diff --git a/packages/web3-eth-contract/CHANGELOG.md b/packages/web3-eth-contract/CHANGELOG.md
index ce09d2e910f..7c165a0eeb5 100644
--- a/packages/web3-eth-contract/CHANGELOG.md
+++ b/packages/web3-eth-contract/CHANGELOG.md
@@ -216,6 +216,10 @@ const transactionHash = receipt.transactionHash;
## [Unreleased]
+### Fixed
+
+- Fix contract defaults (#5756)
+
### Changed
- Update imports statements for objects that was moved between web3 packages (#5771)
diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts
index 8d98b118a42..c7081683107 100644
--- a/packages/web3-eth-contract/src/contract.ts
+++ b/packages/web3-eth-contract/src/contract.ts
@@ -15,7 +15,7 @@ You should have received a copy of the GNU Lesser General Public License
along with web3.js. If not, see .
*/
-import { Web3Context, Web3EventEmitter, Web3PromiEvent } from 'web3-core';
+import { Web3Context, Web3EventEmitter, Web3PromiEvent, Web3ConfigEvent } from 'web3-core';
import { ContractExecutionError, SubscriptionError, Web3ContractError } from 'web3-errors';
import {
createAccessList,
@@ -57,7 +57,6 @@ import {
HexString,
LogsInput,
Mutable,
- Common,
} from 'web3-types';
import {
DataFormat,
@@ -213,69 +212,9 @@ export class Contract
public readonly options: ContractOptions;
/**
- * Can be used to set {@link Contract.defaultAccount} for all contracts.
+ * Set to true if you want contracts' defaults to sync with global defaults.
*/
- public static defaultAccount?: HexString;
-
- /**
- * Can be used to set {@link Contract.defaultBlock} for all contracts.
- */
- public static defaultBlock?: BlockNumberOrTag;
-
- /**
- * Can be used to set {@link Contract.defaultHardfork} for all contracts.
- */
- public static defaultHardfork?: string;
-
- /**
- * Can be used to set {@link Contract.defaultCommon} for all contracts.
- */
- public static defaultCommon?: Common;
-
- /**
- * Can be used to set {@link Contract.transactionSendTimeout} for all contracts.
- */
- public static transactionSendTimeout?: number;
-
- /**
- * Can be used to set {@link Contract.transactionBlockTimeout} for all contracts.
- */
- public static transactionBlockTimeout?: number;
-
- /**
- * Can be used to set {@link Contract.transactionConfirmationBlocks} for all contracts.
- */
- public static transactionConfirmationBlocks?: number;
-
- /**
- * Can be used to set {@link Contract.transactionPollingInterval} for all contracts.
- */
- public static transactionPollingInterval?: number;
-
- /**
- * Can be used to set {@link Contract.transactionPollingTimeout} for all contracts.
- */
- public static transactionPollingTimeout?: number;
-
- /**
- * Can be used to set {@link Contract.transactionReceiptPollingInterval} for all contracts.
- */
- public static transactionReceiptPollingInterval?: number;
-
- /**
- * Can be used to set {@link Contract.transactionConfirmationPollingInterval} for all contracts.
- */
- public static transactionConfirmationPollingInterval?: number;
-
- /**
- * Can be used to set {@link Contract.blockHeaderTimeout} for all contracts.
- */
- public static blockHeaderTimeout?: number;
-
- /**
- * Can be used to set {@link Contract.handleRevert} for all contracts.
- */
- public static handleRevert?: boolean;
+ public syncWithContext = false;
private _errorsInterface!: AbiErrorFragment[];
private _jsonInterface!: ContractAbiWithSignature;
@@ -292,6 +231,7 @@ export class Contract
private _methods!: ContractMethodsInterface;
private _events!: ContractEventsInterface;
+ private context?: Web3Context;
/**
* Creates a new contract instance with all its methods and events defined in its {@doclink glossary/json_interface | json interface} object.
*
@@ -420,6 +360,8 @@ export class Contract
data: options?.data,
};
+ this.syncWithContext = (options as ContractInitOptions)?.syncWithContext ?? false;
+
Object.defineProperty(this.options, 'address', {
set: (value: Address) => this._parseAndSetAddress(value, returnDataFormat),
get: () => this._address,
@@ -431,131 +373,6 @@ export class Contract
});
}
- public get defaultAccount() {
- return (this.constructor as typeof Contract).defaultAccount ?? super.defaultAccount;
- }
-
- public set defaultAccount(value: Address | undefined) {
- super.defaultAccount = value;
- }
-
- public get defaultBlock() {
- return (this.constructor as typeof Contract).defaultBlock ?? super.defaultBlock;
- }
-
- public set defaultBlock(value: BlockNumberOrTag) {
- super.defaultBlock = value;
- }
-
- public get defaultHardfork() {
- return (this.constructor as typeof Contract).defaultHardfork ?? super.defaultHardfork;
- }
-
- public set defaultHardfork(value: string) {
- super.defaultHardfork = value;
- }
-
- public get defaultCommon(): Common | undefined {
- return (this.constructor as typeof Contract).defaultCommon ?? super.defaultCommon;
- }
-
- public set defaultCommon(value: Common | undefined) {
- super.defaultCommon = value;
- }
-
- public get transactionSendTimeout() {
- return (
- (this.constructor as typeof Contract).transactionSendTimeout ??
- super.transactionSendTimeout
- );
- }
-
- public set transactionSendTimeout(value: number) {
- super.transactionSendTimeout = value;
- }
-
- public get transactionBlockTimeout() {
- return (
- (this.constructor as typeof Contract).transactionBlockTimeout ??
- super.transactionBlockTimeout
- );
- }
-
- public set transactionBlockTimeout(value: number) {
- super.transactionBlockTimeout = value;
- }
-
- public get transactionConfirmationBlocks() {
- return (
- (this.constructor as typeof Contract).transactionConfirmationBlocks ??
- super.transactionConfirmationBlocks
- );
- }
-
- public set transactionConfirmationBlocks(value: number) {
- super.transactionConfirmationBlocks = value;
- }
-
- public get transactionPollingInterval() {
- return (
- (this.constructor as typeof Contract).transactionPollingInterval ??
- super.transactionPollingInterval
- );
- }
-
- public set transactionPollingInterval(value: number) {
- super.transactionPollingInterval = value;
- }
-
- public get transactionPollingTimeout() {
- return (
- (this.constructor as typeof Contract).transactionPollingTimeout ??
- super.transactionPollingTimeout
- );
- }
-
- public set transactionPollingTimeout(value: number) {
- super.transactionPollingTimeout = value;
- }
-
- public get transactionReceiptPollingInterval() {
- return (
- (this.constructor as typeof Contract).transactionReceiptPollingInterval ??
- super.transactionReceiptPollingInterval
- );
- }
-
- public set transactionReceiptPollingInterval(value: number | undefined) {
- super.transactionReceiptPollingInterval = value;
- }
-
- public get transactionConfirmationPollingInterval() {
- return (
- (this.constructor as typeof Contract).transactionConfirmationPollingInterval ??
- super.transactionConfirmationPollingInterval
- );
- }
-
- public set transactionConfirmationPollingInterval(value: number | undefined) {
- super.transactionConfirmationPollingInterval = value;
- }
-
- public get blockHeaderTimeout() {
- return (this.constructor as typeof Contract).blockHeaderTimeout ?? super.blockHeaderTimeout;
- }
-
- public set blockHeaderTimeout(value: number) {
- super.blockHeaderTimeout = value;
- }
-
- public get handleRevert() {
- return (this.constructor as typeof Contract).handleRevert ?? super.handleRevert;
- }
-
- public set handleRevert(value: boolean) {
- super.handleRevert = value;
- }
-
/**
* Subscribe to an event.
*
@@ -633,8 +450,10 @@ export class Contract
* ```
*/
public clone() {
+ let newContract: Contract;
+
if (this.options.address) {
- return new Contract(
+ newContract = new Contract(
[...this._jsonInterface, ...this._errorsInterface] as unknown as Abi,
this.options.address,
{
@@ -644,23 +463,28 @@ export class Contract
from: this.options.from,
data: this.options.data,
provider: this.currentProvider,
+ syncWithContext: this.syncWithContext,
+ },
+ this.getContextObject(),
+ );
+ } else {
+ newContract = new Contract(
+ [...this._jsonInterface, ...this._errorsInterface] as unknown as Abi,
+ {
+ gas: this.options.gas,
+ gasPrice: this.options.gasPrice,
+ gasLimit: this.options.gasLimit,
+ from: this.options.from,
+ data: this.options.data,
+ provider: this.currentProvider,
+ syncWithContext: this.syncWithContext,
},
this.getContextObject(),
);
}
+ if (this.context) newContract.subscribeToContextEvents(this.context);
- return new Contract(
- [...this._jsonInterface, ...this._errorsInterface] as unknown as Abi,
- {
- gas: this.options.gas,
- gasPrice: this.options.gasPrice,
- gasLimit: this.options.gasLimit,
- from: this.options.from,
- data: this.options.data,
- provider: this.currentProvider,
- },
- this.getContextObject(),
- );
+ return newContract;
}
/**
@@ -772,6 +596,7 @@ export class Contract
// modifiedOptions.to = '0x0000000000000000000000000000000000000000';
delete modifiedOptions.to;
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
return this._contractMethodDeploySend(
abi as AbiFunctionFragment,
args as unknown[],
@@ -1330,4 +1155,16 @@ export class Contract
return sub;
};
}
+
+ protected subscribeToContextEvents(context: T): void {
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
+ const contractThis = this;
+ this.context = context;
+
+ if (contractThis.syncWithContext) {
+ context.on(Web3ConfigEvent.CONFIG_CHANGE, event => {
+ contractThis.setConfig({ [event.name]: event.newValue });
+ });
+ }
+ }
}
diff --git a/packages/web3-eth-contract/src/types.ts b/packages/web3-eth-contract/src/types.ts
index 2a7110ef2f7..6e43d3ce045 100644
--- a/packages/web3-eth-contract/src/types.ts
+++ b/packages/web3-eth-contract/src/types.ts
@@ -152,6 +152,10 @@ export interface ContractInitOptions {
readonly data?: Bytes;
readonly gasLimit?: Uint;
readonly provider?: SupportedProviders | string;
+ /**
+ * If `true`, the defaults of the contract instance will be updated automatically based on the changes of the context used to instantiate the contract.
+ */
+ readonly syncWithContext?: boolean;
}
export interface NonPayableCallOptions {
diff --git a/packages/web3-eth-contract/src/utils.ts b/packages/web3-eth-contract/src/utils.ts
index 2e1073067c1..d07eafe8a61 100644
--- a/packages/web3-eth-contract/src/utils.ts
+++ b/packages/web3-eth-contract/src/utils.ts
@@ -30,6 +30,7 @@ import {
PayableCallOptions,
ContractOptions,
Web3ContractContext,
+ ContractInitOptions,
} from './types';
export const getSendTxParams = ({
@@ -138,12 +139,19 @@ export const getEstimateGasParams = ({
return txParams as TransactionWithSenderAPI;
};
-export const isContractInitOptions = (options: unknown): options is ContractOptions =>
+export const isContractInitOptions = (options: unknown): options is ContractInitOptions =>
typeof options === 'object' &&
!isNullish(options) &&
- ['data', 'from', 'gas', 'gasPrice', 'gasLimit', 'address', 'jsonInterface'].some(
- key => key in options,
- );
+ [
+ 'data',
+ 'from',
+ 'gas',
+ 'gasPrice',
+ 'gasLimit',
+ 'address',
+ 'jsonInterface',
+ 'syncWithContext',
+ ].some(key => key in options);
export const isWeb3ContractContext = (options: unknown): options is Web3ContractContext =>
typeof options === 'object' && !isNullish(options) && !isContractInitOptions(options);
diff --git a/packages/web3-eth-contract/test/integration/contract_defaults.test.ts b/packages/web3-eth-contract/test/integration/contract_defaults.test.ts
index 488058ef282..5e631e69ba9 100644
--- a/packages/web3-eth-contract/test/integration/contract_defaults.test.ts
+++ b/packages/web3-eth-contract/test/integration/contract_defaults.test.ts
@@ -41,72 +41,37 @@ describe('contract', () => {
sendOptions = { from: acc.address, gas: '1000000' };
});
- describe('defaultAccount', () => {
- it('should use "defaultAccount" on "Contract" level instead of "from"', async () => {
- // eslint-disable-next-line prefer-destructuring
- Contract.defaultAccount = acc.address;
-
- const receiptHandler = jest.fn();
-
- // We didn't specify "from" in this call
- await contract
- .deploy(deployOptions)
- .send({ gas: '1000000' })
- .on('receipt', receiptHandler);
-
- // We didn't specify "from" in this call
- // eslint-disable-next-line jest/no-standalone-expect
- expect(receiptHandler).toHaveBeenCalledWith(
- expect.objectContaining({ from: acc.address }),
- );
- });
-
- it('should use "defaultAccount" on "instance" level instead of "from"', async () => {
- const deployedContract = await contract.deploy(deployOptions).send(sendOptions);
- Contract.defaultAccount = undefined;
- // eslint-disable-next-line prefer-destructuring
- deployedContract.defaultAccount = acc.address;
- // We didn't specify "from" in this call
- const receipt = await deployedContract.methods
- .setGreeting('New Greeting')
- .send({ gas: '1000000' });
- expect(receipt.from).toEqual(acc.address);
- });
-
- it('should throw error when "from" is not set on any level', () => {
- Contract.defaultAccount = undefined;
- contract.defaultAccount = undefined;
-
- expect(() => contract.deploy(deployOptions).send({ gas: '1000000' })).toThrow(
- 'Contract "from" address not specified',
- );
- });
+ it('should use "defaultAccount" on "instance" level instead of "from"', async () => {
+ const deployedContract = await contract.deploy(deployOptions).send(sendOptions);
+ // eslint-disable-next-line prefer-destructuring
+ deployedContract.defaultAccount = acc.address;
+ // We didn't specify "from" in this call
+ const receipt = await deployedContract.methods
+ .setGreeting('New Greeting')
+ .send({ gas: '1000000' });
+ expect(receipt.from).toEqual(acc.address);
});
- describe('defaultBlock', () => {
- it('should use "defaultBlock" on "Contract" level', async () => {
- contract = await contract.deploy(deployOptions).send(sendOptions);
-
- await contract.methods.setGreeting('New Greeting').send(sendOptions);
+ it('should throw error when "from" is not set on any level', () => {
+ contract.defaultAccount = undefined;
- const requestSpy = jest.spyOn(
- contract.currentProvider as Web3BaseProvider,
- 'request',
- );
- Contract.defaultBlock = 'pending';
+ expect(() => contract.deploy(deployOptions).send({ gas: '1000000' })).toThrow(
+ 'Contract "from" address not specified',
+ );
+ });
- // Forcefully delete this property from the contract instance
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-expect-error
- contract.defaultBlock = undefined;
+ it('should set syncWithContext from init options', async () => {
+ contract = new Contract(GreeterAbi, {
+ provider: getSystemTestProvider(),
+ syncWithContext: true,
+ });
- await contract.methods.greet().call();
+ contract = await contract.deploy(deployOptions).send(sendOptions);
- expect(requestSpy).toHaveBeenCalledWith(
- expect.objectContaining({ params: [expect.any(Object), 'pending'] }),
- );
- });
+ expect(contract.syncWithContext).toBeTruthy();
+ });
+ describe('defaultBlock', () => {
it('should use "defaultBlock" on "instance" level', async () => {
contract = await contract.deploy(deployOptions).send(sendOptions);
@@ -117,7 +82,6 @@ describe('contract', () => {
'request',
);
contract.defaultBlock = 'pending';
- Contract.defaultBlock = undefined;
await contract.methods.greet().call();
@@ -140,7 +104,6 @@ describe('contract', () => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
contract.defaultBlock = undefined;
- Contract.defaultBlock = undefined;
await contract.methods.greet().call(undefined, 'pending');
diff --git a/packages/web3-eth-contract/test/integration/contract_defaults_extra.test.ts b/packages/web3-eth-contract/test/integration/contract_defaults_extra.test.ts
index 00b9f6d4cda..da5bbf143e8 100644
--- a/packages/web3-eth-contract/test/integration/contract_defaults_extra.test.ts
+++ b/packages/web3-eth-contract/test/integration/contract_defaults_extra.test.ts
@@ -26,6 +26,7 @@ import {
describeIf,
isWs,
isHttp,
+ closeOpenConnection,
} from '../fixtures/system_test_utils';
type Resolve = (value?: unknown) => void;
@@ -48,17 +49,6 @@ describe('contract defaults (extra)', () => {
let acc: { address: string; privateKey: string };
beforeEach(async () => {
- Contract.defaultCommon = undefined;
- Contract.transactionBlockTimeout = undefined;
- Contract.blockHeaderTimeout = undefined;
- Contract.transactionConfirmationBlocks = undefined;
- Contract.transactionPollingTimeout = undefined;
- Contract.transactionPollingInterval = undefined;
- Contract.handleRevert = undefined;
-
- contract = new Contract(GreeterAbi, undefined, {
- provider: getSystemTestProvider(),
- });
acc = await createTempAccount();
deployOptions = {
@@ -69,66 +59,52 @@ describe('contract defaults (extra)', () => {
sendOptions = { from: acc.address, gas: '1000000' };
});
- describe('defaultHardfork', () => {
- it('should use "defaultHardfork" on "Contract" level', async () => {
- const hardfork = 'berlin';
-
- Contract.defaultHardfork = hardfork;
-
- // const sendTransactionSpy = jest.spyOn(Web3Eth, 'sendTransaction');
-
- contract = await contract.deploy(deployOptions).send(sendOptions);
-
- expect(contract.defaultHardfork).toBe(hardfork);
-
- await contract.methods.greet().call();
+ afterEach(async () => {
+ await closeOpenConnection(contract);
+ });
- await contract.methods.setGreeting('New Greeting').send(sendOptions);
+ it('should use "defaultHardfork" on "instance" level', async () => {
+ const hardfork = 'berlin';
- // todo investigate. this fails, too
- // expect(sendTransactionSpy).toHaveBeenCalledWith(
- // expect.objectContaining({
- // _config: expect.objectContaining({ defaultHardfork: hardfork }),
- // }),
- // expect.any(Object),
- // expect.any(Object),
- // );
+ contract = new Contract(GreeterAbi, undefined, {
+ provider: getSystemTestProvider(),
});
- it('should use "defaultHardfork" on "instance" level', async () => {
- const hardfork = 'berlin';
- contract.defaultHardfork = hardfork;
+ contract = await contract.deploy(deployOptions).send(sendOptions);
+ contract.defaultHardfork = hardfork;
- contract = await contract.deploy(deployOptions).send(sendOptions);
-
- await contract.methods.setGreeting('New Greeting').send(sendOptions);
- await contract.methods.greet().send(sendOptions);
+ await contract.methods.setGreeting('New Greeting').send(sendOptions);
+ await contract.methods.greet().send(sendOptions);
- expect(contract.defaultHardfork).toBe(hardfork);
- const callSpy = jest.spyOn(Web3Eth, 'call');
+ expect(contract.defaultHardfork).toBe(hardfork);
+ const callSpy = jest.spyOn(Web3Eth, 'call');
- await contract.methods.greet().call();
+ await contract.methods.greet().call();
- expect(callSpy).toHaveBeenLastCalledWith(
- expect.objectContaining({
- _config: expect.objectContaining({ defaultHardfork: hardfork }),
- }),
- expect.any(Object),
- undefined,
- expect.any(Object),
- );
- });
+ expect(callSpy).toHaveBeenLastCalledWith(
+ expect.objectContaining({
+ _config: expect.objectContaining({ defaultHardfork: hardfork }),
+ }),
+ expect.any(Object),
+ undefined,
+ expect.any(Object),
+ );
});
describe('defaultChain', () => {
it('should use "defaultChain" on "instance" level', async () => {
+ contract = new Contract(GreeterAbi, undefined, {
+ provider: getSystemTestProvider(),
+ });
+
+ contract = await contract.deploy(deployOptions).send(sendOptions);
+
expect(contract.defaultChain).toBe('mainnet');
const defaultChain = 'ropsten';
contract.defaultChain = defaultChain;
- expect(contract.defaultChain).toBe(defaultChain);
- contract = await contract.deploy(deployOptions).send(sendOptions);
+ expect(contract.defaultChain).toBe(defaultChain);
await contract.methods.setGreeting('New Greeting').send(sendOptions);
@@ -156,14 +132,6 @@ describe('contract defaults (extra)', () => {
};
beforeEach(async () => {
- Contract.defaultCommon = undefined;
- Contract.transactionBlockTimeout = undefined;
- Contract.blockHeaderTimeout = undefined;
- Contract.transactionConfirmationBlocks = undefined;
- Contract.transactionPollingTimeout = undefined;
- Contract.transactionPollingInterval = undefined;
- Contract.handleRevert = undefined;
-
contract = new Contract(GreeterAbi, undefined, {
provider: getSystemTestProvider(),
});
@@ -179,25 +147,6 @@ describe('contract defaults (extra)', () => {
contract = await contract.deploy(deployOptions).send(sendOptions);
});
- // todo this test fails, seems like a bug. any thoughts?
- // it('should use "defaultCommon" on "Contract" level', async () => {
- // Contract.defaultCommon = common;
-
- // const sendTransactionSpy = jest.spyOn(Web3Eth, 'sendTransaction');
-
- // expect(contract.defaultCommon).toMatchObject(common);
-
- // await contract.methods.setGreeting('New Greeting').send(sendOptions);
-
- // expect(sendTransactionSpy).toHaveBeenLastCalledWith(
- // expect.objectContaining({
- // _config: expect.objectContaining({ defaultCommon: common }),
- // }),
- // expect.any(Object),
- // expect.any(Object),
- // );
- // });
-
it('should use "defaultCommon" on "instance" level', async () => {
contract.defaultCommon = common;
const callSpy = jest.spyOn(Web3Eth, 'call');
@@ -214,10 +163,15 @@ describe('contract defaults (extra)', () => {
);
});
});
+
describeIf(isWs)('transactionBlockTimeout', () => {
it('should use "transactionBlockTimeout" on "instance" level', async () => {
+ contract = new Contract(GreeterAbi, undefined, {
+ provider: getSystemTestProvider(),
+ });
contract = await contract.deploy(deployOptions).send(sendOptions);
+ const sendTransactionSpy = jest.spyOn(Web3Eth, 'sendTransaction');
expect(contract.transactionBlockTimeout).toBe(50);
contract.transactionBlockTimeout = 32;
@@ -225,9 +179,20 @@ describe('contract defaults (extra)', () => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
await contract.methods.setGreeting('New Greeting').send(sendOptions);
+
+ expect(sendTransactionSpy).toHaveBeenLastCalledWith(
+ expect.objectContaining({
+ _config: expect.objectContaining({ transactionBlockTimeout: 32 }),
+ }),
+ expect.any(Object),
+ expect.any(Object),
+ );
});
it('should fail if transaction was not mined within `transactionBlockTimeout` blocks', async () => {
+ contract = new Contract(GreeterAbi, undefined, {
+ provider: getSystemTestProvider(),
+ });
contract = await contract.deploy(deployOptions).send(sendOptions);
// Make the test run faster by casing the polling to start after 2 blocks
@@ -275,18 +240,11 @@ describe('contract defaults (extra)', () => {
});
describeIf(isWs)('blockHeaderTimeout', () => {
- it('should use "blockHeaderTimeout" on "Contract" level', async () => {
- expect(Contract.blockHeaderTimeout).toBeUndefined();
- const blockHeaderTimeout = 100;
- Contract.blockHeaderTimeout = blockHeaderTimeout;
-
- expect(Contract.blockHeaderTimeout).toBe(blockHeaderTimeout);
- contract = await contract.deploy(deployOptions).send(sendOptions);
-
- expect(contract.blockHeaderTimeout).toBe(blockHeaderTimeout);
- });
-
it('should use "blockHeaderTimout" on "instance" level', async () => {
+ contract = new Contract(GreeterAbi, undefined, {
+ provider: getSystemTestProvider(),
+ });
+
contract = await contract.deploy(deployOptions).send(sendOptions);
expect(contract.blockHeaderTimeout).toBe(10);
@@ -329,18 +287,11 @@ describe('contract defaults (extra)', () => {
});
describeIf(isHttp)('transactionPollingInterval', () => {
- it('should use "transactionPollingInterval" on "Contract" level', async () => {
- contract = await contract.deploy(deployOptions).send(sendOptions);
-
- expect(Contract.transactionPollingInterval).toBeUndefined();
-
- const transactionPollingInterval = 500;
- Contract.transactionPollingInterval = transactionPollingInterval;
-
- expect(contract.transactionPollingInterval).toBe(transactionPollingInterval);
- });
-
it('should use "transactionPollingTimeout" on "instance" level', async () => {
+ contract = new Contract(GreeterAbi, undefined, {
+ provider: getSystemTestProvider(),
+ });
+
contract = await contract.deploy(deployOptions).send(sendOptions);
const transactionPollingInterval = 500;
@@ -350,41 +301,24 @@ describe('contract defaults (extra)', () => {
});
});
- describe('handleRevert', () => {
- it('should use "handleRevert" on "Contract" level', async () => {
- contract = await contract.deploy(deployOptions).send(sendOptions);
-
- expect(Contract.handleRevert).toBeUndefined();
-
- expect(contract.handleRevert).toBeFalsy();
-
- const handleRevert = true;
- Contract.handleRevert = handleRevert;
-
- expect(contract.handleRevert).toBe(handleRevert);
-
- const sendTransactionSpy = jest.spyOn(Web3Eth, 'sendTransaction');
-
- await contract.methods.setGreeting('New Greeting').send(sendOptions);
-
- expect(sendTransactionSpy).toHaveBeenCalled();
+ it('should use "handleRevert" on "instance" level', async () => {
+ contract = new Contract(GreeterAbi, undefined, {
+ provider: getSystemTestProvider(),
});
- it('should use "handleRevert" on "instance" level', async () => {
- contract = await contract.deploy(deployOptions).send(sendOptions);
+ contract = await contract.deploy(deployOptions).send(sendOptions);
- expect(contract.handleRevert).toBeFalsy();
+ expect(contract.handleRevert).toBeFalsy();
- const handleRevert = true;
- contract.handleRevert = handleRevert;
+ const handleRevert = true;
+ contract.handleRevert = handleRevert;
- expect(contract.handleRevert).toBe(handleRevert);
+ expect(contract.handleRevert).toBe(handleRevert);
- const sendTransactionSpy = jest.spyOn(Web3Eth, 'sendTransaction');
+ const sendTransactionSpy = jest.spyOn(Web3Eth, 'sendTransaction');
- await contract.methods.setGreeting('New Greeting').send(sendOptions);
+ await contract.methods.setGreeting('New Greeting').send(sendOptions);
- expect(sendTransactionSpy).toHaveBeenCalled();
- });
+ expect(sendTransactionSpy).toHaveBeenCalled();
});
});
diff --git a/packages/web3/src/web3.ts b/packages/web3/src/web3.ts
index 3a615910eb9..49371c9aebd 100644
--- a/packages/web3/src/web3.ts
+++ b/packages/web3/src/web3.ts
@@ -87,6 +87,8 @@ export class Web3 extends Web3Context {
} else {
super(jsonInterface, self.getContextObject());
}
+
+ super.subscribeToContextEvents(self);
}
}
diff --git a/packages/web3/test/integration/web3.test.ts b/packages/web3/test/integration/web3.test.ts
index af4fef27a54..c831cbd164a 100644
--- a/packages/web3/test/integration/web3.test.ts
+++ b/packages/web3/test/integration/web3.test.ts
@@ -33,6 +33,7 @@ import {
isWs,
waitForOpenConnection,
} from '../shared_fixtures/system_tests_utils';
+import { GreeterAbi, GreeterBytecode } from '../shared_fixtures/build/Greeter';
describe('Web3 instance', () => {
let clientUrl: string;
@@ -255,4 +256,54 @@ describe('Web3 instance', () => {
);
});
});
+
+ describe('defaults', () => {
+ let contract: Contract;
+ let deployOptions: Record;
+ let sendOptions: Record;
+ let acc: { address: string; privateKey: string };
+
+ beforeAll(() => {
+ web3 = new Web3(clientUrl);
+ });
+
+ beforeEach(async () => {
+ acc = await createTempAccount();
+
+ // todo import GreeterBytecode
+ deployOptions = {
+ data: GreeterBytecode,
+ arguments: ['My Greeting'],
+ };
+
+ sendOptions = { from: acc.address, gas: '1000000' };
+ });
+
+ it('should update defaults on contract instance', () => {
+ const hardfork = 'berlin';
+
+ contract = new web3.eth.Contract(GreeterAbi, undefined, {
+ provider: getSystemTestProvider(),
+ syncWithContext: true,
+ });
+
+ web3.defaultHardfork = hardfork;
+
+ expect(contract.defaultHardfork).toBe(hardfork);
+ });
+
+ it('should update defaults on deployed contract instance', async () => {
+ const hardfork = 'berlin';
+
+ contract = new web3.eth.Contract(GreeterAbi, undefined, {
+ provider: getSystemTestProvider(),
+ syncWithContext: true,
+ });
+ contract = await contract.deploy(deployOptions).send(sendOptions);
+
+ web3.defaultHardfork = hardfork;
+
+ expect(contract.defaultHardfork).toBe(hardfork);
+ });
+ });
});