Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sendTransaction and sendSignedTransaction Error Refactors #5854

Merged
merged 69 commits into from
Mar 9, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
43d93de
Add payload as optional argument for InvalidResponseError
spacesailor24 Feb 22, 2023
db9cb50
Init Transaction Error Scenarios tests
spacesailor24 Feb 22, 2023
8eb82ba
Init ERR_TX_REVERT_TRANSACTION_CUSTOM_ERROR
spacesailor24 Feb 22, 2023
e4a2891
WIP
spacesailor24 Feb 22, 2023
36c9b0d
WIP
spacesailor24 Feb 23, 2023
2378e6a
Update TransactionRevertedWithoutReasonError to handle receipts objec…
spacesailor24 Feb 24, 2023
044fea2
Update sendTransaction revert tests
spacesailor24 Feb 24, 2023
3a12870
Add contractAbi argument to getTransactionError
spacesailor24 Feb 24, 2023
63554f2
sendTransation emits error for ContractExecutionError
spacesailor24 Feb 24, 2023
8c33881
Add ContractExecutionError to SendTransactionEvents. Add contractAbi …
spacesailor24 Feb 24, 2023
853d0b2
Replace use of contractExecutionError sendTransaction event with error
spacesailor24 Feb 24, 2023
bd4ff70
Update contract_methods reverts test
spacesailor24 Feb 24, 2023
75a99f2
Merge branch '4.x' into wyatt/4.x/5840-requstmanger-return-errors
spacesailor24 Feb 24, 2023
d075a86
Update web3-errors test
spacesailor24 Feb 24, 2023
2b59dc6
Update expected error mesage for contract_deploy_test
spacesailor24 Feb 24, 2023
7e830d2
Add expectedErrorObject based on test backend
spacesailor24 Feb 24, 2023
91a4e6f
Correct web3-errors test snapshots
spacesailor24 Feb 24, 2023
ff142e0
fix (#5869)
avkos Feb 24, 2023
8948973
5747 codecov (#5843)
jdevcs Feb 28, 2023
c39aab2
ens system tests (#5849)
nikoulai Feb 28, 2023
3cb0a27
Disconnect function doesn't exists in types of currentProvider (#5865)
avkos Feb 28, 2023
c951bb7
Nikos/fix ens event test (#5880)
nikoulai Mar 1, 2023
b2c21b2
update event emitter geth ipc tests (#5874)
Mar 1, 2023
af78858
4.x issue stale conf (#5878)
jdevcs Mar 2, 2023
77d6fa0
Add documentation for catching provider events (#5886)
Muhammad-Altabba Mar 6, 2023
e5c59af
Fixing tests for WS and IPC
spacesailor24 Feb 24, 2023
de1fe5e
Remove jest specific test code that doesn't work in Cypress
spacesailor24 Feb 24, 2023
f334a9e
Remove jest specific test code that doesn't work in Cypress
spacesailor24 Feb 24, 2023
71e8f1b
Remove jest specific test code
spacesailor24 Feb 24, 2023
de2f1cf
Add toLowerCase for address
spacesailor24 Feb 24, 2023
4205577
Rename TransactionRevertError to TransactionRevertInstructionError
spacesailor24 Feb 25, 2023
a66aaf0
Add beforeAll for Transaction Error Scenario tests
spacesailor24 Feb 25, 2023
284f4ad
Add Transaction Error Scenario tests for call
spacesailor24 Feb 25, 2023
19aadcc
Add support for handleRevert in sendTransaction for geth
spacesailor24 Feb 25, 2023
5376bc8
Update tests and add test to verify event error is same as thrown error
spacesailor24 Feb 25, 2023
662a390
Correct test expected data
spacesailor24 Feb 25, 2023
81be9d8
Remove message from expectedThrownError for sendTransaction tests
spacesailor24 Feb 25, 2023
0f655a5
Add error refactors to sendSignedTransaction and init tests
spacesailor24 Feb 25, 2023
a1d1a56
Remove call Transaction Error Scenario tests
spacesailor24 Feb 25, 2023
d7ce12f
Fix type error
spacesailor24 Feb 25, 2023
dc03c22
Fix nonce issue in tests
spacesailor24 Feb 25, 2023
32add6d
Fix error parsing bug for web3Eth.sendSignedTransaction
spacesailor24 Mar 1, 2023
66b7377
Update expected error for send_signed_transaction error tests
spacesailor24 Mar 1, 2023
b998f8f
Revert ResponseError change to maintain 1.x parity
spacesailor24 Mar 2, 2023
35293d6
Add web3-errors test for TransactionRevertWithCustomError
spacesailor24 Mar 2, 2023
68efd93
Update expected error message for RespnoseError in web3-eth-contract …
spacesailor24 Mar 2, 2023
d6fc658
Add example to dev comment for sendSignedTransaction
spacesailor24 Mar 2, 2023
3d3e7bc
Removed implemented TODO in packages/web3-eth/src/utils/get_transacti…
spacesailor24 Mar 2, 2023
64a3e1f
Update CHANGELOGs
spacesailor24 Mar 2, 2023
fedc918
Update CHANGELOG.md
spacesailor24 Mar 2, 2023
c54d2b9
Init get_transaction_error tests
spacesailor24 Mar 2, 2023
683515c
Add mock to getRevertReason for get_transaction_error tests
spacesailor24 Mar 2, 2023
547f9be
Init getRevertReason tests and parseTransactionError tests
spacesailor24 Mar 2, 2023
9e3c637
Add check for revert before sending tx
spacesailor24 Mar 3, 2023
f4f43f8
Update web3-plugin-example test to account for getRevertReason check
spacesailor24 Mar 7, 2023
d72206c
Turn off checkRevertBeforeSending for sendFewTxes helper
spacesailor24 Mar 7, 2023
2b816bf
Fix test data for send_signed_transaction tests
spacesailor24 Mar 7, 2023
c4180b6
Fix bug in get_transaction_error
spacesailor24 Mar 7, 2023
306b650
Fix send_transaction error test
spacesailor24 Mar 7, 2023
76ee3da
Add checkRevertBeforeSending: false to sendTransaction calls in Contr…
spacesailor24 Mar 7, 2023
bcffc9f
Add checkRevertBeforeSending: false for send tx test helpers
spacesailor24 Mar 7, 2023
2828b41
Remove getRevertReason mock
spacesailor24 Mar 8, 2023
5838adf
A fix at `IpcProvider` and few changes at `SocketProvider` and its de…
Muhammad-Altabba Mar 7, 2023
e79e59f
Fix failed tx test for ganache
spacesailor24 Mar 8, 2023
a2175ff
Update expected transaction errors for ganache
spacesailor24 Mar 9, 2023
5cbb9bf
Fix method handler crashed (#5905)
avkos Mar 8, 2023
e267663
Test fix
spacesailor24 Mar 9, 2023
2662eaf
Use `v1` instead of Short Sha for cloudflare/pages-action (#5909)
Muhammad-Altabba Mar 9, 2023
c216751
Merge branch '4.x' into wyatt/4.x/5840-requstmanger-return-errors
spacesailor24 Mar 9, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/web3-core/src/web3_request_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ export class Web3RequestManager<
throw new RpcError(rpcErrorResponse);
}
} else if (!Web3RequestManager._isReverted(response)) {
throw new InvalidResponseError<ErrorType>(response);
throw new InvalidResponseError<ErrorType, RequestType>(response, payload);
}
}

Expand Down
1 change: 1 addition & 0 deletions packages/web3-errors/src/error_codes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export const ERR_TX_GAS_MISMATCH = 434;
export const ERR_TX_CHAIN_MISMATCH = 435;
export const ERR_TX_HARDFORK_MISMATCH = 436;
export const ERR_TX_INVALID_RECEIVER = 437;
export const ERR_TX_REVERT_TRANSACTION_CUSTOM_ERROR = 438;

// Connection error codes
export const ERR_CONN = 500;
Expand Down
34 changes: 26 additions & 8 deletions packages/web3-errors/src/errors/response_errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ along with web3.js. If not, see <http://www.gnu.org/licenses/>.
*/

// eslint-disable-next-line max-classes-per-file
import { JsonRpcError, JsonRpcResponse, JsonRpcResponseWithError } from 'web3-types';
import {
JsonRpcError,
JsonRpcPayload,
JsonRpcResponse,
JsonRpcResponseWithError,
} from 'web3-types';
import { BaseWeb3Error } from '../web3_error_base';
import { ERR_INVALID_RESPONSE, ERR_RESPONSE } from '../error_codes';

Expand All @@ -36,14 +41,19 @@ const isResponseWithError = <Error = unknown, Result = unknown>(
const buildErrorMessage = (response: JsonRpcResponse<unknown, unknown>): string =>
isResponseWithError(response) ? response.error.message : '';

export class ResponseError<ErrorType = unknown> extends BaseWeb3Error {
export class ResponseError<ErrorType = unknown, RequestType = unknown> extends BaseWeb3Error {
public code = ERR_RESPONSE;
public data?: ErrorType | ErrorType[];
public request?: JsonRpcPayload<RequestType>;

public constructor(response: JsonRpcResponse<unknown, ErrorType>, message?: string) {
public constructor(
response: JsonRpcResponse<unknown, ErrorType>,
message?: string,
request?: JsonRpcPayload<RequestType>,
) {
super(
message ??
`Returned error: ${
`${
Array.isArray(response)
? response.map(r => buildErrorMessage(r)).join(',')
: buildErrorMessage(response)
Expand All @@ -55,16 +65,24 @@ export class ResponseError<ErrorType = unknown> extends BaseWeb3Error {
? response.map(r => r.error?.data as ErrorType)
: response?.error?.data;
}

this.request = request;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added request to the error object as I wanted to add sent transaction details to failed transaction errors to give the user more context (e.g. the sending account when the error Unknown account or Insufficient funds is thrown) on what exactly was sent to provider

}

public toJSON() {
return { ...super.toJSON(), data: this.data };
return { ...super.toJSON(), data: this.data, request: this.request };
}
}

export class InvalidResponseError<ErrorType = unknown> extends ResponseError<ErrorType> {
public constructor(result: JsonRpcResponse<unknown, ErrorType>) {
super(result);
export class InvalidResponseError<ErrorType = unknown, RequestType = unknown> extends ResponseError<
ErrorType,
RequestType
> {
public constructor(
result: JsonRpcResponse<unknown, ErrorType>,
request?: JsonRpcPayload<RequestType>,
) {
super(result, undefined, request);
this.code = ERR_INVALID_RESPONSE;

let errorOrErrors: JsonRpcError | JsonRpcError[] | undefined;
Expand Down
46 changes: 38 additions & 8 deletions packages/web3-errors/src/errors/transaction_errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import {
ERR_TX_UNABLE_TO_POPULATE_NONCE,
ERR_TX_UNSUPPORTED_EIP_1559,
ERR_TX_UNSUPPORTED_TYPE,
ERR_TX_REVERT_TRANSACTION_CUSTOM_ERROR,
} from '../error_codes';
import { InvalidValueError, BaseWeb3Error } from '../web3_error_base';

Expand Down Expand Up @@ -84,25 +85,54 @@ export class RevertInstructionError extends BaseWeb3Error {
}
}

export class TransactionRevertError extends BaseWeb3Error {
export class TransactionRevertError<ReceiptType = TransactionReceipt> extends BaseWeb3Error {
public code = ERR_TX_REVERT_TRANSACTION;

public constructor(
public reason: string,
public signature?: string,
public receipt?: TransactionReceipt,
public receipt?: ReceiptType,
public data?: string,
) {
super(
`Transaction has been reverted by the EVM:\n ${JSON.stringify(receipt, undefined, 2)}`,
);
super(reason);
}

public toJSON() {
return {
...super.toJSON(),
reason: this.reason,
signature: this.signature,
receipt: this.receipt,
data: this.data
};
}
}

export class TransactionRevertWithCustomError<ReceiptType = TransactionReceipt> extends TransactionRevertError<ReceiptType> {
public code = ERR_TX_REVERT_TRANSACTION_CUSTOM_ERROR;

public constructor(
public reason: string,
public customErrorName: string,
public customErrorDecodedSignature: string,
public customErrorArguments: Record<string, unknown>,
public signature?: string,
public receipt?: ReceiptType,
public data?: string,
) {
super(reason);
}

public toJSON() {
return {
...super.toJSON(),
reason: this.reason,
customErrorName: this.customErrorName,
customErrorDecodedSignature: this.customErrorDecodedSignature,
customErrorArguments: this.customErrorArguments,
signature: this.signature,
receipt: this.receipt,
data: this.data
};
}
}
Expand All @@ -125,10 +155,10 @@ export class ContractCodeNotStoredError extends TransactionError {
}
}

export class TransactionRevertedWithoutReasonError extends TransactionError {
public constructor(receipt: TransactionReceipt) {
export class TransactionRevertedWithoutReasonError<ReceiptType = TransactionReceipt> extends TransactionError<ReceiptType> {
public constructor(receipt?: ReceiptType) {
super(
`Transaction has been reverted by the EVM:\n ${JSON.stringify(receipt, undefined, 2)}`,
`Transaction has been reverted by the EVM${receipt === undefined ? '' : `:\n ${JSON.stringify(receipt, undefined, 2)}`}`,
receipt,
);
this.code = ERR_TX_REVERT_WITHOUT_REASON;
Expand Down
47 changes: 19 additions & 28 deletions packages/web3-eth/src/rpc_method_wrappers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,11 @@ import {
import { Web3Context, Web3PromiEvent } from 'web3-core';
import { ETH_DATA_FORMAT, FormatType, DataFormat, DEFAULT_RETURN_FORMAT, format } from 'web3-utils';
import { isBlockTag, isBytes, isNullish, isString } from 'web3-validator';
import { SignatureError, TransactionError, ContractExecutionError } from 'web3-errors';
import {
InvalidResponseError,
SignatureError,
TransactionError,
} from 'web3-errors';
import { ethRpcMethods } from 'web3-rpc-methods';
import { decodeSignedTransaction } from './utils/decode_signed_transaction';
import {
Expand Down Expand Up @@ -77,8 +81,7 @@ import { trySendTransaction } from './utils/try_send_transaction';
import { waitForTransactionReceipt } from './utils/wait_for_transaction_receipt';
import { watchTransactionForConfirmations } from './utils/watch_transaction_for_confirmations';
import { NUMBER_DATA_FORMAT } from './constants';
// eslint-disable-next-line import/no-cycle
import { getRevertReason } from './utils/get_revert_reason';
import { getTransactionError } from './utils/get_transaction_error';

/**
*
Expand Down Expand Up @@ -1078,14 +1081,6 @@ export function sendTransaction<
ETH_DATA_FORMAT,
);

if (web3Context.handleRevert) {
// eslint-disable-next-line no-use-before-define
await getRevertReason(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whole idea of doing eth_call / tx simulation on evm before sending actual transaction is to save gas in case there is error in transaction and to detect error earlier. So calling getRevertReason after transaction status 0x0 ( fail ) at line 1189 via getTransactionError is not useful. This should be changed.

Copy link
Contributor Author

@spacesailor24 spacesailor24 Mar 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jdevcs 1.x doesn't send an eth_call before every sent transaction, and eth_call will not return an error for transactions such as a send to this method:

function revertSend(string memory revertString) public {
    require(keccak256(abi.encodePacked(revertString)) != keccak256(abi.encodePacked("revert")), "This is a send revert");
}

so relying on getting the revert reason without sending the transaction isn't a complete solution. Instead, I would suggest checking for a revert reason before sending the transaction only if options.checkRevertBeforeSend (a new transaction option) is true, and we can set it to default to true since this would be helpful to new ETH users and more experienced devs will just turn it off if unwanted. Then checking a mined transaction's revert reason if status === '0x0 and web3Context.handleRevert === true (as currently done in this refactor)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There also appears to be a discrepancy between providers with returning revert errors when using eth_call:

Sending the transaction:

{
    from: tempAcc.address,
    to: '0x0000000000000000000000000000000000000000',
    value: BigInt('999999999999999999999999999999999999999999999999999999999'),
}

yields err: insufficient funds for gas * price + value: address when submitted to Geth using eth_call, but Ganache doesn't return an error until the transaction is actually submitted

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed by this commit

Copy link
Contributor

@jdevcs jdevcs Mar 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will not secure users 100% of times but where applicable, if it can save user in few scenarios even in that case it should not be skipped before sending tx, and its more good to check it based on defined flag. Thanks for making this change. LGTM.

web3Context,
transactionFormatted as TransactionCall,
);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is part of addressing #5839, the revert reason is retrieved after the transaction has been processed by the network and when transactionReceipt.status === BigInt(0)

if (
!options?.ignoreGasPricing &&
isNullish(transactionFormatted.gasPrice) &&
Expand Down Expand Up @@ -1177,17 +1172,17 @@ export function sendTransaction<
) as unknown as ResolveType,
);
} else if (transactionReceipt.status === BigInt(0)) {
const error = await getTransactionError<ReturnFormat>(
web3Context,
transactionFormatted as TransactionCall,
transactionReceiptFormatted,
);

if (promiEvent.listenerCount('error') > 0) {
promiEvent.emit(
'error',
new TransactionError(
'Transaction failed',
transactionReceiptFormatted,
),
);
Comment on lines -1181 to -1187
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was the cause of #5837

promiEvent.emit('error', error);
}
reject(transactionReceiptFormatted as unknown as ResolveType);
return;

reject(error);
} else {
resolve(transactionReceiptFormatted as unknown as ResolveType);
}
Expand All @@ -1206,14 +1201,10 @@ export function sendTransaction<
);
}
} catch (error) {
if (error instanceof ContractExecutionError) {
promiEvent.emit('contractExecutionError', error);
}
Comment on lines -1209 to -1211
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there's a reason to have an contractExecutionError event when we already have a generic error event that every other error uses (@nikoulai please let me know if there was a specific reason for it since you added it in #5659)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see now that it's being using in web3-eth-contract

Copy link
Contributor Author

@spacesailor24 spacesailor24 Feb 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

web3-eth-contract was updated to check for error instanceof ContractExecutionError instead of relying on an emission of contractExecutionError event

if (promiEvent.listenerCount('error') > 0) {
promiEvent.emit(
'error',
new TransactionError((error as Error).message),
);
if (error instanceof InvalidResponseError &&
promiEvent.listenerCount('error') > 0
) {
promiEvent.emit('error', error);
}

reject(error);
Expand Down
17 changes: 14 additions & 3 deletions packages/web3-eth/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,15 @@ You should have received a copy of the GNU Lesser General Public License
along with web3.js. If not, see <http://www.gnu.org/licenses/>.
*/

import { TransactionError, ContractExecutionError, ResponseError } from 'web3-errors';
import {
TransactionError,
ContractExecutionError,
ResponseError,
TransactionRevertedWithoutReasonError,
TransactionRevertError,
TransactionRevertWithCustomError,
InvalidResponseError,
} from 'web3-errors';
import { Bytes, HexString, Numbers, Transaction, TransactionReceipt } from 'web3-types';
import { DataFormat, ETH_DATA_FORMAT, FormatType } from 'web3-utils';

Expand All @@ -31,8 +39,11 @@ export type SendTransactionEvents<ReturnFormat extends DataFormat> = {
receipt: FormatType<TransactionReceipt, ReturnFormat>;
latestBlockHash: FormatType<Bytes, ReturnFormat>;
};
error: TransactionError<FormatType<TransactionReceipt, ReturnFormat>>;
contractExecutionError: ContractExecutionError | ResponseError<any>;
error:
| TransactionRevertedWithoutReasonError<FormatType<TransactionReceipt, ReturnFormat>>
| TransactionRevertError<FormatType<TransactionReceipt, ReturnFormat>>
| TransactionRevertWithCustomError<FormatType<TransactionReceipt, ReturnFormat>>
| InvalidResponseError;
};

export type SendSignedTransactionEvents<ReturnFormat extends DataFormat> = {
Expand Down
76 changes: 40 additions & 36 deletions packages/web3-eth/src/utils/get_revert_reason.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,45 @@ import { DataFormat, DEFAULT_RETURN_FORMAT } from 'web3-utils';
import { call } from '../rpc_method_wrappers';
import { RevertReason, RevertReasonWithCustomError } from '../types';

export const parseTransactionError = (error: unknown, contractAbi?: ContractAbi) => {
Copy link
Contributor Author

@spacesailor24 spacesailor24 Feb 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to it's own function so it could make getRevertReason more concise and because the new util method getTransactionError uses it

if (
error instanceof ContractExecutionError &&
error.innerError instanceof Eip838ExecutionError
) {
if (contractAbi !== undefined) {
const errorsAbi = contractAbi.filter(abi =>
isAbiErrorFragment(abi),
) as unknown as AbiErrorFragment[];
decodeContractErrorData(errorsAbi, error.innerError);

return {
reason: error.innerError.message,
signature: error.innerError.data?.slice(0, 10),
data: error.innerError.data?.substring(10),
customErrorName: error.innerError.errorName,
customErrorDecodedSignature: error.innerError.errorSignature,
customErrorArguments: error.innerError.errorArgs,
} as RevertReasonWithCustomError;
}

return {
reason: error.innerError.message,
signature: error.innerError.data?.slice(0, 10),
data: error.innerError.data?.substring(10),
} as RevertReason;
}

if (
error instanceof InvalidResponseError &&
!Array.isArray(error.innerError) &&
error.innerError !== undefined
) {
return error.innerError.message;
}

throw error;
};

/**
* Returns the revert reason generated by the EVM if the transaction were to be executed.
*
Expand All @@ -44,41 +83,6 @@ export async function getRevertReason<
await call(web3Context, transaction, web3Context.defaultBlock, returnFormat);
return undefined;
} catch (error) {
if (
error instanceof ContractExecutionError &&
error.innerError instanceof Eip838ExecutionError
) {
if (contractAbi !== undefined) {
const errorsAbi = contractAbi.filter(abi =>
isAbiErrorFragment(abi),
) as unknown as AbiErrorFragment[];
decodeContractErrorData(errorsAbi, error.innerError);

return {
reason: error.innerError.message,
signature: error.innerError.data?.slice(0, 10),
data: error.innerError.data?.substring(10),
customErrorName: error.innerError.errorName,
customErrorDecodedSignature: error.innerError.errorSignature,
customErrorArguments: error.innerError.errorArgs,
} as RevertReasonWithCustomError;
}

return {
reason: error.innerError.message,
signature: error.innerError.data?.slice(0, 10),
data: error.innerError.data?.substring(10),
} as RevertReason;
}

if (
error instanceof InvalidResponseError &&
!Array.isArray(error.innerError) &&
error.innerError !== undefined
) {
return error.innerError.message;
}

throw error;
return parseTransactionError(error, contractAbi);
}
}
Loading