diff --git a/packages/web3-errors/src/errors/transaction_errors.ts b/packages/web3-errors/src/errors/transaction_errors.ts index fb2d0fbb804..e7e0aa96582 100644 --- a/packages/web3-errors/src/errors/transaction_errors.ts +++ b/packages/web3-errors/src/errors/transaction_errors.ts @@ -213,14 +213,14 @@ export class InvalidTransactionWithSender extends InvalidValueError { public code = ERR_TX_INVALID_SENDER; public constructor(value: unknown) { - super(value, 'invalid transaction with sender'); + super(value, 'invalid transaction with invalid sender'); } } export class InvalidTransactionWithReceiver extends InvalidValueError { public code = ERR_TX_INVALID_RECEIVER; public constructor(value: unknown) { - super(value, 'invalid transaction with receiver'); + super(value, 'invalid transaction with invalid receiver'); } } export class InvalidTransactionCall extends InvalidValueError { diff --git a/packages/web3-eth/src/utils/transaction_builder.ts b/packages/web3-eth/src/utils/transaction_builder.ts index 1a5b98f1340..324a8d07e1a 100644 --- a/packages/web3-eth/src/utils/transaction_builder.ts +++ b/packages/web3-eth/src/utils/transaction_builder.ts @@ -40,7 +40,7 @@ import { import { Web3Context } from 'web3-core'; import { privateKeyToAddress } from 'web3-eth-accounts'; import { getId } from 'web3-net'; -import { isNullish, isNumber } from 'web3-validator'; +import { isNullish, isNumber, isHexStrict } from 'web3-validator'; import { InvalidTransactionWithSender, InvalidTransactionWithReceiver, @@ -71,7 +71,7 @@ export const getTransactionFromOrToAttr = ( if (typeof transaction[attr] === 'string' && isAddress(transaction[attr] as string)) { return transaction[attr] as Address; } - if (isNumber(transaction[attr] as Numbers)) { + if (!isHexStrict(transaction[attr] as string) && isNumber(transaction[attr] as Numbers)) { if (web3Context.wallet) { const account = web3Context.wallet.get( format({ eth: 'uint' }, transaction[attr] as Numbers, NUMBER_DATA_FORMAT), diff --git a/packages/web3-eth/src/web3_eth.ts b/packages/web3-eth/src/web3_eth.ts index 61e189a533f..029d6196772 100644 --- a/packages/web3-eth/src/web3_eth.ts +++ b/packages/web3-eth/src/web3_eth.ts @@ -825,7 +825,7 @@ export class Web3Eth extends Web3Context. export const InvalidTransactionWithSenderData: [unknown, string][] = [ [ BigInt(9007199254740991), - 'Invalid value given "9007199254740991". Error: invalid transaction with sender.', + 'Invalid value given "9007199254740991". Error: invalid transaction with invalid sender.', ], - ['Invalid data', 'Invalid value given "Invalid data". Error: invalid transaction with sender.'], - ['0x0', 'Invalid value given "0x0". Error: invalid transaction with sender.'], - [0, 'Invalid value given "0". Error: invalid transaction with sender.'], + [ + 'Invalid data', + 'Invalid value given "Invalid data". Error: invalid transaction with invalid sender.', + ], + ['0x0', 'Invalid value given "0x0". Error: invalid transaction with invalid sender.'], + [0, 'Invalid value given "0". Error: invalid transaction with invalid sender.'], ]; export const InvalidTransactionCallData: [unknown, string][] = [ diff --git a/packages/web3-eth/test/fixtures/format_transaction.ts b/packages/web3-eth/test/fixtures/format_transaction.ts index 81754ef5443..871c885ff3c 100644 --- a/packages/web3-eth/test/fixtures/format_transaction.ts +++ b/packages/web3-eth/test/fixtures/format_transaction.ts @@ -245,3 +245,93 @@ export const numbersAsBigIntTransaction: FormatType< r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', }; + +const dummyTransaction: Transaction = { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + type: '0x0', + data: '0x0', + nonce: '0x4', + chainId: '0x1', + gasLimit: '0x5208', +}; +export const validGetTransactionFromOrToAttrData: { input: any; output: any }[] = [ + { + input: { + role: 'from', + transaction: { + ...dummyTransaction, + from: '0x58422b64d0e95ab4e93a9d95b755d9b53545c9ef', + }, + }, + output: '0x58422b64d0e95ab4e93a9d95b755d9b53545c9ef', + }, +]; +export const invalidGetTransactionFromOrToAttrData: { input: any; output: any }[] = [ + { + input: { + role: 'from', + transaction: { + ...dummyTransaction, + from: '0x58422b64d0e95ab4e93a9d95b755d9b53545c9eff', + }, + }, + output: 'Invalid value given "0x58422b64d0e95ab4e93a9d95b755d9b53545c9eff". Error: invalid transaction with invalid sender', + }, + { + input: { + role: 'to', + transaction: { + ...dummyTransaction, + to: '0x58422b64d0e95ab4e93a9d95b755d9b53545c9eff', + }, + }, + output: 'Invalid value given "0x58422b64d0e95ab4e93a9d95b755d9b53545c9eff". Error: invalid transaction with invalid receiver', + }, + { + input: { + role: 'from', + transaction: { + ...dummyTransaction, + from: '0x1', + }, + }, + output: 'Invalid value given "0x1". Error: invalid transaction with invalid sender', + }, + { + input: { + role: 'from', + transaction: { + ...dummyTransaction, + from: 1, + }, + }, + output: 'Invalid value given "LocalWalletNotAvailableError". Error: Attempted to index account in local wallet, but no wallet is available.', + }, +]; + +export const invalidGetTransactionFromOrToAttrDataForWallet: { input: any; output: any }[] = [ + { + input: { + role: 'from', + transaction: { + ...dummyTransaction, + from: 1, + }, + }, + output: 'Invalid value given "LocalWalletNotAvailableError". Error: Attempted to index account in local wallet, but no wallet is available.', + }, + { + input: { + role: 'from', + transaction: { + ...dummyTransaction, + from: 10, + }, + }, + output: 'Invalid value given "LocalWalletNotAvailableError". Error: Attempted to index account in local wallet, but no wallet is available.', + }, +]; diff --git a/packages/web3-eth/test/unit/utils/getTransactionFromOrToAttr.test.ts b/packages/web3-eth/test/unit/utils/getTransactionFromOrToAttr.test.ts new file mode 100644 index 00000000000..879ff57f11f --- /dev/null +++ b/packages/web3-eth/test/unit/utils/getTransactionFromOrToAttr.test.ts @@ -0,0 +1,70 @@ +/* +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 . +*/ + +import { Web3Context } from 'web3-core'; + +import { Wallet } from 'web3-eth-accounts'; +import { getTransactionFromOrToAttr } from '../../../src/utils/transaction_builder'; +import { + validGetTransactionFromOrToAttrData, + invalidGetTransactionFromOrToAttrData, + invalidGetTransactionFromOrToAttrDataForWallet, +} from '../../fixtures/format_transaction'; +import { createAccountProvider } from '../../fixtures/system_test_utils'; + +import Web3Eth from '../../../src'; + +describe('getTransactionFromOrToAttr', () => { + const web3Context = new Web3Context(); + + describe('valid data', () => { + it.each(validGetTransactionFromOrToAttrData)('$title', ({ input, output }) => { + const { role, transaction } = input; + + expect(getTransactionFromOrToAttr(role, web3Context, transaction)).toEqual(output); + }); + }); + + describe('invalid data', () => { + it.each(invalidGetTransactionFromOrToAttrData)('$title', ({ input, output }) => { + const { role, transaction } = input; + expect(() => getTransactionFromOrToAttr(role, web3Context, transaction)).toThrow( + output, + ); + }); + + it.each(invalidGetTransactionFromOrToAttrDataForWallet)( + '$title with wallet', + ({ input, output }) => { + const privateKey = + '0x348ce564d427a3311b6536bbcff9390d69395b06ed6c486954e971d960fe8709'; + + // setup wallet + const web3Eth = new Web3Eth('http://localhost:8545'); + const accountProvider = createAccountProvider(web3Eth); + const wallet = new Wallet(accountProvider); + web3Eth.wallet?.add(privateKey); + web3Eth['_wallet'] = wallet; + + const { role, transaction } = input; + expect(() => getTransactionFromOrToAttr(role, web3Eth, transaction)).toThrow( + output, + ); + }, + ); + }); +});