From 9a5551568a21f56aa3fcdd222a82683029dc18b7 Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Fri, 13 Jan 2023 15:00:29 +0200 Subject: [PATCH 01/33] Create getters & setters for static defaults properties --- packages/web3-eth-contract/src/contract.ts | 207 ++++++++++++++------- 1 file changed, 142 insertions(+), 65 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index f62c3226b70..9b8523852ac 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -210,71 +210,6 @@ export class Contract */ public readonly options: ContractOptions; - /** - * Can be used to set {@link Contract.defaultAccount} for all contracts. - */ - 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; - private _errorsInterface!: AbiErrorFragment[]; private _jsonInterface!: ContractAbiWithSignature; private _address?: Address; @@ -429,6 +364,16 @@ export class Contract }); } + /** + * Can be used to set {@link Contract.defaultAccount} for all contracts. + */ + public static get defaultAccount() { + return (this.constructor as typeof Contract).defaultAccount; + } + + public static set defaultAccount(value: Address | undefined) { + Contract.defaultAccount = value; + } public get defaultAccount() { return (this.constructor as typeof Contract).defaultAccount ?? super.defaultAccount; } @@ -437,6 +382,17 @@ export class Contract super.defaultAccount = value; } + /** + * Can be used to set {@link Contract.defaultBlock} for all contracts. + */ + public static get defaultBlock() { + return (this.constructor as typeof Contract).defaultBlock; + } + + public static set defaultBlock(value: BlockNumberOrTag) { + Contract.defaultBlock = value; + } + public get defaultBlock() { return (this.constructor as typeof Contract).defaultBlock ?? super.defaultBlock; } @@ -445,6 +401,17 @@ export class Contract super.defaultBlock = value; } + /** + * Can be used to set {@link Contract.defaultHardfork} for all contracts. + */ + public static get defaultHardfork() { + return (this.constructor as typeof Contract).defaultHardfork; + } + + public static set defaultHardfork(value: string) { + Contract.defaultHardfork = value; + } + public get defaultHardfork() { return (this.constructor as typeof Contract).defaultHardfork ?? super.defaultHardfork; } @@ -453,12 +420,34 @@ export class Contract super.defaultHardfork = value; } + /** + * Can be used to set {@link Contract.defaultCommon} for all contracts. + */ + public static get defaultCommon(): Common | undefined { + return (this.constructor as typeof Contract).defaultCommon; + } + + public static set defaultCommon(value: Common | undefined) { + (this.constructor as typeof Contract).defaultCommon = value; + } + public get defaultCommon(): Common | undefined { return (this.constructor as typeof Contract).defaultCommon ?? super.defaultCommon; } public set defaultCommon(value: Common | undefined) { super.defaultCommon = value; + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + // (this as unknown as Web3Context).setConfig({ defaultCommon: value }); + // this.contractWeb3Config.defaultCommon = value; + } + + public static get transactionSendTimeout() { + return (this.constructor as typeof Contract).transactionSendTimeout; + } + + public static set transactionSendTimeout(value: number) { + Contract.transactionSendTimeout = value; } public get transactionSendTimeout() { @@ -472,6 +461,17 @@ export class Contract super.transactionSendTimeout = value; } + /** + * Can be used to set {@link Contract.transactionBlockTimeout} for all contracts. + */ + public static get transactionBlockTimeout() { + return (this.constructor as typeof Contract).transactionBlockTimeout; + } + + public static set transactionBlockTimeout(value: number | undefined) { + Contract.transactionBlockTimeout = value; + } + public get transactionBlockTimeout() { return ( (this.constructor as typeof Contract).transactionBlockTimeout ?? @@ -483,6 +483,17 @@ export class Contract super.transactionBlockTimeout = value; } + /** + * Can be used to set {@link Contract.transactionConfirmationBlocks} for all contracts. + */ + public static get transactionConfirmationBlocks() { + return (this.constructor as typeof Contract).transactionConfirmationBlocks; + } + + public static set transactionConfirmationBlocks(value: number) { + Contract.transactionConfirmationBlocks = value; + } + public get transactionConfirmationBlocks() { return ( (this.constructor as typeof Contract).transactionConfirmationBlocks ?? @@ -494,6 +505,17 @@ export class Contract super.transactionConfirmationBlocks = value; } + /** + * Can be used to set {@link Contract.transactionPollingInterval} for all contracts. + */ + public static get transactionPollingInterval() { + return (this.constructor as typeof Contract).transactionPollingInterval; + } + + public static set transactionPollingInterval(value: number) { + Contract.transactionPollingInterval = value; + } + public get transactionPollingInterval() { return ( (this.constructor as typeof Contract).transactionPollingInterval ?? @@ -505,6 +527,17 @@ export class Contract super.transactionPollingInterval = value; } + /** + * Can be used to set {@link Contract.transactionPollingTimeout} for all contracts. + */ + public static get transactionPollingTimeout() { + return (this.constructor as typeof Contract).transactionPollingTimeout; + } + + public static set transactionPollingTimeout(value: number) { + Contract.transactionPollingTimeout = value; + } + public get transactionPollingTimeout() { return ( (this.constructor as typeof Contract).transactionPollingTimeout ?? @@ -516,6 +549,17 @@ export class Contract super.transactionPollingTimeout = value; } + /** + * Can be used to set {@link Contract.transactionReceiptPollingInterval} for all contracts. + */ + public static get transactionReceiptPollingInterval() { + return (this.constructor as typeof Contract).transactionReceiptPollingInterval; + } + + public static set transactionReceiptPollingInterval(value: number) { + Contract.transactionReceiptPollingInterval = value; + } + public get transactionReceiptPollingInterval() { return ( (this.constructor as typeof Contract).transactionReceiptPollingInterval ?? @@ -527,6 +571,17 @@ export class Contract super.transactionReceiptPollingInterval = value; } + /** + * Can be used to set {@link Contract.transactionConfirmationPollingInterval} for all contracts. + */ + public static get transactionConfirmationPollingInterval() { + return (this.constructor as typeof Contract).transactionConfirmationPollingInterval; + } + + public static set transactionConfirmationPollingInterval(value: number) { + Contract.transactionConfirmationPollingInterval = value; + } + public get transactionConfirmationPollingInterval() { return ( (this.constructor as typeof Contract).transactionConfirmationPollingInterval ?? @@ -538,6 +593,17 @@ export class Contract super.transactionConfirmationPollingInterval = value; } + /** + * Can be used to set {@link Contract.blockHeaderTimeout} for all contracts. + */ + public static get blockHeaderTimeout() { + return (this.constructor as typeof Contract).blockHeaderTimeout; + } + + public static set blockHeaderTimeout(value: number | undefined) { + Contract.blockHeaderTimeout = value; + } + public get blockHeaderTimeout() { return (this.constructor as typeof Contract).blockHeaderTimeout ?? super.blockHeaderTimeout; } @@ -546,6 +612,17 @@ export class Contract super.blockHeaderTimeout = value; } + /** + * Can be used to set {@link Contract.handleRevert} for all contracts. + */ + public static get handleRevert() { + return (this.constructor as typeof Contract).handleRevert; + } + + public static set handleRevert(value: boolean) { + Contract.handleRevert = value; + } + public get handleRevert() { return (this.constructor as typeof Contract).handleRevert ?? super.handleRevert; } From 5b076e3b283cb3cff90901aaa5a0ebd660e86680 Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Fri, 13 Jan 2023 15:41:36 +0200 Subject: [PATCH 02/33] Add web3config static variable to initialize web3Context config --- packages/web3-eth-contract/src/contract.ts | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index 9b8523852ac..306dd4caf4b 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, Web3ConfigOptions } from 'web3-core'; import { ContractExecutionError, SubscriptionError, Web3ContractError } from 'web3-errors'; import { call, @@ -225,6 +225,7 @@ export class Contract private _methods!: ContractMethodsInterface; private _events!: ContractEventsInterface; + private static readonly contractWeb3Config: Partial = {}; /** * Creates a new contract instance with all its methods and events defined in its {@doclink glossary/json_interface | json interface} object. * @@ -362,6 +363,8 @@ export class Contract set: (value: ContractAbi) => this._parseAndSetJsonInterface(value, returnDataFormat), get: () => this._jsonInterface, }); + + this.setConfig(Contract.contractWeb3Config); } /** @@ -373,6 +376,7 @@ export class Contract public static set defaultAccount(value: Address | undefined) { Contract.defaultAccount = value; + Contract.contractWeb3Config.defaultAccount = value; } public get defaultAccount() { return (this.constructor as typeof Contract).defaultAccount ?? super.defaultAccount; @@ -391,6 +395,7 @@ export class Contract public static set defaultBlock(value: BlockNumberOrTag) { Contract.defaultBlock = value; + Contract.contractWeb3Config.defaultBlock = value; } public get defaultBlock() { @@ -410,6 +415,7 @@ export class Contract public static set defaultHardfork(value: string) { Contract.defaultHardfork = value; + Contract.contractWeb3Config.defaultHardfork = value; } public get defaultHardfork() { @@ -429,6 +435,7 @@ export class Contract public static set defaultCommon(value: Common | undefined) { (this.constructor as typeof Contract).defaultCommon = value; + Contract.contractWeb3Config.defaultCommon = value; } public get defaultCommon(): Common | undefined { @@ -448,6 +455,7 @@ export class Contract public static set transactionSendTimeout(value: number) { Contract.transactionSendTimeout = value; + Contract.contractWeb3Config.transactionSendTimeout = value; } public get transactionSendTimeout() { @@ -470,6 +478,7 @@ export class Contract public static set transactionBlockTimeout(value: number | undefined) { Contract.transactionBlockTimeout = value; + Contract.contractWeb3Config.transactionBlockTimeout = value; } public get transactionBlockTimeout() { @@ -492,6 +501,7 @@ export class Contract public static set transactionConfirmationBlocks(value: number) { Contract.transactionConfirmationBlocks = value; + Contract.contractWeb3Config.transactionConfirmationBlocks = value; } public get transactionConfirmationBlocks() { @@ -514,6 +524,7 @@ export class Contract public static set transactionPollingInterval(value: number) { Contract.transactionPollingInterval = value; + Contract.contractWeb3Config.transactionPollingInterval = value; } public get transactionPollingInterval() { @@ -536,6 +547,7 @@ export class Contract public static set transactionPollingTimeout(value: number) { Contract.transactionPollingTimeout = value; + Contract.contractWeb3Config.transactionPollingTimeout = value; } public get transactionPollingTimeout() { @@ -558,6 +570,7 @@ export class Contract public static set transactionReceiptPollingInterval(value: number) { Contract.transactionReceiptPollingInterval = value; + Contract.contractWeb3Config.transactionReceiptPollingInterval = value; } public get transactionReceiptPollingInterval() { @@ -567,7 +580,7 @@ export class Contract ); } - public set transactionReceiptPollingInterval(value: number | undefined) { + public set transactionReceiptPollingInterval(value: number) { super.transactionReceiptPollingInterval = value; } @@ -580,6 +593,7 @@ export class Contract public static set transactionConfirmationPollingInterval(value: number) { Contract.transactionConfirmationPollingInterval = value; + Contract.contractWeb3Config.transactionConfirmationPollingInterval = value; } public get transactionConfirmationPollingInterval() { @@ -602,6 +616,7 @@ export class Contract public static set blockHeaderTimeout(value: number | undefined) { Contract.blockHeaderTimeout = value; + Contract.contractWeb3Config.blockHeaderTimeout = value; } public get blockHeaderTimeout() { @@ -621,6 +636,7 @@ export class Contract public static set handleRevert(value: boolean) { Contract.handleRevert = value; + Contract.contractWeb3Config.handleRevert = value; } public get handleRevert() { From 67db6321d6c93604af538790b809506689c5e9ab Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Fri, 13 Jan 2023 17:26:09 +0200 Subject: [PATCH 03/33] prioritize instance's value --- packages/web3-eth-contract/src/contract.ts | 64 +++++++++++----------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index 306dd4caf4b..ef90476ada7 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -375,11 +375,11 @@ export class Contract } public static set defaultAccount(value: Address | undefined) { - Contract.defaultAccount = value; + (this.constructor as typeof Contract).defaultAccount = value; Contract.contractWeb3Config.defaultAccount = value; } public get defaultAccount() { - return (this.constructor as typeof Contract).defaultAccount ?? super.defaultAccount; + return super.defaultAccount ?? (this.constructor as typeof Contract).defaultAccount; } public set defaultAccount(value: Address | undefined) { @@ -394,12 +394,12 @@ export class Contract } public static set defaultBlock(value: BlockNumberOrTag) { - Contract.defaultBlock = value; + (this.constructor as typeof Contract).defaultBlock = value; Contract.contractWeb3Config.defaultBlock = value; } public get defaultBlock() { - return (this.constructor as typeof Contract).defaultBlock ?? super.defaultBlock; + return super.defaultBlock ?? (this.constructor as typeof Contract).defaultBlock; } public set defaultBlock(value: BlockNumberOrTag) { @@ -414,12 +414,12 @@ export class Contract } public static set defaultHardfork(value: string) { - Contract.defaultHardfork = value; + (this.constructor as typeof Contract).defaultHardfork = value; Contract.contractWeb3Config.defaultHardfork = value; } public get defaultHardfork() { - return (this.constructor as typeof Contract).defaultHardfork ?? super.defaultHardfork; + return super.defaultHardfork ?? (this.constructor as typeof Contract).defaultHardfork; } public set defaultHardfork(value: string) { @@ -439,7 +439,7 @@ export class Contract } public get defaultCommon(): Common | undefined { - return (this.constructor as typeof Contract).defaultCommon ?? super.defaultCommon; + return super.defaultCommon ?? (this.constructor as typeof Contract).defaultCommon; } public set defaultCommon(value: Common | undefined) { @@ -454,14 +454,14 @@ export class Contract } public static set transactionSendTimeout(value: number) { - Contract.transactionSendTimeout = value; + (this.constructor as typeof Contract).transactionSendTimeout = value; Contract.contractWeb3Config.transactionSendTimeout = value; } public get transactionSendTimeout() { return ( - (this.constructor as typeof Contract).transactionSendTimeout ?? - super.transactionSendTimeout + super.transactionSendTimeout ?? + (this.constructor as typeof Contract).transactionSendTimeout ); } @@ -477,14 +477,14 @@ export class Contract } public static set transactionBlockTimeout(value: number | undefined) { - Contract.transactionBlockTimeout = value; + (this.constructor as typeof Contract).transactionBlockTimeout = value; Contract.contractWeb3Config.transactionBlockTimeout = value; } public get transactionBlockTimeout() { return ( - (this.constructor as typeof Contract).transactionBlockTimeout ?? - super.transactionBlockTimeout + super.transactionBlockTimeout ?? + (this.constructor as typeof Contract).transactionBlockTimeout ); } @@ -500,14 +500,14 @@ export class Contract } public static set transactionConfirmationBlocks(value: number) { - Contract.transactionConfirmationBlocks = value; + (this.constructor as typeof Contract).transactionConfirmationBlocks = value; Contract.contractWeb3Config.transactionConfirmationBlocks = value; } public get transactionConfirmationBlocks() { return ( - (this.constructor as typeof Contract).transactionConfirmationBlocks ?? - super.transactionConfirmationBlocks + super.transactionConfirmationBlocks ?? + (this.constructor as typeof Contract).transactionConfirmationBlocks ); } @@ -523,14 +523,14 @@ export class Contract } public static set transactionPollingInterval(value: number) { - Contract.transactionPollingInterval = value; + (this.constructor as typeof Contract).transactionPollingInterval = value; Contract.contractWeb3Config.transactionPollingInterval = value; } public get transactionPollingInterval() { return ( - (this.constructor as typeof Contract).transactionPollingInterval ?? - super.transactionPollingInterval + super.transactionPollingInterval ?? + (this.constructor as typeof Contract).transactionPollingInterval ); } @@ -546,14 +546,14 @@ export class Contract } public static set transactionPollingTimeout(value: number) { - Contract.transactionPollingTimeout = value; + (this.constructor as typeof Contract).transactionPollingTimeout = value; Contract.contractWeb3Config.transactionPollingTimeout = value; } public get transactionPollingTimeout() { return ( - (this.constructor as typeof Contract).transactionPollingTimeout ?? - super.transactionPollingTimeout + super.transactionPollingTimeout ?? + (this.constructor as typeof Contract).transactionPollingTimeout ); } @@ -569,14 +569,14 @@ export class Contract } public static set transactionReceiptPollingInterval(value: number) { - Contract.transactionReceiptPollingInterval = value; + (this.constructor as typeof Contract).transactionReceiptPollingInterval = value; Contract.contractWeb3Config.transactionReceiptPollingInterval = value; } public get transactionReceiptPollingInterval() { return ( - (this.constructor as typeof Contract).transactionReceiptPollingInterval ?? - super.transactionReceiptPollingInterval + super.transactionReceiptPollingInterval ?? + (this.constructor as typeof Contract).transactionReceiptPollingInterval ); } @@ -592,14 +592,14 @@ export class Contract } public static set transactionConfirmationPollingInterval(value: number) { - Contract.transactionConfirmationPollingInterval = value; + (this.constructor as typeof Contract).transactionConfirmationPollingInterval = value; Contract.contractWeb3Config.transactionConfirmationPollingInterval = value; } public get transactionConfirmationPollingInterval() { return ( - (this.constructor as typeof Contract).transactionConfirmationPollingInterval ?? - super.transactionConfirmationPollingInterval + super.transactionConfirmationPollingInterval ?? + (this.constructor as typeof Contract).transactionConfirmationPollingInterval ); } @@ -615,12 +615,12 @@ export class Contract } public static set blockHeaderTimeout(value: number | undefined) { - Contract.blockHeaderTimeout = value; + (this.constructor as typeof Contract).blockHeaderTimeout = value; Contract.contractWeb3Config.blockHeaderTimeout = value; } public get blockHeaderTimeout() { - return (this.constructor as typeof Contract).blockHeaderTimeout ?? super.blockHeaderTimeout; + return super.blockHeaderTimeout ?? (this.constructor as typeof Contract).blockHeaderTimeout; } public set blockHeaderTimeout(value: number) { @@ -635,12 +635,12 @@ export class Contract } public static set handleRevert(value: boolean) { - Contract.handleRevert = value; + (this.constructor as typeof Contract).handleRevert = value; Contract.contractWeb3Config.handleRevert = value; } public get handleRevert() { - return (this.constructor as typeof Contract).handleRevert ?? super.handleRevert; + return super.handleRevert ?? (this.constructor as typeof Contract).handleRevert; } public set handleRevert(value: boolean) { From d824c0b170322021b4d6a551068b33ffaa4385f5 Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Fri, 13 Jan 2023 17:26:41 +0200 Subject: [PATCH 04/33] Update tests --- .../contract_defaults_extra.test.ts | 137 +++++++++++------- 1 file changed, 86 insertions(+), 51 deletions(-) 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..a74b638158b 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,13 +59,20 @@ describe('contract defaults (extra)', () => { sendOptions = { from: acc.address, gas: '1000000' }; }); + afterEach(async () => { + await closeOpenConnection(contract); + }); describe('defaultHardfork', () => { it('should use "defaultHardfork" on "Contract" level', async () => { const hardfork = 'berlin'; Contract.defaultHardfork = hardfork; - // const sendTransactionSpy = jest.spyOn(Web3Eth, 'sendTransaction'); + contract = new Contract(GreeterAbi, undefined, { + provider: getSystemTestProvider(), + }); + + const sendTransactionSpy = jest.spyOn(Web3Eth, 'sendTransaction'); contract = await contract.deploy(deployOptions).send(sendOptions); @@ -85,20 +82,23 @@ describe('contract defaults (extra)', () => { await contract.methods.setGreeting('New Greeting').send(sendOptions); - // todo investigate. this fails, too - // expect(sendTransactionSpy).toHaveBeenCalledWith( - // expect.objectContaining({ - // _config: expect.objectContaining({ defaultHardfork: hardfork }), - // }), - // expect.any(Object), - // expect.any(Object), - // ); + expect(sendTransactionSpy).toHaveBeenCalledWith( + expect.objectContaining({ + _config: expect.objectContaining({ defaultHardfork: hardfork }), + }), + expect.any(Object), + expect.any(Object), + ); }); it('should use "defaultHardfork" on "instance" level', async () => { const hardfork = 'berlin'; contract.defaultHardfork = hardfork; + contract = new Contract(GreeterAbi, undefined, { + provider: getSystemTestProvider(), + }); + contract = await contract.deploy(deployOptions).send(sendOptions); await contract.methods.setGreeting('New Greeting').send(sendOptions); @@ -122,13 +122,18 @@ describe('contract defaults (extra)', () => { 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); @@ -152,18 +157,10 @@ describe('contract defaults (extra)', () => { const common = { customChain: { name: 'testnet', networkId: '1337', chainId: '1337' }, baseChain, - hardfork: 'london' as Hardfork, + hardfork: 'berlin' as Hardfork, }; 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,24 +176,28 @@ 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; + it('should use "defaultCommon" on "Contract" level', async () => { + Contract.defaultCommon = common; - // const sendTransactionSpy = jest.spyOn(Web3Eth, 'sendTransaction'); + contract = new Contract(GreeterAbi, undefined, { + provider: getSystemTestProvider(), + }); - // expect(contract.defaultCommon).toMatchObject(common); + contract = await contract.deploy(deployOptions).send(sendOptions); + const sendTransactionSpy = jest.spyOn(Web3Eth, 'sendTransaction'); - // await contract.methods.setGreeting('New Greeting').send(sendOptions); + expect(contract.defaultCommon).toMatchObject(common); - // expect(sendTransactionSpy).toHaveBeenLastCalledWith( - // expect.objectContaining({ - // _config: expect.objectContaining({ defaultCommon: common }), - // }), - // expect.any(Object), - // expect.any(Object), - // ); - // }); + 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; @@ -214,10 +215,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 +231,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 @@ -280,13 +297,22 @@ describe('contract defaults (extra)', () => { const blockHeaderTimeout = 100; Contract.blockHeaderTimeout = blockHeaderTimeout; + contract = new Contract(GreeterAbi, undefined, { + provider: getSystemTestProvider(), + }); + expect(Contract.blockHeaderTimeout).toBe(blockHeaderTimeout); contract = await contract.deploy(deployOptions).send(sendOptions); expect(contract.blockHeaderTimeout).toBe(blockHeaderTimeout); + Contract.blockHeaderTimeout = 10; }); 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); @@ -330,13 +356,14 @@ 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; + contract = new Contract(GreeterAbi, undefined, { + provider: getSystemTestProvider(), + }); expect(contract.transactionPollingInterval).toBe(transactionPollingInterval); }); @@ -352,15 +379,17 @@ 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; + contract = new Contract(GreeterAbi, undefined, { + provider: getSystemTestProvider(), + }); + + contract = await contract.deploy(deployOptions).send(sendOptions); + expect(contract.handleRevert).toBe(handleRevert); const sendTransactionSpy = jest.spyOn(Web3Eth, 'sendTransaction'); @@ -368,9 +397,15 @@ describe('contract defaults (extra)', () => { await contract.methods.setGreeting('New Greeting').send(sendOptions); expect(sendTransactionSpy).toHaveBeenCalled(); + + Contract.handleRevert = false; }); it('should use "handleRevert" on "instance" level', async () => { + contract = new Contract(GreeterAbi, undefined, { + provider: getSystemTestProvider(), + }); + contract = await contract.deploy(deployOptions).send(sendOptions); expect(contract.handleRevert).toBeFalsy(); From c39de804be207debcf6ed3f02d83964ca7476441 Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Mon, 16 Jan 2023 11:36:09 +0200 Subject: [PATCH 05/33] Enable optional static variables --- packages/web3-eth-contract/src/contract.ts | 61 ++++++++++++++-------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index ef90476ada7..cad020b645c 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -376,7 +376,8 @@ export class Contract public static set defaultAccount(value: Address | undefined) { (this.constructor as typeof Contract).defaultAccount = value; - Contract.contractWeb3Config.defaultAccount = value; + if (value === undefined) delete Contract.contractWeb3Config.defaultAccount; + else Contract.contractWeb3Config.defaultAccount = value; } public get defaultAccount() { return super.defaultAccount ?? (this.constructor as typeof Contract).defaultAccount; @@ -393,9 +394,10 @@ export class Contract return (this.constructor as typeof Contract).defaultBlock; } - public static set defaultBlock(value: BlockNumberOrTag) { + public static set defaultBlock(value: BlockNumberOrTag | undefined) { (this.constructor as typeof Contract).defaultBlock = value; - Contract.contractWeb3Config.defaultBlock = value; + if (value === undefined) delete Contract.contractWeb3Config.defaultBlock; + else Contract.contractWeb3Config.defaultBlock = value; } public get defaultBlock() { @@ -413,9 +415,10 @@ export class Contract return (this.constructor as typeof Contract).defaultHardfork; } - public static set defaultHardfork(value: string) { + public static set defaultHardfork(value: string | undefined) { (this.constructor as typeof Contract).defaultHardfork = value; - Contract.contractWeb3Config.defaultHardfork = value; + if (value === undefined) delete Contract.contractWeb3Config.defaultHardfork; + else Contract.contractWeb3Config.defaultHardfork = value; } public get defaultHardfork() { @@ -435,7 +438,8 @@ export class Contract public static set defaultCommon(value: Common | undefined) { (this.constructor as typeof Contract).defaultCommon = value; - Contract.contractWeb3Config.defaultCommon = value; + if (value === undefined) delete Contract.contractWeb3Config.defaultCommon; + else Contract.contractWeb3Config.defaultCommon = value; } public get defaultCommon(): Common | undefined { @@ -453,9 +457,10 @@ export class Contract return (this.constructor as typeof Contract).transactionSendTimeout; } - public static set transactionSendTimeout(value: number) { + public static set transactionSendTimeout(value: number | undefined) { (this.constructor as typeof Contract).transactionSendTimeout = value; - Contract.contractWeb3Config.transactionSendTimeout = value; + if (value === undefined) delete Contract.contractWeb3Config.transactionSendTimeout; + else Contract.contractWeb3Config.transactionSendTimeout = value; } public get transactionSendTimeout() { @@ -478,7 +483,8 @@ export class Contract public static set transactionBlockTimeout(value: number | undefined) { (this.constructor as typeof Contract).transactionBlockTimeout = value; - Contract.contractWeb3Config.transactionBlockTimeout = value; + if (value === undefined) delete Contract.contractWeb3Config.transactionBlockTimeout; + else Contract.contractWeb3Config.transactionBlockTimeout = value; } public get transactionBlockTimeout() { @@ -499,9 +505,10 @@ export class Contract return (this.constructor as typeof Contract).transactionConfirmationBlocks; } - public static set transactionConfirmationBlocks(value: number) { + public static set transactionConfirmationBlocks(value: number | undefined) { (this.constructor as typeof Contract).transactionConfirmationBlocks = value; - Contract.contractWeb3Config.transactionConfirmationBlocks = value; + if (value === undefined) delete Contract.contractWeb3Config.transactionConfirmationBlocks; + else Contract.contractWeb3Config.transactionConfirmationBlocks = value; } public get transactionConfirmationBlocks() { @@ -522,9 +529,10 @@ export class Contract return (this.constructor as typeof Contract).transactionPollingInterval; } - public static set transactionPollingInterval(value: number) { + public static set transactionPollingInterval(value: number | undefined) { (this.constructor as typeof Contract).transactionPollingInterval = value; - Contract.contractWeb3Config.transactionPollingInterval = value; + if (value === undefined) delete Contract.contractWeb3Config.transactionPollingInterval; + else Contract.contractWeb3Config.transactionPollingInterval = value; } public get transactionPollingInterval() { @@ -545,9 +553,10 @@ export class Contract return (this.constructor as typeof Contract).transactionPollingTimeout; } - public static set transactionPollingTimeout(value: number) { + public static set transactionPollingTimeout(value: number | undefined) { (this.constructor as typeof Contract).transactionPollingTimeout = value; - Contract.contractWeb3Config.transactionPollingTimeout = value; + if (value === undefined) delete Contract.contractWeb3Config.transactionPollingTimeout; + else Contract.contractWeb3Config.transactionPollingTimeout = value; } public get transactionPollingTimeout() { @@ -568,9 +577,11 @@ export class Contract return (this.constructor as typeof Contract).transactionReceiptPollingInterval; } - public static set transactionReceiptPollingInterval(value: number) { + public static set transactionReceiptPollingInterval(value: number | undefined) { (this.constructor as typeof Contract).transactionReceiptPollingInterval = value; - Contract.contractWeb3Config.transactionReceiptPollingInterval = value; + if (value === undefined) + delete Contract.contractWeb3Config.transactionReceiptPollingInterval; + else Contract.contractWeb3Config.transactionReceiptPollingInterval = value; } public get transactionReceiptPollingInterval() { @@ -580,7 +591,7 @@ export class Contract ); } - public set transactionReceiptPollingInterval(value: number) { + public set transactionReceiptPollingInterval(value: number | undefined) { super.transactionReceiptPollingInterval = value; } @@ -591,9 +602,11 @@ export class Contract return (this.constructor as typeof Contract).transactionConfirmationPollingInterval; } - public static set transactionConfirmationPollingInterval(value: number) { + public static set transactionConfirmationPollingInterval(value: number | undefined) { (this.constructor as typeof Contract).transactionConfirmationPollingInterval = value; - Contract.contractWeb3Config.transactionConfirmationPollingInterval = value; + if (value === undefined) + delete Contract.contractWeb3Config.transactionConfirmationPollingInterval; + else Contract.contractWeb3Config.transactionConfirmationPollingInterval = value; } public get transactionConfirmationPollingInterval() { @@ -616,7 +629,8 @@ export class Contract public static set blockHeaderTimeout(value: number | undefined) { (this.constructor as typeof Contract).blockHeaderTimeout = value; - Contract.contractWeb3Config.blockHeaderTimeout = value; + if (value === undefined) delete Contract.contractWeb3Config.blockHeaderTimeout; + else Contract.contractWeb3Config.blockHeaderTimeout = value; } public get blockHeaderTimeout() { @@ -634,9 +648,10 @@ export class Contract return (this.constructor as typeof Contract).handleRevert; } - public static set handleRevert(value: boolean) { + public static set handleRevert(value: boolean | undefined) { (this.constructor as typeof Contract).handleRevert = value; - Contract.contractWeb3Config.handleRevert = value; + if (value === undefined) delete Contract.contractWeb3Config.handleRevert; + else Contract.contractWeb3Config.handleRevert = value; } public get handleRevert() { From 3af00ea3b994a0336129eb17de3551ccf34355b6 Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Tue, 24 Jan 2023 12:15:27 +0200 Subject: [PATCH 06/33] Keep only contractWeb3Config for static defaults --- packages/web3-eth-contract/src/contract.ts | 236 +++++---------------- 1 file changed, 57 insertions(+), 179 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index cad020b645c..bdba14f5d8b 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -225,7 +225,6 @@ export class Contract private _methods!: ContractMethodsInterface; private _events!: ContractEventsInterface; - private static readonly contractWeb3Config: Partial = {}; /** * Creates a new contract instance with all its methods and events defined in its {@doclink glossary/json_interface | json interface} object. * @@ -368,82 +367,68 @@ export class Contract } /** - * Can be used to set {@link Contract.defaultAccount} for all contracts. + * The `contractWeb3Config` of type {@link Web3ConfigOptions} is used to set the defaults for all contracts + * + * Specifically you can set: + * + * `defaultAccount` + * `defaultBlock` + * `defaultHardfork` + * `defaultCommon` + * `transactionSendTimeout` + * `transactionBlockTimeout` + * `transactionConfirmationBlocks` + * `transactionPollingInterval` + * `transactionPollingTimeout` + * `transactionReceiptPollingInterval` + * `transactionConfirmationPollingInterval` + * `blockHeaderTimeout` + * `handleRevert` */ - public static get defaultAccount() { - return (this.constructor as typeof Contract).defaultAccount; - } - - public static set defaultAccount(value: Address | undefined) { - (this.constructor as typeof Contract).defaultAccount = value; - if (value === undefined) delete Contract.contractWeb3Config.defaultAccount; - else Contract.contractWeb3Config.defaultAccount = value; - } - public get defaultAccount() { - return super.defaultAccount ?? (this.constructor as typeof Contract).defaultAccount; - } - public set defaultAccount(value: Address | undefined) { - super.defaultAccount = value; - } + public static contractWeb3Config: Partial = {}; /** - * Can be used to set {@link Contract.defaultBlock} for all contracts. + * Can be used to set {@link Contract.defaultAccount} for all contracts. */ - public static get defaultBlock() { - return (this.constructor as typeof Contract).defaultBlock; + public get defaultAccount() { + return ( + super.defaultAccount ?? + (this.constructor as typeof Contract).contractWeb3Config.defaultAccount + ); } - public static set defaultBlock(value: BlockNumberOrTag | undefined) { - (this.constructor as typeof Contract).defaultBlock = value; - if (value === undefined) delete Contract.contractWeb3Config.defaultBlock; - else Contract.contractWeb3Config.defaultBlock = value; + public set defaultAccount(value: Address | undefined) { + super.defaultAccount = value; } public get defaultBlock() { - return super.defaultBlock ?? (this.constructor as typeof Contract).defaultBlock; + return ( + super.defaultBlock ?? + (this.constructor as typeof Contract).contractWeb3Config.defaultBlock + ); } public set defaultBlock(value: BlockNumberOrTag) { super.defaultBlock = value; } - /** - * Can be used to set {@link Contract.defaultHardfork} for all contracts. - */ - public static get defaultHardfork() { - return (this.constructor as typeof Contract).defaultHardfork; - } - - public static set defaultHardfork(value: string | undefined) { - (this.constructor as typeof Contract).defaultHardfork = value; - if (value === undefined) delete Contract.contractWeb3Config.defaultHardfork; - else Contract.contractWeb3Config.defaultHardfork = value; - } - public get defaultHardfork() { - return super.defaultHardfork ?? (this.constructor as typeof Contract).defaultHardfork; + return ( + super.defaultHardfork ?? + (this.constructor as typeof Contract).contractWeb3Config.defaultHardfork + ); } public set defaultHardfork(value: string) { super.defaultHardfork = value; } - /** - * Can be used to set {@link Contract.defaultCommon} for all contracts. - */ - public static get defaultCommon(): Common | undefined { - return (this.constructor as typeof Contract).defaultCommon; - } - - public static set defaultCommon(value: Common | undefined) { - (this.constructor as typeof Contract).defaultCommon = value; - if (value === undefined) delete Contract.contractWeb3Config.defaultCommon; - else Contract.contractWeb3Config.defaultCommon = value; - } - public get defaultCommon(): Common | undefined { - return super.defaultCommon ?? (this.constructor as typeof Contract).defaultCommon; + return ( + super.defaultCommon ?? + (this.constructor as typeof Contract).contractWeb3Config.defaultCommon + ); } public set defaultCommon(value: Common | undefined) { @@ -453,20 +438,10 @@ export class Contract // this.contractWeb3Config.defaultCommon = value; } - public static get transactionSendTimeout() { - return (this.constructor as typeof Contract).transactionSendTimeout; - } - - public static set transactionSendTimeout(value: number | undefined) { - (this.constructor as typeof Contract).transactionSendTimeout = value; - if (value === undefined) delete Contract.contractWeb3Config.transactionSendTimeout; - else Contract.contractWeb3Config.transactionSendTimeout = value; - } - public get transactionSendTimeout() { return ( super.transactionSendTimeout ?? - (this.constructor as typeof Contract).transactionSendTimeout + (this.constructor as typeof Contract).contractWeb3Config.transactionSendTimeout ); } @@ -474,23 +449,10 @@ export class Contract super.transactionSendTimeout = value; } - /** - * Can be used to set {@link Contract.transactionBlockTimeout} for all contracts. - */ - public static get transactionBlockTimeout() { - return (this.constructor as typeof Contract).transactionBlockTimeout; - } - - public static set transactionBlockTimeout(value: number | undefined) { - (this.constructor as typeof Contract).transactionBlockTimeout = value; - if (value === undefined) delete Contract.contractWeb3Config.transactionBlockTimeout; - else Contract.contractWeb3Config.transactionBlockTimeout = value; - } - public get transactionBlockTimeout() { return ( super.transactionBlockTimeout ?? - (this.constructor as typeof Contract).transactionBlockTimeout + (this.constructor as typeof Contract).contractWeb3Config.transactionBlockTimeout ); } @@ -498,23 +460,10 @@ export class Contract super.transactionBlockTimeout = value; } - /** - * Can be used to set {@link Contract.transactionConfirmationBlocks} for all contracts. - */ - public static get transactionConfirmationBlocks() { - return (this.constructor as typeof Contract).transactionConfirmationBlocks; - } - - public static set transactionConfirmationBlocks(value: number | undefined) { - (this.constructor as typeof Contract).transactionConfirmationBlocks = value; - if (value === undefined) delete Contract.contractWeb3Config.transactionConfirmationBlocks; - else Contract.contractWeb3Config.transactionConfirmationBlocks = value; - } - public get transactionConfirmationBlocks() { return ( super.transactionConfirmationBlocks ?? - (this.constructor as typeof Contract).transactionConfirmationBlocks + (this.constructor as typeof Contract).contractWeb3Config.transactionConfirmationBlocks ); } @@ -522,23 +471,10 @@ export class Contract super.transactionConfirmationBlocks = value; } - /** - * Can be used to set {@link Contract.transactionPollingInterval} for all contracts. - */ - public static get transactionPollingInterval() { - return (this.constructor as typeof Contract).transactionPollingInterval; - } - - public static set transactionPollingInterval(value: number | undefined) { - (this.constructor as typeof Contract).transactionPollingInterval = value; - if (value === undefined) delete Contract.contractWeb3Config.transactionPollingInterval; - else Contract.contractWeb3Config.transactionPollingInterval = value; - } - public get transactionPollingInterval() { return ( super.transactionPollingInterval ?? - (this.constructor as typeof Contract).transactionPollingInterval + (this.constructor as typeof Contract).contractWeb3Config.transactionPollingInterval ); } @@ -546,23 +482,10 @@ export class Contract super.transactionPollingInterval = value; } - /** - * Can be used to set {@link Contract.transactionPollingTimeout} for all contracts. - */ - public static get transactionPollingTimeout() { - return (this.constructor as typeof Contract).transactionPollingTimeout; - } - - public static set transactionPollingTimeout(value: number | undefined) { - (this.constructor as typeof Contract).transactionPollingTimeout = value; - if (value === undefined) delete Contract.contractWeb3Config.transactionPollingTimeout; - else Contract.contractWeb3Config.transactionPollingTimeout = value; - } - public get transactionPollingTimeout() { return ( super.transactionPollingTimeout ?? - (this.constructor as typeof Contract).transactionPollingTimeout + (this.constructor as typeof Contract).contractWeb3Config.transactionPollingTimeout ); } @@ -570,24 +493,11 @@ export class Contract super.transactionPollingTimeout = value; } - /** - * Can be used to set {@link Contract.transactionReceiptPollingInterval} for all contracts. - */ - public static get transactionReceiptPollingInterval() { - return (this.constructor as typeof Contract).transactionReceiptPollingInterval; - } - - public static set transactionReceiptPollingInterval(value: number | undefined) { - (this.constructor as typeof Contract).transactionReceiptPollingInterval = value; - if (value === undefined) - delete Contract.contractWeb3Config.transactionReceiptPollingInterval; - else Contract.contractWeb3Config.transactionReceiptPollingInterval = value; - } - public get transactionReceiptPollingInterval() { return ( super.transactionReceiptPollingInterval ?? - (this.constructor as typeof Contract).transactionReceiptPollingInterval + (this.constructor as typeof Contract).contractWeb3Config + .transactionReceiptPollingInterval ); } @@ -595,24 +505,11 @@ export class Contract super.transactionReceiptPollingInterval = value; } - /** - * Can be used to set {@link Contract.transactionConfirmationPollingInterval} for all contracts. - */ - public static get transactionConfirmationPollingInterval() { - return (this.constructor as typeof Contract).transactionConfirmationPollingInterval; - } - - public static set transactionConfirmationPollingInterval(value: number | undefined) { - (this.constructor as typeof Contract).transactionConfirmationPollingInterval = value; - if (value === undefined) - delete Contract.contractWeb3Config.transactionConfirmationPollingInterval; - else Contract.contractWeb3Config.transactionConfirmationPollingInterval = value; - } - public get transactionConfirmationPollingInterval() { return ( super.transactionConfirmationPollingInterval ?? - (this.constructor as typeof Contract).transactionConfirmationPollingInterval + (this.constructor as typeof Contract).contractWeb3Config + .transactionConfirmationPollingInterval ); } @@ -620,42 +517,22 @@ export class Contract super.transactionConfirmationPollingInterval = value; } - /** - * Can be used to set {@link Contract.blockHeaderTimeout} for all contracts. - */ - public static get blockHeaderTimeout() { - return (this.constructor as typeof Contract).blockHeaderTimeout; - } - - public static set blockHeaderTimeout(value: number | undefined) { - (this.constructor as typeof Contract).blockHeaderTimeout = value; - if (value === undefined) delete Contract.contractWeb3Config.blockHeaderTimeout; - else Contract.contractWeb3Config.blockHeaderTimeout = value; - } - public get blockHeaderTimeout() { - return super.blockHeaderTimeout ?? (this.constructor as typeof Contract).blockHeaderTimeout; + return ( + super.blockHeaderTimeout ?? + (this.constructor as typeof Contract).contractWeb3Config.blockHeaderTimeout + ); } public set blockHeaderTimeout(value: number) { super.blockHeaderTimeout = value; } - /** - * Can be used to set {@link Contract.handleRevert} for all contracts. - */ - public static get handleRevert() { - return (this.constructor as typeof Contract).handleRevert; - } - - public static set handleRevert(value: boolean | undefined) { - (this.constructor as typeof Contract).handleRevert = value; - if (value === undefined) delete Contract.contractWeb3Config.handleRevert; - else Contract.contractWeb3Config.handleRevert = value; - } - public get handleRevert() { - return super.handleRevert ?? (this.constructor as typeof Contract).handleRevert; + return ( + super.handleRevert ?? + (this.constructor as typeof Contract).contractWeb3Config.handleRevert + ); } public set handleRevert(value: boolean) { @@ -1112,7 +989,8 @@ export class Contract return validatorUtils.transformJsonDataToAbiFormat(abi.inputs ?? [], params); } catch (error) { throw new Web3ContractError( - `Invalid parameters for method ${abi.name}: ${(error as Error).message}`, + // todo undo formatting, vscode bug + `Invalid parameters for method ${abi.name}: ${(error as Error).message}\``, ); } } From e89e5dc1877b5e75759f4f7dd0ceb92a1c62c952 Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Tue, 24 Jan 2023 12:28:47 +0200 Subject: [PATCH 07/33] Formatting --- packages/web3-eth-contract/src/contract.ts | 44 +++++++++++----------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index bdba14f5d8b..550427ccc1e 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -210,6 +210,28 @@ export class Contract */ public readonly options: ContractOptions; + /** + * The `contractWeb3Config` of type {@link Web3ConfigOptions} is used to set the defaults for all contracts + * + * Specifically you can set: + * + * `defaultAccount` + * `defaultBlock` + * `defaultHardfork` + * `defaultCommon` + * `transactionSendTimeout` + * `transactionBlockTimeout` + * `transactionConfirmationBlocks` + * `transactionPollingInterval` + * `transactionPollingTimeout` + * `transactionReceiptPollingInterval` + * `transactionConfirmationPollingInterval` + * `blockHeaderTimeout` + * `handleRevert` + */ + + public static contractWeb3Config: Partial = {}; + private _errorsInterface!: AbiErrorFragment[]; private _jsonInterface!: ContractAbiWithSignature; private _address?: Address; @@ -366,28 +388,6 @@ export class Contract this.setConfig(Contract.contractWeb3Config); } - /** - * The `contractWeb3Config` of type {@link Web3ConfigOptions} is used to set the defaults for all contracts - * - * Specifically you can set: - * - * `defaultAccount` - * `defaultBlock` - * `defaultHardfork` - * `defaultCommon` - * `transactionSendTimeout` - * `transactionBlockTimeout` - * `transactionConfirmationBlocks` - * `transactionPollingInterval` - * `transactionPollingTimeout` - * `transactionReceiptPollingInterval` - * `transactionConfirmationPollingInterval` - * `blockHeaderTimeout` - * `handleRevert` - */ - - public static contractWeb3Config: Partial = {}; - /** * Can be used to set {@link Contract.defaultAccount} for all contracts. */ From ca3989874303fac541e14d15da3577287eca01f5 Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Fri, 27 Jan 2023 13:50:56 +0200 Subject: [PATCH 08/33] Enable contract instances to listen on global config event changes --- packages/web3-eth-contract/src/contract.ts | 23 +++++++++++++++++++++- packages/web3/src/web3.ts | 16 ++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index 550427ccc1e..b94ff81f1ea 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -15,7 +15,13 @@ You should have received a copy of the GNU Lesser General Public License along with web3.js. If not, see . */ -import { Web3Context, Web3EventEmitter, Web3PromiEvent, Web3ConfigOptions } from 'web3-core'; +import { + Web3Context, + Web3EventEmitter, + Web3PromiEvent, + Web3ConfigOptions, + Web3ConfigEvent, +} from 'web3-core'; import { ContractExecutionError, SubscriptionError, Web3ContractError } from 'web3-errors'; import { call, @@ -232,6 +238,11 @@ export class Contract public static contractWeb3Config: Partial = {}; + /** + * Set to true if you want contracts' defaults to sync with global defaults. + */ + public static sync_with_globals = false; + private _errorsInterface!: AbiErrorFragment[]; private _jsonInterface!: ContractAbiWithSignature; private _address?: Address; @@ -386,6 +397,16 @@ export class Contract }); this.setConfig(Contract.contractWeb3Config); + + // eslint-disable-next-line @typescript-eslint/no-this-alias + const contractThis = this; + + if (Contract.sync_with_globals) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-call, no-restricted-globals + contractThis.on(Web3ConfigEvent.CONFIG_CHANGE, event => { + contractThis.setConfig({ [event.name]: event.newValue }); + }); + } } /** diff --git a/packages/web3/src/web3.ts b/packages/web3/src/web3.ts index 7d0e6a8fc56..3a3c99fd0cb 100644 --- a/packages/web3/src/web3.ts +++ b/packages/web3/src/web3.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 . */ // eslint-disable-next-line max-classes-per-file -import { Web3Context } from 'web3-core'; +import { Web3ConfigEvent, Web3Context } from 'web3-core'; import Web3Eth from 'web3-eth'; import { ContractAbi } from 'web3-eth-abi'; import Contract, { ContractInitOptions } from 'web3-eth-contract'; @@ -92,10 +92,24 @@ export class Web3 extends Web3Context { super(jsonInterface, self.getContextObject()); } + self.on(Web3ConfigEvent.CONFIG_CHANGE, event => { + for (const contract of ContractBuilder._contracts) { + contract.emit(Web3ConfigEvent.CONFIG_CHANGE, event); + } + }); + // eslint-disable-next-line @typescript-eslint/no-explicit-any ContractBuilder._contracts.push(this as Contract); } + public static set sync_with_globals(value: boolean) { + Contract.sync_with_globals = value; + } + + public static get sync_with_globals() { + return Contract.sync_with_globals; + } + public static setProvider(_provider: SupportedProviders): boolean { for (const contract of ContractBuilder._contracts) { contract.provider = _provider; From 56005cb15b56fa7560fb4303332049c3a2edcf00 Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Fri, 27 Jan 2023 13:59:58 +0200 Subject: [PATCH 09/33] Add tests --- packages/web3/test/integration/web3.test.ts | 51 +++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/packages/web3/test/integration/web3.test.ts b/packages/web3/test/integration/web3.test.ts index af4fef27a54..1c69c70350d 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 } 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'; + + web3.eth.Contract.sync_with_globals = true; + contract = new web3.eth.Contract(GreeterAbi, undefined, { + provider: getSystemTestProvider(), + }); + // contract = await contract.deploy(deployOptions).send(sendOptions); + web3.defaultHardfork = hardfork; + + expect(contract.defaultHardfork).toBe(hardfork); + }); + + // todo this is not working + // it('should update defaults on deployed contract instance', async () => { + // const hardfork = 'berlin'; + + // web3.eth.Contract.sync_with_globals = true; + // contract = new web3.eth.Contract(GreeterAbi, undefined, { + // provider: getSystemTestProvider(), + // }); + // contract = await contract.deploy(deployOptions).send(sendOptions); + // web3.defaultHardfork = hardfork; + + // expect(contract.defaultHardfork).toBe(hardfork); + // }); + }); }); From e341b1cec747a80cf48700da8f8dbaef672e6990 Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Fri, 27 Jan 2023 14:01:05 +0200 Subject: [PATCH 10/33] Remove comment --- packages/web3/test/integration/web3.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web3/test/integration/web3.test.ts b/packages/web3/test/integration/web3.test.ts index 1c69c70350d..c259a1f1975 100644 --- a/packages/web3/test/integration/web3.test.ts +++ b/packages/web3/test/integration/web3.test.ts @@ -286,7 +286,7 @@ describe('Web3 instance', () => { contract = new web3.eth.Contract(GreeterAbi, undefined, { provider: getSystemTestProvider(), }); - // contract = await contract.deploy(deployOptions).send(sendOptions); + web3.defaultHardfork = hardfork; expect(contract.defaultHardfork).toBe(hardfork); From 241a5202cf2de2be086f3943430ee944773e36e9 Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Fri, 27 Jan 2023 15:50:15 +0200 Subject: [PATCH 11/33] Fix global defaults on deployed smart contracts --- packages/web3-eth-contract/src/contract.ts | 15 +++++-- packages/web3/src/web3.ts | 5 +++ packages/web3/test/integration/web3.test.ts | 48 ++++++++++----------- 3 files changed, 41 insertions(+), 27 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index b94ff81f1ea..45e7e74bafe 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -15,6 +15,7 @@ You should have received a copy of the GNU Lesser General Public License along with web3.js. If not, see . */ +import { EventEmitter } from 'events'; import { Web3Context, Web3EventEmitter, @@ -258,6 +259,7 @@ export class Contract private _methods!: ContractMethodsInterface; private _events!: ContractEventsInterface; + protected readonly _eventEmitter: EventEmitter = new EventEmitter(); /** * Creates a new contract instance with all its methods and events defined in its {@doclink glossary/json_interface | json interface} object. * @@ -403,7 +405,7 @@ export class Contract if (Contract.sync_with_globals) { // eslint-disable-next-line @typescript-eslint/no-unsafe-call, no-restricted-globals - contractThis.on(Web3ConfigEvent.CONFIG_CHANGE, event => { + this.on(Web3ConfigEvent.CONFIG_CHANGE, event => { contractThis.setConfig({ [event.name]: event.newValue }); }); } @@ -637,8 +639,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, { @@ -653,7 +657,7 @@ export class Contract ); } - return new Contract( + newContract = new Contract( [...this._jsonInterface, ...this._errorsInterface] as unknown as Abi, { gas: this.options.gas, @@ -665,6 +669,10 @@ export class Contract }, this.getContextObject(), ); + + this._eventEmitter.emit('ContractCloned', newContract); + + return newContract; } /** @@ -776,6 +784,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[], diff --git a/packages/web3/src/web3.ts b/packages/web3/src/web3.ts index 3a3c99fd0cb..dc3c05f2139 100644 --- a/packages/web3/src/web3.ts +++ b/packages/web3/src/web3.ts @@ -98,6 +98,11 @@ export class Web3 extends Web3Context { } }); + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + this._eventEmitter.on('ContractCloned', (contract: Contract) => { + ContractBuilder._contracts.push(contract); + }); + // eslint-disable-next-line @typescript-eslint/no-explicit-any ContractBuilder._contracts.push(this as Contract); } diff --git a/packages/web3/test/integration/web3.test.ts b/packages/web3/test/integration/web3.test.ts index c259a1f1975..abfd73d1b18 100644 --- a/packages/web3/test/integration/web3.test.ts +++ b/packages/web3/test/integration/web3.test.ts @@ -33,7 +33,7 @@ import { isWs, waitForOpenConnection, } from '../shared_fixtures/system_tests_utils'; -import { GreeterAbi } from '../shared_fixtures/build/Greeter'; +import { GreeterAbi, GreeterBytecode } from '../shared_fixtures/build/Greeter'; describe('Web3 instance', () => { let clientUrl: string; @@ -259,25 +259,25 @@ describe('Web3 instance', () => { describe('defaults', () => { let contract: Contract; - // let deployOptions: Record; - // let sendOptions: Record; - // let acc: { address: string; privateKey: string }; + let deployOptions: Record; + let sendOptions: Record; + let acc: { address: string; privateKey: string }; beforeAll(() => { web3 = new Web3(clientUrl); }); - // beforeEach(async () => { - // acc = await createTempAccount(); + beforeEach(async () => { + acc = await createTempAccount(); - // // todo import GreeterBytecode - // deployOptions = { - // data: GreeterBytecode, - // arguments: ['My Greeting'], - // }; + // todo import GreeterBytecode + deployOptions = { + data: GreeterBytecode, + arguments: ['My Greeting'], + }; - // sendOptions = { from: acc.address, gas: '1000000' }; - // }); + sendOptions = { from: acc.address, gas: '1000000' }; + }); it('should update defaults on contract instance', () => { const hardfork = 'berlin'; @@ -292,18 +292,18 @@ describe('Web3 instance', () => { expect(contract.defaultHardfork).toBe(hardfork); }); - // todo this is not working - // it('should update defaults on deployed contract instance', async () => { - // const hardfork = 'berlin'; + it('should update defaults on deployed contract instance', async () => { + const hardfork = 'berlin'; - // web3.eth.Contract.sync_with_globals = true; - // contract = new web3.eth.Contract(GreeterAbi, undefined, { - // provider: getSystemTestProvider(), - // }); - // contract = await contract.deploy(deployOptions).send(sendOptions); - // web3.defaultHardfork = hardfork; + web3.eth.Contract.sync_with_globals = true; + contract = new web3.eth.Contract(GreeterAbi, undefined, { + provider: getSystemTestProvider(), + }); + contract = await contract.deploy(deployOptions).send(sendOptions); + + web3.defaultHardfork = hardfork; - // expect(contract.defaultHardfork).toBe(hardfork); - // }); + expect(contract.defaultHardfork).toBe(hardfork); + }); }); }); From e8a4aebbb49b80ba7800bab7432d93d719314ef7 Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Mon, 30 Jan 2023 15:17:28 +0200 Subject: [PATCH 12/33] Fix clone function --- packages/web3-eth-contract/src/contract.ts | 26 +++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index 45e7e74bafe..8e9764b0b8c 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -655,21 +655,21 @@ export class Contract }, 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, + }, + this.getContextObject(), + ); } - 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, - }, - this.getContextObject(), - ); - this._eventEmitter.emit('ContractCloned', newContract); return newContract; From e1d35e05fbaabc5045ae23cdb6cbdc528bbab9ff Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Mon, 30 Jan 2023 15:19:02 +0200 Subject: [PATCH 13/33] Fix defaultAccount inheritance from class level during contract deployment --- packages/web3-eth-contract/src/contract.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index 8e9764b0b8c..9c815f395fb 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -1193,7 +1193,11 @@ export class Contract let modifiedContractOptions = contractOptions ?? this.options; modifiedContractOptions = { ...modifiedContractOptions, - from: modifiedContractOptions.from ?? this.defaultAccount ?? undefined, + from: + modifiedContractOptions.from ?? + this.defaultAccount ?? + Contract.contractWeb3Config.defaultAccount ?? + undefined, }; const tx = getSendTxParams({ From 977854b43ca3745c70c6a032ac58d7e410e5fb65 Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Mon, 30 Jan 2023 15:20:07 +0200 Subject: [PATCH 14/33] Update tests --- .../integration/contract_defaults.test.ts | 15 +- .../contract_defaults_extra.test.ts | 8 +- packages/web3/test/integration/web3.test.ts | 293 ++++++++++++++++++ 3 files changed, 307 insertions(+), 9 deletions(-) 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..c04e36b1550 100644 --- a/packages/web3-eth-contract/test/integration/contract_defaults.test.ts +++ b/packages/web3-eth-contract/test/integration/contract_defaults.test.ts @@ -44,10 +44,13 @@ describe('contract', () => { describe('defaultAccount', () => { it('should use "defaultAccount" on "Contract" level instead of "from"', async () => { // eslint-disable-next-line prefer-destructuring - Contract.defaultAccount = acc.address; + Contract.contractWeb3Config.defaultAccount = acc.address; const receiptHandler = jest.fn(); + contract = new Contract(GreeterAbi, undefined, { + provider: getSystemTestProvider(), + }); // We didn't specify "from" in this call await contract .deploy(deployOptions) @@ -63,7 +66,7 @@ describe('contract', () => { it('should use "defaultAccount" on "instance" level instead of "from"', async () => { const deployedContract = await contract.deploy(deployOptions).send(sendOptions); - Contract.defaultAccount = undefined; + Contract.contractWeb3Config.defaultAccount = undefined; // eslint-disable-next-line prefer-destructuring deployedContract.defaultAccount = acc.address; // We didn't specify "from" in this call @@ -74,7 +77,7 @@ describe('contract', () => { }); it('should throw error when "from" is not set on any level', () => { - Contract.defaultAccount = undefined; + Contract.contractWeb3Config.defaultAccount = undefined; contract.defaultAccount = undefined; expect(() => contract.deploy(deployOptions).send({ gas: '1000000' })).toThrow( @@ -93,7 +96,7 @@ describe('contract', () => { contract.currentProvider as Web3BaseProvider, 'request', ); - Contract.defaultBlock = 'pending'; + Contract.contractWeb3Config.defaultBlock = 'pending'; // Forcefully delete this property from the contract instance // eslint-disable-next-line @typescript-eslint/ban-ts-comment @@ -117,7 +120,7 @@ describe('contract', () => { 'request', ); contract.defaultBlock = 'pending'; - Contract.defaultBlock = undefined; + Contract.contractWeb3Config.defaultBlock = undefined; await contract.methods.greet().call(); @@ -140,7 +143,7 @@ describe('contract', () => { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error contract.defaultBlock = undefined; - Contract.defaultBlock = undefined; + Contract.contractWeb3Config.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 a74b638158b..6c1d5bebd76 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 @@ -66,7 +66,7 @@ describe('contract defaults (extra)', () => { it('should use "defaultHardfork" on "Contract" level', async () => { const hardfork = 'berlin'; - Contract.defaultHardfork = hardfork; + Contract.contractWeb3Config.defaultHardfork = hardfork; contract = new Contract(GreeterAbi, undefined, { provider: getSystemTestProvider(), @@ -93,13 +93,15 @@ describe('contract defaults (extra)', () => { it('should use "defaultHardfork" on "instance" level', async () => { const hardfork = 'berlin'; - contract.defaultHardfork = hardfork; contract = new Contract(GreeterAbi, undefined, { provider: getSystemTestProvider(), }); contract = await contract.deploy(deployOptions).send(sendOptions); + // console.log(!!contract); + contract.defaultHardfork = hardfork; + Contract.contractWeb3Config.defaultHardfork = 'london'; await contract.methods.setGreeting('New Greeting').send(sendOptions); await contract.methods.greet().send(sendOptions); @@ -177,7 +179,7 @@ describe('contract defaults (extra)', () => { }); it('should use "defaultCommon" on "Contract" level', async () => { - Contract.defaultCommon = common; + Contract.contractWeb3Config.defaultCommon = common; contract = new Contract(GreeterAbi, undefined, { provider: getSystemTestProvider(), diff --git a/packages/web3/test/integration/web3.test.ts b/packages/web3/test/integration/web3.test.ts index abfd73d1b18..a16fb11be4a 100644 --- a/packages/web3/test/integration/web3.test.ts +++ b/packages/web3/test/integration/web3.test.ts @@ -20,6 +20,7 @@ import Contract from 'web3-eth-contract'; import HttpProvider from 'web3-providers-http'; import IpcProvider from 'web3-providers-ipc'; import WebsocketProvider from 'web3-providers-ws'; +import { FMT_BYTES, FMT_NUMBER } from 'web3-utils'; import Web3 from '../../src/index'; import { BasicAbi } from '../shared_fixtures/Basic'; import { validEncodeParametersData } from '../shared_fixtures/data'; @@ -35,6 +36,298 @@ import { } from '../shared_fixtures/system_tests_utils'; import { GreeterAbi, GreeterBytecode } from '../shared_fixtures/build/Greeter'; +// describe.only('error', () => { +// // eslint-disable-next-line jest/expect-expect +// it('should throw an error if no contract address is provided', async () => { +// const abi = [ +// { +// inputs: [], +// payable: false, +// stateMutability: 'nonpayable', +// type: 'constructor', +// }, +// { +// anonymous: false, +// inputs: [ +// { +// indexed: true, +// internalType: 'address', +// name: 'owner', +// type: 'address', +// }, +// { +// indexed: true, +// internalType: 'address', +// name: 'spender', +// type: 'address', +// }, +// { +// indexed: false, +// internalType: 'uint256', +// name: 'value', +// type: 'uint256', +// }, +// ], +// name: 'Approval', +// type: 'event', +// }, +// { +// anonymous: false, +// inputs: [ +// { +// indexed: true, +// internalType: 'address', +// name: 'previousOwner', +// type: 'address', +// }, +// { +// indexed: true, +// internalType: 'address', +// name: 'newOwner', +// type: 'address', +// }, +// ], +// name: 'OwnershipTransferred', +// type: 'event', +// }, +// { +// anonymous: false, +// inputs: [ +// { +// indexed: true, +// internalType: 'address', +// name: 'from', +// type: 'address', +// }, +// { indexed: true, internalType: 'address', name: 'to', type: 'address' }, +// { +// indexed: false, +// internalType: 'uint256', +// name: 'value', +// type: 'uint256', +// }, +// ], +// name: 'Transfer', +// type: 'event', +// }, +// { +// constant: true, +// inputs: [], +// name: '_decimals', +// outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], +// payable: false, +// stateMutability: 'view', +// type: 'function', +// }, +// { +// constant: true, +// inputs: [], +// name: '_name', +// outputs: [{ internalType: 'string', name: '', type: 'string' }], +// payable: false, +// stateMutability: 'view', +// type: 'function', +// }, +// { +// constant: true, +// inputs: [], +// name: '_symbol', +// outputs: [{ internalType: 'string', name: '', type: 'string' }], +// payable: false, +// stateMutability: 'view', +// type: 'function', +// }, +// { +// constant: true, +// inputs: [ +// { internalType: 'address', name: 'owner', type: 'address' }, +// { internalType: 'address', name: 'spender', type: 'address' }, +// ], +// name: 'allowance', +// outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], +// payable: false, +// stateMutability: 'view', +// type: 'function', +// }, +// { +// constant: false, +// inputs: [ +// { internalType: 'address', name: 'spender', type: 'address' }, +// { internalType: 'uint256', name: 'amount', type: 'uint256' }, +// ], +// name: 'approve', +// outputs: [{ internalType: 'bool', name: '', type: 'bool' }], +// payable: false, +// stateMutability: 'nonpayable', +// type: 'function', +// }, +// { +// constant: true, +// inputs: [{ internalType: 'address', name: 'account', type: 'address' }], +// name: 'balanceOf', +// outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], +// payable: false, +// stateMutability: 'view', +// type: 'function', +// }, +// { +// constant: false, +// inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], +// name: 'burn', +// outputs: [{ internalType: 'bool', name: '', type: 'bool' }], +// payable: false, +// stateMutability: 'nonpayable', +// type: 'function', +// }, +// { +// constant: true, +// inputs: [], +// name: 'decimals', +// outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], +// payable: false, +// stateMutability: 'view', +// type: 'function', +// }, +// { +// constant: false, +// inputs: [ +// { internalType: 'address', name: 'spender', type: 'address' }, +// { internalType: 'uint256', name: 'subtractedValue', type: 'uint256' }, +// ], +// name: 'decreaseAllowance', +// outputs: [{ internalType: 'bool', name: '', type: 'bool' }], +// payable: false, +// stateMutability: 'nonpayable', +// type: 'function', +// }, +// { +// constant: true, +// inputs: [], +// name: 'getOwner', +// outputs: [{ internalType: 'address', name: '', type: 'address' }], +// payable: false, +// stateMutability: 'view', +// type: 'function', +// }, +// { +// constant: false, +// inputs: [ +// { internalType: 'address', name: 'spender', type: 'address' }, +// { internalType: 'uint256', name: 'addedValue', type: 'uint256' }, +// ], +// name: 'increaseAllowance', +// outputs: [{ internalType: 'bool', name: '', type: 'bool' }], +// payable: false, +// stateMutability: 'nonpayable', +// type: 'function', +// }, +// { +// constant: false, +// inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], +// name: 'mint', +// outputs: [{ internalType: 'bool', name: '', type: 'bool' }], +// payable: false, +// stateMutability: 'nonpayable', +// type: 'function', +// }, +// { +// constant: true, +// inputs: [], +// name: 'name', +// outputs: [{ internalType: 'string', name: '', type: 'string' }], +// payable: false, +// stateMutability: 'view', +// type: 'function', +// }, +// { +// constant: true, +// inputs: [], +// name: 'owner', +// outputs: [{ internalType: 'address', name: '', type: 'address' }], +// payable: false, +// stateMutability: 'view', +// type: 'function', +// }, +// { +// constant: false, +// inputs: [], +// name: 'renounceOwnership', +// outputs: [], +// payable: false, +// stateMutability: 'nonpayable', +// type: 'function', +// }, +// { +// constant: true, +// inputs: [], +// name: 'symbol', +// outputs: [{ internalType: 'string', name: '', type: 'string' }], +// payable: false, +// stateMutability: 'view', +// type: 'function', +// }, +// { +// constant: true, +// inputs: [], +// name: 'totalSupply', +// outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], +// payable: false, +// stateMutability: 'view', +// type: 'function', +// }, +// { +// constant: false, +// inputs: [ +// { internalType: 'address', name: 'recipient', type: 'address' }, +// { internalType: 'uint256', name: 'amount', type: 'uint256' }, +// ], +// name: 'transfer', +// outputs: [{ internalType: 'bool', name: '', type: 'bool' }], +// payable: false, +// stateMutability: 'nonpayable', +// type: 'function', +// }, +// { +// constant: false, +// inputs: [ +// { internalType: 'address', name: 'sender', type: 'address' }, +// { internalType: 'address', name: 'recipient', type: 'address' }, +// { internalType: 'uint256', name: 'amount', type: 'uint256' }, +// ], +// name: 'transferFrom', +// outputs: [{ internalType: 'bool', name: '', type: 'bool' }], +// payable: false, +// stateMutability: 'nonpayable', +// type: 'function', +// }, +// { +// constant: false, +// inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], +// name: 'transferOwnership', +// outputs: [], +// payable: false, +// stateMutability: 'nonpayable', +// type: 'function', +// }, +// ]; +// const web3 = new Web3('https://bsc-dataseed.binance.org'); +// const contract = new web3.eth.Contract(abi, '0xe9e7cea3dedca5984780bafc599bd69add087d56'); + +// const transferEvent = await contract.getPastEvents( +// 'Transfer', +// { +// fromBlock: '2518880', +// toBlock: '2518880', +// }, +// { +// number: FMT_NUMBER.HEX, +// bytes: FMT_BYTES.HEX, +// }, +// ); + +// console.log(transferEvent); +// }); +// }); describe('Web3 instance', () => { let clientUrl: string; let accounts: string[]; From e81f725ac71e3afac3c845814f1c0c42844321b6 Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Mon, 30 Jan 2023 15:48:07 +0200 Subject: [PATCH 15/33] Update test --- .../test/integration/contract_defaults_extra.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 6c1d5bebd76..cf17db02503 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 @@ -381,10 +381,10 @@ describe('contract defaults (extra)', () => { describe('handleRevert', () => { it('should use "handleRevert" on "Contract" level', async () => { - expect(Contract.handleRevert).toBeUndefined(); + expect(Contract.contractWeb3Config.handleRevert).toBeUndefined(); const handleRevert = true; - Contract.handleRevert = handleRevert; + Contract.contractWeb3Config.handleRevert = handleRevert; contract = new Contract(GreeterAbi, undefined, { provider: getSystemTestProvider(), @@ -400,7 +400,7 @@ describe('contract defaults (extra)', () => { expect(sendTransactionSpy).toHaveBeenCalled(); - Contract.handleRevert = false; + Contract.contractWeb3Config.handleRevert = false; }); it('should use "handleRevert" on "instance" level', async () => { From 6b464e0a5f5fc0e073e49ecb94b4e5cce19ee916 Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Mon, 30 Jan 2023 16:13:50 +0200 Subject: [PATCH 16/33] Update test --- .../integration/contract_defaults_extra.test.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) 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 cf17db02503..5a8d6e4928a 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 @@ -159,7 +159,7 @@ describe('contract defaults (extra)', () => { const common = { customChain: { name: 'testnet', networkId: '1337', chainId: '1337' }, baseChain, - hardfork: 'berlin' as Hardfork, + hardfork: 'london' as Hardfork, }; beforeEach(async () => { @@ -295,19 +295,19 @@ describe('contract defaults (extra)', () => { describeIf(isWs)('blockHeaderTimeout', () => { it('should use "blockHeaderTimeout" on "Contract" level', async () => { - expect(Contract.blockHeaderTimeout).toBeUndefined(); + expect(Contract.contractWeb3Config.blockHeaderTimeout).toBeUndefined(); const blockHeaderTimeout = 100; - Contract.blockHeaderTimeout = blockHeaderTimeout; + Contract.contractWeb3Config.blockHeaderTimeout = blockHeaderTimeout; contract = new Contract(GreeterAbi, undefined, { provider: getSystemTestProvider(), }); - expect(Contract.blockHeaderTimeout).toBe(blockHeaderTimeout); + expect(Contract.contractWeb3Config.blockHeaderTimeout).toBe(blockHeaderTimeout); contract = await contract.deploy(deployOptions).send(sendOptions); expect(contract.blockHeaderTimeout).toBe(blockHeaderTimeout); - Contract.blockHeaderTimeout = 10; + Contract.contractWeb3Config.blockHeaderTimeout = 10; }); it('should use "blockHeaderTimout" on "instance" level', async () => { @@ -358,10 +358,10 @@ describe('contract defaults (extra)', () => { describeIf(isHttp)('transactionPollingInterval', () => { it('should use "transactionPollingInterval" on "Contract" level', async () => { - expect(Contract.transactionPollingInterval).toBeUndefined(); + expect(Contract.contractWeb3Config.transactionPollingInterval).toBeUndefined(); const transactionPollingInterval = 500; - Contract.transactionPollingInterval = transactionPollingInterval; + Contract.contractWeb3Config.transactionPollingInterval = transactionPollingInterval; contract = new Contract(GreeterAbi, undefined, { provider: getSystemTestProvider(), From 5fc372c7b0f2c0b540049fe5914a7248fc5e3daa Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Mon, 30 Jan 2023 16:25:56 +0200 Subject: [PATCH 17/33] Delete unused test --- packages/web3/test/integration/web3.test.ts | 293 -------------------- 1 file changed, 293 deletions(-) diff --git a/packages/web3/test/integration/web3.test.ts b/packages/web3/test/integration/web3.test.ts index a16fb11be4a..abfd73d1b18 100644 --- a/packages/web3/test/integration/web3.test.ts +++ b/packages/web3/test/integration/web3.test.ts @@ -20,7 +20,6 @@ import Contract from 'web3-eth-contract'; import HttpProvider from 'web3-providers-http'; import IpcProvider from 'web3-providers-ipc'; import WebsocketProvider from 'web3-providers-ws'; -import { FMT_BYTES, FMT_NUMBER } from 'web3-utils'; import Web3 from '../../src/index'; import { BasicAbi } from '../shared_fixtures/Basic'; import { validEncodeParametersData } from '../shared_fixtures/data'; @@ -36,298 +35,6 @@ import { } from '../shared_fixtures/system_tests_utils'; import { GreeterAbi, GreeterBytecode } from '../shared_fixtures/build/Greeter'; -// describe.only('error', () => { -// // eslint-disable-next-line jest/expect-expect -// it('should throw an error if no contract address is provided', async () => { -// const abi = [ -// { -// inputs: [], -// payable: false, -// stateMutability: 'nonpayable', -// type: 'constructor', -// }, -// { -// anonymous: false, -// inputs: [ -// { -// indexed: true, -// internalType: 'address', -// name: 'owner', -// type: 'address', -// }, -// { -// indexed: true, -// internalType: 'address', -// name: 'spender', -// type: 'address', -// }, -// { -// indexed: false, -// internalType: 'uint256', -// name: 'value', -// type: 'uint256', -// }, -// ], -// name: 'Approval', -// type: 'event', -// }, -// { -// anonymous: false, -// inputs: [ -// { -// indexed: true, -// internalType: 'address', -// name: 'previousOwner', -// type: 'address', -// }, -// { -// indexed: true, -// internalType: 'address', -// name: 'newOwner', -// type: 'address', -// }, -// ], -// name: 'OwnershipTransferred', -// type: 'event', -// }, -// { -// anonymous: false, -// inputs: [ -// { -// indexed: true, -// internalType: 'address', -// name: 'from', -// type: 'address', -// }, -// { indexed: true, internalType: 'address', name: 'to', type: 'address' }, -// { -// indexed: false, -// internalType: 'uint256', -// name: 'value', -// type: 'uint256', -// }, -// ], -// name: 'Transfer', -// type: 'event', -// }, -// { -// constant: true, -// inputs: [], -// name: '_decimals', -// outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], -// payable: false, -// stateMutability: 'view', -// type: 'function', -// }, -// { -// constant: true, -// inputs: [], -// name: '_name', -// outputs: [{ internalType: 'string', name: '', type: 'string' }], -// payable: false, -// stateMutability: 'view', -// type: 'function', -// }, -// { -// constant: true, -// inputs: [], -// name: '_symbol', -// outputs: [{ internalType: 'string', name: '', type: 'string' }], -// payable: false, -// stateMutability: 'view', -// type: 'function', -// }, -// { -// constant: true, -// inputs: [ -// { internalType: 'address', name: 'owner', type: 'address' }, -// { internalType: 'address', name: 'spender', type: 'address' }, -// ], -// name: 'allowance', -// outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], -// payable: false, -// stateMutability: 'view', -// type: 'function', -// }, -// { -// constant: false, -// inputs: [ -// { internalType: 'address', name: 'spender', type: 'address' }, -// { internalType: 'uint256', name: 'amount', type: 'uint256' }, -// ], -// name: 'approve', -// outputs: [{ internalType: 'bool', name: '', type: 'bool' }], -// payable: false, -// stateMutability: 'nonpayable', -// type: 'function', -// }, -// { -// constant: true, -// inputs: [{ internalType: 'address', name: 'account', type: 'address' }], -// name: 'balanceOf', -// outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], -// payable: false, -// stateMutability: 'view', -// type: 'function', -// }, -// { -// constant: false, -// inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], -// name: 'burn', -// outputs: [{ internalType: 'bool', name: '', type: 'bool' }], -// payable: false, -// stateMutability: 'nonpayable', -// type: 'function', -// }, -// { -// constant: true, -// inputs: [], -// name: 'decimals', -// outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], -// payable: false, -// stateMutability: 'view', -// type: 'function', -// }, -// { -// constant: false, -// inputs: [ -// { internalType: 'address', name: 'spender', type: 'address' }, -// { internalType: 'uint256', name: 'subtractedValue', type: 'uint256' }, -// ], -// name: 'decreaseAllowance', -// outputs: [{ internalType: 'bool', name: '', type: 'bool' }], -// payable: false, -// stateMutability: 'nonpayable', -// type: 'function', -// }, -// { -// constant: true, -// inputs: [], -// name: 'getOwner', -// outputs: [{ internalType: 'address', name: '', type: 'address' }], -// payable: false, -// stateMutability: 'view', -// type: 'function', -// }, -// { -// constant: false, -// inputs: [ -// { internalType: 'address', name: 'spender', type: 'address' }, -// { internalType: 'uint256', name: 'addedValue', type: 'uint256' }, -// ], -// name: 'increaseAllowance', -// outputs: [{ internalType: 'bool', name: '', type: 'bool' }], -// payable: false, -// stateMutability: 'nonpayable', -// type: 'function', -// }, -// { -// constant: false, -// inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], -// name: 'mint', -// outputs: [{ internalType: 'bool', name: '', type: 'bool' }], -// payable: false, -// stateMutability: 'nonpayable', -// type: 'function', -// }, -// { -// constant: true, -// inputs: [], -// name: 'name', -// outputs: [{ internalType: 'string', name: '', type: 'string' }], -// payable: false, -// stateMutability: 'view', -// type: 'function', -// }, -// { -// constant: true, -// inputs: [], -// name: 'owner', -// outputs: [{ internalType: 'address', name: '', type: 'address' }], -// payable: false, -// stateMutability: 'view', -// type: 'function', -// }, -// { -// constant: false, -// inputs: [], -// name: 'renounceOwnership', -// outputs: [], -// payable: false, -// stateMutability: 'nonpayable', -// type: 'function', -// }, -// { -// constant: true, -// inputs: [], -// name: 'symbol', -// outputs: [{ internalType: 'string', name: '', type: 'string' }], -// payable: false, -// stateMutability: 'view', -// type: 'function', -// }, -// { -// constant: true, -// inputs: [], -// name: 'totalSupply', -// outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], -// payable: false, -// stateMutability: 'view', -// type: 'function', -// }, -// { -// constant: false, -// inputs: [ -// { internalType: 'address', name: 'recipient', type: 'address' }, -// { internalType: 'uint256', name: 'amount', type: 'uint256' }, -// ], -// name: 'transfer', -// outputs: [{ internalType: 'bool', name: '', type: 'bool' }], -// payable: false, -// stateMutability: 'nonpayable', -// type: 'function', -// }, -// { -// constant: false, -// inputs: [ -// { internalType: 'address', name: 'sender', type: 'address' }, -// { internalType: 'address', name: 'recipient', type: 'address' }, -// { internalType: 'uint256', name: 'amount', type: 'uint256' }, -// ], -// name: 'transferFrom', -// outputs: [{ internalType: 'bool', name: '', type: 'bool' }], -// payable: false, -// stateMutability: 'nonpayable', -// type: 'function', -// }, -// { -// constant: false, -// inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], -// name: 'transferOwnership', -// outputs: [], -// payable: false, -// stateMutability: 'nonpayable', -// type: 'function', -// }, -// ]; -// const web3 = new Web3('https://bsc-dataseed.binance.org'); -// const contract = new web3.eth.Contract(abi, '0xe9e7cea3dedca5984780bafc599bd69add087d56'); - -// const transferEvent = await contract.getPastEvents( -// 'Transfer', -// { -// fromBlock: '2518880', -// toBlock: '2518880', -// }, -// { -// number: FMT_NUMBER.HEX, -// bytes: FMT_BYTES.HEX, -// }, -// ); - -// console.log(transferEvent); -// }); -// }); describe('Web3 instance', () => { let clientUrl: string; let accounts: string[]; From 85929ef178bcf1e52657285c8b327042ae52f22e Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Wed, 1 Feb 2023 14:19:13 +0200 Subject: [PATCH 18/33] Subscribe for global config changes in contract class --- packages/web3-eth-contract/src/contract.ts | 2 +- packages/web3/src/web3.ts | 34 +--------------------- 2 files changed, 2 insertions(+), 34 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index 9c815f395fb..2fe4ec819b2 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -405,7 +405,7 @@ export class Contract if (Contract.sync_with_globals) { // eslint-disable-next-line @typescript-eslint/no-unsafe-call, no-restricted-globals - this.on(Web3ConfigEvent.CONFIG_CHANGE, event => { + super.on(Web3ConfigEvent.CONFIG_CHANGE, event => { contractThis.setConfig({ [event.name]: event.newValue }); }); } diff --git a/packages/web3/src/web3.ts b/packages/web3/src/web3.ts index f4cb924b0cb..3f49043ca68 100644 --- a/packages/web3/src/web3.ts +++ b/packages/web3/src/web3.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 . */ // eslint-disable-next-line max-classes-per-file -import { Web3ConfigEvent, Web3Context } from 'web3-core'; +import { Web3Context } from 'web3-core'; import Web3Eth, { registeredSubscriptions } from 'web3-eth'; import { ContractAbi } from 'web3-eth-abi'; import Contract, { ContractInitOptions } from 'web3-eth-contract'; @@ -68,8 +68,6 @@ export class Web3 extends Web3Context { const self = this; class ContractBuilder extends Contract { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - private static readonly _contracts: Contract[] = []; public constructor(jsonInterface: Abi); public constructor(jsonInterface: Abi, address: Address); public constructor(jsonInterface: Abi, options: ContractInitOptions); @@ -90,36 +88,6 @@ export class Web3 extends Web3Context { } else { super(jsonInterface, self.getContextObject()); } - - self.on(Web3ConfigEvent.CONFIG_CHANGE, event => { - for (const contract of ContractBuilder._contracts) { - contract.emit(Web3ConfigEvent.CONFIG_CHANGE, event); - } - }); - - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call - this._eventEmitter.on('ContractCloned', (contract: Contract) => { - ContractBuilder._contracts.push(contract); - }); - - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ContractBuilder._contracts.push(this as Contract); - } - - public static set sync_with_globals(value: boolean) { - Contract.sync_with_globals = value; - } - - public static get sync_with_globals() { - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return Contract.sync_with_globals; - } - - public static setProvider(_provider: SupportedProviders): boolean { - for (const contract of ContractBuilder._contracts) { - contract.provider = _provider; - } - return true; } } From 3945f44bd71c9484d8036c109bfd20818660c10c Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Wed, 1 Feb 2023 15:00:59 +0200 Subject: [PATCH 19/33] Remove static contract defaults --- packages/web3-eth-contract/src/contract.ts | 181 +-------------------- 1 file changed, 1 insertion(+), 180 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index 2fe4ec819b2..fc8a6e00c4c 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -217,28 +217,6 @@ export class Contract */ public readonly options: ContractOptions; - /** - * The `contractWeb3Config` of type {@link Web3ConfigOptions} is used to set the defaults for all contracts - * - * Specifically you can set: - * - * `defaultAccount` - * `defaultBlock` - * `defaultHardfork` - * `defaultCommon` - * `transactionSendTimeout` - * `transactionBlockTimeout` - * `transactionConfirmationBlocks` - * `transactionPollingInterval` - * `transactionPollingTimeout` - * `transactionReceiptPollingInterval` - * `transactionConfirmationPollingInterval` - * `blockHeaderTimeout` - * `handleRevert` - */ - - public static contractWeb3Config: Partial = {}; - /** * Set to true if you want contracts' defaults to sync with global defaults. */ @@ -398,8 +376,6 @@ export class Contract get: () => this._jsonInterface, }); - this.setConfig(Contract.contractWeb3Config); - // eslint-disable-next-line @typescript-eslint/no-this-alias const contractThis = this; @@ -411,157 +387,6 @@ export class Contract } } - /** - * Can be used to set {@link Contract.defaultAccount} for all contracts. - */ - public get defaultAccount() { - return ( - super.defaultAccount ?? - (this.constructor as typeof Contract).contractWeb3Config.defaultAccount - ); - } - - public set defaultAccount(value: Address | undefined) { - super.defaultAccount = value; - } - - public get defaultBlock() { - return ( - super.defaultBlock ?? - (this.constructor as typeof Contract).contractWeb3Config.defaultBlock - ); - } - - public set defaultBlock(value: BlockNumberOrTag) { - super.defaultBlock = value; - } - - public get defaultHardfork() { - return ( - super.defaultHardfork ?? - (this.constructor as typeof Contract).contractWeb3Config.defaultHardfork - ); - } - - public set defaultHardfork(value: string) { - super.defaultHardfork = value; - } - - public get defaultCommon(): Common | undefined { - return ( - super.defaultCommon ?? - (this.constructor as typeof Contract).contractWeb3Config.defaultCommon - ); - } - - public set defaultCommon(value: Common | undefined) { - super.defaultCommon = value; - // eslint-disable-next-line @typescript-eslint/no-unsafe-call - // (this as unknown as Web3Context).setConfig({ defaultCommon: value }); - // this.contractWeb3Config.defaultCommon = value; - } - - public get transactionSendTimeout() { - return ( - super.transactionSendTimeout ?? - (this.constructor as typeof Contract).contractWeb3Config.transactionSendTimeout - ); - } - - public set transactionSendTimeout(value: number) { - super.transactionSendTimeout = value; - } - - public get transactionBlockTimeout() { - return ( - super.transactionBlockTimeout ?? - (this.constructor as typeof Contract).contractWeb3Config.transactionBlockTimeout - ); - } - - public set transactionBlockTimeout(value: number) { - super.transactionBlockTimeout = value; - } - - public get transactionConfirmationBlocks() { - return ( - super.transactionConfirmationBlocks ?? - (this.constructor as typeof Contract).contractWeb3Config.transactionConfirmationBlocks - ); - } - - public set transactionConfirmationBlocks(value: number) { - super.transactionConfirmationBlocks = value; - } - - public get transactionPollingInterval() { - return ( - super.transactionPollingInterval ?? - (this.constructor as typeof Contract).contractWeb3Config.transactionPollingInterval - ); - } - - public set transactionPollingInterval(value: number) { - super.transactionPollingInterval = value; - } - - public get transactionPollingTimeout() { - return ( - super.transactionPollingTimeout ?? - (this.constructor as typeof Contract).contractWeb3Config.transactionPollingTimeout - ); - } - - public set transactionPollingTimeout(value: number) { - super.transactionPollingTimeout = value; - } - - public get transactionReceiptPollingInterval() { - return ( - super.transactionReceiptPollingInterval ?? - (this.constructor as typeof Contract).contractWeb3Config - .transactionReceiptPollingInterval - ); - } - - public set transactionReceiptPollingInterval(value: number | undefined) { - super.transactionReceiptPollingInterval = value; - } - - public get transactionConfirmationPollingInterval() { - return ( - super.transactionConfirmationPollingInterval ?? - (this.constructor as typeof Contract).contractWeb3Config - .transactionConfirmationPollingInterval - ); - } - - public set transactionConfirmationPollingInterval(value: number | undefined) { - super.transactionConfirmationPollingInterval = value; - } - - public get blockHeaderTimeout() { - return ( - super.blockHeaderTimeout ?? - (this.constructor as typeof Contract).contractWeb3Config.blockHeaderTimeout - ); - } - - public set blockHeaderTimeout(value: number) { - super.blockHeaderTimeout = value; - } - - public get handleRevert() { - return ( - super.handleRevert ?? - (this.constructor as typeof Contract).contractWeb3Config.handleRevert - ); - } - - public set handleRevert(value: boolean) { - super.handleRevert = value; - } - /** * Subscribe to an event. * @@ -1193,11 +1018,7 @@ export class Contract let modifiedContractOptions = contractOptions ?? this.options; modifiedContractOptions = { ...modifiedContractOptions, - from: - modifiedContractOptions.from ?? - this.defaultAccount ?? - Contract.contractWeb3Config.defaultAccount ?? - undefined, + from: modifiedContractOptions.from ?? this.defaultAccount ?? undefined, }; const tx = getSendTxParams({ From ae4dca40f58dd8adbbab0a70dc2eb50e7e69e020 Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Wed, 1 Feb 2023 15:26:12 +0200 Subject: [PATCH 20/33] Remove tests using static contract defaults --- packages/web3-eth-contract/src/contract.ts | 9 +- .../integration/contract_defaults.test.ts | 81 ++------- .../contract_defaults_extra.test.ts | 167 ++++-------------- 3 files changed, 46 insertions(+), 211 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index fc8a6e00c4c..73bd179ba7f 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -16,13 +16,7 @@ along with web3.js. If not, see . */ import { EventEmitter } from 'events'; -import { - Web3Context, - Web3EventEmitter, - Web3PromiEvent, - Web3ConfigOptions, - Web3ConfigEvent, -} from 'web3-core'; +import { Web3Context, Web3EventEmitter, Web3PromiEvent, Web3ConfigEvent } from 'web3-core'; import { ContractExecutionError, SubscriptionError, Web3ContractError } from 'web3-errors'; import { call, @@ -63,7 +57,6 @@ import { HexString, LogsInput, Mutable, - Common, } from 'web3-types'; import { DataFormat, 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 c04e36b1550..5b5e6db8dea 100644 --- a/packages/web3-eth-contract/test/integration/contract_defaults.test.ts +++ b/packages/web3-eth-contract/test/integration/contract_defaults.test.ts @@ -41,75 +41,26 @@ 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.contractWeb3Config.defaultAccount = acc.address; - - const receiptHandler = jest.fn(); - - contract = new Contract(GreeterAbi, undefined, { - provider: getSystemTestProvider(), - }); - // 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.contractWeb3Config.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 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); + }); - it('should throw error when "from" is not set on any level', () => { - Contract.contractWeb3Config.defaultAccount = undefined; - contract.defaultAccount = undefined; + it('should throw error when "from" is not set on any level', () => { + contract.defaultAccount = undefined; - expect(() => contract.deploy(deployOptions).send({ gas: '1000000' })).toThrow( - 'Contract "from" address not specified', - ); - }); + expect(() => contract.deploy(deployOptions).send({ gas: '1000000' })).toThrow( + 'Contract "from" address not specified', + ); }); 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); - - const requestSpy = jest.spyOn( - contract.currentProvider as Web3BaseProvider, - 'request', - ); - Contract.contractWeb3Config.defaultBlock = 'pending'; - - // Forcefully delete this property from the contract instance - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-expect-error - contract.defaultBlock = undefined; - - await contract.methods.greet().call(); - - expect(requestSpy).toHaveBeenCalledWith( - expect.objectContaining({ params: [expect.any(Object), 'pending'] }), - ); - }); - it('should use "defaultBlock" on "instance" level', async () => { contract = await contract.deploy(deployOptions).send(sendOptions); @@ -120,7 +71,6 @@ describe('contract', () => { 'request', ); contract.defaultBlock = 'pending'; - Contract.contractWeb3Config.defaultBlock = undefined; await contract.methods.greet().call(); @@ -143,7 +93,6 @@ describe('contract', () => { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error contract.defaultBlock = undefined; - Contract.contractWeb3Config.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 5a8d6e4928a..916f62e9ce1 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 @@ -62,64 +62,33 @@ describe('contract defaults (extra)', () => { afterEach(async () => { await closeOpenConnection(contract); }); - describe('defaultHardfork', () => { - it('should use "defaultHardfork" on "Contract" level', async () => { - const hardfork = 'berlin'; - Contract.contractWeb3Config.defaultHardfork = hardfork; + it('should use "defaultHardfork" on "instance" level', async () => { + const hardfork = 'berlin'; - contract = new Contract(GreeterAbi, undefined, { - provider: getSystemTestProvider(), - }); - - const sendTransactionSpy = jest.spyOn(Web3Eth, 'sendTransaction'); - - contract = await contract.deploy(deployOptions).send(sendOptions); - - expect(contract.defaultHardfork).toBe(hardfork); - - await contract.methods.greet().call(); - - await contract.methods.setGreeting('New Greeting').send(sendOptions); - - 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 = new Contract(GreeterAbi, undefined, { - provider: getSystemTestProvider(), - }); - - contract = await contract.deploy(deployOptions).send(sendOptions); - // console.log(!!contract); - contract.defaultHardfork = hardfork; - Contract.contractWeb3Config.defaultHardfork = 'london'; + contract = await contract.deploy(deployOptions).send(sendOptions); + contract.defaultHardfork = hardfork; - 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', () => { @@ -178,29 +147,6 @@ describe('contract defaults (extra)', () => { contract = await contract.deploy(deployOptions).send(sendOptions); }); - it('should use "defaultCommon" on "Contract" level', async () => { - Contract.contractWeb3Config.defaultCommon = common; - - contract = new Contract(GreeterAbi, undefined, { - provider: getSystemTestProvider(), - }); - - contract = await contract.deploy(deployOptions).send(sendOptions); - 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'); @@ -294,22 +240,6 @@ describe('contract defaults (extra)', () => { }); describeIf(isWs)('blockHeaderTimeout', () => { - it('should use "blockHeaderTimeout" on "Contract" level', async () => { - expect(Contract.contractWeb3Config.blockHeaderTimeout).toBeUndefined(); - const blockHeaderTimeout = 100; - Contract.contractWeb3Config.blockHeaderTimeout = blockHeaderTimeout; - - contract = new Contract(GreeterAbi, undefined, { - provider: getSystemTestProvider(), - }); - - expect(Contract.contractWeb3Config.blockHeaderTimeout).toBe(blockHeaderTimeout); - contract = await contract.deploy(deployOptions).send(sendOptions); - - expect(contract.blockHeaderTimeout).toBe(blockHeaderTimeout); - Contract.contractWeb3Config.blockHeaderTimeout = 10; - }); - it('should use "blockHeaderTimout" on "instance" level', async () => { contract = new Contract(GreeterAbi, undefined, { provider: getSystemTestProvider(), @@ -357,18 +287,6 @@ describe('contract defaults (extra)', () => { }); describeIf(isHttp)('transactionPollingInterval', () => { - it('should use "transactionPollingInterval" on "Contract" level', async () => { - expect(Contract.contractWeb3Config.transactionPollingInterval).toBeUndefined(); - - const transactionPollingInterval = 500; - Contract.contractWeb3Config.transactionPollingInterval = transactionPollingInterval; - - contract = new Contract(GreeterAbi, undefined, { - provider: getSystemTestProvider(), - }); - expect(contract.transactionPollingInterval).toBe(transactionPollingInterval); - }); - it('should use "transactionPollingTimeout" on "instance" level', async () => { contract = await contract.deploy(deployOptions).send(sendOptions); @@ -379,49 +297,24 @@ describe('contract defaults (extra)', () => { }); }); - describe('handleRevert', () => { - it('should use "handleRevert" on "Contract" level', async () => { - expect(Contract.contractWeb3Config.handleRevert).toBeUndefined(); - - const handleRevert = true; - Contract.contractWeb3Config.handleRevert = handleRevert; - - contract = new Contract(GreeterAbi, undefined, { - provider: getSystemTestProvider(), - }); - - contract = await contract.deploy(deployOptions).send(sendOptions); - - expect(contract.handleRevert).toBe(handleRevert); - - const sendTransactionSpy = jest.spyOn(Web3Eth, 'sendTransaction'); - - await contract.methods.setGreeting('New Greeting').send(sendOptions); - - expect(sendTransactionSpy).toHaveBeenCalled(); - - Contract.contractWeb3Config.handleRevert = false; + it('should use "handleRevert" on "instance" level', async () => { + contract = new Contract(GreeterAbi, undefined, { + provider: getSystemTestProvider(), }); - it('should use "handleRevert" on "instance" level', async () => { - contract = new Contract(GreeterAbi, undefined, { - provider: getSystemTestProvider(), - }); + 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(); }); }); From b05402b04282ef9308d92d0aa4f1d30eae063fab Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Wed, 1 Feb 2023 15:58:42 +0200 Subject: [PATCH 21/33] Fix failing test --- .../test/integration/contract_defaults_extra.test.ts | 4 ++++ 1 file changed, 4 insertions(+) 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 916f62e9ce1..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 @@ -288,6 +288,10 @@ describe('contract defaults (extra)', () => { describeIf(isHttp)('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; From 1a834f2f7483f8aa52d3c8b510872a35d8f654f5 Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Thu, 2 Feb 2023 14:21:52 +0200 Subject: [PATCH 22/33] Fix global defaults on smart contracts --- packages/web3-eth-contract/src/contract.ts | 25 +++++++++++++--------- packages/web3/src/web3.ts | 11 ++++++++++ 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index 73bd179ba7f..d4b088ae20e 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -368,16 +368,6 @@ export class Contract set: (value: ContractAbi) => this._parseAndSetJsonInterface(value, returnDataFormat), get: () => this._jsonInterface, }); - - // eslint-disable-next-line @typescript-eslint/no-this-alias - const contractThis = this; - - if (Contract.sync_with_globals) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-call, no-restricted-globals - super.on(Web3ConfigEvent.CONFIG_CHANGE, event => { - contractThis.setConfig({ [event.name]: event.newValue }); - }); - } } /** @@ -1099,4 +1089,19 @@ export class Contract return sub; }; } + + protected suscribeToGlobalEvents(context: T): void { + // eslint-disable-next-line @typescript-eslint/no-this-alias + const contractThis = this; + + if (Contract.sync_with_globals) { + context.on(Web3ConfigEvent.CONFIG_CHANGE, event => { + contractThis.setConfig({ [event.name]: event.newValue }); + }); + } + + this._eventEmitter.on('ContractCloned', newContract => { + this.suscribeToGlobalEvents.call(newContract, context); + }); + } } diff --git a/packages/web3/src/web3.ts b/packages/web3/src/web3.ts index 3f49043ca68..9d73006b82d 100644 --- a/packages/web3/src/web3.ts +++ b/packages/web3/src/web3.ts @@ -88,6 +88,17 @@ export class Web3 extends Web3Context { } else { super(jsonInterface, self.getContextObject()); } + + super.suscribeToGlobalEvents(self); + } + + public static set sync_with_globals(value: boolean) { + Contract.sync_with_globals = value; + } + + public static get sync_with_globals() { + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return Contract.sync_with_globals; } } From 2682573176ad68d5bc951771cc2fb86ed546d2c6 Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Thu, 2 Feb 2023 22:50:26 +0200 Subject: [PATCH 23/33] Address feedback --- packages/web3-eth-contract/src/contract.ts | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index d4b088ae20e..305d0d2f8a1 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -230,7 +230,7 @@ export class Contract private _methods!: ContractMethodsInterface; private _events!: ContractEventsInterface; - protected readonly _eventEmitter: EventEmitter = new EventEmitter(); + private context?: Web3Context; /** * Creates a new contract instance with all its methods and events defined in its {@doclink glossary/json_interface | json interface} object. * @@ -478,7 +478,7 @@ export class Contract ); } - this._eventEmitter.emit('ContractCloned', newContract); + newContract.suscribeToGlobalEvents(this.context as Web3Context); return newContract; } @@ -1082,9 +1082,6 @@ export class Contract sub.emit('error', new SubscriptionError('Failed to get past events.')); }); } - this.subscriptionManager?.addSubscription(sub).catch(() => { - sub.emit('error', new SubscriptionError('Failed to subscribe.')); - }); return sub; }; @@ -1093,15 +1090,12 @@ export class Contract protected suscribeToGlobalEvents(context: T): void { // eslint-disable-next-line @typescript-eslint/no-this-alias const contractThis = this; + this.context = context; if (Contract.sync_with_globals) { context.on(Web3ConfigEvent.CONFIG_CHANGE, event => { contractThis.setConfig({ [event.name]: event.newValue }); }); } - - this._eventEmitter.on('ContractCloned', newContract => { - this.suscribeToGlobalEvents.call(newContract, context); - }); } } From f7647da3701649b61e012ca96c1a87911b2feb24 Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Thu, 2 Feb 2023 23:04:27 +0200 Subject: [PATCH 24/33] Remove unused import --- packages/web3-eth-contract/src/contract.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index 305d0d2f8a1..70eaadc114a 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -15,7 +15,6 @@ You should have received a copy of the GNU Lesser General Public License along with web3.js. If not, see . */ -import { EventEmitter } from 'events'; import { Web3Context, Web3EventEmitter, Web3PromiEvent, Web3ConfigEvent } from 'web3-core'; import { ContractExecutionError, SubscriptionError, Web3ContractError } from 'web3-errors'; import { From f2d1b588bdb9ad4becd313ac03386c89e6b38309 Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Fri, 3 Feb 2023 00:07:49 +0200 Subject: [PATCH 25/33] fix --- packages/web3-eth-contract/src/contract.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index 70eaadc114a..3ae68df0d2f 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -1081,6 +1081,9 @@ export class Contract sub.emit('error', new SubscriptionError('Failed to get past events.')); }); } + this.subscriptionManager?.addSubscription(sub).catch(() => { + sub.emit('error', new SubscriptionError('Failed to subscribe.')); + }); return sub; }; From 54dc58ef8692207eb004dc91f58dfcb4ba56e432 Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Fri, 3 Feb 2023 13:13:12 +0200 Subject: [PATCH 26/33] Remove formatting error --- packages/web3-eth-contract/src/contract.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index 3ae68df0d2f..7da43724050 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -826,8 +826,7 @@ export class Contract return validatorUtils.transformJsonDataToAbiFormat(abi.inputs ?? [], params); } catch (error) { throw new Web3ContractError( - // todo undo formatting, vscode bug - `Invalid parameters for method ${abi.name}: ${(error as Error).message}\``, + `Invalid parameters for method ${abi.name}: ${(error as Error).message}`, ); } } From d8469bdda2a63138ced0d52e1c08c857d8613b7e Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Fri, 3 Feb 2023 14:54:01 +0200 Subject: [PATCH 27/33] move syncWithContext in contract init options --- packages/web3-eth-contract/src/contract.ts | 4 ++-- packages/web3/src/web3.ts | 11 +---------- packages/web3/test/integration/web3.test.ts | 4 ++-- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index 7da43724050..26734180120 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -477,7 +477,7 @@ export class Contract ); } - newContract.suscribeToGlobalEvents(this.context as Web3Context); + newContract.subscribeToGlobalEvents(this.context as Web3Context); return newContract; } @@ -1088,7 +1088,7 @@ export class Contract }; } - protected suscribeToGlobalEvents(context: T): void { + protected subscribeToGlobalEvents(context: T): void { // eslint-disable-next-line @typescript-eslint/no-this-alias const contractThis = this; this.context = context; diff --git a/packages/web3/src/web3.ts b/packages/web3/src/web3.ts index 9d73006b82d..1a4ae49f518 100644 --- a/packages/web3/src/web3.ts +++ b/packages/web3/src/web3.ts @@ -89,16 +89,7 @@ export class Web3 extends Web3Context { super(jsonInterface, self.getContextObject()); } - super.suscribeToGlobalEvents(self); - } - - public static set sync_with_globals(value: boolean) { - Contract.sync_with_globals = value; - } - - public static get sync_with_globals() { - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return Contract.sync_with_globals; + super.subscribeToGlobalEvents(self); } } diff --git a/packages/web3/test/integration/web3.test.ts b/packages/web3/test/integration/web3.test.ts index abfd73d1b18..c831cbd164a 100644 --- a/packages/web3/test/integration/web3.test.ts +++ b/packages/web3/test/integration/web3.test.ts @@ -282,9 +282,9 @@ describe('Web3 instance', () => { it('should update defaults on contract instance', () => { const hardfork = 'berlin'; - web3.eth.Contract.sync_with_globals = true; contract = new web3.eth.Contract(GreeterAbi, undefined, { provider: getSystemTestProvider(), + syncWithContext: true, }); web3.defaultHardfork = hardfork; @@ -295,9 +295,9 @@ describe('Web3 instance', () => { it('should update defaults on deployed contract instance', async () => { const hardfork = 'berlin'; - web3.eth.Contract.sync_with_globals = true; contract = new web3.eth.Contract(GreeterAbi, undefined, { provider: getSystemTestProvider(), + syncWithContext: true, }); contract = await contract.deploy(deployOptions).send(sendOptions); From ca1950396e8d71505e292e2a2581b0ec3ac43d6e Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Fri, 3 Feb 2023 15:06:32 +0200 Subject: [PATCH 28/33] move syncWithContext in contract init options --- packages/web3-eth-contract/src/contract.ts | 10 ++++++---- packages/web3-eth-contract/src/types.ts | 4 ++++ packages/web3-eth-contract/src/utils.ts | 13 ++++++++++--- packages/web3/src/web3.ts | 2 +- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index 26734180120..c1a97c9f636 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -212,7 +212,7 @@ export class Contract /** * Set to true if you want contracts' defaults to sync with global defaults. */ - public static sync_with_globals = false; + public syncWithContext = false; private _errorsInterface!: AbiErrorFragment[]; private _jsonInterface!: ContractAbiWithSignature; @@ -358,6 +358,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, @@ -477,7 +479,7 @@ export class Contract ); } - newContract.subscribeToGlobalEvents(this.context as Web3Context); + newContract.subscribeToContextEvents(this.context as Web3Context); return newContract; } @@ -1088,12 +1090,12 @@ export class Contract }; } - protected subscribeToGlobalEvents(context: T): void { + protected subscribeToContextEvents(context: T): void { // eslint-disable-next-line @typescript-eslint/no-this-alias const contractThis = this; this.context = context; - if (Contract.sync_with_globals) { + 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 e6777cf6fcd..6343c7b505c 100644 --- a/packages/web3-eth-contract/src/types.ts +++ b/packages/web3-eth-contract/src/types.ts @@ -150,6 +150,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 7d8b47f0625..8644e9be498 100644 --- a/packages/web3-eth-contract/src/utils.ts +++ b/packages/web3-eth-contract/src/utils.ts @@ -136,9 +136,16 @@ export const getEstimateGasParams = ({ export const isContractInitOptions = (options: unknown): options is ContractOptions => 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/src/web3.ts b/packages/web3/src/web3.ts index 1a4ae49f518..0a14776d930 100644 --- a/packages/web3/src/web3.ts +++ b/packages/web3/src/web3.ts @@ -89,7 +89,7 @@ export class Web3 extends Web3Context { super(jsonInterface, self.getContextObject()); } - super.subscribeToGlobalEvents(self); + super.subscribeToContextEvents(self); } } From d550ef8911abc49905cb57d95494fa329369b035 Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Fri, 3 Feb 2023 17:09:11 +0200 Subject: [PATCH 29/33] Fix and test --- packages/web3-eth-contract/src/contract.ts | 6 ++++-- packages/web3-eth-contract/src/utils.ts | 3 ++- .../test/integration/contract_defaults.test.ts | 11 +++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index c1a97c9f636..ea88acc7942 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -461,6 +461,7 @@ export class Contract from: this.options.from, data: this.options.data, provider: this.currentProvider, + syncWithContext: this.syncWithContext, }, this.getContextObject(), ); @@ -474,12 +475,12 @@ export class Contract from: this.options.from, data: this.options.data, provider: this.currentProvider, + syncWithContext: this.syncWithContext, }, this.getContextObject(), ); } - - newContract.subscribeToContextEvents(this.context as Web3Context); + if (this.context) newContract.subscribeToContextEvents(this.context); return newContract; } @@ -1018,6 +1019,7 @@ export class Contract } const newContract = this.clone(); + // newContract.subscribeToContextEvents(this.context as Web3Context); // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access newContract.options.address = receipt.contractAddress; diff --git a/packages/web3-eth-contract/src/utils.ts b/packages/web3-eth-contract/src/utils.ts index 8644e9be498..53baa6dbdf8 100644 --- a/packages/web3-eth-contract/src/utils.ts +++ b/packages/web3-eth-contract/src/utils.ts @@ -25,6 +25,7 @@ import { PayableCallOptions, ContractOptions, Web3ContractContext, + ContractInitOptions, } from './types'; export const getSendTxParams = ({ @@ -133,7 +134,7 @@ 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) && [ 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 5b5e6db8dea..5e631e69ba9 100644 --- a/packages/web3-eth-contract/test/integration/contract_defaults.test.ts +++ b/packages/web3-eth-contract/test/integration/contract_defaults.test.ts @@ -60,6 +60,17 @@ describe('contract', () => { ); }); + it('should set syncWithContext from init options', async () => { + contract = new Contract(GreeterAbi, { + provider: getSystemTestProvider(), + syncWithContext: true, + }); + + contract = await contract.deploy(deployOptions).send(sendOptions); + + expect(contract.syncWithContext).toBeTruthy(); + }); + describe('defaultBlock', () => { it('should use "defaultBlock" on "instance" level', async () => { contract = await contract.deploy(deployOptions).send(sendOptions); From e0daec23120a47e4e4fccc64dd5acff816d95bb6 Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Fri, 3 Feb 2023 17:12:08 +0200 Subject: [PATCH 30/33] Update changelog --- packages/web3-eth-contract/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/web3-eth-contract/CHANGELOG.md b/packages/web3-eth-contract/CHANGELOG.md index 4b5feba18a6..8f98e2a0d50 100644 --- a/packages/web3-eth-contract/CHANGELOG.md +++ b/packages/web3-eth-contract/CHANGELOG.md @@ -215,3 +215,7 @@ const transactionHash = receipt.transactionHash; - web3.js dependencies (#5757) ## [Unreleased] + +### Fixed + +- Fix contract defaults (#5756) From d5483a0b9dba50f4a090cda0bf42f74dda665e10 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 6 Feb 2023 19:46:29 -1000 Subject: [PATCH 31/33] Update packages/web3-eth-contract/CHANGELOG.md --- packages/web3-eth-contract/CHANGELOG.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/web3-eth-contract/CHANGELOG.md b/packages/web3-eth-contract/CHANGELOG.md index 2de0c77aa5f..440a4b092ee 100644 --- a/packages/web3-eth-contract/CHANGELOG.md +++ b/packages/web3-eth-contract/CHANGELOG.md @@ -220,9 +220,7 @@ const transactionHash = receipt.transactionHash; - Fix contract defaults (#5756) -### Fixed - -- Fix contract defaults (#5756) +### Changed - Update imports statements for objects that was moved between web3 packages (#5771) ### Added From d8c8250512b014b43597bd37db285aa021f50257 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 6 Feb 2023 19:46:57 -1000 Subject: [PATCH 32/33] Update packages/web3-eth-contract/CHANGELOG.md --- packages/web3-eth-contract/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/web3-eth-contract/CHANGELOG.md b/packages/web3-eth-contract/CHANGELOG.md index 440a4b092ee..7c165a0eeb5 100644 --- a/packages/web3-eth-contract/CHANGELOG.md +++ b/packages/web3-eth-contract/CHANGELOG.md @@ -221,6 +221,7 @@ const transactionHash = receipt.transactionHash; - Fix contract defaults (#5756) ### Changed + - Update imports statements for objects that was moved between web3 packages (#5771) ### Added From 2ca87259a8af87d7a4319536e07a70fe2c32a231 Mon Sep 17 00:00:00 2001 From: Nikos Iliakis Date: Tue, 7 Feb 2023 11:57:54 +0200 Subject: [PATCH 33/33] Remove comment --- packages/web3-eth-contract/src/contract.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index ab78bc10fca..5fd3bc0211c 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -1019,7 +1019,6 @@ export class Contract } const newContract = this.clone(); - // newContract.subscribeToContextEvents(this.context as Web3Context); // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access newContract.options.address = receipt.contractAddress;