From 2493268be51f1cb15d988c051ce0c621211afd13 Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Tue, 29 Nov 2022 16:01:56 +0100 Subject: [PATCH 1/9] use Error ABI when sending a transaction --- packages/web3-eth-contract/src/contract.ts | 26 +++++++++++++--------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index b7ce2ab9f6e..dffa896f04e 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -1019,9 +1019,9 @@ export class Contract return { arguments: abiParams, call: async (options?: PayableCallOptions, block?: BlockNumberOrTag) => - this._contractMethodCall(methodAbi, abiParams, errorsAbis, options, block), + this._contractMethodCall(methodAbi, errorsAbis, abiParams, options, block), send: (options?: PayableTxOptions) => - this._contractMethodSend(methodAbi, abiParams, options), // TODO: refactor to parse errorsAbi #5587 + this._contractMethodSend(methodAbi, errorsAbis, abiParams, options), estimateGas: async < ReturnFormat extends DataFormat = typeof DEFAULT_RETURN_FORMAT, >( @@ -1043,9 +1043,9 @@ export class Contract return { arguments: abiParams, call: async (options?: NonPayableCallOptions, block?: BlockNumberOrTag) => - this._contractMethodCall(methodAbi, abiParams, errorsAbis, options, block), + this._contractMethodCall(methodAbi, errorsAbis, abiParams, options, block), send: (options?: NonPayableTxOptions) => - this._contractMethodSend(methodAbi, abiParams, options), // TODO: refactor to parse errorsAbi #5587 + this._contractMethodSend(methodAbi, errorsAbis, abiParams, options), estimateGas: async ( options?: NonPayableCallOptions, returnFormat: ReturnFormat = DEFAULT_RETURN_FORMAT as ReturnFormat, @@ -1064,13 +1064,10 @@ export class Contract }; } - private async _contractMethodCall< - E extends AbiErrorFragment, - Options extends PayableCallOptions | NonPayableCallOptions, - >( + private async _contractMethodCall( abi: AbiFunctionFragment, + errorsAbi: AbiErrorFragment[], params: unknown[], - errorsAbi: E[], options?: Options, block?: BlockNumberOrTag, ) { @@ -1097,6 +1094,7 @@ export class Contract private _contractMethodSend( abi: AbiFunctionFragment, + errorsAbi: AbiErrorFragment[], params: unknown[], options?: Options, contractOptions?: ContractOptions, @@ -1115,7 +1113,15 @@ export class Contract contractOptions: modifiedContractOptions, }); - return sendTransaction(this, tx, DEFAULT_RETURN_FORMAT); + try { + return sendTransaction(this, tx, DEFAULT_RETURN_FORMAT); + } catch (error: unknown) { + if (error instanceof ContractExecutionError) { + // this will parse the error data by trying to decode the ABI error inputs according to EIP-838 + decodeErrorData(errorsAbi, error.innerError); + } + throw error; + } } private _contractMethodDeploySend( From 5b534464c64da62fcd601fa87ff8a3bb0a9de525 Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Tue, 29 Nov 2022 16:18:39 +0100 Subject: [PATCH 2/9] update CHANGELOG.md for #5587 --- CHANGELOG.md | 4 ++++ packages/web3-eth-contract/CHANGELOG.md | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd4aa45dcd3..9dcfaece5d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -895,6 +895,10 @@ should use 4.0.1-alpha.0 for testing. ### Added +#### web3-eth-contract + +- Decoding error data, using Error ABI if available, if error was returned from a smart contract function call (#5587). + #### web3-types - These types were moved from `web3-eth-accounts` to `web3-types` package: Cipher, CipherOptions, ScryptParams, PBKDF2SHA256Params, KeyStore (#5581 ) diff --git a/packages/web3-eth-contract/CHANGELOG.md b/packages/web3-eth-contract/CHANGELOG.md index 7b75e845291..db4994be14b 100644 --- a/packages/web3-eth-contract/CHANGELOG.md +++ b/packages/web3-eth-contract/CHANGELOG.md @@ -184,6 +184,10 @@ const transactionHash = receipt.transactionHash; ## [Unreleased] +### Added + +- Decoding error data, using Error ABI if available, if error was returned from a smart contract function call (#5587). + ### Fixed - Emit past contract events based on `fromBlock` when passed to `contract.events.someEventName` (#5201) From 8607b60b62d82bb8149b939d639a05948df8cbd9 Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Mon, 5 Dec 2022 13:20:27 +0100 Subject: [PATCH 3/9] use async await at internal function _contractMethodSend --- packages/web3-eth-contract/src/contract.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index dffa896f04e..f7625d84626 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -1020,7 +1020,7 @@ export class Contract arguments: abiParams, call: async (options?: PayableCallOptions, block?: BlockNumberOrTag) => this._contractMethodCall(methodAbi, errorsAbis, abiParams, options, block), - send: (options?: PayableTxOptions) => + send: async (options?: PayableTxOptions) => this._contractMethodSend(methodAbi, errorsAbis, abiParams, options), estimateGas: async < ReturnFormat extends DataFormat = typeof DEFAULT_RETURN_FORMAT, @@ -1044,7 +1044,7 @@ export class Contract arguments: abiParams, call: async (options?: NonPayableCallOptions, block?: BlockNumberOrTag) => this._contractMethodCall(methodAbi, errorsAbis, abiParams, options, block), - send: (options?: NonPayableTxOptions) => + send: async (options?: NonPayableTxOptions) => this._contractMethodSend(methodAbi, errorsAbis, abiParams, options), estimateGas: async ( options?: NonPayableCallOptions, @@ -1092,7 +1092,7 @@ export class Contract } } - private _contractMethodSend( + private async _contractMethodSend( abi: AbiFunctionFragment, errorsAbi: AbiErrorFragment[], params: unknown[], @@ -1114,7 +1114,7 @@ export class Contract }); try { - return sendTransaction(this, tx, DEFAULT_RETURN_FORMAT); + return await sendTransaction(this, tx, DEFAULT_RETURN_FORMAT); } catch (error: unknown) { if (error instanceof ContractExecutionError) { // this will parse the error data by trying to decode the ABI error inputs according to EIP-838 From d7779badac459afe6382da734becf7004559a208 Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Mon, 5 Dec 2022 13:24:34 +0100 Subject: [PATCH 4/9] switch parameters positions for 2 internal functions --- packages/web3-eth-contract/src/contract.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index f7625d84626..821557e20d8 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -1019,9 +1019,9 @@ export class Contract return { arguments: abiParams, call: async (options?: PayableCallOptions, block?: BlockNumberOrTag) => - this._contractMethodCall(methodAbi, errorsAbis, abiParams, options, block), + this._contractMethodCall(methodAbi, abiParams, errorsAbis, options, block), send: async (options?: PayableTxOptions) => - this._contractMethodSend(methodAbi, errorsAbis, abiParams, options), + this._contractMethodSend(methodAbi, abiParams, errorsAbis, options), estimateGas: async < ReturnFormat extends DataFormat = typeof DEFAULT_RETURN_FORMAT, >( @@ -1043,9 +1043,9 @@ export class Contract return { arguments: abiParams, call: async (options?: NonPayableCallOptions, block?: BlockNumberOrTag) => - this._contractMethodCall(methodAbi, errorsAbis, abiParams, options, block), + this._contractMethodCall(methodAbi, abiParams, errorsAbis, options, block), send: async (options?: NonPayableTxOptions) => - this._contractMethodSend(methodAbi, errorsAbis, abiParams, options), + this._contractMethodSend(methodAbi, abiParams, errorsAbis, options), estimateGas: async ( options?: NonPayableCallOptions, returnFormat: ReturnFormat = DEFAULT_RETURN_FORMAT as ReturnFormat, @@ -1066,8 +1066,8 @@ export class Contract private async _contractMethodCall( abi: AbiFunctionFragment, - errorsAbi: AbiErrorFragment[], params: unknown[], + errorsAbi: AbiErrorFragment[], options?: Options, block?: BlockNumberOrTag, ) { @@ -1094,8 +1094,8 @@ export class Contract private async _contractMethodSend( abi: AbiFunctionFragment, - errorsAbi: AbiErrorFragment[], params: unknown[], + errorsAbi: AbiErrorFragment[], options?: Options, contractOptions?: ContractOptions, ) { From 4b8cadc762dbe0fa76d0327c71c952c8fe8163dd Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Mon, 5 Dec 2022 20:07:44 +0100 Subject: [PATCH 5/9] fix promiEvent return in _contractMethodSend --- packages/web3-eth-contract/src/contract.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index 821557e20d8..f06cb006441 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -1114,7 +1114,9 @@ export class Contract }); try { - return await sendTransaction(this, tx, DEFAULT_RETURN_FORMAT); + const promiEvent = sendTransaction(this, tx, DEFAULT_RETURN_FORMAT); + await promiEvent; + return promiEvent; } catch (error: unknown) { if (error instanceof ContractExecutionError) { // this will parse the error data by trying to decode the ABI error inputs according to EIP-838 From e9c8986dccebf0e2a8d111ff1c43dc8df15d6b46 Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Mon, 5 Dec 2022 22:06:19 +0100 Subject: [PATCH 6/9] enhance error handling at _contractMethodSend --- packages/web3-eth-contract/src/contract.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index 0de990512ff..6580c4f48d2 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -1061,7 +1061,7 @@ export class Contract arguments: abiParams, call: async (options?: NonPayableCallOptions, block?: BlockNumberOrTag) => this._contractMethodCall(methodAbi, abiParams, errorsAbis, options, block), - send: async (options?: NonPayableTxOptions) => + send: (options?: NonPayableTxOptions) => this._contractMethodSend(methodAbi, abiParams, errorsAbis, options), estimateGas: async ( options?: NonPayableCallOptions, @@ -1109,7 +1109,7 @@ export class Contract } } - private async _contractMethodSend( + private _contractMethodSend( abi: AbiFunctionFragment, params: unknown[], errorsAbi: AbiErrorFragment[], @@ -1130,17 +1130,17 @@ export class Contract contractOptions: modifiedContractOptions, }); - try { - const promiEvent = sendTransaction(this, tx, DEFAULT_RETURN_FORMAT); - await promiEvent; - return promiEvent; - } catch (error: unknown) { + const promiEvent = sendTransaction(this, tx, DEFAULT_RETURN_FORMAT); + + // eslint-disable-next-line @typescript-eslint/no-floating-promises + promiEvent.on('error', (error: unknown) => { if (error instanceof ContractExecutionError) { // this will parse the error data by trying to decode the ABI error inputs according to EIP-838 decodeErrorData(errorsAbi, error.innerError); } - throw error; - } + }); + + return promiEvent; } private _contractMethodDeploySend( From aa89486ef77c4a64fa715cb169ee828e4ad65dc7 Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Tue, 6 Dec 2022 00:20:43 +0100 Subject: [PATCH 7/9] fix a unit test mocking --- packages/web3-eth-contract/test/unit/contract.test.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/web3-eth-contract/test/unit/contract.test.ts b/packages/web3-eth-contract/test/unit/contract.test.ts index f1ce2cd11ec..19d5f633fb3 100644 --- a/packages/web3-eth-contract/test/unit/contract.test.ts +++ b/packages/web3-eth-contract/test/unit/contract.test.ts @@ -144,11 +144,13 @@ describe('Contract', () => { ) { // eslint-disable-next-line expect(_tx.to).toStrictEqual(deployedAddr); - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return Promise.resolve({ status: '0x1' }) as any; + + // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-empty-function + return { status: '0x1', on: () => {} } as any; } - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return Promise.resolve(newContract) as any; + + // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-empty-function + return Promise.resolve(Object.assign(newContract, { on: () => {} })) as any; }); const deployedContract = await contract From bfcd53ec3b65593c81e7daa51ca7159585386d11 Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Tue, 6 Dec 2022 11:34:22 +0100 Subject: [PATCH 8/9] clean unnecessary keyword --- packages/web3-eth-contract/src/contract.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index 6580c4f48d2..3ef46996978 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -1037,7 +1037,7 @@ export class Contract arguments: abiParams, call: async (options?: PayableCallOptions, block?: BlockNumberOrTag) => this._contractMethodCall(methodAbi, abiParams, errorsAbis, options, block), - send: async (options?: PayableTxOptions) => + send: (options?: PayableTxOptions) => this._contractMethodSend(methodAbi, abiParams, errorsAbis, options), estimateGas: async < ReturnFormat extends DataFormat = typeof DEFAULT_RETURN_FORMAT, From 2344bb91245499a15e97638e48143141283d3217 Mon Sep 17 00:00:00 2001 From: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Tue, 6 Dec 2022 12:33:29 +0100 Subject: [PATCH 9/9] use MR Ids instad of issues Ids in CHANGELOG.md files --- CHANGELOG.md | 2 +- packages/web3-eth-contract/CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42275453b73..cee2db1aa8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -897,7 +897,7 @@ should use 4.0.1-alpha.0 for testing. #### web3-eth-contract -- Decoding error data, using Error ABI if available, if error was returned from a smart contract function call (#5587). +- Decoding error data, using Error ABI if available, if error was returned from a smart contract function call (#5662). #### web3-types diff --git a/packages/web3-eth-contract/CHANGELOG.md b/packages/web3-eth-contract/CHANGELOG.md index a532c049eda..7602457ec36 100644 --- a/packages/web3-eth-contract/CHANGELOG.md +++ b/packages/web3-eth-contract/CHANGELOG.md @@ -188,7 +188,7 @@ const transactionHash = receipt.transactionHash; ### Added -- Decoding error data, using Error ABI if available, if error was returned from a smart contract function call (#5587). +- Decoding error data, using Error ABI if available, if error was returned from a smart contract function call (#5662). ### Fixed