diff --git a/CHANGELOG.md b/CHANGELOG.md index fd341cac29c..1d8732915d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -744,6 +744,10 @@ should use 4.0.1-alpha.0 for testing. - Add optional `innerError` property to the abstract class `Web3Error`. This `innerError` could be `Error`, `Error[]` or `undefined`. (#5435) (#5434) - The class `Web3ContractError` is moved to this package from `web3-eth-contract`. (#5434) +- Added the error code `ERR_TX_SIGNING` and used it inside `TransactionSigningError` (#5462) +- Added the error code `ERR_TX_GAS_MISMATCH` and used it inside `TransactionGasMismatchError` (#5462) +- Added `SignatureError` to `web3-errors/src/errors/signature_errors.ts` (moved from `web3-eth/src/errors.ts`) (#5462) +- Added the errors' classes to `web3-errors/src/errors/transaction_errors.ts` from `web3-eth/src/errors.ts` (#5462) #### web3-eth-abi @@ -755,8 +759,18 @@ should use 4.0.1-alpha.0 for testing. - Decoding error data, using Error ABI if available, according to EIP-838. (#5434) - The class `Web3ContractError` is moved from this package to `web3-error`. (#5434) +### Changed + +#### web3-error + +- Moved `SignerError` from `web3-errors/src/errors/signature_errors.ts` to `web3-errors/src/errors/transaction_errors.ts`, and renamed it to `TransactionSigningError` (#5462) + ### Fixed +#### web3-error + +- Corrected the error code for `JSONRPC_ERR_UNAUTHORIZED` to be `4100` (#5462) + #### web3-eth-contract - According to the latest change in `web3-eth-abi`, the decoded values of the large numbers, returned from function calls or events, are now available as `BigInt`. (#5435) @@ -764,3 +778,9 @@ should use 4.0.1-alpha.0 for testing. #### web3-eth-abi - Return `BigInt` instead of `string` when decoding function parameters for large numbers, such as `uint256`. (#5435) + +### Removed + +#### web3-eth + +- Moved the errors' classes from `web3-eth/src/errors.ts` to `web3-errors/src/errors/transaction_errors.ts` (#5462) diff --git a/packages/web3-errors/CHANGELOG.md b/packages/web3-errors/CHANGELOG.md index 8d761f4208d..6af5c8bd691 100644 --- a/packages/web3-errors/CHANGELOG.md +++ b/packages/web3-errors/CHANGELOG.md @@ -41,3 +41,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add optional `innerError` property to the abstract class `Web3Error`. This `innerError` could be `Error`, `Error[]` or `undefined`. (#5435) (#5434) - The class `Web3ContractError` is moved to this package from `web3-eth-contract`. (#5434) +- Added the error code `ERR_TX_SIGNING` and used it inside `TransactionSigningError` (#5462) +- Added the error code `ERR_TX_GAS_MISMATCH` and used it inside `TransactionGasMismatchError` (#5462) +- Added `SignatureError` to `web3-errors/src/errors/signature_errors.ts` (moved from `web3-eth/src/errors.ts`) (#5462) +- Added the errors' classes to `web3-errors/src/errors/transaction_errors.ts` from `web3-eth/src/errors.ts` (#5462) + +### Changed + +- Corrected the error code for `JSONRPC_ERR_UNAUTHORIZED` to be `4100` (#5462) + +### Fixed + +- Moved `SignerError` from `web3-errors/src/errors/signature_errors.ts` to `web3-errors/src/errors/transaction_errors.ts`, and renamed it to `TransactionSigningError` (#5462) diff --git a/packages/web3-errors/src/error_codes.ts b/packages/web3-errors/src/error_codes.ts index f90ec91d915..d530ba0e507 100644 --- a/packages/web3-errors/src/error_codes.ts +++ b/packages/web3-errors/src/error_codes.ts @@ -77,6 +77,9 @@ export const ERR_TX_LOCAL_WALLET_NOT_AVAILABLE = 429; export const ERR_TX_NOT_FOUND = 430; export const ERR_TX_SEND_TIMEOUT = 431; +export const ERR_TX_SIGNING = 433; +export const ERR_TX_GAS_MISMATCH = 434; + // Connection error codes export const ERR_CONN = 500; export const ERR_CONN_INVALID = 501; @@ -113,7 +116,7 @@ export const GENESIS_BLOCK_NUMBER = '0x0'; // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1193.md#provider-errors export const JSONRPC_ERR_REJECTED_REQUEST = 4001; -export const JSONRPC_ERR_UNAUTHORIZED = 4001; +export const JSONRPC_ERR_UNAUTHORIZED = 4100; export const JSONRPC_ERR_UNSUPPORTED_METHOD = 4200; export const JSONRPC_ERR_DISCONNECTED = 4900; export const JSONRPC_ERR_CHAIN_DISCONNECTED = 4901; diff --git a/packages/web3-errors/src/errors/signature_errors.ts b/packages/web3-errors/src/errors/signature_errors.ts index 734b482fe83..cf27d8f2a82 100644 --- a/packages/web3-errors/src/errors/signature_errors.ts +++ b/packages/web3-errors/src/errors/signature_errors.ts @@ -16,11 +16,8 @@ along with web3.js. If not, see . */ import { ERR_SIGNATURE_FAILED } from '../error_codes'; -import { Web3Error } from '../web3_error_base'; +import { InvalidValueError } from '../web3_error_base'; -export class SignerError extends Web3Error { +export class SignatureError extends InvalidValueError { public code = ERR_SIGNATURE_FAILED; - public constructor(errorDetails: string) { - super(`Invalid signature. "${errorDetails}"`); - } } diff --git a/packages/web3-errors/src/errors/transaction_errors.ts b/packages/web3-errors/src/errors/transaction_errors.ts index 9255769b6e6..27e99ce81f7 100644 --- a/packages/web3-errors/src/errors/transaction_errors.ts +++ b/packages/web3-errors/src/errors/transaction_errors.ts @@ -17,19 +17,44 @@ along with web3.js. If not, see . /* eslint-disable max-classes-per-file */ -import { TransactionReceipt } from 'web3-types'; +import { Bytes, HexString, Numbers, TransactionReceipt } from 'web3-types'; import { ERR_RAW_TX_UNDEFINED, ERR_TX, ERR_TX_CONTRACT_NOT_STORED, + ERR_TX_CHAIN_ID_MISMATCH, + ERR_TX_DATA_AND_INPUT, + ERR_TX_GAS_MISMATCH, + ERR_TX_INVALID_CALL, + ERR_TX_INVALID_CHAIN_INFO, + ERR_TX_INVALID_FEE_MARKET_GAS, + ERR_TX_INVALID_FEE_MARKET_GAS_PRICE, + ERR_TX_INVALID_LEGACY_FEE_MARKET, + ERR_TX_INVALID_LEGACY_GAS, + ERR_TX_INVALID_NONCE_OR_CHAIN_ID, + ERR_TX_INVALID_OBJECT, + ERR_TX_INVALID_SENDER, + ERR_TX_LOCAL_WALLET_NOT_AVAILABLE, + ERR_TX_MISSING_CHAIN_INFO, + ERR_TX_MISSING_CUSTOM_CHAIN, + ERR_TX_MISSING_CUSTOM_CHAIN_ID, + ERR_TX_MISSING_GAS, ERR_TX_NO_CONTRACT_ADDRESS, ERR_TX_OUT_OF_GAS, ERR_TX_REVERT_INSTRUCTION, ERR_TX_REVERT_TRANSACTION, ERR_TX_REVERT_WITHOUT_REASON, ERR_TX_NOT_FOUND, + ERR_TX_SEND_TIMEOUT, + ERR_TX_SIGNING, + ERR_TX_UNABLE_TO_POPULATE_NONCE, + ERR_TX_UNSUPPORTED_EIP_1559, + ERR_TX_UNSUPPORTED_TYPE, + ERR_TX_POLLING_TIMEOUT, + ERR_TX_RECEIPT_MISSING_OR_BLOCKHASH_NULL, + ERR_TX_RECEIPT_MISSING_BLOCK_NUMBER, } from '../error_codes'; -import { Web3Error } from '../web3_error_base'; +import { InvalidValueError, Web3Error } from '../web3_error_base'; export class TransactionError extends Web3Error { public code = ERR_TX; @@ -132,3 +157,298 @@ export class TransactionNotFound extends TransactionError { this.code = ERR_TX_NOT_FOUND; } } +export class InvalidTransactionWithSender extends InvalidValueError { + public code = ERR_TX_INVALID_SENDER; + + public constructor(value: unknown) { + super(value, 'invalid transaction with sender'); + } +} + +export class InvalidTransactionCall extends InvalidValueError { + public code = ERR_TX_INVALID_CALL; + + public constructor(value: unknown) { + super(value, 'invalid transaction call'); + } +} + +export class MissingCustomChainError extends InvalidValueError { + public code = ERR_TX_MISSING_CUSTOM_CHAIN; + + public constructor() { + super( + 'MissingCustomChainError', + 'If tx.common is provided it must have tx.common.customChain', + ); + } +} + +export class MissingCustomChainIdError extends InvalidValueError { + public code = ERR_TX_MISSING_CUSTOM_CHAIN_ID; + + public constructor() { + super( + 'MissingCustomChainIdError', + 'If tx.common is provided it must have tx.common.customChain and tx.common.customChain.chainId', + ); + } +} + +export class ChainIdMismatchError extends InvalidValueError { + public code = ERR_TX_CHAIN_ID_MISMATCH; + + public constructor(value: { txChainId: unknown; customChainId: unknown }) { + super( + JSON.stringify(value), + // https://github.com/ChainSafe/web3.js/blob/8783f4d64e424456bdc53b34ef1142d0a7cee4d7/packages/web3-eth-accounts/src/index.js#L176 + 'Chain Id doesnt match in tx.chainId tx.common.customChain.chainId', + ); + } +} + +export class CommonOrChainAndHardforkError extends InvalidValueError { + public code = ERR_TX_INVALID_CHAIN_INFO; + + public constructor() { + super( + 'CommonOrChainAndHardforkError', + 'Please provide the @ethereumjs/common object or the chain and hardfork property but not all together.', + ); + } +} + +export class MissingChainOrHardforkError extends InvalidValueError { + public code = ERR_TX_MISSING_CHAIN_INFO; + + public constructor(value: { chain: string | undefined; hardfork: string | undefined }) { + super( + 'MissingChainOrHardforkError', + `When specifying chain and hardfork, both values must be defined. Received "chain": ${ + value.chain ?? 'undefined' + }, "hardfork": ${value.hardfork ?? 'undefined'}`, + ); + } +} + +export class MissingGasError extends InvalidValueError { + public code = ERR_TX_MISSING_GAS; + + public constructor(value: { + gas: Numbers | undefined; + gasLimit: Numbers | undefined; + gasPrice: Numbers | undefined; + maxPriorityFeePerGas: Numbers | undefined; + maxFeePerGas: Numbers | undefined; + }) { + super( + `gas: ${value.gas ?? 'undefined'}, gasLimit: ${ + value.gasLimit ?? 'undefined' + }, gasPrice: ${value.gasPrice ?? 'undefined'}, maxPriorityFeePerGas: ${ + value.maxPriorityFeePerGas ?? 'undefined' + }, maxFeePerGas: ${value.maxFeePerGas ?? 'undefined'}`, + '"gas" is missing', + ); + } +} + +export class TransactionGasMismatchError extends InvalidValueError { + public code = ERR_TX_GAS_MISMATCH; + + public constructor(value: { + gas: Numbers | undefined; + gasLimit: Numbers | undefined; + gasPrice: Numbers | undefined; + maxPriorityFeePerGas: Numbers | undefined; + maxFeePerGas: Numbers | undefined; + }) { + super( + `gas: ${value.gas ?? 'undefined'}, gasLimit: ${ + value.gasLimit ?? 'undefined' + }, gasPrice: ${value.gasPrice ?? 'undefined'}, maxPriorityFeePerGas: ${ + value.maxPriorityFeePerGas ?? 'undefined' + }, maxFeePerGas: ${value.maxFeePerGas ?? 'undefined'}`, + 'transaction must specify legacy or fee market gas properties, not both', + ); + } +} + +export class InvalidGasOrGasPrice extends InvalidValueError { + public code = ERR_TX_INVALID_LEGACY_GAS; + + public constructor(value: { gas: Numbers | undefined; gasPrice: Numbers | undefined }) { + super( + `gas: ${value.gas ?? 'undefined'}, gasPrice: ${value.gasPrice ?? 'undefined'}`, + 'Gas or gasPrice is lower than 0', + ); + } +} + +export class InvalidMaxPriorityFeePerGasOrMaxFeePerGas extends InvalidValueError { + public code = ERR_TX_INVALID_FEE_MARKET_GAS; + + public constructor(value: { + maxPriorityFeePerGas: Numbers | undefined; + maxFeePerGas: Numbers | undefined; + }) { + super( + `maxPriorityFeePerGas: ${value.maxPriorityFeePerGas ?? 'undefined'}, maxFeePerGas: ${ + value.maxFeePerGas ?? 'undefined' + }`, + 'maxPriorityFeePerGas or maxFeePerGas is lower than 0', + ); + } +} + +export class Eip1559GasPriceError extends InvalidValueError { + public code = ERR_TX_INVALID_FEE_MARKET_GAS_PRICE; + + public constructor(value: unknown) { + super(value, "eip-1559 transactions don't support gasPrice"); + } +} + +export class UnsupportedFeeMarketError extends InvalidValueError { + public code = ERR_TX_INVALID_LEGACY_FEE_MARKET; + + public constructor(value: { + maxPriorityFeePerGas: Numbers | undefined; + maxFeePerGas: Numbers | undefined; + }) { + super( + `maxPriorityFeePerGas: ${value.maxPriorityFeePerGas ?? 'undefined'}, maxFeePerGas: ${ + value.maxFeePerGas ?? 'undefined' + }`, + "pre-eip-1559 transaction don't support maxFeePerGas/maxPriorityFeePerGas", + ); + } +} + +export class InvalidTransactionObjectError extends InvalidValueError { + public code = ERR_TX_INVALID_OBJECT; + + public constructor(value: unknown) { + super(value, 'invalid transaction object'); + } +} + +export class InvalidNonceOrChainIdError extends InvalidValueError { + public code = ERR_TX_INVALID_NONCE_OR_CHAIN_ID; + + public constructor(value: { nonce: Numbers | undefined; chainId: Numbers | undefined }) { + super( + `nonce: ${value.nonce ?? 'undefined'}, chainId: ${value.chainId ?? 'undefined'}`, + 'Nonce or chainId is lower than 0', + ); + } +} + +export class UnableToPopulateNonceError extends InvalidValueError { + public code = ERR_TX_UNABLE_TO_POPULATE_NONCE; + + public constructor() { + super('UnableToPopulateNonceError', 'unable to populate nonce, no from address available'); + } +} + +export class Eip1559NotSupportedError extends InvalidValueError { + public code = ERR_TX_UNSUPPORTED_EIP_1559; + + public constructor() { + super('Eip1559NotSupportedError', "Network doesn't support eip-1559"); + } +} + +export class UnsupportedTransactionTypeError extends InvalidValueError { + public code = ERR_TX_UNSUPPORTED_TYPE; + + public constructor(value: unknown) { + super(value, 'unsupported transaction type'); + } +} + +export class TransactionDataAndInputError extends InvalidValueError { + public code = ERR_TX_DATA_AND_INPUT; + + public constructor(value: { data: HexString | undefined; input: HexString | undefined }) { + super( + `data: ${value.data ?? 'undefined'}, input: ${value.input ?? 'undefined'}`, + 'You can\'t have "data" and "input" as properties of transactions at the same time, please use either "data" or "input" instead.', + ); + } +} + +export class TransactionSendTimeoutError extends Web3Error { + public code = ERR_TX_SEND_TIMEOUT; + + public constructor(value: { numberOfSeconds: number; transactionHash?: Bytes }) { + super( + `The connected Ethereum Node did not respond within ${ + value.numberOfSeconds + } seconds, please make sure your transaction was properly sent and you are connected to a healthy Node. Be aware that transaction might still be pending or mined!\n\tTransaction Hash: ${ + value.transactionHash ? value.transactionHash.toString() : 'not available' + }`, + ); + } +} + +function transactionTimeoutHint(transactionHash?: Bytes) { + return `Please make sure your transaction was properly sent and there no pervious pending transaction for the same account. However, be aware that it might still be mined!\n\tTransaction Hash: ${ + transactionHash ? transactionHash.toString() : 'not available' + }`; +} + +export class TransactionPollingTimeoutError extends Web3Error { + public code = ERR_TX_POLLING_TIMEOUT; + + public constructor(value: { numberOfSeconds: number; transactionHash: Bytes }) { + super( + `Transaction was not mined within ${ + value.numberOfSeconds + } seconds. ${transactionTimeoutHint(value.transactionHash)}`, + ); + } +} + +export class TransactionMissingReceiptOrBlockHashError extends InvalidValueError { + public code = ERR_TX_RECEIPT_MISSING_OR_BLOCKHASH_NULL; + + public constructor(value: { + receipt: TransactionReceipt; + blockHash: Bytes; + transactionHash: Bytes; + }) { + super( + `receipt: ${JSON.stringify( + value.receipt, + )}, blockHash: ${value.blockHash?.toString()}, transactionHash: ${value.transactionHash?.toString()}`, + `Receipt missing or blockHash null`, + ); + } +} + +export class TransactionReceiptMissingBlockNumberError extends InvalidValueError { + public code = ERR_TX_RECEIPT_MISSING_BLOCK_NUMBER; + + public constructor(value: { receipt: TransactionReceipt }) { + super(`receipt: ${JSON.stringify(value.receipt)}`, `Receipt missing block number`); + } +} + +export class TransactionSigningError extends Web3Error { + public code = ERR_TX_SIGNING; + public constructor(errorDetails: string) { + super(`Invalid signature. "${errorDetails}"`); + } +} + +export class LocalWalletNotAvailableError extends InvalidValueError { + public code = ERR_TX_LOCAL_WALLET_NOT_AVAILABLE; + + public constructor() { + super( + 'LocalWalletNotAvailableError', + `Attempted to index account in local wallet, but no wallet is available`, + ); + } +} diff --git a/packages/web3-eth-accounts/src/account.ts b/packages/web3-eth-accounts/src/account.ts index a0bf8bac052..513fb245805 100644 --- a/packages/web3-eth-accounts/src/account.ts +++ b/packages/web3-eth-accounts/src/account.ts @@ -30,7 +30,7 @@ import { KeyStoreVersionError, PBKDF2IterationsError, PrivateKeyLengthError, - SignerError, + TransactionSigningError, UndefinedRawTransactionError, } from 'web3-errors'; import { Address, Bytes, HexString } from 'web3-types'; @@ -248,7 +248,7 @@ export const signTransaction = async ( ): Promise => { const signedTx = transaction.sign(Buffer.from(privateKey.substring(2), 'hex')); if (isNullish(signedTx.v) || isNullish(signedTx.r) || isNullish(signedTx.s)) - throw new SignerError('Signer Error'); + throw new TransactionSigningError('Signer Error'); const validationErrors = signedTx.validate(true); @@ -257,7 +257,7 @@ export const signTransaction = async ( for (const validationError of validationErrors) { errorString += `${errorString} ${validationError}.`; } - throw new SignerError(errorString); + throw new TransactionSigningError(errorString); } const rawTx = bytesToHex(signedTx.serialize()); @@ -621,7 +621,7 @@ export const privateKeyToAccount = (privateKey: Bytes, ignoreLength?: boolean): privateKey: bytesToHex(privateKeyBuffer), // eslint-disable-next-line @typescript-eslint/no-unused-vars signTransaction: (_tx: Record) => { - throw new SignerError('Do not have network access to sign the transaction'); + throw new TransactionSigningError('Do not have network access to sign the transaction'); }, sign: (data: Record | string) => sign(typeof data === 'string' ? data : JSON.stringify(data), privateKeyBuffer), diff --git a/packages/web3-eth/CHANGELOG.md b/packages/web3-eth/CHANGELOG.md index 73ef64f66eb..de3955849b0 100644 --- a/packages/web3-eth/CHANGELOG.md +++ b/packages/web3-eth/CHANGELOG.md @@ -40,3 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - [setimmediate](https://github.com/yuzujs/setImmediate) package to polyfill [setImmediate](https://nodejs.org/api/timers.html#setimmediatecallback-args) for browsers (#5450) + +### Removed + +- Moved the errors' classes from `web3-eth/src/errors.ts` to `web3-errors/src/errors/transaction_errors.ts` (#5462) diff --git a/packages/web3-eth/src/errors.ts b/packages/web3-eth/src/errors.ts deleted file mode 100644 index 63fdaa0cf2d..00000000000 --- a/packages/web3-eth/src/errors.ts +++ /dev/null @@ -1,334 +0,0 @@ -/* -This file is part of web3.js. - -web3.js is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -web3.js is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with web3.js. If not, see . -*/ - -/* eslint-disable max-classes-per-file */ -import { - ERR_TX_CHAIN_ID_MISMATCH, - ERR_TX_INVALID_CALL, - ERR_TX_INVALID_CHAIN_INFO, - ERR_TX_INVALID_SENDER, - ERR_TX_LOCAL_WALLET_NOT_AVAILABLE, - ERR_TX_MISSING_CHAIN_INFO, - ERR_TX_MISSING_CUSTOM_CHAIN, - ERR_TX_MISSING_CUSTOM_CHAIN_ID, - ERR_TX_MISSING_GAS, - ERR_TX_INVALID_FEE_MARKET_GAS, - ERR_TX_INVALID_LEGACY_FEE_MARKET, - ERR_TX_INVALID_NONCE_OR_CHAIN_ID, - ERR_TX_UNSUPPORTED_EIP_1559, - ERR_TX_UNSUPPORTED_TYPE, - ERR_TX_UNABLE_TO_POPULATE_NONCE, - ERR_TX_INVALID_OBJECT, - ERR_TX_INVALID_FEE_MARKET_GAS_PRICE, - ERR_TX_INVALID_LEGACY_GAS, - ERR_TX_DATA_AND_INPUT, - ERR_TX_SEND_TIMEOUT, - ERR_TX_POLLING_TIMEOUT, - ERR_TX_RECEIPT_MISSING_OR_BLOCKHASH_NULL, - ERR_TX_RECEIPT_MISSING_BLOCK_NUMBER, - ERR_SIGNATURE_FAILED, - InvalidValueError, - Web3Error, -} from 'web3-errors'; -import { Bytes, HexString, Numbers, TransactionReceipt } from 'web3-types'; - -export class InvalidTransactionWithSender extends InvalidValueError { - public code = ERR_TX_INVALID_SENDER; - - public constructor(value: unknown) { - super(value, 'invalid transaction with sender'); - } -} - -export class InvalidTransactionCall extends InvalidValueError { - public code = ERR_TX_INVALID_CALL; - - public constructor(value: unknown) { - super(value, 'invalid transaction call'); - } -} - -export class MissingCustomChainError extends InvalidValueError { - public code = ERR_TX_MISSING_CUSTOM_CHAIN; - - public constructor() { - super( - 'MissingCustomChainError', - 'If tx.common is provided it must have tx.common.customChain', - ); - } -} - -export class MissingCustomChainIdError extends InvalidValueError { - public code = ERR_TX_MISSING_CUSTOM_CHAIN_ID; - - public constructor() { - super( - 'MissingCustomChainIdError', - 'If tx.common is provided it must have tx.common.customChain and tx.common.customChain.chainId', - ); - } -} - -export class ChainIdMismatchError extends InvalidValueError { - public code = ERR_TX_CHAIN_ID_MISMATCH; - - public constructor(value: { txChainId: unknown; customChainId: unknown }) { - super( - JSON.stringify(value), - // https://github.com/ChainSafe/web3.js/blob/8783f4d64e424456bdc53b34ef1142d0a7cee4d7/packages/web3-eth-accounts/src/index.js#L176 - 'Chain Id doesnt match in tx.chainId tx.common.customChain.chainId', - ); - } -} - -export class CommonOrChainAndHardforkError extends InvalidValueError { - public code = ERR_TX_INVALID_CHAIN_INFO; - - public constructor() { - super( - 'CommonOrChainAndHardforkError', - 'Please provide the @ethereumjs/common object or the chain and hardfork property but not all together.', - ); - } -} - -export class MissingChainOrHardforkError extends InvalidValueError { - public code = ERR_TX_MISSING_CHAIN_INFO; - - public constructor(value: { chain: string | undefined; hardfork: string | undefined }) { - super( - 'MissingChainOrHardforkError', - `When specifying chain and hardfork, both values must be defined. Received "chain": ${ - value.chain ?? 'undefined' - }, "hardfork": ${value.hardfork ?? 'undefined'}`, - ); - } -} - -export class MissingGasError extends InvalidValueError { - public code = ERR_TX_MISSING_GAS; - - public constructor(value: { - gas: Numbers | undefined; - gasLimit: Numbers | undefined; - gasPrice: Numbers | undefined; - maxPriorityFeePerGas: Numbers | undefined; - maxFeePerGas: Numbers | undefined; - }) { - super( - `gas: ${value.gas ?? 'undefined'}, gasLimit: ${ - value.gasLimit ?? 'undefined' - }, gasPrice: ${value.gasPrice ?? 'undefined'}, maxPriorityFeePerGas: ${ - value.maxPriorityFeePerGas ?? 'undefined' - }, maxFeePerGas: ${value.maxFeePerGas ?? 'undefined'}`, - '"gas" is missing', - ); - } -} - -export class TransactionGasMismatchError extends InvalidValueError { - public code = ERR_TX_MISSING_GAS; - - public constructor(value: { - gas: Numbers | undefined; - gasLimit: Numbers | undefined; - gasPrice: Numbers | undefined; - maxPriorityFeePerGas: Numbers | undefined; - maxFeePerGas: Numbers | undefined; - }) { - super( - `gas: ${value.gas ?? 'undefined'}, gasLimit: ${ - value.gasLimit ?? 'undefined' - }, gasPrice: ${value.gasPrice ?? 'undefined'}, maxPriorityFeePerGas: ${ - value.maxPriorityFeePerGas ?? 'undefined' - }, maxFeePerGas: ${value.maxFeePerGas ?? 'undefined'}`, - 'transaction must specify legacy or fee market gas properties, not both', - ); - } -} - -export class InvalidGasOrGasPrice extends InvalidValueError { - public code = ERR_TX_INVALID_LEGACY_GAS; - - public constructor(value: { gas: Numbers | undefined; gasPrice: Numbers | undefined }) { - super( - `gas: ${value.gas ?? 'undefined'}, gasPrice: ${value.gasPrice ?? 'undefined'}`, - 'Gas or gasPrice is lower than 0', - ); - } -} - -export class InvalidMaxPriorityFeePerGasOrMaxFeePerGas extends InvalidValueError { - public code = ERR_TX_INVALID_FEE_MARKET_GAS; - - public constructor(value: { - maxPriorityFeePerGas: Numbers | undefined; - maxFeePerGas: Numbers | undefined; - }) { - super( - `maxPriorityFeePerGas: ${value.maxPriorityFeePerGas ?? 'undefined'}, maxFeePerGas: ${ - value.maxFeePerGas ?? 'undefined' - }`, - 'maxPriorityFeePerGas or maxFeePerGas is lower than 0', - ); - } -} - -export class Eip1559GasPriceError extends InvalidValueError { - public code = ERR_TX_INVALID_FEE_MARKET_GAS_PRICE; - - public constructor(value: unknown) { - super(value, "eip-1559 transactions don't support gasPrice"); - } -} - -export class UnsupportedFeeMarketError extends InvalidValueError { - public code = ERR_TX_INVALID_LEGACY_FEE_MARKET; - - public constructor(value: { - maxPriorityFeePerGas: Numbers | undefined; - maxFeePerGas: Numbers | undefined; - }) { - super( - `maxPriorityFeePerGas: ${value.maxPriorityFeePerGas ?? 'undefined'}, maxFeePerGas: ${ - value.maxFeePerGas ?? 'undefined' - }`, - "pre-eip-1559 transaction don't support maxFeePerGas/maxPriorityFeePerGas", - ); - } -} - -export class InvalidTransactionObjectError extends InvalidValueError { - public code = ERR_TX_INVALID_OBJECT; - - public constructor(value: unknown) { - super(value, 'invalid transaction object'); - } -} - -export class InvalidNonceOrChainIdError extends InvalidValueError { - public code = ERR_TX_INVALID_NONCE_OR_CHAIN_ID; - - public constructor(value: { nonce: Numbers | undefined; chainId: Numbers | undefined }) { - super( - `nonce: ${value.nonce ?? 'undefined'}, chainId: ${value.chainId ?? 'undefined'}`, - 'Nonce or chainId is lower than 0', - ); - } -} - -export class UnableToPopulateNonceError extends InvalidValueError { - public code = ERR_TX_UNABLE_TO_POPULATE_NONCE; - - public constructor() { - super('UnableToPopulateNonceError', 'unable to populate nonce, no from address available'); - } -} - -export class Eip1559NotSupportedError extends InvalidValueError { - public code = ERR_TX_UNSUPPORTED_EIP_1559; - - public constructor() { - super('Eip1559NotSupportedError', "Network doesn't support eip-1559"); - } -} - -export class UnsupportedTransactionTypeError extends InvalidValueError { - public code = ERR_TX_UNSUPPORTED_TYPE; - - public constructor(value: unknown) { - super(value, 'unsupported transaction type'); - } -} - -export class TransactionDataAndInputError extends InvalidValueError { - public code = ERR_TX_DATA_AND_INPUT; - - public constructor(value: { data: HexString | undefined; input: HexString | undefined }) { - super( - `data: ${value.data ?? 'undefined'}, input: ${value.input ?? 'undefined'}`, - 'You can\'t have "data" and "input" as properties of transactions at the same time, please use either "data" or "input" instead.', - ); - } -} - -export class TransactionSendTimeoutError extends Web3Error { - public code = ERR_TX_SEND_TIMEOUT; - - public constructor(value: { numberOfSeconds: number; transactionHash?: Bytes }) { - super( - `The connected Ethereum Node did not respond within ${ - value.numberOfSeconds - } seconds, please make sure your transaction was properly sent and you are connected to a healthy Node. Be aware that transaction might still be pending or mined!\n\tTransaction Hash: ${ - value.transactionHash ? value.transactionHash.toString() : 'not available' - }`, - ); - } -} - -export class TransactionPollingTimeoutError extends Web3Error { - public code = ERR_TX_POLLING_TIMEOUT; - - public constructor(value: { numberOfSeconds: number; transactionHash: Bytes }) { - super( - `Transaction was not mined within ${ - value.numberOfSeconds - } seconds, please make sure your transaction was properly sent. Be aware that it might still be pending or mined!\n\tTransaction Hash: ${value.transactionHash.toString()}`, - ); - } -} - -export class TransactionMissingReceiptOrBlockHashError extends InvalidValueError { - public code = ERR_TX_RECEIPT_MISSING_OR_BLOCKHASH_NULL; - - public constructor(value: { - receipt: TransactionReceipt; - blockHash: Bytes; - transactionHash: Bytes; - }) { - super( - `receipt: ${JSON.stringify( - value.receipt, - )}, blockHash: ${value.blockHash.toString()}, transactionHash: ${value.transactionHash.toString()}`, - `Receipt missing or blockHash null`, - ); - } -} - -export class TransactionReceiptMissingBlockNumberError extends InvalidValueError { - public code = ERR_TX_RECEIPT_MISSING_BLOCK_NUMBER; - - public constructor(value: { receipt: TransactionReceipt }) { - super(`receipt: ${JSON.stringify(value.receipt)}`, `Receipt missing block number`); - } -} - -export class SignatureError extends InvalidValueError { - public code = ERR_SIGNATURE_FAILED; -} - -export class LocalWalletNotAvailableError extends InvalidValueError { - public code = ERR_TX_LOCAL_WALLET_NOT_AVAILABLE; - - public constructor() { - super( - 'LocalWalletNotAvailableError', - `Attempted to index account in local wallet, but no wallet is available`, - ); - } -} diff --git a/packages/web3-eth/src/rpc_method_wrappers.ts b/packages/web3-eth/src/rpc_method_wrappers.ts index a73b0418c79..1371b4638d2 100644 --- a/packages/web3-eth/src/rpc_method_wrappers.ts +++ b/packages/web3-eth/src/rpc_method_wrappers.ts @@ -50,8 +50,12 @@ import { waitWithTimeout, } from 'web3-utils'; import { isBlockTag, isBytes, isNullish, isString } from 'web3-validator'; -import { TransactionError, TransactionRevertError } from 'web3-errors'; -import { SignatureError, TransactionSendTimeoutError } from './errors'; +import { + TransactionError, + TransactionRevertError, + SignatureError, + TransactionSendTimeoutError, +} from 'web3-errors'; import * as rpcMethods from './rpc_methods'; import { accountSchema, diff --git a/packages/web3-eth/src/utils/format_transaction.ts b/packages/web3-eth/src/utils/format_transaction.ts index a73be284b1a..42468f98c3c 100644 --- a/packages/web3-eth/src/utils/format_transaction.ts +++ b/packages/web3-eth/src/utils/format_transaction.ts @@ -25,7 +25,7 @@ import { } from 'web3-utils'; import { Transaction } from 'web3-types'; import { isNullish } from 'web3-validator'; -import { TransactionDataAndInputError } from '../errors'; +import { TransactionDataAndInputError } from 'web3-errors'; import { transactionSchema } from '../schemas'; export function formatTransaction< diff --git a/packages/web3-eth/src/utils/get_transaction_gas_pricing.ts b/packages/web3-eth/src/utils/get_transaction_gas_pricing.ts index fbe0c0e4c5a..af14af48a8b 100644 --- a/packages/web3-eth/src/utils/get_transaction_gas_pricing.ts +++ b/packages/web3-eth/src/utils/get_transaction_gas_pricing.ts @@ -19,7 +19,7 @@ import { FormatType, DataFormat, format, ETH_DATA_FORMAT } from 'web3-utils'; import { Web3Context } from 'web3-core'; import { EthExecutionAPI, Numbers, Transaction } from 'web3-types'; import { isNullish } from 'web3-validator'; -import { Eip1559NotSupportedError, UnsupportedTransactionTypeError } from '../errors'; +import { Eip1559NotSupportedError, UnsupportedTransactionTypeError } from 'web3-errors'; // eslint-disable-next-line import/no-cycle import { getBlock, getGasPrice } from '../rpc_method_wrappers'; import { InternalTransaction } from '../types'; diff --git a/packages/web3-eth/src/utils/transaction_builder.ts b/packages/web3-eth/src/utils/transaction_builder.ts index ae941d002c8..3ded359af39 100644 --- a/packages/web3-eth/src/utils/transaction_builder.ts +++ b/packages/web3-eth/src/utils/transaction_builder.ts @@ -36,13 +36,13 @@ import { Web3Context } from 'web3-core'; import { privateKeyToAddress } from 'web3-eth-accounts'; import { getId, Web3NetAPI } from 'web3-net'; import { isNullish, isNumber } from 'web3-validator'; -import { NUMBER_DATA_FORMAT } from '../constants'; import { InvalidTransactionWithSender, LocalWalletNotAvailableError, TransactionDataAndInputError, UnableToPopulateNonceError, -} from '../errors'; +} from 'web3-errors'; +import { NUMBER_DATA_FORMAT } from '../constants'; // eslint-disable-next-line import/no-cycle import { getChainId, getTransactionCount } from '../rpc_method_wrappers'; import { detectTransactionType } from './detect_transaction_type'; diff --git a/packages/web3-eth/src/utils/wait_for_transaction_receipt.ts b/packages/web3-eth/src/utils/wait_for_transaction_receipt.ts index 7160768a8cf..11cf2c90cd0 100644 --- a/packages/web3-eth/src/utils/wait_for_transaction_receipt.ts +++ b/packages/web3-eth/src/utils/wait_for_transaction_receipt.ts @@ -14,13 +14,14 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with web3.js. If not, see . */ + import { EthExecutionAPI, Bytes, TransactionReceipt } from 'web3-types'; import { Web3Context } from 'web3-core'; +import { TransactionPollingTimeoutError } from 'web3-errors'; import { DataFormat, isNullish, waitWithTimeout } from 'web3-utils'; // eslint-disable-next-line import/no-cycle import { getTransactionReceipt } from '../rpc_method_wrappers'; -import { TransactionPollingTimeoutError } from '../errors'; export async function waitForTransactionReceipt( web3Context: Web3Context, diff --git a/packages/web3-eth/src/utils/watch_transaction_for_confirmations.ts b/packages/web3-eth/src/utils/watch_transaction_for_confirmations.ts index 2d15987dbfc..82a8e0576da 100644 --- a/packages/web3-eth/src/utils/watch_transaction_for_confirmations.ts +++ b/packages/web3-eth/src/utils/watch_transaction_for_confirmations.ts @@ -29,7 +29,7 @@ import { isNullish } from 'web3-validator'; import { TransactionMissingReceiptOrBlockHashError, TransactionReceiptMissingBlockNumberError, -} from '../errors'; +} from 'web3-errors'; import { SendSignedTransactionEvents, SendTransactionEvents } from '../types'; import { getBlockByNumber } from '../rpc_methods'; import { NewHeadsSubscription } from '../web3_subscriptions'; diff --git a/packages/web3-eth/src/validation.ts b/packages/web3-eth/src/validation.ts index b9ebbd4d894..0f4d0fa6882 100644 --- a/packages/web3-eth/src/validation.ts +++ b/packages/web3-eth/src/validation.ts @@ -44,7 +44,7 @@ import { MissingGasError, TransactionGasMismatchError, UnsupportedFeeMarketError, -} from './errors'; +} from 'web3-errors'; import { formatTransaction } from './utils/format_transaction'; import { InternalTransaction } from './types'; diff --git a/packages/web3-eth/test/fixtures/validate_transaction_for_signing.ts b/packages/web3-eth/test/fixtures/validate_transaction_for_signing.ts index cbe8e4b0ef0..10828550fba 100644 --- a/packages/web3-eth/test/fixtures/validate_transaction_for_signing.ts +++ b/packages/web3-eth/test/fixtures/validate_transaction_for_signing.ts @@ -30,7 +30,7 @@ import { MissingGasError, TransactionGasMismatchError, UnsupportedFeeMarketError, -} from '../../src/errors'; +} from 'web3-errors'; // eslint-disable-next-line @typescript-eslint/no-empty-function export const invalidTransactionObject: any[] = ['42', false, '0x0', BigInt(42), () => {}]; diff --git a/packages/web3-eth/test/fixtures/validation.ts b/packages/web3-eth/test/fixtures/validation.ts index e559821d763..6644167f25a 100644 --- a/packages/web3-eth/test/fixtures/validation.ts +++ b/packages/web3-eth/test/fixtures/validation.ts @@ -25,7 +25,7 @@ import { TransactionCall, TransactionWithSenderAPI, } from 'web3-types'; -import { InvalidTransactionCall, InvalidTransactionWithSender } from '../../src/errors'; +import { InvalidTransactionCall, InvalidTransactionWithSender } from 'web3-errors'; export const isBaseTransactionValidData: [BaseTransactionAPI, true][] = [ [ diff --git a/packages/web3-eth/test/integration/defaults.test.ts b/packages/web3-eth/test/integration/defaults.test.ts index 17051668cbf..539e2a917b6 100644 --- a/packages/web3-eth/test/integration/defaults.test.ts +++ b/packages/web3-eth/test/integration/defaults.test.ts @@ -19,6 +19,7 @@ import { Contract } from 'web3-eth-contract'; import { hexToNumber, numberToHex, DEFAULT_RETURN_FORMAT } from 'web3-utils'; import { TransactionBuilder, TransactionTypeParser, Web3Context, Web3PromiEvent } from 'web3-core'; import { TransactionReceipt, Web3BaseProvider } from 'web3-types'; +import { TransactionPollingTimeoutError, TransactionSendTimeoutError } from 'web3-errors'; import { prepareTransactionForSigning, SendTransactionEvents, @@ -45,7 +46,6 @@ import { MsgSenderAbi, MsgSenderBytecode } from '../shared_fixtures/build/MsgSen import { detectTransactionType } from '../../dist'; import { getTransactionGasPricing } from '../../src/utils/get_transaction_gas_pricing'; import { Resolve, sendFewTxes } from './helper'; -import { TransactionPollingTimeoutError, TransactionSendTimeoutError } from '../../src/errors'; describe('defaults', () => { let web3Eth: Web3Eth; diff --git a/packages/web3-eth/test/unit/default_transaction_builder.test.ts b/packages/web3-eth/test/unit/default_transaction_builder.test.ts index ac5f09a19ba..bb8ac1bc96e 100644 --- a/packages/web3-eth/test/unit/default_transaction_builder.test.ts +++ b/packages/web3-eth/test/unit/default_transaction_builder.test.ts @@ -27,7 +27,7 @@ import { Eip1559NotSupportedError, UnableToPopulateNonceError, UnsupportedTransactionTypeError, -} from '../../src/errors'; +} from 'web3-errors'; import { defaultTransactionBuilder } from '../../src/utils/transaction_builder'; import * as rpcMethods from '../../src/rpc_methods'; diff --git a/packages/web3-eth/test/unit/errors.test.ts b/packages/web3-eth/test/unit/errors.test.ts index a632414db20..e51cb8764a8 100644 --- a/packages/web3-eth/test/unit/errors.test.ts +++ b/packages/web3-eth/test/unit/errors.test.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 { InvalidTransactionCall, InvalidTransactionWithSender } from '../../src/errors'; +import { InvalidTransactionCall, InvalidTransactionWithSender } from 'web3-errors'; import { InvalidTransactionWithSenderData, InvalidTransactionCallData } from '../fixtures/errors'; describe('errors', () => { diff --git a/packages/web3-eth/test/unit/validate_transaction_for_signing.test.ts b/packages/web3-eth/test/unit/validate_transaction_for_signing.test.ts index 7bc9f40d8cc..b2546dd5f3f 100644 --- a/packages/web3-eth/test/unit/validate_transaction_for_signing.test.ts +++ b/packages/web3-eth/test/unit/validate_transaction_for_signing.test.ts @@ -17,7 +17,7 @@ along with web3.js. If not, see . /* eslint-disable jest/no-conditional-expect */ -import { InvalidTransactionObjectError } from '../../src/errors'; +import { InvalidTransactionObjectError } from 'web3-errors'; import { validateTransactionForSigning } from '../../src/validation'; import { invalidNonceOrChainIdData, diff --git a/packages/web3-eth/test/unit/validation.test.ts b/packages/web3-eth/test/unit/validation.test.ts index 72abdf00253..c805cdd75d7 100644 --- a/packages/web3-eth/test/unit/validation.test.ts +++ b/packages/web3-eth/test/unit/validation.test.ts @@ -17,7 +17,7 @@ along with web3.js. If not, see . /* eslint-disable jest/no-conditional-expect */ -import { InvalidTransactionCall, InvalidTransactionWithSender } from '../../src/errors'; +import { InvalidTransactionCall, InvalidTransactionWithSender } from 'web3-errors'; import { isAccessList, isAccessListEntry,