Last active
October 16, 2024 21:53
-
-
Save Yuripetusko/e00df450c3a6445bd8029fa2a2647b86 to your computer and use it in GitHub Desktop.
decode-evm-transaction-error-result.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import type { Abi } from 'abitype'; | |
| import { | |
| AbiErrorSignatureNotFoundError, | |
| BaseError, | |
| ContractFunctionExecutionError, | |
| type ContractFunctionExecutionErrorType, | |
| ContractFunctionRevertedError, | |
| decodeErrorResult, | |
| InvalidInputRpcError, | |
| type SimulateContractErrorType, | |
| UserRejectedRequestError, | |
| type WaitForTransactionReceiptErrorType, | |
| type WriteContractErrorType, | |
| } from 'viem'; | |
| export interface ParseEvmTransactionLogArgs<TAbi extends Abi | readonly unknown[] | undefined> { | |
| abi: TAbi; | |
| error: | |
| | unknown | |
| | ContractFunctionExecutionErrorType | |
| | SimulateContractErrorType | |
| | WriteContractErrorType | |
| | WaitForTransactionReceiptErrorType | |
| | null; | |
| } | |
| /** | |
| * Tries to find decoded error in the error object, or decodes it with the supplied ABI. | |
| * @param error | |
| * @param abi | |
| */ | |
| export const decodeEvmTransactionErrorResult = <TAbi extends Abi | readonly unknown[] | undefined>({ | |
| error, | |
| abi, | |
| }: ParseEvmTransactionLogArgs<TAbi>) => { | |
| try { | |
| if (error instanceof BaseError || error instanceof ContractFunctionExecutionError) { | |
| const revertError = error.walk((err) => err instanceof ContractFunctionRevertedError); | |
| if (revertError instanceof ContractFunctionRevertedError) { | |
| const errorName = revertError.data?.errorName ?? ''; | |
| if (errorName) { | |
| // This error is already decoded | |
| const decodedError = revertError.data; | |
| return { | |
| error, | |
| decodedError, | |
| message: error.shortMessage ?? error.message, | |
| }; | |
| } | |
| } | |
| const rpcError = error.walk((err) => err instanceof InvalidInputRpcError); | |
| if (rpcError instanceof InvalidInputRpcError) { | |
| return { | |
| error: rpcError, | |
| decodedError: undefined, | |
| message: | |
| (rpcError.details ?? rpcError.shortMessage ?? rpcError.message ?? !!rpcError) | |
| ? 'Unknown error' | |
| : undefined, | |
| }; | |
| } | |
| } | |
| // If error could not be decoded with original abi, let's try to decode it with the supplied ABI | |
| const noSignatureError = (error as BaseError).walk( | |
| (err) => err instanceof AbiErrorSignatureNotFoundError, | |
| ); | |
| if (noSignatureError instanceof AbiErrorSignatureNotFoundError && noSignatureError?.signature) { | |
| const decodedError = decodeErrorResult({ | |
| abi, | |
| data: noSignatureError.signature, | |
| }); | |
| return { | |
| decodedError, | |
| error, | |
| message: | |
| decodedError?.errorName ?? | |
| (error as ContractFunctionRevertedError).shortMessage ?? | |
| (error as Error).message ?? | |
| (error as ContractFunctionRevertedError).reason, | |
| }; | |
| } | |
| const userRejectedError = (error as BaseError).walk( | |
| (err) => err instanceof UserRejectedRequestError, | |
| ); | |
| if (userRejectedError instanceof UserRejectedRequestError) { | |
| return { | |
| error: userRejectedError, | |
| decodedError: undefined, | |
| message: userRejectedError.shortMessage, | |
| }; | |
| } | |
| return { | |
| error, | |
| decodedError: undefined, | |
| message: | |
| ((error as ContractFunctionRevertedError).shortMessage ?? | |
| (error as Error).message ?? | |
| !!error) | |
| ? 'Unknown error' | |
| : undefined, | |
| }; | |
| } catch (_) { | |
| return { | |
| error, | |
| decodedError: undefined, | |
| message: | |
| ((error as ContractFunctionRevertedError)?.shortMessage ?? | |
| (error as Error)?.message ?? | |
| !!error) | |
| ? 'Unknown error' | |
| : undefined, | |
| }; | |
| } | |
| }; | |
| export type DecodedContractError<TAbi extends Abi | readonly unknown[] | undefined> = ReturnType< | |
| typeof decodeEvmTransactionErrorResult<TAbi> | |
| >; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment