// TODO(v3) // import type { Account } from '../accounts/types.js' // import type { SendTransactionParameters } from '../actions/wallet/sendTransaction.js' import type { BlockTag } from '../types/block.js' // import type { Chain } from '../types/chain.js' import type { Hex } from '../types/data.js' import type { TransactionType } from '../types/transaction.js' // import { formatEther } from '../unit/formatEther.js' // import { formatGwei } from '../unit/formatGwei.js' import { BaseError } from './base.js' export function prettyPrint( args: Record, ) { const entries = Object.entries(args) .map(([key, value]) => { if (value === undefined || value === false) return null return [key, value] }) .filter(Boolean) as [string, string][] const maxLength = entries.reduce((acc, [key]) => Math.max(acc, key.length), 0) return entries .map(([key, value]) => ` ${`${key}:`.padEnd(maxLength + 1)} ${value}`) .join('\n') } export type FeeConflictErrorType = FeeConflictError & { name: 'FeeConflictError' } export class FeeConflictError extends BaseError { constructor() { super( [ 'Cannot specify both a `gasPrice` and a `maxFeePerGas`/`maxPriorityFeePerGas`.', 'Use `maxFeePerGas`/`maxPriorityFeePerGas` for EIP-1559 compatible networks, and `gasPrice` for others.', ].join('\n'), { name: 'FeeConflictError' }, ) } } export type InvalidLegacyVErrorType = InvalidLegacyVError & { name: 'InvalidLegacyVError' } export class InvalidLegacyVError extends BaseError { constructor({ v }: { v: number }) { super(`Invalid \`v\` value "${v}". Expected 27 or 28.`, { name: 'InvalidLegacyVError', }) } } export type InvalidSerializableTransactionErrorType = InvalidSerializableTransactionError & { name: 'InvalidSerializableTransactionError' } export class InvalidSerializableTransactionError extends BaseError { constructor({ transaction }: { transaction: Record }) { super('Cannot infer a transaction type from provided transaction.', { metaMessages: [ 'Provided Transaction:', '{', prettyPrint(transaction), '}', '', 'To infer the type, either provide:', '- a `type` to the Transaction, or', '- an EIP-1559 Transaction with `maxFeePerGas`, or', '- an EIP-2930 Transaction with `gasPrice` & `accessList`, or', '- an EIP-4844 Transaction with `blobs`, `blobVersionedHashes`, `sidecars`, or', '- an EIP-7702 Transaction with `authorizationList`, or', '- a Legacy Transaction with `gasPrice`', ], name: 'InvalidSerializableTransactionError', }) } } export type InvalidSerializedTransactionTypeErrorType = InvalidSerializedTransactionTypeError & { name: 'InvalidSerializedTransactionTypeError' } export class InvalidSerializedTransactionTypeError extends BaseError { serializedType: Hex constructor({ serializedType }: { serializedType: Hex }) { super(`Serialized transaction type "${serializedType}" is invalid.`, { name: 'InvalidSerializedTransactionType', }) this.serializedType = serializedType } } export type InvalidSerializedTransactionErrorType = InvalidSerializedTransactionError & { name: 'InvalidSerializedTransactionError' } export class InvalidSerializedTransactionError extends BaseError { serializedTransaction: Hex type: TransactionType constructor({ attributes, serializedTransaction, type, }: { attributes: Record serializedTransaction: Hex type: TransactionType }) { const missing = Object.entries(attributes) .map(([key, value]) => (typeof value === 'undefined' ? key : undefined)) .filter(Boolean) super(`Invalid serialized transaction of type "${type}" was provided.`, { metaMessages: [ `Serialized Transaction: "${serializedTransaction}"`, missing.length > 0 ? `Missing Attributes: ${missing.join(', ')}` : '', ].filter(Boolean), name: 'InvalidSerializedTransactionError', }) this.serializedTransaction = serializedTransaction this.type = type } } export type InvalidStorageKeySizeErrorType = InvalidStorageKeySizeError & { name: 'InvalidStorageKeySizeError' } export class InvalidStorageKeySizeError extends BaseError { constructor({ storageKey }: { storageKey: Hex }) { super( `Size for storage key "${storageKey}" is invalid. Expected 32 bytes. Got ${Math.floor( (storageKey.length - 2) / 2, )} bytes.`, { name: 'InvalidStorageKeySizeError' }, ) } } // TODO(v3) // export type TransactionExecutionErrorType = TransactionExecutionError & { // name: 'TransactionExecutionError' // } // export class TransactionExecutionError extends BaseError { // override cause: BaseError // constructor( // cause: BaseError, // { // account, // docsPath, // chain, // data, // gas, // gasPrice, // maxFeePerGas, // maxPriorityFeePerGas, // nonce, // to, // value, // }: Omit & { // account: Account // chain?: Chain | undefined // docsPath?: string | undefined // }, // ) { // const prettyArgs = prettyPrint({ // chain: chain && `${chain?.name} (id: ${chain?.id})`, // from: account?.address, // to, // value: // typeof value !== 'undefined' && // `${formatEther(value)} ${chain?.nativeCurrency?.symbol || 'ETH'}`, // data, // gas, // gasPrice: // typeof gasPrice !== 'undefined' && `${formatGwei(gasPrice)} gwei`, // maxFeePerGas: // typeof maxFeePerGas !== 'undefined' && // `${formatGwei(maxFeePerGas)} gwei`, // maxPriorityFeePerGas: // typeof maxPriorityFeePerGas !== 'undefined' && // `${formatGwei(maxPriorityFeePerGas)} gwei`, // nonce, // }) // super(cause.shortMessage, { // cause, // docsPath, // metaMessages: [ // ...(cause.metaMessages ? [...cause.metaMessages, ' '] : []), // 'Request Arguments:', // prettyArgs, // ].filter(Boolean) as string[], // name: 'TransactionExecutionError', // }) // this.cause = cause // } // } export type TransactionNotFoundErrorType = TransactionNotFoundError & { name: 'TransactionNotFoundError' } export class TransactionNotFoundError extends BaseError { constructor({ blockHash, blockNumber, blockTag, hash, index, }: { blockHash?: Hex | undefined blockNumber?: bigint | undefined blockTag?: BlockTag | undefined hash?: Hex | undefined index?: number | undefined }) { let identifier = 'Transaction' if (blockTag && index !== undefined) identifier = `Transaction at block time "${blockTag}" at index "${index}"` if (blockHash && index !== undefined) identifier = `Transaction at block hash "${blockHash}" at index "${index}"` if (blockNumber && index !== undefined) identifier = `Transaction at block number "${blockNumber}" at index "${index}"` if (hash) identifier = `Transaction with hash "${hash}"` super(`${identifier} could not be found.`, { name: 'TransactionNotFoundError', }) } } export type TransactionReceiptNotFoundErrorType = TransactionReceiptNotFoundError & { name: 'TransactionReceiptNotFoundError' } export class TransactionReceiptNotFoundError extends BaseError { constructor({ hash }: { hash: Hex }) { super( `Transaction receipt with hash "${hash}" could not be found. The Transaction may not be processed on a block yet.`, { name: 'TransactionReceiptNotFoundError', }, ) } } export type WaitForTransactionReceiptTimeoutErrorType = WaitForTransactionReceiptTimeoutError & { name: 'WaitForTransactionReceiptTimeoutError' } export class WaitForTransactionReceiptTimeoutError extends BaseError { constructor({ hash }: { hash: Hex }) { super( `Timed out while waiting for transaction with hash "${hash}" to be confirmed.`, { name: 'WaitForTransactionReceiptTimeoutError' }, ) } }