From 3fd0e9e01c61e4925234c8e38490b9fe57c0a778 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Sun, 9 Jan 2022 23:27:28 -1000 Subject: [PATCH 001/132] Add @ethereumjs/tx dependency --- packages/web3-eth/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/web3-eth/package.json b/packages/web3-eth/package.json index 2b4e61df29a..04fd4603d5a 100644 --- a/packages/web3-eth/package.json +++ b/packages/web3-eth/package.json @@ -39,6 +39,7 @@ "typescript": "^4.5.2" }, "dependencies": { + "@ethereumjs/tx": "^3.4.0", "web3-common": "1.0.0-alpha.0", "web3-core": "4.0.0-alpha.0", "web3-utils": "4.0.0-alpha.0", From f4f30dd400088339a0c3bff0e19b7820c43ba564 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Sun, 9 Jan 2022 23:27:49 -1000 Subject: [PATCH 002/132] Update Web3BaseProvider to SupportedProviders for Web3Eth constructor --- packages/web3-eth/src/index.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/web3-eth/src/index.ts b/packages/web3-eth/src/index.ts index 353cd68a10c..217ed25c1db 100644 --- a/packages/web3-eth/src/index.ts +++ b/packages/web3-eth/src/index.ts @@ -1,9 +1,8 @@ // Disabling because returnTypes must be last param to match 1.x params /* eslint-disable default-param-last */ -// import { TransactionCall, TransactionWithSender, Web3BaseProvider } from 'web3-common'; import { EthExecutionAPI, Web3BaseProvider, TransactionWithSender } from 'web3-common'; -import { Web3ConfigOptions, Web3Context } from 'web3-core'; +import { SupportedProviders, Web3ConfigOptions, Web3Context } from 'web3-core'; import { BlockNumberOrTag, ValidTypes, @@ -34,7 +33,10 @@ import * as rpcMethods from './rpc_methods'; export default class Web3Eth { public readonly web3Context: Web3Context; - public constructor(provider: Web3BaseProvider | string, options?: Partial) { + public constructor( + provider: SupportedProviders | string, + options?: Partial, + ) { this.web3Context = new Web3Context(provider, options); } From 4622b80b490fd9347632038b2f68a281c2297def Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Sun, 9 Jan 2022 23:27:59 -1000 Subject: [PATCH 003/132] WIP eth-tx --- packages/web3-eth/src/eth_tx.ts | 241 ++++++++++++++++++++++++++++++++ 1 file changed, 241 insertions(+) create mode 100644 packages/web3-eth/src/eth_tx.ts diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts new file mode 100644 index 00000000000..7502f865642 --- /dev/null +++ b/packages/web3-eth/src/eth_tx.ts @@ -0,0 +1,241 @@ +import { TransactionFactory } from '@ethereumjs/tx'; +import { AccessList, EthExecutionAPI } from 'web3-common'; +import { Web3Context } from 'web3-core'; +import { + Address, + Numbers, + HexString, + ValidTypes, + convertObjectPropertiesToValidType, + toHex, +} from 'web3-utils'; +import { BlockTags } from 'web3-validator'; + +import Web3Eth from './index'; + +export type chain = 'goerli' | 'kovan' | 'mainnet' | 'rinkeby' | 'ropsten' | 'sepolia'; + +export type hardfork = + | 'arrowGlacier' + | 'berlin' + | 'byzantium' + | 'chainstart' + | 'constantinople' + | 'dao' + | 'homestead' + | 'istanbul' + | 'london' + | 'merge' + | 'muirGlacier' + | 'petersburg' + | 'shanghai' + | 'spuriousDragon' + | 'tangerineWhistle'; + +export interface CustomChain { + name?: string; + networkId: NumberType; + chainId: NumberType; +} + +export interface Common { + customChain: CustomChain; + baseChain?: chain; + hardfork?: hardfork; +} + +export interface CustomChain { + name?: string; + networkId: NumberType; + chainId: NumberType; +} + +export interface BaseTxData { + from?: Address; + to?: Address | null; + value?: NumberType; + gas?: NumberType; + gasPrice?: NumberType; + data?: HexString; + nonce?: NumberType; + chainId?: NumberType; + common?: Common; + chain?: chain; + hardfork?: hardfork; + gasLimit?: NumberType; + v?: NumberType; + r?: NumberType; + s?: NumberType; + type?: NumberType; +} + +export interface AccessListEIP2930TxData + extends BaseTxData { + accessList?: AccessList; +} + +export interface FeeMarketEIP1559TxData + extends AccessListEIP2930TxData { + gasPrice?: never; + maxPriorityFeePerGas?: NumberType; + maxFeePerGas?: NumberType; +} + +export type TxData = BaseTxData | AccessListEIP2930TxData | FeeMarketEIP1559TxData; +const txDataConvertibleProperties: ( + | keyof BaseTxData + | keyof AccessListEIP2930TxData + | keyof FeeMarketEIP1559TxData +)[] = [ + 'nonce', + 'gasPrice', + 'gasLimit', + 'value', + 'v', + 'r', + 's', + 'type', + 'chainId', + 'maxPriorityFeePerGas', + 'maxFeePerGas', +]; + +export default class Web3EthTx { + public static async fromTxData(txData: TxData, web3Context: Web3Context) { + if (typeof txData !== 'object' || txData === null) + // TODO - Replace error + throw new Error('invalid txData object'); + + Web3EthTx._validateCustomChainInfo(txData); + const txDataHexString = Web3EthTx._formatTxData(txData); + const { defaultedTxData, txOptions } = await Web3EthTx._defaultTxDataAndSeparateTxOptions( + txDataHexString, + Web3EthTx._detectTxType(txDataHexString), + web3Context, + ); + return TransactionFactory.fromTxData(defaultedTxData, txOptions); + } + + private static _validateCustomChainInfo(txData: TxData) { + if (txData.common !== undefined) { + if (txData.common.customChain === undefined) + // TODO - Replace error + throw new Error('If tx.common is provided it must have tx.common.customChain'); + if (txData.common.customChain.chainId === undefined) + // TODO - Replace error + throw new Error( + 'If tx.common is provided it must have tx.common.customChain and tx.common.customChain.chainId', + ); + if ( + txData.chainId !== undefined && + txData.chainId !== txData.common.customChain.chainId + ) + // TODO - Replace error + throw new Error( + 'Chain Id doesnt match in tx.chainId tx.common.customChain.chainId', + ); + } + } + + private static _formatTxData(txData: TxData) { + // TODO Fix TSC error + // @ts-ignore - Types of property 'gasPrice' are incompatible. Type 'string | undefined' is not assignable to type 'undefined' + const txDataHexString: + | BaseTxData + | AccessListEIP2930TxData + | FeeMarketEIP1559TxData = convertObjectPropertiesToValidType( + txData, + // TODO Fix TSC error + // @ts-ignore - TSC doesn't understand txDataConvertibleProperties contains keys of all possible tx types + txDataConvertibleProperties, + ValidTypes.HexString, + ); + if (txDataHexString.common !== undefined) { + txDataHexString.common.customChain = convertObjectPropertiesToValidType( + txDataHexString.common.customChain, + ['networkId', 'chainId'], + ValidTypes.HexString, + ); + } + // TODO - Formatting toLowerCase, toChecksumAddress, etc. + return txDataHexString; + } + + private static _detectTxType( + txData: + | BaseTxData + | AccessListEIP2930TxData + | FeeMarketEIP1559TxData, + ) { + const hasEip1559 = + (txData as FeeMarketEIP1559TxData).maxFeePerGas !== undefined || + (txData as FeeMarketEIP1559TxData).maxPriorityFeePerGas !== undefined; + if (txData.gasPrice !== undefined && (txData.type === '0x2' || hasEip1559)) + // TODO - Replace error + throw new Error("eip-1559 transactions don't support gasPrice"); + if ((txData.type === '0x0' || txData.type === '0x1') && hasEip1559) + // TODO - Replace error + throw new Error( + "pre-eip-1559 transaction don't support maxFeePerGas/maxPriorityFeePerGas", + ); + + if (txData.type !== undefined) return txData.type; + + if (hasEip1559) return '0x2'; + if (txData.hardfork === 'berlin') return '0x2'; + if (txData.common?.hardfork === 'berlin') return '0x2'; + + if ((txData as AccessListEIP2930TxData).accessList !== undefined) return '0x1'; + + return '0x0'; + } + + private static async _defaultTxDataAndSeparateTxOptions( + txData: + | BaseTxData + | AccessListEIP2930TxData + | FeeMarketEIP1559TxData, + txType: HexString, + web3Context: Web3Context, + ) { + const defaultedTxData = { + ...txData, + ...await Web3EthTx._handleTxPricing(txData, txType, web3Context), + data: txData.data ?? '0x', + value: txData.value ?? '0x', + gasLimit: txData.gasLimit ?? txData.gas, // TODO txData.gas is optional, need a default if both gasLimit and gas aren't provided + }; + if (txType >= '0x1' && (txData as AccessListEIP2930TxData).accessList === undefined) + (defaultedTxData as AccessListEIP2930TxData).accessList = []; + } + + private static async _handleTxPricing( + txData: + | BaseTxData + | AccessListEIP2930TxData + | FeeMarketEIP1559TxData, + txType: HexString, + web3Context: Web3Context, + ) { + const web3Eth = new Web3Eth(web3Context.currentProvider); + if (txType === '0x2') { + const block = await web3Eth.getBlock(BlockTags.LATEST); + if (block?.baseFeePerGas === undefined) + // TODO - Replace error + throw new Error("Network doesn't support eip-1559"); + const maxPriorityFeePerGas = + // TODO - Replace hardcoded value with configurable one + (txData as FeeMarketEIP1559TxData).maxPriorityFeePerGas ?? '0x9502F900'; // 2.5 + return { + maxPriorityFeePerGas, + maxFeePerGas: + (txData as FeeMarketEIP1559TxData).maxFeePerGas ?? + toHex(BigInt(block.baseFeePerGas) * BigInt(2) + BigInt(maxPriorityFeePerGas)), + }; + } else if (txType === '0x1' || txType === '0x0') { + return { gasPrice: txData.gasPrice ?? await web3Eth.getGasPrice() }; + } else { + throw new Error('txType not specified'); + } + } +} From 8fa2bc5746a2fb4cb0c0e80a0310e47950bfe538 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Wed, 12 Jan 2022 06:01:37 -1000 Subject: [PATCH 004/132] Add support for undefined values for convertToValidType --- packages/web3-utils/src/converters.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/web3-utils/src/converters.ts b/packages/web3-utils/src/converters.ts index 0a51d28a20e..fcacd581ea3 100644 --- a/packages/web3-utils/src/converters.ts +++ b/packages/web3-utils/src/converters.ts @@ -439,9 +439,11 @@ export const jsonInterfaceMethodToString = ( }; export const convertToValidType = ( - value: ValidReturnTypes[ValidTypes], // validate this + value: ValidReturnTypes[ValidTypes] | undefined, // validate this desiredType: ValidTypes, -): ValidReturnTypes[ValidTypes] => { +): ValidReturnTypes[ValidTypes] | undefined => { + if (value === undefined) return value; + switch (desiredType) { case ValidTypes.HexString: return numberToHex(value); From eb2305c5baee6d4e56fb29b83c64c8ad38a1a379 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Wed, 12 Jan 2022 06:02:00 -1000 Subject: [PATCH 005/132] Remove unused Web3BaseProvider --- packages/web3-eth/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web3-eth/src/index.ts b/packages/web3-eth/src/index.ts index 217ed25c1db..b5bd205ac9a 100644 --- a/packages/web3-eth/src/index.ts +++ b/packages/web3-eth/src/index.ts @@ -1,7 +1,7 @@ // Disabling because returnTypes must be last param to match 1.x params /* eslint-disable default-param-last */ -import { EthExecutionAPI, Web3BaseProvider, TransactionWithSender } from 'web3-common'; +import { EthExecutionAPI, TransactionWithSender } from 'web3-common'; import { SupportedProviders, Web3ConfigOptions, Web3Context } from 'web3-core'; import { BlockNumberOrTag, From 30b289d8ef669f11a715f4dd722d703876d9f493 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Wed, 12 Jan 2022 06:02:11 -1000 Subject: [PATCH 006/132] WIP eth-tx utils --- packages/web3-eth/src/eth_tx.ts | 347 +++++++++++++++----------------- 1 file changed, 163 insertions(+), 184 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 7502f865642..1bf42050187 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -1,20 +1,18 @@ -import { TransactionFactory } from '@ethereumjs/tx'; import { AccessList, EthExecutionAPI } from 'web3-common'; import { Web3Context } from 'web3-core'; import { Address, - Numbers, + convertToValidType, HexString, + HexStringBytes, + Numbers, + ValidReturnTypes, ValidTypes, - convertObjectPropertiesToValidType, - toHex, } from 'web3-utils'; -import { BlockTags } from 'web3-validator'; import Web3Eth from './index'; export type chain = 'goerli' | 'kovan' | 'mainnet' | 'rinkeby' | 'ropsten' | 'sepolia'; - export type hardfork = | 'arrowGlacier' | 'berlin' @@ -32,210 +30,191 @@ export type hardfork = | 'spuriousDragon' | 'tangerineWhistle'; -export interface CustomChain { +export interface CustomChain { name?: string; - networkId: NumberType; - chainId: NumberType; + networkId: Numbers; + chainId: Numbers; } -export interface Common { - customChain: CustomChain; +export interface Common { + customChain: CustomChain; baseChain?: chain; hardfork?: hardfork; } -export interface CustomChain { - name?: string; - networkId: NumberType; - chainId: NumberType; -} - -export interface BaseTxData { +export interface Transaction { from?: Address; - to?: Address | null; + to?: Address; value?: NumberType; gas?: NumberType; gasPrice?: NumberType; - data?: HexString; + type?: NumberType; + maxFeePerGas?: NumberType; + maxPriorityFeePerGas?: NumberType; + accessList?: AccessList; + data?: HexStringBytes; nonce?: NumberType; - chainId?: NumberType; - common?: Common; chain?: chain; hardfork?: hardfork; + chainId?: NumberType; + common?: Common; gasLimit?: NumberType; v?: NumberType; r?: NumberType; s?: NumberType; - type?: NumberType; -} - -export interface AccessListEIP2930TxData - extends BaseTxData { - accessList?: AccessList; -} - -export interface FeeMarketEIP1559TxData - extends AccessListEIP2930TxData { - gasPrice?: never; - maxPriorityFeePerGas?: NumberType; - maxFeePerGas?: NumberType; } -export type TxData = BaseTxData | AccessListEIP2930TxData | FeeMarketEIP1559TxData; -const txDataConvertibleProperties: ( - | keyof BaseTxData - | keyof AccessListEIP2930TxData - | keyof FeeMarketEIP1559TxData -)[] = [ - 'nonce', - 'gasPrice', - 'gasLimit', - 'value', - 'v', - 'r', - 's', - 'type', - 'chainId', - 'maxPriorityFeePerGas', - 'maxFeePerGas', -]; - -export default class Web3EthTx { - public static async fromTxData(txData: TxData, web3Context: Web3Context) { - if (typeof txData !== 'object' || txData === null) +export function formatTransaction( + transaction: Transaction, + desiredType: DesiredType, + overrideMethod?: (transaction: Transaction) => Transaction, +): Transaction { + if (overrideMethod !== undefined) return overrideMethod(transaction); + const formattedTransaction = { + ...transaction, + value: convertToValidType(transaction.value, desiredType), + gas: convertToValidType(transaction.gas, desiredType), + gasPrice: convertToValidType(transaction.gasPrice, desiredType), + type: convertToValidType(transaction.type, desiredType), + maxFeePerGas: convertToValidType(transaction.maxFeePerGas, desiredType), + maxPriorityFeePerGas: convertToValidType(transaction.maxPriorityFeePerGas, desiredType), + nonce: convertToValidType(transaction.nonce, desiredType), + chainId: convertToValidType(transaction.chainId, desiredType), + gasLimit: convertToValidType(transaction.gasLimit, desiredType), + v: convertToValidType(transaction.v, desiredType), + r: convertToValidType(transaction.r, desiredType), + s: convertToValidType(transaction.s, desiredType), + common: { + ...transaction.common, + customChain: { + ...transaction.common?.customChain, + networkId: convertToValidType( + transaction.common?.customChain.networkId, + desiredType, + ), + chainId: convertToValidType(transaction.common?.customChain.chainId, desiredType), + }, + }, + }; + return (formattedTransaction as Transaction) +}; + +export const detectTransactionType = ( + transaction: Transaction, + overrideMethod?: (transaction: Transaction) => Numbers | undefined, +): Numbers | undefined => { + if (overrideMethod !== undefined) return overrideMethod(transaction); + if (transaction.type !== undefined) return transaction.type; + + if (transaction.maxFeePerGas !== undefined || transaction.maxPriorityFeePerGas !== undefined) + return '0x2'; + if (transaction.hardfork === 'berlin') return '0x2'; + if (transaction.common?.hardfork === 'berlin') return '0x2'; + + if (transaction.accessList !== undefined) return '0x1'; + + return undefined; +}; + +const validateCustomChainInfo = (transaction: Transaction) => { + if (transaction.common !== undefined) { + if (transaction.common.customChain === undefined) // TODO - Replace error - throw new Error('invalid txData object'); - - Web3EthTx._validateCustomChainInfo(txData); - const txDataHexString = Web3EthTx._formatTxData(txData); - const { defaultedTxData, txOptions } = await Web3EthTx._defaultTxDataAndSeparateTxOptions( - txDataHexString, - Web3EthTx._detectTxType(txDataHexString), - web3Context, - ); - return TransactionFactory.fromTxData(defaultedTxData, txOptions); - } - - private static _validateCustomChainInfo(txData: TxData) { - if (txData.common !== undefined) { - if (txData.common.customChain === undefined) - // TODO - Replace error - throw new Error('If tx.common is provided it must have tx.common.customChain'); - if (txData.common.customChain.chainId === undefined) - // TODO - Replace error - throw new Error( - 'If tx.common is provided it must have tx.common.customChain and tx.common.customChain.chainId', - ); - if ( - txData.chainId !== undefined && - txData.chainId !== txData.common.customChain.chainId - ) - // TODO - Replace error - throw new Error( - 'Chain Id doesnt match in tx.chainId tx.common.customChain.chainId', - ); - } - } - - private static _formatTxData(txData: TxData) { - // TODO Fix TSC error - // @ts-ignore - Types of property 'gasPrice' are incompatible. Type 'string | undefined' is not assignable to type 'undefined' - const txDataHexString: - | BaseTxData - | AccessListEIP2930TxData - | FeeMarketEIP1559TxData = convertObjectPropertiesToValidType( - txData, - // TODO Fix TSC error - // @ts-ignore - TSC doesn't understand txDataConvertibleProperties contains keys of all possible tx types - txDataConvertibleProperties, - ValidTypes.HexString, - ); - if (txDataHexString.common !== undefined) { - txDataHexString.common.customChain = convertObjectPropertiesToValidType( - txDataHexString.common.customChain, - ['networkId', 'chainId'], - ValidTypes.HexString, - ); - } - // TODO - Formatting toLowerCase, toChecksumAddress, etc. - return txDataHexString; - } - - private static _detectTxType( - txData: - | BaseTxData - | AccessListEIP2930TxData - | FeeMarketEIP1559TxData, - ) { - const hasEip1559 = - (txData as FeeMarketEIP1559TxData).maxFeePerGas !== undefined || - (txData as FeeMarketEIP1559TxData).maxPriorityFeePerGas !== undefined; - if (txData.gasPrice !== undefined && (txData.type === '0x2' || hasEip1559)) - // TODO - Replace error - throw new Error("eip-1559 transactions don't support gasPrice"); - if ((txData.type === '0x0' || txData.type === '0x1') && hasEip1559) + throw new Error('If tx.common is provided it must have tx.common.customChain'); + if (transaction.common.customChain.chainId === undefined) // TODO - Replace error throw new Error( - "pre-eip-1559 transaction don't support maxFeePerGas/maxPriorityFeePerGas", + 'If tx.common is provided it must have tx.common.customChain and tx.common.customChain.chainId', ); - - if (txData.type !== undefined) return txData.type; - - if (hasEip1559) return '0x2'; - if (txData.hardfork === 'berlin') return '0x2'; - if (txData.common?.hardfork === 'berlin') return '0x2'; - - if ((txData as AccessListEIP2930TxData).accessList !== undefined) return '0x1'; - - return '0x0'; + if ( + transaction.chainId !== undefined && + transaction.chainId !== transaction.common.customChain.chainId + ) + // TODO - Replace error + throw new Error('Chain Id doesnt match in tx.chainId tx.common.customChain.chainId'); } +}; + +const validateChainInfo = (transaction: Transaction) => { + if ( + transaction.common !== undefined && + transaction.chain !== undefined && + transaction.hardfork !== undefined + ) + // TODO - Replace error + throw new Error( + 'Please provide the @ethereumjs/common object or the chain and hardfork property but not all together.', + ); + if ( + (transaction.chain !== undefined && transaction.hardfork === undefined) || + (transaction.hardfork !== undefined && transaction.chain === undefined) + ) + // TODO - Replace error + throw new Error( + `When specifying chain and hardfork, both values must be defined. Received "chain": ${transaction.chain}, "hardfork": ${transaction.hardfork}`, + ); +} - private static async _defaultTxDataAndSeparateTxOptions( - txData: - | BaseTxData - | AccessListEIP2930TxData - | FeeMarketEIP1559TxData, - txType: HexString, - web3Context: Web3Context, - ) { - const defaultedTxData = { - ...txData, - ...await Web3EthTx._handleTxPricing(txData, txType, web3Context), - data: txData.data ?? '0x', - value: txData.value ?? '0x', - gasLimit: txData.gasLimit ?? txData.gas, // TODO txData.gas is optional, need a default if both gasLimit and gas aren't provided - }; - if (txType >= '0x1' && (txData as AccessListEIP2930TxData).accessList === undefined) - (defaultedTxData as AccessListEIP2930TxData).accessList = []; +const validateGas = (transaction: Transaction) => { + if ( + transaction.gas === undefined && + transaction.gasLimit === undefined && + transaction.maxPriorityFeePerGas === undefined && + transaction.maxFeePerGas === undefined + ) + // TODO - Replace error + throw new Error('"gas" is missing'); + if (transaction.gas !== undefined && transaction.gasPrice !== undefined) { + // This check is verifying gas and gasPrice aren't less than 0. + // transaction's number properties have been converted to HexStrings. + // JavaScript doesn't handle negative hex strings e.g. -0x1, but our + // numberToHex method does. -0x1 < 0 would result in false, so we must check if + // hex string is negative via the inclusion of - + if ( + (transaction.gas as HexString).charAt(0) === '-' || + (transaction.gasPrice as HexString).charAt(0) === '-' + ) + // TODO - Replace error + throw new Error('Gas or gasPrice is lower than 0'); + } else { + if ( + (transaction.maxFeePerGas as HexString).charAt(0) === '-' || + (transaction.maxPriorityFeePerGas as HexString).charAt(0) === '-' + ) + // TODO - Replace error + throw new Error('maxPriorityFeePerGas or maxFeePerGas is lower than 0'); } - private static async _handleTxPricing( - txData: - | BaseTxData - | AccessListEIP2930TxData - | FeeMarketEIP1559TxData, - txType: HexString, - web3Context: Web3Context, - ) { - const web3Eth = new Web3Eth(web3Context.currentProvider); - if (txType === '0x2') { - const block = await web3Eth.getBlock(BlockTags.LATEST); - if (block?.baseFeePerGas === undefined) - // TODO - Replace error - throw new Error("Network doesn't support eip-1559"); - const maxPriorityFeePerGas = - // TODO - Replace hardcoded value with configurable one - (txData as FeeMarketEIP1559TxData).maxPriorityFeePerGas ?? '0x9502F900'; // 2.5 - return { - maxPriorityFeePerGas, - maxFeePerGas: - (txData as FeeMarketEIP1559TxData).maxFeePerGas ?? - toHex(BigInt(block.baseFeePerGas) * BigInt(2) + BigInt(maxPriorityFeePerGas)), - }; - } else if (txType === '0x1' || txType === '0x0') { - return { gasPrice: txData.gasPrice ?? await web3Eth.getGasPrice() }; - } else { - throw new Error('txType not specified'); - } - } + const hasEip1559 = + transaction.maxFeePerGas !== undefined || transaction.maxPriorityFeePerGas !== undefined; + if (transaction.gasPrice !== undefined && (transaction.type === '0x2' || hasEip1559)) + // TODO - Replace error + throw new Error("eip-1559 transactions don't support gasPrice"); + if ((transaction.type === '0x0' || transaction.type === '0x1') && hasEip1559) + // TODO - Replace error + throw new Error("pre-eip-1559 transaction don't support maxFeePerGas/maxPriorityFeePerGas"); } + +export const validateTransaction = ( + transaction: Transaction, + overrideMethod?: (transaction: Transaction) => void, +) => { + if (overrideMethod !== undefined) return overrideMethod(transaction); + + if (typeof transaction !== 'object' || transaction === null) + // TODO - Replace error + throw new Error('invalid transaction obejct'); + + const formattedTransaction = formatTransaction(transaction, ValidTypes.HexString); + + validateCustomChainInfo(transaction); + validateChainInfo(transaction); + validateGas(formattedTransaction); + + if ( + (formattedTransaction.nonce as HexString).charAt(0) === '-' || + (formattedTransaction.chainId as HexString).charAt(0) === '-' + ) + // TODO - Replace error + throw new Error('Nonce or chainId is lower than 0'); +}; From ff167eada88703e53a0b923d186d6edd7abe8910 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Thu, 13 Jan 2022 23:02:02 -1000 Subject: [PATCH 007/132] Export privateKeyToAddress --- packages/web3-eth-accounts/src/account.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web3-eth-accounts/src/account.ts b/packages/web3-eth-accounts/src/account.ts index a69a4002e6b..642267e5209 100644 --- a/packages/web3-eth-accounts/src/account.ts +++ b/packages/web3-eth-accounts/src/account.ts @@ -210,7 +210,7 @@ const uuidV4 = () => { ].join('-'); }; -const privateKeyToAddress = (privateKey: string | Buffer): string => { +export const privateKeyToAddress = (privateKey: string | Buffer): string => { if (!(isString(privateKey) || isBuffer(privateKey))) { throw new InvalidPrivateKeyError(); } From 907c7d082135b2deb3339e3372fce9afc566c4e0 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Thu, 13 Jan 2022 23:02:18 -1000 Subject: [PATCH 008/132] Add web3-eth-accounts dependency --- packages/web3-eth/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/web3-eth/package.json b/packages/web3-eth/package.json index 04fd4603d5a..01f849ba676 100644 --- a/packages/web3-eth/package.json +++ b/packages/web3-eth/package.json @@ -43,6 +43,7 @@ "web3-common": "1.0.0-alpha.0", "web3-core": "4.0.0-alpha.0", "web3-utils": "4.0.0-alpha.0", - "web3-validator": "^0.1.0-alpha.0" + "web3-validator": "^0.1.0-alpha.0", + "web3-eth-accounts": "4.0.0-alpha.0" } } From f87ffc6f0f025e494e047d01e5917a2de3bf6d9f Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Thu, 13 Jan 2022 23:02:32 -1000 Subject: [PATCH 009/132] WIP web3-eth-tx util methods --- packages/web3-eth/src/eth_tx.ts | 179 ++++++++++++++++++++++++++++---- 1 file changed, 157 insertions(+), 22 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 1bf42050187..5bc6477278f 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -2,15 +2,17 @@ import { AccessList, EthExecutionAPI } from 'web3-common'; import { Web3Context } from 'web3-core'; import { Address, + BlockTags, convertToValidType, HexString, HexStringBytes, Numbers, + toHex, ValidReturnTypes, ValidTypes, } from 'web3-utils'; - -import Web3Eth from './index'; +import { privateKeyToAddress } from 'web3-eth-accounts'; +import Web3Eth from '.'; export type chain = 'goerli' | 'kovan' | 'mainnet' | 'rinkeby' | 'ropsten' | 'sepolia'; export type hardfork = @@ -30,14 +32,14 @@ export type hardfork = | 'spuriousDragon' | 'tangerineWhistle'; -export interface CustomChain { +export interface CustomChain { name?: string; - networkId: Numbers; - chainId: Numbers; + networkId: NumberType; + chainId: NumberType; } -export interface Common { - customChain: CustomChain; +export interface Common { + customChain: CustomChain; baseChain?: chain; hardfork?: hardfork; } @@ -57,14 +59,17 @@ export interface Transaction { chain?: chain; hardfork?: hardfork; chainId?: NumberType; - common?: Common; + common?: Common; gasLimit?: NumberType; v?: NumberType; r?: NumberType; s?: NumberType; } -export function formatTransaction( +export function formatTransaction< + DesiredType extends ValidTypes, + ReturnType = ValidReturnTypes[DesiredType], +>( transaction: Transaction, desiredType: DesiredType, overrideMethod?: (transaction: Transaction) => Transaction, @@ -94,10 +99,12 @@ export function formatTransaction) -}; + // TODO - TSC is complaining that ReturnType could be instantiated with an + // arbitrary type which could be unrelated to 'string | number | bigint | undefined' + return formattedTransaction as unknown as Transaction; +} export const detectTransactionType = ( transaction: Transaction, @@ -153,7 +160,7 @@ const validateChainInfo = (transaction: Transaction) => { throw new Error( `When specifying chain and hardfork, both values must be defined. Received "chain": ${transaction.chain}, "hardfork": ${transaction.hardfork}`, ); -} +}; const validateGas = (transaction: Transaction) => { if ( @@ -170,16 +177,15 @@ const validateGas = (transaction: Transaction) => { // JavaScript doesn't handle negative hex strings e.g. -0x1, but our // numberToHex method does. -0x1 < 0 would result in false, so we must check if // hex string is negative via the inclusion of - - if ( - (transaction.gas as HexString).charAt(0) === '-' || - (transaction.gasPrice as HexString).charAt(0) === '-' - ) + if (transaction.gas.charAt(0) === '-' || transaction.gasPrice.charAt(0) === '-') // TODO - Replace error throw new Error('Gas or gasPrice is lower than 0'); - } else { + } + + if (transaction.maxFeePerGas !== undefined && transaction.maxPriorityFeePerGas !== undefined) { if ( - (transaction.maxFeePerGas as HexString).charAt(0) === '-' || - (transaction.maxPriorityFeePerGas as HexString).charAt(0) === '-' + transaction.maxFeePerGas.charAt(0) === '-' || + transaction.maxPriorityFeePerGas.charAt(0) === '-' ) // TODO - Replace error throw new Error('maxPriorityFeePerGas or maxFeePerGas is lower than 0'); @@ -193,9 +199,9 @@ const validateGas = (transaction: Transaction) => { if ((transaction.type === '0x0' || transaction.type === '0x1') && hasEip1559) // TODO - Replace error throw new Error("pre-eip-1559 transaction don't support maxFeePerGas/maxPriorityFeePerGas"); -} +}; -export const validateTransaction = ( +export const validateTransactionForSigning = ( transaction: Transaction, overrideMethod?: (transaction: Transaction) => void, ) => { @@ -218,3 +224,132 @@ export const validateTransaction = ( // TODO - Replace error throw new Error('Nonce or chainId is lower than 0'); }; + +export interface PopulatedUnsignedBaseTransaction { + from: Address; + to?: Address; + value: Numbers; + gas?: Numbers; + gasPrice: Numbers; + type: Numbers; + data: HexStringBytes; + nonce: Numbers; + chain: chain; + hardfork: hardfork; + chainId: Numbers; + common: Common; + gasLimit: Numbers; +} +export interface PopulatedUnsignedEip2930Transaction extends PopulatedUnsignedBaseTransaction { + accessList: AccessList; +} +export interface PopulatedUnsignedEip1559Transaction extends PopulatedUnsignedEip2930Transaction { + gasPrice: never; + maxFeePerGas: NumberType; + maxPriorityFeePerGas: NumberType; +} +export type PopulatedUnsignedTransaction = + | PopulatedUnsignedBaseTransaction + | PopulatedUnsignedEip2930Transaction + | PopulatedUnsignedEip1559Transaction; +export async function populateTransaction< + DesiredType extends ValidTypes, + ReturnType = ValidReturnTypes[DesiredType], +> ( + transaction: Transaction, + web3Context: Web3Context, + desiredType: DesiredType, + privateKey?: HexString, + overrideMethod?: ( + transaction: Transaction, + web3Context: Web3Context, + ) => PopulatedUnsignedTransaction, +): Promise> { + if (overrideMethod !== undefined) return overrideMethod(transaction, web3Context); + + const populatedTransaction = { ...transaction }; + const web3Eth = new Web3Eth(web3Context.currentProvider); + + if (populatedTransaction.from === undefined) { + if (privateKey !== undefined) { + populatedTransaction.from = privateKeyToAddress(privateKey); + } else if (web3Context.defaultAccount !== null) + populatedTransaction.from = web3Context.defaultAccount; + // TODO Try to fill from using web3.eth.accounts.wallet + } + + if (populatedTransaction.nonce === undefined) { + // TODO - Replace error + if (populatedTransaction.from === undefined) + throw new Error('unable to populate nonce, no from address available'); + populatedTransaction.nonce = await web3Eth.getTransactionCount( + populatedTransaction.from, + BlockTags.PENDING, + ); + } + + if (populatedTransaction.value === undefined) populatedTransaction.value = '0x'; + if (populatedTransaction.data === undefined) populatedTransaction.data = '0x'; + // TODO - Add default to Web3Context + if (populatedTransaction.chain === undefined) populatedTransaction.chain = 'mainnet'; + // TODO - Add default to Web3Context + // TODO - Update default to berlin? (It's london in 1.x) + if (populatedTransaction.hardfork === undefined) populatedTransaction.hardfork = 'london'; + + if (populatedTransaction.chainId === undefined) { + if (populatedTransaction.common?.customChain.chainId === undefined) { + // TODO - web3Eth.getChainId not implemented + // populatedTransaction.chainId = await web3Eth.getChainId(); + } + } + + if (populatedTransaction.gas === undefined) { + if (populatedTransaction.gasLimit !== undefined) + populatedTransaction.gas = populatedTransaction.gasLimit; + } + + if (populatedTransaction.gasLimit === undefined) { + if (populatedTransaction.gas !== undefined) + populatedTransaction.gasLimit = populatedTransaction.gas; + } + + // If populatedTransaction.type is already defined, no change will be made + populatedTransaction.type = detectTransactionType(populatedTransaction); + // TODO - After web3Context.defaultTxType is implemented + // if (populatedTransaction.type === undefined) populatedTransaction.type = web3Context.defaultTxType; + + if (populatedTransaction.type !== undefined) { + const hexTxType = toHex(populatedTransaction.type); + if (hexTxType === '0x0' || hexTxType === '0x1') { + if (populatedTransaction.gasPrice === undefined) + populatedTransaction.gasPrice = await web3Eth.getGasPrice(); + } else if (hexTxType === '0x1' || hexTxType === '0x2') { + if (populatedTransaction.accessList === undefined) populatedTransaction.accessList = []; + } else if (hexTxType === '0x2') { + // Unless otherwise specified by web3Context.defaultBlock, this defaults to latest + const block = await web3Eth.getBlock(); + if (block.baseFeePerGas === undefined) + // TODO - Replace error + throw new Error("Network doesn't support eip-1559"); + + if (populatedTransaction.gasPrice !== undefined) { + // Carry over logic from 1.x + populatedTransaction.maxPriorityFeePerGas = populatedTransaction.gasPrice; + populatedTransaction.maxFeePerGas = populatedTransaction.gasPrice; + populatedTransaction.gasPrice = undefined; + } else { + if (populatedTransaction.maxPriorityFeePerGas === undefined) + populatedTransaction.maxPriorityFeePerGas = toHex('2500000000'); // 2.5 Gwei + if (populatedTransaction.maxFeePerGas === undefined) + populatedTransaction.maxFeePerGas = + BigInt(block.baseFeePerGas) * BigInt(2) + + BigInt(populatedTransaction.maxPriorityFeePerGas); + } + } else { + // TODO - Replace error + throw new Error('unsupported transaction type'); + } + } + + return formatTransaction(populatedTransaction, desiredType) as PopulatedUnsignedTransaction +}; From 307201f074251474c4fc70e48561ecc296051183 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 17 Jan 2022 01:40:24 -1000 Subject: [PATCH 010/132] Replace inline errors with error constructors --- packages/web3-eth/src/errors.ts | 121 +++++++++++++++++++-- packages/web3-eth/src/eth_tx.ts | 180 ++++++++++++++++++-------------- 2 files changed, 217 insertions(+), 84 deletions(-) diff --git a/packages/web3-eth/src/errors.ts b/packages/web3-eth/src/errors.ts index 4c957434865..c2a97e9f536 100644 --- a/packages/web3-eth/src/errors.ts +++ b/packages/web3-eth/src/errors.ts @@ -3,19 +3,124 @@ import { Web3Error } from 'web3-utils'; export class InvalidTransactionWithSender extends Web3Error { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - public constructor(value: any) { - // TODO Discuss this naive approach to logging object - // Does not account for non JSON properties + public constructor(value: unknown) { super(JSON.stringify(value), 'invalid transaction with sender'); } } export class InvalidTransactionCall extends Web3Error { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - public constructor(value: any) { - // TODO Discuss this naive approach to logging object - // Does not account for non JSON properties + public constructor(value: unknown) { super(JSON.stringify(value), 'invalid transaction call'); } } + +export class MissingCustomChainError extends Web3Error { + public constructor(value: undefined) { + super(value, 'If tx.common is provided it must have tx.common.customChain'); + } +} + +export class MissingCustomChainIdError extends Web3Error { + public constructor(value: undefined) { + super( + value, + 'If tx.common is provided it must have tx.common.customChain and tx.common.customChain.chainId', + ); + } +} + +export class ChainIdMismatchError extends Web3Error { + public constructor(value: { txChainId: unknown; customChainId: unknown }) { + super( + JSON.stringify(value), + 'Chain Id doesnt match in tx.chainId tx.common.customChain.chainId', + ); + } +} + +export class CommonOrChainAndHardforkError extends Web3Error { + public constructor() { + // TODO - Discuss what to pass as value, would it make sense to pass common, chain, and hardfork for error message here? + super( + 'N/A', + 'Please provide the @ethereumjs/common object or the chain and hardfork property but not all together.', + ); + } +} + +export class MissingChainOrHardforkError extends Web3Error { + public constructor(value: { chain: string | undefined; hardfork: string | undefined }) { + // TODO - Discuss what to pass as value + super( + 'N/A', + `When specifying chain and hardfork, both values must be defined. Received "chain": ${ + value.chain ?? 'undefined' + }, "hardfork": ${value.hardfork ?? 'undefined'}`, + ); + } +} + +export class MissingGasError extends Web3Error { + public constructor(value: unknown) { + super(value, '"gas" is missing'); + } +} + +export class InvalidGasOrGasPrice extends Web3Error { + public constructor(value: { gas: unknown; gasPrice: unknown }) { + super(JSON.stringify(value), 'Gas or gasPrice is lower than 0'); + } +} + +export class InvalidMaxPriorityFeePerGasOrMaxFeePerGas extends Web3Error { + public constructor(value: { maxPriorityFeePerGas: unknown; maxFeePerGas: unknown }) { + super(JSON.stringify(value), 'maxPriorityFeePerGas or maxFeePerGas is lower than 0'); + } +} + +export class Eip1559GasPriceError extends Web3Error { + public constructor(value: unknown) { + super(value, "eip-1559 transactions don't support gasPrice"); + } +} + +export class UnsupportedFeeMarketError extends Web3Error { + public constructor(value: { maxPriorityFeePerGas: unknown; maxFeePerGas: unknown }) { + super( + JSON.stringify(value), + "pre-eip-1559 transaction don't support maxFeePerGas/maxPriorityFeePerGas", + ); + } +} + +export class InvalidTransactionObjectError extends Web3Error { + public constructor(value: unknown) { + super(value, 'invalid transaction obejct'); + } +} + +export class InvalidNonceOrChainIdError extends Web3Error { + public constructor(value: { nonce: unknown; chainId: unknown }) { + super(JSON.stringify(value), 'Nonce or chainId is lower than 0'); + } +} + +export class UnableToPopulateNonceError extends Web3Error { + public constructor() { + // TODO - Discuss what to pass as value + super('N/A', 'unable to populate nonce, no from address available'); + } +} + +export class Eip1559NotSupportedError extends Web3Error { + public constructor() { + // TODO - Discuss what to pass as value + super('N/A', "Network doesn't support eip-1559"); + } +} + +export class UnsupportedTransactionTypeError extends Web3Error { + public constructor(value: unknown) { + super(value, 'unsupported transaction type'); + } +} diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 5bc6477278f..ba67685076d 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -13,6 +13,23 @@ import { } from 'web3-utils'; import { privateKeyToAddress } from 'web3-eth-accounts'; import Web3Eth from '.'; +import { + ChainIdMismatchError, + CommonOrChainAndHardforkError, + Eip1559GasPriceError, + Eip1559NotSupportedError, + InvalidGasOrGasPrice, + InvalidMaxPriorityFeePerGasOrMaxFeePerGas, + InvalidNonceOrChainIdError, + InvalidTransactionObjectError, + MissingChainOrHardforkError, + MissingCustomChainError, + MissingCustomChainIdError, + MissingGasError, + UnableToPopulateNonceError, + UnsupportedFeeMarketError, + UnsupportedTransactionTypeError, +} from './errors'; export type chain = 'goerli' | 'kovan' | 'mainnet' | 'rinkeby' | 'ropsten' | 'sepolia'; export type hardfork = @@ -99,7 +116,7 @@ export function formatTransaction< ), chainId: convertToValidType(transaction.common?.customChain.chainId, desiredType), }, - }, + }, }; // TODO - TSC is complaining that ReturnType could be instantiated with an // arbitrary type which could be unrelated to 'string | number | bigint | undefined' @@ -126,19 +143,17 @@ export const detectTransactionType = ( const validateCustomChainInfo = (transaction: Transaction) => { if (transaction.common !== undefined) { if (transaction.common.customChain === undefined) - // TODO - Replace error - throw new Error('If tx.common is provided it must have tx.common.customChain'); + throw new MissingCustomChainError(transaction.common.customChain); if (transaction.common.customChain.chainId === undefined) - // TODO - Replace error - throw new Error( - 'If tx.common is provided it must have tx.common.customChain and tx.common.customChain.chainId', - ); + throw new MissingCustomChainIdError(transaction.common.customChain.chainId); if ( transaction.chainId !== undefined && transaction.chainId !== transaction.common.customChain.chainId ) - // TODO - Replace error - throw new Error('Chain Id doesnt match in tx.chainId tx.common.customChain.chainId'); + throw new ChainIdMismatchError({ + txChainId: transaction.chainId, + customChainId: transaction.common.customChain.chainId, + }); } }; @@ -148,18 +163,15 @@ const validateChainInfo = (transaction: Transaction) => { transaction.chain !== undefined && transaction.hardfork !== undefined ) - // TODO - Replace error - throw new Error( - 'Please provide the @ethereumjs/common object or the chain and hardfork property but not all together.', - ); + throw new CommonOrChainAndHardforkError(); if ( (transaction.chain !== undefined && transaction.hardfork === undefined) || (transaction.hardfork !== undefined && transaction.chain === undefined) ) - // TODO - Replace error - throw new Error( - `When specifying chain and hardfork, both values must be defined. Received "chain": ${transaction.chain}, "hardfork": ${transaction.hardfork}`, - ); + throw new MissingChainOrHardforkError({ + chain: transaction.chain, + hardfork: transaction.hardfork, + }); }; const validateGas = (transaction: Transaction) => { @@ -169,47 +181,50 @@ const validateGas = (transaction: Transaction) => { transaction.maxPriorityFeePerGas === undefined && transaction.maxFeePerGas === undefined ) - // TODO - Replace error - throw new Error('"gas" is missing'); + throw new MissingGasError(transaction.gas); if (transaction.gas !== undefined && transaction.gasPrice !== undefined) { // This check is verifying gas and gasPrice aren't less than 0. // transaction's number properties have been converted to HexStrings. // JavaScript doesn't handle negative hex strings e.g. -0x1, but our // numberToHex method does. -0x1 < 0 would result in false, so we must check if // hex string is negative via the inclusion of - - if (transaction.gas.charAt(0) === '-' || transaction.gasPrice.charAt(0) === '-') - // TODO - Replace error - throw new Error('Gas or gasPrice is lower than 0'); + if (transaction.gas.startsWith('-') || transaction.gasPrice.startsWith('-')) + throw new InvalidGasOrGasPrice({ + gas: transaction.gas, + gasPrice: transaction.gasPrice, + }); } if (transaction.maxFeePerGas !== undefined && transaction.maxPriorityFeePerGas !== undefined) { if ( - transaction.maxFeePerGas.charAt(0) === '-' || - transaction.maxPriorityFeePerGas.charAt(0) === '-' + transaction.maxFeePerGas.startsWith('-') || + transaction.maxPriorityFeePerGas.startsWith('-') ) - // TODO - Replace error - throw new Error('maxPriorityFeePerGas or maxFeePerGas is lower than 0'); + throw new InvalidMaxPriorityFeePerGasOrMaxFeePerGas({ + maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, + maxFeePerGas: transaction.maxFeePerGas, + }); } const hasEip1559 = transaction.maxFeePerGas !== undefined || transaction.maxPriorityFeePerGas !== undefined; if (transaction.gasPrice !== undefined && (transaction.type === '0x2' || hasEip1559)) - // TODO - Replace error - throw new Error("eip-1559 transactions don't support gasPrice"); + throw new Eip1559GasPriceError(transaction.gasPrice); if ((transaction.type === '0x0' || transaction.type === '0x1') && hasEip1559) - // TODO - Replace error - throw new Error("pre-eip-1559 transaction don't support maxFeePerGas/maxPriorityFeePerGas"); + throw new UnsupportedFeeMarketError({ + maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, + maxFeePerGas: transaction.maxFeePerGas, + }); }; export const validateTransactionForSigning = ( transaction: Transaction, overrideMethod?: (transaction: Transaction) => void, ) => { - if (overrideMethod !== undefined) return overrideMethod(transaction); + if (overrideMethod !== undefined) overrideMethod(transaction); if (typeof transaction !== 'object' || transaction === null) - // TODO - Replace error - throw new Error('invalid transaction obejct'); + throw new InvalidTransactionObjectError(transaction); const formattedTransaction = formatTransaction(transaction, ValidTypes.HexString); @@ -218,11 +233,13 @@ export const validateTransactionForSigning = ( validateGas(formattedTransaction); if ( - (formattedTransaction.nonce as HexString).charAt(0) === '-' || - (formattedTransaction.chainId as HexString).charAt(0) === '-' + (formattedTransaction.nonce as HexString).startsWith('-') || + (formattedTransaction.chainId as HexString).startsWith('-') ) - // TODO - Replace error - throw new Error('Nonce or chainId is lower than 0'); + throw new InvalidNonceOrChainIdError({ + nonce: transaction.nonce, + chainId: transaction.chainId, + }); }; export interface PopulatedUnsignedBaseTransaction { @@ -240,10 +257,12 @@ export interface PopulatedUnsignedBaseTransaction { common: Common; gasLimit: Numbers; } -export interface PopulatedUnsignedEip2930Transaction extends PopulatedUnsignedBaseTransaction { +export interface PopulatedUnsignedEip2930Transaction + extends PopulatedUnsignedBaseTransaction { accessList: AccessList; } -export interface PopulatedUnsignedEip1559Transaction extends PopulatedUnsignedEip2930Transaction { +export interface PopulatedUnsignedEip1559Transaction + extends PopulatedUnsignedEip2930Transaction { gasPrice: never; maxFeePerGas: NumberType; maxPriorityFeePerGas: NumberType; @@ -255,7 +274,7 @@ export type PopulatedUnsignedTransaction = export async function populateTransaction< DesiredType extends ValidTypes, ReturnType = ValidReturnTypes[DesiredType], -> ( +>( transaction: Transaction, web3Context: Web3Context, desiredType: DesiredType, @@ -279,9 +298,7 @@ export async function populateTransaction< } if (populatedTransaction.nonce === undefined) { - // TODO - Replace error - if (populatedTransaction.from === undefined) - throw new Error('unable to populate nonce, no from address available'); + if (populatedTransaction.from === undefined) throw new UnableToPopulateNonceError(); populatedTransaction.nonce = await web3Eth.getTransactionCount( populatedTransaction.from, BlockTags.PENDING, @@ -316,40 +333,51 @@ export async function populateTransaction< // If populatedTransaction.type is already defined, no change will be made populatedTransaction.type = detectTransactionType(populatedTransaction); // TODO - After web3Context.defaultTxType is implemented - // if (populatedTransaction.type === undefined) populatedTransaction.type = web3Context.defaultTxType; - - if (populatedTransaction.type !== undefined) { - const hexTxType = toHex(populatedTransaction.type); - if (hexTxType === '0x0' || hexTxType === '0x1') { - if (populatedTransaction.gasPrice === undefined) - populatedTransaction.gasPrice = await web3Eth.getGasPrice(); - } else if (hexTxType === '0x1' || hexTxType === '0x2') { - if (populatedTransaction.accessList === undefined) populatedTransaction.accessList = []; - } else if (hexTxType === '0x2') { - // Unless otherwise specified by web3Context.defaultBlock, this defaults to latest - const block = await web3Eth.getBlock(); - if (block.baseFeePerGas === undefined) - // TODO - Replace error - throw new Error("Network doesn't support eip-1559"); - - if (populatedTransaction.gasPrice !== undefined) { - // Carry over logic from 1.x - populatedTransaction.maxPriorityFeePerGas = populatedTransaction.gasPrice; - populatedTransaction.maxFeePerGas = populatedTransaction.gasPrice; - populatedTransaction.gasPrice = undefined; - } else { - if (populatedTransaction.maxPriorityFeePerGas === undefined) - populatedTransaction.maxPriorityFeePerGas = toHex('2500000000'); // 2.5 Gwei - if (populatedTransaction.maxFeePerGas === undefined) - populatedTransaction.maxFeePerGas = - BigInt(block.baseFeePerGas) * BigInt(2) + - BigInt(populatedTransaction.maxPriorityFeePerGas); - } + if (populatedTransaction.type === undefined) populatedTransaction.type = '0x0'; // web3Context.defaultTxType; + + const block = await web3Eth.getBlock(); + const hexTxType = toHex(populatedTransaction.type); + + if (hexTxType < '0x0' || hexTxType > '0x2') + throw new UnsupportedTransactionTypeError(populatedTransaction.type); + + if (hexTxType === '0x0' || hexTxType === '0x1') { + // transaction.type not supported before Berlin hardfork + // TODO - Maybe add check for populatedTransaction.hardfork >= Berlin before deleting + if (hexTxType === '0x0') populatedTransaction.type = undefined; + + if (populatedTransaction.gasPrice === undefined) + populatedTransaction.gasPrice = await web3Eth.getGasPrice(); + } + + if (hexTxType === '0x1' || hexTxType === '0x2') { + if (populatedTransaction.accessList === undefined) populatedTransaction.accessList = []; + } + + if (hexTxType === '0x2') { + // Unless otherwise specified by web3Context.defaultBlock, this defaults to latest + if (block.baseFeePerGas === undefined) throw new Eip1559NotSupportedError(); + + if (populatedTransaction.gasPrice !== undefined) { + // Logic from 1.x + populatedTransaction.maxPriorityFeePerGas = populatedTransaction.gasPrice; + populatedTransaction.maxFeePerGas = populatedTransaction.gasPrice; + populatedTransaction.gasPrice = undefined; } else { - // TODO - Replace error - throw new Error('unsupported transaction type'); + if (populatedTransaction.maxPriorityFeePerGas === undefined) + // TODO - Add maxPriorityFeePerGas default to Web3Context + populatedTransaction.maxPriorityFeePerGas = toHex('2500000000'); // 2.5 Gwei + if (populatedTransaction.maxFeePerGas === undefined) + populatedTransaction.maxFeePerGas = + BigInt(block.baseFeePerGas) * BigInt(2) + + BigInt(populatedTransaction.maxPriorityFeePerGas); } } - return formatTransaction(populatedTransaction, desiredType) as PopulatedUnsignedTransaction -}; + return formatTransaction( + populatedTransaction, + desiredType, + ) as PopulatedUnsignedTransaction; +} + +// TODO - Replace use of Web3Context with Web3Eth From c5537655056222fbed7c35d822f321946a6def0c Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 17 Jan 2022 05:33:24 -1000 Subject: [PATCH 011/132] Change types for transaction r and s properties. Correct hardforks in detectTransactionType --- packages/web3-eth/src/eth_tx.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index ba67685076d..436788a7b91 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -79,8 +79,8 @@ export interface Transaction { common?: Common; gasLimit?: NumberType; v?: NumberType; - r?: NumberType; - s?: NumberType; + r?: HexString; + s?: HexString; } export function formatTransaction< @@ -104,8 +104,6 @@ export function formatTransaction< chainId: convertToValidType(transaction.chainId, desiredType), gasLimit: convertToValidType(transaction.gasLimit, desiredType), v: convertToValidType(transaction.v, desiredType), - r: convertToValidType(transaction.r, desiredType), - s: convertToValidType(transaction.s, desiredType), common: { ...transaction.common, customChain: { @@ -132,10 +130,12 @@ export const detectTransactionType = ( if (transaction.maxFeePerGas !== undefined || transaction.maxPriorityFeePerGas !== undefined) return '0x2'; - if (transaction.hardfork === 'berlin') return '0x2'; - if (transaction.common?.hardfork === 'berlin') return '0x2'; + if (transaction.hardfork === 'london') return '0x2'; + if (transaction.common?.hardfork === 'london') return '0x2'; if (transaction.accessList !== undefined) return '0x1'; + if (transaction.hardfork === 'berlin') return '0x1'; + if (transaction.common?.hardfork === 'berlin') return '0x1'; return undefined; }; From 73c46d65bdf4aa829b59199146bbd75a63e80b1d Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 17 Jan 2022 05:33:44 -1000 Subject: [PATCH 012/132] Init formatTransaction tests and fixture --- .../test/fixtures/format_transaction.ts | 118 ++++++++++++++++++ .../test/unit/format_transaction.test.ts | 76 +++++++++++ 2 files changed, 194 insertions(+) create mode 100644 packages/web3-eth/test/fixtures/format_transaction.ts create mode 100644 packages/web3-eth/test/unit/format_transaction.test.ts diff --git a/packages/web3-eth/test/fixtures/format_transaction.ts b/packages/web3-eth/test/fixtures/format_transaction.ts new file mode 100644 index 00000000000..1ac16ad57c0 --- /dev/null +++ b/packages/web3-eth/test/fixtures/format_transaction.ts @@ -0,0 +1,118 @@ +import { ValidReturnTypes, ValidTypes } from 'web3-utils'; +import { Transaction } from '../../src/eth_tx'; + +export const hexStringTransaction: Transaction = { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + type: '0x0', + maxFeePerGas: '0x1229298c00', + maxPriorityFeePerGas: '0x49504f80', + data: '0x0', + nonce: '0x4', + chain: 'mainnet', + hardfork: 'berlin', + chainId: '0x1', + common: { + customChain: { + name: 'foo', + networkId: '0x4', + chainId: '0x42', + }, + baseChain: 'mainnet', + hardfork: 'berlin', + }, + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', +}; + +export const numberTransaction: Transaction = { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: 100000000000, + gas: 21000, + gasPrice: 20000000000, + type: 0, + maxFeePerGas: 78000000000, + maxPriorityFeePerGas: 1230000000, + data: '0x0', + nonce: 4, + chain: 'mainnet', + hardfork: 'berlin', + chainId: 1, + common: { + customChain: { + name: 'foo', + networkId: 4, + chainId: 66, + }, + baseChain: 'mainnet', + hardfork: 'berlin', + }, + gasLimit: 21000, + v: 37, + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', +}; + +export const numberStringTransaction: Transaction = { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '100000000000', + gas: '21000', + gasPrice: '20000000000', + type: '0', + maxFeePerGas: '78000000000', + maxPriorityFeePerGas: '1230000000', + data: '0x0', + nonce: '4', + chain: 'mainnet', + hardfork: 'berlin', + chainId: '1', + common: { + customChain: { + name: 'foo', + networkId: '4', + chainId: '66', + }, + baseChain: 'mainnet', + hardfork: 'berlin', + }, + gasLimit: '21000', + v: '37', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', +}; + +export const bigIntTransaction: Transaction = { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: BigInt(100000000000), + gas: BigInt(21000), + gasPrice: BigInt(20000000000), + type: BigInt(0), + maxFeePerGas: BigInt(78000000000), + maxPriorityFeePerGas: BigInt(1230000000), + data: '0x0', + nonce: BigInt(4), + chain: 'mainnet', + hardfork: 'berlin', + chainId: BigInt(1), + common: { + customChain: { + name: 'foo', + networkId: BigInt(4), + chainId: BigInt(66), + }, + baseChain: 'mainnet', + hardfork: 'berlin', + }, + gasLimit: BigInt(21000), + v: BigInt(37), + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', +}; diff --git a/packages/web3-eth/test/unit/format_transaction.test.ts b/packages/web3-eth/test/unit/format_transaction.test.ts new file mode 100644 index 00000000000..10d5b0c8dd5 --- /dev/null +++ b/packages/web3-eth/test/unit/format_transaction.test.ts @@ -0,0 +1,76 @@ +import { ValidTypes } from 'web3-utils'; +import { formatTransaction } from '../../src/eth_tx'; +import { + bigIntTransaction, + hexStringTransaction, + numberStringTransaction, + numberTransaction, +} from '../fixtures/format_transaction'; + +describe('should convert hex string properties to expected type', () => { + it('numbers', () => { + const result = formatTransaction(hexStringTransaction, ValidTypes.Number); + expect(result).toStrictEqual(numberTransaction); + }); + + it('number strings', () => { + const result = formatTransaction(hexStringTransaction, ValidTypes.NumberString); + expect(result).toStrictEqual(numberStringTransaction); + }); + + it('BigInts', () => { + const result = formatTransaction(hexStringTransaction, ValidTypes.BigInt); + expect(result).toStrictEqual(bigIntTransaction); + }); +}); + +describe('should convert number properties to expected type', () => { + it('hex string', () => { + const result = formatTransaction(numberTransaction, ValidTypes.HexString); + expect(result).toStrictEqual(hexStringTransaction); + }); + + it('number strings', () => { + const result = formatTransaction(numberTransaction, ValidTypes.NumberString); + expect(result).toStrictEqual(numberStringTransaction); + }); + + it('BigInts', () => { + const result = formatTransaction(numberTransaction, ValidTypes.BigInt); + expect(result).toStrictEqual(bigIntTransaction); + }); +}); + +describe('should convert number string properties to expected type', () => { + it('hex strings', () => { + const result = formatTransaction(numberStringTransaction, ValidTypes.HexString); + expect(result).toStrictEqual(hexStringTransaction); + }); + + it('numbers', () => { + const result = formatTransaction(numberStringTransaction, ValidTypes.Number); + expect(result).toStrictEqual(numberTransaction); + }); + + it('BigInts', () => { + const result = formatTransaction(numberStringTransaction, ValidTypes.BigInt); + expect(result).toStrictEqual(bigIntTransaction); + }); +}); + +describe('should convert bigint properties to expected type', () => { + it('hex strings', () => { + const result = formatTransaction(bigIntTransaction, ValidTypes.HexString); + expect(result).toStrictEqual(hexStringTransaction); + }); + + it('numbers', () => { + const result = formatTransaction(bigIntTransaction, ValidTypes.Number); + expect(result).toStrictEqual(numberTransaction); + }); + + it('number strings', () => { + const result = formatTransaction(bigIntTransaction, ValidTypes.NumberString); + expect(result).toStrictEqual(numberStringTransaction); + }); +}); From dfdf768817a8a8631ba1c111df63aab14497cd76 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 17 Jan 2022 05:34:24 -1000 Subject: [PATCH 013/132] Init detectTransactionType and fixture --- .../test/fixtures/detect_transaction_type.ts | 154 ++++++++++++++++++ .../test/unit/detect_transction_type.test.ts | 41 +++++ 2 files changed, 195 insertions(+) create mode 100644 packages/web3-eth/test/fixtures/detect_transaction_type.ts create mode 100644 packages/web3-eth/test/unit/detect_transction_type.test.ts diff --git a/packages/web3-eth/test/fixtures/detect_transaction_type.ts b/packages/web3-eth/test/fixtures/detect_transaction_type.ts new file mode 100644 index 00000000000..3ac2876a34c --- /dev/null +++ b/packages/web3-eth/test/fixtures/detect_transaction_type.ts @@ -0,0 +1,154 @@ +import { ValidReturnTypes, ValidTypes } from 'web3-utils'; +import { Transaction } from '../../src/eth_tx'; + +export const transactionType0x0: Transaction[] = [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + type: '0x0', + data: '0x0', + nonce: '0x4', + chainId: '0x1', + gasLimit: '0x5208', + }, +]; + +export const transactionType0x1: Transaction[] = [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + type: '0x1', + data: '0x0', + nonce: '0x4', + chainId: '0x1', + gasLimit: '0x5208', + }, + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + data: '0x0', + nonce: '0x4', + chainId: '0x1', + gasLimit: '0x5208', + accessList: [], + }, + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + data: '0x0', + nonce: '0x4', + chainId: '0x1', + gasLimit: '0x5208', + hardfork: 'berlin', + }, + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + data: '0x0', + nonce: '0x4', + chainId: '0x1', + gasLimit: '0x5208', + common: { + customChain: { + networkId: '0x42', + chainId: '0x42', + }, + hardfork: 'berlin', + }, + }, +]; + +export const transactionType0x2: Transaction[] = [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + type: '0x2', + data: '0x0', + nonce: '0x4', + chainId: '0x1', + gasLimit: '0x5208', + }, + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + maxFeePerGas: '0x1229298c00', + data: '0x0', + nonce: '0x4', + chainId: '0x1', + gasLimit: '0x5208', + }, + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + maxPriorityFeePerGas: '0x49504f80', + data: '0x0', + nonce: '0x4', + chainId: '0x1', + gasLimit: '0x5208', + }, + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + data: '0x0', + nonce: '0x4', + chainId: '0x1', + gasLimit: '0x5208', + hardfork: 'london', + }, + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + data: '0x0', + nonce: '0x4', + chainId: '0x1', + gasLimit: '0x5208', + common: { + customChain: { + networkId: '0x42', + chainId: '0x42', + }, + hardfork: 'london', + }, + }, +]; + +export const transactionTypeUndefined: Transaction[] = [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + data: '0x0', + nonce: '0x4', + chainId: '0x1', + gasLimit: '0x5208', + }, +]; diff --git a/packages/web3-eth/test/unit/detect_transction_type.test.ts b/packages/web3-eth/test/unit/detect_transction_type.test.ts new file mode 100644 index 00000000000..97ba5a96605 --- /dev/null +++ b/packages/web3-eth/test/unit/detect_transction_type.test.ts @@ -0,0 +1,41 @@ +import { detectTransactionType, Transaction } from '../../src/eth_tx'; +import { + transactionType0x0, + transactionType0x1, + transactionType0x2, + transactionTypeUndefined, +} from '../fixtures/detect_transaction_type'; + +describe('should override detectTransactionType method', () => { + it('should return 42', () => { + const overrideFunction = (transaction: Transaction) => { + if (transaction.type !== undefined) return transaction.type; + return 42; + }; + expect(detectTransactionType(transactionTypeUndefined[0], overrideFunction)).toBe(42); + }); +}); + +describe('should detect transaction type 0x0', () => { + it.each(transactionType0x0)('%s', transaction => { + expect(detectTransactionType(transaction)).toBe('0x0'); + }); +}); + +describe('should detect transaction type 0x1', () => { + it.each(transactionType0x1)('%s', transaction => { + expect(detectTransactionType(transaction)).toBe('0x1'); + }); +}); + +describe('should detect transaction type 0x2', () => { + it.each(transactionType0x2)('%s', transaction => { + expect(detectTransactionType(transaction)).toBe('0x2'); + }); +}); + +describe('should not be able to detect transaction type, returning undefined', () => { + it.each(transactionTypeUndefined)('%s', transaction => { + expect(detectTransactionType(transaction)).toBeUndefined(); + }); +}); From 9071db3d9015fce0fc4fd47e8637e9cc51d68fa6 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Wed, 19 Jan 2022 02:50:15 -1000 Subject: [PATCH 014/132] Add more descriptive error messages --- packages/web3-eth/src/errors.ts | 65 +++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 16 deletions(-) diff --git a/packages/web3-eth/src/errors.ts b/packages/web3-eth/src/errors.ts index c2a97e9f536..84a7a0f573c 100644 --- a/packages/web3-eth/src/errors.ts +++ b/packages/web3-eth/src/errors.ts @@ -1,6 +1,6 @@ /* eslint-disable max-classes-per-file */ -import { Web3Error } from 'web3-utils'; +import { Numbers, Web3Error } from 'web3-utils'; export class InvalidTransactionWithSender extends Web3Error { public constructor(value: unknown) { @@ -15,15 +15,17 @@ export class InvalidTransactionCall extends Web3Error { } export class MissingCustomChainError extends Web3Error { - public constructor(value: undefined) { - super(value, 'If tx.common is provided it must have tx.common.customChain'); + public constructor() { + // TODO - Discuss what to pass as value + super('N/A', 'If tx.common is provided it must have tx.common.customChain'); } } export class MissingCustomChainIdError extends Web3Error { - public constructor(value: undefined) { + public constructor() { super( - value, + // TODO - Discuss what to pass as value + 'N/A', 'If tx.common is provided it must have tx.common.customChain and tx.common.customChain.chainId', ); } @@ -61,20 +63,43 @@ export class MissingChainOrHardforkError extends Web3Error { } export class MissingGasError extends Web3Error { - public constructor(value: unknown) { - super(value, '"gas" is missing'); + public constructor(value: { + gas: Numbers | undefined; + gasLimit: Numbers | undefined; + maxPriorityFeePerGas: Numbers | undefined; + maxFeePerGas: Numbers | undefined; + }) { + super( + `gas: ${value.gas ?? 'undefined'}, gasLimit: ${ + value.gasLimit ?? 'undefined' + }, maxPriorityFeePerGas: ${value.maxPriorityFeePerGas ?? 'undefined'}, maxFeePerGas: ${ + value.maxFeePerGas ?? 'undefined' + }`, + '"gas" is missing', + ); } } export class InvalidGasOrGasPrice extends Web3Error { - public constructor(value: { gas: unknown; gasPrice: unknown }) { - super(JSON.stringify(value), 'Gas or gasPrice is lower than 0'); + 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 Web3Error { - public constructor(value: { maxPriorityFeePerGas: unknown; maxFeePerGas: unknown }) { - super(JSON.stringify(value), 'maxPriorityFeePerGas or maxFeePerGas is lower than 0'); + 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', + ); } } @@ -85,9 +110,14 @@ export class Eip1559GasPriceError extends Web3Error { } export class UnsupportedFeeMarketError extends Web3Error { - public constructor(value: { maxPriorityFeePerGas: unknown; maxFeePerGas: unknown }) { + public constructor(value: { + maxPriorityFeePerGas: Numbers | undefined; + maxFeePerGas: Numbers | undefined; + }) { super( - JSON.stringify(value), + `maxPriorityFeePerGas: ${value.maxPriorityFeePerGas ?? 'undefined'}, maxFeePerGas: ${ + value.maxFeePerGas ?? 'undefined' + }`, "pre-eip-1559 transaction don't support maxFeePerGas/maxPriorityFeePerGas", ); } @@ -95,13 +125,16 @@ export class UnsupportedFeeMarketError extends Web3Error { export class InvalidTransactionObjectError extends Web3Error { public constructor(value: unknown) { - super(value, 'invalid transaction obejct'); + super(value, 'invalid transaction object'); } } export class InvalidNonceOrChainIdError extends Web3Error { - public constructor(value: { nonce: unknown; chainId: unknown }) { - super(JSON.stringify(value), 'Nonce or chainId is lower than 0'); + 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', + ); } } From 82d83fd0891b4002c968785832356de6958d4900 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Wed, 19 Jan 2022 03:02:14 -1000 Subject: [PATCH 015/132] Logic fixes for validateTransactionForSigning --- packages/web3-eth/src/eth_tx.ts | 78 +++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 29 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 436788a7b91..f5317ad6a73 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -109,10 +109,10 @@ export function formatTransaction< customChain: { ...transaction.common?.customChain, networkId: convertToValidType( - transaction.common?.customChain.networkId, + transaction.common?.customChain?.networkId, desiredType, ), - chainId: convertToValidType(transaction.common?.customChain.chainId, desiredType), + chainId: convertToValidType(transaction.common?.customChain?.chainId, desiredType), }, }, }; @@ -142,10 +142,9 @@ export const detectTransactionType = ( const validateCustomChainInfo = (transaction: Transaction) => { if (transaction.common !== undefined) { - if (transaction.common.customChain === undefined) - throw new MissingCustomChainError(transaction.common.customChain); + if (transaction.common.customChain === undefined) throw new MissingCustomChainError(); if (transaction.common.customChain.chainId === undefined) - throw new MissingCustomChainIdError(transaction.common.customChain.chainId); + throw new MissingCustomChainIdError(); if ( transaction.chainId !== undefined && transaction.chainId !== transaction.common.customChain.chainId @@ -181,30 +180,46 @@ const validateGas = (transaction: Transaction) => { transaction.maxPriorityFeePerGas === undefined && transaction.maxFeePerGas === undefined ) - throw new MissingGasError(transaction.gas); - if (transaction.gas !== undefined && transaction.gasPrice !== undefined) { - // This check is verifying gas and gasPrice aren't less than 0. - // transaction's number properties have been converted to HexStrings. - // JavaScript doesn't handle negative hex strings e.g. -0x1, but our - // numberToHex method does. -0x1 < 0 would result in false, so we must check if - // hex string is negative via the inclusion of - - if (transaction.gas.startsWith('-') || transaction.gasPrice.startsWith('-')) - throw new InvalidGasOrGasPrice({ - gas: transaction.gas, - gasPrice: transaction.gasPrice, - }); - } + throw new MissingGasError({ + gas: transaction.gas, + gasLimit: transaction.gasLimit, + maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, + maxFeePerGas: transaction.maxFeePerGas, + }); - if (transaction.maxFeePerGas !== undefined && transaction.maxPriorityFeePerGas !== undefined) { + if (transaction.gas !== undefined || transaction.gasPrice !== undefined) { if ( - transaction.maxFeePerGas.startsWith('-') || - transaction.maxPriorityFeePerGas.startsWith('-') + // TODO - Discuss requirement of gasPrice, wasn't enforced in 1.x, but + // at this point gasPrice should've been populated by populateTransaction + // if not provided by the user + + // This check is verifying gas and gasPrice aren't less than 0. + // transaction's number properties have been converted to HexStrings. + // JavaScript doesn't handle negative hex strings e.g. -0x1, but our + // numberToHex method does. -0x1 < 0 would result in false, so we must check if + // hex string is negative via the inclusion of - + transaction.gas === undefined || + transaction.gasPrice === undefined || + transaction.gas.startsWith('-') || + transaction.gasPrice.startsWith('-') ) - throw new InvalidMaxPriorityFeePerGasOrMaxFeePerGas({ - maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, - maxFeePerGas: transaction.maxFeePerGas, + throw new InvalidGasOrGasPrice({ + gas: transaction.gas, + gasPrice: transaction.gasPrice, }); - } + } else if ( + // TODO - Discuss requirement of maxFeePerGas and maxPriorityFeePerGas + // wasn't enforced in 1.x, but at this point the properties should've been + // populated by populateTransaction if not provided by the user + transaction.maxFeePerGas === undefined || + transaction.maxPriorityFeePerGas === undefined || + transaction.maxFeePerGas.startsWith('-') || + transaction.maxPriorityFeePerGas.startsWith('-') + ) + throw new InvalidMaxPriorityFeePerGasOrMaxFeePerGas({ + maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, + maxFeePerGas: transaction.maxFeePerGas, + }); const hasEip1559 = transaction.maxFeePerGas !== undefined || transaction.maxPriorityFeePerGas !== undefined; @@ -212,8 +227,8 @@ const validateGas = (transaction: Transaction) => { throw new Eip1559GasPriceError(transaction.gasPrice); if ((transaction.type === '0x0' || transaction.type === '0x1') && hasEip1559) throw new UnsupportedFeeMarketError({ - maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, maxFeePerGas: transaction.maxFeePerGas, + maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, }); }; @@ -221,7 +236,10 @@ export const validateTransactionForSigning = ( transaction: Transaction, overrideMethod?: (transaction: Transaction) => void, ) => { - if (overrideMethod !== undefined) overrideMethod(transaction); + if (overrideMethod !== undefined) { + overrideMethod(transaction); + return; + } if (typeof transaction !== 'object' || transaction === null) throw new InvalidTransactionObjectError(transaction); @@ -233,8 +251,10 @@ export const validateTransactionForSigning = ( validateGas(formattedTransaction); if ( - (formattedTransaction.nonce as HexString).startsWith('-') || - (formattedTransaction.chainId as HexString).startsWith('-') + formattedTransaction.nonce === undefined || + formattedTransaction.chainId === undefined || + formattedTransaction.nonce.startsWith('-') || + formattedTransaction.chainId.startsWith('-') ) throw new InvalidNonceOrChainIdError({ nonce: transaction.nonce, From 953ee21ea961d7bc96cce9c83533f9c06a21f52e Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Wed, 19 Jan 2022 03:11:32 -1000 Subject: [PATCH 016/132] Init validateTransactionForSigning tests and fixtures --- .../validate_transaction_for_signing.ts | 854 ++++++++++++++++++ .../test/unit/detect_transction_type.test.ts | 8 +- .../validate_transaction_for_signing.test.ts | 73 ++ 3 files changed, 931 insertions(+), 4 deletions(-) create mode 100644 packages/web3-eth/test/fixtures/validate_transaction_for_signing.ts create mode 100644 packages/web3-eth/test/unit/validate_transaction_for_signing.test.ts diff --git a/packages/web3-eth/test/fixtures/validate_transaction_for_signing.ts b/packages/web3-eth/test/fixtures/validate_transaction_for_signing.ts new file mode 100644 index 00000000000..a3a1f0d13df --- /dev/null +++ b/packages/web3-eth/test/fixtures/validate_transaction_for_signing.ts @@ -0,0 +1,854 @@ +import { ValidReturnTypes, ValidTypes } from 'web3-utils'; +import { + ChainIdMismatchError, + CommonOrChainAndHardforkError, + Eip1559GasPriceError, + InvalidGasOrGasPrice, + InvalidMaxPriorityFeePerGasOrMaxFeePerGas, + InvalidNonceOrChainIdError, + MissingChainOrHardforkError, + MissingCustomChainError, + MissingCustomChainIdError, + MissingGasError, + UnsupportedFeeMarketError, +} from '../../src/errors'; +import { Transaction } from '../../src/eth_tx'; + +// eslint-disable-next-line @typescript-eslint/no-empty-function +export const invalidTransactionObject: any[] = ['42', false, '0x0', BigInt(42), () => {}]; + +export const validateCustomChainInfoData: [ + Transaction | any, + undefined | MissingCustomChainError | MissingCustomChainIdError | ChainIdMismatchError, +][] = [ + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + type: '0x0', + data: '0x0', + nonce: '0x4', + chainId: '0x1', + common: { + customChain: { + name: 'foo', + networkId: '0x4', + chainId: '0x1', + }, + baseChain: 'mainnet', + hardfork: 'berlin', + }, + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + undefined, + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + type: '0x0', + data: '0x0', + nonce: '0x4', + chain: 'mainnet', + hardfork: 'berlin', + chainId: '0x1', + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + undefined, + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + type: '0x0', + data: '0x0', + nonce: '0x4', + chainId: '0x1', + common: { + customChain: { + networkId: '0x4', + chainId: '0x1', + }, + }, + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + undefined, + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + type: '0x0', + data: '0x0', + nonce: '0x4', + chainId: '0x1', + common: {}, + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new MissingCustomChainError(), + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + type: '0x0', + data: '0x0', + nonce: '0x4', + chainId: '0x1', + common: { + customChain: { + networkId: '0x4', + }, + }, + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new MissingCustomChainIdError(), + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + type: '0x0', + data: '0x0', + nonce: '0x4', + chainId: '0x1', + common: { + customChain: { + networkId: '0x4', + chainId: '0x42', + }, + }, + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new ChainIdMismatchError({ txChainId: '0x1', customChainId: '0x42' }), + ], +]; + +export const validateChainInfoData: [ + Transaction | any, + undefined | CommonOrChainAndHardforkError | MissingChainOrHardforkError, +][] = [ + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + type: '0x0', + data: '0x0', + nonce: '0x4', + chainId: '0x1', + common: { + customChain: { + name: 'foo', + networkId: '0x4', + chainId: '0x1', + }, + baseChain: 'mainnet', + hardfork: 'berlin', + }, + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + undefined, + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + type: '0x0', + data: '0x0', + nonce: '0x4', + chain: 'mainnet', + hardfork: 'berlin', + chainId: '0x1', + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + undefined, + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + type: '0x0', + data: '0x0', + nonce: '0x4', + chainId: '0x1', + chain: 'mainnet', + hardfork: 'berlin', + common: { + customChain: { + name: 'foo', + networkId: '0x4', + chainId: '0x1', + }, + baseChain: 'mainnet', + hardfork: 'berlin', + }, + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new CommonOrChainAndHardforkError(), + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + type: '0x0', + data: '0x0', + nonce: '0x4', + chainId: '0x1', + chain: 'mainnet', + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new MissingChainOrHardforkError({ + chain: 'mainnet', + hardfork: undefined, + }), + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + type: '0x0', + data: '0x0', + nonce: '0x4', + chainId: '0x1', + hardfork: 'berlin', + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new MissingChainOrHardforkError({ + chain: undefined, + hardfork: 'berlin', + }), + ], +]; + +export const validateGasData: [ + Transaction | any, + ( + | undefined + | MissingGasError + | InvalidGasOrGasPrice + | InvalidMaxPriorityFeePerGasOrMaxFeePerGas + | Eip1559GasPriceError + | UnsupportedFeeMarketError + ), +][] = [ + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + type: '0x0', + data: '0x0', + nonce: '0x4', + chain: 'mainnet', + hardfork: 'berlin', + chainId: '0x1', + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + undefined, + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + maxFeePerGas: '0x1229298c00', + maxPriorityFeePerGas: '0x49504f80', + type: '0x2', + data: '0x0', + nonce: '0x4', + chain: 'mainnet', + hardfork: 'berlin', + chainId: '0x1', + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + undefined, + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + type: '0x2', + data: '0x0', + nonce: '0x4', + chain: 'mainnet', + hardfork: 'berlin', + chainId: '0x1', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new MissingGasError({ + gas: undefined, + gasLimit: undefined, + maxPriorityFeePerGas: undefined, + maxFeePerGas: undefined, + }), + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + type: '0x0', + data: '0x0', + nonce: '0x4', + chain: 'mainnet', + hardfork: 'berlin', + chainId: '0x1', + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new InvalidGasOrGasPrice({ gas: '0x5208', gasPrice: undefined }), + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gasPrice: '0x4a817c800', + type: '0x0', + data: '0x0', + nonce: '0x4', + chain: 'mainnet', + hardfork: 'berlin', + chainId: '0x1', + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new InvalidGasOrGasPrice({ gas: undefined, gasPrice: '0x4a817c800' }), + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '-0x5208', + gasPrice: '0x4a817c800', + type: '0x0', + data: '0x0', + nonce: '0x4', + chain: 'mainnet', + hardfork: 'berlin', + chainId: '0x1', + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new InvalidGasOrGasPrice({ gas: '-0x5208', gasPrice: '0x4a817c800' }), + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '-0x4a817c800', + type: '0x0', + data: '0x0', + nonce: '0x4', + chain: 'mainnet', + hardfork: 'berlin', + chainId: '0x1', + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new InvalidGasOrGasPrice({ gas: '0x5208', gasPrice: '-0x4a817c800' }), + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + maxFeePerGas: '0x1229298c00', + type: '0x2', + data: '0x0', + nonce: '0x4', + chain: 'mainnet', + hardfork: 'berlin', + chainId: '0x1', + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new InvalidMaxPriorityFeePerGasOrMaxFeePerGas({ + maxPriorityFeePerGas: undefined, + maxFeePerGas: '0x1229298c00', + }), + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + maxPriorityFeePerGas: '0x49504f80', + type: '0x2', + data: '0x0', + nonce: '0x4', + chain: 'mainnet', + hardfork: 'berlin', + chainId: '0x1', + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new InvalidMaxPriorityFeePerGasOrMaxFeePerGas({ + maxPriorityFeePerGas: '0x49504f80', + maxFeePerGas: undefined, + }), + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + maxFeePerGas: '-0x1229298c00', + maxPriorityFeePerGas: '0x49504f80', + type: '0x2', + data: '0x0', + nonce: '0x4', + chain: 'mainnet', + hardfork: 'berlin', + chainId: '0x1', + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new InvalidMaxPriorityFeePerGasOrMaxFeePerGas({ + maxPriorityFeePerGas: '0x49504f80', + maxFeePerGas: '-0x1229298c00', + }), + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + maxFeePerGas: '0x1229298c00', + maxPriorityFeePerGas: '-0x49504f80', + type: '0x2', + data: '0x0', + nonce: '0x4', + chain: 'mainnet', + hardfork: 'berlin', + chainId: '0x1', + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new InvalidMaxPriorityFeePerGasOrMaxFeePerGas({ + maxPriorityFeePerGas: '-0x49504f80', + maxFeePerGas: '0x1229298c00', + }), + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + maxFeePerGas: '0x1229298c00', + type: '0x0', + data: '0x0', + nonce: '0x4', + chain: 'mainnet', + hardfork: 'berlin', + chainId: '0x1', + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new Eip1559GasPriceError('0x4a817c800'), + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + maxPriorityFeePerGas: '0x49504f80', + type: '0x0', + data: '0x0', + nonce: '0x4', + chain: 'mainnet', + hardfork: 'berlin', + chainId: '0x1', + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new Eip1559GasPriceError('0x4a817c800'), + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + maxFeePerGas: '0x1229298c00', + maxPriorityFeePerGas: '0x49504f80', + type: '0x0', + data: '0x0', + nonce: '0x4', + chain: 'mainnet', + hardfork: 'berlin', + chainId: '0x1', + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new Eip1559GasPriceError('0x4a817c800'), + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + maxFeePerGas: '0x1229298c00', + maxPriorityFeePerGas: '0x49504f80', + type: '0x2', + data: '0x0', + nonce: '0x4', + chain: 'mainnet', + hardfork: 'berlin', + chainId: '0x1', + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new Eip1559GasPriceError('0x4a817c800'), + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + type: '0x2', + data: '0x0', + nonce: '0x4', + chain: 'mainnet', + hardfork: 'berlin', + chainId: '0x1', + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new Eip1559GasPriceError('0x4a817c800'), + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + maxFeePerGas: '0x1229298c00', + maxPriorityFeePerGas: '0x49504f80', + type: '0x0', + data: '0x0', + nonce: '0x4', + chain: 'mainnet', + hardfork: 'berlin', + chainId: '0x1', + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new UnsupportedFeeMarketError({ + maxFeePerGas: '0x1229298c00', + maxPriorityFeePerGas: '0x49504f80', + }), + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + maxFeePerGas: '0x1229298c00', + maxPriorityFeePerGas: '0x49504f80', + type: '0x1', + data: '0x0', + nonce: '0x4', + chain: 'mainnet', + hardfork: 'berlin', + chainId: '0x1', + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new UnsupportedFeeMarketError({ + maxFeePerGas: '0x1229298c00', + maxPriorityFeePerGas: '0x49504f80', + }), + ], +]; + +export const invalidNonceOrChainIdData: [ + Transaction | any, + undefined | InvalidNonceOrChainIdError, +][] = [ + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + type: '0x0', + data: '0x0', + nonce: '0x4', + chainId: '0x1', + common: { + customChain: { + name: 'foo', + networkId: '0x4', + chainId: '0x1', + }, + baseChain: 'mainnet', + hardfork: 'berlin', + }, + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + undefined, + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + type: '0x0', + data: '0x0', + chainId: '0x1', + common: { + customChain: { + name: 'foo', + networkId: '0x4', + chainId: '0x1', + }, + baseChain: 'mainnet', + hardfork: 'berlin', + }, + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new InvalidNonceOrChainIdError({ + nonce: undefined, + chainId: '0x1', + }), + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + type: '0x0', + data: '0x0', + nonce: '0x4', + common: { + customChain: { + name: 'foo', + networkId: '0x4', + chainId: '0x1', + }, + baseChain: 'mainnet', + hardfork: 'berlin', + }, + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new InvalidNonceOrChainIdError({ + nonce: '0x4', + chainId: undefined, + }), + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + type: '0x0', + data: '0x0', + nonce: '-0x4', + chainId: '0x1', + common: { + customChain: { + name: 'foo', + networkId: '0x4', + chainId: '0x1', + }, + baseChain: 'mainnet', + hardfork: 'berlin', + }, + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new InvalidNonceOrChainIdError({ + nonce: '-0x4', + chainId: '0x1', + }), + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + type: '0x0', + data: '0x0', + nonce: '0x4', + chainId: '-0x1', + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new InvalidNonceOrChainIdError({ + nonce: '0x4', + chainId: '-0x1', + }), + ], + [ + { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', + type: '0x0', + data: '0x0', + nonce: '0x4', + chainId: '-0x1', + common: { + customChain: { + name: 'foo', + networkId: '0x4', + chainId: '-0x1', + }, + baseChain: 'mainnet', + hardfork: 'berlin', + }, + gasLimit: '0x5208', + v: '0x25', + r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + }, + new InvalidNonceOrChainIdError({ + nonce: '0x4', + chainId: '-0x1', + }), + ], +]; diff --git a/packages/web3-eth/test/unit/detect_transction_type.test.ts b/packages/web3-eth/test/unit/detect_transction_type.test.ts index 97ba5a96605..1d0013062c7 100644 --- a/packages/web3-eth/test/unit/detect_transction_type.test.ts +++ b/packages/web3-eth/test/unit/detect_transction_type.test.ts @@ -8,10 +8,10 @@ import { describe('should override detectTransactionType method', () => { it('should return 42', () => { - const overrideFunction = (transaction: Transaction) => { - if (transaction.type !== undefined) return transaction.type; - return 42; - }; + // @ts-expect-error - Purposefully not using transaction here, + // but must be present to satisfy method signature + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const overrideFunction = (transaction: Transaction) => 42; expect(detectTransactionType(transactionTypeUndefined[0], overrideFunction)).toBe(42); }); }); 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 new file mode 100644 index 00000000000..261005fcb2c --- /dev/null +++ b/packages/web3-eth/test/unit/validate_transaction_for_signing.test.ts @@ -0,0 +1,73 @@ +/* eslint-disable jest/no-conditional-expect */ + +import { InvalidTransactionObjectError } from '../../src/errors'; +import { Transaction, validateTransactionForSigning } from '../../src/eth_tx'; +import { + invalidNonceOrChainIdData, + invalidTransactionObject, + validateChainInfoData, + validateCustomChainInfoData, + validateGasData, +} from '../fixtures/validate_transaction_for_signing'; + +describe('validateTransactionForSigning', () => { + describe('should override validateTransactionForSigning method', () => { + it('should return 42', () => { + // @ts-expect-error - Purposefully not using transaction here, + // but must be present to satisfy method signature + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const overrideFunction = (transaction: Transaction) => 42; + expect( + validateTransactionForSigning(invalidTransactionObject[0], overrideFunction), + ).toBe(42); + }); + }); + + describe('should throw InvalidTransactionObjectError', () => { + it.each(invalidTransactionObject)('%s', transaction => { + expect(() => validateTransactionForSigning(transaction)).toThrow( + new InvalidTransactionObjectError(transaction), + ); + }); + }); + + describe('validateCustomChainInfo', () => { + it.each(validateCustomChainInfoData)('%s should return %s', (transaction, output) => { + if (output instanceof Error) { + expect(() => validateTransactionForSigning(transaction)).toThrow(output); + } else { + expect(validateTransactionForSigning(transaction)).toBeUndefined(); + } + }); + }); + + describe('validateChainInfo', () => { + it.each(validateChainInfoData)('%s should return %s', (transaction, output) => { + if (output instanceof Error) { + expect(() => validateTransactionForSigning(transaction)).toThrow(output); + } else { + expect(validateTransactionForSigning(transaction)).toBeUndefined(); + } + }); + }); + + describe('validateGas', () => { + it.each(validateGasData)('%s should return %s', (transaction, output) => { + if (output instanceof Error) { + expect(() => validateTransactionForSigning(transaction)).toThrow(output); + } else { + expect(validateTransactionForSigning(transaction)).toBeUndefined(); + } + }); + }); + + describe('should throw InvalidNonceOrChainIdError', () => { + it.each(invalidNonceOrChainIdData)('%s', (transaction, output) => { + if (output instanceof Error) { + expect(() => validateTransactionForSigning(transaction)).toThrow(output); + } else { + expect(validateTransactionForSigning(transaction)).toBeUndefined(); + } + }); + }); +}); From 77093a37d70459adfd1d428113877ac1d602365c Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Wed, 19 Jan 2022 03:14:55 -1000 Subject: [PATCH 017/132] Add esModuleInterop: true to tsconfig --- templates/tsconfig.json.tmpl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/templates/tsconfig.json.tmpl b/templates/tsconfig.json.tmpl index 7ed7f6b23a4..33b9f1c8116 100644 --- a/templates/tsconfig.json.tmpl +++ b/templates/tsconfig.json.tmpl @@ -1,7 +1,8 @@ { "extends": "../../tsconfig", "compilerOptions": { - "outDir": "dist" + "outDir": "dist", + "esModuleInterop": true }, "include": ["src/**/*"] } From 281b6bdffb5401fc718ade67b3a875a8934985f6 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Wed, 19 Jan 2022 07:19:16 -1000 Subject: [PATCH 018/132] Small bug fixes and added TODOs --- packages/web3-eth/src/eth_tx.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index f5317ad6a73..031979469ba 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -84,7 +84,7 @@ export interface Transaction { } export function formatTransaction< - DesiredType extends ValidTypes, + DesiredType extends ValidTypes = ValidTypes, ReturnType = ValidReturnTypes[DesiredType], >( transaction: Transaction, @@ -94,7 +94,8 @@ export function formatTransaction< if (overrideMethod !== undefined) return overrideMethod(transaction); const formattedTransaction = { ...transaction, - value: convertToValidType(transaction.value, desiredType), + value: + transaction.value === '0x' ? '0x' : convertToValidType(transaction.value, desiredType), gas: convertToValidType(transaction.gas, desiredType), gasPrice: convertToValidType(transaction.gasPrice, desiredType), type: convertToValidType(transaction.type, desiredType), @@ -289,8 +290,9 @@ export interface PopulatedUnsignedEip1559Transaction } export type PopulatedUnsignedTransaction = | PopulatedUnsignedBaseTransaction - | PopulatedUnsignedEip2930Transaction + | PopulatedUnsignedEip2930Transaction | PopulatedUnsignedEip1559Transaction; + export async function populateTransaction< DesiredType extends ValidTypes, ReturnType = ValidReturnTypes[DesiredType], @@ -350,6 +352,8 @@ export async function populateTransaction< populatedTransaction.gasLimit = populatedTransaction.gas; } + // TODO - Discuss how this should work with default hardfork, because detectTransactionType + // will use 0x2 for london and 0x1 for berlin, but should this be overwritten by web3Context.defaultTxType? // If populatedTransaction.type is already defined, no change will be made populatedTransaction.type = detectTransactionType(populatedTransaction); // TODO - After web3Context.defaultTxType is implemented @@ -364,7 +368,7 @@ export async function populateTransaction< if (hexTxType === '0x0' || hexTxType === '0x1') { // transaction.type not supported before Berlin hardfork // TODO - Maybe add check for populatedTransaction.hardfork >= Berlin before deleting - if (hexTxType === '0x0') populatedTransaction.type = undefined; + // if (hexTxType === '0x0') populatedTransaction.type = undefined; if (populatedTransaction.gasPrice === undefined) populatedTransaction.gasPrice = await web3Eth.getGasPrice(); @@ -386,7 +390,7 @@ export async function populateTransaction< } else { if (populatedTransaction.maxPriorityFeePerGas === undefined) // TODO - Add maxPriorityFeePerGas default to Web3Context - populatedTransaction.maxPriorityFeePerGas = toHex('2500000000'); // 2.5 Gwei + populatedTransaction.maxPriorityFeePerGas = toHex(2500000000); // 2.5 Gwei if (populatedTransaction.maxFeePerGas === undefined) populatedTransaction.maxFeePerGas = BigInt(block.baseFeePerGas) * BigInt(2) + @@ -394,6 +398,7 @@ export async function populateTransaction< } } + // TODO - TSC returns that as only PopulatedUnsignedBaseTransaction return formatTransaction( populatedTransaction, desiredType, From 06f75753b293f3b73cad251e116eb4185afa23f0 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Wed, 19 Jan 2022 07:19:44 -1000 Subject: [PATCH 019/132] Add parent describe to detect_transaction_type test --- .../test/unit/detect_transction_type.test.ts | 48 ++++++++++--------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/packages/web3-eth/test/unit/detect_transction_type.test.ts b/packages/web3-eth/test/unit/detect_transction_type.test.ts index 1d0013062c7..4a2a141578f 100644 --- a/packages/web3-eth/test/unit/detect_transction_type.test.ts +++ b/packages/web3-eth/test/unit/detect_transction_type.test.ts @@ -6,36 +6,38 @@ import { transactionTypeUndefined, } from '../fixtures/detect_transaction_type'; -describe('should override detectTransactionType method', () => { - it('should return 42', () => { - // @ts-expect-error - Purposefully not using transaction here, - // but must be present to satisfy method signature - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const overrideFunction = (transaction: Transaction) => 42; - expect(detectTransactionType(transactionTypeUndefined[0], overrideFunction)).toBe(42); +describe('detectTransactionType', () => { + describe('should override detectTransactionType method', () => { + it('should return 42', () => { + // @ts-expect-error - Purposefully not using transaction here, + // but must be present to satisfy method signature + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const overrideFunction = (transaction: Transaction) => 42; + expect(detectTransactionType(transactionTypeUndefined[0], overrideFunction)).toBe(42); + }); }); -}); -describe('should detect transaction type 0x0', () => { - it.each(transactionType0x0)('%s', transaction => { - expect(detectTransactionType(transaction)).toBe('0x0'); + describe('should detect transaction type 0x0', () => { + it.each(transactionType0x0)('%s', transaction => { + expect(detectTransactionType(transaction)).toBe('0x0'); + }); }); -}); -describe('should detect transaction type 0x1', () => { - it.each(transactionType0x1)('%s', transaction => { - expect(detectTransactionType(transaction)).toBe('0x1'); + describe('should detect transaction type 0x1', () => { + it.each(transactionType0x1)('%s', transaction => { + expect(detectTransactionType(transaction)).toBe('0x1'); + }); }); -}); -describe('should detect transaction type 0x2', () => { - it.each(transactionType0x2)('%s', transaction => { - expect(detectTransactionType(transaction)).toBe('0x2'); + describe('should detect transaction type 0x2', () => { + it.each(transactionType0x2)('%s', transaction => { + expect(detectTransactionType(transaction)).toBe('0x2'); + }); }); -}); -describe('should not be able to detect transaction type, returning undefined', () => { - it.each(transactionTypeUndefined)('%s', transaction => { - expect(detectTransactionType(transaction)).toBeUndefined(); + describe('should not be able to detect transaction type, returning undefined', () => { + it.each(transactionTypeUndefined)('%s', transaction => { + expect(detectTransactionType(transaction)).toBeUndefined(); + }); }); }); From 143922bf35ce19d3759d5cfa33f9993e2c2831d5 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Wed, 19 Jan 2022 07:19:56 -1000 Subject: [PATCH 020/132] Add parent describe to format_transaction test --- .../test/unit/format_transaction.test.ts | 104 +++++++++--------- 1 file changed, 53 insertions(+), 51 deletions(-) diff --git a/packages/web3-eth/test/unit/format_transaction.test.ts b/packages/web3-eth/test/unit/format_transaction.test.ts index 10d5b0c8dd5..9ac9cbefeb1 100644 --- a/packages/web3-eth/test/unit/format_transaction.test.ts +++ b/packages/web3-eth/test/unit/format_transaction.test.ts @@ -7,70 +7,72 @@ import { numberTransaction, } from '../fixtures/format_transaction'; -describe('should convert hex string properties to expected type', () => { - it('numbers', () => { - const result = formatTransaction(hexStringTransaction, ValidTypes.Number); - expect(result).toStrictEqual(numberTransaction); - }); +describe('formatTransaction', () => { + describe('should convert hex string properties to expected type', () => { + it('numbers', () => { + const result = formatTransaction(hexStringTransaction, ValidTypes.Number); + expect(result).toStrictEqual(numberTransaction); + }); - it('number strings', () => { - const result = formatTransaction(hexStringTransaction, ValidTypes.NumberString); - expect(result).toStrictEqual(numberStringTransaction); - }); + it('number strings', () => { + const result = formatTransaction(hexStringTransaction, ValidTypes.NumberString); + expect(result).toStrictEqual(numberStringTransaction); + }); - it('BigInts', () => { - const result = formatTransaction(hexStringTransaction, ValidTypes.BigInt); - expect(result).toStrictEqual(bigIntTransaction); + it('BigInts', () => { + const result = formatTransaction(hexStringTransaction, ValidTypes.BigInt); + expect(result).toStrictEqual(bigIntTransaction); + }); }); -}); -describe('should convert number properties to expected type', () => { - it('hex string', () => { - const result = formatTransaction(numberTransaction, ValidTypes.HexString); - expect(result).toStrictEqual(hexStringTransaction); - }); + describe('should convert number properties to expected type', () => { + it('hex string', () => { + const result = formatTransaction(numberTransaction, ValidTypes.HexString); + expect(result).toStrictEqual(hexStringTransaction); + }); - it('number strings', () => { - const result = formatTransaction(numberTransaction, ValidTypes.NumberString); - expect(result).toStrictEqual(numberStringTransaction); - }); + it('number strings', () => { + const result = formatTransaction(numberTransaction, ValidTypes.NumberString); + expect(result).toStrictEqual(numberStringTransaction); + }); - it('BigInts', () => { - const result = formatTransaction(numberTransaction, ValidTypes.BigInt); - expect(result).toStrictEqual(bigIntTransaction); + it('BigInts', () => { + const result = formatTransaction(numberTransaction, ValidTypes.BigInt); + expect(result).toStrictEqual(bigIntTransaction); + }); }); -}); -describe('should convert number string properties to expected type', () => { - it('hex strings', () => { - const result = formatTransaction(numberStringTransaction, ValidTypes.HexString); - expect(result).toStrictEqual(hexStringTransaction); - }); + describe('should convert number string properties to expected type', () => { + it('hex strings', () => { + const result = formatTransaction(numberStringTransaction, ValidTypes.HexString); + expect(result).toStrictEqual(hexStringTransaction); + }); - it('numbers', () => { - const result = formatTransaction(numberStringTransaction, ValidTypes.Number); - expect(result).toStrictEqual(numberTransaction); - }); + it('numbers', () => { + const result = formatTransaction(numberStringTransaction, ValidTypes.Number); + expect(result).toStrictEqual(numberTransaction); + }); - it('BigInts', () => { - const result = formatTransaction(numberStringTransaction, ValidTypes.BigInt); - expect(result).toStrictEqual(bigIntTransaction); + it('BigInts', () => { + const result = formatTransaction(numberStringTransaction, ValidTypes.BigInt); + expect(result).toStrictEqual(bigIntTransaction); + }); }); -}); -describe('should convert bigint properties to expected type', () => { - it('hex strings', () => { - const result = formatTransaction(bigIntTransaction, ValidTypes.HexString); - expect(result).toStrictEqual(hexStringTransaction); - }); + describe('should convert bigint properties to expected type', () => { + it('hex strings', () => { + const result = formatTransaction(bigIntTransaction, ValidTypes.HexString); + expect(result).toStrictEqual(hexStringTransaction); + }); - it('numbers', () => { - const result = formatTransaction(bigIntTransaction, ValidTypes.Number); - expect(result).toStrictEqual(numberTransaction); - }); + it('numbers', () => { + const result = formatTransaction(bigIntTransaction, ValidTypes.Number); + expect(result).toStrictEqual(numberTransaction); + }); - it('number strings', () => { - const result = formatTransaction(bigIntTransaction, ValidTypes.NumberString); - expect(result).toStrictEqual(numberStringTransaction); + it('number strings', () => { + const result = formatTransaction(bigIntTransaction, ValidTypes.NumberString); + expect(result).toStrictEqual(numberStringTransaction); + }); }); }); From fb16061224f42d09f53830c4f2cc4aaa14cc2ed9 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Wed, 19 Jan 2022 07:20:31 -1000 Subject: [PATCH 021/132] Add web3-providers-http as dev dependency for tests --- packages/web3-eth/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/web3-eth/package.json b/packages/web3-eth/package.json index 01f849ba676..b08f0a6d55f 100644 --- a/packages/web3-eth/package.json +++ b/packages/web3-eth/package.json @@ -36,7 +36,8 @@ "jest-extended": "^1.1.0", "prettier": "^2.4.1", "ts-jest": "^27.0.7", - "typescript": "^4.5.2" + "typescript": "^4.5.2", + "web3-providers-http": "4.0.0-alpha.1" }, "dependencies": { "@ethereumjs/tx": "^3.4.0", From dcf90376b70a59571359e9ea5e75070044231bf8 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Wed, 19 Jan 2022 07:24:38 -1000 Subject: [PATCH 022/132] Init populate_transaction tests --- .../test/unit/populate_transaction.test.ts | 376 ++++++++++++++++++ 1 file changed, 376 insertions(+) create mode 100644 packages/web3-eth/test/unit/populate_transaction.test.ts diff --git a/packages/web3-eth/test/unit/populate_transaction.test.ts b/packages/web3-eth/test/unit/populate_transaction.test.ts new file mode 100644 index 00000000000..afa83d0f763 --- /dev/null +++ b/packages/web3-eth/test/unit/populate_transaction.test.ts @@ -0,0 +1,376 @@ +import { EthExecutionAPI } from 'web3-common'; +import { Web3Context } from 'web3-core'; +import { BlockTags, ValidTypes } from 'web3-utils'; +import { HttpProvider } from 'web3-providers-http'; + +import * as rpcMethods from '../../src/rpc_methods'; +import { + PopulatedUnsignedEip1559Transaction, + PopulatedUnsignedEip2930Transaction, + populateTransaction, + Transaction, +} from '../../src/eth_tx'; +import { + Eip1559NotSupportedError, + UnableToPopulateNonceError, + UnsupportedTransactionTypeError, +} from '../../src/errors'; + +jest.mock('../../src/rpc_methods'); + +describe('populateTransaction', () => { + const expectedFrom = '0xb8CE9ab6943e0eCED004cDe8e3bBed6568B2Fa01'; + const expectedNonce = '0x42'; + const expectedGas = '0x5208'; + const expectedGasLimit = expectedGas; + const expectedGasPrice = '0x4a817c800'; + const expectedBaseFeePerGas = '0x13afe8b904'; + const expectedMaxPriorityFeePerGas = '0x9502f900'; + const expectedMaxFeePerGas = '0x27f4d46b08'; + const transaction: Transaction = { + from: expectedFrom, + to: '0x3535353535353535353535353535353535353535', + value: '0x174876e800', + gas: expectedGas, + gasLimit: expectedGasLimit, + gasPrice: expectedGasPrice, + type: '0x0', + maxFeePerGas: expectedMaxFeePerGas, + maxPriorityFeePerGas: expectedMaxPriorityFeePerGas, + data: '0x0', + nonce: expectedNonce, + chain: 'mainnet', + hardfork: 'berlin', + chainId: '0x1', + common: { + customChain: { + name: 'foo', + networkId: '0x4', + chainId: '0x42', + }, + baseChain: 'mainnet', + hardfork: 'berlin', + }, + }; + const mockBlockData = { + parentHash: '0xe99e022112df268087ea7eafaf4790497fd21dbeeb6bd7a1721df161a6657a54', + sha3Uncles: '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347', + miner: '0xbb7b8287f3f0a933474a79eae42cbca977791171', + stateRoot: '0xddc8b0234c2e0cad087c8b389aa7ef01f7d79b2570bccb77ce48648aa61c904d', + transactionsRoot: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', + receiptsRoot: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', + logsBloom: + '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', + difficulty: '0x4ea3f27bc', + number: '0x1b4', + gasLimit: '0x1388', + gasUsed: '0x1c96e73', + timestamp: '0x55ba467c', + extraData: '0x476574682f4c5649562f76312e302e302f6c696e75782f676f312e342e32', + mixHash: '0x4fffe9ae21f1c9e15207b1f472d5bbdd68c9595d461666602f2be20daf5e7843', + nonce: '0x1c11920a4', + totalDifficulty: '0x78ed983323d', + size: '0x220', + transactions: [ + '0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b', + '0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b', + '0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b', + ], + uncles: [ + '0xdc0818cf78f21a8e70579cb46a43643f78291264dda342ae31049421c82d21ae', + '0xdc0818cf78f21a8e70579cb46a43643f78291264dda342ae31049421c82d21ae', + '0xdc0818cf78f21a8e70579cb46a43643f78291264dda342ae31049421c82d21ae', + ], + hash: '0xdc0818cf78f21a8e70579cb46a43643f78291264dda342ae31049421c82d21ae', + baseFeePerGas: expectedBaseFeePerGas, + }; + let web3Context: Web3Context; + let getTransactionCountSpy: jest.SpyInstance; + + beforeEach(() => { + // @ts-expect-error - Mocked implementation doesn't have correct method signature + // (i.e. requestManager, blockNumber, hydrated params), but that doesn't matter for the test + jest.spyOn(rpcMethods, 'getBlockByNumber').mockImplementation(() => mockBlockData); + getTransactionCountSpy = jest + .spyOn(rpcMethods, 'getTransactionCount') + // @ts-expect-error - Mocked implementation doesn't have correct method signature + // (i.e. requestManager, blockNumber, hydrated params), but that doesn't matter for the test + .mockImplementation(() => expectedNonce); + // @ts-expect-error - Mocked implementation doesn't have correct method signature + // (i.e. requestManager, blockNumber, hydrated params), but that doesn't matter for the test + jest.spyOn(rpcMethods, 'getGasPrice').mockImplementation(() => expectedGasPrice); + + web3Context = new Web3Context(new HttpProvider('http://127.0.0.1')); + }); + + describe('should populate from', () => { + it('should use privateKey to populate', async () => { + const input = { ...transaction }; + delete input.from; + + const result = await populateTransaction( + input, + web3Context, + ValidTypes.HexString, + '0x348ce564d427a3311b6536bbcff9390d69395b06ed6c486954e971d960fe8709', + ); + expect(result.from).toBe(expectedFrom); + }); + + it('should use web3Context.defaultAccount to populate', async () => { + web3Context = new Web3Context(new HttpProvider('http://127.0.0.1'), { + defaultAccount: expectedFrom, + }); + + const input = { ...transaction }; + delete input.from; + + const result = await populateTransaction(input, web3Context, ValidTypes.HexString); + expect(result.from).toBe(expectedFrom); + }); + }); + + describe('should populate nonce', () => { + it('should throw UnableToPopulateNonceError', async () => { + const input = { ...transaction }; + delete input.from; + delete input.nonce; + + await expect( + populateTransaction(input, web3Context, ValidTypes.HexString), + ).rejects.toThrow(new UnableToPopulateNonceError()); + }); + + it('should use web3Eth.getTransactionCount to populate nonce', async () => { + const input = { ...transaction }; + delete input.nonce; + + const result = await populateTransaction(input, web3Context, ValidTypes.HexString); + expect(result.nonce).toBe(expectedNonce); + expect(getTransactionCountSpy).toHaveBeenCalledWith( + web3Context.requestManager, + expectedFrom, + BlockTags.PENDING, + ); + }); + }); + + describe('should populate value', () => { + it('should populate with 0x', async () => { + const input = { ...transaction }; + delete input.value; + + const result = await populateTransaction(input, web3Context, ValidTypes.HexString); + expect(result.value).toBe('0x'); + }); + }); + + describe('should populate data', () => { + it('should populate with 0x', async () => { + const input = { ...transaction }; + delete input.data; + + const result = await populateTransaction(input, web3Context, ValidTypes.HexString); + expect(result.data).toBe('0x'); + }); + }); + + describe('should populate chain', () => { + it('should populate with 0x', async () => { + const input = { ...transaction }; + delete input.chain; + + const result = await populateTransaction(input, web3Context, ValidTypes.HexString); + expect(result.chain).toBe('mainnet'); + }); + }); + + describe('should populate hardfork', () => { + it('should populate with 0x', async () => { + const input = { ...transaction }; + delete input.hardfork; + + const result = await populateTransaction(input, web3Context, ValidTypes.HexString); + expect(result.hardfork).toBe('london'); + }); + }); + + describe('should populate chainId', () => { + // TODO - web3Eth.getChainId not implemented + it.skip('should populate with web3Eth.getChainId', async () => { + const input = { ...transaction }; + delete input.chainId; + + const result = await populateTransaction(input, web3Context, ValidTypes.HexString); + expect(result.chainId).toBe('0x1'); + }); + }); + + describe('should populate gas', () => { + it('should populate with gasLimit', async () => { + const input = { ...transaction }; + delete input.gas; + + const result = await populateTransaction(input, web3Context, ValidTypes.HexString); + expect(result.gas).toBe(expectedGas); + }); + }); + + describe('should populate gasLimit', () => { + it('should populate with gas', async () => { + const input = { ...transaction }; + delete input.gasLimit; + + const result = await populateTransaction(input, web3Context, ValidTypes.HexString); + expect(result.gasLimit).toBe(expectedGasLimit); + }); + }); + + describe('should populate type', () => { + it('should populate with 0x0', async () => { + const input = { ...transaction }; + delete input.type; + + // Used by detectTransactionType + delete input.maxFeePerGas; + delete input.maxPriorityFeePerGas; + delete input.common?.hardfork; + delete input.accessList; + // detectTransactionType will automatically set type to 0x2 for london + // and 0x1 for berlin, so manually setting to something it doesn't handle yet + input.hardfork = 'merge'; + + const result = await populateTransaction(input, web3Context, ValidTypes.HexString); + expect(result.type).toBe('0x0'); + }); + + it('should throw UnsupportedTransactionTypeError', async () => { + const input = { ...transaction }; + input.type = '0x4'; + + await expect( + populateTransaction(input, web3Context, ValidTypes.HexString), + ).rejects.toThrow(new UnsupportedTransactionTypeError(input.type)); + }); + }); + + describe('should populate gasPrice', () => { + it('should populate with web3Eth.getGasPrice (tx.type 0x0)', async () => { + const input = { ...transaction }; + delete input.gasPrice; + input.type = '0x0'; + + const result = await populateTransaction(input, web3Context, ValidTypes.HexString); + expect(result.gasPrice).toBe(expectedGasPrice); + }); + + it('should populate with web3Eth.getGasPrice (tx.type 0x1)', async () => { + const input = { ...transaction }; + delete input.gasPrice; + input.type = '0x1'; + + const result = await populateTransaction(input, web3Context, ValidTypes.HexString); + expect(result.gasPrice).toBe(expectedGasPrice); + }); + }); + + describe('should populate accessList', () => { + it('should populate with [] (tx.type 0x1)', async () => { + const input = { ...transaction }; + delete input.accessList; + input.type = '0x1'; + + const result = await populateTransaction(input, web3Context, ValidTypes.HexString); + expect((result as PopulatedUnsignedEip2930Transaction).accessList).toStrictEqual([]); + }); + + it('should populate with [] (tx.type 0x2)', async () => { + const input = { ...transaction }; + delete input.accessList; + input.type = '0x2'; + + const result = await populateTransaction(input, web3Context, ValidTypes.HexString); + expect((result as PopulatedUnsignedEip1559Transaction).accessList).toStrictEqual([]); + }); + }); + + describe('should populate maxPriorityFeePerGas and maxFeePerGas', () => { + it('should throw Eip1559NotSupportedError', async () => { + const mockBlockDataNoBaseFeePerGas = { ...mockBlockData, baseFeePerGas: undefined }; + jest.spyOn(rpcMethods, 'getBlockByNumber').mockImplementation( + // @ts-expect-error - Mocked implementation doesn't have correct method signature + // (i.e. requestManager, blockNumber, hydrated params), but that doesn't matter for the test + () => mockBlockDataNoBaseFeePerGas, + ); + + const input = { ...transaction }; + input.type = '0x2'; + + await expect( + populateTransaction(input, web3Context, ValidTypes.HexString), + ).rejects.toThrow(new Eip1559NotSupportedError()); + }); + + it('should populate with gasPrice', async () => { + const input = { ...transaction }; + delete input.maxPriorityFeePerGas; + delete input.maxFeePerGas; + input.type = '0x2'; + + const result = await populateTransaction(input, web3Context, ValidTypes.HexString); + expect((result as PopulatedUnsignedEip1559Transaction).maxPriorityFeePerGas).toBe( + expectedGasPrice, + ); + expect((result as PopulatedUnsignedEip1559Transaction).maxPriorityFeePerGas).toBe( + expectedGasPrice, + ); + expect(result.gasPrice).toBeUndefined(); + }); + + it('should populate with default maxPriorityFeePerGas and calculated maxFeePerGas (no maxPriorityFeePerGas and maxFeePerGas)', async () => { + const input = { ...transaction }; + delete input.maxPriorityFeePerGas; + delete input.maxFeePerGas; + delete input.gasPrice; + input.type = '0x2'; + + const result = await populateTransaction(input, web3Context, ValidTypes.HexString); + expect((result as PopulatedUnsignedEip1559Transaction).maxPriorityFeePerGas).toBe( + expectedMaxPriorityFeePerGas, + ); // 2.5 Gwei, hardcoded in populateTransaction; + expect((result as PopulatedUnsignedEip1559Transaction).maxFeePerGas).toBe( + expectedMaxFeePerGas, + ); + }); + + it('should populate with default maxPriorityFeePerGas and calculated maxFeePerGas (no maxFeePerGas)', async () => { + const input = { ...transaction }; + delete input.maxFeePerGas; + delete input.gasPrice; + input.type = '0x2'; + + const result = await populateTransaction(input, web3Context, ValidTypes.HexString); + expect((result as PopulatedUnsignedEip1559Transaction).maxPriorityFeePerGas).toBe( + expectedMaxPriorityFeePerGas, + ); // 2.5 Gwei, hardcoded in populateTransaction; + expect((result as PopulatedUnsignedEip1559Transaction).maxFeePerGas).toBe( + expectedMaxFeePerGas, + ); + }); + + it('should populate with default maxPriorityFeePerGas and calculated maxFeePerGas (no maxPriorityFeePerGas)', async () => { + const input = { ...transaction }; + delete input.maxPriorityFeePerGas; + delete input.gasPrice; + input.type = '0x2'; + + const result = await populateTransaction(input, web3Context, ValidTypes.HexString); + expect((result as PopulatedUnsignedEip1559Transaction).maxPriorityFeePerGas).toBe( + expectedMaxPriorityFeePerGas, + ); // 2.5 Gwei, hardcoded in populateTransaction; + expect((result as PopulatedUnsignedEip1559Transaction).maxFeePerGas).toBe( + expectedMaxFeePerGas, + ); + }); + }); +}); From 17e418c55afb0e0d611bbf98c5a5294a36865d7c Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Wed, 19 Jan 2022 07:29:20 -1000 Subject: [PATCH 023/132] Move types from eth_tx.ts to types.ts --- packages/web3-eth/src/eth_tx.ts | 88 +-------- packages/web3-eth/src/types.ts | 184 +++++++----------- .../test/unit/detect_transction_type.test.ts | 3 +- .../test/unit/populate_transaction.test.ts | 4 +- 4 files changed, 76 insertions(+), 203 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 031979469ba..b9db9972a76 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -1,17 +1,16 @@ -import { AccessList, EthExecutionAPI } from 'web3-common'; +import { EthExecutionAPI } from 'web3-common'; import { Web3Context } from 'web3-core'; import { - Address, BlockTags, convertToValidType, HexString, - HexStringBytes, Numbers, toHex, ValidReturnTypes, ValidTypes, } from 'web3-utils'; import { privateKeyToAddress } from 'web3-eth-accounts'; + import Web3Eth from '.'; import { ChainIdMismatchError, @@ -30,58 +29,7 @@ import { UnsupportedFeeMarketError, UnsupportedTransactionTypeError, } from './errors'; - -export type chain = 'goerli' | 'kovan' | 'mainnet' | 'rinkeby' | 'ropsten' | 'sepolia'; -export type hardfork = - | 'arrowGlacier' - | 'berlin' - | 'byzantium' - | 'chainstart' - | 'constantinople' - | 'dao' - | 'homestead' - | 'istanbul' - | 'london' - | 'merge' - | 'muirGlacier' - | 'petersburg' - | 'shanghai' - | 'spuriousDragon' - | 'tangerineWhistle'; - -export interface CustomChain { - name?: string; - networkId: NumberType; - chainId: NumberType; -} - -export interface Common { - customChain: CustomChain; - baseChain?: chain; - hardfork?: hardfork; -} - -export interface Transaction { - from?: Address; - to?: Address; - value?: NumberType; - gas?: NumberType; - gasPrice?: NumberType; - type?: NumberType; - maxFeePerGas?: NumberType; - maxPriorityFeePerGas?: NumberType; - accessList?: AccessList; - data?: HexStringBytes; - nonce?: NumberType; - chain?: chain; - hardfork?: hardfork; - chainId?: NumberType; - common?: Common; - gasLimit?: NumberType; - v?: NumberType; - r?: HexString; - s?: HexString; -} +import { PopulatedUnsignedTransaction, Transaction } from './types'; export function formatTransaction< DesiredType extends ValidTypes = ValidTypes, @@ -263,36 +211,6 @@ export const validateTransactionForSigning = ( }); }; -export interface PopulatedUnsignedBaseTransaction { - from: Address; - to?: Address; - value: Numbers; - gas?: Numbers; - gasPrice: Numbers; - type: Numbers; - data: HexStringBytes; - nonce: Numbers; - chain: chain; - hardfork: hardfork; - chainId: Numbers; - common: Common; - gasLimit: Numbers; -} -export interface PopulatedUnsignedEip2930Transaction - extends PopulatedUnsignedBaseTransaction { - accessList: AccessList; -} -export interface PopulatedUnsignedEip1559Transaction - extends PopulatedUnsignedEip2930Transaction { - gasPrice: never; - maxFeePerGas: NumberType; - maxPriorityFeePerGas: NumberType; -} -export type PopulatedUnsignedTransaction = - | PopulatedUnsignedBaseTransaction - | PopulatedUnsignedEip2930Transaction - | PopulatedUnsignedEip1559Transaction; - export async function populateTransaction< DesiredType extends ValidTypes, ReturnType = ValidReturnTypes[DesiredType], diff --git a/packages/web3-eth/src/types.ts b/packages/web3-eth/src/types.ts index 15f7f961505..6a4b83ab7f0 100644 --- a/packages/web3-eth/src/types.ts +++ b/packages/web3-eth/src/types.ts @@ -8,135 +8,89 @@ import { HexString32Bytes, HexString256Bytes, HexStringBytes, - Uint, } from 'web3-utils'; -export enum ChainNames { - MAINNET = 'mainnet', - GOERLI = 'goerli', - KOVAN = 'kovan', - RINKEBY = 'rinkeby', - ROPSTEN = 'ropsten', +export type chain = 'goerli' | 'kovan' | 'mainnet' | 'rinkeby' | 'ropsten' | 'sepolia'; +export type hardfork = + | 'arrowGlacier' + | 'berlin' + | 'byzantium' + | 'chainstart' + | 'constantinople' + | 'dao' + | 'homestead' + | 'istanbul' + | 'london' + | 'merge' + | 'muirGlacier' + | 'petersburg' + | 'shanghai' + | 'spuriousDragon' + | 'tangerineWhistle'; + +export interface CustomChain { + name?: string; + networkId: NumberType; + chainId: NumberType; } -export enum HardForks { - CHAIN_START = 'chainstart', - HOMESTEAD = 'homestead', - DAO = 'dao', - TANGERINE_WHISTLE = 'tangerineWhistle', - SPURIOUS_DRAGON = 'spuriousDragon', - BYZANTIUM = 'byzantium', - CONSTANTINOPLE = 'constantinople', - PETERSBURG = 'petersburg', - ISTANBUL = 'istanbul', - BERLIN = 'berlin', - LONDON = 'london', +export interface Common { + customChain: CustomChain; + baseChain?: chain; + hardfork?: hardfork; } -export interface Transaction { +export interface Transaction { from?: Address; to?: Address; - value?: Numbers; - gas?: Numbers; - gasPrice?: Numbers; - type?: Numbers; - maxFeePerGas?: Numbers; - maxPriorityFeePerGas?: Numbers; + value?: NumberType; + gas?: NumberType; + gasPrice?: NumberType; + type?: NumberType; + maxFeePerGas?: NumberType; + maxPriorityFeePerGas?: NumberType; accessList?: AccessList; - input: HexStringBytes; - data?: HexString; - nonce?: Numbers; - chain?: HexString; - hardfork?: HexString; - common?: { - customChain: { - name?: string; - networkId: Numbers; - chainId: Numbers; - }; - baseChain?: ChainNames; - hardfork?: HardForks; - }; -} - -interface BaseTransactionFormatted< - DesiredType extends ValidTypes = ValidTypes.HexString, - ReturnType = ValidReturnTypes[DesiredType], -> { - readonly to?: Address | null; - readonly type: ReturnType; - readonly nonce: ReturnType; - readonly gas: ReturnType; - readonly value: ReturnType; - readonly input: HexStringBytes; -} - -interface Transaction1559UnsignedFormatted< - DesiredType extends ValidTypes = ValidTypes.HexString, - ReturnType = ValidReturnTypes[DesiredType], -> extends BaseTransactionFormatted { - readonly maxFeePerGas: ReturnType; - readonly maxPriorityFeePerGas: ReturnType; - readonly accessList: AccessList; + data?: HexStringBytes; + nonce?: NumberType; + chain?: chain; + hardfork?: hardfork; + chainId?: NumberType; + common?: Common; + gasLimit?: NumberType; + v?: NumberType; + r?: HexString; + s?: HexString; } -interface Transaction1559SignedFormatted< - DesiredType extends ValidTypes = ValidTypes.HexString, - ReturnType = ValidReturnTypes[DesiredType], -> extends Transaction1559UnsignedFormatted { - readonly yParity: ReturnType; - readonly r: ReturnType; - readonly s: ReturnType; -} - -interface Transaction2930UnsignedFormatted< - DesiredType extends ValidTypes = ValidTypes.HexString, - ReturnType = ValidReturnTypes[DesiredType], -> extends BaseTransactionFormatted { - readonly gasPrice: ReturnType; - readonly accessList: AccessList; +export interface PopulatedUnsignedBaseTransaction { + from: Address; + to?: Address; + value: Numbers; + gas?: Numbers; + gasPrice: Numbers; + type: Numbers; + data: HexStringBytes; + nonce: Numbers; + chain: chain; + hardfork: hardfork; + chainId: Numbers; + common: Common; + gasLimit: Numbers; } - -interface Transaction2930SignedFormatted< - DesiredType extends ValidTypes = ValidTypes.HexString, - ReturnType = ValidReturnTypes[DesiredType], -> extends Transaction2930UnsignedFormatted { - readonly yParity: ReturnType; - readonly r: ReturnType; - readonly s: ReturnType; +export interface PopulatedUnsignedEip2930Transaction + extends PopulatedUnsignedBaseTransaction { + accessList: AccessList; } - -interface TransactionLegacyUnsignedFormatted< - DesiredType extends ValidTypes = ValidTypes.HexString, - ReturnType = ValidReturnTypes[DesiredType], -> extends BaseTransactionFormatted { - readonly gasPrice: ReturnType; +export interface PopulatedUnsignedEip1559Transaction + extends PopulatedUnsignedEip2930Transaction { + gasPrice: never; + maxFeePerGas: NumberType; + maxPriorityFeePerGas: NumberType; } - -interface TransactionLegacySignedFormatted< - DesiredType extends ValidTypes = ValidTypes.HexString, - ReturnType = ValidReturnTypes[DesiredType], -> extends TransactionLegacyUnsignedFormatted { - readonly v: ReturnType; - readonly r: Uint; - readonly s: Uint; -} - -type TransactionSignedFormatted = - | Transaction1559SignedFormatted - | Transaction2930SignedFormatted - | TransactionLegacySignedFormatted; - -export type TransactionInfoFormatted< - DesiredType extends ValidTypes = ValidTypes.HexString, - ReturnType = ValidReturnTypes[DesiredType], -> = TransactionSignedFormatted & { - readonly blockHash: HexString32Bytes | null; - readonly blockNumber: ReturnType | null; - readonly from: Address; - readonly hash: HexString32Bytes; - readonly transactionIndex: ReturnType | null; -}; +export type PopulatedUnsignedTransaction = + | PopulatedUnsignedBaseTransaction + | PopulatedUnsignedEip2930Transaction + | PopulatedUnsignedEip1559Transaction; export interface ReceiptInfoFormatted< DesiredType extends ValidTypes = ValidTypes.HexString, diff --git a/packages/web3-eth/test/unit/detect_transction_type.test.ts b/packages/web3-eth/test/unit/detect_transction_type.test.ts index 4a2a141578f..c270134ebfd 100644 --- a/packages/web3-eth/test/unit/detect_transction_type.test.ts +++ b/packages/web3-eth/test/unit/detect_transction_type.test.ts @@ -1,4 +1,5 @@ -import { detectTransactionType, Transaction } from '../../src/eth_tx'; +import { detectTransactionType } from '../../src/eth_tx'; +import { Transaction } from '../../src/types'; import { transactionType0x0, transactionType0x1, diff --git a/packages/web3-eth/test/unit/populate_transaction.test.ts b/packages/web3-eth/test/unit/populate_transaction.test.ts index afa83d0f763..df6655729c1 100644 --- a/packages/web3-eth/test/unit/populate_transaction.test.ts +++ b/packages/web3-eth/test/unit/populate_transaction.test.ts @@ -4,12 +4,12 @@ import { BlockTags, ValidTypes } from 'web3-utils'; import { HttpProvider } from 'web3-providers-http'; import * as rpcMethods from '../../src/rpc_methods'; +import { populateTransaction } from '../../src/eth_tx'; import { PopulatedUnsignedEip1559Transaction, PopulatedUnsignedEip2930Transaction, - populateTransaction, Transaction, -} from '../../src/eth_tx'; +} from '../../src/types'; import { Eip1559NotSupportedError, UnableToPopulateNonceError, From 5c3abbd9f09cde518a9110245e018c6a6790a57c Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Wed, 19 Jan 2022 07:47:06 -1000 Subject: [PATCH 024/132] Remove TODOs --- packages/web3-eth/src/eth_tx.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index b9db9972a76..c91ed2eaaab 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -138,10 +138,6 @@ const validateGas = (transaction: Transaction) => { if (transaction.gas !== undefined || transaction.gasPrice !== undefined) { if ( - // TODO - Discuss requirement of gasPrice, wasn't enforced in 1.x, but - // at this point gasPrice should've been populated by populateTransaction - // if not provided by the user - // This check is verifying gas and gasPrice aren't less than 0. // transaction's number properties have been converted to HexStrings. // JavaScript doesn't handle negative hex strings e.g. -0x1, but our @@ -157,9 +153,6 @@ const validateGas = (transaction: Transaction) => { gasPrice: transaction.gasPrice, }); } else if ( - // TODO - Discuss requirement of maxFeePerGas and maxPriorityFeePerGas - // wasn't enforced in 1.x, but at this point the properties should've been - // populated by populateTransaction if not provided by the user transaction.maxFeePerGas === undefined || transaction.maxPriorityFeePerGas === undefined || transaction.maxFeePerGas.startsWith('-') || From 631187273da4a3d866a851a2a77bda7f1d01a924 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Wed, 19 Jan 2022 07:50:56 -1000 Subject: [PATCH 025/132] Add missing , --- packages/web3-eth/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web3-eth/package.json b/packages/web3-eth/package.json index a9f9129b632..3781f4ec864 100644 --- a/packages/web3-eth/package.json +++ b/packages/web3-eth/package.json @@ -43,7 +43,7 @@ "@ethereumjs/tx": "^3.4.0", "web3-common": "1.0.0-alpha.0", "web3-core": "4.0.0-alpha.0", - "web3-eth-accounts": "4.0.0-alpha.0" + "web3-eth-accounts": "4.0.0-alpha.0", "web3-utils": "4.0.0-alpha.1", "web3-validator": "^0.1.0-alpha.0" } From 11f8097c4e930d1b1b14c7b17bdac76050037ecc Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Wed, 19 Jan 2022 07:51:00 -1000 Subject: [PATCH 026/132] Remove TODO --- packages/web3-eth/src/eth_tx.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index c91ed2eaaab..fc863854865 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -243,7 +243,6 @@ export async function populateTransaction< // TODO - Add default to Web3Context if (populatedTransaction.chain === undefined) populatedTransaction.chain = 'mainnet'; // TODO - Add default to Web3Context - // TODO - Update default to berlin? (It's london in 1.x) if (populatedTransaction.hardfork === undefined) populatedTransaction.hardfork = 'london'; if (populatedTransaction.chainId === undefined) { From ef46dbcbd77827e05f1dcf748491b7c5e67f3d08 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Wed, 19 Jan 2022 07:54:17 -1000 Subject: [PATCH 027/132] Remove TODO --- packages/web3-eth/src/eth_tx.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index fc863854865..30e67885dea 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -262,9 +262,6 @@ export async function populateTransaction< populatedTransaction.gasLimit = populatedTransaction.gas; } - // TODO - Discuss how this should work with default hardfork, because detectTransactionType - // will use 0x2 for london and 0x1 for berlin, but should this be overwritten by web3Context.defaultTxType? - // If populatedTransaction.type is already defined, no change will be made populatedTransaction.type = detectTransactionType(populatedTransaction); // TODO - After web3Context.defaultTxType is implemented if (populatedTransaction.type === undefined) populatedTransaction.type = '0x0'; // web3Context.defaultTxType; From cbe1c205753a1037c0e66631c9ca16586f45f419 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Fri, 21 Jan 2022 05:24:02 -1000 Subject: [PATCH 028/132] Fix transaction type import issues --- packages/web3-eth/test/fixtures/detect_transaction_type.ts | 2 +- packages/web3-eth/test/fixtures/format_transaction.ts | 2 +- .../web3-eth/test/fixtures/validate_transaction_for_signing.ts | 2 +- packages/web3-eth/test/unit/populate_transaction.test.ts | 2 +- .../test/unit/validate_transaction_for_signing.test.ts | 3 ++- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/web3-eth/test/fixtures/detect_transaction_type.ts b/packages/web3-eth/test/fixtures/detect_transaction_type.ts index 3ac2876a34c..d793a795890 100644 --- a/packages/web3-eth/test/fixtures/detect_transaction_type.ts +++ b/packages/web3-eth/test/fixtures/detect_transaction_type.ts @@ -1,5 +1,5 @@ import { ValidReturnTypes, ValidTypes } from 'web3-utils'; -import { Transaction } from '../../src/eth_tx'; +import { Transaction } from '../../src/types'; export const transactionType0x0: Transaction[] = [ { diff --git a/packages/web3-eth/test/fixtures/format_transaction.ts b/packages/web3-eth/test/fixtures/format_transaction.ts index 1ac16ad57c0..03c24ed9b90 100644 --- a/packages/web3-eth/test/fixtures/format_transaction.ts +++ b/packages/web3-eth/test/fixtures/format_transaction.ts @@ -1,5 +1,5 @@ import { ValidReturnTypes, ValidTypes } from 'web3-utils'; -import { Transaction } from '../../src/eth_tx'; +import { Transaction } from '../../src/types'; export const hexStringTransaction: Transaction = { from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', 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 a3a1f0d13df..7390ccea592 100644 --- a/packages/web3-eth/test/fixtures/validate_transaction_for_signing.ts +++ b/packages/web3-eth/test/fixtures/validate_transaction_for_signing.ts @@ -12,7 +12,7 @@ import { MissingGasError, UnsupportedFeeMarketError, } from '../../src/errors'; -import { Transaction } from '../../src/eth_tx'; +import { Transaction } from '../../src/types'; // 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/unit/populate_transaction.test.ts b/packages/web3-eth/test/unit/populate_transaction.test.ts index df6655729c1..8ae99af0f8f 100644 --- a/packages/web3-eth/test/unit/populate_transaction.test.ts +++ b/packages/web3-eth/test/unit/populate_transaction.test.ts @@ -1,7 +1,7 @@ import { EthExecutionAPI } from 'web3-common'; import { Web3Context } from 'web3-core'; import { BlockTags, ValidTypes } from 'web3-utils'; -import { HttpProvider } from 'web3-providers-http'; +import HttpProvider from 'web3-providers-http'; import * as rpcMethods from '../../src/rpc_methods'; import { populateTransaction } from '../../src/eth_tx'; 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 261005fcb2c..4865aece364 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 @@ -1,7 +1,8 @@ /* eslint-disable jest/no-conditional-expect */ import { InvalidTransactionObjectError } from '../../src/errors'; -import { Transaction, validateTransactionForSigning } from '../../src/eth_tx'; +import { validateTransactionForSigning } from '../../src/eth_tx'; +import { Transaction } from '../../src/types'; import { invalidNonceOrChainIdData, invalidTransactionObject, From 36a2ad804f4744b528b3be9695f11921f695d53b Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Fri, 21 Jan 2022 05:25:58 -1000 Subject: [PATCH 029/132] Update convertToValidType test data for undefined --- packages/web3-utils/test/fixtures/converters.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/web3-utils/test/fixtures/converters.ts b/packages/web3-utils/test/fixtures/converters.ts index b0683f413ae..b88bae51514 100644 --- a/packages/web3-utils/test/fixtures/converters.ts +++ b/packages/web3-utils/test/fixtures/converters.ts @@ -265,9 +265,9 @@ export const toCheckSumValidData: [string, string][] = [ ]; export const convertToValidTypeValidData: [ - ValidReturnTypes[ValidTypes], + ValidReturnTypes[ValidTypes] | undefined, ValidTypes, - ValidReturnTypes[ValidTypes], + ValidReturnTypes[ValidTypes] | undefined, ][] = [ ['0x2a', ValidTypes.HexString, '0x2a'], ['42', ValidTypes.HexString, '0x2a'], @@ -301,6 +301,7 @@ export const convertToValidTypeValidData: [ ['-42', ValidTypes.BigInt, BigInt('-42')], [-42, ValidTypes.BigInt, BigInt('-42')], [BigInt('-42'), ValidTypes.BigInt, BigInt('-42')], + [undefined, ValidTypes.HexString, undefined], ]; export const convertToValidTypeInvalidData: [any, any, InvalidDesiredTypeError | string][] = [ @@ -313,7 +314,6 @@ export const convertToValidTypeInvalidData: [any, any, InvalidDesiredTypeError | ['foo', ValidTypes.HexString, 'value "foo" at "/0" must pass "int" validation'], ['4.2', ValidTypes.HexString, 'value "4.2" at "/0" must pass "int" validation'], [null, ValidTypes.HexString, 'value at "/0" must pass "int" validation'], - [undefined, ValidTypes.HexString, 'value at "/0" must pass "int" validation'], [true, ValidTypes.HexString, 'value "true" at "/0" must pass "int" validation'], ]; From 008aed2fdbc7fdb213de9f18b4cac8f28d87dd61 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Fri, 21 Jan 2022 05:33:20 -1000 Subject: [PATCH 030/132] Update override method tests --- .../test/unit/detect_transction_type.test.ts | 11 ++++------- .../web3-eth/test/unit/format_transaction.test.ts | 6 ++++++ .../web3-eth/test/unit/populate_transaction.test.ts | 13 +++++++++++++ .../unit/validate_transaction_for_signing.test.ts | 13 ++++--------- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/packages/web3-eth/test/unit/detect_transction_type.test.ts b/packages/web3-eth/test/unit/detect_transction_type.test.ts index c270134ebfd..4aa75f30c1c 100644 --- a/packages/web3-eth/test/unit/detect_transction_type.test.ts +++ b/packages/web3-eth/test/unit/detect_transction_type.test.ts @@ -1,5 +1,4 @@ import { detectTransactionType } from '../../src/eth_tx'; -import { Transaction } from '../../src/types'; import { transactionType0x0, transactionType0x1, @@ -9,12 +8,10 @@ import { describe('detectTransactionType', () => { describe('should override detectTransactionType method', () => { - it('should return 42', () => { - // @ts-expect-error - Purposefully not using transaction here, - // but must be present to satisfy method signature - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const overrideFunction = (transaction: Transaction) => 42; - expect(detectTransactionType(transactionTypeUndefined[0], overrideFunction)).toBe(42); + it('should call override method', () => { + const overrideFunction = jest.fn(); + detectTransactionType(transactionTypeUndefined[0], overrideFunction); + expect(overrideFunction).toHaveBeenCalledWith(transactionTypeUndefined[0]); }); }); diff --git a/packages/web3-eth/test/unit/format_transaction.test.ts b/packages/web3-eth/test/unit/format_transaction.test.ts index 9ac9cbefeb1..06e91b482f5 100644 --- a/packages/web3-eth/test/unit/format_transaction.test.ts +++ b/packages/web3-eth/test/unit/format_transaction.test.ts @@ -8,6 +8,12 @@ import { } from '../fixtures/format_transaction'; describe('formatTransaction', () => { + it('should call override method', () => { + const overrideFunction = jest.fn(); + formatTransaction(hexStringTransaction, ValidTypes.Number, overrideFunction); + expect(overrideFunction).toHaveBeenCalledWith(hexStringTransaction); + }); + describe('should convert hex string properties to expected type', () => { it('numbers', () => { const result = formatTransaction(hexStringTransaction, ValidTypes.Number); diff --git a/packages/web3-eth/test/unit/populate_transaction.test.ts b/packages/web3-eth/test/unit/populate_transaction.test.ts index 8ae99af0f8f..b47ccdc4529 100644 --- a/packages/web3-eth/test/unit/populate_transaction.test.ts +++ b/packages/web3-eth/test/unit/populate_transaction.test.ts @@ -103,6 +103,19 @@ describe('populateTransaction', () => { web3Context = new Web3Context(new HttpProvider('http://127.0.0.1')); }); + it('should call override method', async () => { + const overrideFunction = jest.fn(); + const input = { ...transaction }; + await populateTransaction( + input, + web3Context, + ValidTypes.HexString, + '0x348ce564d427a3311b6536bbcff9390d69395b06ed6c486954e971d960fe8709', + overrideFunction, + ); + expect(overrideFunction).toHaveBeenCalledWith(input); + }); + describe('should populate from', () => { it('should use privateKey to populate', async () => { const input = { ...transaction }; 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 4865aece364..0ae040eb126 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 @@ -2,7 +2,6 @@ import { InvalidTransactionObjectError } from '../../src/errors'; import { validateTransactionForSigning } from '../../src/eth_tx'; -import { Transaction } from '../../src/types'; import { invalidNonceOrChainIdData, invalidTransactionObject, @@ -13,14 +12,10 @@ import { describe('validateTransactionForSigning', () => { describe('should override validateTransactionForSigning method', () => { - it('should return 42', () => { - // @ts-expect-error - Purposefully not using transaction here, - // but must be present to satisfy method signature - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const overrideFunction = (transaction: Transaction) => 42; - expect( - validateTransactionForSigning(invalidTransactionObject[0], overrideFunction), - ).toBe(42); + it('should call override method', () => { + const overrideFunction = jest.fn(); + validateTransactionForSigning(invalidTransactionObject[0], overrideFunction); + expect(overrideFunction).toHaveBeenCalledWith(invalidTransactionObject[0]); }); }); From 293be77d9ad2459613d7be44bb32afc0112d3073 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Sun, 23 Jan 2022 19:02:37 -1000 Subject: [PATCH 031/132] Update packages/web3-eth/src/eth_tx.ts Co-authored-by: jdevcs <86780488+jdevcs@users.noreply.github.com> --- packages/web3-eth/src/eth_tx.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 30e67885dea..a45a81b4694 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -269,7 +269,7 @@ export async function populateTransaction< const block = await web3Eth.getBlock(); const hexTxType = toHex(populatedTransaction.type); - if (hexTxType < '0x0' || hexTxType > '0x2') + if (hexTxType < '0x0' || hexTxType > '0x7f') //https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2718.md#transactions throw new UnsupportedTransactionTypeError(populatedTransaction.type); if (hexTxType === '0x0' || hexTxType === '0x1') { From e82d5d33ce1f0c537898fe979ca689a6af418b53 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Sun, 23 Jan 2022 19:10:35 -1000 Subject: [PATCH 032/132] Move getBlock to after type check for populateTransaction --- packages/web3-eth/src/eth_tx.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 30e67885dea..5f15efeb1fc 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -122,6 +122,7 @@ const validateChainInfo = (transaction: Transaction) => { }); }; +// TODO Split into validateEipXXX methods const validateGas = (transaction: Transaction) => { if ( transaction.gas === undefined && @@ -266,7 +267,7 @@ export async function populateTransaction< // TODO - After web3Context.defaultTxType is implemented if (populatedTransaction.type === undefined) populatedTransaction.type = '0x0'; // web3Context.defaultTxType; - const block = await web3Eth.getBlock(); + // TODO Probably need to account for negative hex strings const hexTxType = toHex(populatedTransaction.type); if (hexTxType < '0x0' || hexTxType > '0x2') @@ -286,6 +287,8 @@ export async function populateTransaction< } if (hexTxType === '0x2') { + const block = await web3Eth.getBlock(); + // Unless otherwise specified by web3Context.defaultBlock, this defaults to latest if (block.baseFeePerGas === undefined) throw new Eip1559NotSupportedError(); From eaa4bd0ff89a0a1a65a9547caf22b34f12abcc35 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Sun, 23 Jan 2022 21:25:48 -1000 Subject: [PATCH 033/132] Replace N/A with name of error for error.msg --- packages/web3-eth/src/errors.ts | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/packages/web3-eth/src/errors.ts b/packages/web3-eth/src/errors.ts index 84a7a0f573c..41301b6ced7 100644 --- a/packages/web3-eth/src/errors.ts +++ b/packages/web3-eth/src/errors.ts @@ -16,16 +16,17 @@ export class InvalidTransactionCall extends Web3Error { export class MissingCustomChainError extends Web3Error { public constructor() { - // TODO - Discuss what to pass as value - super('N/A', 'If tx.common is provided it must have tx.common.customChain'); + super( + 'MissingCustomChainError', + 'If tx.common is provided it must have tx.common.customChain', + ); } } export class MissingCustomChainIdError extends Web3Error { public constructor() { super( - // TODO - Discuss what to pass as value - 'N/A', + 'MissingCustomChainIdError', 'If tx.common is provided it must have tx.common.customChain and tx.common.customChain.chainId', ); } @@ -42,9 +43,8 @@ export class ChainIdMismatchError extends Web3Error { export class CommonOrChainAndHardforkError extends Web3Error { public constructor() { - // TODO - Discuss what to pass as value, would it make sense to pass common, chain, and hardfork for error message here? super( - 'N/A', + 'CommonOrChainAndHardforkError', 'Please provide the @ethereumjs/common object or the chain and hardfork property but not all together.', ); } @@ -52,9 +52,8 @@ export class CommonOrChainAndHardforkError extends Web3Error { export class MissingChainOrHardforkError extends Web3Error { public constructor(value: { chain: string | undefined; hardfork: string | undefined }) { - // TODO - Discuss what to pass as value super( - 'N/A', + 'MissingChainOrHardforkError', `When specifying chain and hardfork, both values must be defined. Received "chain": ${ value.chain ?? 'undefined' }, "hardfork": ${value.hardfork ?? 'undefined'}`, @@ -140,15 +139,13 @@ export class InvalidNonceOrChainIdError extends Web3Error { export class UnableToPopulateNonceError extends Web3Error { public constructor() { - // TODO - Discuss what to pass as value - super('N/A', 'unable to populate nonce, no from address available'); + super('UnableToPopulateNonceError', 'unable to populate nonce, no from address available'); } } export class Eip1559NotSupportedError extends Web3Error { public constructor() { - // TODO - Discuss what to pass as value - super('N/A', "Network doesn't support eip-1559"); + super('Eip1559NotSupportedError', "Network doesn't support eip-1559"); } } From 92bcaaf1ae52c42117082328ce8dea55c1cba021 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Sun, 23 Jan 2022 21:33:01 -1000 Subject: [PATCH 034/132] Assign formattedTransaction type Transaction --- packages/web3-eth/src/eth_tx.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 726431555de..5a1ee98cd8b 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -40,7 +40,7 @@ export function formatTransaction< overrideMethod?: (transaction: Transaction) => Transaction, ): Transaction { if (overrideMethod !== undefined) return overrideMethod(transaction); - const formattedTransaction = { + const formattedTransaction: Transaction = { ...transaction, value: transaction.value === '0x' ? '0x' : convertToValidType(transaction.value, desiredType), @@ -65,9 +65,8 @@ export function formatTransaction< }, }, }; - // TODO - TSC is complaining that ReturnType could be instantiated with an - // arbitrary type which could be unrelated to 'string | number | bigint | undefined' - return formattedTransaction as unknown as Transaction; + + return formattedTransaction; } export const detectTransactionType = ( @@ -270,7 +269,8 @@ export async function populateTransaction< // TODO Probably need to account for negative hex strings const hexTxType = toHex(populatedTransaction.type); - if (hexTxType < '0x0' || hexTxType > '0x7f') //https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2718.md#transactions + if (hexTxType < '0x0' || hexTxType > '0x7f') + // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2718.md#transactions throw new UnsupportedTransactionTypeError(populatedTransaction.type); if (hexTxType === '0x0' || hexTxType === '0x1') { From e41aed821e3552a15b12ff7c8c2b1bf357caa98c Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 24 Jan 2022 00:13:33 -1000 Subject: [PATCH 035/132] convertToValidType now throws error for value === undefined --- packages/web3-utils/src/converters.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/web3-utils/src/converters.ts b/packages/web3-utils/src/converters.ts index fcacd581ea3..8251b9514de 100644 --- a/packages/web3-utils/src/converters.ts +++ b/packages/web3-utils/src/converters.ts @@ -439,10 +439,11 @@ export const jsonInterfaceMethodToString = ( }; export const convertToValidType = ( - value: ValidReturnTypes[ValidTypes] | undefined, // validate this + value: ValidReturnTypes[ValidTypes], // validate this desiredType: ValidTypes, -): ValidReturnTypes[ValidTypes] | undefined => { - if (value === undefined) return value; +) => { + // TODO - Replace error + if (value === undefined) throw new Error('value is undefined'); switch (desiredType) { case ValidTypes.HexString: From f7ff2d82a994b8e5e73202f0bab6d06e144fc4a5 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 24 Jan 2022 00:13:45 -1000 Subject: [PATCH 036/132] NumberType extends Numbers --- packages/web3-eth/src/types.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/web3-eth/src/types.ts b/packages/web3-eth/src/types.ts index 6a4b83ab7f0..24f25ed3d98 100644 --- a/packages/web3-eth/src/types.ts +++ b/packages/web3-eth/src/types.ts @@ -40,7 +40,7 @@ export interface Common { hardfork?: hardfork; } -export interface Transaction { +export interface Transaction { from?: Address; to?: Address; value?: NumberType; @@ -62,7 +62,7 @@ export interface Transaction { s?: HexString; } -export interface PopulatedUnsignedBaseTransaction { +export interface PopulatedUnsignedBaseTransaction { from: Address; to?: Address; value: Numbers; @@ -77,17 +77,17 @@ export interface PopulatedUnsignedBaseTransaction { common: Common; gasLimit: Numbers; } -export interface PopulatedUnsignedEip2930Transaction +export interface PopulatedUnsignedEip2930Transaction extends PopulatedUnsignedBaseTransaction { accessList: AccessList; } -export interface PopulatedUnsignedEip1559Transaction +export interface PopulatedUnsignedEip1559Transaction extends PopulatedUnsignedEip2930Transaction { gasPrice: never; maxFeePerGas: NumberType; maxPriorityFeePerGas: NumberType; } -export type PopulatedUnsignedTransaction = +export type PopulatedUnsignedTransaction = | PopulatedUnsignedBaseTransaction | PopulatedUnsignedEip2930Transaction | PopulatedUnsignedEip1559Transaction; From 0f5bac0a18a44fbc95f1c16de60018c376036c99 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 24 Jan 2022 00:14:01 -1000 Subject: [PATCH 037/132] Transaction type related changes --- packages/web3-eth/src/eth_tx.ts | 118 ++++++++++++++++---------------- 1 file changed, 60 insertions(+), 58 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 5a1ee98cd8b..2bed5ea9196 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -1,14 +1,6 @@ import { EthExecutionAPI } from 'web3-common'; import { Web3Context } from 'web3-core'; -import { - BlockTags, - convertToValidType, - HexString, - Numbers, - toHex, - ValidReturnTypes, - ValidTypes, -} from 'web3-utils'; +import { BlockTags, convertToValidType, HexString, Numbers, toHex, ValidTypes } from 'web3-utils'; import { privateKeyToAddress } from 'web3-eth-accounts'; import Web3Eth from '.'; @@ -29,44 +21,67 @@ import { UnsupportedFeeMarketError, UnsupportedTransactionTypeError, } from './errors'; -import { PopulatedUnsignedTransaction, Transaction } from './types'; +import { Transaction } from './types'; -export function formatTransaction< - DesiredType extends ValidTypes = ValidTypes, - ReturnType = ValidReturnTypes[DesiredType], ->( +export function formatTransaction( transaction: Transaction, desiredType: DesiredType, - overrideMethod?: (transaction: Transaction) => Transaction, -): Transaction { - if (overrideMethod !== undefined) return overrideMethod(transaction); - const formattedTransaction: Transaction = { - ...transaction, - value: - transaction.value === '0x' ? '0x' : convertToValidType(transaction.value, desiredType), - gas: convertToValidType(transaction.gas, desiredType), - gasPrice: convertToValidType(transaction.gasPrice, desiredType), - type: convertToValidType(transaction.type, desiredType), - maxFeePerGas: convertToValidType(transaction.maxFeePerGas, desiredType), - maxPriorityFeePerGas: convertToValidType(transaction.maxPriorityFeePerGas, desiredType), - nonce: convertToValidType(transaction.nonce, desiredType), - chainId: convertToValidType(transaction.chainId, desiredType), - gasLimit: convertToValidType(transaction.gasLimit, desiredType), - v: convertToValidType(transaction.v, desiredType), - common: { - ...transaction.common, - customChain: { - ...transaction.common?.customChain, - networkId: convertToValidType( - transaction.common?.customChain?.networkId, +): Transaction { + const formattedTransaction = { ...transaction }; + if (formattedTransaction.value !== undefined) + formattedTransaction.value = + formattedTransaction.value === '0x' + ? '0x' + : convertToValidType(formattedTransaction.value, desiredType); + if (formattedTransaction.gas !== undefined) + formattedTransaction.gas = convertToValidType(formattedTransaction.gas, desiredType); + if (formattedTransaction.gasPrice !== undefined) + formattedTransaction.gasPrice = convertToValidType( + formattedTransaction.gasPrice, + desiredType, + ); + if (formattedTransaction.type !== undefined) + formattedTransaction.type = convertToValidType(formattedTransaction.type, desiredType); + if (formattedTransaction.maxFeePerGas !== undefined) + formattedTransaction.maxFeePerGas = convertToValidType( + formattedTransaction.maxFeePerGas, + desiredType, + ); + if (formattedTransaction.maxPriorityFeePerGas !== undefined) + formattedTransaction.maxPriorityFeePerGas = convertToValidType( + formattedTransaction.maxPriorityFeePerGas, + desiredType, + ); + if (formattedTransaction.nonce !== undefined) + formattedTransaction.nonce = convertToValidType(formattedTransaction.nonce, desiredType); + if (formattedTransaction.chainId !== undefined) + formattedTransaction.chainId = convertToValidType( + formattedTransaction.chainId, + desiredType, + ); + if (formattedTransaction.gasLimit !== undefined) + formattedTransaction.gasLimit = convertToValidType( + formattedTransaction.gasLimit, + desiredType, + ); + if (formattedTransaction.v !== undefined) + formattedTransaction.v = convertToValidType(formattedTransaction.v, desiredType); + if (formattedTransaction.common !== undefined) { + if (formattedTransaction.common.customChain !== undefined) { + if (formattedTransaction.common.customChain.networkId !== undefined) + formattedTransaction.common.customChain.networkId = convertToValidType( + formattedTransaction.common.customChain.networkId, + desiredType, + ); + if (formattedTransaction.common.customChain.chainId !== undefined) + formattedTransaction.common.customChain.chainId = convertToValidType( + formattedTransaction.common.customChain.chainId, desiredType, - ), - chainId: convertToValidType(transaction.common?.customChain?.chainId, desiredType), - }, - }, - }; + ); + } + } - return formattedTransaction; + return formattedTransaction as Transaction; } export const detectTransactionType = ( @@ -204,21 +219,12 @@ export const validateTransactionForSigning = ( }); }; -export async function populateTransaction< - DesiredType extends ValidTypes, - ReturnType = ValidReturnTypes[DesiredType], ->( +export async function populateTransaction( transaction: Transaction, web3Context: Web3Context, desiredType: DesiredType, privateKey?: HexString, - overrideMethod?: ( - transaction: Transaction, - web3Context: Web3Context, - ) => PopulatedUnsignedTransaction, -): Promise> { - if (overrideMethod !== undefined) return overrideMethod(transaction, web3Context); - +) { const populatedTransaction = { ...transaction }; const web3Eth = new Web3Eth(web3Context.currentProvider); @@ -308,11 +314,7 @@ export async function populateTransaction< } } - // TODO - TSC returns that as only PopulatedUnsignedBaseTransaction - return formatTransaction( - populatedTransaction, - desiredType, - ) as PopulatedUnsignedTransaction; + return formatTransaction(populatedTransaction, desiredType); } // TODO - Replace use of Web3Context with Web3Eth From b3d7e972015fa6e0b6926ca0b52c2f4f3ff97e50 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 24 Jan 2022 00:25:57 -1000 Subject: [PATCH 038/132] Refactor DesiredType logic --- packages/web3-eth/src/eth_tx.ts | 35 +++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 2bed5ea9196..0d7748dcf9d 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -1,6 +1,14 @@ import { EthExecutionAPI } from 'web3-common'; import { Web3Context } from 'web3-core'; -import { BlockTags, convertToValidType, HexString, Numbers, toHex, ValidTypes } from 'web3-utils'; +import { + BlockTags, + convertToValidType, + HexString, + Numbers, + toHex, + ValidReturnTypes, + ValidTypes, +} from 'web3-utils'; import { privateKeyToAddress } from 'web3-eth-accounts'; import Web3Eth from '.'; @@ -21,12 +29,12 @@ import { UnsupportedFeeMarketError, UnsupportedTransactionTypeError, } from './errors'; -import { Transaction } from './types'; +import { PopulatedUnsignedTransaction, Transaction } from './types'; -export function formatTransaction( - transaction: Transaction, - desiredType: DesiredType, -): Transaction { +export function formatTransaction< + DesiredType extends ValidTypes, + NumberType extends ValidReturnTypes[DesiredType] = ValidReturnTypes[DesiredType], +>(transaction: Transaction, desiredType: DesiredType): Transaction { const formattedTransaction = { ...transaction }; if (formattedTransaction.value !== undefined) formattedTransaction.value = @@ -81,7 +89,7 @@ export function formatTransaction( } } - return formattedTransaction as Transaction; + return formattedTransaction as Transaction; } export const detectTransactionType = ( @@ -219,12 +227,15 @@ export const validateTransactionForSigning = ( }); }; -export async function populateTransaction( +export async function populateTransaction< + DesiredType extends ValidTypes, + NumberType extends ValidReturnTypes[DesiredType] = ValidReturnTypes[DesiredType], +>( transaction: Transaction, web3Context: Web3Context, desiredType: DesiredType, privateKey?: HexString, -) { +): Promise> { const populatedTransaction = { ...transaction }; const web3Eth = new Web3Eth(web3Context.currentProvider); @@ -314,7 +325,11 @@ export async function populateTransaction( } } - return formatTransaction(populatedTransaction, desiredType); + // TODO - Types of property 'gasPrice' are incompatible + return formatTransaction( + populatedTransaction, + desiredType, + ) as unknown as PopulatedUnsignedTransaction; } // TODO - Replace use of Web3Context with Web3Eth From 307d7b3a88cc905c746c50dd99342d2b79e845ca Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 24 Jan 2022 01:25:13 -1000 Subject: [PATCH 039/132] Convert to deep copy for formatTransaction method --- packages/web3-eth/src/eth_tx.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 0d7748dcf9d..bfdd9a30c27 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -35,7 +35,17 @@ export function formatTransaction< DesiredType extends ValidTypes, NumberType extends ValidReturnTypes[DesiredType] = ValidReturnTypes[DesiredType], >(transaction: Transaction, desiredType: DesiredType): Transaction { - const formattedTransaction = { ...transaction }; + // TODO - The spread operator performs a shallow copy of transaction. + // I tried using Object.assign({}, transaction) which is supposed to perform a deep copy, + // but format_transactions.test.ts were still failing due to original object properties + // being wrongfully updated by this method. + const formattedTransaction = { + ...transaction, + common: { + ...transaction.common, + customChain: { ...transaction.common?.customChain }, + }, + }; if (formattedTransaction.value !== undefined) formattedTransaction.value = formattedTransaction.value === '0x' From d505d1e150de2effa82c5dd127dd7d7486e30c83 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 24 Jan 2022 01:25:49 -1000 Subject: [PATCH 040/132] skip override method test - needs to be refactored. General formatting --- .../test/unit/format_transaction.test.ts | 68 +++++++++++-------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/packages/web3-eth/test/unit/format_transaction.test.ts b/packages/web3-eth/test/unit/format_transaction.test.ts index 06e91b482f5..e27c0a3d45f 100644 --- a/packages/web3-eth/test/unit/format_transaction.test.ts +++ b/packages/web3-eth/test/unit/format_transaction.test.ts @@ -8,77 +8,89 @@ import { } from '../fixtures/format_transaction'; describe('formatTransaction', () => { - it('should call override method', () => { - const overrideFunction = jest.fn(); - formatTransaction(hexStringTransaction, ValidTypes.Number, overrideFunction); - expect(overrideFunction).toHaveBeenCalledWith(hexStringTransaction); + it.skip('should call override method', () => { + // const overrideFunction = jest.fn(); + // formatTransaction(hexStringTransaction, ValidTypes.Number, overrideFunction); + // expect(overrideFunction).toHaveBeenCalledWith(hexStringTransaction); }); describe('should convert hex string properties to expected type', () => { it('numbers', () => { - const result = formatTransaction(hexStringTransaction, ValidTypes.Number); - expect(result).toStrictEqual(numberTransaction); + expect(formatTransaction(hexStringTransaction, ValidTypes.Number)).toStrictEqual( + numberTransaction, + ); }); it('number strings', () => { - const result = formatTransaction(hexStringTransaction, ValidTypes.NumberString); - expect(result).toStrictEqual(numberStringTransaction); + expect(formatTransaction(hexStringTransaction, ValidTypes.NumberString)).toStrictEqual( + numberStringTransaction, + ); }); it('BigInts', () => { - const result = formatTransaction(hexStringTransaction, ValidTypes.BigInt); - expect(result).toStrictEqual(bigIntTransaction); + expect(formatTransaction(hexStringTransaction, ValidTypes.BigInt)).toStrictEqual( + bigIntTransaction, + ); }); }); describe('should convert number properties to expected type', () => { it('hex string', () => { - const result = formatTransaction(numberTransaction, ValidTypes.HexString); - expect(result).toStrictEqual(hexStringTransaction); + expect(formatTransaction(numberTransaction, ValidTypes.HexString)).toStrictEqual( + hexStringTransaction, + ); }); it('number strings', () => { - const result = formatTransaction(numberTransaction, ValidTypes.NumberString); - expect(result).toStrictEqual(numberStringTransaction); + expect(formatTransaction(numberTransaction, ValidTypes.NumberString)).toStrictEqual( + numberStringTransaction, + ); }); it('BigInts', () => { - const result = formatTransaction(numberTransaction, ValidTypes.BigInt); - expect(result).toStrictEqual(bigIntTransaction); + expect(formatTransaction(numberTransaction, ValidTypes.BigInt)).toStrictEqual( + bigIntTransaction, + ); }); }); describe('should convert number string properties to expected type', () => { it('hex strings', () => { - const result = formatTransaction(numberStringTransaction, ValidTypes.HexString); - expect(result).toStrictEqual(hexStringTransaction); + expect(formatTransaction(numberStringTransaction, ValidTypes.HexString)).toStrictEqual( + hexStringTransaction, + ); }); it('numbers', () => { - const result = formatTransaction(numberStringTransaction, ValidTypes.Number); - expect(result).toStrictEqual(numberTransaction); + expect(formatTransaction(numberStringTransaction, ValidTypes.Number)).toStrictEqual( + numberTransaction, + ); }); it('BigInts', () => { - const result = formatTransaction(numberStringTransaction, ValidTypes.BigInt); - expect(result).toStrictEqual(bigIntTransaction); + expect(formatTransaction(numberStringTransaction, ValidTypes.BigInt)).toStrictEqual( + bigIntTransaction, + ); }); }); describe('should convert bigint properties to expected type', () => { it('hex strings', () => { - const result = formatTransaction(bigIntTransaction, ValidTypes.HexString); - expect(result).toStrictEqual(hexStringTransaction); + expect(formatTransaction(bigIntTransaction, ValidTypes.HexString)).toStrictEqual( + hexStringTransaction, + ); }); it('numbers', () => { - const result = formatTransaction(bigIntTransaction, ValidTypes.Number); - expect(result).toStrictEqual(numberTransaction); + expect(formatTransaction(bigIntTransaction, ValidTypes.Number)).toStrictEqual( + numberTransaction, + ); }); it('number strings', () => { - const result = formatTransaction(bigIntTransaction, ValidTypes.NumberString); - expect(result).toStrictEqual(numberStringTransaction); + expect(formatTransaction(bigIntTransaction, ValidTypes.NumberString)).toStrictEqual( + numberStringTransaction, + ); }); }); }); From 7caa46f863fcb32932c340f7eae91bcc79c9b87e Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 24 Jan 2022 01:26:20 -1000 Subject: [PATCH 041/132] Skip override method test - needs to be refactored. Set input.type > 0x7f --- .../test/unit/populate_transaction.test.ts | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/web3-eth/test/unit/populate_transaction.test.ts b/packages/web3-eth/test/unit/populate_transaction.test.ts index b47ccdc4529..b72d41cfd7a 100644 --- a/packages/web3-eth/test/unit/populate_transaction.test.ts +++ b/packages/web3-eth/test/unit/populate_transaction.test.ts @@ -103,17 +103,17 @@ describe('populateTransaction', () => { web3Context = new Web3Context(new HttpProvider('http://127.0.0.1')); }); - it('should call override method', async () => { - const overrideFunction = jest.fn(); - const input = { ...transaction }; - await populateTransaction( - input, - web3Context, - ValidTypes.HexString, - '0x348ce564d427a3311b6536bbcff9390d69395b06ed6c486954e971d960fe8709', - overrideFunction, - ); - expect(overrideFunction).toHaveBeenCalledWith(input); + it.skip('should call override method', async () => { + // const overrideFunction = jest.fn(); + // const input = { ...transaction }; + // await populateTransaction( + // input, + // web3Context, + // ValidTypes.HexString, + // '0x348ce564d427a3311b6536bbcff9390d69395b06ed6c486954e971d960fe8709', + // overrideFunction, + // ); + // expect(overrideFunction).toHaveBeenCalledWith(input); }); describe('should populate from', () => { @@ -259,7 +259,7 @@ describe('populateTransaction', () => { it('should throw UnsupportedTransactionTypeError', async () => { const input = { ...transaction }; - input.type = '0x4'; + input.type = '0x8'; // // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2718.md#transactions await expect( populateTransaction(input, web3Context, ValidTypes.HexString), From 6aec094556a93a6a8b34e6aee20ac8298a32c91b Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 24 Jan 2022 19:58:58 -1000 Subject: [PATCH 042/132] Refactor formatTransaction --- packages/web3-eth/src/eth_tx.ts | 67 ++++++++++++++------------------- 1 file changed, 29 insertions(+), 38 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index bfdd9a30c27..d5e4d7e1f2d 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -46,44 +46,35 @@ export function formatTransaction< customChain: { ...transaction.common?.customChain }, }, }; - if (formattedTransaction.value !== undefined) - formattedTransaction.value = - formattedTransaction.value === '0x' - ? '0x' - : convertToValidType(formattedTransaction.value, desiredType); - if (formattedTransaction.gas !== undefined) - formattedTransaction.gas = convertToValidType(formattedTransaction.gas, desiredType); - if (formattedTransaction.gasPrice !== undefined) - formattedTransaction.gasPrice = convertToValidType( - formattedTransaction.gasPrice, - desiredType, - ); - if (formattedTransaction.type !== undefined) - formattedTransaction.type = convertToValidType(formattedTransaction.type, desiredType); - if (formattedTransaction.maxFeePerGas !== undefined) - formattedTransaction.maxFeePerGas = convertToValidType( - formattedTransaction.maxFeePerGas, - desiredType, - ); - if (formattedTransaction.maxPriorityFeePerGas !== undefined) - formattedTransaction.maxPriorityFeePerGas = convertToValidType( - formattedTransaction.maxPriorityFeePerGas, - desiredType, - ); - if (formattedTransaction.nonce !== undefined) - formattedTransaction.nonce = convertToValidType(formattedTransaction.nonce, desiredType); - if (formattedTransaction.chainId !== undefined) - formattedTransaction.chainId = convertToValidType( - formattedTransaction.chainId, - desiredType, - ); - if (formattedTransaction.gasLimit !== undefined) - formattedTransaction.gasLimit = convertToValidType( - formattedTransaction.gasLimit, - desiredType, - ); - if (formattedTransaction.v !== undefined) - formattedTransaction.v = convertToValidType(formattedTransaction.v, desiredType); + + const formattableProperties: (keyof Transaction)[] = [ + 'value', + 'gas', + 'gasPrice', + 'type', + 'maxFeePerGas', + 'maxPriorityFeePerGas', + 'nonce', + 'chainId', + 'gasLimit', + 'v', + ]; + for (const transactionProperty of formattableProperties) { + const formattedProperty = formattedTransaction[transactionProperty]; + if ( + formattedProperty !== undefined && + formattedProperty !== null && + typeof formattedProperty !== 'object' && + !Array.isArray(formattedProperty) + ) { + if (transactionProperty === 'value' && formattedProperty === '0x') continue; + (formattedTransaction[transactionProperty] as Numbers) = convertToValidType( + formattedProperty, + desiredType, + ); + } + } + if (formattedTransaction.common !== undefined) { if (formattedTransaction.common.customChain !== undefined) { if (formattedTransaction.common.customChain.networkId !== undefined) From 3fce2e919bbb9315ff13dc49f875db9dcf64e144 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 24 Jan 2022 20:36:33 -1000 Subject: [PATCH 043/132] Add error codes to web3-eth errors --- packages/web3-common/src/constants.ts | 18 +++++++++ packages/web3-eth/src/errors.ts | 53 +++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/packages/web3-common/src/constants.ts b/packages/web3-common/src/constants.ts index e0d663b316c..d1ff6630433 100644 --- a/packages/web3-common/src/constants.ts +++ b/packages/web3-common/src/constants.ts @@ -31,6 +31,24 @@ export const ERR_TX_REVERT_WITHOUT_REASON = 405; export const ERR_TX_OUT_OF_GAS = 406; export const ERR_RAW_TX_UNDEFINED = 407; +export const ERR_TX_INVALID_SENDER = 408; +export const ERR_TX_INVALID_CALL = 409; +export const ERR_TX_MISSING_CUSTOM_CHAIN = 410; +export const ERR_TX_MISSING_CUSTOM_CHAIN_ID = 411; +export const ERR_TX_CHAIN_ID_MISMATCH = 412; +export const ERR_TX_INVALID_CHAIN_INFO = 413; +export const ERR_TX_MISSING_CHAIN_INFO = 414; +export const ERR_TX_MISSING_GAS = 415; +export const ERR_TX_INVALID_LEGACY_GAS = 416; +export const ERR_TX_INVALID_FEE_MARKET_GAS = 417; +export const ERR_TX_INVALID_FEE_MARKET_GAS_PRICE = 418; +export const ERR_TX_INVALID_LEGACY_FEE_MARKET = 419; +export const ERR_TX_INVALID_OBJECT = 420; +export const ERR_TX_INVALID_NONCE_OR_CHAIN_ID = 421; +export const ERR_TX_UNABLE_TO_POPULATE_NONCE = 422; +export const ERR_TX_UNSUPPORTED_EIP_1559 = 423; +export const ERR_TX_UNSUPPORTED_TYPE = 424; + // Connection error codes export const ERR_CONN = 500; export const ERR_CONN_INVALID = 501; diff --git a/packages/web3-eth/src/errors.ts b/packages/web3-eth/src/errors.ts index 41301b6ced7..483d58fa9c8 100644 --- a/packages/web3-eth/src/errors.ts +++ b/packages/web3-eth/src/errors.ts @@ -1,20 +1,45 @@ /* eslint-disable max-classes-per-file */ +import { ERR_TX_MISSING_GAS } from 'web3-common'; +import { ERR_TX_INVALID_FEE_MARKET_GAS } from 'web3-common'; +import { ERR_TX_INVALID_LEGACY_FEE_MARKET } from 'web3-common'; +import { ERR_TX_INVALID_NONCE_OR_CHAIN_ID } from 'web3-common'; +import { ERR_TX_UNSUPPORTED_EIP_1559 } from 'web3-common'; +import { ERR_TX_UNSUPPORTED_TYPE } from 'web3-common'; +import { ERR_TX_UNABLE_TO_POPULATE_NONCE } from 'web3-common'; +import { ERR_TX_INVALID_OBJECT } from 'web3-common'; +import { ERR_TX_INVALID_FEE_MARKET_GAS_PRICE } from 'web3-common'; +import { ERR_TX_INVALID_LEGACY_GAS } from 'web3-common'; +import { + ERR_TX_CHAIN_ID_MISMATCH, + ERR_TX_INVALID_CALL, + ERR_TX_INVALID_CHAIN_INFO, + ERR_TX_INVALID_SENDER, + ERR_TX_MISSING_CHAIN_INFO, + ERR_TX_MISSING_CUSTOM_CHAIN, + ERR_TX_MISSING_CUSTOM_CHAIN_ID, +} from 'web3-common'; import { Numbers, Web3Error } from 'web3-utils'; export class InvalidTransactionWithSender extends Web3Error { + public code = ERR_TX_INVALID_SENDER; + public constructor(value: unknown) { super(JSON.stringify(value), 'invalid transaction with sender'); } } export class InvalidTransactionCall extends Web3Error { + public code = ERR_TX_INVALID_CALL; + public constructor(value: unknown) { super(JSON.stringify(value), 'invalid transaction call'); } } export class MissingCustomChainError extends Web3Error { + public code = ERR_TX_MISSING_CUSTOM_CHAIN; + public constructor() { super( 'MissingCustomChainError', @@ -24,6 +49,8 @@ export class MissingCustomChainError extends Web3Error { } export class MissingCustomChainIdError extends Web3Error { + public code = ERR_TX_MISSING_CUSTOM_CHAIN_ID; + public constructor() { super( 'MissingCustomChainIdError', @@ -33,6 +60,8 @@ export class MissingCustomChainIdError extends Web3Error { } export class ChainIdMismatchError extends Web3Error { + public code = ERR_TX_CHAIN_ID_MISMATCH; + public constructor(value: { txChainId: unknown; customChainId: unknown }) { super( JSON.stringify(value), @@ -42,6 +71,8 @@ export class ChainIdMismatchError extends Web3Error { } export class CommonOrChainAndHardforkError extends Web3Error { + public code = ERR_TX_INVALID_CHAIN_INFO; + public constructor() { super( 'CommonOrChainAndHardforkError', @@ -51,6 +82,8 @@ export class CommonOrChainAndHardforkError extends Web3Error { } export class MissingChainOrHardforkError extends Web3Error { + public code = ERR_TX_MISSING_CHAIN_INFO; + public constructor(value: { chain: string | undefined; hardfork: string | undefined }) { super( 'MissingChainOrHardforkError', @@ -62,6 +95,8 @@ export class MissingChainOrHardforkError extends Web3Error { } export class MissingGasError extends Web3Error { + public code = ERR_TX_MISSING_GAS; + public constructor(value: { gas: Numbers | undefined; gasLimit: Numbers | undefined; @@ -80,6 +115,8 @@ export class MissingGasError extends Web3Error { } export class InvalidGasOrGasPrice extends Web3Error { + 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'}`, @@ -89,6 +126,8 @@ export class InvalidGasOrGasPrice extends Web3Error { } export class InvalidMaxPriorityFeePerGasOrMaxFeePerGas extends Web3Error { + public code = ERR_TX_INVALID_FEE_MARKET_GAS; + public constructor(value: { maxPriorityFeePerGas: Numbers | undefined; maxFeePerGas: Numbers | undefined; @@ -103,12 +142,16 @@ export class InvalidMaxPriorityFeePerGasOrMaxFeePerGas extends Web3Error { } export class Eip1559GasPriceError extends Web3Error { + 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 Web3Error { + public code = ERR_TX_INVALID_LEGACY_FEE_MARKET; + public constructor(value: { maxPriorityFeePerGas: Numbers | undefined; maxFeePerGas: Numbers | undefined; @@ -123,12 +166,16 @@ export class UnsupportedFeeMarketError extends Web3Error { } export class InvalidTransactionObjectError extends Web3Error { + public code = ERR_TX_INVALID_OBJECT; + public constructor(value: unknown) { super(value, 'invalid transaction object'); } } export class InvalidNonceOrChainIdError extends Web3Error { + 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'}`, @@ -138,18 +185,24 @@ export class InvalidNonceOrChainIdError extends Web3Error { } export class UnableToPopulateNonceError extends Web3Error { + public code = ERR_TX_UNABLE_TO_POPULATE_NONCE; + public constructor() { super('UnableToPopulateNonceError', 'unable to populate nonce, no from address available'); } } export class Eip1559NotSupportedError extends Web3Error { + public code = ERR_TX_UNSUPPORTED_EIP_1559; + public constructor() { super('Eip1559NotSupportedError', "Network doesn't support eip-1559"); } } export class UnsupportedTransactionTypeError extends Web3Error { + public code = ERR_TX_UNSUPPORTED_TYPE; + public constructor(value: unknown) { super(value, 'unsupported transaction type'); } From cd0ffb08cdfbb98ac72ec7066533baa6e30ec60b Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 24 Jan 2022 22:20:54 -1000 Subject: [PATCH 044/132] Refactor validateGate if statements into readable consts --- packages/web3-eth/src/eth_tx.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index d5e4d7e1f2d..dd0d15ce947 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -147,12 +147,11 @@ const validateChainInfo = (transaction: Transaction) => { // TODO Split into validateEipXXX methods const validateGas = (transaction: Transaction) => { - if ( - transaction.gas === undefined && - transaction.gasLimit === undefined && - transaction.maxPriorityFeePerGas === undefined && - transaction.maxFeePerGas === undefined - ) + const legacyGasPresent = transaction.gas === undefined && transaction.gasLimit === undefined; + const feeMarketGasPresent = + transaction.maxPriorityFeePerGas === undefined && transaction.maxFeePerGas === undefined; + + if (!legacyGasPresent && !feeMarketGasPresent) throw new MissingGasError({ gas: transaction.gas, gasLimit: transaction.gasLimit, @@ -160,7 +159,7 @@ const validateGas = (transaction: Transaction) => { maxFeePerGas: transaction.maxFeePerGas, }); - if (transaction.gas !== undefined || transaction.gasPrice !== undefined) { + if (legacyGasPresent) { if ( // This check is verifying gas and gasPrice aren't less than 0. // transaction's number properties have been converted to HexStrings. From c393ea62555877a70b48c4fca37d78f14dd91c41 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 24 Jan 2022 22:24:14 -1000 Subject: [PATCH 045/132] Update comment --- packages/web3-eth/src/eth_tx.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index dd0d15ce947..a28a821cfde 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -37,7 +37,7 @@ export function formatTransaction< >(transaction: Transaction, desiredType: DesiredType): Transaction { // TODO - The spread operator performs a shallow copy of transaction. // I tried using Object.assign({}, transaction) which is supposed to perform a deep copy, - // but format_transactions.test.ts were still failing due to original object properties + // but format_transactions.test.ts were still failing due to original nested object properties // being wrongfully updated by this method. const formattedTransaction = { ...transaction, From dd78824ea5043272a392aeea8055f484adeb7645 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 24 Jan 2022 23:09:31 -1000 Subject: [PATCH 046/132] Add link to error message from 1.x --- packages/web3-eth/src/errors.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/web3-eth/src/errors.ts b/packages/web3-eth/src/errors.ts index 483d58fa9c8..c922176d27b 100644 --- a/packages/web3-eth/src/errors.ts +++ b/packages/web3-eth/src/errors.ts @@ -65,6 +65,7 @@ export class ChainIdMismatchError extends Web3Error { 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', ); } From c06a8fa030fa31aa13b94334bb9857e81a55c1f3 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 24 Jan 2022 23:09:52 -1000 Subject: [PATCH 047/132] Fix bug with is gas consts in validateGas --- packages/web3-eth/src/eth_tx.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index a28a821cfde..4529a4c2487 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -147,9 +147,9 @@ const validateChainInfo = (transaction: Transaction) => { // TODO Split into validateEipXXX methods const validateGas = (transaction: Transaction) => { - const legacyGasPresent = transaction.gas === undefined && transaction.gasLimit === undefined; + const legacyGasPresent = transaction.gas !== undefined && transaction.gasLimit !== undefined; const feeMarketGasPresent = - transaction.maxPriorityFeePerGas === undefined && transaction.maxFeePerGas === undefined; + transaction.maxPriorityFeePerGas !== undefined && transaction.maxFeePerGas !== undefined; if (!legacyGasPresent && !feeMarketGasPresent) throw new MissingGasError({ From 8a2eeead7de66d020186205f53b2075f54ba73c8 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 24 Jan 2022 23:10:10 -1000 Subject: [PATCH 048/132] Init InvalidConvertibleValueError --- packages/web3-utils/src/errors.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/web3-utils/src/errors.ts b/packages/web3-utils/src/errors.ts index 122bbbc66b9..9d3439bb2ae 100644 --- a/packages/web3-utils/src/errors.ts +++ b/packages/web3-utils/src/errors.ts @@ -108,3 +108,9 @@ export class InvalidConvertiblePropertiesListError extends Web3Error { super(value, 'invalid list of convertible properties for conversion given'); } } + +export class InvalidConvertibleValueError extends Web3Error { + public constructor() { + super(undefined, 'cannot convert undefined'); + } +} From f70ac6e75ce794d4958cb6bce21e4fa35ecec428 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 24 Jan 2022 23:11:21 -1000 Subject: [PATCH 049/132] Replace error with InvalidConvertibleValueError --- packages/web3-utils/src/converters.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/web3-utils/src/converters.ts b/packages/web3-utils/src/converters.ts index 8251b9514de..f28075b06c8 100644 --- a/packages/web3-utils/src/converters.ts +++ b/packages/web3-utils/src/converters.ts @@ -10,6 +10,7 @@ import { InvalidDesiredTypeError, InvalidConvertibleObjectError, InvalidConvertiblePropertiesListError, + InvalidConvertibleValueError, } from './errors'; import { Address, @@ -442,8 +443,7 @@ export const convertToValidType = ( value: ValidReturnTypes[ValidTypes], // validate this desiredType: ValidTypes, ) => { - // TODO - Replace error - if (value === undefined) throw new Error('value is undefined'); + if (value === undefined) throw new InvalidConvertibleValueError(); switch (desiredType) { case ValidTypes.HexString: From 2be1e66a94248e3c146c5f48cd60d15889cdba7e Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 24 Jan 2022 23:11:41 -1000 Subject: [PATCH 050/132] Update tests for formatting undefined --- packages/web3-utils/test/fixtures/converters.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/web3-utils/test/fixtures/converters.ts b/packages/web3-utils/test/fixtures/converters.ts index b88bae51514..a042c18865b 100644 --- a/packages/web3-utils/test/fixtures/converters.ts +++ b/packages/web3-utils/test/fixtures/converters.ts @@ -3,6 +3,7 @@ import { InvalidConvertibleObjectError, InvalidConvertiblePropertiesListError, InvalidDesiredTypeError, + InvalidConvertibleValueError, } from '../../src/errors'; import { Address, @@ -265,9 +266,9 @@ export const toCheckSumValidData: [string, string][] = [ ]; export const convertToValidTypeValidData: [ - ValidReturnTypes[ValidTypes] | undefined, + ValidReturnTypes[ValidTypes], ValidTypes, - ValidReturnTypes[ValidTypes] | undefined, + ValidReturnTypes[ValidTypes], ][] = [ ['0x2a', ValidTypes.HexString, '0x2a'], ['42', ValidTypes.HexString, '0x2a'], @@ -301,10 +302,13 @@ export const convertToValidTypeValidData: [ ['-42', ValidTypes.BigInt, BigInt('-42')], [-42, ValidTypes.BigInt, BigInt('-42')], [BigInt('-42'), ValidTypes.BigInt, BigInt('-42')], - [undefined, ValidTypes.HexString, undefined], ]; -export const convertToValidTypeInvalidData: [any, any, InvalidDesiredTypeError | string][] = [ +export const convertToValidTypeInvalidData: [ + any, + any, + InvalidDesiredTypeError | InvalidConvertibleValueError | string, +][] = [ ['0x2a', 'hexString', new InvalidDesiredTypeError('hexString')], ['0x2a', 'qwerty', new InvalidDesiredTypeError('qwerty')], ['0x2a', 42, new InvalidDesiredTypeError(42)], @@ -315,6 +319,7 @@ export const convertToValidTypeInvalidData: [any, any, InvalidDesiredTypeError | ['4.2', ValidTypes.HexString, 'value "4.2" at "/0" must pass "int" validation'], [null, ValidTypes.HexString, 'value at "/0" must pass "int" validation'], [true, ValidTypes.HexString, 'value "true" at "/0" must pass "int" validation'], + [undefined, ValidTypes.HexString, new InvalidConvertibleValueError()], ]; export const convertObjectPropertiesToValidTypeValidData: [ From 4b387714bcd2e4349450b6ea1d0c47c314f957da Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 24 Jan 2022 23:11:58 -1000 Subject: [PATCH 051/132] Update expected errors for validateGas tests --- .../fixtures/validate_transaction_for_signing.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) 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 7390ccea592..6da7b2943f1 100644 --- a/packages/web3-eth/test/fixtures/validate_transaction_for_signing.ts +++ b/packages/web3-eth/test/fixtures/validate_transaction_for_signing.ts @@ -395,7 +395,12 @@ export const validateGasData: [ r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', }, - new InvalidGasOrGasPrice({ gas: undefined, gasPrice: '0x4a817c800' }), + new MissingGasError({ + gas: undefined, + gasLimit: '0x5208', + maxFeePerGas: undefined, + maxPriorityFeePerGas: undefined, + }), ], [ { @@ -454,7 +459,9 @@ export const validateGasData: [ r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', }, - new InvalidMaxPriorityFeePerGasOrMaxFeePerGas({ + new MissingGasError({ + gas: undefined, + gasLimit: '0x5208', maxPriorityFeePerGas: undefined, maxFeePerGas: '0x1229298c00', }), @@ -476,7 +483,9 @@ export const validateGasData: [ r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', }, - new InvalidMaxPriorityFeePerGasOrMaxFeePerGas({ + new MissingGasError({ + gas: undefined, + gasLimit: '0x5208', maxPriorityFeePerGas: '0x49504f80', maxFeePerGas: undefined, }), From 741fa8c2f6e14133112b234c3285574ed050a72d Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 24 Jan 2022 23:51:03 -1000 Subject: [PATCH 052/132] No longer default tx.type if undefined --- packages/web3-eth/src/eth_tx.ts | 70 +++++++++---------- .../test/unit/populate_transaction.test.ts | 17 ----- 2 files changed, 34 insertions(+), 53 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 4529a4c2487..c2507cc6e85 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -281,47 +281,45 @@ export async function populateTransaction< populatedTransaction.type = detectTransactionType(populatedTransaction); // TODO - After web3Context.defaultTxType is implemented - if (populatedTransaction.type === undefined) populatedTransaction.type = '0x0'; // web3Context.defaultTxType; + // if (populatedTransaction.type === undefined) populatedTransaction.type = '0x0'; // web3Context.defaultTxType; - // TODO Probably need to account for negative hex strings - const hexTxType = toHex(populatedTransaction.type); + if (populatedTransaction.type !== undefined) { + // TODO Probably need to account for negative hex strings + const hexTxType = toHex(populatedTransaction.type); - if (hexTxType < '0x0' || hexTxType > '0x7f') - // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2718.md#transactions - throw new UnsupportedTransactionTypeError(populatedTransaction.type); + if (hexTxType < '0x0' || hexTxType > '0x7f') + // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2718.md#transactions + throw new UnsupportedTransactionTypeError(populatedTransaction.type); - if (hexTxType === '0x0' || hexTxType === '0x1') { - // transaction.type not supported before Berlin hardfork - // TODO - Maybe add check for populatedTransaction.hardfork >= Berlin before deleting - // if (hexTxType === '0x0') populatedTransaction.type = undefined; - - if (populatedTransaction.gasPrice === undefined) - populatedTransaction.gasPrice = await web3Eth.getGasPrice(); - } + if (hexTxType === '0x0' || hexTxType === '0x1') { + if (populatedTransaction.gasPrice === undefined) + populatedTransaction.gasPrice = await web3Eth.getGasPrice(); + } - if (hexTxType === '0x1' || hexTxType === '0x2') { - if (populatedTransaction.accessList === undefined) populatedTransaction.accessList = []; - } + if (hexTxType === '0x1' || hexTxType === '0x2') { + if (populatedTransaction.accessList === undefined) populatedTransaction.accessList = []; + } - if (hexTxType === '0x2') { - const block = await web3Eth.getBlock(); - - // Unless otherwise specified by web3Context.defaultBlock, this defaults to latest - if (block.baseFeePerGas === undefined) throw new Eip1559NotSupportedError(); - - if (populatedTransaction.gasPrice !== undefined) { - // Logic from 1.x - populatedTransaction.maxPriorityFeePerGas = populatedTransaction.gasPrice; - populatedTransaction.maxFeePerGas = populatedTransaction.gasPrice; - populatedTransaction.gasPrice = undefined; - } else { - if (populatedTransaction.maxPriorityFeePerGas === undefined) - // TODO - Add maxPriorityFeePerGas default to Web3Context - populatedTransaction.maxPriorityFeePerGas = toHex(2500000000); // 2.5 Gwei - if (populatedTransaction.maxFeePerGas === undefined) - populatedTransaction.maxFeePerGas = - BigInt(block.baseFeePerGas) * BigInt(2) + - BigInt(populatedTransaction.maxPriorityFeePerGas); + if (hexTxType === '0x2') { + const block = await web3Eth.getBlock(); + + // Unless otherwise specified by web3Context.defaultBlock, this defaults to latest + if (block.baseFeePerGas === undefined) throw new Eip1559NotSupportedError(); + + if (populatedTransaction.gasPrice !== undefined) { + // Logic from 1.x + populatedTransaction.maxPriorityFeePerGas = populatedTransaction.gasPrice; + populatedTransaction.maxFeePerGas = populatedTransaction.gasPrice; + populatedTransaction.gasPrice = undefined; + } else { + if (populatedTransaction.maxPriorityFeePerGas === undefined) + // TODO - Add maxPriorityFeePerGas default to Web3Context + populatedTransaction.maxPriorityFeePerGas = toHex(2500000000); // 2.5 Gwei + if (populatedTransaction.maxFeePerGas === undefined) + populatedTransaction.maxFeePerGas = + BigInt(block.baseFeePerGas) * BigInt(2) + + BigInt(populatedTransaction.maxPriorityFeePerGas); + } } } diff --git a/packages/web3-eth/test/unit/populate_transaction.test.ts b/packages/web3-eth/test/unit/populate_transaction.test.ts index b72d41cfd7a..18dcd21c07c 100644 --- a/packages/web3-eth/test/unit/populate_transaction.test.ts +++ b/packages/web3-eth/test/unit/populate_transaction.test.ts @@ -240,23 +240,6 @@ describe('populateTransaction', () => { }); describe('should populate type', () => { - it('should populate with 0x0', async () => { - const input = { ...transaction }; - delete input.type; - - // Used by detectTransactionType - delete input.maxFeePerGas; - delete input.maxPriorityFeePerGas; - delete input.common?.hardfork; - delete input.accessList; - // detectTransactionType will automatically set type to 0x2 for london - // and 0x1 for berlin, so manually setting to something it doesn't handle yet - input.hardfork = 'merge'; - - const result = await populateTransaction(input, web3Context, ValidTypes.HexString); - expect(result.type).toBe('0x0'); - }); - it('should throw UnsupportedTransactionTypeError', async () => { const input = { ...transaction }; input.type = '0x8'; // // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2718.md#transactions From 07f5cd7bfbb70669da922f80d962705fa1a0b9d6 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Tue, 25 Jan 2022 19:35:52 -1000 Subject: [PATCH 053/132] Refactor detectTransactionType --- packages/web3-eth/src/eth_tx.ts | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index c2507cc6e85..1117603039c 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -95,19 +95,27 @@ export function formatTransaction< export const detectTransactionType = ( transaction: Transaction, - overrideMethod?: (transaction: Transaction) => Numbers | undefined, -): Numbers | undefined => { + overrideMethod?: (transaction: Transaction) => HexString | undefined, +): HexString | undefined => { + // TODO - Refactor overrideMethod if (overrideMethod !== undefined) return overrideMethod(transaction); - if (transaction.type !== undefined) return transaction.type; + if (transaction.type !== undefined) + return convertToValidType(transaction.type, ValidTypes.HexString); - if (transaction.maxFeePerGas !== undefined || transaction.maxPriorityFeePerGas !== undefined) + if ( + transaction.maxFeePerGas !== undefined || + transaction.maxPriorityFeePerGas !== undefined || + transaction.hardfork === 'london' || + transaction.common?.hardfork === 'london' + ) return '0x2'; - if (transaction.hardfork === 'london') return '0x2'; - if (transaction.common?.hardfork === 'london') return '0x2'; - if (transaction.accessList !== undefined) return '0x1'; - if (transaction.hardfork === 'berlin') return '0x1'; - if (transaction.common?.hardfork === 'berlin') return '0x1'; + if ( + transaction.accessList !== undefined || + transaction.hardfork === 'berlin' || + transaction.common?.hardfork === 'berlin' + ) + return '0x1'; return undefined; }; From cb6e7eb2efcb01129e24d8ff53e0dcbbe66e2794 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Tue, 25 Jan 2022 21:39:01 -1000 Subject: [PATCH 054/132] Fix type error for return in detectTransactionType --- packages/web3-eth/src/eth_tx.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 1117603039c..c710b99629e 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -100,7 +100,7 @@ export const detectTransactionType = ( // TODO - Refactor overrideMethod if (overrideMethod !== undefined) return overrideMethod(transaction); if (transaction.type !== undefined) - return convertToValidType(transaction.type, ValidTypes.HexString); + return convertToValidType(transaction.type, ValidTypes.HexString) as HexString; if ( transaction.maxFeePerGas !== undefined || @@ -337,5 +337,3 @@ export async function populateTransaction< desiredType, ) as unknown as PopulatedUnsignedTransaction; } - -// TODO - Replace use of Web3Context with Web3Eth From 0ea5d7b20f3e36660a69da22baf5c32659e4d740 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Tue, 25 Jan 2022 21:45:23 -1000 Subject: [PATCH 055/132] Init rpc_method_wrappers.ts --- packages/web3-eth/src/errors.ts | 21 +- packages/web3-eth/src/index.ts | 235 +++--------- packages/web3-eth/src/rpc_method_wrappers.ts | 383 +++++++++++++++++++ 3 files changed, 441 insertions(+), 198 deletions(-) create mode 100644 packages/web3-eth/src/rpc_method_wrappers.ts diff --git a/packages/web3-eth/src/errors.ts b/packages/web3-eth/src/errors.ts index c922176d27b..fd81b3f1ee2 100644 --- a/packages/web3-eth/src/errors.ts +++ b/packages/web3-eth/src/errors.ts @@ -1,15 +1,4 @@ /* eslint-disable max-classes-per-file */ - -import { ERR_TX_MISSING_GAS } from 'web3-common'; -import { ERR_TX_INVALID_FEE_MARKET_GAS } from 'web3-common'; -import { ERR_TX_INVALID_LEGACY_FEE_MARKET } from 'web3-common'; -import { ERR_TX_INVALID_NONCE_OR_CHAIN_ID } from 'web3-common'; -import { ERR_TX_UNSUPPORTED_EIP_1559 } from 'web3-common'; -import { ERR_TX_UNSUPPORTED_TYPE } from 'web3-common'; -import { ERR_TX_UNABLE_TO_POPULATE_NONCE } from 'web3-common'; -import { ERR_TX_INVALID_OBJECT } from 'web3-common'; -import { ERR_TX_INVALID_FEE_MARKET_GAS_PRICE } from 'web3-common'; -import { ERR_TX_INVALID_LEGACY_GAS } from 'web3-common'; import { ERR_TX_CHAIN_ID_MISMATCH, ERR_TX_INVALID_CALL, @@ -18,6 +7,16 @@ import { 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, } from 'web3-common'; import { Numbers, Web3Error } from 'web3-utils'; diff --git a/packages/web3-eth/src/index.ts b/packages/web3-eth/src/index.ts index b5bd205ac9a..be56dde1b63 100644 --- a/packages/web3-eth/src/index.ts +++ b/packages/web3-eth/src/index.ts @@ -6,29 +6,18 @@ import { SupportedProviders, Web3ConfigOptions, Web3Context } from 'web3-core'; import { BlockNumberOrTag, ValidTypes, - ValidReturnTypes, - convertToValidType, Address, Uint256, HexString32Bytes, HexStringBytes, Uint, HexString8Bytes, - convertObjectPropertiesToValidType, Filter, } from 'web3-utils'; -import { isHexString32Bytes } from 'web3-validator'; // import { Transaction, BlockFormatted } from './types'; import { BlockFormatted } from './types'; -import { - convertibleBlockProperties, - convertibleFeeHistoryResultProperties, - convertibleReceiptInfoProperties, - convertibleTransactionInfoProperties, -} from './convertible_properties'; - -import * as rpcMethods from './rpc_methods'; +import * as rpcMethodsWrappers from './rpc_method_wrappers'; export default class Web3Eth { public readonly web3Context: Web3Context; @@ -41,74 +30,49 @@ export default class Web3Eth { } public async getProtocolVersion() { - return rpcMethods.getProtocolVersion(this.web3Context.requestManager); + return rpcMethodsWrappers.getProtocolVersion(this.web3Context); } public async isSyncing() { - return rpcMethods.getSyncing(this.web3Context.requestManager); + return rpcMethodsWrappers.isSyncing(this.web3Context); } public async getCoinbase() { - return rpcMethods.getCoinbase(this.web3Context.requestManager); + return rpcMethodsWrappers.getCoinbase(this.web3Context); } public async isMining() { - return rpcMethods.getMining(this.web3Context.requestManager); + return rpcMethodsWrappers.isMining(this.web3Context); } public async getHashRate( returnType?: ReturnType, ) { - const response = await rpcMethods.getHashRate(this.web3Context.requestManager); - - return convertToValidType( - response, - returnType ?? this.web3Context.defaultReturnType, - ) as ValidReturnTypes[ReturnType]; + return rpcMethodsWrappers.getHashRate(this.web3Context, returnType); } public async getGasPrice( returnType?: ReturnType, ) { - const response = await rpcMethods.getGasPrice(this.web3Context.requestManager); - - return convertToValidType( - response, - returnType ?? this.web3Context.defaultReturnType, - ) as ValidReturnTypes[ReturnType]; + return rpcMethodsWrappers.getGasPrice(this.web3Context, returnType); } public async getAccounts() { - return rpcMethods.getAccounts(this.web3Context.requestManager); + return rpcMethodsWrappers.getAccounts(this.web3Context); } public async getBlockNumber( returnType?: ReturnType, ) { - const response = await rpcMethods.getBlockNumber(this.web3Context.requestManager); - - return convertToValidType( - response, - returnType ?? this.web3Context.defaultReturnType, - ) as ValidReturnTypes[ReturnType]; + return rpcMethodsWrappers.getBlockNumber(this.web3Context, returnType); } - // TODO Discuss the use of multiple optional parameters public async getBalance( address: Address, blockNumber: BlockNumberOrTag = this.web3Context.defaultBlock, returnType?: ReturnType, ) { - const response = await rpcMethods.getBalance( - this.web3Context.requestManager, - address, - blockNumber, - ); - - return convertToValidType( - response, - returnType ?? this.web3Context.defaultReturnType, - ) as ValidReturnTypes[ReturnType]; + return rpcMethodsWrappers.getBalance(this.web3Context, address, blockNumber, returnType); } public async getStorageAt( @@ -116,73 +80,38 @@ export default class Web3Eth { storageSlot: Uint256, blockNumber: BlockNumberOrTag = this.web3Context.defaultBlock, ) { - return rpcMethods.getStorageAt( - this.web3Context.requestManager, - address, - storageSlot, - blockNumber, - ); + return rpcMethodsWrappers.getStorageAt(this.web3Context, address, storageSlot, blockNumber); } public async getCode( address: Address, blockNumber: BlockNumberOrTag = this.web3Context.defaultBlock, ) { - return rpcMethods.getCode(this.web3Context.requestManager, address, blockNumber); + return rpcMethodsWrappers.getCode(this.web3Context, address, blockNumber); } - // TODO Discuss the use of multiple optional parameters + // TODO - Should this.web3Context.defaultBlock still be used? Or should rpcMethodsWrappers handle defaults? + // Or vice verse public async getBlock( block: HexString32Bytes | BlockNumberOrTag = this.web3Context.defaultBlock, hydrated = false, returnType?: ReturnType, ): Promise> { - const response = isHexString32Bytes(block) - ? await rpcMethods.getBlockByHash(this.web3Context.requestManager, block, hydrated) - : await rpcMethods.getBlockByNumber(this.web3Context.requestManager, block, hydrated); - - // @ts-expect-error Having a problem determining if BlockFormatted is correct type - return convertObjectPropertiesToValidType( - response, - convertibleBlockProperties, - returnType ?? this.web3Context.defaultReturnType, - ); + return rpcMethodsWrappers.getBlock(this.web3Context, block, hydrated, returnType); } - // TODO Discuss the use of multiple optional parameters public async getBlockTransactionCount( block: HexString32Bytes | BlockNumberOrTag = this.web3Context.defaultBlock, returnType?: ReturnType, ) { - const response = isHexString32Bytes(block) - ? await rpcMethods.getBlockTransactionCountByHash( - this.web3Context.requestManager, - block, - ) - : await rpcMethods.getBlockTransactionCountByNumber( - this.web3Context.requestManager, - block, - ); - - return convertToValidType( - response, - returnType ?? this.web3Context.defaultReturnType, - ) as ValidReturnTypes[ReturnType]; + return rpcMethodsWrappers.getBlockTransactionCount(this.web3Context, block, returnType); } - // TODO Discuss the use of multiple optional parameters public async getBlockUncleCount( block: HexString32Bytes | BlockNumberOrTag = this.web3Context.defaultBlock, returnType?: ReturnType, ) { - const response = isHexString32Bytes(block) - ? await rpcMethods.getUncleCountByBlockHash(this.web3Context.requestManager, block) - : await rpcMethods.getUncleCountByBlockNumber(this.web3Context.requestManager, block); - - return convertToValidType( - response, - returnType ?? this.web3Context.defaultReturnType, - ) as ValidReturnTypes[ReturnType]; + return rpcMethodsWrappers.getBlockUncleCount(this.web3Context, block, returnType); } public async getUncle( @@ -190,135 +119,76 @@ export default class Web3Eth { uncleIndex: Uint, returnType?: ReturnType, ): Promise> { - const response = isHexString32Bytes(block) - ? await rpcMethods.getUncleByBlockHashAndIndex( - this.web3Context.requestManager, - block, - uncleIndex, - ) - : await rpcMethods.getUncleByBlockNumberAndIndex( - this.web3Context.requestManager, - block, - uncleIndex, - ); - - // @ts-expect-error Having a problem determining if BlockFormatted is correct type - return convertObjectPropertiesToValidType( - response, - convertibleBlockProperties, - returnType ?? this.web3Context.defaultReturnType, - ); + return rpcMethodsWrappers.getUncle(this.web3Context, block, uncleIndex, returnType); } public async getTransaction( transactionHash: HexString32Bytes, returnType?: ReturnType, ) { - const response = await rpcMethods.getTransactionByHash( - this.web3Context.requestManager, - transactionHash, - ); - - return response === null - ? response - : convertObjectPropertiesToValidType( - response, - // TODO - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-expect-error - convertibleTransactionInfoProperties, - returnType ?? this.web3Context.defaultReturnType, - ); + return rpcMethodsWrappers.getTransaction(this.web3Context, transactionHash, returnType); } - // // TODO Can't find in spec - // // public async getPendingTransactions() { + // TODO Can't find in spec + // public async getPendingTransactions() { - // // } + // } public async getTransactionFromBlock( block: HexString32Bytes | BlockNumberOrTag = this.web3Context.defaultBlock, transactionIndex: Uint, returnType?: ReturnType, ) { - const response = isHexString32Bytes(block) - ? await rpcMethods.getTransactionByBlockHashAndIndex( - this.web3Context.requestManager, - block, - transactionIndex, - ) - : await rpcMethods.getTransactionByBlockNumberAndIndex( - this.web3Context.requestManager, - block, - transactionIndex, - ); - - return response === null - ? response - : convertObjectPropertiesToValidType( - response, - // TODO - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-expect-error - convertibleTransactionInfoProperties, - returnType ?? this.web3Context.defaultReturnType, - ); + return rpcMethodsWrappers.getTransactionFromBlock( + this.web3Context, + block, + transactionIndex, + returnType, + ); } public async getTransactionReceipt( transactionHash: HexString32Bytes, returnType?: ReturnType, ) { - const response = await rpcMethods.getTransactionReceipt( - this.web3Context.requestManager, + return rpcMethodsWrappers.getTransactionReceipt( + this.web3Context, transactionHash, + returnType, ); - - return response === null - ? response - : convertObjectPropertiesToValidType( - response, - convertibleReceiptInfoProperties, - returnType ?? this.web3Context.defaultReturnType, - ); } - // TODO Discuss the use of multiple optional parameters public async getTransactionCount( address: Address, blockNumber: BlockNumberOrTag = this.web3Context.defaultBlock, returnType?: ReturnType, ) { - const response = await rpcMethods.getTransactionCount( - this.web3Context.requestManager, + return rpcMethodsWrappers.getTransactionCount( + this.web3Context, address, blockNumber, + returnType, ); - - return convertToValidType( - response, - returnType ?? this.web3Context.defaultReturnType, - ) as ValidReturnTypes[ReturnType]; } // TODO Needs to convert input to hex string // public async sendTransaction(transaction: Transaction) { - // return rpcMethods.sendTransaction(this.web3Context.requestManager, transaction); + // return rpcMethodsWrappers.sendTransaction(this.web3Context, transaction); // } public async sendSignedTransaction(transaction: HexStringBytes) { - return rpcMethods.sendRawTransaction(this.web3Context.requestManager, transaction); + return rpcMethodsWrappers.sendSignedTransaction(this.web3Context, transaction); } // TODO address can be an address or the index of a local wallet in web3.eth.accounts.wallet // https://web3js.readthedocs.io/en/v1.5.2/web3-eth.html?highlight=sendTransaction#sign public async sign(message: HexStringBytes, address: Address) { - return rpcMethods.sign(this.web3Context.requestManager, address, message); + return rpcMethodsWrappers.sign(this.web3Context, message, address); } // TODO Needs to convert input to hex string // public async signTransaction(transaction: Transaction) { - // return rpcMethods.signTransaction(this.web3Context.requestManager, transaction); + // return rpcMethodsWrappers.signTransaction(this.web3Context, transaction); // } // TODO Decide what to do with transaction.to @@ -327,7 +197,7 @@ export default class Web3Eth { // transaction: Transaction & { to: Address }, // blockNumber: BlockNumberOrTag = this.web3Context.defaultBlock, // ) { - // return rpcMethods.call(this.web3Context.requestManager, transaction, blockNumber); + // return rpcMethodsWrappers.call(this.web3Context, transaction, blockNumber); // } // TODO Missing param @@ -336,20 +206,16 @@ export default class Web3Eth { blockNumber: BlockNumberOrTag = this.web3Context.defaultBlock, returnType?: ReturnType, ) { - const response = await rpcMethods.estimateGas( - this.web3Context.requestManager, + return rpcMethodsWrappers.estimateGas( + this.web3Context, transaction, blockNumber, + returnType, ); - - return convertToValidType( - response, - returnType ?? this.web3Context.defaultReturnType, - ) as ValidReturnTypes[ReturnType]; } public async getPastLogs(filter: Filter) { - return rpcMethods.getLogs(this.web3Context.requestManager, { + return rpcMethodsWrappers.getPastLogs(this.web3Context, { ...filter, // These defaults are carried over from 1.x // https://web3js.readthedocs.io/en/v1.5.2/web3-eth.html?highlight=sendTransaction#getpastlogs @@ -359,7 +225,7 @@ export default class Web3Eth { } public async getWork() { - return rpcMethods.getWork(this.web3Context.requestManager); + return rpcMethodsWrappers.getWork(this.web3Context); } public async submitWork( @@ -367,7 +233,7 @@ export default class Web3Eth { seedHash: HexString32Bytes, difficulty: HexString32Bytes, ) { - return rpcMethods.submitWork(this.web3Context.requestManager, nonce, seedHash, difficulty); + return rpcMethodsWrappers.submitWork(this.web3Context, nonce, seedHash, difficulty); } // // TODO @@ -396,17 +262,12 @@ export default class Web3Eth { rewardPercentiles: number[], returnType?: ReturnType, ) { - const response = await rpcMethods.getFeeHistory( - this.web3Context.requestManager, + return rpcMethodsWrappers.getFeeHistory( + this.web3Context, blockCount, newestBlock, rewardPercentiles, - ); - - return convertObjectPropertiesToValidType( - response, - convertibleFeeHistoryResultProperties, - returnType ?? this.web3Context.defaultReturnType, + returnType, ); } } diff --git a/packages/web3-eth/src/rpc_method_wrappers.ts b/packages/web3-eth/src/rpc_method_wrappers.ts new file mode 100644 index 00000000000..65a6986a3cf --- /dev/null +++ b/packages/web3-eth/src/rpc_method_wrappers.ts @@ -0,0 +1,383 @@ +// Disabling because returnTypes must be last param to match 1.x params +/* eslint-disable default-param-last */ + +import { EthExecutionAPI, TransactionWithSender } from 'web3-common'; +import { Web3Context } from 'web3-core'; +import { + Address, + BlockNumberOrTag, + convertObjectPropertiesToValidType, + convertToValidType, + Filter, + HexString32Bytes, + HexString8Bytes, + HexStringBytes, + Uint, + Uint256, + ValidReturnTypes, + ValidTypes, +} from 'web3-utils'; +import { isHexString32Bytes } from 'web3-validator'; +import { + convertibleBlockProperties, + convertibleFeeHistoryResultProperties, + convertibleReceiptInfoProperties, +} from './convertible_properties'; + +import * as rpcMethods from './rpc_methods'; +import { BlockFormatted } from './types'; + +export const getProtocolVersion = async (web3Context: Web3Context) => + rpcMethods.getProtocolVersion(web3Context.requestManager); +export const isSyncing = async (web3Context: Web3Context) => + rpcMethods.getSyncing(web3Context.requestManager); +export const getCoinbase = async (web3Context: Web3Context) => + rpcMethods.getCoinbase(web3Context.requestManager); +export const isMining = async (web3Context: Web3Context) => + rpcMethods.getMining(web3Context.requestManager); + +export async function getHashRate( + web3Context: Web3Context, + returnType?: ReturnType, +) { + const response = await rpcMethods.getHashRate(web3Context.requestManager); + + return convertToValidType( + response, + returnType ?? web3Context.defaultReturnType, + ) as ValidReturnTypes[ReturnType]; +} + +export async function getGasPrice( + web3Context: Web3Context, + returnType?: ReturnType, +) { + const response = await rpcMethods.getGasPrice(web3Context.requestManager); + + return convertToValidType( + response, + returnType ?? web3Context.defaultReturnType, + ) as ValidReturnTypes[ReturnType]; +} + +export const getAccounts = async (web3Context: Web3Context) => + rpcMethods.getAccounts(web3Context.requestManager); + +export async function getBlockNumber( + web3Context: Web3Context, + returnType?: ReturnType, +) { + const response = await rpcMethods.getBlockNumber(web3Context.requestManager); + + return convertToValidType( + response, + returnType ?? web3Context.defaultReturnType, + ) as ValidReturnTypes[ReturnType]; +} + +export async function getBalance( + web3Context: Web3Context, + address: Address, + blockNumber: BlockNumberOrTag = web3Context.defaultBlock, + returnType?: ReturnType, +) { + const response = await rpcMethods.getBalance(web3Context.requestManager, address, blockNumber); + + return convertToValidType( + response, + returnType ?? web3Context.defaultReturnType, + ) as ValidReturnTypes[ReturnType]; +} + +export const getStorageAt = async ( + web3Context: Web3Context, + address: Address, + storageSlot: Uint256, + blockNumber: BlockNumberOrTag = web3Context.defaultBlock, +) => rpcMethods.getStorageAt(web3Context.requestManager, address, storageSlot, blockNumber); + +export const getCode = async ( + web3Context: Web3Context, + address: Address, + blockNumber: BlockNumberOrTag = web3Context.defaultBlock, +) => rpcMethods.getCode(web3Context.requestManager, address, blockNumber); + +export async function getBlock( + web3Context: Web3Context, + block: HexString32Bytes | BlockNumberOrTag = web3Context.defaultBlock, + hydrated = false, + returnType?: ReturnType, +): Promise> { + const response = isHexString32Bytes(block) + ? await rpcMethods.getBlockByHash(web3Context.requestManager, block, hydrated) + : await rpcMethods.getBlockByNumber(web3Context.requestManager, block, hydrated); + + // @ts-expect-error Having a problem determining if BlockFormatted is correct type + return convertObjectPropertiesToValidType( + response, + convertibleBlockProperties, + returnType ?? web3Context.defaultReturnType, + ); +} + +export async function getBlockTransactionCount< + ReturnType extends ValidTypes = ValidTypes.HexString, +>( + web3Context: Web3Context, + block: HexString32Bytes | BlockNumberOrTag = web3Context.defaultBlock, + returnType?: ReturnType, +) { + const response = isHexString32Bytes(block) + ? await rpcMethods.getBlockTransactionCountByHash(web3Context.requestManager, block) + : await rpcMethods.getBlockTransactionCountByNumber(web3Context.requestManager, block); + + return convertToValidType( + response, + returnType ?? web3Context.defaultReturnType, + ) as ValidReturnTypes[ReturnType]; +} + +export async function getBlockUncleCount( + web3Context: Web3Context, + block: HexString32Bytes | BlockNumberOrTag = web3Context.defaultBlock, + returnType?: ReturnType, +) { + const response = isHexString32Bytes(block) + ? await rpcMethods.getUncleCountByBlockHash(web3Context.requestManager, block) + : await rpcMethods.getUncleCountByBlockNumber(web3Context.requestManager, block); + + return convertToValidType( + response, + returnType ?? web3Context.defaultReturnType, + ) as ValidReturnTypes[ReturnType]; +} + +export async function getUncle( + web3Context: Web3Context, + block: HexString32Bytes | BlockNumberOrTag = web3Context.defaultBlock, + uncleIndex: Uint, + returnType?: ReturnType, +): Promise> { + const response = isHexString32Bytes(block) + ? await rpcMethods.getUncleByBlockHashAndIndex( + web3Context.requestManager, + block, + uncleIndex, + ) + : await rpcMethods.getUncleByBlockNumberAndIndex( + web3Context.requestManager, + block, + uncleIndex, + ); + + // @ts-expect-error Having a problem determining if BlockFormatted is correct type + return convertObjectPropertiesToValidType( + response, + convertibleBlockProperties, + returnType ?? web3Context.defaultReturnType, + ); +} + +export async function getTransaction( + web3Context: Web3Context, + transactionHash: HexString32Bytes, + returnType?: ReturnType, +) { + const response = await rpcMethods.getTransactionByHash( + web3Context.requestManager, + transactionHash, + ); + + return response === null + ? response + : convertObjectPropertiesToValidType( + response, + // TODO + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + convertibleTransactionInfoProperties, + returnType ?? web3Context.defaultReturnType, + ); +} + +// TODO Can't find in spec +// export async function getPendingTransactions() { +// } + +export async function getTransactionFromBlock( + web3Context: Web3Context, + block: HexString32Bytes | BlockNumberOrTag = web3Context.defaultBlock, + transactionIndex: Uint, + returnType?: ReturnType, +) { + const response = isHexString32Bytes(block) + ? await rpcMethods.getTransactionByBlockHashAndIndex( + web3Context.requestManager, + block, + transactionIndex, + ) + : await rpcMethods.getTransactionByBlockNumberAndIndex( + web3Context.requestManager, + block, + transactionIndex, + ); + + return response === null + ? response + : convertObjectPropertiesToValidType( + response, + // TODO + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + convertibleTransactionInfoProperties, + returnType ?? web3Context.defaultReturnType, + ); +} + +export async function getTransactionReceipt( + web3Context: Web3Context, + transactionHash: HexString32Bytes, + returnType?: ReturnType, +) { + const response = await rpcMethods.getTransactionReceipt( + web3Context.requestManager, + transactionHash, + ); + + return response === null + ? response + : convertObjectPropertiesToValidType( + response, + convertibleReceiptInfoProperties, + returnType ?? web3Context.defaultReturnType, + ); +} + +export async function getTransactionCount( + web3Context: Web3Context, + address: Address, + blockNumber: BlockNumberOrTag = web3Context.defaultBlock, + returnType?: ReturnType, +) { + const response = await rpcMethods.getTransactionCount( + web3Context.requestManager, + address, + blockNumber, + ); + + return convertToValidType( + response, + returnType ?? web3Context.defaultReturnType, + ) as ValidReturnTypes[ReturnType]; +} + +// TODO Needs to convert input to hex string +// public async sendTransaction(transaction: Transaction) { +// return rpcMethods.sendTransaction(this.web3Context.requestManager, transaction); +// } + +export const sendSignedTransaction = async ( + web3Context: Web3Context, + transaction: HexStringBytes, +) => rpcMethods.sendRawTransaction(web3Context.requestManager, transaction); + +// TODO address can be an address or the index of a local wallet in web3.eth.accounts.wallet +// https://web3js.readthedocs.io/en/v1.5.2/web3-eth.html?highlight=sendTransaction#sign +export const sign = async ( + web3Context: Web3Context, + message: HexStringBytes, + address: Address, +) => rpcMethods.sign(web3Context.requestManager, address, message); + +// TODO Needs to convert input to hex string +// public async signTransaction(transaction: Transaction) { +// return rpcMethods.signTransaction(this.web3Context.requestManager, transaction); +// } + +// TODO Decide what to do with transaction.to +// https://github.com/ChainSafe/web3.js/pull/4525#issuecomment-982330076 +// public async call( +// transaction: Transaction & { to: Address }, +// blockNumber: BlockNumberOrTag = this.web3Context.defaultBlock, +// ) { +// return rpcMethods.call(this.web3Context.requestManager, transaction, blockNumber); +// } + +// TODO Missing param +export async function estimateGas( + web3Context: Web3Context, + transaction: Partial, + blockNumber: BlockNumberOrTag = web3Context.defaultBlock, + returnType?: ReturnType, +) { + const response = await rpcMethods.estimateGas( + web3Context.requestManager, + transaction, + blockNumber, + ); + + return convertToValidType( + response, + returnType ?? web3Context.defaultReturnType, + ) as ValidReturnTypes[ReturnType]; +} + +export const getPastLogs = async (web3Context: Web3Context, filter: Filter) => + rpcMethods.getLogs(web3Context.requestManager, { + ...filter, + // These defaults are carried over from 1.x + // https://web3js.readthedocs.io/en/v1.5.2/web3-eth.html?highlight=sendTransaction#getpastlogs + fromBlock: filter.fromBlock ?? web3Context.defaultBlock, + toBlock: filter.toBlock ?? web3Context.defaultBlock, + }); + +export const getWork = async (web3Context: Web3Context) => + rpcMethods.getWork(web3Context.requestManager); + +export const submitWork = async ( + web3Context: Web3Context, + nonce: HexString8Bytes, + seedHash: HexString32Bytes, + difficulty: HexString32Bytes, +) => rpcMethods.submitWork(web3Context.requestManager, nonce, seedHash, difficulty); + +// TODO +// public async requestAccounts() { + +// } + +// TODO +// public async getChainId() { + +// } + +// TODO +// public async getNodeInfo() { + +// } + +// TODO +// public async getProof() { + +// } + +export async function getFeeHistory( + web3Context: Web3Context, + blockCount: Uint, + newestBlock: BlockNumberOrTag = web3Context.defaultBlock, + rewardPercentiles: number[], + returnType?: ReturnType, +) { + const response = await rpcMethods.getFeeHistory( + web3Context.requestManager, + blockCount, + newestBlock, + rewardPercentiles, + ); + + return convertObjectPropertiesToValidType( + response, + convertibleFeeHistoryResultProperties, + returnType ?? web3Context.defaultReturnType, + ); +} From 27c5087e06e9b44122acbd863234d6bd32634810 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Tue, 25 Jan 2022 22:45:19 -1000 Subject: [PATCH 056/132] Remove Web3Eth import --- packages/web3-eth/src/eth_tx.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index c710b99629e..4f7c408e57d 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -11,7 +11,6 @@ import { } from 'web3-utils'; import { privateKeyToAddress } from 'web3-eth-accounts'; -import Web3Eth from '.'; import { ChainIdMismatchError, CommonOrChainAndHardforkError, @@ -30,6 +29,7 @@ import { UnsupportedTransactionTypeError, } from './errors'; import { PopulatedUnsignedTransaction, Transaction } from './types'; +import { getBlock, getGasPrice, getTransactionCount } from './rpc_method_wrappers'; export function formatTransaction< DesiredType extends ValidTypes, @@ -245,7 +245,6 @@ export async function populateTransaction< privateKey?: HexString, ): Promise> { const populatedTransaction = { ...transaction }; - const web3Eth = new Web3Eth(web3Context.currentProvider); if (populatedTransaction.from === undefined) { if (privateKey !== undefined) { @@ -257,7 +256,8 @@ export async function populateTransaction< if (populatedTransaction.nonce === undefined) { if (populatedTransaction.from === undefined) throw new UnableToPopulateNonceError(); - populatedTransaction.nonce = await web3Eth.getTransactionCount( + populatedTransaction.nonce = await getTransactionCount( + web3Context, populatedTransaction.from, BlockTags.PENDING, ); @@ -301,7 +301,7 @@ export async function populateTransaction< if (hexTxType === '0x0' || hexTxType === '0x1') { if (populatedTransaction.gasPrice === undefined) - populatedTransaction.gasPrice = await web3Eth.getGasPrice(); + populatedTransaction.gasPrice = await getGasPrice(web3Context); } if (hexTxType === '0x1' || hexTxType === '0x2') { @@ -309,7 +309,7 @@ export async function populateTransaction< } if (hexTxType === '0x2') { - const block = await web3Eth.getBlock(); + const block = await getBlock(web3Context); // Unless otherwise specified by web3Context.defaultBlock, this defaults to latest if (block.baseFeePerGas === undefined) throw new Eip1559NotSupportedError(); From 025bcc5b038dbe5c2f11887d73d36a28a7d945aa Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Tue, 25 Jan 2022 22:45:45 -1000 Subject: [PATCH 057/132] Refactor use of web3Context.defaults --- packages/web3-eth/src/rpc_method_wrappers.ts | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/web3-eth/src/rpc_method_wrappers.ts b/packages/web3-eth/src/rpc_method_wrappers.ts index 65a6986a3cf..8169dd224d6 100644 --- a/packages/web3-eth/src/rpc_method_wrappers.ts +++ b/packages/web3-eth/src/rpc_method_wrappers.ts @@ -22,6 +22,7 @@ import { convertibleBlockProperties, convertibleFeeHistoryResultProperties, convertibleReceiptInfoProperties, + convertibleTransactionInfoProperties, } from './convertible_properties'; import * as rpcMethods from './rpc_methods'; @@ -29,10 +30,13 @@ import { BlockFormatted } from './types'; export const getProtocolVersion = async (web3Context: Web3Context) => rpcMethods.getProtocolVersion(web3Context.requestManager); + export const isSyncing = async (web3Context: Web3Context) => rpcMethods.getSyncing(web3Context.requestManager); + export const getCoinbase = async (web3Context: Web3Context) => rpcMethods.getCoinbase(web3Context.requestManager); + export const isMining = async (web3Context: Web3Context) => rpcMethods.getMining(web3Context.requestManager); @@ -206,19 +210,20 @@ export async function getTransaction( web3Context: Web3Context, - block: HexString32Bytes | BlockNumberOrTag = web3Context.defaultBlock, + block: HexString32Bytes | BlockNumberOrTag | undefined, transactionIndex: Uint, returnType?: ReturnType, ) { - const response = isHexString32Bytes(block) + const blockOrDefault = block ?? web3Context.defaultBlock; + const response = isHexString32Bytes(blockOrDefault) ? await rpcMethods.getTransactionByBlockHashAndIndex( web3Context.requestManager, - block, + blockOrDefault, transactionIndex, ) : await rpcMethods.getTransactionByBlockNumberAndIndex( web3Context.requestManager, - block, + blockOrDefault, transactionIndex, ); @@ -256,13 +261,13 @@ export async function getTransactionReceipt( web3Context: Web3Context, address: Address, - blockNumber: BlockNumberOrTag = web3Context.defaultBlock, + blockNumber: BlockNumberOrTag | undefined, returnType?: ReturnType, ) { const response = await rpcMethods.getTransactionCount( web3Context.requestManager, address, - blockNumber, + blockNumber ?? web3Context.defaultBlock, ); return convertToValidType( From ec02b6ffe35943612fcf9561031b5e7101f6fe52 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Tue, 25 Jan 2022 22:46:08 -1000 Subject: [PATCH 058/132] Restore Formatted transaction types --- packages/web3-eth/src/types.ts | 80 ++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/packages/web3-eth/src/types.ts b/packages/web3-eth/src/types.ts index 24f25ed3d98..7fc303acbfb 100644 --- a/packages/web3-eth/src/types.ts +++ b/packages/web3-eth/src/types.ts @@ -8,6 +8,7 @@ import { HexString32Bytes, HexString256Bytes, HexStringBytes, + Uint, } from 'web3-utils'; export type chain = 'goerli' | 'kovan' | 'mainnet' | 'rinkeby' | 'ropsten' | 'sepolia'; @@ -92,6 +93,85 @@ export type PopulatedUnsignedTransaction = | PopulatedUnsignedEip2930Transaction | PopulatedUnsignedEip1559Transaction; +interface BaseTransactionFormatted< + DesiredType extends ValidTypes = ValidTypes.HexString, + ReturnType = ValidReturnTypes[DesiredType], +> { + readonly to?: Address | null; + readonly type: ReturnType; + readonly nonce: ReturnType; + readonly gas: ReturnType; + readonly value: ReturnType; + readonly input: HexStringBytes; +} + +interface Transaction1559UnsignedFormatted< + DesiredType extends ValidTypes = ValidTypes.HexString, + ReturnType = ValidReturnTypes[DesiredType], +> extends BaseTransactionFormatted { + readonly maxFeePerGas: ReturnType; + readonly maxPriorityFeePerGas: ReturnType; + readonly accessList: AccessList; +} + +interface Transaction1559SignedFormatted< + DesiredType extends ValidTypes = ValidTypes.HexString, + ReturnType = ValidReturnTypes[DesiredType], +> extends Transaction1559UnsignedFormatted { + readonly yParity: ReturnType; + readonly r: ReturnType; + readonly s: ReturnType; +} + +interface Transaction2930UnsignedFormatted< + DesiredType extends ValidTypes = ValidTypes.HexString, + ReturnType = ValidReturnTypes[DesiredType], +> extends BaseTransactionFormatted { + readonly gasPrice: ReturnType; + readonly accessList: AccessList; +} + +interface Transaction2930SignedFormatted< + DesiredType extends ValidTypes = ValidTypes.HexString, + ReturnType = ValidReturnTypes[DesiredType], +> extends Transaction2930UnsignedFormatted { + readonly yParity: ReturnType; + readonly r: ReturnType; + readonly s: ReturnType; +} + +interface TransactionLegacyUnsignedFormatted< + DesiredType extends ValidTypes = ValidTypes.HexString, + ReturnType = ValidReturnTypes[DesiredType], +> extends BaseTransactionFormatted { + readonly gasPrice: ReturnType; +} + +interface TransactionLegacySignedFormatted< + DesiredType extends ValidTypes = ValidTypes.HexString, + ReturnType = ValidReturnTypes[DesiredType], +> extends TransactionLegacyUnsignedFormatted { + readonly v: ReturnType; + readonly r: Uint; + readonly s: Uint; +} + +type TransactionSignedFormatted = + | Transaction1559SignedFormatted + | Transaction2930SignedFormatted + | TransactionLegacySignedFormatted; + +export type TransactionInfoFormatted< + DesiredType extends ValidTypes = ValidTypes.HexString, + ReturnType = ValidReturnTypes[DesiredType], +> = TransactionSignedFormatted & { + readonly blockHash: HexString32Bytes | null; + readonly blockNumber: ReturnType | null; + readonly from: Address; + readonly hash: HexString32Bytes; + readonly transactionIndex: ReturnType | null; +}; + export interface ReceiptInfoFormatted< DesiredType extends ValidTypes = ValidTypes.HexString, ReturnType = ValidReturnTypes[DesiredType], From c5c40a0eff926de5b895b915e369a0ae427ffec5 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Tue, 25 Jan 2022 22:46:25 -1000 Subject: [PATCH 059/132] Init web3_rpc_method_wrappers tests --- ..._rpc_method_wrappers_no_parameters.test.ts | 54 +++ ...pc_method_wrappers_with_parameters.test.ts | 447 ++++++++++++++++++ 2 files changed, 501 insertions(+) create mode 100644 packages/web3-eth/test/unit/web3_rpc_method_wrappers_no_parameters.test.ts create mode 100644 packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts diff --git a/packages/web3-eth/test/unit/web3_rpc_method_wrappers_no_parameters.test.ts b/packages/web3-eth/test/unit/web3_rpc_method_wrappers_no_parameters.test.ts new file mode 100644 index 00000000000..b017ad4f1e0 --- /dev/null +++ b/packages/web3-eth/test/unit/web3_rpc_method_wrappers_no_parameters.test.ts @@ -0,0 +1,54 @@ +import Web3Eth from '../../src/index'; +import * as rpcMethods from '../../src/rpc_methods'; +import { + getAccounts, + getCoinbase, + getProtocolVersion, + getWork, + isMining, + isSyncing, +} from '../../src/rpc_method_wrappers'; + +jest.mock('../../src/rpc_methods'); + +describe('web3_eth_methods_no_parameters', () => { + let web3Eth: Web3Eth; + + beforeAll(() => { + web3Eth = new Web3Eth('http://127.0.0.1:8545'); + }); + + describe('should call RPC method with only request manager parameter', () => { + it('getProtocolVersion', async () => { + await getProtocolVersion(web3Eth.web3Context); + expect(rpcMethods.getProtocolVersion).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, + ); + }); + + it('isSyncing', async () => { + await isSyncing(web3Eth.web3Context); + expect(rpcMethods.getSyncing).toHaveBeenCalledWith(web3Eth.web3Context.requestManager); + }); + + it('getCoinbase', async () => { + await getCoinbase(web3Eth.web3Context); + expect(rpcMethods.getCoinbase).toHaveBeenCalledWith(web3Eth.web3Context.requestManager); + }); + + it('isMining', async () => { + await isMining(web3Eth.web3Context); + expect(rpcMethods.getMining).toHaveBeenCalledWith(web3Eth.web3Context.requestManager); + }); + + it('getAccounts', async () => { + await getAccounts(web3Eth.web3Context); + expect(rpcMethods.getAccounts).toHaveBeenCalledWith(web3Eth.web3Context.requestManager); + }); + + it('getWork', async () => { + await getWork(web3Eth.web3Context); + expect(rpcMethods.getWork).toHaveBeenCalledWith(web3Eth.web3Context.requestManager); + }); + }); +}); diff --git a/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts b/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts new file mode 100644 index 00000000000..76cd1f34eb0 --- /dev/null +++ b/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts @@ -0,0 +1,447 @@ +/* eslint-disable import/namespace */ + +import Web3Eth from '../../src/index'; +import * as rpcMethods from '../../src/rpc_methods'; +import { + estimateGas, + getBalance, + getBlock, + getBlockNumber, + getBlockTransactionCount, + getBlockUncleCount, + getCode, + getFeeHistory, + getGasPrice, + getHashRate, + getPastLogs, + getStorageAt, + getTransaction, + getTransactionCount, + getTransactionFromBlock, + getTransactionReceipt, + getUncle, + sendSignedTransaction, + sign, + submitWork, +} from '../../src/rpc_method_wrappers'; +import { + estimateGasValidData, + getBalanceValidData, + getBlockNumberValidData, + getBlockTransactionCountValidData, + getBlockUncleCountValidData, + getBlockValidData, + getCodeValidData, + getFeeHistoryValidData, + getGasPriceValidData, + getHashRateValidData, + getPastLogsValidData, + getStorageAtValidData, + getTransactionCountValidData, + getTransactionFromBlockValidData, + getTransactionReceiptValidData, + getTransactionValidData, + getUncleValidData, + sendSignedTransactionValidData, + signValidData, + submitWorkValidData, +} from '../fixtures/web3_eth_methods'; + +jest.mock('../../src/rpc_methods'); + +describe('web3_eth_methods_with_parameters', () => { + let web3Eth: Web3Eth; + + beforeAll(() => { + web3Eth = new Web3Eth('http://127.0.0.1:8545'); + }); + + describe('should call RPC method with expected parameters', () => { + describe('only has returnType parameter', () => { + describe('getHashRate', () => { + it.each(getHashRateValidData)( + 'returnType: %s mockRpcResponse: %s output: %s', + async (returnType, mockRpcResponse, output) => { + (rpcMethods.getHashRate as jest.Mock).mockResolvedValueOnce( + mockRpcResponse, + ); + expect(await getHashRate(web3Eth.web3Context, returnType)).toBe(output); + expect(rpcMethods.getHashRate).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, + ); + }, + ); + }); + + describe('getGasPrice', () => { + it.each(getGasPriceValidData)( + 'returnType: %s mockRpcResponse: %s output: %s', + async (returnType, mockRpcResponse, output) => { + (rpcMethods.getGasPrice as jest.Mock).mockResolvedValueOnce( + mockRpcResponse, + ); + expect(await getGasPrice(web3Eth.web3Context, returnType)).toBe(output); + expect(rpcMethods.getGasPrice).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, + ); + }, + ); + }); + + describe('getBlockNumber', () => { + it.each(getBlockNumberValidData)( + 'returnType: %s mockRpcResponse: %s output: %s', + async (returnType, mockRpcResponse, output) => { + (rpcMethods.getBlockNumber as jest.Mock).mockResolvedValueOnce( + mockRpcResponse, + ); + expect(await getBlockNumber(web3Eth.web3Context, returnType)).toBe(output); + expect(rpcMethods.getBlockNumber).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, + ); + }, + ); + }); + }); + + describe('has multiple parameters', () => { + describe('has returnType parameter', () => { + describe('getBalance', () => { + it.each(getBalanceValidData)( + 'input: %s\nmockRpcResponse: %s\nrpcMethodParameters: %s\noutput: %s', + async (input, mockRpcResponse, rpcMethodParameters, output) => { + (rpcMethods.getBalance as jest.Mock).mockResolvedValueOnce( + mockRpcResponse, + ); + expect(await getBalance(web3Eth.web3Context, ...input)).toBe(output); + expect(rpcMethods.getBalance).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, + ...rpcMethodParameters, + ); + }, + ); + }); + + describe('getBlock', () => { + it.each(getBlockValidData)( + 'input: %s\nmockRpcResponse: %s\nexpectedRpcMethodToBeCalled: %s\nrpcMethodParameters: %s\noutput: %s', + async ( + input, + mockRpcResponse, + expectedRpcMethodToBeCalled, + rpcMethodParameters, + output, + ) => { + ( + rpcMethods[expectedRpcMethodToBeCalled] as jest.Mock + ).mockResolvedValueOnce(mockRpcResponse); + expect(await getBlock(web3Eth.web3Context, ...input)).toStrictEqual( + output, + ); + expect(rpcMethods[expectedRpcMethodToBeCalled]).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, + ...rpcMethodParameters, + ); + }, + ); + }); + + describe('getBlockTransactionCount', () => { + it.each(getBlockTransactionCountValidData)( + 'input: %s\nmockRpcResponse: %s\nexpectedRpcMethodToBeCalled: %s\nrpcMethodParameters: %s\noutput: %s', + async ( + input, + mockRpcResponse, + expectedRpcMethodToBeCalled, + rpcMethodParameters, + output, + ) => { + ( + rpcMethods[expectedRpcMethodToBeCalled] as jest.Mock + ).mockResolvedValueOnce(mockRpcResponse); + expect( + await getBlockTransactionCount(web3Eth.web3Context, ...input), + ).toStrictEqual(output); + expect(rpcMethods[expectedRpcMethodToBeCalled]).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, + ...rpcMethodParameters, + ); + }, + ); + }); + + describe('getBlockUncleCount', () => { + it.each(getBlockUncleCountValidData)( + 'input: %s\nmockRpcResponse: %s\nexpectedRpcMethodToBeCalled: %s\nrpcMethodParameters: %s\noutput: %s', + async ( + input, + mockRpcResponse, + expectedRpcMethodToBeCalled, + rpcMethodParameters, + output, + ) => { + ( + rpcMethods[expectedRpcMethodToBeCalled] as jest.Mock + ).mockResolvedValueOnce(mockRpcResponse); + expect( + await getBlockUncleCount(web3Eth.web3Context, ...input), + ).toStrictEqual(output); + expect(rpcMethods[expectedRpcMethodToBeCalled]).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, + ...rpcMethodParameters, + ); + }, + ); + }); + + describe('getUncle', () => { + it.each(getUncleValidData)( + 'input: %s\nmockRpcResponse: %s\nexpectedRpcMethodToBeCalled: %s\nrpcMethodParameters: %s\noutput: %s', + async ( + input, + mockRpcResponse, + expectedRpcMethodToBeCalled, + rpcMethodParameters, + output, + ) => { + ( + rpcMethods[expectedRpcMethodToBeCalled] as jest.Mock + ).mockResolvedValueOnce(mockRpcResponse); + expect(await getUncle(web3Eth.web3Context, ...input)).toStrictEqual( + output, + ); + expect(rpcMethods[expectedRpcMethodToBeCalled]).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, + ...rpcMethodParameters, + ); + }, + ); + }); + + describe('getTransaction', () => { + it.each(getTransactionValidData)( + 'input: %s\nmockRpcResponse: %s\nexpectedRpcMethodToBeCalled: %s\nrpcMethodParameters: %s\noutput: %s', + async (input, mockRpcResponse, rpcMethodParameters, output) => { + (rpcMethods.getTransactionByHash as jest.Mock).mockResolvedValueOnce( + mockRpcResponse, + ); + expect( + await getTransaction(web3Eth.web3Context, ...input), + ).toStrictEqual(output); + expect(rpcMethods.getTransactionByHash).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, + ...rpcMethodParameters, + ); + }, + ); + }); + + describe('getTransactionFromBlock', () => { + it.each(getTransactionFromBlockValidData)( + 'input: %s\nmockRpcResponse: %s\nexpectedRpcMethodToBeCalled: %s\nrpcMethodParameters: %s\noutput: %s', + async ( + input, + mockRpcResponse, + expectedRpcMethodToBeCalled, + rpcMethodParameters, + output, + ) => { + ( + rpcMethods[expectedRpcMethodToBeCalled] as jest.Mock + ).mockResolvedValueOnce(mockRpcResponse); + expect( + await getTransactionFromBlock(web3Eth.web3Context, ...input), + ).toStrictEqual(output); + expect(rpcMethods[expectedRpcMethodToBeCalled]).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, + ...rpcMethodParameters, + ); + }, + ); + }); + + describe('getTransactionReceipt', () => { + it.each(getTransactionReceiptValidData)( + 'input: %s\nmockRpcResponse: %s\nexpectedRpcMethodToBeCalled: %s\nrpcMethodParameters: %s\noutput: %s', + async (input, mockRpcResponse, rpcMethodParameters, output) => { + (rpcMethods.getTransactionReceipt as jest.Mock).mockResolvedValueOnce( + mockRpcResponse, + ); + expect( + await getTransactionReceipt(web3Eth.web3Context, ...input), + ).toStrictEqual(output); + expect(rpcMethods.getTransactionReceipt).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, + ...rpcMethodParameters, + ); + }, + ); + }); + + describe('getTransactionCount', () => { + it.each(getTransactionCountValidData)( + 'input: %s\nmockRpcResponse: %s\nexpectedRpcMethodToBeCalled: %s\nrpcMethodParameters: %s\noutput: %s', + async (input, mockRpcResponse, rpcMethodParameters, output) => { + (rpcMethods.getTransactionCount as jest.Mock).mockResolvedValueOnce( + mockRpcResponse, + ); + expect( + await getTransactionCount(web3Eth.web3Context, ...input), + ).toStrictEqual(output); + expect(rpcMethods.getTransactionCount).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, + ...rpcMethodParameters, + ); + }, + ); + }); + + describe('estimateGas', () => { + it.each(estimateGasValidData)( + 'input: %s\nmockRpcResponse: %s\nexpectedRpcMethodToBeCalled: %s\nrpcMethodParameters: %s\noutput: %s', + async (input, mockRpcResponse, rpcMethodParameters, output) => { + (rpcMethods.estimateGas as jest.Mock).mockResolvedValueOnce( + mockRpcResponse, + ); + expect(await estimateGas(web3Eth.web3Context, ...input)).toStrictEqual( + output, + ); + expect(rpcMethods.estimateGas).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, + ...rpcMethodParameters, + ); + }, + ); + }); + + describe('getFeeHistory', () => { + it.each(getFeeHistoryValidData)( + 'input: %s\nmockRpcResponse: %s\nexpectedRpcMethodToBeCalled: %s\nrpcMethodParameters: %s\noutput: %s', + async (input, mockRpcResponse, rpcMethodParameters, output) => { + (rpcMethods.getFeeHistory as jest.Mock).mockResolvedValueOnce( + mockRpcResponse, + ); + expect( + await getFeeHistory(web3Eth.web3Context, ...input), + ).toStrictEqual(output); + expect(rpcMethods.getFeeHistory).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, + ...rpcMethodParameters, + ); + }, + ); + }); + }); + + describe("doesn't have returnType parameter", () => { + describe('getStorageAt', () => { + it.each(getStorageAtValidData)( + 'input: %s\nmockRpcResponse: %s\nrpcMethodParameters: %s\noutput: %s', + async (input, mockRpcResponse, rpcMethodParameters) => { + (rpcMethods.getStorageAt as jest.Mock).mockResolvedValueOnce( + mockRpcResponse, + ); + expect(await getStorageAt(web3Eth.web3Context, ...input)).toBe( + mockRpcResponse, + ); + expect(rpcMethods.getStorageAt).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, + ...rpcMethodParameters, + ); + }, + ); + }); + + describe('getCode', () => { + it.each(getCodeValidData)( + 'input: %s\nmockRpcResponse: %s\nrpcMethodParameters: %s\noutput: %s', + async (input, mockRpcResponse, rpcMethodParameters) => { + (rpcMethods.getCode as jest.Mock).mockResolvedValueOnce( + mockRpcResponse, + ); + expect(await getCode(web3Eth.web3Context, ...input)).toBe( + mockRpcResponse, + ); + expect(rpcMethods.getCode).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, + ...rpcMethodParameters, + ); + }, + ); + }); + + describe('sendSignedTransaction', () => { + it.each(sendSignedTransactionValidData)( + 'input: %s\nmockRpcResponse: %s\nrpcMethodParameters: %s\noutput: %s', + async (input, mockRpcResponse) => { + (rpcMethods.sendRawTransaction as jest.Mock).mockResolvedValueOnce( + mockRpcResponse, + ); + expect(await sendSignedTransaction(web3Eth.web3Context, input)).toBe( + mockRpcResponse, + ); + expect(rpcMethods.sendRawTransaction).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, + input, + ); + }, + ); + }); + + describe('sign', () => { + it.each(signValidData)( + 'input: %s\nmockRpcResponse: %s', + async (input, mockRpcResponse) => { + (rpcMethods.sign as jest.Mock).mockResolvedValueOnce(mockRpcResponse); + expect(await sign(web3Eth.web3Context, ...input)).toBe(mockRpcResponse); + expect(rpcMethods.sign).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, + // web3-eth methods takes sign(message, address) + // RPC method takes sign(address, message) + // so we manually swap them here + input[1], + input[0], + ); + }, + ); + }); + + describe('getPastLogs', () => { + it.each(getPastLogsValidData)( + 'input: %s\nmockRpcResponse: %s\nrpcMethodParameters: %s', + async (input, mockRpcResponse, rpcMethodParameters) => { + (rpcMethods.getLogs as jest.Mock).mockResolvedValueOnce( + mockRpcResponse, + ); + expect(await getPastLogs(web3Eth.web3Context, input)).toBe( + mockRpcResponse, + ); + expect(rpcMethods.getLogs).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, + rpcMethodParameters, + ); + }, + ); + }); + + describe('submitWork', () => { + it.each(submitWorkValidData)( + 'input: %s\nmockRpcResponse: %s\nrpcMethodParameters: %s', + async (input, mockRpcResponse) => { + (rpcMethods.submitWork as jest.Mock).mockResolvedValueOnce( + mockRpcResponse, + ); + expect(await submitWork(web3Eth.web3Context, ...input)).toBe( + mockRpcResponse, + ); + expect(rpcMethods.submitWork).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, + ...input, + ); + }, + ); + }); + }); + }); + }); +}); From 52b56ffaeee1b28a6dcf13dda1b8ef128767fe54 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Sun, 30 Jan 2022 22:55:10 -1000 Subject: [PATCH 060/132] Refactor web3_eth_methods_with_parameters test --- ...eth_methods.ts => rpc_methods_wrappers.ts} | 18 +- .../web3_eth_methods_with_parameters.ts | 1221 +++++++++++++++++ .../web3_eth_methods_no_parameters.test.ts | 18 +- .../web3_eth_methods_with_parameters.test.ts | 362 ++--- ...pc_method_wrappers_with_parameters.test.ts | 2 +- 5 files changed, 1369 insertions(+), 252 deletions(-) rename packages/web3-eth/test/fixtures/{web3_eth_methods.ts => rpc_methods_wrappers.ts} (99%) create mode 100644 packages/web3-eth/test/fixtures/web3_eth_methods_with_parameters.ts diff --git a/packages/web3-eth/test/fixtures/web3_eth_methods.ts b/packages/web3-eth/test/fixtures/rpc_methods_wrappers.ts similarity index 99% rename from packages/web3-eth/test/fixtures/web3_eth_methods.ts rename to packages/web3-eth/test/fixtures/rpc_methods_wrappers.ts index 9b0b926f875..e49734562e7 100644 --- a/packages/web3-eth/test/fixtures/web3_eth_methods.ts +++ b/packages/web3-eth/test/fixtures/rpc_methods_wrappers.ts @@ -235,7 +235,7 @@ export const getBalanceValidData: [ ], ]; -const block: Block = { +export const block: Block = { parentHash: '0xe99e022112df268087ea7eafaf4790497fd21dbeeb6bd7a1721df161a6657a54', sha3Uncles: '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347', miner: '0xbb7b8287f3f0a933474a79eae42cbca977791171', @@ -267,7 +267,7 @@ const block: Block = { hash: '0xdc0818cf78f21a8e70579cb46a43643f78291264dda342ae31049421c82d21ae', baseFeePerGas: '0x13afe8b904', }; -const transactionInfo: TransactionInfo = { +export const transactionInfo: TransactionInfo = { blockHash: '0x1d59ff54b1eb26b013ce3cb5fc9dab3705b415a67127a003c3e61eb445bb8df2', blockNumber: '0x5daf3b', from: '0xa7d9ddbe1f17865597fbd27ec712455208b6b76d', @@ -286,8 +286,12 @@ const transactionInfo: TransactionInfo = { maxFeePerGas: '0x1475505aab', maxPriorityFeePerGas: '0x7f324180', }; -const hydratedTransactions: TransactionInfo[] = [transactionInfo, transactionInfo, transactionInfo]; -const blockFormattedNumberString: BlockFormatted = { +export const hydratedTransactions: TransactionInfo[] = [ + transactionInfo, + transactionInfo, + transactionInfo, +]; +export const blockFormattedNumberString: BlockFormatted = { ...block, transactions: hydratedTransactions, difficulty: '21109876668', @@ -300,7 +304,7 @@ const blockFormattedNumberString: BlockFormatted = { baseFeePerGas: '84555643140', size: '544', }; -const blockFormattedNumber: BlockFormatted = { +export const blockFormattedNumber: BlockFormatted = { ...block, transactions: hydratedTransactions, difficulty: 21109876668, @@ -313,7 +317,7 @@ const blockFormattedNumber: BlockFormatted = { baseFeePerGas: 84555643140, size: 544, }; -const blockFormattedBigInt: BlockFormatted = { +export const blockFormattedBigInt: BlockFormatted = { ...block, transactions: hydratedTransactions, // TODO Change this to TransactionInfoFormatted @@ -1566,7 +1570,7 @@ export const getTransactionCountValidData: [ ], ]; -const transactionWithSender: TransactionWithSender = { +export const transactionWithSender: TransactionWithSender = { to: '0x407d73d8a49eeb85d32cf465507dd71d507100c1', type: '0x0', nonce: '0x1', diff --git a/packages/web3-eth/test/fixtures/web3_eth_methods_with_parameters.ts b/packages/web3-eth/test/fixtures/web3_eth_methods_with_parameters.ts new file mode 100644 index 00000000000..fac341a1908 --- /dev/null +++ b/packages/web3-eth/test/fixtures/web3_eth_methods_with_parameters.ts @@ -0,0 +1,1221 @@ +import { TransactionWithSender } from 'web3-common'; +import { + Address, + BlockNumberOrTag, + BlockTags, + Filter, + HexString32Bytes, + HexString8Bytes, + HexStringBytes, + Uint, + Uint256, + ValidTypes, +} from 'web3-utils'; +import { transactionWithSender } from './rpc_methods_wrappers'; + +// Array consists of: returnType parameter +export const getHashRateValidData: [ValidTypes | undefined][] = [ + [undefined], + [ValidTypes.HexString], + [ValidTypes.NumberString], + [ValidTypes.Number], + [ValidTypes.BigInt], +]; + +// Array consists of: returnType parameter, mock RPC result, expected output +export const getGasPriceValidData: [ValidTypes | undefined][] = [ + [undefined], + [ValidTypes.HexString], + [ValidTypes.NumberString], + [ValidTypes.Number], + [ValidTypes.BigInt], +]; + +// Array consists of: returnType parameter +export const getBlockNumberValidData: [ValidTypes | undefined][] = [ + [undefined], + [ValidTypes.HexString], + [ValidTypes.NumberString], + [ValidTypes.Number], + [ValidTypes.BigInt], +]; + +/** + * Array consists of: + * - array of inputs + * - array of passed RPC parameters (excluding Web3Context) - This is to account for any defaults set by the method + */ +export const getBalanceValidData: [ + [Address, BlockNumberOrTag | undefined, ValidTypes | undefined], + [Address, BlockNumberOrTag, ValidTypes | undefined], +][] = [ + // All possible undefined values + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', undefined, undefined], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, undefined], + ], + // Defined blockNumber, undefined returnType + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, undefined], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, undefined], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.EARLIEST, undefined], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, undefined], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.PENDING, undefined], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, undefined], + ], + // Undefined blockNumber, returnType = ValidTypes.HexString + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', undefined, ValidTypes.HexString], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, ValidTypes.HexString], + ], + // Defined blockNumber, returnType = ValidTypes.HexString + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, ValidTypes.HexString], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, ValidTypes.HexString], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.EARLIEST, ValidTypes.HexString], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.EARLIEST, ValidTypes.HexString], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.PENDING, ValidTypes.HexString], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.PENDING, ValidTypes.HexString], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', '0x4b7', ValidTypes.HexString], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', '0x4b7', ValidTypes.HexString], + ], + // Undefined blockNumber, returnType = ValidTypes.NumberString + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', undefined, ValidTypes.NumberString], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, ValidTypes.NumberString], + ], + // Defined blockNumber, returnType = ValidTypes.NumberString + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, ValidTypes.NumberString], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, ValidTypes.NumberString], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.EARLIEST, ValidTypes.NumberString], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.EARLIEST, ValidTypes.NumberString], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.PENDING, ValidTypes.NumberString], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.PENDING, ValidTypes.NumberString], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', '0x4b7', ValidTypes.NumberString], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', '0x4b7', ValidTypes.NumberString], + ], + // Undefined blockNumber, returnType = ValidTypes.Number + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', undefined, ValidTypes.Number], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, ValidTypes.Number], + ], + // Defined blockNumber, returnType = ValidTypes.Number + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, ValidTypes.Number], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, ValidTypes.Number], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.EARLIEST, ValidTypes.Number], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.EARLIEST, ValidTypes.Number], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.PENDING, ValidTypes.Number], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.PENDING, ValidTypes.Number], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', '0x4b7', ValidTypes.Number], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', '0x4b7', ValidTypes.Number], + ], + // Undefined blockNumber, returnType = ValidTypes.BigInt + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', undefined, ValidTypes.BigInt], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, ValidTypes.BigInt], + ], + // Defined blockNumber, returnType = ValidTypes.BigInt + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, ValidTypes.BigInt], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, ValidTypes.BigInt], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.EARLIEST, ValidTypes.BigInt], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.EARLIEST, ValidTypes.BigInt], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.PENDING, ValidTypes.BigInt], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.PENDING, ValidTypes.BigInt], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', '0x4b7', ValidTypes.BigInt], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', '0x4b7', ValidTypes.BigInt], + ], +]; + +/** + * Array consists of: + * - array of inputs + * - array of passed RPC parameters (excluding Web3Context) - This is to account for any defaults set by the method + */ +export const getBlockValidData: [ + [HexString32Bytes | BlockNumberOrTag | undefined, boolean | undefined, ValidTypes | undefined], + [HexString32Bytes | BlockNumberOrTag, boolean, ValidTypes | undefined], +][] = [ + // All possible undefined values + [ + [undefined, undefined, undefined], + [BlockTags.LATEST, false, undefined], + ], + // Defined block, undefined hydrated and returnType + [ + [ + '0xdc0818cf78f21a8e70579cb46a43643f78291264dda342ae31049421c82d21ae', + undefined, + undefined, + ], + ['0xdc0818cf78f21a8e70579cb46a43643f78291264dda342ae31049421c82d21ae', false, undefined], + ], + [ + [BlockTags.LATEST, undefined, undefined], + [BlockTags.LATEST, false, undefined], + ], + [ + [BlockTags.EARLIEST, undefined, undefined], + [BlockTags.EARLIEST, false, undefined], + ], + [ + [BlockTags.PENDING, undefined, undefined], + [BlockTags.PENDING, false, undefined], + ], + // Defined block, hydrated = true, and undefined returnType + [ + [BlockTags.LATEST, true, undefined], + [BlockTags.LATEST, true, undefined], + ], + [ + [BlockTags.EARLIEST, true, undefined], + [BlockTags.EARLIEST, true, undefined], + ], + [ + [BlockTags.PENDING, true, undefined], + [BlockTags.PENDING, true, undefined], + ], + // Defined block, hydrated = false, and undefined returnType + [ + [BlockTags.LATEST, false, undefined], + [BlockTags.LATEST, false, undefined], + ], + [ + [BlockTags.EARLIEST, false, undefined], + [BlockTags.EARLIEST, false, undefined], + ], + [ + [BlockTags.PENDING, false, undefined], + [BlockTags.PENDING, false, undefined], + ], + // Defined block, hydrated = true, and returnType = ValidTypes.HexString + [ + [BlockTags.LATEST, true, ValidTypes.HexString], + [BlockTags.LATEST, true, ValidTypes.HexString], + ], + [ + [BlockTags.EARLIEST, true, ValidTypes.HexString], + [BlockTags.EARLIEST, true, ValidTypes.HexString], + ], + [ + [BlockTags.PENDING, true, ValidTypes.HexString], + [BlockTags.PENDING, true, ValidTypes.HexString], + ], + // Defined block, hydrated = true, and returnType = ValidTypes.NumberString + [ + [BlockTags.LATEST, true, ValidTypes.NumberString], + [BlockTags.LATEST, true, ValidTypes.NumberString], + ], + [ + [BlockTags.EARLIEST, true, ValidTypes.NumberString], + [BlockTags.EARLIEST, true, ValidTypes.NumberString], + ], + [ + [BlockTags.PENDING, true, ValidTypes.NumberString], + [BlockTags.PENDING, true, ValidTypes.NumberString], + ], + // Defined block, hydrated = true, and returnType = ValidTypes.Number + [ + [BlockTags.LATEST, true, ValidTypes.Number], + [BlockTags.LATEST, true, ValidTypes.Number], + ], + [ + [BlockTags.EARLIEST, true, ValidTypes.Number], + [BlockTags.EARLIEST, true, ValidTypes.Number], + ], + [ + [BlockTags.PENDING, true, ValidTypes.Number], + [BlockTags.PENDING, true, ValidTypes.Number], + ], + // Defined block, hydrated = true, and returnType = ValidTypes.BigInt + [ + [BlockTags.LATEST, true, ValidTypes.BigInt], + [BlockTags.LATEST, true, ValidTypes.BigInt], + ], + [ + [BlockTags.EARLIEST, true, ValidTypes.BigInt], + [BlockTags.EARLIEST, true, ValidTypes.BigInt], + ], + [ + [BlockTags.PENDING, true, ValidTypes.BigInt], + [BlockTags.PENDING, true, ValidTypes.BigInt], + ], +]; + +/** + * Array consists of: + * - array of inputs + * - array of passed RPC parameters (excluding Web3Context) - This is to account for any defaults set by the method + */ +export const getBlockTransactionCountValidData: [ + [HexString32Bytes | BlockNumberOrTag | undefined, ValidTypes | undefined], + [HexString32Bytes | BlockNumberOrTag, ValidTypes | undefined], +][] = [ + // All possible undefined values + [ + [undefined, undefined], + [BlockTags.LATEST, undefined], + ], + // Defined block, undefined returnType + [ + ['0xdc0818cf78f21a8e70579cb46a43643f78291264dda342ae31049421c82d21ae', undefined], + ['0xdc0818cf78f21a8e70579cb46a43643f78291264dda342ae31049421c82d21ae', undefined], + ], + [ + [BlockTags.LATEST, undefined], + [BlockTags.LATEST, undefined], + ], + [ + [BlockTags.EARLIEST, undefined], + [BlockTags.EARLIEST, undefined], + ], + [ + [BlockTags.PENDING, undefined], + [BlockTags.PENDING, undefined], + ], + // Defined block and returnType = ValidTypes.HexString + [ + [BlockTags.LATEST, ValidTypes.HexString], + [BlockTags.LATEST, ValidTypes.HexString], + ], + [ + [BlockTags.EARLIEST, ValidTypes.HexString], + [BlockTags.EARLIEST, ValidTypes.HexString], + ], + [ + [BlockTags.PENDING, ValidTypes.HexString], + [BlockTags.PENDING, ValidTypes.HexString], + ], + // Defined block and returnType = ValidTypes.NumberString + [ + [BlockTags.LATEST, ValidTypes.NumberString], + [BlockTags.LATEST, ValidTypes.NumberString], + ], + [ + [BlockTags.EARLIEST, ValidTypes.NumberString], + [BlockTags.EARLIEST, ValidTypes.NumberString], + ], + [ + [BlockTags.PENDING, ValidTypes.NumberString], + [BlockTags.PENDING, ValidTypes.NumberString], + ], + // Defined block, hydrated = true, and returnType = ValidTypes.Number + [ + [BlockTags.LATEST, ValidTypes.Number], + [BlockTags.LATEST, ValidTypes.Number], + ], + [ + [BlockTags.EARLIEST, ValidTypes.Number], + [BlockTags.EARLIEST, ValidTypes.Number], + ], + [ + [BlockTags.PENDING, ValidTypes.Number], + [BlockTags.PENDING, ValidTypes.Number], + ], + // Defined block and returnType = ValidTypes.BigInt + [ + [BlockTags.LATEST, ValidTypes.BigInt], + [BlockTags.LATEST, ValidTypes.BigInt], + ], + [ + [BlockTags.EARLIEST, ValidTypes.BigInt], + [BlockTags.EARLIEST, ValidTypes.BigInt], + ], + [ + [BlockTags.PENDING, ValidTypes.BigInt], + [BlockTags.PENDING, ValidTypes.BigInt], + ], +]; + +/** + * Array consists of: + * - array of inputs + * - array of passed RPC parameters (excluding Web3Context) - This is to account for any defaults set by the method + */ +export const getBlockUncleCountValidData: [ + [HexString32Bytes | BlockNumberOrTag | undefined, ValidTypes | undefined], + [HexString32Bytes | BlockNumberOrTag, ValidTypes | undefined], +][] = [ + // All possible undefined values + [ + [undefined, undefined], + [BlockTags.LATEST, undefined], + ], + // Defined block, undefined returnType + [ + ['0xdc0818cf78f21a8e70579cb46a43643f78291264dda342ae31049421c82d21ae', undefined], + ['0xdc0818cf78f21a8e70579cb46a43643f78291264dda342ae31049421c82d21ae', undefined], + ], + [ + [BlockTags.LATEST, undefined], + [BlockTags.LATEST, undefined], + ], + [ + [BlockTags.EARLIEST, undefined], + [BlockTags.EARLIEST, undefined], + ], + [ + [BlockTags.PENDING, undefined], + [BlockTags.PENDING, undefined], + ], + // Defined block and returnType = ValidTypes.HexString + [ + [BlockTags.LATEST, ValidTypes.HexString], + [BlockTags.LATEST, ValidTypes.HexString], + ], + [ + [BlockTags.EARLIEST, ValidTypes.HexString], + [BlockTags.EARLIEST, ValidTypes.HexString], + ], + [ + [BlockTags.PENDING, ValidTypes.HexString], + [BlockTags.PENDING, ValidTypes.HexString], + ], + // Defined block and returnType = ValidTypes.NumberString + [ + [BlockTags.LATEST, ValidTypes.NumberString], + [BlockTags.LATEST, ValidTypes.NumberString], + ], + [ + [BlockTags.EARLIEST, ValidTypes.NumberString], + [BlockTags.EARLIEST, ValidTypes.NumberString], + ], + [ + [BlockTags.PENDING, ValidTypes.NumberString], + [BlockTags.PENDING, ValidTypes.NumberString], + ], + // Defined block, hydrated = true, and returnType = ValidTypes.Number + [ + [BlockTags.LATEST, ValidTypes.Number], + [BlockTags.LATEST, ValidTypes.Number], + ], + [ + [BlockTags.EARLIEST, ValidTypes.Number], + [BlockTags.EARLIEST, ValidTypes.Number], + ], + [ + [BlockTags.PENDING, ValidTypes.Number], + [BlockTags.PENDING, ValidTypes.Number], + ], + // Defined block and returnType = ValidTypes.BigInt + [ + [BlockTags.LATEST, ValidTypes.BigInt], + [BlockTags.LATEST, ValidTypes.BigInt], + ], + [ + [BlockTags.EARLIEST, ValidTypes.BigInt], + [BlockTags.EARLIEST, ValidTypes.BigInt], + ], + [ + [BlockTags.PENDING, ValidTypes.BigInt], + [BlockTags.PENDING, ValidTypes.BigInt], + ], +]; + +/** + * Array consists of: + * - array of inputs + * - array of passed RPC parameters (excluding Web3Context) - This is to account for any defaults set by the method + */ +export const getUncleValidData: [ + [HexString32Bytes | BlockNumberOrTag | undefined, Uint, ValidTypes | undefined], + [HexString32Bytes | BlockNumberOrTag, Uint, ValidTypes | undefined], +][] = [ + // All possible undefined values + [ + [undefined, '0x0', undefined], + [BlockTags.LATEST, '0x0', undefined], + ], + // Defined block, uncleIndex = '0x0', and undefined returnType + [ + ['0xc3073501c72f0d9372a18015637c86a394c7d52b633ced791d64e88969cfa3e2', '0x0', undefined], + ['0xc3073501c72f0d9372a18015637c86a394c7d52b633ced791d64e88969cfa3e2', '0x0', undefined], + ], + [ + [BlockTags.LATEST, '0x0', undefined], + [BlockTags.LATEST, '0x0', undefined], + ], + [ + [BlockTags.EARLIEST, '0x0', undefined], + [BlockTags.EARLIEST, '0x0', undefined], + ], + [ + [BlockTags.PENDING, '0x0', undefined], + [BlockTags.PENDING, '0x0', undefined], + ], + // Defined block, uncleIndex = '0x0', and undefined returnType + [ + [BlockTags.LATEST, '0x0', undefined], + [BlockTags.LATEST, '0x0', undefined], + ], + [ + [BlockTags.EARLIEST, '0x0', undefined], + [BlockTags.EARLIEST, '0x0', undefined], + ], + [ + [BlockTags.PENDING, '0x0', undefined], + [BlockTags.PENDING, '0x0', undefined], + ], + // Defined block, uncleIndex = true, and returnType = ValidTypes.HexString + [ + [BlockTags.LATEST, '0x0', ValidTypes.HexString], + [BlockTags.LATEST, '0x0', ValidTypes.HexString], + ], + [ + [BlockTags.EARLIEST, '0x0', ValidTypes.HexString], + [BlockTags.EARLIEST, '0x0', ValidTypes.HexString], + ], + [ + [BlockTags.PENDING, '0x0', ValidTypes.HexString], + [BlockTags.PENDING, '0x0', ValidTypes.HexString], + ], + // Defined block, uncleIndex = '0x0', and returnType = ValidTypes.NumberString + [ + [BlockTags.LATEST, '0x0', ValidTypes.NumberString], + [BlockTags.LATEST, '0x0', ValidTypes.NumberString], + ], + [ + [BlockTags.EARLIEST, '0x0', ValidTypes.NumberString], + [BlockTags.EARLIEST, '0x0', ValidTypes.NumberString], + ], + [ + [BlockTags.PENDING, '0x0', ValidTypes.NumberString], + [BlockTags.PENDING, '0x0', ValidTypes.NumberString], + ], + // Defined block, uncleIndex = '0x0', and returnType = ValidTypes.Number + [ + [BlockTags.LATEST, '0x0', ValidTypes.Number], + [BlockTags.LATEST, '0x0', ValidTypes.Number], + ], + [ + [BlockTags.EARLIEST, '0x0', ValidTypes.Number], + [BlockTags.EARLIEST, '0x0', ValidTypes.Number], + ], + [ + [BlockTags.PENDING, '0x0', ValidTypes.Number], + [BlockTags.PENDING, '0x0', ValidTypes.Number], + ], + // Defined block, uncleIndex = '0x0', and returnType = ValidTypes.BigInt + [ + [BlockTags.LATEST, '0x0', ValidTypes.BigInt], + [BlockTags.LATEST, '0x0', ValidTypes.BigInt], + ], + [ + [BlockTags.EARLIEST, '0x0', ValidTypes.BigInt], + [BlockTags.EARLIEST, '0x0', ValidTypes.BigInt], + ], + [ + [BlockTags.PENDING, '0x0', ValidTypes.BigInt], + [BlockTags.PENDING, '0x0', ValidTypes.BigInt], + ], +]; + +/** + * Array consists of: + * - array of inputs + * - mock RPC result + * - array of passed RPC parameters (excluding Web3Context) - This is to account for any defaults set by the method + * - expected output + */ +export const getTransactionValidData: [ + [HexString32Bytes, ValidTypes | undefined], + [HexString32Bytes, ValidTypes | undefined], +][] = [ + // Defined transactionHash, undefined returnType + [ + ['0xe21194c9509beb01be7e90c2bcefff2804cd85836ae12134f22ad4acda0fc547', undefined], + ['0xe21194c9509beb01be7e90c2bcefff2804cd85836ae12134f22ad4acda0fc547', undefined], + ], + // Defined transactionHash and returnType = ValidTypes.HexString + [ + [ + '0xe21194c9509beb01be7e90c2bcefff2804cd85836ae12134f22ad4acda0fc547', + ValidTypes.HexString, + ], + [ + '0xe21194c9509beb01be7e90c2bcefff2804cd85836ae12134f22ad4acda0fc547', + ValidTypes.HexString, + ], + ], + // Defined transactionHash and returnType = ValidTypes.NumberString + [ + [ + '0xe21194c9509beb01be7e90c2bcefff2804cd85836ae12134f22ad4acda0fc547', + ValidTypes.NumberString, + ], + [ + '0xe21194c9509beb01be7e90c2bcefff2804cd85836ae12134f22ad4acda0fc547', + ValidTypes.NumberString, + ], + ], + // Defined block, hydrated = true, and returnType = ValidTypes.Number + [ + ['0xe21194c9509beb01be7e90c2bcefff2804cd85836ae12134f22ad4acda0fc547', ValidTypes.Number], + ['0xe21194c9509beb01be7e90c2bcefff2804cd85836ae12134f22ad4acda0fc547', ValidTypes.Number], + ], + // Defined block and returnType = ValidTypes.BigInt + [ + ['0xe21194c9509beb01be7e90c2bcefff2804cd85836ae12134f22ad4acda0fc547', ValidTypes.BigInt], + ['0xe21194c9509beb01be7e90c2bcefff2804cd85836ae12134f22ad4acda0fc547', ValidTypes.BigInt], + ], +]; + +/** + * Array consists of: + * - array of inputs + * - array of passed RPC parameters (excluding Web3Context) - This is to account for any defaults set by the method + */ +export const getTransactionFromBlockValidData: [ + [HexString32Bytes | BlockNumberOrTag | undefined, Uint, ValidTypes | undefined], + [HexString32Bytes | BlockNumberOrTag, Uint, ValidTypes | undefined], +][] = [ + // All possible undefined values + [ + [undefined, '0x0', undefined], + [BlockTags.LATEST, '0x0', undefined], + ], + // Defined block, uncleIndex = '0x0', and undefined returnType + [ + ['0xc3073501c72f0d9372a18015637c86a394c7d52b633ced791d64e88969cfa3e2', '0x0', undefined], + ['0xc3073501c72f0d9372a18015637c86a394c7d52b633ced791d64e88969cfa3e2', '0x0', undefined], + ], + [ + [BlockTags.LATEST, '0x0', undefined], + [BlockTags.LATEST, '0x0', undefined], + ], + [ + [BlockTags.EARLIEST, '0x0', undefined], + [BlockTags.EARLIEST, '0x0', undefined], + ], + [ + [BlockTags.PENDING, '0x0', undefined], + [BlockTags.PENDING, '0x0', undefined], + ], + // Defined block, uncleIndex = '0x0', and undefined returnType + [ + [BlockTags.LATEST, '0x0', undefined], + [BlockTags.LATEST, '0x0', undefined], + ], + [ + [BlockTags.EARLIEST, '0x0', undefined], + [BlockTags.EARLIEST, '0x0', undefined], + ], + [ + [BlockTags.PENDING, '0x0', undefined], + [BlockTags.PENDING, '0x0', undefined], + ], + // Defined block, uncleIndex = true, and returnType = ValidTypes.HexString + [ + [BlockTags.LATEST, '0x0', ValidTypes.HexString], + [BlockTags.LATEST, '0x0', ValidTypes.HexString], + ], + [ + [BlockTags.EARLIEST, '0x0', ValidTypes.HexString], + [BlockTags.EARLIEST, '0x0', ValidTypes.HexString], + ], + [ + [BlockTags.PENDING, '0x0', ValidTypes.HexString], + [BlockTags.PENDING, '0x0', ValidTypes.HexString], + ], + // Defined block, uncleIndex = '0x0', and returnType = ValidTypes.NumberString + [ + [BlockTags.LATEST, '0x0', ValidTypes.NumberString], + [BlockTags.LATEST, '0x0', ValidTypes.NumberString], + ], + [ + [BlockTags.EARLIEST, '0x0', ValidTypes.NumberString], + [BlockTags.EARLIEST, '0x0', ValidTypes.NumberString], + ], + [ + [BlockTags.PENDING, '0x0', ValidTypes.NumberString], + [BlockTags.PENDING, '0x0', ValidTypes.NumberString], + ], + // Defined block, uncleIndex = '0x0', and returnType = ValidTypes.Number + [ + [BlockTags.LATEST, '0x0', ValidTypes.Number], + [BlockTags.LATEST, '0x0', ValidTypes.Number], + ], + [ + [BlockTags.EARLIEST, '0x0', ValidTypes.Number], + [BlockTags.EARLIEST, '0x0', ValidTypes.Number], + ], + [ + [BlockTags.PENDING, '0x0', ValidTypes.Number], + [BlockTags.PENDING, '0x0', ValidTypes.Number], + ], + // Defined block, uncleIndex = '0x0', and returnType = ValidTypes.BigInt + [ + [BlockTags.LATEST, '0x0', ValidTypes.BigInt], + [BlockTags.LATEST, '0x0', ValidTypes.BigInt], + ], + [ + [BlockTags.EARLIEST, '0x0', ValidTypes.BigInt], + [BlockTags.EARLIEST, '0x0', ValidTypes.BigInt], + ], + [ + [BlockTags.PENDING, '0x0', ValidTypes.BigInt], + [BlockTags.PENDING, '0x0', ValidTypes.BigInt], + ], +]; + +/** + * Array consists of: + * - array of inputs + * - array of passed RPC parameters (excluding Web3Context) - This is to account for any defaults set by the method + */ +export const getTransactionReceiptValidData: [ + [HexString32Bytes, ValidTypes | undefined], + [HexString32Bytes, ValidTypes | undefined], +][] = [ + // Defined block, undefined returnType + [ + ['0xe21194c9509beb01be7e90c2bcefff2804cd85836ae12134f22ad4acda0fc547', undefined], + ['0xe21194c9509beb01be7e90c2bcefff2804cd85836ae12134f22ad4acda0fc547', undefined], + ], + // Defined block and returnType = ValidTypes.HexString + [ + [ + '0xe21194c9509beb01be7e90c2bcefff2804cd85836ae12134f22ad4acda0fc547', + ValidTypes.HexString, + ], + [ + '0xe21194c9509beb01be7e90c2bcefff2804cd85836ae12134f22ad4acda0fc547', + ValidTypes.HexString, + ], + ], + // Defined block and returnType = ValidTypes.NumberString + [ + [ + '0xe21194c9509beb01be7e90c2bcefff2804cd85836ae12134f22ad4acda0fc547', + ValidTypes.NumberString, + ], + [ + '0xe21194c9509beb01be7e90c2bcefff2804cd85836ae12134f22ad4acda0fc547', + ValidTypes.NumberString, + ], + ], + // Defined block, hydrated = true, and returnType = ValidTypes.Number + [ + ['0xe21194c9509beb01be7e90c2bcefff2804cd85836ae12134f22ad4acda0fc547', ValidTypes.Number], + ['0xe21194c9509beb01be7e90c2bcefff2804cd85836ae12134f22ad4acda0fc547', ValidTypes.Number], + ], + // Defined block and returnType = ValidTypes.BigInt + [ + ['0xe21194c9509beb01be7e90c2bcefff2804cd85836ae12134f22ad4acda0fc547', ValidTypes.BigInt], + ['0xe21194c9509beb01be7e90c2bcefff2804cd85836ae12134f22ad4acda0fc547', ValidTypes.BigInt], + ], +]; + +/** + * Array consists of: + * - array of inputs + * - array of passed RPC parameters (excluding Web3Context) - This is to account for any defaults set by the method + */ +export const getTransactionCountValidData: [ + [Address, HexString32Bytes | BlockNumberOrTag | undefined, ValidTypes | undefined], + [Address, HexString32Bytes | BlockNumberOrTag, ValidTypes | undefined], +][] = [ + // All possible undefined values + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', undefined, undefined], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, undefined], + ], + // Defined address and block number, undefined returnType + [ + [ + '0x407d73d8a49eeb85d32cf465507dd71d507100c1', + '0xc3073501c72f0d9372a18015637c86a394c7d52b633ced791d64e88969cfa3e2', + undefined, + ], + [ + '0x407d73d8a49eeb85d32cf465507dd71d507100c1', + '0xc3073501c72f0d9372a18015637c86a394c7d52b633ced791d64e88969cfa3e2', + undefined, + ], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, undefined], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, undefined], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.EARLIEST, undefined], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.EARLIEST, undefined], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.PENDING, undefined], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.PENDING, undefined], + ], + // Defined block, uncleIndex = and undefined returnType + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, undefined], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, undefined], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.EARLIEST, undefined], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.EARLIEST, undefined], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.PENDING, undefined], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.PENDING, undefined], + ], + // Defined block, uncleIndex = true, and returnType = ValidTypes.HexString + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, ValidTypes.HexString], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, ValidTypes.HexString], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.EARLIEST, ValidTypes.HexString], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.EARLIEST, ValidTypes.HexString], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.PENDING, ValidTypes.HexString], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.PENDING, ValidTypes.HexString], + ], + // Defined block, uncleIndex = and returnType = ValidTypes.NumberString + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, ValidTypes.NumberString], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, ValidTypes.NumberString], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.EARLIEST, ValidTypes.NumberString], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.EARLIEST, ValidTypes.NumberString], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.PENDING, ValidTypes.NumberString], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.PENDING, ValidTypes.NumberString], + ], + // Defined block, uncleIndex = and returnType = ValidTypes.Number + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, ValidTypes.Number], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, ValidTypes.Number], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.EARLIEST, ValidTypes.Number], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.EARLIEST, ValidTypes.Number], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.PENDING, ValidTypes.Number], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.PENDING, ValidTypes.Number], + ], + // Defined block, uncleIndex = and returnType = ValidTypes.BigInt + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, ValidTypes.BigInt], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST, ValidTypes.BigInt], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.EARLIEST, ValidTypes.BigInt], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.EARLIEST, ValidTypes.BigInt], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.PENDING, ValidTypes.BigInt], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.PENDING, ValidTypes.BigInt], + ], +]; + +/** + * Array consists of: + * - array of inputs + * - array of passed RPC parameters (excluding Web3Context) - This is to account for any defaults set by the method + */ +export const estimateGasValidData: [ + [ + Partial, + HexString32Bytes | BlockNumberOrTag | undefined, + ValidTypes | undefined, + ], + [Partial, HexString32Bytes | BlockNumberOrTag, ValidTypes | undefined], +][] = [ + // All possible undefined values + [ + [transactionWithSender, undefined, undefined], + [transactionWithSender, BlockTags.LATEST, undefined], + ], + // Defined transaction and block number, undefined returnType + [ + [ + transactionWithSender, + '0xc3073501c72f0d9372a18015637c86a394c7d52b633ced791d64e88969cfa3e2', + undefined, + ], + [ + transactionWithSender, + '0xc3073501c72f0d9372a18015637c86a394c7d52b633ced791d64e88969cfa3e2', + undefined, + ], + ], + [ + [transactionWithSender, BlockTags.LATEST, undefined], + [transactionWithSender, BlockTags.LATEST, undefined], + ], + [ + [transactionWithSender, BlockTags.EARLIEST, undefined], + [transactionWithSender, BlockTags.EARLIEST, undefined], + ], + [ + [transactionWithSender, BlockTags.PENDING, undefined], + [transactionWithSender, BlockTags.PENDING, undefined], + ], + // Defined transaction and block number, undefined returnType + [ + [transactionWithSender, BlockTags.LATEST, undefined], + [transactionWithSender, BlockTags.LATEST, undefined], + ], + [ + [transactionWithSender, BlockTags.EARLIEST, undefined], + [transactionWithSender, BlockTags.EARLIEST, undefined], + ], + [ + [transactionWithSender, BlockTags.PENDING, undefined], + [transactionWithSender, BlockTags.PENDING, undefined], + ], + // Defined transaction and block number, returnType = ValidTypes.HexString + [ + [transactionWithSender, BlockTags.LATEST, ValidTypes.HexString], + [transactionWithSender, BlockTags.LATEST, ValidTypes.HexString], + ], + [ + [transactionWithSender, BlockTags.EARLIEST, ValidTypes.HexString], + [transactionWithSender, BlockTags.EARLIEST, ValidTypes.HexString], + ], + [ + [transactionWithSender, BlockTags.PENDING, ValidTypes.HexString], + [transactionWithSender, BlockTags.PENDING, ValidTypes.HexString], + ], + // Defined transaction and block number, returnType = ValidTypes.NumberString + [ + [transactionWithSender, BlockTags.LATEST, ValidTypes.NumberString], + [transactionWithSender, BlockTags.LATEST, ValidTypes.NumberString], + ], + [ + [transactionWithSender, BlockTags.EARLIEST, ValidTypes.NumberString], + [transactionWithSender, BlockTags.EARLIEST, ValidTypes.NumberString], + ], + [ + [transactionWithSender, BlockTags.PENDING, ValidTypes.NumberString], + [transactionWithSender, BlockTags.PENDING, ValidTypes.NumberString], + ], + // Defined transaction and block number, returnType = ValidTypes.Number + [ + [transactionWithSender, BlockTags.LATEST, ValidTypes.Number], + [transactionWithSender, BlockTags.LATEST, ValidTypes.Number], + ], + [ + [transactionWithSender, BlockTags.EARLIEST, ValidTypes.Number], + [transactionWithSender, BlockTags.EARLIEST, ValidTypes.Number], + ], + [ + [transactionWithSender, BlockTags.PENDING, ValidTypes.Number], + [transactionWithSender, BlockTags.PENDING, ValidTypes.Number], + ], + // Defined transaction and block number, returnType = ValidTypes.BigInt + [ + [transactionWithSender, BlockTags.LATEST, ValidTypes.BigInt], + [transactionWithSender, BlockTags.LATEST, ValidTypes.BigInt], + ], + [ + [transactionWithSender, BlockTags.EARLIEST, ValidTypes.BigInt], + [transactionWithSender, BlockTags.EARLIEST, ValidTypes.BigInt], + ], + [ + [transactionWithSender, BlockTags.PENDING, ValidTypes.BigInt], + [transactionWithSender, BlockTags.PENDING, ValidTypes.BigInt], + ], +]; + +/** + * Array consists of: + * - array of inputs + * - array of passed RPC parameters (excluding Web3Context) - This is to account for any defaults set by the method + */ +export const getFeeHistoryValidData: [ + [Uint, HexString32Bytes | BlockNumberOrTag | undefined, number[], ValidTypes | undefined], + [Uint, HexString32Bytes | BlockNumberOrTag, number[], ValidTypes | undefined], +][] = [ + // All possible undefined values + [ + ['0x4', undefined, [], undefined], + ['0x4', BlockTags.LATEST, [], undefined], + ], + // Defined transaction and block number, undefined returnType + [ + [ + '0x4', + '0xc3073501c72f0d9372a18015637c86a394c7d52b633ced791d64e88969cfa3e2', + [], + undefined, + ], + [ + '0x4', + '0xc3073501c72f0d9372a18015637c86a394c7d52b633ced791d64e88969cfa3e2', + [], + undefined, + ], + ], + [ + ['0x4', BlockTags.LATEST, [], undefined], + ['0x4', BlockTags.LATEST, [], undefined], + ], + [ + ['0x4', BlockTags.EARLIEST, [], undefined], + ['0x4', BlockTags.EARLIEST, [], undefined], + ], + [ + ['0x4', BlockTags.PENDING, [], undefined], + ['0x4', BlockTags.PENDING, [], undefined], + ], + // Defined transaction and block number, undefined returnType + [ + ['0x4', BlockTags.LATEST, [], undefined], + ['0x4', BlockTags.LATEST, [], undefined], + ], + [ + ['0x4', BlockTags.EARLIEST, [], undefined], + ['0x4', BlockTags.EARLIEST, [], undefined], + ], + [ + ['0x4', BlockTags.PENDING, [], undefined], + ['0x4', BlockTags.PENDING, [], undefined], + ], + // Defined transaction and block number, returnType = ValidTypes.HexString + [ + ['0x4', BlockTags.LATEST, [], ValidTypes.HexString], + ['0x4', BlockTags.LATEST, [], ValidTypes.HexString], + ], + [ + ['0x4', BlockTags.EARLIEST, [], ValidTypes.HexString], + ['0x4', BlockTags.EARLIEST, [], ValidTypes.HexString], + ], + [ + ['0x4', BlockTags.PENDING, [], ValidTypes.HexString], + ['0x4', BlockTags.PENDING, [], ValidTypes.HexString], + ], + // Defined transaction and block number, returnType = ValidTypes.NumberString + [ + ['0x4', BlockTags.LATEST, [], ValidTypes.NumberString], + ['0x4', BlockTags.LATEST, [], ValidTypes.NumberString], + ], + [ + ['0x4', BlockTags.EARLIEST, [], ValidTypes.NumberString], + ['0x4', BlockTags.EARLIEST, [], ValidTypes.NumberString], + ], + [ + ['0x4', BlockTags.PENDING, [], ValidTypes.NumberString], + ['0x4', BlockTags.PENDING, [], ValidTypes.NumberString], + ], + // Defined transaction and block number, returnType = ValidTypes.Number + [ + ['0x4', BlockTags.LATEST, [], ValidTypes.Number], + ['0x4', BlockTags.LATEST, [], ValidTypes.Number], + ], + [ + ['0x4', BlockTags.EARLIEST, [], ValidTypes.Number], + ['0x4', BlockTags.EARLIEST, [], ValidTypes.Number], + ], + [ + ['0x4', BlockTags.PENDING, [], ValidTypes.Number], + ['0x4', BlockTags.PENDING, [], ValidTypes.Number], + ], + // Defined transaction and block number, returnType = ValidTypes.BigInt + [ + ['0x4', BlockTags.LATEST, [], ValidTypes.BigInt], + ['0x4', BlockTags.LATEST, [], ValidTypes.BigInt], + ], + [ + ['0x4', BlockTags.EARLIEST, [], ValidTypes.BigInt], + ['0x4', BlockTags.EARLIEST, [], ValidTypes.BigInt], + ], + [ + ['0x4', BlockTags.PENDING, [], ValidTypes.BigInt], + ['0x4', BlockTags.PENDING, [], ValidTypes.BigInt], + ], +]; + +/** + * Array consists of: + * - array of inputs + * - array of passed RPC parameters (excluding Web3Context) - This is to account for any defaults set by the method + */ +export const getStorageAtValidData: [ + [Address, Uint256, BlockNumberOrTag | undefined], + [Address, Uint256, BlockNumberOrTag], +][] = [ + // All possible undefined values + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', '0x0', undefined], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', '0x0', BlockTags.LATEST], + ], + // Defined address, storageSlot, and blockNumber + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', '0x0', BlockTags.LATEST], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', '0x0', BlockTags.LATEST], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', '0x0', BlockTags.EARLIEST], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', '0x0', BlockTags.EARLIEST], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', '0x0', BlockTags.PENDING], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', '0x0', BlockTags.PENDING], + ], +]; + +/** + * Array consists of: + * - array of inputs + * - array of passed RPC parameters (excluding Web3Context) - This is to account for any defaults set by the method + */ +export const getCodeValidData: [ + [Address, BlockNumberOrTag | undefined], + [Address, BlockNumberOrTag], +][] = [ + // All possible undefined values + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', undefined], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST], + ], + // Defined address and blockNumber + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.LATEST], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.EARLIEST], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.EARLIEST], + ], + [ + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.PENDING], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c1', BlockTags.PENDING], + ], +]; + +/** + * Array consists of: + * - input + * - mock RPC result + */ +export const sendSignedTransactionValidData: [HexStringBytes][] = [ + ['0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675'], +]; + +/** + * Array consists of: + * - array of inputs + */ +export const signValidData: [[HexStringBytes, Address]][] = [ + [['0xdeadbeaf', '0x407d73d8a49eeb85d32cf465507dd71d507100c1']], +]; + +/** + * Array consists of: + * - array of inputs + * - array of passed RPC parameters (excluding Web3Context) - This is to account for any defaults set by the method + */ +export const getPastLogsValidData: [Filter, Filter][] = [ + [ + {}, + { + fromBlock: BlockTags.LATEST, + toBlock: BlockTags.LATEST, + }, + ], + [ + { + address: '0x407d73d8a49eeb85d32cf465507dd71d507100c1', + topics: [ + '0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b', + null, + [ + '0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b', + '0x0000000000000000000000000aff3454fce5edbc8cca8697c15331677e6ebccc', + ], + ], + }, + { + fromBlock: BlockTags.LATEST, + toBlock: BlockTags.LATEST, + address: '0x407d73d8a49eeb85d32cf465507dd71d507100c1', + topics: [ + '0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b', + null, + [ + '0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b', + '0x0000000000000000000000000aff3454fce5edbc8cca8697c15331677e6ebccc', + ], + ], + }, + ], + [ + { + fromBlock: BlockTags.LATEST, + toBlock: BlockTags.LATEST, + }, + { + fromBlock: BlockTags.LATEST, + toBlock: BlockTags.LATEST, + }, + ], + [ + { + fromBlock: BlockTags.PENDING, + toBlock: BlockTags.PENDING, + }, + { + fromBlock: BlockTags.PENDING, + toBlock: BlockTags.PENDING, + }, + ], + [ + { + fromBlock: BlockTags.EARLIEST, + toBlock: BlockTags.EARLIEST, + }, + { + fromBlock: BlockTags.EARLIEST, + toBlock: BlockTags.EARLIEST, + }, + ], +]; + +/** + * Array consists of: + * - array of inputs + */ +export const submitWorkValidData: [[HexString8Bytes, HexString32Bytes, HexString32Bytes]][] = [ + [ + [ + '0x0000000000000001', + '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef', + '0xD1FE5700000000000000000000000000D1FE5700000000000000000000000000', + ], + ], +]; diff --git a/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts b/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts index 2017a9c67f3..8c7a768dd8a 100644 --- a/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts +++ b/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts @@ -1,7 +1,7 @@ import Web3Eth from '../../src/index'; -import * as rpcMethods from '../../src/rpc_methods'; +import * as rpcMethodWrappers from '../../src/rpc_method_wrappers'; -jest.mock('../../src/rpc_methods'); +jest.mock('../../src/rpc_method_wrappers'); describe('web3_eth_methods_no_parameters', () => { let web3Eth: Web3Eth; @@ -13,34 +13,32 @@ describe('web3_eth_methods_no_parameters', () => { describe('should call RPC method with only request manager parameter', () => { it('getProtocolVersion', async () => { await web3Eth.getProtocolVersion(); - expect(rpcMethods.getProtocolVersion).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, - ); + expect(rpcMethodWrappers.getProtocolVersion).toHaveBeenCalledWith(web3Eth.web3Context); }); it('isSyncing', async () => { await web3Eth.isSyncing(); - expect(rpcMethods.getSyncing).toHaveBeenCalledWith(web3Eth.web3Context.requestManager); + expect(rpcMethodWrappers.isSyncing).toHaveBeenCalledWith(web3Eth.web3Context); }); it('getCoinbase', async () => { await web3Eth.getCoinbase(); - expect(rpcMethods.getCoinbase).toHaveBeenCalledWith(web3Eth.web3Context.requestManager); + expect(rpcMethodWrappers.getCoinbase).toHaveBeenCalledWith(web3Eth.web3Context); }); it('isMining', async () => { await web3Eth.isMining(); - expect(rpcMethods.getMining).toHaveBeenCalledWith(web3Eth.web3Context.requestManager); + expect(rpcMethodWrappers.isMining).toHaveBeenCalledWith(web3Eth.web3Context); }); it('getAccounts', async () => { await web3Eth.getAccounts(); - expect(rpcMethods.getAccounts).toHaveBeenCalledWith(web3Eth.web3Context.requestManager); + expect(rpcMethodWrappers.getAccounts).toHaveBeenCalledWith(web3Eth.web3Context); }); it('getWork', async () => { await web3Eth.getWork(); - expect(rpcMethods.getWork).toHaveBeenCalledWith(web3Eth.web3Context.requestManager); + expect(rpcMethodWrappers.getWork).toHaveBeenCalledWith(web3Eth.web3Context); }); }); }); diff --git a/packages/web3-eth/test/unit/web3_eth_methods_with_parameters.test.ts b/packages/web3-eth/test/unit/web3_eth_methods_with_parameters.test.ts index 744f59dcb26..53e038a13b6 100644 --- a/packages/web3-eth/test/unit/web3_eth_methods_with_parameters.test.ts +++ b/packages/web3-eth/test/unit/web3_eth_methods_with_parameters.test.ts @@ -1,9 +1,10 @@ /* eslint-disable import/namespace */ import Web3Eth from '../../src/index'; -import * as rpcMethods from '../../src/rpc_methods'; +import * as rpcMethodWrappers from '../../src/rpc_method_wrappers'; import { estimateGasValidData, + // estimateGasValidData, getBalanceValidData, getBlockNumberValidData, getBlockTransactionCountValidData, @@ -11,6 +12,8 @@ import { getBlockValidData, getCodeValidData, getFeeHistoryValidData, + // getCodeValidData, + // getFeeHistoryValidData, getGasPriceValidData, getHashRateValidData, getPastLogsValidData, @@ -23,9 +26,19 @@ import { sendSignedTransactionValidData, signValidData, submitWorkValidData, -} from '../fixtures/web3_eth_methods'; + // getPastLogsValidData, + // getStorageAtValidData, + // getTransactionCountValidData, + // getTransactionFromBlockValidData, + // getTransactionReceiptValidData, + // getTransactionValidData, + // getUncleValidData, + // sendSignedTransactionValidData, + // signValidData, + // submitWorkValidData, +} from '../fixtures/web3_eth_methods_with_parameters'; -jest.mock('../../src/rpc_methods'); +jest.mock('../../src/rpc_method_wrappers'); describe('web3_eth_methods_with_parameters', () => { let web3Eth: Web3Eth; @@ -37,48 +50,33 @@ describe('web3_eth_methods_with_parameters', () => { describe('should call RPC method with expected parameters', () => { describe('only has returnType parameter', () => { describe('getHashRate', () => { - it.each(getHashRateValidData)( - 'returnType: %s mockRpcResponse: %s output: %s', - async (returnType, mockRpcResponse, output) => { - (rpcMethods.getHashRate as jest.Mock).mockResolvedValueOnce( - mockRpcResponse, - ); - expect(await web3Eth.getHashRate(returnType)).toBe(output); - expect(rpcMethods.getHashRate).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, - ); - }, - ); + it.each(getHashRateValidData)('returnType: %s', async returnType => { + await web3Eth.getHashRate(returnType); + expect(rpcMethodWrappers.getHashRate).toHaveBeenCalledWith( + web3Eth.web3Context, + returnType, + ); + }); }); describe('getGasPrice', () => { - it.each(getGasPriceValidData)( - 'returnType: %s mockRpcResponse: %s output: %s', - async (returnType, mockRpcResponse, output) => { - (rpcMethods.getGasPrice as jest.Mock).mockResolvedValueOnce( - mockRpcResponse, - ); - expect(await web3Eth.getGasPrice(returnType)).toBe(output); - expect(rpcMethods.getGasPrice).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, - ); - }, - ); + it.each(getGasPriceValidData)('returnType: %s', async returnType => { + await web3Eth.getGasPrice(returnType); + expect(rpcMethodWrappers.getGasPrice).toHaveBeenCalledWith( + web3Eth.web3Context, + returnType, + ); + }); }); describe('getBlockNumber', () => { - it.each(getBlockNumberValidData)( - 'returnType: %s mockRpcResponse: %s output: %s', - async (returnType, mockRpcResponse, output) => { - (rpcMethods.getBlockNumber as jest.Mock).mockResolvedValueOnce( - mockRpcResponse, - ); - expect(await web3Eth.getBlockNumber(returnType)).toBe(output); - expect(rpcMethods.getBlockNumber).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, - ); - }, - ); + it.each(getBlockNumberValidData)('returnType: %s', async returnType => { + await web3Eth.getBlockNumber(returnType); + expect(rpcMethodWrappers.getBlockNumber).toHaveBeenCalledWith( + web3Eth.web3Context, + returnType, + ); + }); }); }); @@ -86,14 +84,11 @@ describe('web3_eth_methods_with_parameters', () => { describe('has returnType parameter', () => { describe('getBalance', () => { it.each(getBalanceValidData)( - 'input: %s\nmockRpcResponse: %s\nrpcMethodParameters: %s\noutput: %s', - async (input, mockRpcResponse, rpcMethodParameters, output) => { - (rpcMethods.getBalance as jest.Mock).mockResolvedValueOnce( - mockRpcResponse, - ); - expect(await web3Eth.getBalance(...input)).toBe(output); - expect(rpcMethods.getBalance).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + 'input: %s\nrpcMethodParameters: %s', + async (input, rpcMethodParameters) => { + await web3Eth.getBalance(...input); + expect(rpcMethodWrappers.getBalance).toHaveBeenCalledWith( + web3Eth.web3Context, ...rpcMethodParameters, ); }, @@ -102,20 +97,11 @@ describe('web3_eth_methods_with_parameters', () => { describe('getBlock', () => { it.each(getBlockValidData)( - 'input: %s\nmockRpcResponse: %s\nexpectedRpcMethodToBeCalled: %s\nrpcMethodParameters: %s\noutput: %s', - async ( - input, - mockRpcResponse, - expectedRpcMethodToBeCalled, - rpcMethodParameters, - output, - ) => { - ( - rpcMethods[expectedRpcMethodToBeCalled] as jest.Mock - ).mockResolvedValueOnce(mockRpcResponse); - expect(await web3Eth.getBlock(...input)).toStrictEqual(output); - expect(rpcMethods[expectedRpcMethodToBeCalled]).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + 'input: %s\nrpcMethodParameters: %s', + async (input, rpcMethodParameters) => { + await web3Eth.getBlock(...input); + expect(rpcMethodWrappers.getBlock).toHaveBeenCalledWith( + web3Eth.web3Context, ...rpcMethodParameters, ); }, @@ -124,22 +110,11 @@ describe('web3_eth_methods_with_parameters', () => { describe('getBlockTransactionCount', () => { it.each(getBlockTransactionCountValidData)( - 'input: %s\nmockRpcResponse: %s\nexpectedRpcMethodToBeCalled: %s\nrpcMethodParameters: %s\noutput: %s', - async ( - input, - mockRpcResponse, - expectedRpcMethodToBeCalled, - rpcMethodParameters, - output, - ) => { - ( - rpcMethods[expectedRpcMethodToBeCalled] as jest.Mock - ).mockResolvedValueOnce(mockRpcResponse); - expect(await web3Eth.getBlockTransactionCount(...input)).toStrictEqual( - output, - ); - expect(rpcMethods[expectedRpcMethodToBeCalled]).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + 'input: %s\nrpcMethodParameters: %s', + async (input, rpcMethodParameters) => { + await web3Eth.getBlockTransactionCount(...input); + expect(rpcMethodWrappers.getBlockTransactionCount).toHaveBeenCalledWith( + web3Eth.web3Context, ...rpcMethodParameters, ); }, @@ -148,22 +123,11 @@ describe('web3_eth_methods_with_parameters', () => { describe('getBlockUncleCount', () => { it.each(getBlockUncleCountValidData)( - 'input: %s\nmockRpcResponse: %s\nexpectedRpcMethodToBeCalled: %s\nrpcMethodParameters: %s\noutput: %s', - async ( - input, - mockRpcResponse, - expectedRpcMethodToBeCalled, - rpcMethodParameters, - output, - ) => { - ( - rpcMethods[expectedRpcMethodToBeCalled] as jest.Mock - ).mockResolvedValueOnce(mockRpcResponse); - expect(await web3Eth.getBlockUncleCount(...input)).toStrictEqual( - output, - ); - expect(rpcMethods[expectedRpcMethodToBeCalled]).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + 'input: %s\nrpcMethodParameters: %s', + async (input, rpcMethodParameters) => { + await web3Eth.getBlockUncleCount(...input); + expect(rpcMethodWrappers.getBlockUncleCount).toHaveBeenCalledWith( + web3Eth.web3Context, ...rpcMethodParameters, ); }, @@ -172,20 +136,11 @@ describe('web3_eth_methods_with_parameters', () => { describe('getUncle', () => { it.each(getUncleValidData)( - 'input: %s\nmockRpcResponse: %s\nexpectedRpcMethodToBeCalled: %s\nrpcMethodParameters: %s\noutput: %s', - async ( - input, - mockRpcResponse, - expectedRpcMethodToBeCalled, - rpcMethodParameters, - output, - ) => { - ( - rpcMethods[expectedRpcMethodToBeCalled] as jest.Mock - ).mockResolvedValueOnce(mockRpcResponse); - expect(await web3Eth.getUncle(...input)).toStrictEqual(output); - expect(rpcMethods[expectedRpcMethodToBeCalled]).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + 'input: %s\nrpcMethodParameters: %s', + async (input, rpcMethodParameters) => { + await web3Eth.getUncle(...input); + expect(rpcMethodWrappers.getUncle).toHaveBeenCalledWith( + web3Eth.web3Context, ...rpcMethodParameters, ); }, @@ -194,14 +149,11 @@ describe('web3_eth_methods_with_parameters', () => { describe('getTransaction', () => { it.each(getTransactionValidData)( - 'input: %s\nmockRpcResponse: %s\nexpectedRpcMethodToBeCalled: %s\nrpcMethodParameters: %s\noutput: %s', - async (input, mockRpcResponse, rpcMethodParameters, output) => { - (rpcMethods.getTransactionByHash as jest.Mock).mockResolvedValueOnce( - mockRpcResponse, - ); - expect(await web3Eth.getTransaction(...input)).toStrictEqual(output); - expect(rpcMethods.getTransactionByHash).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + 'input: %s\nrpcMethodParameters: %s', + async (input, rpcMethodParameters) => { + await web3Eth.getTransaction(...input); + expect(rpcMethodWrappers.getTransaction).toHaveBeenCalledWith( + web3Eth.web3Context, ...rpcMethodParameters, ); }, @@ -210,22 +162,11 @@ describe('web3_eth_methods_with_parameters', () => { describe('getTransactionFromBlock', () => { it.each(getTransactionFromBlockValidData)( - 'input: %s\nmockRpcResponse: %s\nexpectedRpcMethodToBeCalled: %s\nrpcMethodParameters: %s\noutput: %s', - async ( - input, - mockRpcResponse, - expectedRpcMethodToBeCalled, - rpcMethodParameters, - output, - ) => { - ( - rpcMethods[expectedRpcMethodToBeCalled] as jest.Mock - ).mockResolvedValueOnce(mockRpcResponse); - expect(await web3Eth.getTransactionFromBlock(...input)).toStrictEqual( - output, - ); - expect(rpcMethods[expectedRpcMethodToBeCalled]).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + 'input: %s\nrpcMethodParameters: %s', + async (input, rpcMethodParameters) => { + await web3Eth.getTransactionFromBlock(...input); + expect(rpcMethodWrappers.getTransactionFromBlock).toHaveBeenCalledWith( + web3Eth.web3Context, ...rpcMethodParameters, ); }, @@ -234,16 +175,11 @@ describe('web3_eth_methods_with_parameters', () => { describe('getTransactionReceipt', () => { it.each(getTransactionReceiptValidData)( - 'input: %s\nmockRpcResponse: %s\nexpectedRpcMethodToBeCalled: %s\nrpcMethodParameters: %s\noutput: %s', - async (input, mockRpcResponse, rpcMethodParameters, output) => { - (rpcMethods.getTransactionReceipt as jest.Mock).mockResolvedValueOnce( - mockRpcResponse, - ); - expect(await web3Eth.getTransactionReceipt(...input)).toStrictEqual( - output, - ); - expect(rpcMethods.getTransactionReceipt).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + 'input: %s\nrpcMethodParameters: %s', + async (input, rpcMethodParameters) => { + await web3Eth.getTransactionReceipt(...input); + expect(rpcMethodWrappers.getTransactionReceipt).toHaveBeenCalledWith( + web3Eth.web3Context, ...rpcMethodParameters, ); }, @@ -252,16 +188,11 @@ describe('web3_eth_methods_with_parameters', () => { describe('getTransactionCount', () => { it.each(getTransactionCountValidData)( - 'input: %s\nmockRpcResponse: %s\nexpectedRpcMethodToBeCalled: %s\nrpcMethodParameters: %s\noutput: %s', - async (input, mockRpcResponse, rpcMethodParameters, output) => { - (rpcMethods.getTransactionCount as jest.Mock).mockResolvedValueOnce( - mockRpcResponse, - ); - expect(await web3Eth.getTransactionCount(...input)).toStrictEqual( - output, - ); - expect(rpcMethods.getTransactionCount).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + 'input: %s\rpcMethodParameters: %s', + async (input, rpcMethodParameters) => { + await web3Eth.getTransactionCount(...input); + expect(rpcMethodWrappers.getTransactionCount).toHaveBeenCalledWith( + web3Eth.web3Context, ...rpcMethodParameters, ); }, @@ -270,14 +201,11 @@ describe('web3_eth_methods_with_parameters', () => { describe('estimateGas', () => { it.each(estimateGasValidData)( - 'input: %s\nmockRpcResponse: %s\nexpectedRpcMethodToBeCalled: %s\nrpcMethodParameters: %s\noutput: %s', - async (input, mockRpcResponse, rpcMethodParameters, output) => { - (rpcMethods.estimateGas as jest.Mock).mockResolvedValueOnce( - mockRpcResponse, - ); - expect(await web3Eth.estimateGas(...input)).toStrictEqual(output); - expect(rpcMethods.estimateGas).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + 'input: %s\nrpcMethodParameters: %s', + async (input, rpcMethodParameters) => { + await web3Eth.estimateGas(...input); + expect(rpcMethodWrappers.estimateGas).toHaveBeenCalledWith( + web3Eth.web3Context, ...rpcMethodParameters, ); }, @@ -286,14 +214,11 @@ describe('web3_eth_methods_with_parameters', () => { describe('getFeeHistory', () => { it.each(getFeeHistoryValidData)( - 'input: %s\nmockRpcResponse: %s\nexpectedRpcMethodToBeCalled: %s\nrpcMethodParameters: %s\noutput: %s', - async (input, mockRpcResponse, rpcMethodParameters, output) => { - (rpcMethods.getFeeHistory as jest.Mock).mockResolvedValueOnce( - mockRpcResponse, - ); - expect(await web3Eth.getFeeHistory(...input)).toStrictEqual(output); - expect(rpcMethods.getFeeHistory).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + 'input: %s\nrpcMethodParameters: %s', + async (input, rpcMethodParameters) => { + await web3Eth.getFeeHistory(...input); + expect(rpcMethodWrappers.getFeeHistory).toHaveBeenCalledWith( + web3Eth.web3Context, ...rpcMethodParameters, ); }, @@ -304,14 +229,11 @@ describe('web3_eth_methods_with_parameters', () => { describe("doesn't have returnType parameter", () => { describe('getStorageAt', () => { it.each(getStorageAtValidData)( - 'input: %s\nmockRpcResponse: %s\nrpcMethodParameters: %s\noutput: %s', - async (input, mockRpcResponse, rpcMethodParameters) => { - (rpcMethods.getStorageAt as jest.Mock).mockResolvedValueOnce( - mockRpcResponse, - ); - expect(await web3Eth.getStorageAt(...input)).toBe(mockRpcResponse); - expect(rpcMethods.getStorageAt).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + 'input: %s\nrpcMethodParameters: %s', + async (input, rpcMethodParameters) => { + await web3Eth.getStorageAt(...input); + expect(rpcMethodWrappers.getStorageAt).toHaveBeenCalledWith( + web3Eth.web3Context, ...rpcMethodParameters, ); }, @@ -320,14 +242,11 @@ describe('web3_eth_methods_with_parameters', () => { describe('getCode', () => { it.each(getCodeValidData)( - 'input: %s\nmockRpcResponse: %s\nrpcMethodParameters: %s\noutput: %s', - async (input, mockRpcResponse, rpcMethodParameters) => { - (rpcMethods.getCode as jest.Mock).mockResolvedValueOnce( - mockRpcResponse, - ); - expect(await web3Eth.getCode(...input)).toBe(mockRpcResponse); - expect(rpcMethods.getCode).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + 'input: %s\nrpcMethodParameters: %s', + async (input, rpcMethodParameters) => { + await web3Eth.getCode(...input); + expect(rpcMethodWrappers.getCode).toHaveBeenCalledWith( + web3Eth.web3Context, ...rpcMethodParameters, ); }, @@ -335,51 +254,32 @@ describe('web3_eth_methods_with_parameters', () => { }); describe('sendSignedTransaction', () => { - it.each(sendSignedTransactionValidData)( - 'input: %s\nmockRpcResponse: %s\nrpcMethodParameters: %s\noutput: %s', - async (input, mockRpcResponse) => { - (rpcMethods.sendRawTransaction as jest.Mock).mockResolvedValueOnce( - mockRpcResponse, - ); - expect(await web3Eth.sendSignedTransaction(input)).toBe( - mockRpcResponse, - ); - expect(rpcMethods.sendRawTransaction).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, - input, - ); - }, - ); + it.each(sendSignedTransactionValidData)('input: %s', async input => { + await web3Eth.sendSignedTransaction(input); + expect(rpcMethodWrappers.sendSignedTransaction).toHaveBeenCalledWith( + web3Eth.web3Context, + input, + ); + }); }); describe('sign', () => { - it.each(signValidData)( - 'input: %s\nmockRpcResponse: %s', - async (input, mockRpcResponse) => { - (rpcMethods.sign as jest.Mock).mockResolvedValueOnce(mockRpcResponse); - expect(await web3Eth.sign(...input)).toBe(mockRpcResponse); - expect(rpcMethods.sign).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, - // web3-eth methods takes sign(message, address) - // RPC method takes sign(address, message) - // so we manually swap them here - input[1], - input[0], - ); - }, - ); + it.each(signValidData)('input: %s', async input => { + await web3Eth.sign(...input); + expect(rpcMethodWrappers.sign).toHaveBeenCalledWith( + web3Eth.web3Context, + ...input, + ); + }); }); describe('getPastLogs', () => { it.each(getPastLogsValidData)( - 'input: %s\nmockRpcResponse: %s\nrpcMethodParameters: %s', - async (input, mockRpcResponse, rpcMethodParameters) => { - (rpcMethods.getLogs as jest.Mock).mockResolvedValueOnce( - mockRpcResponse, - ); - expect(await web3Eth.getPastLogs(input)).toBe(mockRpcResponse); - expect(rpcMethods.getLogs).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + 'input: %s\nrpcMethodParameters: %s', + async (input, rpcMethodParameters) => { + await web3Eth.getPastLogs(input); + expect(rpcMethodWrappers.getPastLogs).toHaveBeenCalledWith( + web3Eth.web3Context, rpcMethodParameters, ); }, @@ -387,19 +287,13 @@ describe('web3_eth_methods_with_parameters', () => { }); describe('submitWork', () => { - it.each(submitWorkValidData)( - 'input: %s\nmockRpcResponse: %s\nrpcMethodParameters: %s', - async (input, mockRpcResponse) => { - (rpcMethods.submitWork as jest.Mock).mockResolvedValueOnce( - mockRpcResponse, - ); - expect(await web3Eth.submitWork(...input)).toBe(mockRpcResponse); - expect(rpcMethods.submitWork).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, - ...input, - ); - }, - ); + it.each(submitWorkValidData)('input: %s', async input => { + await web3Eth.submitWork(...input); + expect(rpcMethodWrappers.submitWork).toHaveBeenCalledWith( + web3Eth.web3Context, + ...input, + ); + }); }); }); }); diff --git a/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts b/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts index 76cd1f34eb0..adb1fcaa0f2 100644 --- a/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts +++ b/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts @@ -45,7 +45,7 @@ import { sendSignedTransactionValidData, signValidData, submitWorkValidData, -} from '../fixtures/web3_eth_methods'; +} from '../fixtures/rpc_methods_wrappers'; jest.mock('../../src/rpc_methods'); From 93120285ef8a73561ca3cf2469b72d513c7177b7 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Sun, 30 Jan 2022 23:03:47 -1000 Subject: [PATCH 061/132] Replace if X === undefined checks with ? --- packages/web3-eth/src/eth_tx.ts | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 4f7c408e57d..f4ba1d9603f 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -75,20 +75,16 @@ export function formatTransaction< } } - if (formattedTransaction.common !== undefined) { - if (formattedTransaction.common.customChain !== undefined) { - if (formattedTransaction.common.customChain.networkId !== undefined) - formattedTransaction.common.customChain.networkId = convertToValidType( - formattedTransaction.common.customChain.networkId, - desiredType, - ); - if (formattedTransaction.common.customChain.chainId !== undefined) - formattedTransaction.common.customChain.chainId = convertToValidType( - formattedTransaction.common.customChain.chainId, - desiredType, - ); - } - } + if (formattedTransaction.common?.customChain?.networkId !== undefined) + formattedTransaction.common.customChain.networkId = convertToValidType( + formattedTransaction.common.customChain.networkId, + desiredType, + ); + if (formattedTransaction.common?.customChain?.chainId !== undefined) + formattedTransaction.common.customChain.chainId = convertToValidType( + formattedTransaction.common.customChain.chainId, + desiredType, + ); return formattedTransaction as Transaction; } From abfd252ecdfd45789858069114711462eed9b856 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Sun, 30 Jan 2022 23:04:01 -1000 Subject: [PATCH 062/132] Un-export consts that aren't used --- .../test/fixtures/rpc_methods_wrappers.ts | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/packages/web3-eth/test/fixtures/rpc_methods_wrappers.ts b/packages/web3-eth/test/fixtures/rpc_methods_wrappers.ts index e49734562e7..a861a8ef17f 100644 --- a/packages/web3-eth/test/fixtures/rpc_methods_wrappers.ts +++ b/packages/web3-eth/test/fixtures/rpc_methods_wrappers.ts @@ -235,7 +235,7 @@ export const getBalanceValidData: [ ], ]; -export const block: Block = { +const block: Block = { parentHash: '0xe99e022112df268087ea7eafaf4790497fd21dbeeb6bd7a1721df161a6657a54', sha3Uncles: '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347', miner: '0xbb7b8287f3f0a933474a79eae42cbca977791171', @@ -267,7 +267,7 @@ export const block: Block = { hash: '0xdc0818cf78f21a8e70579cb46a43643f78291264dda342ae31049421c82d21ae', baseFeePerGas: '0x13afe8b904', }; -export const transactionInfo: TransactionInfo = { +const transactionInfo: TransactionInfo = { blockHash: '0x1d59ff54b1eb26b013ce3cb5fc9dab3705b415a67127a003c3e61eb445bb8df2', blockNumber: '0x5daf3b', from: '0xa7d9ddbe1f17865597fbd27ec712455208b6b76d', @@ -286,12 +286,8 @@ export const transactionInfo: TransactionInfo = { maxFeePerGas: '0x1475505aab', maxPriorityFeePerGas: '0x7f324180', }; -export const hydratedTransactions: TransactionInfo[] = [ - transactionInfo, - transactionInfo, - transactionInfo, -]; -export const blockFormattedNumberString: BlockFormatted = { +const hydratedTransactions: TransactionInfo[] = [transactionInfo, transactionInfo, transactionInfo]; +const blockFormattedNumberString: BlockFormatted = { ...block, transactions: hydratedTransactions, difficulty: '21109876668', @@ -304,7 +300,7 @@ export const blockFormattedNumberString: BlockFormatted baseFeePerGas: '84555643140', size: '544', }; -export const blockFormattedNumber: BlockFormatted = { +const blockFormattedNumber: BlockFormatted = { ...block, transactions: hydratedTransactions, difficulty: 21109876668, @@ -317,7 +313,7 @@ export const blockFormattedNumber: BlockFormatted = { baseFeePerGas: 84555643140, size: 544, }; -export const blockFormattedBigInt: BlockFormatted = { +const blockFormattedBigInt: BlockFormatted = { ...block, transactions: hydratedTransactions, // TODO Change this to TransactionInfoFormatted From 64b9b08d9652e1b30321ea05ba1673971f3ce70a Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 31 Jan 2022 20:59:05 -1000 Subject: [PATCH 063/132] Add defaultTransactionType and defaultMaxPriorityFeePerGas --- packages/web3-core/src/types.ts | 4 ++- packages/web3-core/src/web3_config.ts | 32 ++++++++++++++++++++- packages/web3-eth/src/eth_tx.ts | 41 ++++++++++++++++++++------- 3 files changed, 64 insertions(+), 13 deletions(-) diff --git a/packages/web3-core/src/types.ts b/packages/web3-core/src/types.ts index c9534b92011..c7d9d49b702 100644 --- a/packages/web3-core/src/types.ts +++ b/packages/web3-core/src/types.ts @@ -6,7 +6,7 @@ import { JsonRpcResult, Web3BaseProvider, } from 'web3-common'; -import { HexString, ValidTypes } from 'web3-utils'; +import { HexString, Numbers, ValidTypes } from 'web3-utils'; export type LegacyRequestProvider = { request: ( @@ -52,4 +52,6 @@ export interface Web3ConfigOptions { defaultHardfork: string | null; defaultCommon: Record | null; defaultReturnType: ValidTypes; + defaultTransactionType: Numbers | null; + defaultMaxPriorityFeePerGas: Numbers; } diff --git a/packages/web3-core/src/web3_config.ts b/packages/web3-core/src/web3_config.ts index 8aa732764dd..c31e8d49f19 100644 --- a/packages/web3-core/src/web3_config.ts +++ b/packages/web3-core/src/web3_config.ts @@ -1,4 +1,4 @@ -import { ValidTypes } from 'web3-utils'; +import { toHex, ValidTypes } from 'web3-utils'; import { Web3EventEmitter } from 'web3-common'; import { Web3ConfigOptions } from './types'; @@ -28,6 +28,8 @@ export abstract class Web3Config defaultHardfork: null, defaultCommon: null, defaultReturnType: ValidTypes.HexString, + defaultTransactionType: null, + defaultMaxPriorityFeePerGas: toHex(2500000000), }; public getConfig() { @@ -196,4 +198,32 @@ export abstract class Web3Config this._config.defaultReturnType = val; } + + public get defaultTransactionType() { + return this._config.defaultTransactionType; + } + + public set defaultTransactionType(val) { + this.emit(Web3ConfigEvent.CONFIG_CHANGE, { + name: 'defaultTransactionType', + oldValue: this._config.defaultTransactionType, + newValue: val, + }); + + this._config.defaultTransactionType = val; + } + + public get defaultMaxPriorityFeePerGas() { + return this._config.defaultMaxPriorityFeePerGas; + } + + public set defaultMaxPriorityFeePerGas(val) { + this.emit(Web3ConfigEvent.CONFIG_CHANGE, { + name: 'defaultMaxPriorityFeePerGas', + oldValue: this._config.defaultMaxPriorityFeePerGas, + newValue: val, + }); + + this._config.defaultMaxPriorityFeePerGas = val; + } } diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index f4ba1d9603f..1791cfa47f0 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -28,7 +28,7 @@ import { UnsupportedFeeMarketError, UnsupportedTransactionTypeError, } from './errors'; -import { PopulatedUnsignedTransaction, Transaction } from './types'; +import { chain, hardfork, PopulatedUnsignedTransaction, Transaction } from './types'; import { getBlock, getGasPrice, getTransactionCount } from './rpc_method_wrappers'; export function formatTransaction< @@ -261,10 +261,17 @@ export async function populateTransaction< if (populatedTransaction.value === undefined) populatedTransaction.value = '0x'; if (populatedTransaction.data === undefined) populatedTransaction.data = '0x'; - // TODO - Add default to Web3Context - if (populatedTransaction.chain === undefined) populatedTransaction.chain = 'mainnet'; - // TODO - Add default to Web3Context - if (populatedTransaction.hardfork === undefined) populatedTransaction.hardfork = 'london'; + if (populatedTransaction.chain === undefined) { + populatedTransaction.chain = + web3Context.defaultChain !== null || web3Context.defaultChain !== undefined + ? (web3Context.defaultChain as chain) + : 'mainnet'; + } + if (populatedTransaction.hardfork === undefined) + populatedTransaction.hardfork = + web3Context.defaultHardfork !== null || web3Context.defaultHardfork !== undefined + ? (web3Context.defaultHardfork as hardfork) + : 'london'; if (populatedTransaction.chainId === undefined) { if (populatedTransaction.common?.customChain.chainId === undefined) { @@ -284,15 +291,25 @@ export async function populateTransaction< } populatedTransaction.type = detectTransactionType(populatedTransaction); - // TODO - After web3Context.defaultTxType is implemented - // if (populatedTransaction.type === undefined) populatedTransaction.type = '0x0'; // web3Context.defaultTxType; + if ( + populatedTransaction.type === undefined && + (web3Context.defaultTransactionType !== null || + web3Context.defaultTransactionType !== undefined) + ) + populatedTransaction.type = convertToValidType( + // TODO - TSC is complaining it could be null, even though we check above + web3Context.defaultTransactionType as Numbers, + ValidTypes.HexString, + ); if (populatedTransaction.type !== undefined) { - // TODO Probably need to account for negative hex strings const hexTxType = toHex(populatedTransaction.type); + if (hexTxType.startsWith('-')) + throw new UnsupportedTransactionTypeError(populatedTransaction.type); + + // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2718.md#transactions if (hexTxType < '0x0' || hexTxType > '0x7f') - // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2718.md#transactions throw new UnsupportedTransactionTypeError(populatedTransaction.type); if (hexTxType === '0x0' || hexTxType === '0x1') { @@ -317,8 +334,10 @@ export async function populateTransaction< populatedTransaction.gasPrice = undefined; } else { if (populatedTransaction.maxPriorityFeePerGas === undefined) - // TODO - Add maxPriorityFeePerGas default to Web3Context - populatedTransaction.maxPriorityFeePerGas = toHex(2500000000); // 2.5 Gwei + populatedTransaction.maxPriorityFeePerGas = convertToValidType( + web3Context.defaultMaxPriorityFeePerGas, + ValidTypes.HexString, + ); if (populatedTransaction.maxFeePerGas === undefined) populatedTransaction.maxFeePerGas = BigInt(block.baseFeePerGas) * BigInt(2) + From 63d841d278cceaf28c54ea28a4e834564c4df712 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 31 Jan 2022 21:43:25 -1000 Subject: [PATCH 064/132] Update defaults for chain and hardfork to mainnet and london --- packages/web3-core/src/web3_config.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/web3-core/src/web3_config.ts b/packages/web3-core/src/web3_config.ts index c31e8d49f19..4004ee718d3 100644 --- a/packages/web3-core/src/web3_config.ts +++ b/packages/web3-core/src/web3_config.ts @@ -24,8 +24,9 @@ export abstract class Web3Config transactionPollingTimeout: 750, blockHeaderTimeout: 10, maxListenersWarningThreshold: 100, - defaultChain: null, - defaultHardfork: null, + defaultChain: 'mainnet', + defaultHardfork: 'london', + // TODO - Check if there is a default Common defaultCommon: null, defaultReturnType: ValidTypes.HexString, defaultTransactionType: null, From aaa70ec9fb7aa440f8dae1a025f4e8060b5e5cc5 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 31 Jan 2022 21:44:09 -1000 Subject: [PATCH 065/132] Update to use web3Context.default chain and hardfork. Init tests for defaults --- packages/web3-eth/src/eth_tx.ts | 13 +-- .../test/unit/populate_transaction.test.ts | 104 +++++++++++++++++- 2 files changed, 106 insertions(+), 11 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 1791cfa47f0..70e95182039 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -95,6 +95,7 @@ export const detectTransactionType = ( ): HexString | undefined => { // TODO - Refactor overrideMethod if (overrideMethod !== undefined) return overrideMethod(transaction); + if (transaction.type !== undefined) return convertToValidType(transaction.type, ValidTypes.HexString) as HexString; @@ -262,16 +263,10 @@ export async function populateTransaction< if (populatedTransaction.value === undefined) populatedTransaction.value = '0x'; if (populatedTransaction.data === undefined) populatedTransaction.data = '0x'; if (populatedTransaction.chain === undefined) { - populatedTransaction.chain = - web3Context.defaultChain !== null || web3Context.defaultChain !== undefined - ? (web3Context.defaultChain as chain) - : 'mainnet'; + populatedTransaction.chain = web3Context.defaultChain as chain; } if (populatedTransaction.hardfork === undefined) - populatedTransaction.hardfork = - web3Context.defaultHardfork !== null || web3Context.defaultHardfork !== undefined - ? (web3Context.defaultHardfork as hardfork) - : 'london'; + populatedTransaction.hardfork = web3Context.defaultHardfork as hardfork; if (populatedTransaction.chainId === undefined) { if (populatedTransaction.common?.customChain.chainId === undefined) { @@ -322,9 +317,9 @@ export async function populateTransaction< } if (hexTxType === '0x2') { + // Unless otherwise specified by web3Context.defaultBlock, this defaults to latest const block = await getBlock(web3Context); - // Unless otherwise specified by web3Context.defaultBlock, this defaults to latest if (block.baseFeePerGas === undefined) throw new Eip1559NotSupportedError(); if (populatedTransaction.gasPrice !== undefined) { diff --git a/packages/web3-eth/test/unit/populate_transaction.test.ts b/packages/web3-eth/test/unit/populate_transaction.test.ts index 18dcd21c07c..1794baca321 100644 --- a/packages/web3-eth/test/unit/populate_transaction.test.ts +++ b/packages/web3-eth/test/unit/populate_transaction.test.ts @@ -27,6 +27,7 @@ describe('populateTransaction', () => { const expectedBaseFeePerGas = '0x13afe8b904'; const expectedMaxPriorityFeePerGas = '0x9502f900'; const expectedMaxFeePerGas = '0x27f4d46b08'; + const defaultTransactionType = '0x0'; const transaction: Transaction = { from: expectedFrom, to: '0x3535353535353535353535353535353535353535', @@ -189,23 +190,43 @@ describe('populateTransaction', () => { }); describe('should populate chain', () => { - it('should populate with 0x', async () => { + it('should populate with mainnet', async () => { const input = { ...transaction }; delete input.chain; const result = await populateTransaction(input, web3Context, ValidTypes.HexString); expect(result.chain).toBe('mainnet'); }); + + it('should use web3Context.defaultChain to populate', async () => { + web3Context = new Web3Context(new HttpProvider('http://127.0.0.1')); + + const input = { ...transaction }; + delete input.chain; + + const result = await populateTransaction(input, web3Context, ValidTypes.HexString); + expect(result.chain).toBe(web3Context.defaultChain); + }); }); describe('should populate hardfork', () => { - it('should populate with 0x', async () => { + it('should populate with london', async () => { const input = { ...transaction }; delete input.hardfork; const result = await populateTransaction(input, web3Context, ValidTypes.HexString); expect(result.hardfork).toBe('london'); }); + + it('should use web3Context.defaultHardfork to populate', async () => { + web3Context = new Web3Context(new HttpProvider('http://127.0.0.1')); + + const input = { ...transaction }; + delete input.hardfork; + + const result = await populateTransaction(input, web3Context, ValidTypes.HexString); + expect(result.hardfork).toBe(web3Context.defaultHardfork); + }); }); describe('should populate chainId', () => { @@ -248,6 +269,27 @@ describe('populateTransaction', () => { populateTransaction(input, web3Context, ValidTypes.HexString), ).rejects.toThrow(new UnsupportedTransactionTypeError(input.type)); }); + + it('should use web3Context.defaultTransactionType to populate', async () => { + web3Context = new Web3Context(new HttpProvider('http://127.0.0.1'), { + defaultTransactionType, + }); + + const input = { ...transaction }; + delete input.gas; + delete input.gasLimit; + delete input.gasPrice; + delete input.maxFeePerGas; + delete input.maxPriorityFeePerGas; + delete input.accessList; + delete input.type; + + input.hardfork = 'istanbul'; + if (input.common !== undefined) input.common.hardfork = 'istanbul'; + + const result = await populateTransaction(input, web3Context, ValidTypes.HexString); + expect(result.type).toBe(web3Context.defaultTransactionType); + }); }); describe('should populate gasPrice', () => { @@ -368,5 +410,63 @@ describe('populateTransaction', () => { expectedMaxFeePerGas, ); }); + + it('should populate with web3Context.defaultMaxPriorityFeePerGas and calculated maxFeePerGas (no maxPriorityFeePerGas and maxFeePerGas)', async () => { + const input = { ...transaction }; + delete input.maxPriorityFeePerGas; + delete input.maxFeePerGas; + delete input.gasPrice; + input.type = '0x2'; + + web3Context = new Web3Context(new HttpProvider('http://127.0.0.1'), { + defaultMaxPriorityFeePerGas: expectedMaxPriorityFeePerGas, + }); + + const result = await populateTransaction(input, web3Context, ValidTypes.HexString); + expect((result as PopulatedUnsignedEip1559Transaction).maxPriorityFeePerGas).toBe( + web3Context.defaultMaxPriorityFeePerGas, + ); // 2.5 Gwei, hardcoded in populateTransaction; + expect((result as PopulatedUnsignedEip1559Transaction).maxFeePerGas).toBe( + expectedMaxFeePerGas, + ); + }); + + it('should populate with web3Context.defaultMaxPriorityFeePerGas and calculated maxFeePerGas (no maxFeePerGas)', async () => { + const input = { ...transaction }; + delete input.maxFeePerGas; + delete input.gasPrice; + input.type = '0x2'; + + web3Context = new Web3Context(new HttpProvider('http://127.0.0.1'), { + defaultMaxPriorityFeePerGas: expectedMaxPriorityFeePerGas, + }); + + const result = await populateTransaction(input, web3Context, ValidTypes.HexString); + expect((result as PopulatedUnsignedEip1559Transaction).maxPriorityFeePerGas).toBe( + web3Context.defaultMaxPriorityFeePerGas, + ); // 2.5 Gwei, hardcoded in populateTransaction; + expect((result as PopulatedUnsignedEip1559Transaction).maxFeePerGas).toBe( + expectedMaxFeePerGas, + ); + }); + + it('should populate with web3Context.defaultMaxPriorityFeePerGas and calculated maxFeePerGas (no maxPriorityFeePerGas)', async () => { + const input = { ...transaction }; + delete input.maxPriorityFeePerGas; + delete input.gasPrice; + input.type = '0x2'; + + web3Context = new Web3Context(new HttpProvider('http://127.0.0.1'), { + defaultMaxPriorityFeePerGas: expectedMaxPriorityFeePerGas, + }); + + const result = await populateTransaction(input, web3Context, ValidTypes.HexString); + expect((result as PopulatedUnsignedEip1559Transaction).maxPriorityFeePerGas).toBe( + web3Context.defaultMaxPriorityFeePerGas, + ); // 2.5 Gwei, hardcoded in populateTransaction; + expect((result as PopulatedUnsignedEip1559Transaction).maxFeePerGas).toBe( + expectedMaxFeePerGas, + ); + }); }); }); From 95aebb9d1e17716ed82af540126d8c9e5e9bc1e3 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 31 Jan 2022 22:20:26 -1000 Subject: [PATCH 066/132] Update test to account for added defaults --- packages/web3-core/test/unit/web3_config.test.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/web3-core/test/unit/web3_config.test.ts b/packages/web3-core/test/unit/web3_config.test.ts index 77d9d590c1e..07a307e728a 100644 --- a/packages/web3-core/test/unit/web3_config.test.ts +++ b/packages/web3-core/test/unit/web3_config.test.ts @@ -1,4 +1,4 @@ -import { ValidTypes } from 'web3-utils'; +import { toHex, ValidTypes } from 'web3-utils'; import { Web3Config, Web3ConfigEvent } from '../../src/web3_config'; class MyConfigObject extends Web3Config {} @@ -7,15 +7,17 @@ const defaultConfig = { blockHeaderTimeout: 10, defaultAccount: null, defaultBlock: 'latest', - defaultChain: null, + defaultChain: 'mainnet', defaultCommon: null, - defaultHardfork: null, + defaultHardfork: 'london', defaultReturnType: ValidTypes.HexString, handleRevert: false, maxListenersWarningThreshold: 100, transactionBlockTimeout: 50, transactionConfirmationBlocks: 24, transactionPollingTimeout: 750, + defaultTransactionType: null, + defaultMaxPriorityFeePerGas: toHex(2500000000), }; describe('Web3Config', () => { From e91f019666d0441b0aa871a9c89e8cb923563d1d Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 31 Jan 2022 22:42:29 -1000 Subject: [PATCH 067/132] Refactor validateGas to use helper methods --- packages/web3-eth/src/eth_tx.ts | 84 ++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 37 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 70e95182039..c882940084b 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -117,7 +117,7 @@ export const detectTransactionType = ( return undefined; }; -const validateCustomChainInfo = (transaction: Transaction) => { +const _validateCustomChainInfo = (transaction: Transaction) => { if (transaction.common !== undefined) { if (transaction.common.customChain === undefined) throw new MissingCustomChainError(); if (transaction.common.customChain.chainId === undefined) @@ -133,7 +133,7 @@ const validateCustomChainInfo = (transaction: Transaction) => { } }; -const validateChainInfo = (transaction: Transaction) => { +const _validateChainInfo = (transaction: Transaction) => { if ( transaction.common !== undefined && transaction.chain !== undefined && @@ -150,37 +150,26 @@ const validateChainInfo = (transaction: Transaction) => { }); }; -// TODO Split into validateEipXXX methods -const validateGas = (transaction: Transaction) => { - const legacyGasPresent = transaction.gas !== undefined && transaction.gasLimit !== undefined; - const feeMarketGasPresent = - transaction.maxPriorityFeePerGas !== undefined && transaction.maxFeePerGas !== undefined; - - if (!legacyGasPresent && !feeMarketGasPresent) - throw new MissingGasError({ +const _validateLegacyGas = (transaction: Transaction) => { + if ( + // This check is verifying gas and gasPrice aren't less than 0. + // transaction's number properties have been converted to HexStrings. + // JavaScript doesn't handle negative hex strings e.g. -0x1, but our + // numberToHex method does. -0x1 < 0 would result in false, so we must check if + // hex string is negative via the inclusion of - + transaction.gas === undefined || + transaction.gasPrice === undefined || + transaction.gas.startsWith('-') || + transaction.gasPrice.startsWith('-') + ) + throw new InvalidGasOrGasPrice({ gas: transaction.gas, - gasLimit: transaction.gasLimit, - maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, - maxFeePerGas: transaction.maxFeePerGas, + gasPrice: transaction.gasPrice, }); +}; - if (legacyGasPresent) { - if ( - // This check is verifying gas and gasPrice aren't less than 0. - // transaction's number properties have been converted to HexStrings. - // JavaScript doesn't handle negative hex strings e.g. -0x1, but our - // numberToHex method does. -0x1 < 0 would result in false, so we must check if - // hex string is negative via the inclusion of - - transaction.gas === undefined || - transaction.gasPrice === undefined || - transaction.gas.startsWith('-') || - transaction.gasPrice.startsWith('-') - ) - throw new InvalidGasOrGasPrice({ - gas: transaction.gas, - gasPrice: transaction.gasPrice, - }); - } else if ( +const _validateFeeMarketGas = (transaction: Transaction) => { + if ( transaction.maxFeePerGas === undefined || transaction.maxPriorityFeePerGas === undefined || transaction.maxFeePerGas.startsWith('-') || @@ -190,18 +179,39 @@ const validateGas = (transaction: Transaction) => { maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, maxFeePerGas: transaction.maxFeePerGas, }); +}; - const hasEip1559 = - transaction.maxFeePerGas !== undefined || transaction.maxPriorityFeePerGas !== undefined; - if (transaction.gasPrice !== undefined && (transaction.type === '0x2' || hasEip1559)) +const _validateEip1559 = (transaction: Transaction) => { + if (transaction.gasPrice !== undefined && transaction.type === '0x2') throw new Eip1559GasPriceError(transaction.gasPrice); - if ((transaction.type === '0x0' || transaction.type === '0x1') && hasEip1559) + if (transaction.type === '0x0' || transaction.type === '0x1') throw new UnsupportedFeeMarketError({ maxFeePerGas: transaction.maxFeePerGas, maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, }); }; +// TODO Split into validateEipXXX methods +const _validateGas = (transaction: Transaction) => { + const legacyGasPresent = transaction.gas !== undefined && transaction.gasLimit !== undefined; + const feeMarketGasPresent = + transaction.maxPriorityFeePerGas !== undefined && transaction.maxFeePerGas !== undefined; + + if (!legacyGasPresent && !feeMarketGasPresent) + throw new MissingGasError({ + gas: transaction.gas, + gasLimit: transaction.gasLimit, + maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, + maxFeePerGas: transaction.maxFeePerGas, + }); + + (legacyGasPresent ? _validateLegacyGas : _validateFeeMarketGas)(transaction); + + const hasEip1559 = + transaction.maxFeePerGas !== undefined || transaction.maxPriorityFeePerGas !== undefined; + if (hasEip1559) _validateEip1559(transaction); +}; + export const validateTransactionForSigning = ( transaction: Transaction, overrideMethod?: (transaction: Transaction) => void, @@ -216,9 +226,9 @@ export const validateTransactionForSigning = ( const formattedTransaction = formatTransaction(transaction, ValidTypes.HexString); - validateCustomChainInfo(transaction); - validateChainInfo(transaction); - validateGas(formattedTransaction); + _validateCustomChainInfo(transaction); + _validateChainInfo(transaction); + _validateGas(formattedTransaction); if ( formattedTransaction.nonce === undefined || From 1dec5c8ed3e85646424e9ebe55bed85c42df04c0 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 31 Jan 2022 22:42:52 -1000 Subject: [PATCH 068/132] remove TODO --- packages/web3-eth/src/eth_tx.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index c882940084b..c537dcd6f46 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -191,7 +191,6 @@ const _validateEip1559 = (transaction: Transaction) => { }); }; -// TODO Split into validateEipXXX methods const _validateGas = (transaction: Transaction) => { const legacyGasPresent = transaction.gas !== undefined && transaction.gasLimit !== undefined; const feeMarketGasPresent = From b810f453a11a6f2addd60b3054db91f00ba929e0 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Tue, 1 Feb 2022 18:35:45 -1000 Subject: [PATCH 069/132] Init error TransactionGasMismatchError --- packages/web3-eth/src/errors.ts | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/packages/web3-eth/src/errors.ts b/packages/web3-eth/src/errors.ts index fd81b3f1ee2..80eb8d7d845 100644 --- a/packages/web3-eth/src/errors.ts +++ b/packages/web3-eth/src/errors.ts @@ -100,20 +100,42 @@ export class MissingGasError extends Web3Error { 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' - }, maxPriorityFeePerGas: ${value.maxPriorityFeePerGas ?? 'undefined'}, maxFeePerGas: ${ - value.maxFeePerGas ?? 'undefined' - }`, + }, gasPrice: ${value.gasPrice ?? 'undefined'}, maxPriorityFeePerGas: ${ + value.maxPriorityFeePerGas ?? 'undefined' + }, maxFeePerGas: ${value.maxFeePerGas ?? 'undefined'}`, '"gas" is missing', ); } } +export class TransactionGasMismatchError extends Web3Error { + 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 Web3Error { public code = ERR_TX_INVALID_LEGACY_GAS; From ccf4cc8d2998a5c85ec73bd91db10e8784d25cb2 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Tue, 1 Feb 2022 18:36:26 -1000 Subject: [PATCH 070/132] Fix tests and refactor transaction validator helper methods --- packages/web3-eth/src/eth_tx.ts | 61 ++++++++---- .../validate_transaction_for_signing.ts | 98 ++++++++++++------- 2 files changed, 106 insertions(+), 53 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index c537dcd6f46..2d10572a135 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -24,6 +24,7 @@ import { MissingCustomChainError, MissingCustomChainIdError, MissingGasError, + TransactionGasMismatchError, UnableToPopulateNonceError, UnsupportedFeeMarketError, UnsupportedTransactionTypeError, @@ -131,6 +132,8 @@ const _validateCustomChainInfo = (transaction: Transaction) => { customChainId: transaction.common.customChain.chainId, }); } + + // TODO - Should throw error? }; const _validateChainInfo = (transaction: Transaction) => { @@ -166,9 +169,25 @@ const _validateLegacyGas = (transaction: Transaction) => { gas: transaction.gas, gasPrice: transaction.gasPrice, }); + if (transaction.maxFeePerGas !== undefined || transaction.maxPriorityFeePerGas !== undefined) + throw new UnsupportedFeeMarketError({ + maxFeePerGas: transaction.maxFeePerGas, + maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, + }); }; const _validateFeeMarketGas = (transaction: Transaction) => { + // These errors come from 1.x, so they must be checked before + // InvalidMaxPriorityFeePerGasOrMaxFeePerGas to throw the same error + // for the same code executing in 1.x + if (transaction.gasPrice !== undefined && transaction.type === '0x2') + throw new Eip1559GasPriceError(transaction.gasPrice); + if (transaction.type === '0x0' || transaction.type === '0x1') + throw new UnsupportedFeeMarketError({ + maxFeePerGas: transaction.maxFeePerGas, + maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, + }); + if ( transaction.maxFeePerGas === undefined || transaction.maxPriorityFeePerGas === undefined || @@ -181,34 +200,40 @@ const _validateFeeMarketGas = (transaction: Transaction) => { }); }; -const _validateEip1559 = (transaction: Transaction) => { - if (transaction.gasPrice !== undefined && transaction.type === '0x2') - throw new Eip1559GasPriceError(transaction.gasPrice); - if (transaction.type === '0x0' || transaction.type === '0x1') - throw new UnsupportedFeeMarketError({ - maxFeePerGas: transaction.maxFeePerGas, - maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, - }); -}; - +/** + * This method checks if all required gas properties are present for either + * legacy gas (type 0x0 and 0x1) OR fee market transactions (0x2) + */ const _validateGas = (transaction: Transaction) => { - const legacyGasPresent = transaction.gas !== undefined && transaction.gasLimit !== undefined; + const gasPresent = transaction.gas !== undefined || transaction.gasLimit !== undefined; + const legacyGasPresent = gasPresent && transaction.gasPrice !== undefined; const feeMarketGasPresent = - transaction.maxPriorityFeePerGas !== undefined && transaction.maxFeePerGas !== undefined; + gasPresent && + transaction.maxPriorityFeePerGas !== undefined && + transaction.maxFeePerGas !== undefined; if (!legacyGasPresent && !feeMarketGasPresent) throw new MissingGasError({ gas: transaction.gas, gasLimit: transaction.gasLimit, + gasPrice: transaction.gasPrice, maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, maxFeePerGas: transaction.maxFeePerGas, }); - (legacyGasPresent ? _validateLegacyGas : _validateFeeMarketGas)(transaction); + if (legacyGasPresent && feeMarketGasPresent) + throw new TransactionGasMismatchError({ + gas: transaction.gas, + gasLimit: transaction.gasLimit, + gasPrice: transaction.gasPrice, + maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, + maxFeePerGas: transaction.maxFeePerGas, + }); - const hasEip1559 = - transaction.maxFeePerGas !== undefined || transaction.maxPriorityFeePerGas !== undefined; - if (hasEip1559) _validateEip1559(transaction); + (legacyGasPresent ? _validateLegacyGas : _validateFeeMarketGas)(transaction); + (transaction.type !== undefined && transaction.type < '0x1' + ? _validateLegacyGas + : _validateFeeMarketGas)(transaction); }; export const validateTransactionForSigning = ( @@ -223,10 +248,10 @@ export const validateTransactionForSigning = ( if (typeof transaction !== 'object' || transaction === null) throw new InvalidTransactionObjectError(transaction); - const formattedTransaction = formatTransaction(transaction, ValidTypes.HexString); - _validateCustomChainInfo(transaction); _validateChainInfo(transaction); + + const formattedTransaction = formatTransaction(transaction, ValidTypes.HexString); _validateGas(formattedTransaction); if ( 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 6da7b2943f1..a4f35037a05 100644 --- a/packages/web3-eth/test/fixtures/validate_transaction_for_signing.ts +++ b/packages/web3-eth/test/fixtures/validate_transaction_for_signing.ts @@ -10,6 +10,7 @@ import { MissingCustomChainError, MissingCustomChainIdError, MissingGasError, + TransactionGasMismatchError, UnsupportedFeeMarketError, } from '../../src/errors'; import { Transaction } from '../../src/types'; @@ -355,6 +356,7 @@ export const validateGasData: [ new MissingGasError({ gas: undefined, gasLimit: undefined, + gasPrice: undefined, maxPriorityFeePerGas: undefined, maxFeePerGas: undefined, }), @@ -376,14 +378,19 @@ export const validateGasData: [ r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', }, - new InvalidGasOrGasPrice({ gas: '0x5208', gasPrice: undefined }), + new MissingGasError({ + gas: '0x5208', + gasLimit: '0x5208', + gasPrice: undefined, + maxFeePerGas: undefined, + maxPriorityFeePerGas: undefined, + }), ], [ { from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', to: '0x3535353535353535353535353535353535353535', value: '0x174876e800', - gasPrice: '0x4a817c800', type: '0x0', data: '0x0', nonce: '0x4', @@ -398,6 +405,7 @@ export const validateGasData: [ new MissingGasError({ gas: undefined, gasLimit: '0x5208', + gasPrice: undefined, maxFeePerGas: undefined, maxPriorityFeePerGas: undefined, }), @@ -462,6 +470,7 @@ export const validateGasData: [ new MissingGasError({ gas: undefined, gasLimit: '0x5208', + gasPrice: undefined, maxPriorityFeePerGas: undefined, maxFeePerGas: '0x1229298c00', }), @@ -486,6 +495,7 @@ export const validateGasData: [ new MissingGasError({ gas: undefined, gasLimit: '0x5208', + gasPrice: undefined, maxPriorityFeePerGas: '0x49504f80', maxFeePerGas: undefined, }), @@ -495,7 +505,9 @@ export const validateGasData: [ from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', to: '0x3535353535353535353535353535353535353535', value: '0x174876e800', - maxFeePerGas: '-0x1229298c00', + gas: '0x5208', + gasPrice: '0x4a817c800', + maxFeePerGas: '0x1229298c00', maxPriorityFeePerGas: '0x49504f80', type: '0x2', data: '0x0', @@ -508,9 +520,12 @@ export const validateGasData: [ r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', }, - new InvalidMaxPriorityFeePerGasOrMaxFeePerGas({ + new TransactionGasMismatchError({ + gas: '0x5208', + gasLimit: '0x5208', + gasPrice: '0x4a817c800', + maxFeePerGas: '0x1229298c00', maxPriorityFeePerGas: '0x49504f80', - maxFeePerGas: '-0x1229298c00', }), ], [ @@ -518,9 +533,11 @@ export const validateGasData: [ from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', to: '0x3535353535353535353535353535353535353535', value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', maxFeePerGas: '0x1229298c00', - maxPriorityFeePerGas: '-0x49504f80', - type: '0x2', + maxPriorityFeePerGas: '0x49504f80', + type: '0x0', data: '0x0', nonce: '0x4', chain: 'mainnet', @@ -531,9 +548,12 @@ export const validateGasData: [ r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', }, - new InvalidMaxPriorityFeePerGasOrMaxFeePerGas({ - maxPriorityFeePerGas: '-0x49504f80', + new TransactionGasMismatchError({ + gas: '0x5208', + gasLimit: '0x5208', + gasPrice: '0x4a817c800', maxFeePerGas: '0x1229298c00', + maxPriorityFeePerGas: '0x49504f80', }), ], [ @@ -541,10 +561,9 @@ export const validateGasData: [ from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', to: '0x3535353535353535353535353535353535353535', value: '0x174876e800', - gas: '0x5208', - gasPrice: '0x4a817c800', - maxFeePerGas: '0x1229298c00', - type: '0x0', + maxFeePerGas: '-0x1229298c00', + maxPriorityFeePerGas: '0x49504f80', + type: '0x2', data: '0x0', nonce: '0x4', chain: 'mainnet', @@ -555,17 +574,19 @@ export const validateGasData: [ r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', }, - new Eip1559GasPriceError('0x4a817c800'), + new InvalidMaxPriorityFeePerGasOrMaxFeePerGas({ + maxPriorityFeePerGas: '0x49504f80', + maxFeePerGas: '-0x1229298c00', + }), ], [ { from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', to: '0x3535353535353535353535353535353535353535', value: '0x174876e800', - gas: '0x5208', - gasPrice: '0x4a817c800', - maxPriorityFeePerGas: '0x49504f80', - type: '0x0', + maxFeePerGas: '0x1229298c00', + maxPriorityFeePerGas: '-0x49504f80', + type: '0x2', data: '0x0', nonce: '0x4', chain: 'mainnet', @@ -576,7 +597,10 @@ export const validateGasData: [ r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', }, - new Eip1559GasPriceError('0x4a817c800'), + new InvalidMaxPriorityFeePerGasOrMaxFeePerGas({ + maxPriorityFeePerGas: '-0x49504f80', + maxFeePerGas: '0x1229298c00', + }), ], [ { @@ -585,9 +609,7 @@ export const validateGasData: [ value: '0x174876e800', gas: '0x5208', gasPrice: '0x4a817c800', - maxFeePerGas: '0x1229298c00', - maxPriorityFeePerGas: '0x49504f80', - type: '0x0', + type: '0x2', data: '0x0', nonce: '0x4', chain: 'mainnet', @@ -605,11 +627,9 @@ export const validateGasData: [ from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', to: '0x3535353535353535353535353535353535353535', value: '0x174876e800', - gas: '0x5208', - gasPrice: '0x4a817c800', maxFeePerGas: '0x1229298c00', maxPriorityFeePerGas: '0x49504f80', - type: '0x2', + type: '0x0', data: '0x0', nonce: '0x4', chain: 'mainnet', @@ -620,16 +640,19 @@ export const validateGasData: [ r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', }, - new Eip1559GasPriceError('0x4a817c800'), + new UnsupportedFeeMarketError({ + maxFeePerGas: '0x1229298c00', + maxPriorityFeePerGas: '0x49504f80', + }), ], [ { from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', to: '0x3535353535353535353535353535353535353535', value: '0x174876e800', - gas: '0x5208', - gasPrice: '0x4a817c800', - type: '0x2', + maxFeePerGas: '0x1229298c00', + maxPriorityFeePerGas: '0x49504f80', + type: '0x1', data: '0x0', nonce: '0x4', chain: 'mainnet', @@ -640,14 +663,18 @@ export const validateGasData: [ r: '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', }, - new Eip1559GasPriceError('0x4a817c800'), + new UnsupportedFeeMarketError({ + maxFeePerGas: '0x1229298c00', + maxPriorityFeePerGas: '0x49504f80', + }), ], [ { from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', to: '0x3535353535353535353535353535353535353535', value: '0x174876e800', - maxFeePerGas: '0x1229298c00', + gas: '0x5208', + gasPrice: '0x4a817c800', maxPriorityFeePerGas: '0x49504f80', type: '0x0', data: '0x0', @@ -661,7 +688,7 @@ export const validateGasData: [ s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', }, new UnsupportedFeeMarketError({ - maxFeePerGas: '0x1229298c00', + maxFeePerGas: undefined, maxPriorityFeePerGas: '0x49504f80', }), ], @@ -670,9 +697,10 @@ export const validateGasData: [ from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', to: '0x3535353535353535353535353535353535353535', value: '0x174876e800', + gas: '0x5208', + gasPrice: '0x4a817c800', maxFeePerGas: '0x1229298c00', - maxPriorityFeePerGas: '0x49504f80', - type: '0x1', + type: '0x0', data: '0x0', nonce: '0x4', chain: 'mainnet', @@ -685,7 +713,7 @@ export const validateGasData: [ }, new UnsupportedFeeMarketError({ maxFeePerGas: '0x1229298c00', - maxPriorityFeePerGas: '0x49504f80', + maxPriorityFeePerGas: undefined, }), ], ]; From 74989ad1ac82fc3b3b6ba3fe53117b03b53d539f Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Tue, 1 Feb 2022 19:08:39 -1000 Subject: [PATCH 071/132] Move validation methods to validation.ts --- packages/web3-eth/src/eth_tx.ts | 136 +--------------------------- packages/web3-eth/src/validation.ts | 136 +++++++++++++++++++++++++++- 2 files changed, 139 insertions(+), 133 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 2d10572a135..3ea5b0a8689 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -12,25 +12,15 @@ import { import { privateKeyToAddress } from 'web3-eth-accounts'; import { - ChainIdMismatchError, - CommonOrChainAndHardforkError, - Eip1559GasPriceError, Eip1559NotSupportedError, - InvalidGasOrGasPrice, - InvalidMaxPriorityFeePerGasOrMaxFeePerGas, InvalidNonceOrChainIdError, InvalidTransactionObjectError, - MissingChainOrHardforkError, - MissingCustomChainError, - MissingCustomChainIdError, - MissingGasError, - TransactionGasMismatchError, UnableToPopulateNonceError, - UnsupportedFeeMarketError, UnsupportedTransactionTypeError, } from './errors'; import { chain, hardfork, PopulatedUnsignedTransaction, Transaction } from './types'; import { getBlock, getGasPrice, getTransactionCount } from './rpc_method_wrappers'; +import { validateChainInfo, validateCustomChainInfo, validateGas } from './validation'; export function formatTransaction< DesiredType extends ValidTypes, @@ -118,124 +108,6 @@ export const detectTransactionType = ( return undefined; }; -const _validateCustomChainInfo = (transaction: Transaction) => { - if (transaction.common !== undefined) { - if (transaction.common.customChain === undefined) throw new MissingCustomChainError(); - if (transaction.common.customChain.chainId === undefined) - throw new MissingCustomChainIdError(); - if ( - transaction.chainId !== undefined && - transaction.chainId !== transaction.common.customChain.chainId - ) - throw new ChainIdMismatchError({ - txChainId: transaction.chainId, - customChainId: transaction.common.customChain.chainId, - }); - } - - // TODO - Should throw error? -}; - -const _validateChainInfo = (transaction: Transaction) => { - if ( - transaction.common !== undefined && - transaction.chain !== undefined && - transaction.hardfork !== undefined - ) - throw new CommonOrChainAndHardforkError(); - if ( - (transaction.chain !== undefined && transaction.hardfork === undefined) || - (transaction.hardfork !== undefined && transaction.chain === undefined) - ) - throw new MissingChainOrHardforkError({ - chain: transaction.chain, - hardfork: transaction.hardfork, - }); -}; - -const _validateLegacyGas = (transaction: Transaction) => { - if ( - // This check is verifying gas and gasPrice aren't less than 0. - // transaction's number properties have been converted to HexStrings. - // JavaScript doesn't handle negative hex strings e.g. -0x1, but our - // numberToHex method does. -0x1 < 0 would result in false, so we must check if - // hex string is negative via the inclusion of - - transaction.gas === undefined || - transaction.gasPrice === undefined || - transaction.gas.startsWith('-') || - transaction.gasPrice.startsWith('-') - ) - throw new InvalidGasOrGasPrice({ - gas: transaction.gas, - gasPrice: transaction.gasPrice, - }); - if (transaction.maxFeePerGas !== undefined || transaction.maxPriorityFeePerGas !== undefined) - throw new UnsupportedFeeMarketError({ - maxFeePerGas: transaction.maxFeePerGas, - maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, - }); -}; - -const _validateFeeMarketGas = (transaction: Transaction) => { - // These errors come from 1.x, so they must be checked before - // InvalidMaxPriorityFeePerGasOrMaxFeePerGas to throw the same error - // for the same code executing in 1.x - if (transaction.gasPrice !== undefined && transaction.type === '0x2') - throw new Eip1559GasPriceError(transaction.gasPrice); - if (transaction.type === '0x0' || transaction.type === '0x1') - throw new UnsupportedFeeMarketError({ - maxFeePerGas: transaction.maxFeePerGas, - maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, - }); - - if ( - transaction.maxFeePerGas === undefined || - transaction.maxPriorityFeePerGas === undefined || - transaction.maxFeePerGas.startsWith('-') || - transaction.maxPriorityFeePerGas.startsWith('-') - ) - throw new InvalidMaxPriorityFeePerGasOrMaxFeePerGas({ - maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, - maxFeePerGas: transaction.maxFeePerGas, - }); -}; - -/** - * This method checks if all required gas properties are present for either - * legacy gas (type 0x0 and 0x1) OR fee market transactions (0x2) - */ -const _validateGas = (transaction: Transaction) => { - const gasPresent = transaction.gas !== undefined || transaction.gasLimit !== undefined; - const legacyGasPresent = gasPresent && transaction.gasPrice !== undefined; - const feeMarketGasPresent = - gasPresent && - transaction.maxPriorityFeePerGas !== undefined && - transaction.maxFeePerGas !== undefined; - - if (!legacyGasPresent && !feeMarketGasPresent) - throw new MissingGasError({ - gas: transaction.gas, - gasLimit: transaction.gasLimit, - gasPrice: transaction.gasPrice, - maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, - maxFeePerGas: transaction.maxFeePerGas, - }); - - if (legacyGasPresent && feeMarketGasPresent) - throw new TransactionGasMismatchError({ - gas: transaction.gas, - gasLimit: transaction.gasLimit, - gasPrice: transaction.gasPrice, - maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, - maxFeePerGas: transaction.maxFeePerGas, - }); - - (legacyGasPresent ? _validateLegacyGas : _validateFeeMarketGas)(transaction); - (transaction.type !== undefined && transaction.type < '0x1' - ? _validateLegacyGas - : _validateFeeMarketGas)(transaction); -}; - export const validateTransactionForSigning = ( transaction: Transaction, overrideMethod?: (transaction: Transaction) => void, @@ -248,11 +120,11 @@ export const validateTransactionForSigning = ( if (typeof transaction !== 'object' || transaction === null) throw new InvalidTransactionObjectError(transaction); - _validateCustomChainInfo(transaction); - _validateChainInfo(transaction); + validateCustomChainInfo(transaction); + validateChainInfo(transaction); const formattedTransaction = formatTransaction(transaction, ValidTypes.HexString); - _validateGas(formattedTransaction); + validateGas(formattedTransaction); if ( formattedTransaction.nonce === undefined || diff --git a/packages/web3-eth/src/validation.ts b/packages/web3-eth/src/validation.ts index 26d79854d78..7c52032626e 100644 --- a/packages/web3-eth/src/validation.ts +++ b/packages/web3-eth/src/validation.ts @@ -8,8 +8,24 @@ import { TransactionLegacyUnsigned, TransactionWithSender, } from 'web3-common'; +import { HexString } from 'web3-utils'; import { isAddress, isHexStrict, isHexString32Bytes } from 'web3-validator'; -import { InvalidTransactionCall, InvalidTransactionWithSender } from './errors'; +import { + ChainIdMismatchError, + CommonOrChainAndHardforkError, + Eip1559GasPriceError, + InvalidGasOrGasPrice, + InvalidMaxPriorityFeePerGasOrMaxFeePerGas, + InvalidTransactionCall, + InvalidTransactionWithSender, + MissingChainOrHardforkError, + MissingCustomChainError, + MissingCustomChainIdError, + MissingGasError, + TransactionGasMismatchError, + UnsupportedFeeMarketError, +} from './errors'; +import { Transaction } from './types'; export function isBaseTransaction(value: BaseTransaction): boolean { if (value.to !== undefined && value?.to !== null && !isAddress(value.to)) return false; @@ -102,3 +118,121 @@ export function isTransactionCall(value: TransactionCall): boolean { export function validateTransactionCall(value: TransactionCall) { if (!isTransactionCall(value)) throw new InvalidTransactionCall(value); } + +export const validateCustomChainInfo = (transaction: Transaction) => { + if (transaction.common !== undefined) { + if (transaction.common.customChain === undefined) throw new MissingCustomChainError(); + if (transaction.common.customChain.chainId === undefined) + throw new MissingCustomChainIdError(); + if ( + transaction.chainId !== undefined && + transaction.chainId !== transaction.common.customChain.chainId + ) + throw new ChainIdMismatchError({ + txChainId: transaction.chainId, + customChainId: transaction.common.customChain.chainId, + }); + } + + // TODO - Should throw error? +}; + +export const validateChainInfo = (transaction: Transaction) => { + if ( + transaction.common !== undefined && + transaction.chain !== undefined && + transaction.hardfork !== undefined + ) + throw new CommonOrChainAndHardforkError(); + if ( + (transaction.chain !== undefined && transaction.hardfork === undefined) || + (transaction.hardfork !== undefined && transaction.chain === undefined) + ) + throw new MissingChainOrHardforkError({ + chain: transaction.chain, + hardfork: transaction.hardfork, + }); +}; + +export const validateLegacyGas = (transaction: Transaction) => { + if ( + // This check is verifying gas and gasPrice aren't less than 0. + // transaction's number properties have been converted to HexStrings. + // JavaScript doesn't handle negative hex strings e.g. -0x1, but our + // numberToHex method does. -0x1 < 0 would result in false, so we must check if + // hex string is negative via the inclusion of - + transaction.gas === undefined || + transaction.gasPrice === undefined || + transaction.gas.startsWith('-') || + transaction.gasPrice.startsWith('-') + ) + throw new InvalidGasOrGasPrice({ + gas: transaction.gas, + gasPrice: transaction.gasPrice, + }); + if (transaction.maxFeePerGas !== undefined || transaction.maxPriorityFeePerGas !== undefined) + throw new UnsupportedFeeMarketError({ + maxFeePerGas: transaction.maxFeePerGas, + maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, + }); +}; + +export const validateFeeMarketGas = (transaction: Transaction) => { + // These errors come from 1.x, so they must be checked before + // InvalidMaxPriorityFeePerGasOrMaxFeePerGas to throw the same error + // for the same code executing in 1.x + if (transaction.gasPrice !== undefined && transaction.type === '0x2') + throw new Eip1559GasPriceError(transaction.gasPrice); + if (transaction.type === '0x0' || transaction.type === '0x1') + throw new UnsupportedFeeMarketError({ + maxFeePerGas: transaction.maxFeePerGas, + maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, + }); + + if ( + transaction.maxFeePerGas === undefined || + transaction.maxPriorityFeePerGas === undefined || + transaction.maxFeePerGas.startsWith('-') || + transaction.maxPriorityFeePerGas.startsWith('-') + ) + throw new InvalidMaxPriorityFeePerGasOrMaxFeePerGas({ + maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, + maxFeePerGas: transaction.maxFeePerGas, + }); +}; + +/** + * This method checks if all required gas properties are present for either + * legacy gas (type 0x0 and 0x1) OR fee market transactions (0x2) + */ +export const validateGas = (transaction: Transaction) => { + const gasPresent = transaction.gas !== undefined || transaction.gasLimit !== undefined; + const legacyGasPresent = gasPresent && transaction.gasPrice !== undefined; + const feeMarketGasPresent = + gasPresent && + transaction.maxPriorityFeePerGas !== undefined && + transaction.maxFeePerGas !== undefined; + + if (!legacyGasPresent && !feeMarketGasPresent) + throw new MissingGasError({ + gas: transaction.gas, + gasLimit: transaction.gasLimit, + gasPrice: transaction.gasPrice, + maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, + maxFeePerGas: transaction.maxFeePerGas, + }); + + if (legacyGasPresent && feeMarketGasPresent) + throw new TransactionGasMismatchError({ + gas: transaction.gas, + gasLimit: transaction.gasLimit, + gasPrice: transaction.gasPrice, + maxPriorityFeePerGas: transaction.maxPriorityFeePerGas, + maxFeePerGas: transaction.maxFeePerGas, + }); + + (legacyGasPresent ? validateLegacyGas : validateFeeMarketGas)(transaction); + (transaction.type !== undefined && transaction.type < '0x1' + ? validateLegacyGas + : validateFeeMarketGas)(transaction); +}; From 6373134c4ee1515700494cab61a819ec70544cb7 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Wed, 2 Feb 2022 20:59:47 -1000 Subject: [PATCH 072/132] Add input to Transaction type --- packages/web3-eth/src/types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/web3-eth/src/types.ts b/packages/web3-eth/src/types.ts index 7fc303acbfb..95bc4e5d0a2 100644 --- a/packages/web3-eth/src/types.ts +++ b/packages/web3-eth/src/types.ts @@ -52,6 +52,7 @@ export interface Transaction { maxPriorityFeePerGas?: NumberType; accessList?: AccessList; data?: HexStringBytes; + input?: HexStringBytes; nonce?: NumberType; chain?: chain; hardfork?: hardfork; From 3c1657586496e6409ced7187f9d881cf9c82738d Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Wed, 2 Feb 2022 21:00:03 -1000 Subject: [PATCH 073/132] Add @ethereumjs/common dependency --- packages/web3-eth/package.json | 1 + yarn.lock | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/packages/web3-eth/package.json b/packages/web3-eth/package.json index 3781f4ec864..ad48da1708e 100644 --- a/packages/web3-eth/package.json +++ b/packages/web3-eth/package.json @@ -40,6 +40,7 @@ "web3-providers-http": "4.0.0-alpha.1" }, "dependencies": { + "@ethereumjs/common": "^2.6.1", "@ethereumjs/tx": "^3.4.0", "web3-common": "1.0.0-alpha.0", "web3-core": "4.0.0-alpha.0", diff --git a/yarn.lock b/yarn.lock index 5c00679cd88..1d60086c240 100644 --- a/yarn.lock +++ b/yarn.lock @@ -321,6 +321,14 @@ crc-32 "^1.2.0" ethereumjs-util "^7.1.3" +"@ethereumjs/common@^2.6.1": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.6.1.tgz#7cf8947b928506f84551f15e00af1bbb505f4dbd" + integrity sha512-eUe5RsYiOnazszPsgQOdaetCwgVquiiQHBpB59xNABOrBPNh/ZdTJz+uhHGzKvPm6Dr91ViBGYZcdclTgtki0g== + dependencies: + crc-32 "^1.2.0" + ethereumjs-util "^7.1.4" + "@ethereumjs/tx@^3.4.0": version "3.4.0" resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.4.0.tgz#7eb1947eefa55eb9cf05b3ca116fb7a3dbd0bce7" @@ -3428,6 +3436,17 @@ ethereumjs-util@^7.1.3: ethereum-cryptography "^0.1.3" rlp "^2.2.4" +ethereumjs-util@^7.1.4: + version "7.1.4" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.4.tgz#a6885bcdd92045b06f596c7626c3e89ab3312458" + integrity sha512-p6KmuPCX4mZIqsQzXfmSx9Y0l2hqf+VkAiwSisW3UKUFdk8ZkAt+AYaor83z2nSi6CU2zSsXMlD80hAbNEGM0A== + dependencies: + "@types/bn.js" "^5.1.0" + bn.js "^5.1.2" + create-hash "^1.1.2" + ethereum-cryptography "^0.1.3" + rlp "^2.2.4" + eventemitter3@^4.0.4: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" From 989c2dd287b9c2c3b7521c070837b64ea698e5be Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Wed, 2 Feb 2022 21:00:19 -1000 Subject: [PATCH 074/132] yarn format --- packages/web3-eth/src/validation.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/web3-eth/src/validation.ts b/packages/web3-eth/src/validation.ts index 7c52032626e..07ebe72aa50 100644 --- a/packages/web3-eth/src/validation.ts +++ b/packages/web3-eth/src/validation.ts @@ -142,8 +142,9 @@ export const validateChainInfo = (transaction: Transaction) => { transaction.common !== undefined && transaction.chain !== undefined && transaction.hardfork !== undefined - ) + ) { throw new CommonOrChainAndHardforkError(); + } if ( (transaction.chain !== undefined && transaction.hardfork === undefined) || (transaction.hardfork !== undefined && transaction.chain === undefined) From aa985ac77228a33f3f4c32b60b5eb0212b0c50cd Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Thu, 3 Feb 2022 00:53:33 -1000 Subject: [PATCH 075/132] Remove null for defaultTransactionType --- packages/web3-core/src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web3-core/src/types.ts b/packages/web3-core/src/types.ts index c7d9d49b702..0945735d659 100644 --- a/packages/web3-core/src/types.ts +++ b/packages/web3-core/src/types.ts @@ -52,6 +52,6 @@ export interface Web3ConfigOptions { defaultHardfork: string | null; defaultCommon: Record | null; defaultReturnType: ValidTypes; - defaultTransactionType: Numbers | null; + defaultTransactionType: Numbers; defaultMaxPriorityFeePerGas: Numbers; } From 69cc3cff79a3f469be7f790d4d2e2243b128ec57 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Thu, 3 Feb 2022 00:53:42 -1000 Subject: [PATCH 076/132] Add default for defaultTransactionType --- packages/web3-core/src/web3_config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web3-core/src/web3_config.ts b/packages/web3-core/src/web3_config.ts index 4004ee718d3..652dacda885 100644 --- a/packages/web3-core/src/web3_config.ts +++ b/packages/web3-core/src/web3_config.ts @@ -29,7 +29,7 @@ export abstract class Web3Config // TODO - Check if there is a default Common defaultCommon: null, defaultReturnType: ValidTypes.HexString, - defaultTransactionType: null, + defaultTransactionType: '0x0', defaultMaxPriorityFeePerGas: toHex(2500000000), }; From 2bf6c5bb790ca24fc155314b1397cfc3fac7eacf Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Thu, 3 Feb 2022 01:02:07 -1000 Subject: [PATCH 077/132] Update default for defaultTransactionType --- packages/web3-core/test/unit/web3_config.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web3-core/test/unit/web3_config.test.ts b/packages/web3-core/test/unit/web3_config.test.ts index 07a307e728a..b093462a788 100644 --- a/packages/web3-core/test/unit/web3_config.test.ts +++ b/packages/web3-core/test/unit/web3_config.test.ts @@ -16,7 +16,7 @@ const defaultConfig = { transactionBlockTimeout: 50, transactionConfirmationBlocks: 24, transactionPollingTimeout: 750, - defaultTransactionType: null, + defaultTransactionType: '0x0', defaultMaxPriorityFeePerGas: toHex(2500000000), }; From 0bcc33d6b82dca38ab3ec9b8b4b6412ffb6c4abc Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Thu, 3 Feb 2022 01:11:58 -1000 Subject: [PATCH 078/132] Bug fixes, refactors, and init prepareTransactionForSigning and tests --- packages/web3-eth/src/eth_tx.ts | 152 ++- packages/web3-eth/src/validation.ts | 6 +- .../prepare_transaction_for_signing.ts | 889 ++++++++++++++++++ .../prepare_transaction_for_signing.test.ts | 100 ++ 4 files changed, 1113 insertions(+), 34 deletions(-) create mode 100644 packages/web3-eth/test/fixtures/prepare_transaction_for_signing.ts create mode 100644 packages/web3-eth/test/unit/prepare_transaction_for_signing.test.ts diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 3ea5b0a8689..fd6db749e91 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -6,10 +6,13 @@ import { HexString, Numbers, toHex, + toNumber, ValidReturnTypes, ValidTypes, } from 'web3-utils'; import { privateKeyToAddress } from 'web3-eth-accounts'; +import { TransactionFactory, TxOptions } from '@ethereumjs/tx'; +import Common from '@ethereumjs/common'; import { Eip1559NotSupportedError, @@ -18,7 +21,14 @@ import { UnableToPopulateNonceError, UnsupportedTransactionTypeError, } from './errors'; -import { chain, hardfork, PopulatedUnsignedTransaction, Transaction } from './types'; +import { + chain, + hardfork, + PopulatedUnsignedEip1559Transaction, + PopulatedUnsignedEip2930Transaction, + PopulatedUnsignedTransaction, + Transaction, +} from './types'; import { getBlock, getGasPrice, getTransactionCount } from './rpc_method_wrappers'; import { validateChainInfo, validateCustomChainInfo, validateGas } from './validation'; @@ -30,13 +40,12 @@ export function formatTransaction< // I tried using Object.assign({}, transaction) which is supposed to perform a deep copy, // but format_transactions.test.ts were still failing due to original nested object properties // being wrongfully updated by this method. - const formattedTransaction = { - ...transaction, - common: { - ...transaction.common, - customChain: { ...transaction.common?.customChain }, - }, - }; + const formattedTransaction = { ...transaction }; + if (transaction.common !== undefined) { + formattedTransaction.common = { ...transaction.common }; + if (transaction.common.customChain !== undefined) + formattedTransaction.common.customChain = { ...transaction.common.customChain }; + } const formattableProperties: (keyof Transaction)[] = [ 'value', @@ -77,6 +86,15 @@ export function formatTransaction< desiredType, ); + if (formattedTransaction.data !== undefined && formattedTransaction.input !== undefined) + throw new Error( + 'You can\'t have "data" and "input" as properties of transactions at the same time, please use either "data" or "input" instead.', + ); + else if (formattedTransaction.input !== undefined) { + formattedTransaction.data = formattedTransaction.input; + delete formattedTransaction.input; + } + return formattedTransaction as Transaction; } @@ -145,7 +163,7 @@ export async function populateTransaction< transaction: Transaction, web3Context: Web3Context, desiredType: DesiredType, - privateKey?: HexString, + privateKey?: HexString | Buffer, ): Promise> { const populatedTransaction = { ...transaction }; @@ -166,30 +184,42 @@ export async function populateTransaction< ); } - if (populatedTransaction.value === undefined) populatedTransaction.value = '0x'; - if (populatedTransaction.data === undefined) populatedTransaction.data = '0x'; - if (populatedTransaction.chain === undefined) { - populatedTransaction.chain = web3Context.defaultChain as chain; + // TODO - Not sure if needed + // if (populatedTransaction.value === undefined) populatedTransaction.value = '0x'; + + if (populatedTransaction.data !== undefined && populatedTransaction.input !== undefined) + throw new Error( + 'You can\'t have "data" and "input" as properties of transactions at the same time, please use either "data" or "input" instead.', + ); + else if (populatedTransaction.input !== undefined) { + populatedTransaction.data = populatedTransaction.input; + delete populatedTransaction.input; } - if (populatedTransaction.hardfork === undefined) - populatedTransaction.hardfork = web3Context.defaultHardfork as hardfork; - if (populatedTransaction.chainId === undefined) { - if (populatedTransaction.common?.customChain.chainId === undefined) { + if ( + populatedTransaction.data !== undefined && + populatedTransaction.data !== null && + populatedTransaction.data !== '' && + !populatedTransaction.data.startsWith('0x') + ) + populatedTransaction.data = `0x${populatedTransaction.data}`; + + if (populatedTransaction.common === undefined) { + if (populatedTransaction.chain === undefined) + populatedTransaction.chain = web3Context.defaultChain as chain; + if (populatedTransaction.hardfork === undefined) + populatedTransaction.hardfork = web3Context.defaultHardfork as hardfork; + } else if (populatedTransaction.chainId === undefined) + if (populatedTransaction.common.customChain.chainId === undefined) { // TODO - web3Eth.getChainId not implemented // populatedTransaction.chainId = await web3Eth.getChainId(); } - } - if (populatedTransaction.gas === undefined) { - if (populatedTransaction.gasLimit !== undefined) - populatedTransaction.gas = populatedTransaction.gasLimit; - } + if (populatedTransaction.gas === undefined && populatedTransaction.gasLimit !== undefined) + populatedTransaction.gas = populatedTransaction.gasLimit; - if (populatedTransaction.gasLimit === undefined) { - if (populatedTransaction.gas !== undefined) - populatedTransaction.gasLimit = populatedTransaction.gas; - } + if (populatedTransaction.gasLimit === undefined && populatedTransaction.gas !== undefined) + populatedTransaction.gasLimit = populatedTransaction.gas; populatedTransaction.type = detectTransactionType(populatedTransaction); if ( @@ -197,11 +227,7 @@ export async function populateTransaction< (web3Context.defaultTransactionType !== null || web3Context.defaultTransactionType !== undefined) ) - populatedTransaction.type = convertToValidType( - // TODO - TSC is complaining it could be null, even though we check above - web3Context.defaultTransactionType as Numbers, - ValidTypes.HexString, - ); + populatedTransaction.type = web3Context.defaultTransactionType as HexString; if (populatedTransaction.type !== undefined) { const hexTxType = toHex(populatedTransaction.type); @@ -253,3 +279,67 @@ export async function populateTransaction< desiredType, ) as unknown as PopulatedUnsignedTransaction; } + +const getEthereumjsTxDataFromTransaction = ( + transaction: PopulatedUnsignedTransaction, +) => ({ + nonce: transaction.nonce as HexString, + gasPrice: transaction.gasPrice as HexString, + gasLimit: transaction.gasLimit as HexString, + to: transaction.to as HexString, + value: transaction.value as HexString, + data: transaction.data, + type: transaction.type as HexString, + chainId: transaction.chainId as HexString, + accessList: (transaction as PopulatedUnsignedEip2930Transaction).accessList, + maxPriorityFeePerGas: (transaction as PopulatedUnsignedEip1559Transaction) + .maxPriorityFeePerGas as HexString, + maxFeePerGas: (transaction as PopulatedUnsignedEip1559Transaction).maxFeePerGas as HexString, +}); + +const getEthereumjsTransactionOptions = ( + transaction: PopulatedUnsignedTransaction, +) => { + const hasTransactionSigningOptions = + (transaction.chain !== undefined && transaction.hardfork !== undefined) || + transaction.common !== undefined; + + let common; + if (!hasTransactionSigningOptions) { + common = Common.custom({ + name: 'custom-network', + chainId: toNumber(transaction.chainId) as number, + // networkId: transaction.networkId, + defaultHardfork: transaction.hardfork ?? 'london', + }); + } else if (transaction.common) + common = Common.custom({ + name: transaction.common.customChain.name ?? 'custom-network', + chainId: toNumber(transaction.common.customChain.chainId) as number, + // networkId: transaction.common.customChain.networkId, + defaultHardfork: transaction.common.hardfork ?? 'london', + }); + + return { common } as TxOptions; +}; + +// TODO - Needs override function +export const prepareTransactionForSigning = async ( + transaction: Transaction, + web3Context: Web3Context, + privateKey?: HexString | Buffer, +) => { + const populatedTransaction = await populateTransaction( + transaction, + web3Context, + ValidTypes.HexString, + privateKey, + ); + + validateTransactionForSigning(populatedTransaction); + + return TransactionFactory.fromTxData( + getEthereumjsTxDataFromTransaction(populatedTransaction), + getEthereumjsTransactionOptions(populatedTransaction), + ); +}; diff --git a/packages/web3-eth/src/validation.ts b/packages/web3-eth/src/validation.ts index 07ebe72aa50..ec65cc0f307 100644 --- a/packages/web3-eth/src/validation.ts +++ b/packages/web3-eth/src/validation.ts @@ -233,7 +233,7 @@ export const validateGas = (transaction: Transaction) => { }); (legacyGasPresent ? validateLegacyGas : validateFeeMarketGas)(transaction); - (transaction.type !== undefined && transaction.type < '0x1' - ? validateLegacyGas - : validateFeeMarketGas)(transaction); + (transaction.type !== undefined && transaction.type > '0x1' + ? validateFeeMarketGas + : validateLegacyGas)(transaction); }; diff --git a/packages/web3-eth/test/fixtures/prepare_transaction_for_signing.ts b/packages/web3-eth/test/fixtures/prepare_transaction_for_signing.ts new file mode 100644 index 00000000000..2ccd553ced7 --- /dev/null +++ b/packages/web3-eth/test/fixtures/prepare_transaction_for_signing.ts @@ -0,0 +1,889 @@ +import { AccessList, Block } from 'web3-common'; +// import { Block } from 'web3-common'; +import { HexString } from 'web3-utils'; +import { Common, Transaction } from '../../src/types'; + +export const preEip1559Block: Block = { + parentHash: '0xe99e022112df268087ea7eafaf4790497fd21dbeeb6bd7a1721df161a6657a54', + sha3Uncles: '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347', + miner: '0xbb7b8287f3f0a933474a79eae42cbca977791171', + stateRoot: '0xddc8b0234c2e0cad087c8b389aa7ef01f7d79b2570bccb77ce48648aa61c904d', + transactionsRoot: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', + receiptsRoot: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', + logsBloom: + '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', + difficulty: '0x4ea3f27bc', + number: '0x1b4', + gasLimit: '0x1388', + gasUsed: '0x0', + timestamp: '0x55ba467c', + extraData: '0x476574682f4c5649562f76312e302e302f6c696e75782f676f312e342e32', + mixHash: '0x4fffe9ae21f1c9e15207b1f472d5bbdd68c9595d461666602f2be20daf5e7843', + nonce: '0x689056015818adbe', + totalDifficulty: '0x78ed983323d', + size: '0x220', + transactions: [], + uncles: [], + hash: '0xdc0818cf78f21a8e70579cb46a43643f78291264dda342ae31049421c82d21ae', +}; +export const postEip1559Block: Block = { + parentHash: '0x28f49150e1fe6f245655925b290f59e707d1e5c646dadaa22937169433b30294', + sha3Uncles: '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347', + miner: '0x86864f1edf10eaf105b1bdc6e9aa8232b4c6aa00', + stateRoot: '0x116981b10423133ade5bd44f03c54cc3c57f4467a1c3d4b0c6d8d33a76c361ad', + transactionsRoot: '0x738f53f745d58169da93ebbd52cc49e0c979d6ca68a6513007b546b19ab78ba4', + receiptsRoot: '0xc97d4f9980d680053606318a5820261a1dccb556d1056b70f0d48fb384986be5', + logsBloom: + '0x4020001000000000000000008000010000000000400200000001002140000008000000010000810020000840000204304000081000000b00400010000822200004200020020140000001000882000064000021303200020000400008800000000002202102000084010000090020a8000800002000000010000030300000000000000006001005000040080001010000010040018100004c0050004000000000420000000021000200000010020008100000004000080000000000000040000900080102004002000080210201081014004030200148101000002020108025000018020020102040000204240500010000002200048000401300080088000002', + difficulty: '0x6cd6be3a', + number: '0xa0d600', + gasLimit: '0x1c9c381', + gasUsed: '0x8dc073', + timestamp: '0x60dc24ec', + extraData: '0x796f75747562652e636f6d2f77617463683f763d6451773477395767586351', + mixHash: '0xa29afb1fa1aea9eeac72ff435a8fc420bbc1fa1be08223eb61f294ee32250bde', + nonce: '0x122af1a5ccd78f3b', + totalDifficulty: '0x78828f2d886cbb', + size: '0x2042', + transactions: [], + uncles: [], + hash: '0x846880b1158f434884f3637802ed09bac77eafc35b5f03b881ac88ce38a54907', + baseFeePerGas: '0x7', +}; + +const common: Common = { + baseChain: 'mainnet', + customChain: { + name: 'custom-network', + networkId: 1, + chainId: 1, + }, + hardfork: 'istanbul', +}; +const commonBerlin: Common = { + baseChain: 'mainnet', + customChain: { + name: 'custom-network', + networkId: 1, + chainId: 1, + }, + hardfork: 'berlin', +}; +const commonLondon: Common = { + baseChain: 'mainnet', + customChain: { + name: 'custom-network', + networkId: 1, + chainId: 1, + }, + hardfork: 'london', +}; + +const accessList: AccessList = [ + { + address: '0x0000000000000000000000000000000000000101', + storageKeys: [ + '0x0000000000000000000000000000000000000000000000000000000000000000', + '0x00000000000000000000000000000000000000000000000000000000000060a7', + ], + }, +]; + +/** + * Array consists of: + * - pre/post EIP1559 block + * - transaction data + * - private key + * - RLP encoded signed transaction + * - v + * - r + * - s + * + * Each test runs with from specified, and without (will use private key to get from) + */ +export const validTransactions: [ + Block, + Transaction, + HexString, + HexString, + HexString, + HexString, + HexString, + HexString, + HexString, + HexString, +][] = [ + [ + preEip1559Block, + { + chainId: 1, + nonce: 0, + gasPrice: '20000000000', + gas: 21000, + to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', + from: '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + value: '1000000000', + data: '', + common, + }, + '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', + '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + '0xf868808504a817c80082520894f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca008026a0afa02d193471bb974081585daabf8a751d4decbb519604ac7df612cc11e9226da04bf1bd55e82cebb2b09ed39bbffe35107ea611fa212c2d9a1f1ada4952077118', + '0xab0f71614c37231d71ae521ce188a9c7c9d5e976124a91f62f9f125348dd0326', + '0x2c7903a33b55caf582d170f21595f1a7e598df3fa61b103ea0cd9d6b2a92565d', + '0x26', + '0xafa02d193471bb974081585daabf8a751d4decbb519604ac7df612cc11e9226d', + '0x4bf1bd55e82cebb2b09ed39bbffe35107ea611fa212c2d9a1f1ada4952077118', + ], + [ + preEip1559Block, + { + chainId: 1, + nonce: 0, + gasPrice: '20000000000', + gas: 21000, + to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', + value: '1000000000', + data: '', + common, + }, + '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', + '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + '0xf868808504a817c80082520894f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca008026a0afa02d193471bb974081585daabf8a751d4decbb519604ac7df612cc11e9226da04bf1bd55e82cebb2b09ed39bbffe35107ea611fa212c2d9a1f1ada4952077118', + '0xab0f71614c37231d71ae521ce188a9c7c9d5e976124a91f62f9f125348dd0326', + '0x2c7903a33b55caf582d170f21595f1a7e598df3fa61b103ea0cd9d6b2a92565d', + '0x26', + '0xafa02d193471bb974081585daabf8a751d4decbb519604ac7df612cc11e9226d', + '0x4bf1bd55e82cebb2b09ed39bbffe35107ea611fa212c2d9a1f1ada4952077118', + ], + [ + preEip1559Block, + { + chainId: 1, + nonce: 0, + gasPrice: '1', + gas: 31853, + to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', + from: '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + value: '0', + data: '', + common, + }, + '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', + '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + '0xf85f8001827c6d94f0109fc8df283027b6285cc889f5aa624eac1f55808026a074dcecc6b8ad09ca09882ac1088eac145e799f56ea3f5b5fe8fcb52bbd3ea4f7a03d49e02af9c239b1b8aea8a7ac9162862dec03207f9f59bc38a4f2b9e42077a9', + '0xfe1f3da48513409d62210b76d3493190fed19e4d54f0aa4283715184bff68e0b', + '0xce07a6c829c9a7d0a11d5ce7120bfdae769b75ba2c20961a00738d540267a975', + '0x26', + '0x74dcecc6b8ad09ca09882ac1088eac145e799f56ea3f5b5fe8fcb52bbd3ea4f7', + '0x3d49e02af9c239b1b8aea8a7ac9162862dec03207f9f59bc38a4f2b9e42077a9', + ], + [ + preEip1559Block, + { + chainId: 1, + nonce: 0, + gasPrice: '1', + gas: 31853, + to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', + value: '0', + data: '', + common, + }, + '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', + '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + '0xf85f8001827c6d94f0109fc8df283027b6285cc889f5aa624eac1f55808026a074dcecc6b8ad09ca09882ac1088eac145e799f56ea3f5b5fe8fcb52bbd3ea4f7a03d49e02af9c239b1b8aea8a7ac9162862dec03207f9f59bc38a4f2b9e42077a9', + '0xfe1f3da48513409d62210b76d3493190fed19e4d54f0aa4283715184bff68e0b', + '0xce07a6c829c9a7d0a11d5ce7120bfdae769b75ba2c20961a00738d540267a975', + '0x26', + '0x74dcecc6b8ad09ca09882ac1088eac145e799f56ea3f5b5fe8fcb52bbd3ea4f7', + '0x3d49e02af9c239b1b8aea8a7ac9162862dec03207f9f59bc38a4f2b9e42077a9', + ], + [ + preEip1559Block, + { + chainId: 1, + nonce: 0, + gasPrice: '234567897654321', + gas: 2000000, + to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', + from: '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + value: '1000000000', + data: '', + common, + }, + '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', + '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + '0xf86a8086d55698372431831e848094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca008025a009ebb6ca057a0535d6186462bc0b465b561c94a295bdb0621fc19208ab149a9ca0440ffd775ce91a833ab410777204d5341a6f9fa91216a6f3ee2c051fea6a0428', + '0xd8f64a42b57be0d565f385378db2f6bf324ce14a594afc05de90436e9ce01f60', + '0x6893a6ee8df79b0f5d64a180cd1ef35d030f3e296a5361cf04d02ce720d32ec5', + '0x25', + '0x9ebb6ca057a0535d6186462bc0b465b561c94a295bdb0621fc19208ab149a9c', + '0x440ffd775ce91a833ab410777204d5341a6f9fa91216a6f3ee2c051fea6a0428', + ], + [ + preEip1559Block, + { + chainId: 1, + nonce: 0, + gasPrice: '234567897654321', + gas: 2000000, + to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', + value: '1000000000', + data: '', + common, + }, + '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', + '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + '0xf86a8086d55698372431831e848094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca008025a009ebb6ca057a0535d6186462bc0b465b561c94a295bdb0621fc19208ab149a9ca0440ffd775ce91a833ab410777204d5341a6f9fa91216a6f3ee2c051fea6a0428', + '0xd8f64a42b57be0d565f385378db2f6bf324ce14a594afc05de90436e9ce01f60', + '0x6893a6ee8df79b0f5d64a180cd1ef35d030f3e296a5361cf04d02ce720d32ec5', + '0x25', + '0x9ebb6ca057a0535d6186462bc0b465b561c94a295bdb0621fc19208ab149a9c', + '0x440ffd775ce91a833ab410777204d5341a6f9fa91216a6f3ee2c051fea6a0428', + ], + // TODO - r doesn't match + // https://github.com/ChainSafe/web3.js/blob/1.x/test/eth.accounts.signTransaction.js#L167 + // [ + // preEip1559Block, + // { + // chainId: 1, + // nonce: 0, + // gasPrice: '10', + // gas: 31853, + // to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', + // from: '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + // value: '0', + // data: '', + // common: common + // }, + // '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', + // '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + // '0xf85f800a827c6d94f0109fc8df283027b6285cc889f5aa624eac1f55808025a03cbfff5b8ef4588b930ecbf9b85388795875edf814dfc6c71884f99b6d7555cca057142e729c1c83bfccb2785e629fc32dffb2e613df565e78e119aa4694cb1df9', + // '0x247533e8b3d12185a871fca5503b7e86f2fecef4a43ded244d5c18ec6b6b057f', + // '0xf5932468728558772f9422155ef1d7de7f8daf41542da16f1c1063cb98299953', + // '0x25', + // '0x22f17b38af35286ffbb0c6376c86ec91c20ecbad93f84913a0cc15e7580cd9', + // '0x83d6e12e82e3544cb4439964d5087da78f74cefeec9a450b16ae179fd8fe20' + // ], + // [ + // preEip1559Block, + // { + // chainId: 1, + // nonce: 0, + // gasPrice: '10', + // gas: 31853, + // to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', + // value: '0', + // data: '', + // common: common + // }, + // '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', + // '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + // '0xf85f800a827c6d94f0109fc8df283027b6285cc889f5aa624eac1f55808025a03cbfff5b8ef4588b930ecbf9b85388795875edf814dfc6c71884f99b6d7555cca057142e729c1c83bfccb2785e629fc32dffb2e613df565e78e119aa4694cb1df9', + // '0x247533e8b3d12185a871fca5503b7e86f2fecef4a43ded244d5c18ec6b6b057f', + // '0xf5932468728558772f9422155ef1d7de7f8daf41542da16f1c1063cb98299953', + // '0x25', + // '0x22f17b38af35286ffbb0c6376c86ec91c20ecbad93f84913a0cc15e7580cd9', + // '0x83d6e12e82e3544cb4439964d5087da78f74cefeec9a450b16ae179fd8fe20' + // ], + [ + preEip1559Block, + { + chainId: 1, + nonce: 0, + gasPrice: '20000000000', + gas: 21000, + to: '0x3535353535353535353535353535353535353535', + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + value: '1000000000000000000', + data: '', + common, + }, + '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', + '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + '0xf86c808504a817c800825208943535353535353535353535353535353535353535880de0b6b3a76400008025a04f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88da07e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + '0xda3be87732110de6c1354c83770aae630ede9ac308d9f7b399ecfba23d923384', + '0x7dbc5644b83abd32d014d170ba9bdc855c126328c0cb41af0ed6422bef0bb32e', + '0x25', + '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + ], + [ + preEip1559Block, + { + chainId: 1, + nonce: 0, + gasPrice: '20000000000', + gas: 21000, + to: '0x3535353535353535353535353535353535353535', + value: '1000000000000000000', + data: '', + common, + }, + '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', + '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + '0xf86c808504a817c800825208943535353535353535353535353535353535353535880de0b6b3a76400008025a04f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88da07e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + '0xda3be87732110de6c1354c83770aae630ede9ac308d9f7b399ecfba23d923384', + '0x7dbc5644b83abd32d014d170ba9bdc855c126328c0cb41af0ed6422bef0bb32e', + '0x25', + '0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d', + '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', + ], + [ + preEip1559Block, + { + chainId: 1, + nonce: 0, + gasPrice: '230000000000', + gas: 50000, + to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + value: '1000000000000000000', + data: '0x0123abcd', + common, + }, + '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', + '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + '0xf8708085358d117c0082c35094fcad0b19bb29d4674531d6f115237e16afce377c880de0b6b3a7640000840123abcd26a031bb05bd1535150d312dcaa870a4a69c130a51aa80537659c1f308bf1f180ac6a012c938a8e04ac4e279d0b7c29811609031a96e949ad98f1ca74ca6078910bede', + '0xe86ab542020b3f386af1a1c79881d5db06f5fac58da79f697308f1d1e1799f2c', + '0x044d45bc28c2126e98c9cd0103a6559f5a92e01ecc201f48472f1e10a4c3ae27', + '0x26', + '0x31bb05bd1535150d312dcaa870a4a69c130a51aa80537659c1f308bf1f180ac6', + '0x12c938a8e04ac4e279d0b7c29811609031a96e949ad98f1ca74ca6078910bede', + ], + [ + preEip1559Block, + { + chainId: 1, + nonce: 0, + gasPrice: '230000000000', + gas: 50000, + to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', + value: '1000000000000000000', + data: '0x0123abcd', + common, + }, + '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', + '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + '0xf8708085358d117c0082c35094fcad0b19bb29d4674531d6f115237e16afce377c880de0b6b3a7640000840123abcd26a031bb05bd1535150d312dcaa870a4a69c130a51aa80537659c1f308bf1f180ac6a012c938a8e04ac4e279d0b7c29811609031a96e949ad98f1ca74ca6078910bede', + '0xe86ab542020b3f386af1a1c79881d5db06f5fac58da79f697308f1d1e1799f2c', + '0x044d45bc28c2126e98c9cd0103a6559f5a92e01ecc201f48472f1e10a4c3ae27', + '0x26', + '0x31bb05bd1535150d312dcaa870a4a69c130a51aa80537659c1f308bf1f180ac6', + '0x12c938a8e04ac4e279d0b7c29811609031a96e949ad98f1ca74ca6078910bede', + ], + [ + preEip1559Block, + { + chainId: 1, + nonce: 10, + gasPrice: '230000000000', + gas: 50000, + to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + value: '1000000000000000000', + data: '0x0123abcd', + common, + }, + '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', + '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + '0xf8700a85358d117c0082c35094fcad0b19bb29d4674531d6f115237e16afce377c880de0b6b3a7640000840123abcd25a0496e628e8348a24312ded09ee3d99d85b1b8f947725aa382dcf4003b7389d5aaa00c1b1cfdd66c510fd708d33279a1a61e53dff3c6ced67cf7f7b830862d6e2029', + '0x42fb18cc20b10438c6b4bcb4f3fc777a72195caf3e8b6ddc671df4a249e84ba7', + '0xa75c245723fedf4b739771f5eeedeb3dc6ecd3b9ea79277a33dc5ab27be0c911', + '0x25', + '0x496e628e8348a24312ded09ee3d99d85b1b8f947725aa382dcf4003b7389d5aa', + '0xc1b1cfdd66c510fd708d33279a1a61e53dff3c6ced67cf7f7b830862d6e2029', + ], + [ + preEip1559Block, + { + chainId: 1, + nonce: 10, + gasPrice: '230000000000', + gas: 50000, + to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', + value: '1000000000000000000', + data: '0x0123abcd', + common, + }, + '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', + '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + '0xf8700a85358d117c0082c35094fcad0b19bb29d4674531d6f115237e16afce377c880de0b6b3a7640000840123abcd25a0496e628e8348a24312ded09ee3d99d85b1b8f947725aa382dcf4003b7389d5aaa00c1b1cfdd66c510fd708d33279a1a61e53dff3c6ced67cf7f7b830862d6e2029', + '0x42fb18cc20b10438c6b4bcb4f3fc777a72195caf3e8b6ddc671df4a249e84ba7', + '0xa75c245723fedf4b739771f5eeedeb3dc6ecd3b9ea79277a33dc5ab27be0c911', + '0x25', + '0x496e628e8348a24312ded09ee3d99d85b1b8f947725aa382dcf4003b7389d5aa', + '0xc1b1cfdd66c510fd708d33279a1a61e53dff3c6ced67cf7f7b830862d6e2029', + ], + [ + preEip1559Block, + { + chainId: 1, + nonce: '0xa', + gasPrice: '230000000000', + gas: 50000, + to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + value: '1000000000000000000', + data: '0x0123abcd', + common, + }, + '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', + '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + '0xf8700a85358d117c0082c35094fcad0b19bb29d4674531d6f115237e16afce377c880de0b6b3a7640000840123abcd25a0496e628e8348a24312ded09ee3d99d85b1b8f947725aa382dcf4003b7389d5aaa00c1b1cfdd66c510fd708d33279a1a61e53dff3c6ced67cf7f7b830862d6e2029', + '0x42fb18cc20b10438c6b4bcb4f3fc777a72195caf3e8b6ddc671df4a249e84ba7', + '0xa75c245723fedf4b739771f5eeedeb3dc6ecd3b9ea79277a33dc5ab27be0c911', + '0x25', + '0x496e628e8348a24312ded09ee3d99d85b1b8f947725aa382dcf4003b7389d5aa', + '0xc1b1cfdd66c510fd708d33279a1a61e53dff3c6ced67cf7f7b830862d6e2029', + ], + [ + preEip1559Block, + { + chainId: 1, + nonce: '0xa', + gasPrice: '230000000000', + gas: 50000, + to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', + value: '1000000000000000000', + data: '0x0123abcd', + common, + }, + '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', + '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + '0xf8700a85358d117c0082c35094fcad0b19bb29d4674531d6f115237e16afce377c880de0b6b3a7640000840123abcd25a0496e628e8348a24312ded09ee3d99d85b1b8f947725aa382dcf4003b7389d5aaa00c1b1cfdd66c510fd708d33279a1a61e53dff3c6ced67cf7f7b830862d6e2029', + '0x42fb18cc20b10438c6b4bcb4f3fc777a72195caf3e8b6ddc671df4a249e84ba7', + '0xa75c245723fedf4b739771f5eeedeb3dc6ecd3b9ea79277a33dc5ab27be0c911', + '0x25', + '0x496e628e8348a24312ded09ee3d99d85b1b8f947725aa382dcf4003b7389d5aa', + '0xc1b1cfdd66c510fd708d33279a1a61e53dff3c6ced67cf7f7b830862d6e2029', + ], + [ + preEip1559Block, + { + chainId: 1, + nonce: '16', + gasPrice: '230000000000', + gas: 50000, + to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + value: '1000000000000000000', + data: '0x0123abcd', + common, + }, + '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', + '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + '0xf8701085358d117c0082c35094fcad0b19bb29d4674531d6f115237e16afce377c880de0b6b3a7640000840123abcd25a04ba217e16f62ac277698e8853bcc010db07285b457606e9f3487c70ccc5e6508a05c6cfaa17fc1a52bede0cf25c8bd2e024b4fb89ed205f62cb3e177a83654f29d', + '0xa2db7be5398c250e3ecf569c573f222255d46c509199ff649cca5e806edf5212', + '0x9c8c1fb88a95974c5ac75b6c58af2b5a62d9ccb9dffad7552a3182344bf37c27', + '0x25', + '0x4ba217e16f62ac277698e8853bcc010db07285b457606e9f3487c70ccc5e6508', + '0x5c6cfaa17fc1a52bede0cf25c8bd2e024b4fb89ed205f62cb3e177a83654f29d', + ], + [ + preEip1559Block, + { + chainId: 1, + nonce: '16', + gasPrice: '230000000000', + gas: 50000, + to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', + value: '1000000000000000000', + data: '0x0123abcd', + common, + }, + '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', + '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + '0xf8701085358d117c0082c35094fcad0b19bb29d4674531d6f115237e16afce377c880de0b6b3a7640000840123abcd25a04ba217e16f62ac277698e8853bcc010db07285b457606e9f3487c70ccc5e6508a05c6cfaa17fc1a52bede0cf25c8bd2e024b4fb89ed205f62cb3e177a83654f29d', + '0xa2db7be5398c250e3ecf569c573f222255d46c509199ff649cca5e806edf5212', + '0x9c8c1fb88a95974c5ac75b6c58af2b5a62d9ccb9dffad7552a3182344bf37c27', + '0x25', + '0x4ba217e16f62ac277698e8853bcc010db07285b457606e9f3487c70ccc5e6508', + '0x5c6cfaa17fc1a52bede0cf25c8bd2e024b4fb89ed205f62cb3e177a83654f29d', + ], + [ + preEip1559Block, + { + chainId: 1, + nonce: 16, + gasPrice: '230000000000', + gas: 50000, + to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + value: '1000000000000000000', + data: '0x0123abcd', + common, + }, + '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', + '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + '0xf8701085358d117c0082c35094fcad0b19bb29d4674531d6f115237e16afce377c880de0b6b3a7640000840123abcd25a04ba217e16f62ac277698e8853bcc010db07285b457606e9f3487c70ccc5e6508a05c6cfaa17fc1a52bede0cf25c8bd2e024b4fb89ed205f62cb3e177a83654f29d', + '0xa2db7be5398c250e3ecf569c573f222255d46c509199ff649cca5e806edf5212', + '0x9c8c1fb88a95974c5ac75b6c58af2b5a62d9ccb9dffad7552a3182344bf37c27', + '0x25', + '0x4ba217e16f62ac277698e8853bcc010db07285b457606e9f3487c70ccc5e6508', + '0x5c6cfaa17fc1a52bede0cf25c8bd2e024b4fb89ed205f62cb3e177a83654f29d', + ], + [ + preEip1559Block, + { + chainId: 1, + nonce: 16, + gasPrice: '230000000000', + gas: 50000, + to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', + value: '1000000000000000000', + data: '0x0123abcd', + common, + }, + '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', + '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + '0xf8701085358d117c0082c35094fcad0b19bb29d4674531d6f115237e16afce377c880de0b6b3a7640000840123abcd25a04ba217e16f62ac277698e8853bcc010db07285b457606e9f3487c70ccc5e6508a05c6cfaa17fc1a52bede0cf25c8bd2e024b4fb89ed205f62cb3e177a83654f29d', + '0xa2db7be5398c250e3ecf569c573f222255d46c509199ff649cca5e806edf5212', + '0x9c8c1fb88a95974c5ac75b6c58af2b5a62d9ccb9dffad7552a3182344bf37c27', + '0x25', + '0x4ba217e16f62ac277698e8853bcc010db07285b457606e9f3487c70ccc5e6508', + '0x5c6cfaa17fc1a52bede0cf25c8bd2e024b4fb89ed205f62cb3e177a83654f29d', + ], + [ + preEip1559Block, + { + chainId: 1, + nonce: '0x16', + gasPrice: '230000000000', + gas: 50000, + to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + value: '1000000000000000000', + data: '0x0123abcd', + common, + }, + '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', + '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + '0xf8701685358d117c0082c35094fcad0b19bb29d4674531d6f115237e16afce377c880de0b6b3a7640000840123abcd26a0e027ec9e9921975678b73de44f7d2cd6b987a6655b9d0291b2cdff15836c6efba051b4e20835793bf0cdf268339111a24d80a4a7bb141e975a66d0edbcc20542d0', + '0x3135f97ac8d534b4b487cc2965fb1dcf427b92fd233577900dab3420e7afca13', + '0x77fd104f011a0085a9fa80f6f77cb213bce71fe8b4585d6fa9e3217117263a5b', + '0x26', + '0xe027ec9e9921975678b73de44f7d2cd6b987a6655b9d0291b2cdff15836c6efb', + '0x51b4e20835793bf0cdf268339111a24d80a4a7bb141e975a66d0edbcc20542d0', + ], + [ + preEip1559Block, + { + chainId: 1, + nonce: '0x16', + gasPrice: '230000000000', + gas: 50000, + to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', + value: '1000000000000000000', + data: '0x0123abcd', + common, + }, + '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', + '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + '0xf8701685358d117c0082c35094fcad0b19bb29d4674531d6f115237e16afce377c880de0b6b3a7640000840123abcd26a0e027ec9e9921975678b73de44f7d2cd6b987a6655b9d0291b2cdff15836c6efba051b4e20835793bf0cdf268339111a24d80a4a7bb141e975a66d0edbcc20542d0', + '0x3135f97ac8d534b4b487cc2965fb1dcf427b92fd233577900dab3420e7afca13', + '0x77fd104f011a0085a9fa80f6f77cb213bce71fe8b4585d6fa9e3217117263a5b', + '0x26', + '0xe027ec9e9921975678b73de44f7d2cd6b987a6655b9d0291b2cdff15836c6efb', + '0x51b4e20835793bf0cdf268339111a24d80a4a7bb141e975a66d0edbcc20542d0', + ], + [ + preEip1559Block, + { + chainId: 1, + nonce: '0x16', + gasPrice: '230000000000', + gas: 50000, + to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + value: '1000000000000000000', + input: '0x0123abcd', + common, + }, + '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', + '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + '0xf8701685358d117c0082c35094fcad0b19bb29d4674531d6f115237e16afce377c880de0b6b3a7640000840123abcd26a0e027ec9e9921975678b73de44f7d2cd6b987a6655b9d0291b2cdff15836c6efba051b4e20835793bf0cdf268339111a24d80a4a7bb141e975a66d0edbcc20542d0', + '0x3135f97ac8d534b4b487cc2965fb1dcf427b92fd233577900dab3420e7afca13', + '0x77fd104f011a0085a9fa80f6f77cb213bce71fe8b4585d6fa9e3217117263a5b', + '0x26', + '0xe027ec9e9921975678b73de44f7d2cd6b987a6655b9d0291b2cdff15836c6efb', + '0x51b4e20835793bf0cdf268339111a24d80a4a7bb141e975a66d0edbcc20542d0', + ], + [ + preEip1559Block, + { + chainId: 1, + nonce: '0x16', + gasPrice: '230000000000', + gas: 50000, + to: '0xFCAd0B19bB29D4674531d6f115237E16AfCE377c', + value: '1000000000000000000', + input: '0x0123abcd', + common, + }, + '0xbe6383dad004f233317e46ddb46ad31b16064d14447a95cc1d8c8d4bc61c3728', + '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + '0xf8701685358d117c0082c35094fcad0b19bb29d4674531d6f115237e16afce377c880de0b6b3a7640000840123abcd26a0e027ec9e9921975678b73de44f7d2cd6b987a6655b9d0291b2cdff15836c6efba051b4e20835793bf0cdf268339111a24d80a4a7bb141e975a66d0edbcc20542d0', + '0x3135f97ac8d534b4b487cc2965fb1dcf427b92fd233577900dab3420e7afca13', + '0x77fd104f011a0085a9fa80f6f77cb213bce71fe8b4585d6fa9e3217117263a5b', + '0x26', + '0xe027ec9e9921975678b73de44f7d2cd6b987a6655b9d0291b2cdff15836c6efb', + '0x51b4e20835793bf0cdf268339111a24d80a4a7bb141e975a66d0edbcc20542d0', + ], + [ + preEip1559Block, + { + chainId: 1, + nonce: 0, + gasPrice: '20000000000', + gas: 27200, + to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', + from: '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + value: '1000000000', + data: '', + common: commonBerlin, + accessList, + }, + '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', + '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + '0x01f8c601808504a817c800826a4094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca0080f85bf859940000000000000000000000000000000000000101f842a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000060a701a07a49fff8f639e42af36704b16e30fd95823d9ab7e71bf7c231e397dec2c5427ca0773bfdc5e911eedc0470325727426cff3c65329be4701005cd4ea620aacfa335', + '0xbac5b9b1d381034a2eaee9d574acaff42b39dc3bc236a6022928828bdb189b92', + '0x19920e15ec80c033dec688ccc2cb414144a0dac23f6f36f503390228cc4672eb', + '0x1', + '0x7a49fff8f639e42af36704b16e30fd95823d9ab7e71bf7c231e397dec2c5427c', + '0x773bfdc5e911eedc0470325727426cff3c65329be4701005cd4ea620aacfa335', + ], + [ + preEip1559Block, + { + chainId: 1, + nonce: 0, + gasPrice: '20000000000', + gas: 27200, + to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', + value: '1000000000', + data: '', + common: commonBerlin, + accessList, + }, + '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', + '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + '0x01f8c601808504a817c800826a4094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca0080f85bf859940000000000000000000000000000000000000101f842a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000060a701a07a49fff8f639e42af36704b16e30fd95823d9ab7e71bf7c231e397dec2c5427ca0773bfdc5e911eedc0470325727426cff3c65329be4701005cd4ea620aacfa335', + '0xbac5b9b1d381034a2eaee9d574acaff42b39dc3bc236a6022928828bdb189b92', + '0x19920e15ec80c033dec688ccc2cb414144a0dac23f6f36f503390228cc4672eb', + '0x1', + '0x7a49fff8f639e42af36704b16e30fd95823d9ab7e71bf7c231e397dec2c5427c', + '0x773bfdc5e911eedc0470325727426cff3c65329be4701005cd4ea620aacfa335', + ], + [ + postEip1559Block, + { + chainId: 1, + nonce: 0, + maxPriorityFeePerGas: '0x3B9ACA00', + maxFeePerGas: '0xB2D05E00', + gas: 27200, + gasLimit: '0x6A40', + to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', + from: '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + value: '1000000000', + data: '', + common: commonLondon, + accessList, + }, + '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', + '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + '0x02f8ca0180843b9aca0084b2d05e00826a4094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca0080f85bf859940000000000000000000000000000000000000101f842a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000060a701a0e86d3360f40f934686e1f9e53d5f49634adb0227169dd8a93b66683eb32b9c1ca04e5851b4601e2e9178148ca0f4f8360d9fba16baf272931debdf270ffa6fafc9', + '0xc102cf9a2cfa23b06d013970497793077c2fa2a203ec32ddeee2ec87a4ab1cb8', + '0x69325a2750893097fb1b7ab621bacef5fc20fd33374e1c3f44a79f9f35602b59', + '0x1', + '0xe86d3360f40f934686e1f9e53d5f49634adb0227169dd8a93b66683eb32b9c1c', + '0x4e5851b4601e2e9178148ca0f4f8360d9fba16baf272931debdf270ffa6fafc9', + ], + [ + postEip1559Block, + { + chainId: 1, + nonce: 0, + maxPriorityFeePerGas: '0x3B9ACA00', + maxFeePerGas: '0xB2D05E00', + gas: 27200, + gasLimit: '0x6A40', + to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', + value: '1000000000', + data: '', + common: commonLondon, + accessList, + }, + '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', + '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + '0x02f8ca0180843b9aca0084b2d05e00826a4094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca0080f85bf859940000000000000000000000000000000000000101f842a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000060a701a0e86d3360f40f934686e1f9e53d5f49634adb0227169dd8a93b66683eb32b9c1ca04e5851b4601e2e9178148ca0f4f8360d9fba16baf272931debdf270ffa6fafc9', + '0xc102cf9a2cfa23b06d013970497793077c2fa2a203ec32ddeee2ec87a4ab1cb8', + '0x69325a2750893097fb1b7ab621bacef5fc20fd33374e1c3f44a79f9f35602b59', + '0x1', + '0xe86d3360f40f934686e1f9e53d5f49634adb0227169dd8a93b66683eb32b9c1c', + '0x4e5851b4601e2e9178148ca0f4f8360d9fba16baf272931debdf270ffa6fafc9', + ], + [ + postEip1559Block, + { + chainId: 1, + nonce: 0, + gas: 27200, + maxPriorityFeePerGas: '0x3B9ACA00', + gasLimit: '0x6A40', + to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', + from: '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + value: '1000000000', + data: '', + common: commonLondon, + }, + '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', + '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + '0x02f86e0180843b9aca00843b9aca0e826a4094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca0080c080a0eb8ca6017e6926503ce11c404ba9b61f30d53ea934857e4f4489f43a6c189cf8a03655ba42b2fdcabdb3363cb39e7f672baa91455632e02bab27f92e1a275ca833', + '0x488a813f2286f7c015947aa13133bdae49ec75ae1c8f5eba80034d71a038dca8', + '0xcd6d6dee80ecc38f1b22f2d128bf6043dc41079fc913183a8995b5b3e187df61', + '0x0', + '0xeb8ca6017e6926503ce11c404ba9b61f30d53ea934857e4f4489f43a6c189cf8', + '0x3655ba42b2fdcabdb3363cb39e7f672baa91455632e02bab27f92e1a275ca833', + ], + [ + postEip1559Block, + { + chainId: 1, + nonce: 0, + maxPriorityFeePerGas: '0x3B9ACA00', + gas: 27200, + gasLimit: '0x6A40', + to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', + value: '1000000000', + data: '', + common: commonLondon, + }, + '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', + '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + '0x02f86e0180843b9aca00843b9aca0e826a4094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca0080c080a0eb8ca6017e6926503ce11c404ba9b61f30d53ea934857e4f4489f43a6c189cf8a03655ba42b2fdcabdb3363cb39e7f672baa91455632e02bab27f92e1a275ca833', + '0x488a813f2286f7c015947aa13133bdae49ec75ae1c8f5eba80034d71a038dca8', + '0xcd6d6dee80ecc38f1b22f2d128bf6043dc41079fc913183a8995b5b3e187df61', + '0x0', + '0xeb8ca6017e6926503ce11c404ba9b61f30d53ea934857e4f4489f43a6c189cf8', + '0x3655ba42b2fdcabdb3363cb39e7f672baa91455632e02bab27f92e1a275ca833', + ], + [ + postEip1559Block, + { + chainId: 1, + nonce: 0, + gas: 27200, + maxPriorityFeePerGas: '0x3B9ACA00', + gasLimit: '0x6A40', + to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', + from: '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + value: '1000000000', + data: '', + common: commonLondon, + accessList, + }, + '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', + '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + '0x02f8ca0180843b9aca00843b9aca0e826a4094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca0080f85bf859940000000000000000000000000000000000000101f842a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000060a780a0e3a2e10c7d3af3407ec2d38c64788d6673926e9b28d6d2e7df3c94cdf0548233a00ad3e5faafaf3a9350ab16c1be0198ce9ff3c6bef0b91e05488d757f07de9557', + '0xbc2c9edab3d4e3a795fa402b52d6149e874de15f0cc6c0858eb34e1fe1ef31fe', + '0xa3a2cdc45e9cefb9a614ead90ce65f68bcf8a90dbe0ccbd84c1b62403bd05346', + '0x0', + '0xe3a2e10c7d3af3407ec2d38c64788d6673926e9b28d6d2e7df3c94cdf0548233', + '0xad3e5faafaf3a9350ab16c1be0198ce9ff3c6bef0b91e05488d757f07de9557', + ], + [ + postEip1559Block, + { + chainId: 1, + nonce: 0, + maxPriorityFeePerGas: '0x3B9ACA00', + gas: 27200, + gasLimit: '0x6A40', + to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', + value: '1000000000', + data: '', + common: commonLondon, + accessList, + }, + '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', + '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + '0x02f8ca0180843b9aca00843b9aca0e826a4094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca0080f85bf859940000000000000000000000000000000000000101f842a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000060a780a0e3a2e10c7d3af3407ec2d38c64788d6673926e9b28d6d2e7df3c94cdf0548233a00ad3e5faafaf3a9350ab16c1be0198ce9ff3c6bef0b91e05488d757f07de9557', + '0xbc2c9edab3d4e3a795fa402b52d6149e874de15f0cc6c0858eb34e1fe1ef31fe', + '0xa3a2cdc45e9cefb9a614ead90ce65f68bcf8a90dbe0ccbd84c1b62403bd05346', + '0x0', + '0xe3a2e10c7d3af3407ec2d38c64788d6673926e9b28d6d2e7df3c94cdf0548233', + '0xad3e5faafaf3a9350ab16c1be0198ce9ff3c6bef0b91e05488d757f07de9557', + ], + // https://github.com/ChainSafe/web3.js/blob/1.x/test/eth.accounts.signTransaction.js#L656 + // [ + // postEip1559Block, + // { + // chainId: 1, + // nonce: 0, + // maxPriorityFeePerGas: '0x3B9ACA00', + // maxFeePerGas: '0xB2D05E00', + // gasLimit: '0x6A40', + // to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', + // from: '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + // value: '1000000000', + // data: '', + // common: commonLondon, + // }, + // '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', + // '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + // '0x02f86e018084c733124884cb72ec20826a4094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca0080c001a08896fb9a5c033e0163b073cf7a951a1db2dca41b26b4188f13a05158eb26fd32a005e8855691199cd0b6dcae88f3325c374e2f0697b9c528a5c10d5bd8dfb6a3e3', + // '0xd5b7290a477b9c421d39e61d0f566ec33276fb49b9ff85cfd6152a18f1c92dab', + // '0x17e20e530a889ce52057de228b5b97edcad6002468d723346cd0b6b7a9943457', + // '0x0', + // '0xe3a2e10c7d3af3407ec2d38c64788d6673926e9b28d6d2e7df3c94cdf0548233', + // '0xad3e5faafaf3a9350ab16c1be0198ce9ff3c6bef0b91e05488d757f07de9557', + // ], + [ + postEip1559Block, + { + chainId: 1, + nonce: 0, + maxPriorityFeePerGas: '1000000000', + maxFeePerGas: '3000000000', + gasLimit: '0x6A40', + to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', + from: '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + value: '1000000000', + data: '', + common: commonLondon, + }, + '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', + '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + '0x02f86e0180843b9aca0084b2d05e00826a4094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca0080c080a0d1290a118d51918c1ca17e3af0267c45efcd745cf42e78eabc444c424d6bcf37a003c81e1fda169575023a94200ee034128747f91020e704abaee30dbcfc785c36', + '0x82c19b39a6b7eaa0492863a8b236fad5018f267b4977c270ddd5228c4cbda60e', + '0xe3beea0918f445c21eb2f42e3cbc3c5d54321ec642f47d12c473b2765df97f2b', + '0x0', + '0xd1290a118d51918c1ca17e3af0267c45efcd745cf42e78eabc444c424d6bcf37', + '0x3c81e1fda169575023a94200ee034128747f91020e704abaee30dbcfc785c36', + ], + [ + postEip1559Block, + { + chainId: 1, + nonce: 0, + maxPriorityFeePerGas: '1000000000', + maxFeePerGas: '3000000000', + gasLimit: '0x6A40', + to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', + value: '1000000000', + data: '', + common: commonLondon, + }, + '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318', + '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23', + '0x02f86e0180843b9aca0084b2d05e00826a4094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca0080c080a0d1290a118d51918c1ca17e3af0267c45efcd745cf42e78eabc444c424d6bcf37a003c81e1fda169575023a94200ee034128747f91020e704abaee30dbcfc785c36', + '0x82c19b39a6b7eaa0492863a8b236fad5018f267b4977c270ddd5228c4cbda60e', + '0xe3beea0918f445c21eb2f42e3cbc3c5d54321ec642f47d12c473b2765df97f2b', + '0x0', + '0xd1290a118d51918c1ca17e3af0267c45efcd745cf42e78eabc444c424d6bcf37', + '0x3c81e1fda169575023a94200ee034128747f91020e704abaee30dbcfc785c36', + ], +]; diff --git a/packages/web3-eth/test/unit/prepare_transaction_for_signing.test.ts b/packages/web3-eth/test/unit/prepare_transaction_for_signing.test.ts new file mode 100644 index 00000000000..07e5d64b9fe --- /dev/null +++ b/packages/web3-eth/test/unit/prepare_transaction_for_signing.test.ts @@ -0,0 +1,100 @@ +import { EthExecutionAPI } from 'web3-common'; +import { Web3Context } from 'web3-core'; +import HttpProvider from 'web3-providers-http'; +import { + AccessListEIP2930Transaction, + FeeMarketEIP1559Transaction, + Transaction, +} from '@ethereumjs/tx'; + +import * as rpcMethods from '../../src/rpc_methods'; +import { prepareTransactionForSigning } from '../../src/eth_tx'; +import { validTransactions } from '../fixtures/prepare_transaction_for_signing'; + +describe('prepareTransactionForSigning', () => { + const web3Context = new Web3Context(new HttpProvider('http://127.0.0.1')); + + beforeEach(() => { + // getTransactionCountSpy = jest + // .spyOn(rpcMethods, 'getTransactionCount') + // // @ts-expect-error - Mocked implementation doesn't have correct method signature + // // (i.e. requestManager, blockNumber, hydrated params), but that doesn't matter for the test + // .mockImplementation(() => expectedNonce); + // // @ts-expect-error - Mocked implementation doesn't have correct method signature + // // (i.e. requestManager, blockNumber, hydrated params), but that doesn't matter for the test + // jest.spyOn(rpcMethods, 'getGasPrice').mockImplementation(() => expectedGasPrice); + }); + + describe('should return an @ethereumjs/tx instance with expected properties', () => { + it.each(validTransactions)( + 'mockBlock: %s\nexpectedTransaction: %s\nexpectedPrivateKey: %s\nexpectedAddress: %s\nexpectedRlpEncodedTransaction: %s\nexpectedTransactionHash: %s\nexpectedMessageToSign: %s\nexpectedV: %s\nexpectedR: %s\nexpectedS: %s', + async ( + mockBlock, + expectedTransaction, + expectedPrivateKey, + expectedAddress, + expectedRlpEncodedTransaction, + expectedTransactionHash, + expectedMessageToSign, + expectedV, + expectedR, + expectedS, + ) => { + // @ts-expect-error - Mocked implementation doesn't have correct method signature + // (i.e. requestManager, blockNumber, hydrated params), but that doesn't matter for the test + jest.spyOn(rpcMethods, 'getBlockByNumber').mockImplementation(() => mockBlock); + + const ethereumjsTx = await prepareTransactionForSigning( + expectedTransaction, + web3Context, + expectedPrivateKey, + ); + + // should produce an @ethereumjs/tx instance + expect( + ethereumjsTx instanceof Transaction || + ethereumjsTx instanceof AccessListEIP2930Transaction || + ethereumjsTx instanceof FeeMarketEIP1559Transaction, + ).toBeTruthy(); + expect(ethereumjsTx.sign).toBeDefined(); + + // should sign transaction + const signedTransaction = ethereumjsTx.sign( + Buffer.from(expectedPrivateKey.substring(2), 'hex'), + ); + + const senderAddress = signedTransaction.getSenderAddress().toString(); + expect(senderAddress).toBe(expectedAddress.toLowerCase()); + + // should be able to obtain expectedRlpEncodedTransaction + const rlpEncodedTransaction = `0x${signedTransaction.serialize().toString('hex')}`; + expect(rlpEncodedTransaction).toBe(expectedRlpEncodedTransaction); + + // should be able to obtain expectedTransactionHash + const transactionHash = `0x${signedTransaction.hash().toString('hex')}`; + expect(transactionHash).toBe(expectedTransactionHash); + + // should be able to obtain expectedMessageToSign + const messageToSign = `0x${signedTransaction.getMessageToSign().toString('hex')}`; + expect(messageToSign).toBe(expectedMessageToSign); + + // should have expected v, r, and s + const v = + signedTransaction.v !== undefined + ? `0x${signedTransaction.v.toString('hex')}` + : ''; + const r = + signedTransaction.r !== undefined + ? `0x${signedTransaction.r.toString('hex')}` + : ''; + const s = + signedTransaction.s !== undefined + ? `0x${signedTransaction.s.toString('hex')}` + : ''; + expect(v).toBe(expectedV); + expect(r).toBe(expectedR); + expect(s).toBe(expectedS); + }, + ); + }); +}); From 55476e6c607956c8b2d5b4ec9e9c1b5a5e4e03e8 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Thu, 3 Feb 2022 01:12:44 -1000 Subject: [PATCH 079/132] Remove unused test code --- .../test/unit/prepare_transaction_for_signing.test.ts | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/packages/web3-eth/test/unit/prepare_transaction_for_signing.test.ts b/packages/web3-eth/test/unit/prepare_transaction_for_signing.test.ts index 07e5d64b9fe..9ee9eacd785 100644 --- a/packages/web3-eth/test/unit/prepare_transaction_for_signing.test.ts +++ b/packages/web3-eth/test/unit/prepare_transaction_for_signing.test.ts @@ -14,17 +14,6 @@ import { validTransactions } from '../fixtures/prepare_transaction_for_signing'; describe('prepareTransactionForSigning', () => { const web3Context = new Web3Context(new HttpProvider('http://127.0.0.1')); - beforeEach(() => { - // getTransactionCountSpy = jest - // .spyOn(rpcMethods, 'getTransactionCount') - // // @ts-expect-error - Mocked implementation doesn't have correct method signature - // // (i.e. requestManager, blockNumber, hydrated params), but that doesn't matter for the test - // .mockImplementation(() => expectedNonce); - // // @ts-expect-error - Mocked implementation doesn't have correct method signature - // // (i.e. requestManager, blockNumber, hydrated params), but that doesn't matter for the test - // jest.spyOn(rpcMethods, 'getGasPrice').mockImplementation(() => expectedGasPrice); - }); - describe('should return an @ethereumjs/tx instance with expected properties', () => { it.each(validTransactions)( 'mockBlock: %s\nexpectedTransaction: %s\nexpectedPrivateKey: %s\nexpectedAddress: %s\nexpectedRlpEncodedTransaction: %s\nexpectedTransactionHash: %s\nexpectedMessageToSign: %s\nexpectedV: %s\nexpectedR: %s\nexpectedS: %s', From 2cbc215b3c71f96c134511d8dc290b72b9dc5ca5 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Fri, 4 Feb 2022 15:49:09 -1000 Subject: [PATCH 080/132] revert transaction data and value to default to 0x --- packages/web3-eth/src/eth_tx.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index fd6db749e91..c2195785ad8 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -184,8 +184,7 @@ export async function populateTransaction< ); } - // TODO - Not sure if needed - // if (populatedTransaction.value === undefined) populatedTransaction.value = '0x'; + if (populatedTransaction.value === undefined) populatedTransaction.value = '0x'; if (populatedTransaction.data !== undefined && populatedTransaction.input !== undefined) throw new Error( @@ -197,11 +196,12 @@ export async function populateTransaction< } if ( - populatedTransaction.data !== undefined && - populatedTransaction.data !== null && - populatedTransaction.data !== '' && - !populatedTransaction.data.startsWith('0x') + populatedTransaction.data === undefined || + populatedTransaction.data === null || + populatedTransaction.data === '' ) + populatedTransaction.data = '0x'; + if (!populatedTransaction.data.startsWith('0x')) populatedTransaction.data = `0x${populatedTransaction.data}`; if (populatedTransaction.common === undefined) { From ea49c6c5cf61f9df573b323849b3bab8a2bcc32d Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Fri, 4 Feb 2022 15:58:13 -1000 Subject: [PATCH 081/132] Fix failing populate_transaction tests --- packages/web3-eth/test/unit/populate_transaction.test.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/web3-eth/test/unit/populate_transaction.test.ts b/packages/web3-eth/test/unit/populate_transaction.test.ts index 1794baca321..febb9403fd4 100644 --- a/packages/web3-eth/test/unit/populate_transaction.test.ts +++ b/packages/web3-eth/test/unit/populate_transaction.test.ts @@ -193,6 +193,7 @@ describe('populateTransaction', () => { it('should populate with mainnet', async () => { const input = { ...transaction }; delete input.chain; + delete input.common; const result = await populateTransaction(input, web3Context, ValidTypes.HexString); expect(result.chain).toBe('mainnet'); @@ -203,6 +204,7 @@ describe('populateTransaction', () => { const input = { ...transaction }; delete input.chain; + delete input.common; const result = await populateTransaction(input, web3Context, ValidTypes.HexString); expect(result.chain).toBe(web3Context.defaultChain); @@ -213,6 +215,7 @@ describe('populateTransaction', () => { it('should populate with london', async () => { const input = { ...transaction }; delete input.hardfork; + delete input.common; const result = await populateTransaction(input, web3Context, ValidTypes.HexString); expect(result.hardfork).toBe('london'); @@ -223,6 +226,7 @@ describe('populateTransaction', () => { const input = { ...transaction }; delete input.hardfork; + delete input.common; const result = await populateTransaction(input, web3Context, ValidTypes.HexString); expect(result.hardfork).toBe(web3Context.defaultHardfork); From 3b5d0419d3061b4371ff7f9fc04260020f8ee091 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 7 Feb 2022 15:59:43 -1000 Subject: [PATCH 082/132] Add defaultNetworkId to web3_config --- packages/web3-core/src/types.ts | 1 + packages/web3-core/src/web3_config.ts | 15 +++++++++++++++ packages/web3-core/test/unit/web3_config.test.ts | 1 + packages/web3-eth/src/eth_tx.ts | 13 +++++++++++-- packages/web3-eth/src/types.ts | 2 ++ 5 files changed, 30 insertions(+), 2 deletions(-) diff --git a/packages/web3-core/src/types.ts b/packages/web3-core/src/types.ts index 0945735d659..01d0eac5c3e 100644 --- a/packages/web3-core/src/types.ts +++ b/packages/web3-core/src/types.ts @@ -48,6 +48,7 @@ export interface Web3ConfigOptions { transactionPollingTimeout: number; blockHeaderTimeout: number; maxListenersWarningThreshold: number; + defaultNetworkId: Numbers | null; defaultChain: string | null; defaultHardfork: string | null; defaultCommon: Record | null; diff --git a/packages/web3-core/src/web3_config.ts b/packages/web3-core/src/web3_config.ts index 652dacda885..4cd39f69a24 100644 --- a/packages/web3-core/src/web3_config.ts +++ b/packages/web3-core/src/web3_config.ts @@ -24,6 +24,7 @@ export abstract class Web3Config transactionPollingTimeout: 750, blockHeaderTimeout: 10, maxListenersWarningThreshold: 100, + defaultNetworkId: null, defaultChain: 'mainnet', defaultHardfork: 'london', // TODO - Check if there is a default Common @@ -144,6 +145,20 @@ export abstract class Web3Config this._config.maxListenersWarningThreshold = val; } + public get defaultNetworkId() { + return this._config.defaultNetworkId; + } + + public set defaultNetworkId(val) { + this.emit(Web3ConfigEvent.CONFIG_CHANGE, { + name: 'defaultNetworkId', + oldValue: this._config.defaultNetworkId, + newValue: val, + }); + + this._config.defaultNetworkId = val; + } + public get defaultChain() { return this._config.defaultChain; } diff --git a/packages/web3-core/test/unit/web3_config.test.ts b/packages/web3-core/test/unit/web3_config.test.ts index b093462a788..8de9c154c4c 100644 --- a/packages/web3-core/test/unit/web3_config.test.ts +++ b/packages/web3-core/test/unit/web3_config.test.ts @@ -8,6 +8,7 @@ const defaultConfig = { defaultAccount: null, defaultBlock: 'latest', defaultChain: 'mainnet', + defaultNetworkId: null, defaultCommon: null, defaultHardfork: 'london', defaultReturnType: ValidTypes.HexString, diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index c2195785ad8..03bcc858c28 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -215,6 +215,12 @@ export async function populateTransaction< // populatedTransaction.chainId = await web3Eth.getChainId(); } + if (populatedTransaction.networkId === undefined) { + populatedTransaction.networkId = web3Context.defaultNetworkId ?? undefined; + // TODO - getNetworkId (net_version) not implemented + // populatedTransaction.networkId = await getNetworkId(); + } + if (populatedTransaction.gas === undefined && populatedTransaction.gasLimit !== undefined) populatedTransaction.gas = populatedTransaction.gasLimit; @@ -309,14 +315,17 @@ const getEthereumjsTransactionOptions = ( common = Common.custom({ name: 'custom-network', chainId: toNumber(transaction.chainId) as number, - // networkId: transaction.networkId, + networkId: + transaction.networkId !== undefined + ? (toNumber(transaction.networkId) as number) + : undefined, defaultHardfork: transaction.hardfork ?? 'london', }); } else if (transaction.common) common = Common.custom({ name: transaction.common.customChain.name ?? 'custom-network', chainId: toNumber(transaction.common.customChain.chainId) as number, - // networkId: transaction.common.customChain.networkId, + networkId: toNumber(transaction.common.customChain.networkId) as number, defaultHardfork: transaction.common.hardfork ?? 'london', }); diff --git a/packages/web3-eth/src/types.ts b/packages/web3-eth/src/types.ts index 6446a638f61..e83c7a156b7 100644 --- a/packages/web3-eth/src/types.ts +++ b/packages/web3-eth/src/types.ts @@ -57,6 +57,7 @@ export interface Transaction { chain?: chain; hardfork?: hardfork; chainId?: NumberType; + networkId?: NumberType; common?: Common; gasLimit?: NumberType; v?: NumberType; @@ -73,6 +74,7 @@ export interface PopulatedUnsignedBaseTransaction Date: Mon, 7 Feb 2022 16:00:10 -1000 Subject: [PATCH 083/132] Add TODO for failing prepare_transaction_for_signing test --- .../web3-eth/test/fixtures/prepare_transaction_for_signing.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/web3-eth/test/fixtures/prepare_transaction_for_signing.ts b/packages/web3-eth/test/fixtures/prepare_transaction_for_signing.ts index 2ccd553ced7..77d961744d1 100644 --- a/packages/web3-eth/test/fixtures/prepare_transaction_for_signing.ts +++ b/packages/web3-eth/test/fixtures/prepare_transaction_for_signing.ts @@ -817,6 +817,7 @@ export const validTransactions: [ '0xe3a2e10c7d3af3407ec2d38c64788d6673926e9b28d6d2e7df3c94cdf0548233', '0xad3e5faafaf3a9350ab16c1be0198ce9ff3c6bef0b91e05488d757f07de9557', ], + // TODO - RLP encoded value doesn't match // https://github.com/ChainSafe/web3.js/blob/1.x/test/eth.accounts.signTransaction.js#L656 // [ // postEip1559Block, From 2eb1a5a57fd4f9c446066264d1ddc2f630e6dc7e Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 7 Feb 2022 16:55:14 -1000 Subject: [PATCH 084/132] Remove TODO --- packages/web3-eth/src/index.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/web3-eth/src/index.ts b/packages/web3-eth/src/index.ts index be56dde1b63..4e1215287c6 100644 --- a/packages/web3-eth/src/index.ts +++ b/packages/web3-eth/src/index.ts @@ -90,8 +90,6 @@ export default class Web3Eth { return rpcMethodsWrappers.getCode(this.web3Context, address, blockNumber); } - // TODO - Should this.web3Context.defaultBlock still be used? Or should rpcMethodsWrappers handle defaults? - // Or vice verse public async getBlock( block: HexString32Bytes | BlockNumberOrTag = this.web3Context.defaultBlock, hydrated = false, From b65ffe96f66a5c6e6c0eeefbd0b33224a8befedb Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 7 Feb 2022 16:55:33 -1000 Subject: [PATCH 085/132] Init TransactionDataAndInputError --- packages/web3-common/src/constants.ts | 1 + packages/web3-eth/src/errors.ts | 14 +++++++++++++- packages/web3-eth/src/eth_tx.ts | 15 +++++++++------ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/packages/web3-common/src/constants.ts b/packages/web3-common/src/constants.ts index 43e95b97366..971543160dd 100644 --- a/packages/web3-common/src/constants.ts +++ b/packages/web3-common/src/constants.ts @@ -48,6 +48,7 @@ export const ERR_TX_INVALID_NONCE_OR_CHAIN_ID = 421; export const ERR_TX_UNABLE_TO_POPULATE_NONCE = 422; export const ERR_TX_UNSUPPORTED_EIP_1559 = 423; export const ERR_TX_UNSUPPORTED_TYPE = 424; +export const ERR_TX_DATA_AND_INPUT = 425; // Connection error codes export const ERR_CONN = 500; diff --git a/packages/web3-eth/src/errors.ts b/packages/web3-eth/src/errors.ts index 80eb8d7d845..2166fec6d1c 100644 --- a/packages/web3-eth/src/errors.ts +++ b/packages/web3-eth/src/errors.ts @@ -17,8 +17,9 @@ import { ERR_TX_INVALID_OBJECT, ERR_TX_INVALID_FEE_MARKET_GAS_PRICE, ERR_TX_INVALID_LEGACY_GAS, + ERR_TX_DATA_AND_INPUT, } from 'web3-common'; -import { Numbers, Web3Error } from 'web3-utils'; +import { HexString, Numbers, Web3Error } from 'web3-utils'; export class InvalidTransactionWithSender extends Web3Error { public code = ERR_TX_INVALID_SENDER; @@ -229,3 +230,14 @@ export class UnsupportedTransactionTypeError extends Web3Error { super(value, 'unsupported transaction type'); } } + +export class TransactionDataAndInputError extends Web3Error { + 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.', + ); + } +} diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 03bcc858c28..7ce43d10838 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -18,6 +18,7 @@ import { Eip1559NotSupportedError, InvalidNonceOrChainIdError, InvalidTransactionObjectError, + TransactionDataAndInputError, UnableToPopulateNonceError, UnsupportedTransactionTypeError, } from './errors'; @@ -87,9 +88,10 @@ export function formatTransaction< ); if (formattedTransaction.data !== undefined && formattedTransaction.input !== undefined) - throw new Error( - 'You can\'t have "data" and "input" as properties of transactions at the same time, please use either "data" or "input" instead.', - ); + throw new TransactionDataAndInputError({ + data: formattedTransaction.data, + input: formattedTransaction.input, + }); else if (formattedTransaction.input !== undefined) { formattedTransaction.data = formattedTransaction.input; delete formattedTransaction.input; @@ -187,9 +189,10 @@ export async function populateTransaction< if (populatedTransaction.value === undefined) populatedTransaction.value = '0x'; if (populatedTransaction.data !== undefined && populatedTransaction.input !== undefined) - throw new Error( - 'You can\'t have "data" and "input" as properties of transactions at the same time, please use either "data" or "input" instead.', - ); + throw new TransactionDataAndInputError({ + data: populatedTransaction.data, + input: populatedTransaction.input, + }); else if (populatedTransaction.input !== undefined) { populatedTransaction.data = populatedTransaction.input; delete populatedTransaction.input; From ff6d72e46f54f4b50797af9ac24bbf35f3e30ef5 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 7 Feb 2022 17:55:50 -1000 Subject: [PATCH 086/132] Add else if to populateTransaction - data --- packages/web3-eth/src/eth_tx.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 7ce43d10838..199659c731f 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -204,7 +204,7 @@ export async function populateTransaction< populatedTransaction.data === '' ) populatedTransaction.data = '0x'; - if (!populatedTransaction.data.startsWith('0x')) + else if (!populatedTransaction.data.startsWith('0x')) populatedTransaction.data = `0x${populatedTransaction.data}`; if (populatedTransaction.common === undefined) { From c428810de207721d79fde243d5c897f28ff953d1 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 7 Feb 2022 18:04:21 -1000 Subject: [PATCH 087/132] Refactor populateTransaction - chainId --- packages/web3-eth/src/eth_tx.ts | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 199659c731f..85a27c73c05 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -212,17 +212,20 @@ export async function populateTransaction< populatedTransaction.chain = web3Context.defaultChain as chain; if (populatedTransaction.hardfork === undefined) populatedTransaction.hardfork = web3Context.defaultHardfork as hardfork; - } else if (populatedTransaction.chainId === undefined) - if (populatedTransaction.common.customChain.chainId === undefined) { + } + + if ( + populatedTransaction.chainId === undefined && + populatedTransaction.common?.customChain.chainId === undefined + ) + if (populatedTransaction.networkId === undefined) { // TODO - web3Eth.getChainId not implemented // populatedTransaction.chainId = await web3Eth.getChainId(); - } - if (populatedTransaction.networkId === undefined) { - populatedTransaction.networkId = web3Context.defaultNetworkId ?? undefined; - // TODO - getNetworkId (net_version) not implemented - // populatedTransaction.networkId = await getNetworkId(); - } + populatedTransaction.networkId = web3Context.defaultNetworkId ?? undefined; + // TODO - getNetworkId (net_version) not implemented + // populatedTransaction.networkId = await getNetworkId(); + } if (populatedTransaction.gas === undefined && populatedTransaction.gasLimit !== undefined) populatedTransaction.gas = populatedTransaction.gasLimit; From 5d26cdd3a2ce030d7dbd2e5c158ce3f860a5cd2b Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 7 Feb 2022 18:08:15 -1000 Subject: [PATCH 088/132] Comment out unused ifs --- packages/web3-eth/src/eth_tx.ts | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 85a27c73c05..15b7740dfcd 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -214,18 +214,15 @@ export async function populateTransaction< populatedTransaction.hardfork = web3Context.defaultHardfork as hardfork; } - if ( - populatedTransaction.chainId === undefined && - populatedTransaction.common?.customChain.chainId === undefined - ) - if (populatedTransaction.networkId === undefined) { - // TODO - web3Eth.getChainId not implemented - // populatedTransaction.chainId = await web3Eth.getChainId(); - - populatedTransaction.networkId = web3Context.defaultNetworkId ?? undefined; - // TODO - getNetworkId (net_version) not implemented - // populatedTransaction.networkId = await getNetworkId(); - } + // if (populatedTransaction.chainId === undefined && populatedTransaction.common?.customChain.chainId === undefined) + // TODO - web3Eth.getChainId not implemented + // populatedTransaction.chainId = await web3Eth.getChainId(); + + // if (populatedTransaction.networkId === undefined) { + // populatedTransaction.networkId = web3Context.defaultNetworkId ?? undefined; + // TODO - getNetworkId (net_version) not implemented + // populatedTransaction.networkId = await getNetworkId(); + // } if (populatedTransaction.gas === undefined && populatedTransaction.gasLimit !== undefined) populatedTransaction.gas = populatedTransaction.gasLimit; From 4bbf720aa3f36552b43508c712b6ab372834beef Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 7 Feb 2022 18:10:09 -1000 Subject: [PATCH 089/132] Remove populateTransaction - gas --- packages/web3-eth/src/eth_tx.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 15b7740dfcd..b6c63739749 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -224,9 +224,6 @@ export async function populateTransaction< // populatedTransaction.networkId = await getNetworkId(); // } - if (populatedTransaction.gas === undefined && populatedTransaction.gasLimit !== undefined) - populatedTransaction.gas = populatedTransaction.gasLimit; - if (populatedTransaction.gasLimit === undefined && populatedTransaction.gas !== undefined) populatedTransaction.gasLimit = populatedTransaction.gas; From c305abf7c0bec544fe0ccb0fa369c8662a48e13a Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 7 Feb 2022 18:12:08 -1000 Subject: [PATCH 090/132] Remove populateTransaction - hexTxType --- packages/web3-eth/src/eth_tx.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index b6c63739749..79e3d9836be 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -236,25 +236,23 @@ export async function populateTransaction< populatedTransaction.type = web3Context.defaultTransactionType as HexString; if (populatedTransaction.type !== undefined) { - const hexTxType = toHex(populatedTransaction.type); - - if (hexTxType.startsWith('-')) + if (populatedTransaction.type.startsWith('-')) throw new UnsupportedTransactionTypeError(populatedTransaction.type); // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2718.md#transactions - if (hexTxType < '0x0' || hexTxType > '0x7f') + if (populatedTransaction.type < '0x0' || populatedTransaction.type > '0x7f') throw new UnsupportedTransactionTypeError(populatedTransaction.type); - if (hexTxType === '0x0' || hexTxType === '0x1') { + if (populatedTransaction.type === '0x0' || populatedTransaction.type === '0x1') { if (populatedTransaction.gasPrice === undefined) populatedTransaction.gasPrice = await getGasPrice(web3Context); } - if (hexTxType === '0x1' || hexTxType === '0x2') { + if (populatedTransaction.type === '0x1' || populatedTransaction.type === '0x2') { if (populatedTransaction.accessList === undefined) populatedTransaction.accessList = []; } - if (hexTxType === '0x2') { + if (populatedTransaction.type === '0x2') { // Unless otherwise specified by web3Context.defaultBlock, this defaults to latest const block = await getBlock(web3Context); From 7d3c3a3037f56cdda144daa0d50f885391f72278 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 7 Feb 2022 18:15:33 -1000 Subject: [PATCH 091/132] Replace use of ValidReturnTypes[ValidTypes.HexString] with HexString --- packages/web3-eth/src/eth_tx.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 79e3d9836be..20a38742a82 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -285,7 +285,7 @@ export async function populateTransaction< } const getEthereumjsTxDataFromTransaction = ( - transaction: PopulatedUnsignedTransaction, + transaction: PopulatedUnsignedTransaction, ) => ({ nonce: transaction.nonce as HexString, gasPrice: transaction.gasPrice as HexString, @@ -301,9 +301,7 @@ const getEthereumjsTxDataFromTransaction = ( maxFeePerGas: (transaction as PopulatedUnsignedEip1559Transaction).maxFeePerGas as HexString, }); -const getEthereumjsTransactionOptions = ( - transaction: PopulatedUnsignedTransaction, -) => { +const getEthereumjsTransactionOptions = (transaction: PopulatedUnsignedTransaction) => { const hasTransactionSigningOptions = (transaction.chain !== undefined && transaction.hardfork !== undefined) || transaction.common !== undefined; From 8cf4f04ddf3d0cb05ca4324853714b497346a849 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 7 Feb 2022 18:16:55 -1000 Subject: [PATCH 092/132] Remove toHex import --- packages/web3-eth/src/eth_tx.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 20a38742a82..629be7a36ec 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -5,7 +5,6 @@ import { convertToValidType, HexString, Numbers, - toHex, toNumber, ValidReturnTypes, ValidTypes, From 0e11ad6d5e3a0e2d7fc5fc72d75e391b3dce659b Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 7 Feb 2022 18:41:10 -1000 Subject: [PATCH 093/132] Remove | null for Web3ConfigOptions defaultChain and defaultHardfork --- packages/web3-core/src/types.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/web3-core/src/types.ts b/packages/web3-core/src/types.ts index 01d0eac5c3e..4e2862d4e64 100644 --- a/packages/web3-core/src/types.ts +++ b/packages/web3-core/src/types.ts @@ -49,8 +49,8 @@ export interface Web3ConfigOptions { blockHeaderTimeout: number; maxListenersWarningThreshold: number; defaultNetworkId: Numbers | null; - defaultChain: string | null; - defaultHardfork: string | null; + defaultChain: string; + defaultHardfork: string; defaultCommon: Record | null; defaultReturnType: ValidTypes; defaultTransactionType: Numbers; From 89c922b26a1766ca48baf15d5f6600543506eda2 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 7 Feb 2022 18:41:27 -1000 Subject: [PATCH 094/132] Refactor getEthereumjsTransactionOptions --- packages/web3-eth/src/eth_tx.ts | 47 +++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 629be7a36ec..0f760190830 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -300,29 +300,42 @@ const getEthereumjsTxDataFromTransaction = ( maxFeePerGas: (transaction as PopulatedUnsignedEip1559Transaction).maxFeePerGas as HexString, }); -const getEthereumjsTransactionOptions = (transaction: PopulatedUnsignedTransaction) => { +const getEthereumjsTransactionOptions = ( + transaction: PopulatedUnsignedTransaction, + web3Context: Web3Context, +) => { const hasTransactionSigningOptions = (transaction.chain !== undefined && transaction.hardfork !== undefined) || transaction.common !== undefined; let common; if (!hasTransactionSigningOptions) { - common = Common.custom({ - name: 'custom-network', - chainId: toNumber(transaction.chainId) as number, - networkId: - transaction.networkId !== undefined - ? (toNumber(transaction.networkId) as number) - : undefined, - defaultHardfork: transaction.hardfork ?? 'london', - }); + common = Common.custom( + { + name: 'custom-network', + chainId: toNumber(transaction.chainId) as number, + networkId: + transaction.networkId !== undefined + ? (toNumber(transaction.networkId) as number) + : undefined, + defaultHardfork: transaction.hardfork ?? web3Context.defaultHardfork, + }, + { + baseChain: web3Context.defaultChain, + }, + ); } else if (transaction.common) - common = Common.custom({ - name: transaction.common.customChain.name ?? 'custom-network', - chainId: toNumber(transaction.common.customChain.chainId) as number, - networkId: toNumber(transaction.common.customChain.networkId) as number, - defaultHardfork: transaction.common.hardfork ?? 'london', - }); + common = Common.custom( + { + name: transaction.common.customChain.name ?? 'custom-network', + chainId: toNumber(transaction.common.customChain.chainId) as number, + networkId: toNumber(transaction.common.customChain.networkId) as number, + defaultHardfork: transaction.common.hardfork ?? web3Context.defaultHardfork, + }, + { + baseChain: transaction.common.baseChain ?? web3Context.defaultChain, + }, + ); return { common } as TxOptions; }; @@ -344,6 +357,6 @@ export const prepareTransactionForSigning = async ( return TransactionFactory.fromTxData( getEthereumjsTxDataFromTransaction(populatedTransaction), - getEthereumjsTransactionOptions(populatedTransaction), + getEthereumjsTransactionOptions(populatedTransaction, web3Context), ); }; From 6ea21eb9063eb032904c12b7676024df6ea24de8 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 7 Feb 2022 18:43:30 -1000 Subject: [PATCH 095/132] Remove no longer needed populateTransaction - gas test --- .../web3-eth/test/unit/populate_transaction.test.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/packages/web3-eth/test/unit/populate_transaction.test.ts b/packages/web3-eth/test/unit/populate_transaction.test.ts index febb9403fd4..06f85f0b94d 100644 --- a/packages/web3-eth/test/unit/populate_transaction.test.ts +++ b/packages/web3-eth/test/unit/populate_transaction.test.ts @@ -244,16 +244,6 @@ describe('populateTransaction', () => { }); }); - describe('should populate gas', () => { - it('should populate with gasLimit', async () => { - const input = { ...transaction }; - delete input.gas; - - const result = await populateTransaction(input, web3Context, ValidTypes.HexString); - expect(result.gas).toBe(expectedGas); - }); - }); - describe('should populate gasLimit', () => { it('should populate with gas', async () => { const input = { ...transaction }; From a808d0dc9af2af3a35db6cc5482d872d2cfb8e7b Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 7 Feb 2022 21:24:49 -1000 Subject: [PATCH 096/132] Update packages/web3-eth/src/validation.ts --- packages/web3-eth/src/validation.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/web3-eth/src/validation.ts b/packages/web3-eth/src/validation.ts index 10c5544617f..ed309f2d633 100644 --- a/packages/web3-eth/src/validation.ts +++ b/packages/web3-eth/src/validation.ts @@ -135,7 +135,6 @@ export const validateCustomChainInfo = (transaction: Transaction) => { }); } - // TODO - Should throw error? }; export const validateChainInfo = (transaction: Transaction) => { From 380002cbae93d3bc3c6e5ba3efd7b74f20b6f0be Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Wed, 9 Feb 2022 20:37:39 -1000 Subject: [PATCH 097/132] Remove unnecessary rpc method wrappers --- packages/web3-eth/src/index.ts | 28 ++-- packages/web3-eth/src/rpc_method_wrappers.ts | 61 --------- .../web3_eth_methods_no_parameters.test.ts | 18 +-- .../web3_eth_methods_with_parameters.test.ts | 26 ++-- ..._rpc_method_wrappers_no_parameters.test.ts | 54 -------- ...pc_method_wrappers_with_parameters.test.ts | 122 ------------------ 6 files changed, 41 insertions(+), 268 deletions(-) delete mode 100644 packages/web3-eth/test/unit/web3_rpc_method_wrappers_no_parameters.test.ts diff --git a/packages/web3-eth/src/index.ts b/packages/web3-eth/src/index.ts index 4e1215287c6..773e25960e7 100644 --- a/packages/web3-eth/src/index.ts +++ b/packages/web3-eth/src/index.ts @@ -17,6 +17,7 @@ import { // import { Transaction, BlockFormatted } from './types'; import { BlockFormatted } from './types'; +import * as rpcMethods from './rpc_methods'; import * as rpcMethodsWrappers from './rpc_method_wrappers'; export default class Web3Eth { @@ -30,19 +31,19 @@ export default class Web3Eth { } public async getProtocolVersion() { - return rpcMethodsWrappers.getProtocolVersion(this.web3Context); + return rpcMethods.getProtocolVersion(this.web3Context.requestManager); } public async isSyncing() { - return rpcMethodsWrappers.isSyncing(this.web3Context); + return rpcMethods.getSyncing(this.web3Context.requestManager); } public async getCoinbase() { - return rpcMethodsWrappers.getCoinbase(this.web3Context); + return rpcMethods.getCoinbase(this.web3Context.requestManager); } public async isMining() { - return rpcMethodsWrappers.isMining(this.web3Context); + return rpcMethods.getMining(this.web3Context.requestManager); } public async getHashRate( @@ -80,14 +81,19 @@ export default class Web3Eth { storageSlot: Uint256, blockNumber: BlockNumberOrTag = this.web3Context.defaultBlock, ) { - return rpcMethodsWrappers.getStorageAt(this.web3Context, address, storageSlot, blockNumber); + return rpcMethods.getStorageAt( + this.web3Context.requestManager, + address, + storageSlot, + blockNumber, + ); } public async getCode( address: Address, blockNumber: BlockNumberOrTag = this.web3Context.defaultBlock, ) { - return rpcMethodsWrappers.getCode(this.web3Context, address, blockNumber); + return rpcMethods.getCode(this.web3Context.requestManager, address, blockNumber); } public async getBlock( @@ -175,13 +181,13 @@ export default class Web3Eth { // } public async sendSignedTransaction(transaction: HexStringBytes) { - return rpcMethodsWrappers.sendSignedTransaction(this.web3Context, transaction); + return rpcMethods.sendRawTransaction(this.web3Context.requestManager, transaction); } // TODO address can be an address or the index of a local wallet in web3.eth.accounts.wallet // https://web3js.readthedocs.io/en/v1.5.2/web3-eth.html?highlight=sendTransaction#sign public async sign(message: HexStringBytes, address: Address) { - return rpcMethodsWrappers.sign(this.web3Context, message, address); + return rpcMethods.sign(this.web3Context.requestManager, message, address); } // TODO Needs to convert input to hex string @@ -213,7 +219,7 @@ export default class Web3Eth { } public async getPastLogs(filter: Filter) { - return rpcMethodsWrappers.getPastLogs(this.web3Context, { + return rpcMethods.getLogs(this.web3Context.requestManager, { ...filter, // These defaults are carried over from 1.x // https://web3js.readthedocs.io/en/v1.5.2/web3-eth.html?highlight=sendTransaction#getpastlogs @@ -223,7 +229,7 @@ export default class Web3Eth { } public async getWork() { - return rpcMethodsWrappers.getWork(this.web3Context); + return rpcMethods.getWork(this.web3Context.requestManager); } public async submitWork( @@ -231,7 +237,7 @@ export default class Web3Eth { seedHash: HexString32Bytes, difficulty: HexString32Bytes, ) { - return rpcMethodsWrappers.submitWork(this.web3Context, nonce, seedHash, difficulty); + return rpcMethods.submitWork(this.web3Context.requestManager, nonce, seedHash, difficulty); } // // TODO diff --git a/packages/web3-eth/src/rpc_method_wrappers.ts b/packages/web3-eth/src/rpc_method_wrappers.ts index 8169dd224d6..95006796934 100644 --- a/packages/web3-eth/src/rpc_method_wrappers.ts +++ b/packages/web3-eth/src/rpc_method_wrappers.ts @@ -8,12 +8,8 @@ import { BlockNumberOrTag, convertObjectPropertiesToValidType, convertToValidType, - Filter, HexString32Bytes, - HexString8Bytes, - HexStringBytes, Uint, - Uint256, ValidReturnTypes, ValidTypes, } from 'web3-utils'; @@ -28,18 +24,6 @@ import { import * as rpcMethods from './rpc_methods'; import { BlockFormatted } from './types'; -export const getProtocolVersion = async (web3Context: Web3Context) => - rpcMethods.getProtocolVersion(web3Context.requestManager); - -export const isSyncing = async (web3Context: Web3Context) => - rpcMethods.getSyncing(web3Context.requestManager); - -export const getCoinbase = async (web3Context: Web3Context) => - rpcMethods.getCoinbase(web3Context.requestManager); - -export const isMining = async (web3Context: Web3Context) => - rpcMethods.getMining(web3Context.requestManager); - export async function getHashRate( web3Context: Web3Context, returnType?: ReturnType, @@ -93,19 +77,6 @@ export async function getBalance, - address: Address, - storageSlot: Uint256, - blockNumber: BlockNumberOrTag = web3Context.defaultBlock, -) => rpcMethods.getStorageAt(web3Context.requestManager, address, storageSlot, blockNumber); - -export const getCode = async ( - web3Context: Web3Context, - address: Address, - blockNumber: BlockNumberOrTag = web3Context.defaultBlock, -) => rpcMethods.getCode(web3Context.requestManager, address, blockNumber); - export async function getBlock( web3Context: Web3Context, block: HexString32Bytes | BlockNumberOrTag = web3Context.defaultBlock, @@ -281,19 +252,6 @@ export async function getTransactionCount, - transaction: HexStringBytes, -) => rpcMethods.sendRawTransaction(web3Context.requestManager, transaction); - -// TODO address can be an address or the index of a local wallet in web3.eth.accounts.wallet -// https://web3js.readthedocs.io/en/v1.5.2/web3-eth.html?highlight=sendTransaction#sign -export const sign = async ( - web3Context: Web3Context, - message: HexStringBytes, - address: Address, -) => rpcMethods.sign(web3Context.requestManager, address, message); - // TODO Needs to convert input to hex string // public async signTransaction(transaction: Transaction) { // return rpcMethods.signTransaction(this.web3Context.requestManager, transaction); @@ -327,25 +285,6 @@ export async function estimateGas, filter: Filter) => - rpcMethods.getLogs(web3Context.requestManager, { - ...filter, - // These defaults are carried over from 1.x - // https://web3js.readthedocs.io/en/v1.5.2/web3-eth.html?highlight=sendTransaction#getpastlogs - fromBlock: filter.fromBlock ?? web3Context.defaultBlock, - toBlock: filter.toBlock ?? web3Context.defaultBlock, - }); - -export const getWork = async (web3Context: Web3Context) => - rpcMethods.getWork(web3Context.requestManager); - -export const submitWork = async ( - web3Context: Web3Context, - nonce: HexString8Bytes, - seedHash: HexString32Bytes, - difficulty: HexString32Bytes, -) => rpcMethods.submitWork(web3Context.requestManager, nonce, seedHash, difficulty); - // TODO // public async requestAccounts() { diff --git a/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts b/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts index 8c7a768dd8a..2017a9c67f3 100644 --- a/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts +++ b/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts @@ -1,7 +1,7 @@ import Web3Eth from '../../src/index'; -import * as rpcMethodWrappers from '../../src/rpc_method_wrappers'; +import * as rpcMethods from '../../src/rpc_methods'; -jest.mock('../../src/rpc_method_wrappers'); +jest.mock('../../src/rpc_methods'); describe('web3_eth_methods_no_parameters', () => { let web3Eth: Web3Eth; @@ -13,32 +13,34 @@ describe('web3_eth_methods_no_parameters', () => { describe('should call RPC method with only request manager parameter', () => { it('getProtocolVersion', async () => { await web3Eth.getProtocolVersion(); - expect(rpcMethodWrappers.getProtocolVersion).toHaveBeenCalledWith(web3Eth.web3Context); + expect(rpcMethods.getProtocolVersion).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, + ); }); it('isSyncing', async () => { await web3Eth.isSyncing(); - expect(rpcMethodWrappers.isSyncing).toHaveBeenCalledWith(web3Eth.web3Context); + expect(rpcMethods.getSyncing).toHaveBeenCalledWith(web3Eth.web3Context.requestManager); }); it('getCoinbase', async () => { await web3Eth.getCoinbase(); - expect(rpcMethodWrappers.getCoinbase).toHaveBeenCalledWith(web3Eth.web3Context); + expect(rpcMethods.getCoinbase).toHaveBeenCalledWith(web3Eth.web3Context.requestManager); }); it('isMining', async () => { await web3Eth.isMining(); - expect(rpcMethodWrappers.isMining).toHaveBeenCalledWith(web3Eth.web3Context); + expect(rpcMethods.getMining).toHaveBeenCalledWith(web3Eth.web3Context.requestManager); }); it('getAccounts', async () => { await web3Eth.getAccounts(); - expect(rpcMethodWrappers.getAccounts).toHaveBeenCalledWith(web3Eth.web3Context); + expect(rpcMethods.getAccounts).toHaveBeenCalledWith(web3Eth.web3Context.requestManager); }); it('getWork', async () => { await web3Eth.getWork(); - expect(rpcMethodWrappers.getWork).toHaveBeenCalledWith(web3Eth.web3Context); + expect(rpcMethods.getWork).toHaveBeenCalledWith(web3Eth.web3Context.requestManager); }); }); }); diff --git a/packages/web3-eth/test/unit/web3_eth_methods_with_parameters.test.ts b/packages/web3-eth/test/unit/web3_eth_methods_with_parameters.test.ts index 53e038a13b6..357ee911568 100644 --- a/packages/web3-eth/test/unit/web3_eth_methods_with_parameters.test.ts +++ b/packages/web3-eth/test/unit/web3_eth_methods_with_parameters.test.ts @@ -1,6 +1,7 @@ /* eslint-disable import/namespace */ import Web3Eth from '../../src/index'; +import * as rpcMethods from '../../src/rpc_methods'; import * as rpcMethodWrappers from '../../src/rpc_method_wrappers'; import { estimateGasValidData, @@ -38,6 +39,7 @@ import { // submitWorkValidData, } from '../fixtures/web3_eth_methods_with_parameters'; +jest.mock('../../src/rpc_methods'); jest.mock('../../src/rpc_method_wrappers'); describe('web3_eth_methods_with_parameters', () => { @@ -232,8 +234,8 @@ describe('web3_eth_methods_with_parameters', () => { 'input: %s\nrpcMethodParameters: %s', async (input, rpcMethodParameters) => { await web3Eth.getStorageAt(...input); - expect(rpcMethodWrappers.getStorageAt).toHaveBeenCalledWith( - web3Eth.web3Context, + expect(rpcMethods.getStorageAt).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, ...rpcMethodParameters, ); }, @@ -245,8 +247,8 @@ describe('web3_eth_methods_with_parameters', () => { 'input: %s\nrpcMethodParameters: %s', async (input, rpcMethodParameters) => { await web3Eth.getCode(...input); - expect(rpcMethodWrappers.getCode).toHaveBeenCalledWith( - web3Eth.web3Context, + expect(rpcMethods.getCode).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, ...rpcMethodParameters, ); }, @@ -256,8 +258,8 @@ describe('web3_eth_methods_with_parameters', () => { describe('sendSignedTransaction', () => { it.each(sendSignedTransactionValidData)('input: %s', async input => { await web3Eth.sendSignedTransaction(input); - expect(rpcMethodWrappers.sendSignedTransaction).toHaveBeenCalledWith( - web3Eth.web3Context, + expect(rpcMethods.sendRawTransaction).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, input, ); }); @@ -266,8 +268,8 @@ describe('web3_eth_methods_with_parameters', () => { describe('sign', () => { it.each(signValidData)('input: %s', async input => { await web3Eth.sign(...input); - expect(rpcMethodWrappers.sign).toHaveBeenCalledWith( - web3Eth.web3Context, + expect(rpcMethods.sign).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, ...input, ); }); @@ -278,8 +280,8 @@ describe('web3_eth_methods_with_parameters', () => { 'input: %s\nrpcMethodParameters: %s', async (input, rpcMethodParameters) => { await web3Eth.getPastLogs(input); - expect(rpcMethodWrappers.getPastLogs).toHaveBeenCalledWith( - web3Eth.web3Context, + expect(rpcMethods.getLogs).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, rpcMethodParameters, ); }, @@ -289,8 +291,8 @@ describe('web3_eth_methods_with_parameters', () => { describe('submitWork', () => { it.each(submitWorkValidData)('input: %s', async input => { await web3Eth.submitWork(...input); - expect(rpcMethodWrappers.submitWork).toHaveBeenCalledWith( - web3Eth.web3Context, + expect(rpcMethods.submitWork).toHaveBeenCalledWith( + web3Eth.web3Context.requestManager, ...input, ); }); diff --git a/packages/web3-eth/test/unit/web3_rpc_method_wrappers_no_parameters.test.ts b/packages/web3-eth/test/unit/web3_rpc_method_wrappers_no_parameters.test.ts deleted file mode 100644 index b017ad4f1e0..00000000000 --- a/packages/web3-eth/test/unit/web3_rpc_method_wrappers_no_parameters.test.ts +++ /dev/null @@ -1,54 +0,0 @@ -import Web3Eth from '../../src/index'; -import * as rpcMethods from '../../src/rpc_methods'; -import { - getAccounts, - getCoinbase, - getProtocolVersion, - getWork, - isMining, - isSyncing, -} from '../../src/rpc_method_wrappers'; - -jest.mock('../../src/rpc_methods'); - -describe('web3_eth_methods_no_parameters', () => { - let web3Eth: Web3Eth; - - beforeAll(() => { - web3Eth = new Web3Eth('http://127.0.0.1:8545'); - }); - - describe('should call RPC method with only request manager parameter', () => { - it('getProtocolVersion', async () => { - await getProtocolVersion(web3Eth.web3Context); - expect(rpcMethods.getProtocolVersion).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, - ); - }); - - it('isSyncing', async () => { - await isSyncing(web3Eth.web3Context); - expect(rpcMethods.getSyncing).toHaveBeenCalledWith(web3Eth.web3Context.requestManager); - }); - - it('getCoinbase', async () => { - await getCoinbase(web3Eth.web3Context); - expect(rpcMethods.getCoinbase).toHaveBeenCalledWith(web3Eth.web3Context.requestManager); - }); - - it('isMining', async () => { - await isMining(web3Eth.web3Context); - expect(rpcMethods.getMining).toHaveBeenCalledWith(web3Eth.web3Context.requestManager); - }); - - it('getAccounts', async () => { - await getAccounts(web3Eth.web3Context); - expect(rpcMethods.getAccounts).toHaveBeenCalledWith(web3Eth.web3Context.requestManager); - }); - - it('getWork', async () => { - await getWork(web3Eth.web3Context); - expect(rpcMethods.getWork).toHaveBeenCalledWith(web3Eth.web3Context.requestManager); - }); - }); -}); diff --git a/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts b/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts index adb1fcaa0f2..20d007e7f8f 100644 --- a/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts +++ b/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts @@ -9,20 +9,14 @@ import { getBlockNumber, getBlockTransactionCount, getBlockUncleCount, - getCode, getFeeHistory, getGasPrice, getHashRate, - getPastLogs, - getStorageAt, getTransaction, getTransactionCount, getTransactionFromBlock, getTransactionReceipt, getUncle, - sendSignedTransaction, - sign, - submitWork, } from '../../src/rpc_method_wrappers'; import { estimateGasValidData, @@ -31,20 +25,14 @@ import { getBlockTransactionCountValidData, getBlockUncleCountValidData, getBlockValidData, - getCodeValidData, getFeeHistoryValidData, getGasPriceValidData, getHashRateValidData, - getPastLogsValidData, - getStorageAtValidData, getTransactionCountValidData, getTransactionFromBlockValidData, getTransactionReceiptValidData, getTransactionValidData, getUncleValidData, - sendSignedTransactionValidData, - signValidData, - submitWorkValidData, } from '../fixtures/rpc_methods_wrappers'; jest.mock('../../src/rpc_methods'); @@ -332,116 +320,6 @@ describe('web3_eth_methods_with_parameters', () => { ); }); }); - - describe("doesn't have returnType parameter", () => { - describe('getStorageAt', () => { - it.each(getStorageAtValidData)( - 'input: %s\nmockRpcResponse: %s\nrpcMethodParameters: %s\noutput: %s', - async (input, mockRpcResponse, rpcMethodParameters) => { - (rpcMethods.getStorageAt as jest.Mock).mockResolvedValueOnce( - mockRpcResponse, - ); - expect(await getStorageAt(web3Eth.web3Context, ...input)).toBe( - mockRpcResponse, - ); - expect(rpcMethods.getStorageAt).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, - ...rpcMethodParameters, - ); - }, - ); - }); - - describe('getCode', () => { - it.each(getCodeValidData)( - 'input: %s\nmockRpcResponse: %s\nrpcMethodParameters: %s\noutput: %s', - async (input, mockRpcResponse, rpcMethodParameters) => { - (rpcMethods.getCode as jest.Mock).mockResolvedValueOnce( - mockRpcResponse, - ); - expect(await getCode(web3Eth.web3Context, ...input)).toBe( - mockRpcResponse, - ); - expect(rpcMethods.getCode).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, - ...rpcMethodParameters, - ); - }, - ); - }); - - describe('sendSignedTransaction', () => { - it.each(sendSignedTransactionValidData)( - 'input: %s\nmockRpcResponse: %s\nrpcMethodParameters: %s\noutput: %s', - async (input, mockRpcResponse) => { - (rpcMethods.sendRawTransaction as jest.Mock).mockResolvedValueOnce( - mockRpcResponse, - ); - expect(await sendSignedTransaction(web3Eth.web3Context, input)).toBe( - mockRpcResponse, - ); - expect(rpcMethods.sendRawTransaction).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, - input, - ); - }, - ); - }); - - describe('sign', () => { - it.each(signValidData)( - 'input: %s\nmockRpcResponse: %s', - async (input, mockRpcResponse) => { - (rpcMethods.sign as jest.Mock).mockResolvedValueOnce(mockRpcResponse); - expect(await sign(web3Eth.web3Context, ...input)).toBe(mockRpcResponse); - expect(rpcMethods.sign).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, - // web3-eth methods takes sign(message, address) - // RPC method takes sign(address, message) - // so we manually swap them here - input[1], - input[0], - ); - }, - ); - }); - - describe('getPastLogs', () => { - it.each(getPastLogsValidData)( - 'input: %s\nmockRpcResponse: %s\nrpcMethodParameters: %s', - async (input, mockRpcResponse, rpcMethodParameters) => { - (rpcMethods.getLogs as jest.Mock).mockResolvedValueOnce( - mockRpcResponse, - ); - expect(await getPastLogs(web3Eth.web3Context, input)).toBe( - mockRpcResponse, - ); - expect(rpcMethods.getLogs).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, - rpcMethodParameters, - ); - }, - ); - }); - - describe('submitWork', () => { - it.each(submitWorkValidData)( - 'input: %s\nmockRpcResponse: %s\nrpcMethodParameters: %s', - async (input, mockRpcResponse) => { - (rpcMethods.submitWork as jest.Mock).mockResolvedValueOnce( - mockRpcResponse, - ); - expect(await submitWork(web3Eth.web3Context, ...input)).toBe( - mockRpcResponse, - ); - expect(rpcMethods.submitWork).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, - ...input, - ); - }, - ); - }); - }); }); }); }); From c5cf8c222d52f5520035cf9d3bede904f6ed6702 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Sat, 12 Feb 2022 21:04:23 -1000 Subject: [PATCH 098/132] Web3Eth now extends Web3Context instead of instantiating it --- packages/web3-eth/src/index.ts | 117 +++++++---------- .../web3_eth_methods_no_parameters.test.ts | 12 +- .../web3_eth_methods_with_parameters.test.ts | 62 +++------ ..._rpc_method_wrappers_no_parameters.test.ts | 26 ++-- ...pc_method_wrappers_with_parameters.test.ts | 122 +++++++----------- 5 files changed, 133 insertions(+), 206 deletions(-) diff --git a/packages/web3-eth/src/index.ts b/packages/web3-eth/src/index.ts index 4e1215287c6..e88a65b9007 100644 --- a/packages/web3-eth/src/index.ts +++ b/packages/web3-eth/src/index.ts @@ -2,7 +2,7 @@ /* eslint-disable default-param-last */ import { EthExecutionAPI, TransactionWithSender } from 'web3-common'; -import { SupportedProviders, Web3ConfigOptions, Web3Context } from 'web3-core'; +import { Web3Context } from 'web3-core'; import { BlockNumberOrTag, ValidTypes, @@ -15,116 +15,103 @@ import { Filter, } from 'web3-utils'; -// import { Transaction, BlockFormatted } from './types'; import { BlockFormatted } from './types'; import * as rpcMethodsWrappers from './rpc_method_wrappers'; -export default class Web3Eth { - public readonly web3Context: Web3Context; - - public constructor( - provider: SupportedProviders | string, - options?: Partial, - ) { - this.web3Context = new Web3Context(provider, options); - } - +export default class Web3Eth extends Web3Context { public async getProtocolVersion() { - return rpcMethodsWrappers.getProtocolVersion(this.web3Context); + return rpcMethodsWrappers.getProtocolVersion(this); } public async isSyncing() { - return rpcMethodsWrappers.isSyncing(this.web3Context); + return rpcMethodsWrappers.isSyncing(this); } public async getCoinbase() { - return rpcMethodsWrappers.getCoinbase(this.web3Context); + return rpcMethodsWrappers.getCoinbase(this); } public async isMining() { - return rpcMethodsWrappers.isMining(this.web3Context); + return rpcMethodsWrappers.isMining(this); } public async getHashRate( returnType?: ReturnType, ) { - return rpcMethodsWrappers.getHashRate(this.web3Context, returnType); + return rpcMethodsWrappers.getHashRate(this, returnType); } public async getGasPrice( returnType?: ReturnType, ) { - return rpcMethodsWrappers.getGasPrice(this.web3Context, returnType); + return rpcMethodsWrappers.getGasPrice(this, returnType); } public async getAccounts() { - return rpcMethodsWrappers.getAccounts(this.web3Context); + return rpcMethodsWrappers.getAccounts(this); } public async getBlockNumber( returnType?: ReturnType, ) { - return rpcMethodsWrappers.getBlockNumber(this.web3Context, returnType); + return rpcMethodsWrappers.getBlockNumber(this, returnType); } public async getBalance( address: Address, - blockNumber: BlockNumberOrTag = this.web3Context.defaultBlock, + blockNumber: BlockNumberOrTag = this.defaultBlock, returnType?: ReturnType, ) { - return rpcMethodsWrappers.getBalance(this.web3Context, address, blockNumber, returnType); + return rpcMethodsWrappers.getBalance(this, address, blockNumber, returnType); } public async getStorageAt( address: Address, storageSlot: Uint256, - blockNumber: BlockNumberOrTag = this.web3Context.defaultBlock, + blockNumber: BlockNumberOrTag = this.defaultBlock, ) { - return rpcMethodsWrappers.getStorageAt(this.web3Context, address, storageSlot, blockNumber); + return rpcMethodsWrappers.getStorageAt(this, address, storageSlot, blockNumber); } - public async getCode( - address: Address, - blockNumber: BlockNumberOrTag = this.web3Context.defaultBlock, - ) { - return rpcMethodsWrappers.getCode(this.web3Context, address, blockNumber); + public async getCode(address: Address, blockNumber: BlockNumberOrTag = this.defaultBlock) { + return rpcMethodsWrappers.getCode(this, address, blockNumber); } public async getBlock( - block: HexString32Bytes | BlockNumberOrTag = this.web3Context.defaultBlock, + block: HexString32Bytes | BlockNumberOrTag = this.defaultBlock, hydrated = false, returnType?: ReturnType, ): Promise> { - return rpcMethodsWrappers.getBlock(this.web3Context, block, hydrated, returnType); + return rpcMethodsWrappers.getBlock(this, block, hydrated, returnType); } public async getBlockTransactionCount( - block: HexString32Bytes | BlockNumberOrTag = this.web3Context.defaultBlock, + block: HexString32Bytes | BlockNumberOrTag = this.defaultBlock, returnType?: ReturnType, ) { - return rpcMethodsWrappers.getBlockTransactionCount(this.web3Context, block, returnType); + return rpcMethodsWrappers.getBlockTransactionCount(this, block, returnType); } public async getBlockUncleCount( - block: HexString32Bytes | BlockNumberOrTag = this.web3Context.defaultBlock, + block: HexString32Bytes | BlockNumberOrTag = this.defaultBlock, returnType?: ReturnType, ) { - return rpcMethodsWrappers.getBlockUncleCount(this.web3Context, block, returnType); + return rpcMethodsWrappers.getBlockUncleCount(this, block, returnType); } public async getUncle( - block: HexString32Bytes | BlockNumberOrTag = this.web3Context.defaultBlock, + block: HexString32Bytes | BlockNumberOrTag = this.defaultBlock, uncleIndex: Uint, returnType?: ReturnType, ): Promise> { - return rpcMethodsWrappers.getUncle(this.web3Context, block, uncleIndex, returnType); + return rpcMethodsWrappers.getUncle(this, block, uncleIndex, returnType); } public async getTransaction( transactionHash: HexString32Bytes, returnType?: ReturnType, ) { - return rpcMethodsWrappers.getTransaction(this.web3Context, transactionHash, returnType); + return rpcMethodsWrappers.getTransaction(this, transactionHash, returnType); } // TODO Can't find in spec @@ -133,12 +120,12 @@ export default class Web3Eth { // } public async getTransactionFromBlock( - block: HexString32Bytes | BlockNumberOrTag = this.web3Context.defaultBlock, + block: HexString32Bytes | BlockNumberOrTag = this.defaultBlock, transactionIndex: Uint, returnType?: ReturnType, ) { return rpcMethodsWrappers.getTransactionFromBlock( - this.web3Context, + this, block, transactionIndex, returnType, @@ -149,81 +136,67 @@ export default class Web3Eth { transactionHash: HexString32Bytes, returnType?: ReturnType, ) { - return rpcMethodsWrappers.getTransactionReceipt( - this.web3Context, - transactionHash, - returnType, - ); + return rpcMethodsWrappers.getTransactionReceipt(this, transactionHash, returnType); } public async getTransactionCount( address: Address, - blockNumber: BlockNumberOrTag = this.web3Context.defaultBlock, + blockNumber: BlockNumberOrTag = this.defaultBlock, returnType?: ReturnType, ) { - return rpcMethodsWrappers.getTransactionCount( - this.web3Context, - address, - blockNumber, - returnType, - ); + return rpcMethodsWrappers.getTransactionCount(this, address, blockNumber, returnType); } // TODO Needs to convert input to hex string // public async sendTransaction(transaction: Transaction) { - // return rpcMethodsWrappers.sendTransaction(this.web3Context, transaction); + // return rpcMethodsWrappers.sendTransaction(this, transaction); // } public async sendSignedTransaction(transaction: HexStringBytes) { - return rpcMethodsWrappers.sendSignedTransaction(this.web3Context, transaction); + return rpcMethodsWrappers.sendSignedTransaction(this, transaction); } // TODO address can be an address or the index of a local wallet in web3.eth.accounts.wallet // https://web3js.readthedocs.io/en/v1.5.2/web3-eth.html?highlight=sendTransaction#sign public async sign(message: HexStringBytes, address: Address) { - return rpcMethodsWrappers.sign(this.web3Context, message, address); + return rpcMethodsWrappers.sign(this, message, address); } // TODO Needs to convert input to hex string // public async signTransaction(transaction: Transaction) { - // return rpcMethodsWrappers.signTransaction(this.web3Context, transaction); + // return rpcMethodsWrappers.signTransaction(this, transaction); // } // TODO Decide what to do with transaction.to // https://github.com/ChainSafe/web3.js/pull/4525#issuecomment-982330076 // public async call( // transaction: Transaction & { to: Address }, - // blockNumber: BlockNumberOrTag = this.web3Context.defaultBlock, + // blockNumber: BlockNumberOrTag = this.defaultBlock, // ) { - // return rpcMethodsWrappers.call(this.web3Context, transaction, blockNumber); + // return rpcMethodsWrappers.call(this, transaction, blockNumber); // } // TODO Missing param public async estimateGas( transaction: Partial, - blockNumber: BlockNumberOrTag = this.web3Context.defaultBlock, + blockNumber: BlockNumberOrTag = this.defaultBlock, returnType?: ReturnType, ) { - return rpcMethodsWrappers.estimateGas( - this.web3Context, - transaction, - blockNumber, - returnType, - ); + return rpcMethodsWrappers.estimateGas(this, transaction, blockNumber, returnType); } public async getPastLogs(filter: Filter) { - return rpcMethodsWrappers.getPastLogs(this.web3Context, { + return rpcMethodsWrappers.getPastLogs(this, { ...filter, // These defaults are carried over from 1.x // https://web3js.readthedocs.io/en/v1.5.2/web3-eth.html?highlight=sendTransaction#getpastlogs - fromBlock: filter.fromBlock ?? this.web3Context.defaultBlock, - toBlock: filter.toBlock ?? this.web3Context.defaultBlock, + fromBlock: filter.fromBlock ?? this.defaultBlock, + toBlock: filter.toBlock ?? this.defaultBlock, }); } public async getWork() { - return rpcMethodsWrappers.getWork(this.web3Context); + return rpcMethodsWrappers.getWork(this); } public async submitWork( @@ -231,7 +204,7 @@ export default class Web3Eth { seedHash: HexString32Bytes, difficulty: HexString32Bytes, ) { - return rpcMethodsWrappers.submitWork(this.web3Context, nonce, seedHash, difficulty); + return rpcMethodsWrappers.submitWork(this, nonce, seedHash, difficulty); } // // TODO @@ -256,12 +229,12 @@ export default class Web3Eth { public async getFeeHistory( blockCount: Uint, - newestBlock: BlockNumberOrTag = this.web3Context.defaultBlock, + newestBlock: BlockNumberOrTag = this.defaultBlock, rewardPercentiles: number[], returnType?: ReturnType, ) { return rpcMethodsWrappers.getFeeHistory( - this.web3Context, + this, blockCount, newestBlock, rewardPercentiles, diff --git a/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts b/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts index 8c7a768dd8a..9d26ad51946 100644 --- a/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts +++ b/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts @@ -13,32 +13,32 @@ describe('web3_eth_methods_no_parameters', () => { describe('should call RPC method with only request manager parameter', () => { it('getProtocolVersion', async () => { await web3Eth.getProtocolVersion(); - expect(rpcMethodWrappers.getProtocolVersion).toHaveBeenCalledWith(web3Eth.web3Context); + expect(rpcMethodWrappers.getProtocolVersion).toHaveBeenCalledWith(web3Eth); }); it('isSyncing', async () => { await web3Eth.isSyncing(); - expect(rpcMethodWrappers.isSyncing).toHaveBeenCalledWith(web3Eth.web3Context); + expect(rpcMethodWrappers.isSyncing).toHaveBeenCalledWith(web3Eth); }); it('getCoinbase', async () => { await web3Eth.getCoinbase(); - expect(rpcMethodWrappers.getCoinbase).toHaveBeenCalledWith(web3Eth.web3Context); + expect(rpcMethodWrappers.getCoinbase).toHaveBeenCalledWith(web3Eth); }); it('isMining', async () => { await web3Eth.isMining(); - expect(rpcMethodWrappers.isMining).toHaveBeenCalledWith(web3Eth.web3Context); + expect(rpcMethodWrappers.isMining).toHaveBeenCalledWith(web3Eth); }); it('getAccounts', async () => { await web3Eth.getAccounts(); - expect(rpcMethodWrappers.getAccounts).toHaveBeenCalledWith(web3Eth.web3Context); + expect(rpcMethodWrappers.getAccounts).toHaveBeenCalledWith(web3Eth); }); it('getWork', async () => { await web3Eth.getWork(); - expect(rpcMethodWrappers.getWork).toHaveBeenCalledWith(web3Eth.web3Context); + expect(rpcMethodWrappers.getWork).toHaveBeenCalledWith(web3Eth); }); }); }); diff --git a/packages/web3-eth/test/unit/web3_eth_methods_with_parameters.test.ts b/packages/web3-eth/test/unit/web3_eth_methods_with_parameters.test.ts index 53e038a13b6..dbefa3b1a5d 100644 --- a/packages/web3-eth/test/unit/web3_eth_methods_with_parameters.test.ts +++ b/packages/web3-eth/test/unit/web3_eth_methods_with_parameters.test.ts @@ -4,7 +4,6 @@ import Web3Eth from '../../src/index'; import * as rpcMethodWrappers from '../../src/rpc_method_wrappers'; import { estimateGasValidData, - // estimateGasValidData, getBalanceValidData, getBlockNumberValidData, getBlockTransactionCountValidData, @@ -12,8 +11,6 @@ import { getBlockValidData, getCodeValidData, getFeeHistoryValidData, - // getCodeValidData, - // getFeeHistoryValidData, getGasPriceValidData, getHashRateValidData, getPastLogsValidData, @@ -26,16 +23,6 @@ import { sendSignedTransactionValidData, signValidData, submitWorkValidData, - // getPastLogsValidData, - // getStorageAtValidData, - // getTransactionCountValidData, - // getTransactionFromBlockValidData, - // getTransactionReceiptValidData, - // getTransactionValidData, - // getUncleValidData, - // sendSignedTransactionValidData, - // signValidData, - // submitWorkValidData, } from '../fixtures/web3_eth_methods_with_parameters'; jest.mock('../../src/rpc_method_wrappers'); @@ -52,20 +39,14 @@ describe('web3_eth_methods_with_parameters', () => { describe('getHashRate', () => { it.each(getHashRateValidData)('returnType: %s', async returnType => { await web3Eth.getHashRate(returnType); - expect(rpcMethodWrappers.getHashRate).toHaveBeenCalledWith( - web3Eth.web3Context, - returnType, - ); + expect(rpcMethodWrappers.getHashRate).toHaveBeenCalledWith(web3Eth, returnType); }); }); describe('getGasPrice', () => { it.each(getGasPriceValidData)('returnType: %s', async returnType => { await web3Eth.getGasPrice(returnType); - expect(rpcMethodWrappers.getGasPrice).toHaveBeenCalledWith( - web3Eth.web3Context, - returnType, - ); + expect(rpcMethodWrappers.getGasPrice).toHaveBeenCalledWith(web3Eth, returnType); }); }); @@ -73,7 +54,7 @@ describe('web3_eth_methods_with_parameters', () => { it.each(getBlockNumberValidData)('returnType: %s', async returnType => { await web3Eth.getBlockNumber(returnType); expect(rpcMethodWrappers.getBlockNumber).toHaveBeenCalledWith( - web3Eth.web3Context, + web3Eth, returnType, ); }); @@ -88,7 +69,7 @@ describe('web3_eth_methods_with_parameters', () => { async (input, rpcMethodParameters) => { await web3Eth.getBalance(...input); expect(rpcMethodWrappers.getBalance).toHaveBeenCalledWith( - web3Eth.web3Context, + web3Eth, ...rpcMethodParameters, ); }, @@ -101,7 +82,7 @@ describe('web3_eth_methods_with_parameters', () => { async (input, rpcMethodParameters) => { await web3Eth.getBlock(...input); expect(rpcMethodWrappers.getBlock).toHaveBeenCalledWith( - web3Eth.web3Context, + web3Eth, ...rpcMethodParameters, ); }, @@ -114,7 +95,7 @@ describe('web3_eth_methods_with_parameters', () => { async (input, rpcMethodParameters) => { await web3Eth.getBlockTransactionCount(...input); expect(rpcMethodWrappers.getBlockTransactionCount).toHaveBeenCalledWith( - web3Eth.web3Context, + web3Eth, ...rpcMethodParameters, ); }, @@ -127,7 +108,7 @@ describe('web3_eth_methods_with_parameters', () => { async (input, rpcMethodParameters) => { await web3Eth.getBlockUncleCount(...input); expect(rpcMethodWrappers.getBlockUncleCount).toHaveBeenCalledWith( - web3Eth.web3Context, + web3Eth, ...rpcMethodParameters, ); }, @@ -140,7 +121,7 @@ describe('web3_eth_methods_with_parameters', () => { async (input, rpcMethodParameters) => { await web3Eth.getUncle(...input); expect(rpcMethodWrappers.getUncle).toHaveBeenCalledWith( - web3Eth.web3Context, + web3Eth, ...rpcMethodParameters, ); }, @@ -153,7 +134,7 @@ describe('web3_eth_methods_with_parameters', () => { async (input, rpcMethodParameters) => { await web3Eth.getTransaction(...input); expect(rpcMethodWrappers.getTransaction).toHaveBeenCalledWith( - web3Eth.web3Context, + web3Eth, ...rpcMethodParameters, ); }, @@ -166,7 +147,7 @@ describe('web3_eth_methods_with_parameters', () => { async (input, rpcMethodParameters) => { await web3Eth.getTransactionFromBlock(...input); expect(rpcMethodWrappers.getTransactionFromBlock).toHaveBeenCalledWith( - web3Eth.web3Context, + web3Eth, ...rpcMethodParameters, ); }, @@ -179,7 +160,7 @@ describe('web3_eth_methods_with_parameters', () => { async (input, rpcMethodParameters) => { await web3Eth.getTransactionReceipt(...input); expect(rpcMethodWrappers.getTransactionReceipt).toHaveBeenCalledWith( - web3Eth.web3Context, + web3Eth, ...rpcMethodParameters, ); }, @@ -192,7 +173,7 @@ describe('web3_eth_methods_with_parameters', () => { async (input, rpcMethodParameters) => { await web3Eth.getTransactionCount(...input); expect(rpcMethodWrappers.getTransactionCount).toHaveBeenCalledWith( - web3Eth.web3Context, + web3Eth, ...rpcMethodParameters, ); }, @@ -205,7 +186,7 @@ describe('web3_eth_methods_with_parameters', () => { async (input, rpcMethodParameters) => { await web3Eth.estimateGas(...input); expect(rpcMethodWrappers.estimateGas).toHaveBeenCalledWith( - web3Eth.web3Context, + web3Eth, ...rpcMethodParameters, ); }, @@ -218,7 +199,7 @@ describe('web3_eth_methods_with_parameters', () => { async (input, rpcMethodParameters) => { await web3Eth.getFeeHistory(...input); expect(rpcMethodWrappers.getFeeHistory).toHaveBeenCalledWith( - web3Eth.web3Context, + web3Eth, ...rpcMethodParameters, ); }, @@ -233,7 +214,7 @@ describe('web3_eth_methods_with_parameters', () => { async (input, rpcMethodParameters) => { await web3Eth.getStorageAt(...input); expect(rpcMethodWrappers.getStorageAt).toHaveBeenCalledWith( - web3Eth.web3Context, + web3Eth, ...rpcMethodParameters, ); }, @@ -246,7 +227,7 @@ describe('web3_eth_methods_with_parameters', () => { async (input, rpcMethodParameters) => { await web3Eth.getCode(...input); expect(rpcMethodWrappers.getCode).toHaveBeenCalledWith( - web3Eth.web3Context, + web3Eth, ...rpcMethodParameters, ); }, @@ -257,7 +238,7 @@ describe('web3_eth_methods_with_parameters', () => { it.each(sendSignedTransactionValidData)('input: %s', async input => { await web3Eth.sendSignedTransaction(input); expect(rpcMethodWrappers.sendSignedTransaction).toHaveBeenCalledWith( - web3Eth.web3Context, + web3Eth, input, ); }); @@ -266,10 +247,7 @@ describe('web3_eth_methods_with_parameters', () => { describe('sign', () => { it.each(signValidData)('input: %s', async input => { await web3Eth.sign(...input); - expect(rpcMethodWrappers.sign).toHaveBeenCalledWith( - web3Eth.web3Context, - ...input, - ); + expect(rpcMethodWrappers.sign).toHaveBeenCalledWith(web3Eth, ...input); }); }); @@ -279,7 +257,7 @@ describe('web3_eth_methods_with_parameters', () => { async (input, rpcMethodParameters) => { await web3Eth.getPastLogs(input); expect(rpcMethodWrappers.getPastLogs).toHaveBeenCalledWith( - web3Eth.web3Context, + web3Eth, rpcMethodParameters, ); }, @@ -290,7 +268,7 @@ describe('web3_eth_methods_with_parameters', () => { it.each(submitWorkValidData)('input: %s', async input => { await web3Eth.submitWork(...input); expect(rpcMethodWrappers.submitWork).toHaveBeenCalledWith( - web3Eth.web3Context, + web3Eth, ...input, ); }); diff --git a/packages/web3-eth/test/unit/web3_rpc_method_wrappers_no_parameters.test.ts b/packages/web3-eth/test/unit/web3_rpc_method_wrappers_no_parameters.test.ts index b017ad4f1e0..e3bb528b017 100644 --- a/packages/web3-eth/test/unit/web3_rpc_method_wrappers_no_parameters.test.ts +++ b/packages/web3-eth/test/unit/web3_rpc_method_wrappers_no_parameters.test.ts @@ -20,35 +20,33 @@ describe('web3_eth_methods_no_parameters', () => { describe('should call RPC method with only request manager parameter', () => { it('getProtocolVersion', async () => { - await getProtocolVersion(web3Eth.web3Context); - expect(rpcMethods.getProtocolVersion).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, - ); + await getProtocolVersion(web3Eth); + expect(rpcMethods.getProtocolVersion).toHaveBeenCalledWith(web3Eth.requestManager); }); it('isSyncing', async () => { - await isSyncing(web3Eth.web3Context); - expect(rpcMethods.getSyncing).toHaveBeenCalledWith(web3Eth.web3Context.requestManager); + await isSyncing(web3Eth); + expect(rpcMethods.getSyncing).toHaveBeenCalledWith(web3Eth.requestManager); }); it('getCoinbase', async () => { - await getCoinbase(web3Eth.web3Context); - expect(rpcMethods.getCoinbase).toHaveBeenCalledWith(web3Eth.web3Context.requestManager); + await getCoinbase(web3Eth); + expect(rpcMethods.getCoinbase).toHaveBeenCalledWith(web3Eth.requestManager); }); it('isMining', async () => { - await isMining(web3Eth.web3Context); - expect(rpcMethods.getMining).toHaveBeenCalledWith(web3Eth.web3Context.requestManager); + await isMining(web3Eth); + expect(rpcMethods.getMining).toHaveBeenCalledWith(web3Eth.requestManager); }); it('getAccounts', async () => { - await getAccounts(web3Eth.web3Context); - expect(rpcMethods.getAccounts).toHaveBeenCalledWith(web3Eth.web3Context.requestManager); + await getAccounts(web3Eth); + expect(rpcMethods.getAccounts).toHaveBeenCalledWith(web3Eth.requestManager); }); it('getWork', async () => { - await getWork(web3Eth.web3Context); - expect(rpcMethods.getWork).toHaveBeenCalledWith(web3Eth.web3Context.requestManager); + await getWork(web3Eth); + expect(rpcMethods.getWork).toHaveBeenCalledWith(web3Eth.requestManager); }); }); }); diff --git a/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts b/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts index adb1fcaa0f2..c43a2e0d67e 100644 --- a/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts +++ b/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts @@ -65,10 +65,8 @@ describe('web3_eth_methods_with_parameters', () => { (rpcMethods.getHashRate as jest.Mock).mockResolvedValueOnce( mockRpcResponse, ); - expect(await getHashRate(web3Eth.web3Context, returnType)).toBe(output); - expect(rpcMethods.getHashRate).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, - ); + expect(await getHashRate(web3Eth, returnType)).toBe(output); + expect(rpcMethods.getHashRate).toHaveBeenCalledWith(web3Eth.requestManager); }, ); }); @@ -80,10 +78,8 @@ describe('web3_eth_methods_with_parameters', () => { (rpcMethods.getGasPrice as jest.Mock).mockResolvedValueOnce( mockRpcResponse, ); - expect(await getGasPrice(web3Eth.web3Context, returnType)).toBe(output); - expect(rpcMethods.getGasPrice).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, - ); + expect(await getGasPrice(web3Eth, returnType)).toBe(output); + expect(rpcMethods.getGasPrice).toHaveBeenCalledWith(web3Eth.requestManager); }, ); }); @@ -95,9 +91,9 @@ describe('web3_eth_methods_with_parameters', () => { (rpcMethods.getBlockNumber as jest.Mock).mockResolvedValueOnce( mockRpcResponse, ); - expect(await getBlockNumber(web3Eth.web3Context, returnType)).toBe(output); + expect(await getBlockNumber(web3Eth, returnType)).toBe(output); expect(rpcMethods.getBlockNumber).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + web3Eth.requestManager, ); }, ); @@ -113,9 +109,9 @@ describe('web3_eth_methods_with_parameters', () => { (rpcMethods.getBalance as jest.Mock).mockResolvedValueOnce( mockRpcResponse, ); - expect(await getBalance(web3Eth.web3Context, ...input)).toBe(output); + expect(await getBalance(web3Eth, ...input)).toBe(output); expect(rpcMethods.getBalance).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + web3Eth.requestManager, ...rpcMethodParameters, ); }, @@ -135,11 +131,9 @@ describe('web3_eth_methods_with_parameters', () => { ( rpcMethods[expectedRpcMethodToBeCalled] as jest.Mock ).mockResolvedValueOnce(mockRpcResponse); - expect(await getBlock(web3Eth.web3Context, ...input)).toStrictEqual( - output, - ); + expect(await getBlock(web3Eth, ...input)).toStrictEqual(output); expect(rpcMethods[expectedRpcMethodToBeCalled]).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + web3Eth.requestManager, ...rpcMethodParameters, ); }, @@ -159,11 +153,11 @@ describe('web3_eth_methods_with_parameters', () => { ( rpcMethods[expectedRpcMethodToBeCalled] as jest.Mock ).mockResolvedValueOnce(mockRpcResponse); - expect( - await getBlockTransactionCount(web3Eth.web3Context, ...input), - ).toStrictEqual(output); + expect(await getBlockTransactionCount(web3Eth, ...input)).toStrictEqual( + output, + ); expect(rpcMethods[expectedRpcMethodToBeCalled]).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + web3Eth.requestManager, ...rpcMethodParameters, ); }, @@ -183,11 +177,11 @@ describe('web3_eth_methods_with_parameters', () => { ( rpcMethods[expectedRpcMethodToBeCalled] as jest.Mock ).mockResolvedValueOnce(mockRpcResponse); - expect( - await getBlockUncleCount(web3Eth.web3Context, ...input), - ).toStrictEqual(output); + expect(await getBlockUncleCount(web3Eth, ...input)).toStrictEqual( + output, + ); expect(rpcMethods[expectedRpcMethodToBeCalled]).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + web3Eth.requestManager, ...rpcMethodParameters, ); }, @@ -207,11 +201,9 @@ describe('web3_eth_methods_with_parameters', () => { ( rpcMethods[expectedRpcMethodToBeCalled] as jest.Mock ).mockResolvedValueOnce(mockRpcResponse); - expect(await getUncle(web3Eth.web3Context, ...input)).toStrictEqual( - output, - ); + expect(await getUncle(web3Eth, ...input)).toStrictEqual(output); expect(rpcMethods[expectedRpcMethodToBeCalled]).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + web3Eth.requestManager, ...rpcMethodParameters, ); }, @@ -225,11 +217,9 @@ describe('web3_eth_methods_with_parameters', () => { (rpcMethods.getTransactionByHash as jest.Mock).mockResolvedValueOnce( mockRpcResponse, ); - expect( - await getTransaction(web3Eth.web3Context, ...input), - ).toStrictEqual(output); + expect(await getTransaction(web3Eth, ...input)).toStrictEqual(output); expect(rpcMethods.getTransactionByHash).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + web3Eth.requestManager, ...rpcMethodParameters, ); }, @@ -249,11 +239,11 @@ describe('web3_eth_methods_with_parameters', () => { ( rpcMethods[expectedRpcMethodToBeCalled] as jest.Mock ).mockResolvedValueOnce(mockRpcResponse); - expect( - await getTransactionFromBlock(web3Eth.web3Context, ...input), - ).toStrictEqual(output); + expect(await getTransactionFromBlock(web3Eth, ...input)).toStrictEqual( + output, + ); expect(rpcMethods[expectedRpcMethodToBeCalled]).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + web3Eth.requestManager, ...rpcMethodParameters, ); }, @@ -267,11 +257,11 @@ describe('web3_eth_methods_with_parameters', () => { (rpcMethods.getTransactionReceipt as jest.Mock).mockResolvedValueOnce( mockRpcResponse, ); - expect( - await getTransactionReceipt(web3Eth.web3Context, ...input), - ).toStrictEqual(output); + expect(await getTransactionReceipt(web3Eth, ...input)).toStrictEqual( + output, + ); expect(rpcMethods.getTransactionReceipt).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + web3Eth.requestManager, ...rpcMethodParameters, ); }, @@ -285,11 +275,11 @@ describe('web3_eth_methods_with_parameters', () => { (rpcMethods.getTransactionCount as jest.Mock).mockResolvedValueOnce( mockRpcResponse, ); - expect( - await getTransactionCount(web3Eth.web3Context, ...input), - ).toStrictEqual(output); + expect(await getTransactionCount(web3Eth, ...input)).toStrictEqual( + output, + ); expect(rpcMethods.getTransactionCount).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + web3Eth.requestManager, ...rpcMethodParameters, ); }, @@ -303,11 +293,9 @@ describe('web3_eth_methods_with_parameters', () => { (rpcMethods.estimateGas as jest.Mock).mockResolvedValueOnce( mockRpcResponse, ); - expect(await estimateGas(web3Eth.web3Context, ...input)).toStrictEqual( - output, - ); + expect(await estimateGas(web3Eth, ...input)).toStrictEqual(output); expect(rpcMethods.estimateGas).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + web3Eth.requestManager, ...rpcMethodParameters, ); }, @@ -321,11 +309,9 @@ describe('web3_eth_methods_with_parameters', () => { (rpcMethods.getFeeHistory as jest.Mock).mockResolvedValueOnce( mockRpcResponse, ); - expect( - await getFeeHistory(web3Eth.web3Context, ...input), - ).toStrictEqual(output); + expect(await getFeeHistory(web3Eth, ...input)).toStrictEqual(output); expect(rpcMethods.getFeeHistory).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + web3Eth.requestManager, ...rpcMethodParameters, ); }, @@ -341,11 +327,9 @@ describe('web3_eth_methods_with_parameters', () => { (rpcMethods.getStorageAt as jest.Mock).mockResolvedValueOnce( mockRpcResponse, ); - expect(await getStorageAt(web3Eth.web3Context, ...input)).toBe( - mockRpcResponse, - ); + expect(await getStorageAt(web3Eth, ...input)).toBe(mockRpcResponse); expect(rpcMethods.getStorageAt).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + web3Eth.requestManager, ...rpcMethodParameters, ); }, @@ -359,11 +343,9 @@ describe('web3_eth_methods_with_parameters', () => { (rpcMethods.getCode as jest.Mock).mockResolvedValueOnce( mockRpcResponse, ); - expect(await getCode(web3Eth.web3Context, ...input)).toBe( - mockRpcResponse, - ); + expect(await getCode(web3Eth, ...input)).toBe(mockRpcResponse); expect(rpcMethods.getCode).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + web3Eth.requestManager, ...rpcMethodParameters, ); }, @@ -377,11 +359,11 @@ describe('web3_eth_methods_with_parameters', () => { (rpcMethods.sendRawTransaction as jest.Mock).mockResolvedValueOnce( mockRpcResponse, ); - expect(await sendSignedTransaction(web3Eth.web3Context, input)).toBe( + expect(await sendSignedTransaction(web3Eth, input)).toBe( mockRpcResponse, ); expect(rpcMethods.sendRawTransaction).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + web3Eth.requestManager, input, ); }, @@ -393,9 +375,9 @@ describe('web3_eth_methods_with_parameters', () => { 'input: %s\nmockRpcResponse: %s', async (input, mockRpcResponse) => { (rpcMethods.sign as jest.Mock).mockResolvedValueOnce(mockRpcResponse); - expect(await sign(web3Eth.web3Context, ...input)).toBe(mockRpcResponse); + expect(await sign(web3Eth, ...input)).toBe(mockRpcResponse); expect(rpcMethods.sign).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + web3Eth.requestManager, // web3-eth methods takes sign(message, address) // RPC method takes sign(address, message) // so we manually swap them here @@ -413,11 +395,9 @@ describe('web3_eth_methods_with_parameters', () => { (rpcMethods.getLogs as jest.Mock).mockResolvedValueOnce( mockRpcResponse, ); - expect(await getPastLogs(web3Eth.web3Context, input)).toBe( - mockRpcResponse, - ); + expect(await getPastLogs(web3Eth, input)).toBe(mockRpcResponse); expect(rpcMethods.getLogs).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + web3Eth.requestManager, rpcMethodParameters, ); }, @@ -431,11 +411,9 @@ describe('web3_eth_methods_with_parameters', () => { (rpcMethods.submitWork as jest.Mock).mockResolvedValueOnce( mockRpcResponse, ); - expect(await submitWork(web3Eth.web3Context, ...input)).toBe( - mockRpcResponse, - ); + expect(await submitWork(web3Eth, ...input)).toBe(mockRpcResponse); expect(rpcMethods.submitWork).toHaveBeenCalledWith( - web3Eth.web3Context.requestManager, + web3Eth.requestManager, ...input, ); }, From 1e35ca5dc2194e12729c20f8c32fca8870db3797 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Sat, 12 Feb 2022 22:01:44 -1000 Subject: [PATCH 099/132] Init getPendingTransactions --- packages/web3-common/src/eth_execution_api.ts | 1 + packages/web3-eth/src/index.ts | 8 ++++---- packages/web3-eth/src/rpc_methods.ts | 7 +++++++ .../web3-eth/test/unit/rpc_methods_no_parameters.test.ts | 9 +++++++++ .../test/unit/web3_eth_methods_no_parameters.test.ts | 5 +++++ 5 files changed, 26 insertions(+), 4 deletions(-) diff --git a/packages/web3-common/src/eth_execution_api.ts b/packages/web3-common/src/eth_execution_api.ts index 795bdb5b546..45b9c2c25d0 100644 --- a/packages/web3-common/src/eth_execution_api.ts +++ b/packages/web3-common/src/eth_execution_api.ts @@ -211,6 +211,7 @@ export type EthExecutionAPI = { transactionIndex: Uint, ) => TransactionInfo | null; eth_getTransactionReceipt: (transactionHash: HexString32Bytes) => ReceiptInfo | null; + eth_pendingTransactions: () => TransactionInfo[]; // https://github.com/ethereum/execution-apis/blob/main/src/eth/client.json eth_protocolVersion: () => string; diff --git a/packages/web3-eth/src/index.ts b/packages/web3-eth/src/index.ts index 1a292f3a465..f3745f5bd95 100644 --- a/packages/web3-eth/src/index.ts +++ b/packages/web3-eth/src/index.ts @@ -115,10 +115,10 @@ export default class Web3Eth extends Web3Context { return rpcMethodsWrappers.getTransaction(this, transactionHash, returnType); } - // TODO Can't find in spec - // public async getPendingTransactions() { - - // } + // TODO Format transactions + public async getPendingTransactions() { + return rpcMethods.getPendingTransactions(this.requestManager); + } public async getTransactionFromBlock( block: HexString32Bytes | BlockNumberOrTag = this.defaultBlock, diff --git a/packages/web3-eth/src/rpc_methods.ts b/packages/web3-eth/src/rpc_methods.ts index aed97bcc52b..d679e4e4ccd 100644 --- a/packages/web3-eth/src/rpc_methods.ts +++ b/packages/web3-eth/src/rpc_methods.ts @@ -323,6 +323,13 @@ export async function getTransactionReceipt( }); } +export async function getPendingTransactions(requestManager: Web3RequestManager) { + return requestManager.send({ + method: 'eth_pendingTransactions', + params: [], + }); +} + export async function getUncleByBlockHashAndIndex( requestManager: Web3RequestManager, blockHash: HexString32Bytes, diff --git a/packages/web3-eth/test/unit/rpc_methods_no_parameters.test.ts b/packages/web3-eth/test/unit/rpc_methods_no_parameters.test.ts index f2dfd50621c..12ac9d0a3f9 100644 --- a/packages/web3-eth/test/unit/rpc_methods_no_parameters.test.ts +++ b/packages/web3-eth/test/unit/rpc_methods_no_parameters.test.ts @@ -8,6 +8,7 @@ import { getGasPrice, getHashRate, getMining, + getPendingTransactions, getProtocolVersion, getSyncing, getWork, @@ -127,5 +128,13 @@ describe('rpc_methods_no_parameters', () => { params: [], }); }); + it('getPendingTransactions', async () => { + await getPendingTransactions(requestManager); + + expect(requestManagerSendSpy).toHaveBeenCalledWith({ + method: 'eth_pendingTransactions', + params: [], + }); + }); }); }); diff --git a/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts b/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts index fee8f5bcfec..7218de7aa74 100644 --- a/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts +++ b/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts @@ -40,5 +40,10 @@ describe('web3_eth_methods_no_parameters', () => { await web3Eth.getWork(); expect(rpcMethods.getWork).toHaveBeenCalledWith(web3Eth.requestManager); }); + + it('getPendingTransactions', async () => { + await web3Eth.getPendingTransactions(); + expect(rpcMethods.getPendingTransactions).toHaveBeenCalledWith(web3Eth.requestManager); + }); }); }); From 770b2171c0ce92ec039e56d4fa8fbfb39db6bfa4 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Sat, 12 Feb 2022 22:26:24 -1000 Subject: [PATCH 100/132] Init requestAccounts --- packages/web3-common/src/eth_execution_api.ts | 3 ++- packages/web3-eth/src/index.ts | 8 +++---- packages/web3-eth/src/rpc_methods.ts | 21 ++++++++++++------- .../unit/rpc_methods_no_parameters.test.ts | 9 ++++++++ .../web3_eth_methods_no_parameters.test.ts | 5 +++++ 5 files changed, 34 insertions(+), 12 deletions(-) diff --git a/packages/web3-common/src/eth_execution_api.ts b/packages/web3-common/src/eth_execution_api.ts index 45b9c2c25d0..72445ee7a0f 100644 --- a/packages/web3-common/src/eth_execution_api.ts +++ b/packages/web3-common/src/eth_execution_api.ts @@ -211,7 +211,6 @@ export type EthExecutionAPI = { transactionIndex: Uint, ) => TransactionInfo | null; eth_getTransactionReceipt: (transactionHash: HexString32Bytes) => ReceiptInfo | null; - eth_pendingTransactions: () => TransactionInfo[]; // https://github.com/ethereum/execution-apis/blob/main/src/eth/client.json eth_protocolVersion: () => string; @@ -288,4 +287,6 @@ export type EthExecutionAPI = { eth_compileSolidity: (code: string) => CompileResult; eth_compileLLL: (code: string) => HexStringBytes; eth_compileSerpent: (code: string) => HexStringBytes; + eth_pendingTransactions: () => TransactionInfo[]; + eth_requestAccounts: () => Address[]; }; diff --git a/packages/web3-eth/src/index.ts b/packages/web3-eth/src/index.ts index f3745f5bd95..08159ec0fe2 100644 --- a/packages/web3-eth/src/index.ts +++ b/packages/web3-eth/src/index.ts @@ -208,10 +208,10 @@ export default class Web3Eth extends Web3Context { return rpcMethods.submitWork(this.requestManager, nonce, seedHash, difficulty); } - // // TODO - // // public async requestAccounts() { - - // // } + // TODO - Format addresses + public async requestAccounts() { + return rpcMethods.requestAccounts(this.requestManager); + } // // TODO // // public async getChainId() { diff --git a/packages/web3-eth/src/rpc_methods.ts b/packages/web3-eth/src/rpc_methods.ts index d679e4e4ccd..50e172975c6 100644 --- a/packages/web3-eth/src/rpc_methods.ts +++ b/packages/web3-eth/src/rpc_methods.ts @@ -323,13 +323,6 @@ export async function getTransactionReceipt( }); } -export async function getPendingTransactions(requestManager: Web3RequestManager) { - return requestManager.send({ - method: 'eth_pendingTransactions', - params: [], - }); -} - export async function getUncleByBlockHashAndIndex( requestManager: Web3RequestManager, blockHash: HexString32Bytes, @@ -500,3 +493,17 @@ export async function getFeeHistory( params: [blockCount, newestBlock, rewardPercentiles], }); } + +export async function getPendingTransactions(requestManager: Web3RequestManager) { + return requestManager.send({ + method: 'eth_pendingTransactions', + params: [], + }); +} + +export async function requestAccounts(requestManager: Web3RequestManager) { + return requestManager.send({ + method: 'eth_requestAccounts', + params: [], + }); +} diff --git a/packages/web3-eth/test/unit/rpc_methods_no_parameters.test.ts b/packages/web3-eth/test/unit/rpc_methods_no_parameters.test.ts index 12ac9d0a3f9..f63dce6abc9 100644 --- a/packages/web3-eth/test/unit/rpc_methods_no_parameters.test.ts +++ b/packages/web3-eth/test/unit/rpc_methods_no_parameters.test.ts @@ -14,6 +14,7 @@ import { getWork, newBlockFilter, newPendingTransactionFilter, + requestAccounts, } from '../../src/rpc_methods'; describe('rpc_methods_no_parameters', () => { @@ -136,5 +137,13 @@ describe('rpc_methods_no_parameters', () => { params: [], }); }); + it('requestAccounts', async () => { + await requestAccounts(requestManager); + + expect(requestManagerSendSpy).toHaveBeenCalledWith({ + method: 'eth_requestAccounts', + params: [], + }); + }); }); }); diff --git a/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts b/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts index 7218de7aa74..c985bdc6a3e 100644 --- a/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts +++ b/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts @@ -45,5 +45,10 @@ describe('web3_eth_methods_no_parameters', () => { await web3Eth.getPendingTransactions(); expect(rpcMethods.getPendingTransactions).toHaveBeenCalledWith(web3Eth.requestManager); }); + + it('requestAccounts', async () => { + await web3Eth.requestAccounts(); + expect(rpcMethods.requestAccounts).toHaveBeenCalledWith(web3Eth.requestManager); + }); }); }); From 54cdc59026b5342ea8e67aa1dac474bbc5d7ac76 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Sat, 12 Feb 2022 22:40:04 -1000 Subject: [PATCH 101/132] Add EIP-1102 as a comment for requestAccounts --- packages/web3-common/src/eth_execution_api.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/web3-common/src/eth_execution_api.ts b/packages/web3-common/src/eth_execution_api.ts index 72445ee7a0f..c4535e5732f 100644 --- a/packages/web3-common/src/eth_execution_api.ts +++ b/packages/web3-common/src/eth_execution_api.ts @@ -288,5 +288,7 @@ export type EthExecutionAPI = { eth_compileLLL: (code: string) => HexStringBytes; eth_compileSerpent: (code: string) => HexStringBytes; eth_pendingTransactions: () => TransactionInfo[]; + + // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1102.md eth_requestAccounts: () => Address[]; }; From 892b3416c7fde7fce8135e7131bdc72209ec1804 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Sat, 12 Feb 2022 22:48:31 -1000 Subject: [PATCH 102/132] Init getChainId --- packages/web3-common/src/eth_execution_api.ts | 3 +++ packages/web3-eth/src/index.ts | 8 ++++---- packages/web3-eth/src/rpc_methods.ts | 7 +++++++ .../web3-eth/test/unit/rpc_methods_no_parameters.test.ts | 9 +++++++++ .../test/unit/web3_eth_methods_no_parameters.test.ts | 5 +++++ 5 files changed, 28 insertions(+), 4 deletions(-) diff --git a/packages/web3-common/src/eth_execution_api.ts b/packages/web3-common/src/eth_execution_api.ts index c4535e5732f..6602bc6f014 100644 --- a/packages/web3-common/src/eth_execution_api.ts +++ b/packages/web3-common/src/eth_execution_api.ts @@ -291,4 +291,7 @@ export type EthExecutionAPI = { // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1102.md eth_requestAccounts: () => Address[]; + + // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-695.md + eth_chainId: () => Uint; }; diff --git a/packages/web3-eth/src/index.ts b/packages/web3-eth/src/index.ts index 08159ec0fe2..9a429e830d5 100644 --- a/packages/web3-eth/src/index.ts +++ b/packages/web3-eth/src/index.ts @@ -213,10 +213,10 @@ export default class Web3Eth extends Web3Context { return rpcMethods.requestAccounts(this.requestManager); } - // // TODO - // // public async getChainId() { - - // // } + // TODO - Format chainId + public async getChainId() { + return rpcMethods.getChainId(this.requestManager); + } // // TODO // // public async getNodeInfo() { diff --git a/packages/web3-eth/src/rpc_methods.ts b/packages/web3-eth/src/rpc_methods.ts index 50e172975c6..a9ecb108004 100644 --- a/packages/web3-eth/src/rpc_methods.ts +++ b/packages/web3-eth/src/rpc_methods.ts @@ -507,3 +507,10 @@ export async function requestAccounts(requestManager: Web3RequestManager) { params: [], }); } + +export async function getChainId(requestManager: Web3RequestManager) { + return requestManager.send({ + method: 'eth_chainId', + params: [], + }); +} diff --git a/packages/web3-eth/test/unit/rpc_methods_no_parameters.test.ts b/packages/web3-eth/test/unit/rpc_methods_no_parameters.test.ts index f63dce6abc9..16c9c1e72e5 100644 --- a/packages/web3-eth/test/unit/rpc_methods_no_parameters.test.ts +++ b/packages/web3-eth/test/unit/rpc_methods_no_parameters.test.ts @@ -3,6 +3,7 @@ import { Web3RequestManager } from 'web3-core'; import { getAccounts, getBlockNumber, + getChainId, getCoinbase, getCompilers, getGasPrice, @@ -145,5 +146,13 @@ describe('rpc_methods_no_parameters', () => { params: [], }); }); + it('getChainId', async () => { + await getChainId(requestManager); + + expect(requestManagerSendSpy).toHaveBeenCalledWith({ + method: 'eth_chainId', + params: [], + }); + }); }); }); diff --git a/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts b/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts index c985bdc6a3e..01b4f2d284b 100644 --- a/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts +++ b/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts @@ -50,5 +50,10 @@ describe('web3_eth_methods_no_parameters', () => { await web3Eth.requestAccounts(); expect(rpcMethods.requestAccounts).toHaveBeenCalledWith(web3Eth.requestManager); }); + + it('getChainId', async () => { + await web3Eth.getChainId(); + expect(rpcMethods.getChainId).toHaveBeenCalledWith(web3Eth.requestManager); + }); }); }); From 1ac1a9ca10d5948d8df296c8a113c96a5b8af8a8 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 14 Feb 2022 21:42:50 -1000 Subject: [PATCH 103/132] Init getProof --- packages/web3-common/src/eth_execution_api.ts | 22 + packages/web3-eth/src/index.ts | 19 +- packages/web3-eth/src/rpc_method_wrappers.ts | 48 +- packages/web3-eth/src/rpc_methods.ts | 12 + packages/web3-eth/src/types.ts | 15 + packages/web3-eth/src/validation.ts | 1 - .../test/fixtures/rpc_methods_with_params.ts | 121 ++++- .../test/fixtures/rpc_methods_wrappers.ts | 439 ++++++++++++++++++ .../web3_eth_methods_with_parameters.ts | 311 +++++++++++++ .../unit/rpc_methods_with_parameters.test.ts | 12 + .../web3_eth_methods_with_parameters.test.ts | 14 + ...pc_method_wrappers_with_parameters.test.ts | 18 + 12 files changed, 999 insertions(+), 33 deletions(-) diff --git a/packages/web3-common/src/eth_execution_api.ts b/packages/web3-common/src/eth_execution_api.ts index 6602bc6f014..d986355ab8a 100644 --- a/packages/web3-common/src/eth_execution_api.ts +++ b/packages/web3-common/src/eth_execution_api.ts @@ -188,6 +188,21 @@ export interface CompileResult { }; } +export interface StorageProof { + readonly key: HexString32Bytes; + readonly value: Uint; + readonly proof: HexString32Bytes[]; +} + +export interface AccountObject { + readonly balance: Uint; + readonly codeHash: HexString32Bytes; + readonly nonce: Uint; + readonly storageHash: HexString32Bytes; + readonly accountProof: HexString32Bytes[]; + readonly storageProof: StorageProof[]; +} + /* eslint-disable camelcase */ export type EthExecutionAPI = { // https://github.com/ethereum/execution-apis/blob/main/src/eth/block.json @@ -294,4 +309,11 @@ export type EthExecutionAPI = { // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-695.md eth_chainId: () => Uint; + + // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1186.md + eth_getProof: ( + address: Address, + storageKey: HexString32Bytes, + blockNumber: BlockNumberOrTag, + ) => AccountObject; }; diff --git a/packages/web3-eth/src/index.ts b/packages/web3-eth/src/index.ts index 9a429e830d5..335cff1f4a8 100644 --- a/packages/web3-eth/src/index.ts +++ b/packages/web3-eth/src/index.ts @@ -218,15 +218,20 @@ export default class Web3Eth extends Web3Context { return rpcMethods.getChainId(this.requestManager); } - // // TODO - // // public async getNodeInfo() { + // TODO + // public async getNodeInfo() { - // // } - - // // TODO - // // public async getProof() { + // } - // // } + // TODO - Format input + public async getProof( + address: Address, + storageKey: HexString32Bytes, + blockNumber: BlockNumberOrTag = this.defaultBlock, + returnType?: ReturnType, + ) { + return rpcMethodsWrappers.getProof(this, address, storageKey, blockNumber, returnType); + } public async getFeeHistory( blockCount: Uint, diff --git a/packages/web3-eth/src/rpc_method_wrappers.ts b/packages/web3-eth/src/rpc_method_wrappers.ts index 1e1fe2b1345..4da137658ab 100644 --- a/packages/web3-eth/src/rpc_method_wrappers.ts +++ b/packages/web3-eth/src/rpc_method_wrappers.ts @@ -172,10 +172,6 @@ export async function getTransaction( web3Context: Web3Context, block: HexString32Bytes | BlockNumberOrTag | undefined, @@ -282,26 +278,6 @@ export async function estimateGas( web3Context: Web3Context, blockCount: Uint, @@ -322,3 +298,27 @@ export async function getFeeHistory( + web3Context: Web3Context, + address: Address, + storageKey: HexString32Bytes, + blockNumber: BlockNumberOrTag = web3Context.defaultBlock, + returnType?: ReturnType, +) { + const response = await rpcMethods.getProof( + web3Context.requestManager, + address, + storageKey, + blockNumber, + ); + return { + ...response, + balance: convertToValidType(response.balance, returnType ?? web3Context.defaultReturnType), + nonce: convertToValidType(response.nonce, returnType ?? web3Context.defaultReturnType), + storageProof: response.storageProof.map(proof => ({ + ...proof, + value: convertToValidType(proof.value, returnType ?? web3Context.defaultReturnType), + })), + }; +} diff --git a/packages/web3-eth/src/rpc_methods.ts b/packages/web3-eth/src/rpc_methods.ts index a9ecb108004..252d43783be 100644 --- a/packages/web3-eth/src/rpc_methods.ts +++ b/packages/web3-eth/src/rpc_methods.ts @@ -514,3 +514,15 @@ export async function getChainId(requestManager: Web3RequestManager) { params: [], }); } + +export async function getProof( + requestManager: Web3RequestManager, + address: Address, + storageKey: HexString32Bytes, + blockNumber: BlockNumberOrTag, +) { + return requestManager.send({ + method: 'eth_getProof', + params: [address, storageKey, blockNumber], + }); +} diff --git a/packages/web3-eth/src/types.ts b/packages/web3-eth/src/types.ts index e83c7a156b7..e66f0aaf62d 100644 --- a/packages/web3-eth/src/types.ts +++ b/packages/web3-eth/src/types.ts @@ -230,3 +230,18 @@ export interface FeeHistoryResultFormatted< readonly baseFeePerGas: ReturnType; readonly reward: number[][]; } + +export interface StorageProofFormatted { + readonly key: HexString32Bytes; + readonly value: NumberType; + readonly proof: HexString32Bytes[]; +} + +export interface AccountObjectFormatted { + readonly balance: NumberType; + readonly codeHash: HexString32Bytes; + readonly nonce: NumberType; + readonly storageHash: HexString32Bytes; + readonly accountProof: HexString32Bytes[]; + readonly storageProof: StorageProofFormatted[]; +} diff --git a/packages/web3-eth/src/validation.ts b/packages/web3-eth/src/validation.ts index ed309f2d633..a4ffd5aaefa 100644 --- a/packages/web3-eth/src/validation.ts +++ b/packages/web3-eth/src/validation.ts @@ -134,7 +134,6 @@ export const validateCustomChainInfo = (transaction: Transaction) => { customChainId: transaction.common.customChain.chainId, }); } - }; export const validateChainInfo = (transaction: Transaction) => { diff --git a/packages/web3-eth/test/fixtures/rpc_methods_with_params.ts b/packages/web3-eth/test/fixtures/rpc_methods_with_params.ts index 1b269b4eeb3..42ae27d32bb 100644 --- a/packages/web3-eth/test/fixtures/rpc_methods_with_params.ts +++ b/packages/web3-eth/test/fixtures/rpc_methods_with_params.ts @@ -1,4 +1,4 @@ -import { TransactionCall, TransactionWithSender } from 'web3-common'; +import { AccountObject, TransactionCall, TransactionWithSender } from 'web3-common'; import { Address, BlockNumberOrTag, @@ -254,3 +254,122 @@ export const getFeeHistoryValidData: [Uint, BlockNumberOrTag, number[]][] = [ ['0x1', BlockTags.LATEST, [42]], ['0x1', BlockTags.PENDING, [42]], ]; + +export const getProofValidData: [Address, HexString32Bytes, BlockNumberOrTag, AccountObject][] = [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + '0x1', + { + accountProof: [ + '0xf90211a090dcaf88c40c7bbc95a912cbdde67c175767b31173df9ee4b0d733bfdd511c43a0babe369f6b12092f49181ae04ca173fb68d1a5456f18d20fa32cba73954052bda0473ecf8a7e36a829e75039a3b055e51b8332cbf03324ab4af2066bbd6fbf0021a0bbda34753d7aa6c38e603f360244e8f59611921d9e1f128372fec0d586d4f9e0a04e44caecff45c9891f74f6a2156735886eedf6f1a733628ebc802ec79d844648a0a5f3f2f7542148c973977c8a1e154c4300fec92f755f7846f1b734d3ab1d90e7a0e823850f50bf72baae9d1733a36a444ab65d0a6faaba404f0583ce0ca4dad92da0f7a00cbe7d4b30b11faea3ae61b7f1f2b315b61d9f6bd68bfe587ad0eeceb721a07117ef9fc932f1a88e908eaead8565c19b5645dc9e5b1b6e841c5edbdfd71681a069eb2de283f32c11f859d7bcf93da23990d3e662935ed4d6b39ce3673ec84472a0203d26456312bbc4da5cd293b75b840fc5045e493d6f904d180823ec22bfed8ea09287b5c21f2254af4e64fca76acc5cd87399c7f1ede818db4326c98ce2dc2208a06fc2d754e304c48ce6a517753c62b1a9c1d5925b89707486d7fc08919e0a94eca07b1c54f15e299bd58bdfef9741538c7828b5d7d11a489f9c20d052b3471df475a051f9dd3739a927c89e357580a4c97b40234aa01ed3d5e0390dc982a7975880a0a089d613f26159af43616fd9455bb461f4869bfede26f2130835ed067a8b967bfb80', + '0xf90211a0395d87a95873cd98c21cf1df9421af03f7247880a2554e20738eec2c7507a494a0bcf6546339a1e7e14eb8fb572a968d217d2a0d1f3bc4257b22ef5333e9e4433ca012ae12498af8b2752c99efce07f3feef8ec910493be749acd63822c3558e6671a0dbf51303afdc36fc0c2d68a9bb05dab4f4917e7531e4a37ab0a153472d1b86e2a0ae90b50f067d9a2244e3d975233c0a0558c39ee152969f6678790abf773a9621a01d65cd682cc1be7c5e38d8da5c942e0a73eeaef10f387340a40a106699d494c3a06163b53d956c55544390c13634ea9aa75309f4fd866f312586942daf0f60fb37a058a52c1e858b1382a8893eb9c1f111f266eb9e21e6137aff0dddea243a567000a037b4b100761e02de63ea5f1fcfcf43e81a372dafb4419d126342136d329b7a7ba032472415864b08f808ba4374092003c8d7c40a9f7f9fe9cc8291f62538e1cc14a074e238ff5ec96b810364515551344100138916594d6af966170ff326a092fab0a0d31ac4eef14a79845200a496662e92186ca8b55e29ed0f9f59dbc6b521b116fea090607784fe738458b63c1942bba7c0321ae77e18df4961b2bc66727ea996464ea078f757653c1b63f72aff3dcc3f2a2e4c8cb4a9d36d1117c742833c84e20de994a0f78407de07f4b4cb4f899dfb95eedeb4049aeb5fc1635d65cf2f2f4dfd25d1d7a0862037513ba9d45354dd3e36264aceb2b862ac79d2050f14c95657e43a51b85c80', + '0xf90171a04ad705ea7bf04339fa36b124fa221379bd5a38ffe9a6112cb2d94be3a437b879a08e45b5f72e8149c01efcb71429841d6a8879d4bbe27335604a5bff8dfdf85dcea00313d9b2f7c03733d6549ea3b810e5262ed844ea12f70993d87d3e0f04e3979ea0b59e3cdd6750fa8b15164612a5cb6567cdfb386d4e0137fccee5f35ab55d0efda0fe6db56e42f2057a071c980a778d9a0b61038f269dd74a0e90155b3f40f14364a08538587f2378a0849f9608942cf481da4120c360f8391bbcc225d811823c6432a026eac94e755534e16f9552e73025d6d9c30d1d7682a4cb5bd7741ddabfd48c50a041557da9a74ca68da793e743e81e2029b2835e1cc16e9e25bd0c1e89d4ccad6980a041dda0a40a21ade3a20fcd1a4abb2a42b74e9a32b02424ff8db4ea708a5e0fb9a09aaf8326a51f613607a8685f57458329b41e938bb761131a5747e066b81a0a16808080a022e6cef138e16d2272ef58434ddf49260dc1de1f8ad6dfca3da5d2a92aaaadc58080', + '0xf851808080a009833150c367df138f1538689984b8a84fc55692d3d41fe4d1e5720ff5483a6980808080808080808080a0a319c1c415b271afc0adcb664e67738d103ac168e0bc0b7bd2da7966165cb9518080', + ], + balance: '0x0', + codeHash: '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470', + nonce: '0x0', + storageHash: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', + storageProof: [ + { + key: '0x0000000000000000000000000000000000000000000000000000000000000000', + value: '0x0', + proof: [], + }, + { + key: '0x0000000000000000000000000000000000000000000000000000000000000001', + value: '0x0', + proof: [], + }, + ], + }, + ], + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.EARLIEST, + { + accountProof: [ + '0xf90211a090dcaf88c40c7bbc95a912cbdde67c175767b31173df9ee4b0d733bfdd511c43a0babe369f6b12092f49181ae04ca173fb68d1a5456f18d20fa32cba73954052bda0473ecf8a7e36a829e75039a3b055e51b8332cbf03324ab4af2066bbd6fbf0021a0bbda34753d7aa6c38e603f360244e8f59611921d9e1f128372fec0d586d4f9e0a04e44caecff45c9891f74f6a2156735886eedf6f1a733628ebc802ec79d844648a0a5f3f2f7542148c973977c8a1e154c4300fec92f755f7846f1b734d3ab1d90e7a0e823850f50bf72baae9d1733a36a444ab65d0a6faaba404f0583ce0ca4dad92da0f7a00cbe7d4b30b11faea3ae61b7f1f2b315b61d9f6bd68bfe587ad0eeceb721a07117ef9fc932f1a88e908eaead8565c19b5645dc9e5b1b6e841c5edbdfd71681a069eb2de283f32c11f859d7bcf93da23990d3e662935ed4d6b39ce3673ec84472a0203d26456312bbc4da5cd293b75b840fc5045e493d6f904d180823ec22bfed8ea09287b5c21f2254af4e64fca76acc5cd87399c7f1ede818db4326c98ce2dc2208a06fc2d754e304c48ce6a517753c62b1a9c1d5925b89707486d7fc08919e0a94eca07b1c54f15e299bd58bdfef9741538c7828b5d7d11a489f9c20d052b3471df475a051f9dd3739a927c89e357580a4c97b40234aa01ed3d5e0390dc982a7975880a0a089d613f26159af43616fd9455bb461f4869bfede26f2130835ed067a8b967bfb80', + '0xf90211a0395d87a95873cd98c21cf1df9421af03f7247880a2554e20738eec2c7507a494a0bcf6546339a1e7e14eb8fb572a968d217d2a0d1f3bc4257b22ef5333e9e4433ca012ae12498af8b2752c99efce07f3feef8ec910493be749acd63822c3558e6671a0dbf51303afdc36fc0c2d68a9bb05dab4f4917e7531e4a37ab0a153472d1b86e2a0ae90b50f067d9a2244e3d975233c0a0558c39ee152969f6678790abf773a9621a01d65cd682cc1be7c5e38d8da5c942e0a73eeaef10f387340a40a106699d494c3a06163b53d956c55544390c13634ea9aa75309f4fd866f312586942daf0f60fb37a058a52c1e858b1382a8893eb9c1f111f266eb9e21e6137aff0dddea243a567000a037b4b100761e02de63ea5f1fcfcf43e81a372dafb4419d126342136d329b7a7ba032472415864b08f808ba4374092003c8d7c40a9f7f9fe9cc8291f62538e1cc14a074e238ff5ec96b810364515551344100138916594d6af966170ff326a092fab0a0d31ac4eef14a79845200a496662e92186ca8b55e29ed0f9f59dbc6b521b116fea090607784fe738458b63c1942bba7c0321ae77e18df4961b2bc66727ea996464ea078f757653c1b63f72aff3dcc3f2a2e4c8cb4a9d36d1117c742833c84e20de994a0f78407de07f4b4cb4f899dfb95eedeb4049aeb5fc1635d65cf2f2f4dfd25d1d7a0862037513ba9d45354dd3e36264aceb2b862ac79d2050f14c95657e43a51b85c80', + '0xf90171a04ad705ea7bf04339fa36b124fa221379bd5a38ffe9a6112cb2d94be3a437b879a08e45b5f72e8149c01efcb71429841d6a8879d4bbe27335604a5bff8dfdf85dcea00313d9b2f7c03733d6549ea3b810e5262ed844ea12f70993d87d3e0f04e3979ea0b59e3cdd6750fa8b15164612a5cb6567cdfb386d4e0137fccee5f35ab55d0efda0fe6db56e42f2057a071c980a778d9a0b61038f269dd74a0e90155b3f40f14364a08538587f2378a0849f9608942cf481da4120c360f8391bbcc225d811823c6432a026eac94e755534e16f9552e73025d6d9c30d1d7682a4cb5bd7741ddabfd48c50a041557da9a74ca68da793e743e81e2029b2835e1cc16e9e25bd0c1e89d4ccad6980a041dda0a40a21ade3a20fcd1a4abb2a42b74e9a32b02424ff8db4ea708a5e0fb9a09aaf8326a51f613607a8685f57458329b41e938bb761131a5747e066b81a0a16808080a022e6cef138e16d2272ef58434ddf49260dc1de1f8ad6dfca3da5d2a92aaaadc58080', + '0xf851808080a009833150c367df138f1538689984b8a84fc55692d3d41fe4d1e5720ff5483a6980808080808080808080a0a319c1c415b271afc0adcb664e67738d103ac168e0bc0b7bd2da7966165cb9518080', + ], + balance: '0x0', + codeHash: '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470', + nonce: '0x0', + storageHash: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', + storageProof: [ + { + key: '0x0000000000000000000000000000000000000000000000000000000000000000', + value: '0', + proof: [], + }, + { + key: '0x0000000000000000000000000000000000000000000000000000000000000001', + value: '0', + proof: [], + }, + ], + }, + ], + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.LATEST, + { + accountProof: [ + '0xf90211a090dcaf88c40c7bbc95a912cbdde67c175767b31173df9ee4b0d733bfdd511c43a0babe369f6b12092f49181ae04ca173fb68d1a5456f18d20fa32cba73954052bda0473ecf8a7e36a829e75039a3b055e51b8332cbf03324ab4af2066bbd6fbf0021a0bbda34753d7aa6c38e603f360244e8f59611921d9e1f128372fec0d586d4f9e0a04e44caecff45c9891f74f6a2156735886eedf6f1a733628ebc802ec79d844648a0a5f3f2f7542148c973977c8a1e154c4300fec92f755f7846f1b734d3ab1d90e7a0e823850f50bf72baae9d1733a36a444ab65d0a6faaba404f0583ce0ca4dad92da0f7a00cbe7d4b30b11faea3ae61b7f1f2b315b61d9f6bd68bfe587ad0eeceb721a07117ef9fc932f1a88e908eaead8565c19b5645dc9e5b1b6e841c5edbdfd71681a069eb2de283f32c11f859d7bcf93da23990d3e662935ed4d6b39ce3673ec84472a0203d26456312bbc4da5cd293b75b840fc5045e493d6f904d180823ec22bfed8ea09287b5c21f2254af4e64fca76acc5cd87399c7f1ede818db4326c98ce2dc2208a06fc2d754e304c48ce6a517753c62b1a9c1d5925b89707486d7fc08919e0a94eca07b1c54f15e299bd58bdfef9741538c7828b5d7d11a489f9c20d052b3471df475a051f9dd3739a927c89e357580a4c97b40234aa01ed3d5e0390dc982a7975880a0a089d613f26159af43616fd9455bb461f4869bfede26f2130835ed067a8b967bfb80', + '0xf90211a0395d87a95873cd98c21cf1df9421af03f7247880a2554e20738eec2c7507a494a0bcf6546339a1e7e14eb8fb572a968d217d2a0d1f3bc4257b22ef5333e9e4433ca012ae12498af8b2752c99efce07f3feef8ec910493be749acd63822c3558e6671a0dbf51303afdc36fc0c2d68a9bb05dab4f4917e7531e4a37ab0a153472d1b86e2a0ae90b50f067d9a2244e3d975233c0a0558c39ee152969f6678790abf773a9621a01d65cd682cc1be7c5e38d8da5c942e0a73eeaef10f387340a40a106699d494c3a06163b53d956c55544390c13634ea9aa75309f4fd866f312586942daf0f60fb37a058a52c1e858b1382a8893eb9c1f111f266eb9e21e6137aff0dddea243a567000a037b4b100761e02de63ea5f1fcfcf43e81a372dafb4419d126342136d329b7a7ba032472415864b08f808ba4374092003c8d7c40a9f7f9fe9cc8291f62538e1cc14a074e238ff5ec96b810364515551344100138916594d6af966170ff326a092fab0a0d31ac4eef14a79845200a496662e92186ca8b55e29ed0f9f59dbc6b521b116fea090607784fe738458b63c1942bba7c0321ae77e18df4961b2bc66727ea996464ea078f757653c1b63f72aff3dcc3f2a2e4c8cb4a9d36d1117c742833c84e20de994a0f78407de07f4b4cb4f899dfb95eedeb4049aeb5fc1635d65cf2f2f4dfd25d1d7a0862037513ba9d45354dd3e36264aceb2b862ac79d2050f14c95657e43a51b85c80', + '0xf90171a04ad705ea7bf04339fa36b124fa221379bd5a38ffe9a6112cb2d94be3a437b879a08e45b5f72e8149c01efcb71429841d6a8879d4bbe27335604a5bff8dfdf85dcea00313d9b2f7c03733d6549ea3b810e5262ed844ea12f70993d87d3e0f04e3979ea0b59e3cdd6750fa8b15164612a5cb6567cdfb386d4e0137fccee5f35ab55d0efda0fe6db56e42f2057a071c980a778d9a0b61038f269dd74a0e90155b3f40f14364a08538587f2378a0849f9608942cf481da4120c360f8391bbcc225d811823c6432a026eac94e755534e16f9552e73025d6d9c30d1d7682a4cb5bd7741ddabfd48c50a041557da9a74ca68da793e743e81e2029b2835e1cc16e9e25bd0c1e89d4ccad6980a041dda0a40a21ade3a20fcd1a4abb2a42b74e9a32b02424ff8db4ea708a5e0fb9a09aaf8326a51f613607a8685f57458329b41e938bb761131a5747e066b81a0a16808080a022e6cef138e16d2272ef58434ddf49260dc1de1f8ad6dfca3da5d2a92aaaadc58080', + '0xf851808080a009833150c367df138f1538689984b8a84fc55692d3d41fe4d1e5720ff5483a6980808080808080808080a0a319c1c415b271afc0adcb664e67738d103ac168e0bc0b7bd2da7966165cb9518080', + ], + balance: '0x0', + codeHash: '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470', + nonce: '0x0', + storageHash: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', + storageProof: [ + { + key: '0x0000000000000000000000000000000000000000000000000000000000000000', + value: '0', + proof: [], + }, + { + key: '0x0000000000000000000000000000000000000000000000000000000000000001', + value: '0', + proof: [], + }, + ], + }, + ], + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.PENDING, + { + accountProof: [ + '0xf90211a090dcaf88c40c7bbc95a912cbdde67c175767b31173df9ee4b0d733bfdd511c43a0babe369f6b12092f49181ae04ca173fb68d1a5456f18d20fa32cba73954052bda0473ecf8a7e36a829e75039a3b055e51b8332cbf03324ab4af2066bbd6fbf0021a0bbda34753d7aa6c38e603f360244e8f59611921d9e1f128372fec0d586d4f9e0a04e44caecff45c9891f74f6a2156735886eedf6f1a733628ebc802ec79d844648a0a5f3f2f7542148c973977c8a1e154c4300fec92f755f7846f1b734d3ab1d90e7a0e823850f50bf72baae9d1733a36a444ab65d0a6faaba404f0583ce0ca4dad92da0f7a00cbe7d4b30b11faea3ae61b7f1f2b315b61d9f6bd68bfe587ad0eeceb721a07117ef9fc932f1a88e908eaead8565c19b5645dc9e5b1b6e841c5edbdfd71681a069eb2de283f32c11f859d7bcf93da23990d3e662935ed4d6b39ce3673ec84472a0203d26456312bbc4da5cd293b75b840fc5045e493d6f904d180823ec22bfed8ea09287b5c21f2254af4e64fca76acc5cd87399c7f1ede818db4326c98ce2dc2208a06fc2d754e304c48ce6a517753c62b1a9c1d5925b89707486d7fc08919e0a94eca07b1c54f15e299bd58bdfef9741538c7828b5d7d11a489f9c20d052b3471df475a051f9dd3739a927c89e357580a4c97b40234aa01ed3d5e0390dc982a7975880a0a089d613f26159af43616fd9455bb461f4869bfede26f2130835ed067a8b967bfb80', + '0xf90211a0395d87a95873cd98c21cf1df9421af03f7247880a2554e20738eec2c7507a494a0bcf6546339a1e7e14eb8fb572a968d217d2a0d1f3bc4257b22ef5333e9e4433ca012ae12498af8b2752c99efce07f3feef8ec910493be749acd63822c3558e6671a0dbf51303afdc36fc0c2d68a9bb05dab4f4917e7531e4a37ab0a153472d1b86e2a0ae90b50f067d9a2244e3d975233c0a0558c39ee152969f6678790abf773a9621a01d65cd682cc1be7c5e38d8da5c942e0a73eeaef10f387340a40a106699d494c3a06163b53d956c55544390c13634ea9aa75309f4fd866f312586942daf0f60fb37a058a52c1e858b1382a8893eb9c1f111f266eb9e21e6137aff0dddea243a567000a037b4b100761e02de63ea5f1fcfcf43e81a372dafb4419d126342136d329b7a7ba032472415864b08f808ba4374092003c8d7c40a9f7f9fe9cc8291f62538e1cc14a074e238ff5ec96b810364515551344100138916594d6af966170ff326a092fab0a0d31ac4eef14a79845200a496662e92186ca8b55e29ed0f9f59dbc6b521b116fea090607784fe738458b63c1942bba7c0321ae77e18df4961b2bc66727ea996464ea078f757653c1b63f72aff3dcc3f2a2e4c8cb4a9d36d1117c742833c84e20de994a0f78407de07f4b4cb4f899dfb95eedeb4049aeb5fc1635d65cf2f2f4dfd25d1d7a0862037513ba9d45354dd3e36264aceb2b862ac79d2050f14c95657e43a51b85c80', + '0xf90171a04ad705ea7bf04339fa36b124fa221379bd5a38ffe9a6112cb2d94be3a437b879a08e45b5f72e8149c01efcb71429841d6a8879d4bbe27335604a5bff8dfdf85dcea00313d9b2f7c03733d6549ea3b810e5262ed844ea12f70993d87d3e0f04e3979ea0b59e3cdd6750fa8b15164612a5cb6567cdfb386d4e0137fccee5f35ab55d0efda0fe6db56e42f2057a071c980a778d9a0b61038f269dd74a0e90155b3f40f14364a08538587f2378a0849f9608942cf481da4120c360f8391bbcc225d811823c6432a026eac94e755534e16f9552e73025d6d9c30d1d7682a4cb5bd7741ddabfd48c50a041557da9a74ca68da793e743e81e2029b2835e1cc16e9e25bd0c1e89d4ccad6980a041dda0a40a21ade3a20fcd1a4abb2a42b74e9a32b02424ff8db4ea708a5e0fb9a09aaf8326a51f613607a8685f57458329b41e938bb761131a5747e066b81a0a16808080a022e6cef138e16d2272ef58434ddf49260dc1de1f8ad6dfca3da5d2a92aaaadc58080', + '0xf851808080a009833150c367df138f1538689984b8a84fc55692d3d41fe4d1e5720ff5483a6980808080808080808080a0a319c1c415b271afc0adcb664e67738d103ac168e0bc0b7bd2da7966165cb9518080', + ], + balance: '0x0', + codeHash: '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470', + nonce: '0x0', + storageHash: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', + storageProof: [ + { + key: '0x0000000000000000000000000000000000000000000000000000000000000000', + value: '0', + proof: [], + }, + { + key: '0x0000000000000000000000000000000000000000000000000000000000000001', + value: '0', + proof: [], + }, + ], + }, + ], +]; diff --git a/packages/web3-eth/test/fixtures/rpc_methods_wrappers.ts b/packages/web3-eth/test/fixtures/rpc_methods_wrappers.ts index ee1e22d10dc..4a60ffa9a6b 100644 --- a/packages/web3-eth/test/fixtures/rpc_methods_wrappers.ts +++ b/packages/web3-eth/test/fixtures/rpc_methods_wrappers.ts @@ -1,4 +1,5 @@ import { + AccountObject, Block, FeeHistoryResult, FilterResults, @@ -21,6 +22,7 @@ import { HexString8Bytes, } from 'web3-utils'; import { + AccountObjectFormatted, BlockFormatted, FeeHistoryResultFormatted, ReceiptInfoFormatted, @@ -2153,3 +2155,440 @@ export const submitWorkValidData: [ true, ], ]; + +const accountObject: AccountObject = { + accountProof: [ + '0xf90211a090dcaf88c40c7bbc95a912cbdde67c175767b31173df9ee4b0d733bfdd511c43a0babe369f6b12092f49181ae04ca173fb68d1a5456f18d20fa32cba73954052bda0473ecf8a7e36a829e75039a3b055e51b8332cbf03324ab4af2066bbd6fbf0021a0bbda34753d7aa6c38e603f360244e8f59611921d9e1f128372fec0d586d4f9e0a04e44caecff45c9891f74f6a2156735886eedf6f1a733628ebc802ec79d844648a0a5f3f2f7542148c973977c8a1e154c4300fec92f755f7846f1b734d3ab1d90e7a0e823850f50bf72baae9d1733a36a444ab65d0a6faaba404f0583ce0ca4dad92da0f7a00cbe7d4b30b11faea3ae61b7f1f2b315b61d9f6bd68bfe587ad0eeceb721a07117ef9fc932f1a88e908eaead8565c19b5645dc9e5b1b6e841c5edbdfd71681a069eb2de283f32c11f859d7bcf93da23990d3e662935ed4d6b39ce3673ec84472a0203d26456312bbc4da5cd293b75b840fc5045e493d6f904d180823ec22bfed8ea09287b5c21f2254af4e64fca76acc5cd87399c7f1ede818db4326c98ce2dc2208a06fc2d754e304c48ce6a517753c62b1a9c1d5925b89707486d7fc08919e0a94eca07b1c54f15e299bd58bdfef9741538c7828b5d7d11a489f9c20d052b3471df475a051f9dd3739a927c89e357580a4c97b40234aa01ed3d5e0390dc982a7975880a0a089d613f26159af43616fd9455bb461f4869bfede26f2130835ed067a8b967bfb80', + '0xf90211a0395d87a95873cd98c21cf1df9421af03f7247880a2554e20738eec2c7507a494a0bcf6546339a1e7e14eb8fb572a968d217d2a0d1f3bc4257b22ef5333e9e4433ca012ae12498af8b2752c99efce07f3feef8ec910493be749acd63822c3558e6671a0dbf51303afdc36fc0c2d68a9bb05dab4f4917e7531e4a37ab0a153472d1b86e2a0ae90b50f067d9a2244e3d975233c0a0558c39ee152969f6678790abf773a9621a01d65cd682cc1be7c5e38d8da5c942e0a73eeaef10f387340a40a106699d494c3a06163b53d956c55544390c13634ea9aa75309f4fd866f312586942daf0f60fb37a058a52c1e858b1382a8893eb9c1f111f266eb9e21e6137aff0dddea243a567000a037b4b100761e02de63ea5f1fcfcf43e81a372dafb4419d126342136d329b7a7ba032472415864b08f808ba4374092003c8d7c40a9f7f9fe9cc8291f62538e1cc14a074e238ff5ec96b810364515551344100138916594d6af966170ff326a092fab0a0d31ac4eef14a79845200a496662e92186ca8b55e29ed0f9f59dbc6b521b116fea090607784fe738458b63c1942bba7c0321ae77e18df4961b2bc66727ea996464ea078f757653c1b63f72aff3dcc3f2a2e4c8cb4a9d36d1117c742833c84e20de994a0f78407de07f4b4cb4f899dfb95eedeb4049aeb5fc1635d65cf2f2f4dfd25d1d7a0862037513ba9d45354dd3e36264aceb2b862ac79d2050f14c95657e43a51b85c80', + '0xf90171a04ad705ea7bf04339fa36b124fa221379bd5a38ffe9a6112cb2d94be3a437b879a08e45b5f72e8149c01efcb71429841d6a8879d4bbe27335604a5bff8dfdf85dcea00313d9b2f7c03733d6549ea3b810e5262ed844ea12f70993d87d3e0f04e3979ea0b59e3cdd6750fa8b15164612a5cb6567cdfb386d4e0137fccee5f35ab55d0efda0fe6db56e42f2057a071c980a778d9a0b61038f269dd74a0e90155b3f40f14364a08538587f2378a0849f9608942cf481da4120c360f8391bbcc225d811823c6432a026eac94e755534e16f9552e73025d6d9c30d1d7682a4cb5bd7741ddabfd48c50a041557da9a74ca68da793e743e81e2029b2835e1cc16e9e25bd0c1e89d4ccad6980a041dda0a40a21ade3a20fcd1a4abb2a42b74e9a32b02424ff8db4ea708a5e0fb9a09aaf8326a51f613607a8685f57458329b41e938bb761131a5747e066b81a0a16808080a022e6cef138e16d2272ef58434ddf49260dc1de1f8ad6dfca3da5d2a92aaaadc58080', + '0xf851808080a009833150c367df138f1538689984b8a84fc55692d3d41fe4d1e5720ff5483a6980808080808080808080a0a319c1c415b271afc0adcb664e67738d103ac168e0bc0b7bd2da7966165cb9518080', + ], + balance: '0x0', + codeHash: '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470', + nonce: '0x0', + storageHash: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', + storageProof: [ + { + key: '0x0000000000000000000000000000000000000000000000000000000000000000', + value: '0x0', + proof: [], + }, + { + key: '0x0000000000000000000000000000000000000000000000000000000000000001', + value: '0x0', + proof: [], + }, + ], +}; +const accountObjectNumberString: AccountObjectFormatted = { + accountProof: [ + '0xf90211a090dcaf88c40c7bbc95a912cbdde67c175767b31173df9ee4b0d733bfdd511c43a0babe369f6b12092f49181ae04ca173fb68d1a5456f18d20fa32cba73954052bda0473ecf8a7e36a829e75039a3b055e51b8332cbf03324ab4af2066bbd6fbf0021a0bbda34753d7aa6c38e603f360244e8f59611921d9e1f128372fec0d586d4f9e0a04e44caecff45c9891f74f6a2156735886eedf6f1a733628ebc802ec79d844648a0a5f3f2f7542148c973977c8a1e154c4300fec92f755f7846f1b734d3ab1d90e7a0e823850f50bf72baae9d1733a36a444ab65d0a6faaba404f0583ce0ca4dad92da0f7a00cbe7d4b30b11faea3ae61b7f1f2b315b61d9f6bd68bfe587ad0eeceb721a07117ef9fc932f1a88e908eaead8565c19b5645dc9e5b1b6e841c5edbdfd71681a069eb2de283f32c11f859d7bcf93da23990d3e662935ed4d6b39ce3673ec84472a0203d26456312bbc4da5cd293b75b840fc5045e493d6f904d180823ec22bfed8ea09287b5c21f2254af4e64fca76acc5cd87399c7f1ede818db4326c98ce2dc2208a06fc2d754e304c48ce6a517753c62b1a9c1d5925b89707486d7fc08919e0a94eca07b1c54f15e299bd58bdfef9741538c7828b5d7d11a489f9c20d052b3471df475a051f9dd3739a927c89e357580a4c97b40234aa01ed3d5e0390dc982a7975880a0a089d613f26159af43616fd9455bb461f4869bfede26f2130835ed067a8b967bfb80', + '0xf90211a0395d87a95873cd98c21cf1df9421af03f7247880a2554e20738eec2c7507a494a0bcf6546339a1e7e14eb8fb572a968d217d2a0d1f3bc4257b22ef5333e9e4433ca012ae12498af8b2752c99efce07f3feef8ec910493be749acd63822c3558e6671a0dbf51303afdc36fc0c2d68a9bb05dab4f4917e7531e4a37ab0a153472d1b86e2a0ae90b50f067d9a2244e3d975233c0a0558c39ee152969f6678790abf773a9621a01d65cd682cc1be7c5e38d8da5c942e0a73eeaef10f387340a40a106699d494c3a06163b53d956c55544390c13634ea9aa75309f4fd866f312586942daf0f60fb37a058a52c1e858b1382a8893eb9c1f111f266eb9e21e6137aff0dddea243a567000a037b4b100761e02de63ea5f1fcfcf43e81a372dafb4419d126342136d329b7a7ba032472415864b08f808ba4374092003c8d7c40a9f7f9fe9cc8291f62538e1cc14a074e238ff5ec96b810364515551344100138916594d6af966170ff326a092fab0a0d31ac4eef14a79845200a496662e92186ca8b55e29ed0f9f59dbc6b521b116fea090607784fe738458b63c1942bba7c0321ae77e18df4961b2bc66727ea996464ea078f757653c1b63f72aff3dcc3f2a2e4c8cb4a9d36d1117c742833c84e20de994a0f78407de07f4b4cb4f899dfb95eedeb4049aeb5fc1635d65cf2f2f4dfd25d1d7a0862037513ba9d45354dd3e36264aceb2b862ac79d2050f14c95657e43a51b85c80', + '0xf90171a04ad705ea7bf04339fa36b124fa221379bd5a38ffe9a6112cb2d94be3a437b879a08e45b5f72e8149c01efcb71429841d6a8879d4bbe27335604a5bff8dfdf85dcea00313d9b2f7c03733d6549ea3b810e5262ed844ea12f70993d87d3e0f04e3979ea0b59e3cdd6750fa8b15164612a5cb6567cdfb386d4e0137fccee5f35ab55d0efda0fe6db56e42f2057a071c980a778d9a0b61038f269dd74a0e90155b3f40f14364a08538587f2378a0849f9608942cf481da4120c360f8391bbcc225d811823c6432a026eac94e755534e16f9552e73025d6d9c30d1d7682a4cb5bd7741ddabfd48c50a041557da9a74ca68da793e743e81e2029b2835e1cc16e9e25bd0c1e89d4ccad6980a041dda0a40a21ade3a20fcd1a4abb2a42b74e9a32b02424ff8db4ea708a5e0fb9a09aaf8326a51f613607a8685f57458329b41e938bb761131a5747e066b81a0a16808080a022e6cef138e16d2272ef58434ddf49260dc1de1f8ad6dfca3da5d2a92aaaadc58080', + '0xf851808080a009833150c367df138f1538689984b8a84fc55692d3d41fe4d1e5720ff5483a6980808080808080808080a0a319c1c415b271afc0adcb664e67738d103ac168e0bc0b7bd2da7966165cb9518080', + ], + balance: '0', + codeHash: '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470', + nonce: '0', + storageHash: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', + storageProof: [ + { + key: '0x0000000000000000000000000000000000000000000000000000000000000000', + value: '0', + proof: [], + }, + { + key: '0x0000000000000000000000000000000000000000000000000000000000000001', + value: '0', + proof: [], + }, + ], +}; +const accountObjectNumber: AccountObjectFormatted = { + accountProof: [ + '0xf90211a090dcaf88c40c7bbc95a912cbdde67c175767b31173df9ee4b0d733bfdd511c43a0babe369f6b12092f49181ae04ca173fb68d1a5456f18d20fa32cba73954052bda0473ecf8a7e36a829e75039a3b055e51b8332cbf03324ab4af2066bbd6fbf0021a0bbda34753d7aa6c38e603f360244e8f59611921d9e1f128372fec0d586d4f9e0a04e44caecff45c9891f74f6a2156735886eedf6f1a733628ebc802ec79d844648a0a5f3f2f7542148c973977c8a1e154c4300fec92f755f7846f1b734d3ab1d90e7a0e823850f50bf72baae9d1733a36a444ab65d0a6faaba404f0583ce0ca4dad92da0f7a00cbe7d4b30b11faea3ae61b7f1f2b315b61d9f6bd68bfe587ad0eeceb721a07117ef9fc932f1a88e908eaead8565c19b5645dc9e5b1b6e841c5edbdfd71681a069eb2de283f32c11f859d7bcf93da23990d3e662935ed4d6b39ce3673ec84472a0203d26456312bbc4da5cd293b75b840fc5045e493d6f904d180823ec22bfed8ea09287b5c21f2254af4e64fca76acc5cd87399c7f1ede818db4326c98ce2dc2208a06fc2d754e304c48ce6a517753c62b1a9c1d5925b89707486d7fc08919e0a94eca07b1c54f15e299bd58bdfef9741538c7828b5d7d11a489f9c20d052b3471df475a051f9dd3739a927c89e357580a4c97b40234aa01ed3d5e0390dc982a7975880a0a089d613f26159af43616fd9455bb461f4869bfede26f2130835ed067a8b967bfb80', + '0xf90211a0395d87a95873cd98c21cf1df9421af03f7247880a2554e20738eec2c7507a494a0bcf6546339a1e7e14eb8fb572a968d217d2a0d1f3bc4257b22ef5333e9e4433ca012ae12498af8b2752c99efce07f3feef8ec910493be749acd63822c3558e6671a0dbf51303afdc36fc0c2d68a9bb05dab4f4917e7531e4a37ab0a153472d1b86e2a0ae90b50f067d9a2244e3d975233c0a0558c39ee152969f6678790abf773a9621a01d65cd682cc1be7c5e38d8da5c942e0a73eeaef10f387340a40a106699d494c3a06163b53d956c55544390c13634ea9aa75309f4fd866f312586942daf0f60fb37a058a52c1e858b1382a8893eb9c1f111f266eb9e21e6137aff0dddea243a567000a037b4b100761e02de63ea5f1fcfcf43e81a372dafb4419d126342136d329b7a7ba032472415864b08f808ba4374092003c8d7c40a9f7f9fe9cc8291f62538e1cc14a074e238ff5ec96b810364515551344100138916594d6af966170ff326a092fab0a0d31ac4eef14a79845200a496662e92186ca8b55e29ed0f9f59dbc6b521b116fea090607784fe738458b63c1942bba7c0321ae77e18df4961b2bc66727ea996464ea078f757653c1b63f72aff3dcc3f2a2e4c8cb4a9d36d1117c742833c84e20de994a0f78407de07f4b4cb4f899dfb95eedeb4049aeb5fc1635d65cf2f2f4dfd25d1d7a0862037513ba9d45354dd3e36264aceb2b862ac79d2050f14c95657e43a51b85c80', + '0xf90171a04ad705ea7bf04339fa36b124fa221379bd5a38ffe9a6112cb2d94be3a437b879a08e45b5f72e8149c01efcb71429841d6a8879d4bbe27335604a5bff8dfdf85dcea00313d9b2f7c03733d6549ea3b810e5262ed844ea12f70993d87d3e0f04e3979ea0b59e3cdd6750fa8b15164612a5cb6567cdfb386d4e0137fccee5f35ab55d0efda0fe6db56e42f2057a071c980a778d9a0b61038f269dd74a0e90155b3f40f14364a08538587f2378a0849f9608942cf481da4120c360f8391bbcc225d811823c6432a026eac94e755534e16f9552e73025d6d9c30d1d7682a4cb5bd7741ddabfd48c50a041557da9a74ca68da793e743e81e2029b2835e1cc16e9e25bd0c1e89d4ccad6980a041dda0a40a21ade3a20fcd1a4abb2a42b74e9a32b02424ff8db4ea708a5e0fb9a09aaf8326a51f613607a8685f57458329b41e938bb761131a5747e066b81a0a16808080a022e6cef138e16d2272ef58434ddf49260dc1de1f8ad6dfca3da5d2a92aaaadc58080', + '0xf851808080a009833150c367df138f1538689984b8a84fc55692d3d41fe4d1e5720ff5483a6980808080808080808080a0a319c1c415b271afc0adcb664e67738d103ac168e0bc0b7bd2da7966165cb9518080', + ], + balance: 0, + codeHash: '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470', + nonce: 0, + storageHash: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', + storageProof: [ + { + key: '0x0000000000000000000000000000000000000000000000000000000000000000', + value: 0, + proof: [], + }, + { + key: '0x0000000000000000000000000000000000000000000000000000000000000001', + value: 0, + proof: [], + }, + ], +}; +const accountObjectBigInt: AccountObjectFormatted = { + accountProof: [ + '0xf90211a090dcaf88c40c7bbc95a912cbdde67c175767b31173df9ee4b0d733bfdd511c43a0babe369f6b12092f49181ae04ca173fb68d1a5456f18d20fa32cba73954052bda0473ecf8a7e36a829e75039a3b055e51b8332cbf03324ab4af2066bbd6fbf0021a0bbda34753d7aa6c38e603f360244e8f59611921d9e1f128372fec0d586d4f9e0a04e44caecff45c9891f74f6a2156735886eedf6f1a733628ebc802ec79d844648a0a5f3f2f7542148c973977c8a1e154c4300fec92f755f7846f1b734d3ab1d90e7a0e823850f50bf72baae9d1733a36a444ab65d0a6faaba404f0583ce0ca4dad92da0f7a00cbe7d4b30b11faea3ae61b7f1f2b315b61d9f6bd68bfe587ad0eeceb721a07117ef9fc932f1a88e908eaead8565c19b5645dc9e5b1b6e841c5edbdfd71681a069eb2de283f32c11f859d7bcf93da23990d3e662935ed4d6b39ce3673ec84472a0203d26456312bbc4da5cd293b75b840fc5045e493d6f904d180823ec22bfed8ea09287b5c21f2254af4e64fca76acc5cd87399c7f1ede818db4326c98ce2dc2208a06fc2d754e304c48ce6a517753c62b1a9c1d5925b89707486d7fc08919e0a94eca07b1c54f15e299bd58bdfef9741538c7828b5d7d11a489f9c20d052b3471df475a051f9dd3739a927c89e357580a4c97b40234aa01ed3d5e0390dc982a7975880a0a089d613f26159af43616fd9455bb461f4869bfede26f2130835ed067a8b967bfb80', + '0xf90211a0395d87a95873cd98c21cf1df9421af03f7247880a2554e20738eec2c7507a494a0bcf6546339a1e7e14eb8fb572a968d217d2a0d1f3bc4257b22ef5333e9e4433ca012ae12498af8b2752c99efce07f3feef8ec910493be749acd63822c3558e6671a0dbf51303afdc36fc0c2d68a9bb05dab4f4917e7531e4a37ab0a153472d1b86e2a0ae90b50f067d9a2244e3d975233c0a0558c39ee152969f6678790abf773a9621a01d65cd682cc1be7c5e38d8da5c942e0a73eeaef10f387340a40a106699d494c3a06163b53d956c55544390c13634ea9aa75309f4fd866f312586942daf0f60fb37a058a52c1e858b1382a8893eb9c1f111f266eb9e21e6137aff0dddea243a567000a037b4b100761e02de63ea5f1fcfcf43e81a372dafb4419d126342136d329b7a7ba032472415864b08f808ba4374092003c8d7c40a9f7f9fe9cc8291f62538e1cc14a074e238ff5ec96b810364515551344100138916594d6af966170ff326a092fab0a0d31ac4eef14a79845200a496662e92186ca8b55e29ed0f9f59dbc6b521b116fea090607784fe738458b63c1942bba7c0321ae77e18df4961b2bc66727ea996464ea078f757653c1b63f72aff3dcc3f2a2e4c8cb4a9d36d1117c742833c84e20de994a0f78407de07f4b4cb4f899dfb95eedeb4049aeb5fc1635d65cf2f2f4dfd25d1d7a0862037513ba9d45354dd3e36264aceb2b862ac79d2050f14c95657e43a51b85c80', + '0xf90171a04ad705ea7bf04339fa36b124fa221379bd5a38ffe9a6112cb2d94be3a437b879a08e45b5f72e8149c01efcb71429841d6a8879d4bbe27335604a5bff8dfdf85dcea00313d9b2f7c03733d6549ea3b810e5262ed844ea12f70993d87d3e0f04e3979ea0b59e3cdd6750fa8b15164612a5cb6567cdfb386d4e0137fccee5f35ab55d0efda0fe6db56e42f2057a071c980a778d9a0b61038f269dd74a0e90155b3f40f14364a08538587f2378a0849f9608942cf481da4120c360f8391bbcc225d811823c6432a026eac94e755534e16f9552e73025d6d9c30d1d7682a4cb5bd7741ddabfd48c50a041557da9a74ca68da793e743e81e2029b2835e1cc16e9e25bd0c1e89d4ccad6980a041dda0a40a21ade3a20fcd1a4abb2a42b74e9a32b02424ff8db4ea708a5e0fb9a09aaf8326a51f613607a8685f57458329b41e938bb761131a5747e066b81a0a16808080a022e6cef138e16d2272ef58434ddf49260dc1de1f8ad6dfca3da5d2a92aaaadc58080', + '0xf851808080a009833150c367df138f1538689984b8a84fc55692d3d41fe4d1e5720ff5483a6980808080808080808080a0a319c1c415b271afc0adcb664e67738d103ac168e0bc0b7bd2da7966165cb9518080', + ], + balance: BigInt('0x0'), + codeHash: '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470', + nonce: BigInt('0x0'), + storageHash: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', + storageProof: [ + { + key: '0x0000000000000000000000000000000000000000000000000000000000000000', + value: BigInt('0x0'), + proof: [], + }, + { + key: '0x0000000000000000000000000000000000000000000000000000000000000001', + value: BigInt('0x0'), + proof: [], + }, + ], +}; +/** + * Array consists of: + * - array of inputs + * - mock RPC result + * - array of passed RPC parameters (excluding requestManager) - This is to account for any defaults set by the method + * - expected output + */ +export const getProofValidData: [ + [Address, HexString32Bytes, BlockNumberOrTag | undefined, ValidTypes | undefined], + AccountObject, + [Address, HexString32Bytes, BlockNumberOrTag], + ( + | AccountObject + | AccountObjectFormatted + | AccountObjectFormatted + | AccountObjectFormatted + ), +][] = [ + // All possible undefined values + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + undefined, + undefined, + ], + accountObject, + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.LATEST, + ], + accountObject, + ], + // Defined block number, undefined returnType + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + '0x1', + undefined, + ], + accountObject, + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + '0x1', + ], + accountObject, + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.EARLIEST, + undefined, + ], + accountObject, + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.EARLIEST, + ], + accountObject, + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.LATEST, + undefined, + ], + accountObject, + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.LATEST, + ], + accountObject, + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.PENDING, + undefined, + ], + accountObject, + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.PENDING, + ], + accountObject, + ], + // Defined block number, returnType = ValidTypes.HexString + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + '0x1', + ValidTypes.HexString, + ], + accountObject, + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + '0x1', + ], + accountObject, + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.EARLIEST, + ValidTypes.HexString, + ], + accountObject, + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.EARLIEST, + ], + accountObject, + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.LATEST, + ValidTypes.HexString, + ], + accountObject, + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.LATEST, + ], + accountObject, + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.PENDING, + ValidTypes.HexString, + ], + accountObject, + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.PENDING, + ], + accountObject, + ], + // Defined block number, returnType = ValidTypes.NumberString + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + '0x1', + ValidTypes.NumberString, + ], + accountObject, + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + '0x1', + ], + accountObjectNumberString, + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.EARLIEST, + ValidTypes.NumberString, + ], + accountObject, + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.EARLIEST, + ], + accountObjectNumberString, + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.LATEST, + ValidTypes.NumberString, + ], + accountObject, + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.LATEST, + ], + accountObjectNumberString, + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.PENDING, + ValidTypes.NumberString, + ], + accountObject, + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.PENDING, + ], + accountObjectNumberString, + ], + // Defined block number, returnType = ValidTypes.Number + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + '0x1', + ValidTypes.Number, + ], + accountObject, + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + '0x1', + ], + accountObjectNumber, + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.EARLIEST, + ValidTypes.Number, + ], + accountObject, + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.EARLIEST, + ], + accountObjectNumber, + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.LATEST, + ValidTypes.Number, + ], + accountObject, + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.LATEST, + ], + accountObjectNumber, + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.PENDING, + ValidTypes.Number, + ], + accountObject, + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.PENDING, + ], + accountObjectNumber, + ], + // Defined block number, returnType = ValidTypes.BigInt + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + '0x1', + ValidTypes.BigInt, + ], + accountObject, + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + '0x1', + ], + accountObjectBigInt, + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.EARLIEST, + ValidTypes.BigInt, + ], + accountObject, + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.EARLIEST, + ], + accountObjectBigInt, + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.LATEST, + ValidTypes.BigInt, + ], + accountObject, + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.LATEST, + ], + accountObjectBigInt, + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.PENDING, + ValidTypes.BigInt, + ], + accountObject, + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.PENDING, + ], + accountObjectBigInt, + ], +]; diff --git a/packages/web3-eth/test/fixtures/web3_eth_methods_with_parameters.ts b/packages/web3-eth/test/fixtures/web3_eth_methods_with_parameters.ts index fac341a1908..df3614b3697 100644 --- a/packages/web3-eth/test/fixtures/web3_eth_methods_with_parameters.ts +++ b/packages/web3-eth/test/fixtures/web3_eth_methods_with_parameters.ts @@ -1219,3 +1219,314 @@ export const submitWorkValidData: [[HexString8Bytes, HexString32Bytes, HexString ], ], ]; + +/** + * Array consists of: + * - array of inputs + * - array of passed RPC parameters (excluding Web3Context) - This is to account for any defaults set by the method + */ +export const getProofValidData: [ + [Address, HexString32Bytes, BlockNumberOrTag | undefined, ValidTypes | undefined], + [Address, HexString32Bytes, BlockNumberOrTag, ValidTypes | undefined], +][] = [ + // All possible undefined values + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + undefined, + undefined, + ], + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.LATEST, + undefined, + ], + ], + // Defined block number, undefined returnType + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + '0x1', + undefined, + ], + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + '0x1', + undefined, + ], + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.EARLIEST, + undefined, + ], + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.EARLIEST, + undefined, + ], + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.LATEST, + undefined, + ], + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.LATEST, + undefined, + ], + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.PENDING, + undefined, + ], + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.PENDING, + undefined, + ], + ], + // Defined block number, returnType = ValidTypes.HexString + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + '0x1', + ValidTypes.HexString, + ], + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + '0x1', + ValidTypes.HexString, + ], + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.EARLIEST, + ValidTypes.HexString, + ], + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.EARLIEST, + ValidTypes.HexString, + ], + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.LATEST, + ValidTypes.HexString, + ], + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.LATEST, + ValidTypes.HexString, + ], + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.PENDING, + ValidTypes.HexString, + ], + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.PENDING, + ValidTypes.HexString, + ], + ], + // Defined block number, returnType = ValidTypes.NumberString + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + '0x1', + ValidTypes.NumberString, + ], + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + '0x1', + ValidTypes.NumberString, + ], + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.EARLIEST, + ValidTypes.NumberString, + ], + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.EARLIEST, + ValidTypes.NumberString, + ], + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.LATEST, + ValidTypes.NumberString, + ], + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.LATEST, + ValidTypes.NumberString, + ], + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.PENDING, + ValidTypes.NumberString, + ], + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.PENDING, + ValidTypes.NumberString, + ], + ], + // Defined block number, returnType = ValidTypes.Number + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + '0x1', + ValidTypes.Number, + ], + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + '0x1', + ValidTypes.Number, + ], + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.EARLIEST, + ValidTypes.Number, + ], + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.EARLIEST, + ValidTypes.Number, + ], + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.LATEST, + ValidTypes.Number, + ], + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.LATEST, + ValidTypes.Number, + ], + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.PENDING, + ValidTypes.Number, + ], + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.PENDING, + ValidTypes.Number, + ], + ], + // Defined block number, returnType = ValidTypes.BigInt + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + '0x1', + ValidTypes.BigInt, + ], + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + '0x1', + ValidTypes.BigInt, + ], + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.EARLIEST, + ValidTypes.BigInt, + ], + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.EARLIEST, + ValidTypes.BigInt, + ], + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.LATEST, + ValidTypes.BigInt, + ], + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.LATEST, + ValidTypes.BigInt, + ], + ], + [ + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.PENDING, + ValidTypes.BigInt, + ], + [ + '0x1234567890123456789012345678901234567890', + '0x295a70b2de5e3953354a6a8344e616ed314d7251', + BlockTags.PENDING, + ValidTypes.BigInt, + ], + ], +]; diff --git a/packages/web3-eth/test/unit/rpc_methods_with_parameters.test.ts b/packages/web3-eth/test/unit/rpc_methods_with_parameters.test.ts index 502e802dc9d..4ea522daaf2 100644 --- a/packages/web3-eth/test/unit/rpc_methods_with_parameters.test.ts +++ b/packages/web3-eth/test/unit/rpc_methods_with_parameters.test.ts @@ -16,6 +16,7 @@ import { getFilterChanges, getFilterLogs, getLogs, + getProof, getStorageAt, getTransactionByBlockHashAndIndex, getTransactionByBlockNumberAndIndex, @@ -51,6 +52,7 @@ import { getFilterChangesValidData, getFilterLogsValidData, getLogsValidData, + getProofValidData, getStorageAtValidData, getTransactionByBlockHashAndIndexValidData, getTransactionByBlockNumberAndIndexValidData, @@ -416,4 +418,14 @@ describe('rpc_methods_with_parameters', () => { }, ); }); + + describe('getProof', () => { + it.each(getProofValidData)('%s', async (address, storageKey, blockNumberOrTag) => { + await getProof(requestManager, address, storageKey, blockNumberOrTag); + expect(requestManagerSendSpy).toHaveBeenCalledWith({ + method: 'eth_getProof', + params: [address, storageKey, blockNumberOrTag], + }); + }); + }); }); diff --git a/packages/web3-eth/test/unit/web3_eth_methods_with_parameters.test.ts b/packages/web3-eth/test/unit/web3_eth_methods_with_parameters.test.ts index 4370dec0715..60911333ee9 100644 --- a/packages/web3-eth/test/unit/web3_eth_methods_with_parameters.test.ts +++ b/packages/web3-eth/test/unit/web3_eth_methods_with_parameters.test.ts @@ -15,6 +15,7 @@ import { getGasPriceValidData, getHashRateValidData, getPastLogsValidData, + getProofValidData, getStorageAtValidData, getTransactionCountValidData, getTransactionFromBlockValidData, @@ -207,6 +208,19 @@ describe('web3_eth_methods_with_parameters', () => { }, ); }); + + describe('getProof', () => { + it.each(getProofValidData)( + 'input: %s\nrpcMethodParameters: %s', + async (input, rpcMethodParameters) => { + await web3Eth.getProof(...input); + expect(rpcMethodWrappers.getProof).toHaveBeenCalledWith( + web3Eth, + ...rpcMethodParameters, + ); + }, + ); + }); }); describe("doesn't have returnType parameter", () => { diff --git a/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts b/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts index 7498f605850..5fb823afd70 100644 --- a/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts +++ b/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts @@ -12,6 +12,7 @@ import { getFeeHistory, getGasPrice, getHashRate, + getProof, getTransaction, getTransactionCount, getTransactionFromBlock, @@ -28,6 +29,7 @@ import { getFeeHistoryValidData, getGasPriceValidData, getHashRateValidData, + getProofValidData, getTransactionCountValidData, getTransactionFromBlockValidData, getTransactionReceiptValidData, @@ -305,6 +307,22 @@ describe('web3_eth_methods_with_parameters', () => { }, ); }); + + describe('getProof', () => { + it.each(getProofValidData)( + 'input: %s\nmockRpcResponse: %s\nrpcMethodParameters: %s\noutput: %s', + async (input, mockRpcResponse, rpcMethodParameters, output) => { + (rpcMethods.getProof as jest.Mock).mockResolvedValueOnce( + mockRpcResponse, + ); + expect(await getProof(web3Eth, ...input)).toStrictEqual(output); + expect(rpcMethods.getProof).toHaveBeenCalledWith( + web3Eth.requestManager, + ...rpcMethodParameters, + ); + }, + ); + }); }); }); }); From 499c39a5c17ca9949dec0b1ef45c833ffbb0a967 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 14 Feb 2022 23:10:59 -1000 Subject: [PATCH 104/132] Init Web3EthExecutionAPI --- packages/web3-common/src/eth_execution_api.ts | 29 --------------- packages/web3-eth/src/index.ts | 5 +-- packages/web3-eth/src/rpc_method_wrappers.ts | 3 +- packages/web3-eth/src/rpc_methods.ts | 11 +++--- .../web3-eth/src/web3_eth_execution_api.ts | 36 +++++++++++++++++++ 5 files changed, 48 insertions(+), 36 deletions(-) create mode 100644 packages/web3-eth/src/web3_eth_execution_api.ts diff --git a/packages/web3-common/src/eth_execution_api.ts b/packages/web3-common/src/eth_execution_api.ts index d986355ab8a..795bdb5b546 100644 --- a/packages/web3-common/src/eth_execution_api.ts +++ b/packages/web3-common/src/eth_execution_api.ts @@ -188,21 +188,6 @@ export interface CompileResult { }; } -export interface StorageProof { - readonly key: HexString32Bytes; - readonly value: Uint; - readonly proof: HexString32Bytes[]; -} - -export interface AccountObject { - readonly balance: Uint; - readonly codeHash: HexString32Bytes; - readonly nonce: Uint; - readonly storageHash: HexString32Bytes; - readonly accountProof: HexString32Bytes[]; - readonly storageProof: StorageProof[]; -} - /* eslint-disable camelcase */ export type EthExecutionAPI = { // https://github.com/ethereum/execution-apis/blob/main/src/eth/block.json @@ -302,18 +287,4 @@ export type EthExecutionAPI = { eth_compileSolidity: (code: string) => CompileResult; eth_compileLLL: (code: string) => HexStringBytes; eth_compileSerpent: (code: string) => HexStringBytes; - eth_pendingTransactions: () => TransactionInfo[]; - - // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1102.md - eth_requestAccounts: () => Address[]; - - // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-695.md - eth_chainId: () => Uint; - - // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1186.md - eth_getProof: ( - address: Address, - storageKey: HexString32Bytes, - blockNumber: BlockNumberOrTag, - ) => AccountObject; }; diff --git a/packages/web3-eth/src/index.ts b/packages/web3-eth/src/index.ts index 335cff1f4a8..990d7e018bc 100644 --- a/packages/web3-eth/src/index.ts +++ b/packages/web3-eth/src/index.ts @@ -1,7 +1,7 @@ // Disabling because returnTypes must be last param to match 1.x params /* eslint-disable default-param-last */ -import { EthExecutionAPI, TransactionWithSender } from 'web3-common'; +import { TransactionWithSender } from 'web3-common'; import { Web3Context } from 'web3-core'; import { BlockNumberOrTag, @@ -18,8 +18,9 @@ import { import { BlockFormatted } from './types'; import * as rpcMethods from './rpc_methods'; import * as rpcMethodsWrappers from './rpc_method_wrappers'; +import { Web3EthExecutionAPI } from './web3_eth_execution_api'; -export default class Web3Eth extends Web3Context { +export default class Web3Eth extends Web3Context { public async getProtocolVersion() { return rpcMethods.getProtocolVersion(this.requestManager); } diff --git a/packages/web3-eth/src/rpc_method_wrappers.ts b/packages/web3-eth/src/rpc_method_wrappers.ts index 4da137658ab..6cbe3ded39f 100644 --- a/packages/web3-eth/src/rpc_method_wrappers.ts +++ b/packages/web3-eth/src/rpc_method_wrappers.ts @@ -23,6 +23,7 @@ import { import * as rpcMethods from './rpc_methods'; import { BlockFormatted } from './types'; +import { Web3EthExecutionAPI } from './web3_eth_execution_api'; export async function getHashRate( web3Context: Web3Context, @@ -300,7 +301,7 @@ export async function getFeeHistory( - web3Context: Web3Context, + web3Context: Web3Context, address: Address, storageKey: HexString32Bytes, blockNumber: BlockNumberOrTag = web3Context.defaultBlock, diff --git a/packages/web3-eth/src/rpc_methods.ts b/packages/web3-eth/src/rpc_methods.ts index 252d43783be..4e5aa4f2ff3 100644 --- a/packages/web3-eth/src/rpc_methods.ts +++ b/packages/web3-eth/src/rpc_methods.ts @@ -12,6 +12,7 @@ import { } from 'web3-utils'; import { validator } from 'web3-validator'; import { validateTransactionCall, validateTransactionWithSender } from './validation'; +import { Web3EthExecutionAPI } from './web3_eth_execution_api'; export async function getProtocolVersion(requestManager: Web3RequestManager) { return requestManager.send({ @@ -494,21 +495,23 @@ export async function getFeeHistory( }); } -export async function getPendingTransactions(requestManager: Web3RequestManager) { +export async function getPendingTransactions( + requestManager: Web3RequestManager, +) { return requestManager.send({ method: 'eth_pendingTransactions', params: [], }); } -export async function requestAccounts(requestManager: Web3RequestManager) { +export async function requestAccounts(requestManager: Web3RequestManager) { return requestManager.send({ method: 'eth_requestAccounts', params: [], }); } -export async function getChainId(requestManager: Web3RequestManager) { +export async function getChainId(requestManager: Web3RequestManager) { return requestManager.send({ method: 'eth_chainId', params: [], @@ -516,7 +519,7 @@ export async function getChainId(requestManager: Web3RequestManager) { } export async function getProof( - requestManager: Web3RequestManager, + requestManager: Web3RequestManager, address: Address, storageKey: HexString32Bytes, blockNumber: BlockNumberOrTag, diff --git a/packages/web3-eth/src/web3_eth_execution_api.ts b/packages/web3-eth/src/web3_eth_execution_api.ts new file mode 100644 index 00000000000..26cf6c67ad7 --- /dev/null +++ b/packages/web3-eth/src/web3_eth_execution_api.ts @@ -0,0 +1,36 @@ +import { EthExecutionAPI, TransactionInfo } from 'web3-common'; +import { Address, BlockNumberOrTag, HexString32Bytes, Uint } from 'web3-utils'; + +export interface StorageProof { + readonly key: HexString32Bytes; + readonly value: Uint; + readonly proof: HexString32Bytes[]; +} + +export interface AccountObject { + readonly balance: Uint; + readonly codeHash: HexString32Bytes; + readonly nonce: Uint; + readonly storageHash: HexString32Bytes; + readonly accountProof: HexString32Bytes[]; + readonly storageProof: StorageProof[]; +} + +export type Web3EthExecutionAPI = EthExecutionAPI & { + eth_pendingTransactions: () => TransactionInfo[]; + + // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1102.md + eth_requestAccounts: () => Address[]; + + // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-695.md + eth_chainId: () => Uint; + + web3_clientVersion: () => string; + + // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1186.md + eth_getProof: ( + address: Address, + storageKey: HexString32Bytes, + blockNumber: BlockNumberOrTag, + ) => AccountObject; +}; From c35ed3bd3d1c7aa01f52edc3ab5f36b2720eb692 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Fri, 18 Feb 2022 15:11:04 -1000 Subject: [PATCH 105/132] Fix imports for AccountObject in fixtures --- packages/web3-eth/test/fixtures/rpc_methods_with_params.ts | 4 +++- packages/web3-eth/test/fixtures/rpc_methods_wrappers.ts | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/web3-eth/test/fixtures/rpc_methods_with_params.ts b/packages/web3-eth/test/fixtures/rpc_methods_with_params.ts index 42ae27d32bb..1ff4ce9eea0 100644 --- a/packages/web3-eth/test/fixtures/rpc_methods_with_params.ts +++ b/packages/web3-eth/test/fixtures/rpc_methods_with_params.ts @@ -1,4 +1,4 @@ -import { AccountObject, TransactionCall, TransactionWithSender } from 'web3-common'; +import { TransactionCall, TransactionWithSender } from 'web3-common'; import { Address, BlockNumberOrTag, @@ -10,6 +10,8 @@ import { Uint256, } from 'web3-utils'; +import { AccountObject } from '../../src/web3_eth_execution_api'; + import { isTransactionCallValidData, isTransactionWithSenderValidData } from './validation'; export const getBalanceValidData: [Address, BlockNumberOrTag][] = [ diff --git a/packages/web3-eth/test/fixtures/rpc_methods_wrappers.ts b/packages/web3-eth/test/fixtures/rpc_methods_wrappers.ts index 4a60ffa9a6b..727317a1277 100644 --- a/packages/web3-eth/test/fixtures/rpc_methods_wrappers.ts +++ b/packages/web3-eth/test/fixtures/rpc_methods_wrappers.ts @@ -1,5 +1,4 @@ import { - AccountObject, Block, FeeHistoryResult, FilterResults, @@ -21,6 +20,7 @@ import { Filter, HexString8Bytes, } from 'web3-utils'; + import { AccountObjectFormatted, BlockFormatted, @@ -28,6 +28,7 @@ import { ReceiptInfoFormatted, TransactionInfoFormatted, } from '../../src/types'; +import { AccountObject } from '../../src/web3_eth_execution_api'; // Array consists of: returnType parameter, mock RPC result, expected output export const getHashRateValidData: [ From a99208f0ab09e5fdc83f4c9f75520bc6e07da16c Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Fri, 18 Feb 2022 18:23:00 -1000 Subject: [PATCH 106/132] Add formatting to getPendingTransactions. Move formatTransaction to seperate file --- packages/web3-eth/src/eth_tx.ts | 69 +----------------- packages/web3-eth/src/format_transaction.ts | 70 +++++++++++++++++++ packages/web3-eth/src/index.ts | 7 +- packages/web3-eth/src/rpc_method_wrappers.ts | 11 +++ packages/web3-eth/src/types.ts | 2 +- .../test/fixtures/rpc_methods_wrappers.ts | 37 ++++++++++ .../test/unit/format_transaction.test.ts | 2 +- .../web3_eth_methods_no_parameters.test.ts | 2 + ...pc_method_wrappers_with_parameters.test.ts | 17 +++++ 9 files changed, 144 insertions(+), 73 deletions(-) create mode 100644 packages/web3-eth/src/format_transaction.ts diff --git a/packages/web3-eth/src/eth_tx.ts b/packages/web3-eth/src/eth_tx.ts index 0f760190830..b2be4ec0068 100644 --- a/packages/web3-eth/src/eth_tx.ts +++ b/packages/web3-eth/src/eth_tx.ts @@ -4,7 +4,6 @@ import { BlockTags, convertToValidType, HexString, - Numbers, toNumber, ValidReturnTypes, ValidTypes, @@ -31,73 +30,7 @@ import { } from './types'; import { getBlock, getGasPrice, getTransactionCount } from './rpc_method_wrappers'; import { validateChainInfo, validateCustomChainInfo, validateGas } from './validation'; - -export function formatTransaction< - DesiredType extends ValidTypes, - NumberType extends ValidReturnTypes[DesiredType] = ValidReturnTypes[DesiredType], ->(transaction: Transaction, desiredType: DesiredType): Transaction { - // TODO - The spread operator performs a shallow copy of transaction. - // I tried using Object.assign({}, transaction) which is supposed to perform a deep copy, - // but format_transactions.test.ts were still failing due to original nested object properties - // being wrongfully updated by this method. - const formattedTransaction = { ...transaction }; - if (transaction.common !== undefined) { - formattedTransaction.common = { ...transaction.common }; - if (transaction.common.customChain !== undefined) - formattedTransaction.common.customChain = { ...transaction.common.customChain }; - } - - const formattableProperties: (keyof Transaction)[] = [ - 'value', - 'gas', - 'gasPrice', - 'type', - 'maxFeePerGas', - 'maxPriorityFeePerGas', - 'nonce', - 'chainId', - 'gasLimit', - 'v', - ]; - for (const transactionProperty of formattableProperties) { - const formattedProperty = formattedTransaction[transactionProperty]; - if ( - formattedProperty !== undefined && - formattedProperty !== null && - typeof formattedProperty !== 'object' && - !Array.isArray(formattedProperty) - ) { - if (transactionProperty === 'value' && formattedProperty === '0x') continue; - (formattedTransaction[transactionProperty] as Numbers) = convertToValidType( - formattedProperty, - desiredType, - ); - } - } - - if (formattedTransaction.common?.customChain?.networkId !== undefined) - formattedTransaction.common.customChain.networkId = convertToValidType( - formattedTransaction.common.customChain.networkId, - desiredType, - ); - if (formattedTransaction.common?.customChain?.chainId !== undefined) - formattedTransaction.common.customChain.chainId = convertToValidType( - formattedTransaction.common.customChain.chainId, - desiredType, - ); - - if (formattedTransaction.data !== undefined && formattedTransaction.input !== undefined) - throw new TransactionDataAndInputError({ - data: formattedTransaction.data, - input: formattedTransaction.input, - }); - else if (formattedTransaction.input !== undefined) { - formattedTransaction.data = formattedTransaction.input; - delete formattedTransaction.input; - } - - return formattedTransaction as Transaction; -} +import { formatTransaction } from './format_transaction'; export const detectTransactionType = ( transaction: Transaction, diff --git a/packages/web3-eth/src/format_transaction.ts b/packages/web3-eth/src/format_transaction.ts new file mode 100644 index 00000000000..8dae27e09b3 --- /dev/null +++ b/packages/web3-eth/src/format_transaction.ts @@ -0,0 +1,70 @@ +import { convertToValidType, Numbers, ValidReturnTypes, ValidTypes } from 'web3-utils'; +import { TransactionDataAndInputError } from './errors'; +import { Transaction } from './types'; + +export function formatTransaction< + DesiredType extends ValidTypes, + NumberType extends ValidReturnTypes[DesiredType] = ValidReturnTypes[DesiredType], +>(transaction: Transaction, desiredType: DesiredType): Transaction { + // TODO - The spread operator performs a shallow copy of transaction. + // I tried using Object.assign({}, transaction) which is supposed to perform a deep copy, + // but format_transactions.test.ts were still failing due to original nested object properties + // being wrongfully updated by this method. + const formattedTransaction = { ...transaction }; + if (transaction.common !== undefined) { + formattedTransaction.common = { ...transaction.common }; + if (transaction.common.customChain !== undefined) + formattedTransaction.common.customChain = { ...transaction.common.customChain }; + } + + const formattableProperties: (keyof Transaction)[] = [ + 'value', + 'gas', + 'gasPrice', + 'type', + 'maxFeePerGas', + 'maxPriorityFeePerGas', + 'nonce', + 'chainId', + 'gasLimit', + 'v', + ]; + for (const transactionProperty of formattableProperties) { + const formattedProperty = formattedTransaction[transactionProperty]; + if ( + formattedProperty !== undefined && + formattedProperty !== null && + typeof formattedProperty !== 'object' && + !Array.isArray(formattedProperty) + ) { + if (transactionProperty === 'value' && formattedProperty === '0x') continue; + (formattedTransaction[transactionProperty] as Numbers) = convertToValidType( + formattedProperty, + desiredType, + ); + } + } + + if (formattedTransaction.common?.customChain?.networkId !== undefined) + formattedTransaction.common.customChain.networkId = convertToValidType( + formattedTransaction.common.customChain.networkId, + desiredType, + ); + if (formattedTransaction.common?.customChain?.chainId !== undefined) + formattedTransaction.common.customChain.chainId = convertToValidType( + formattedTransaction.common.customChain.chainId, + desiredType, + ); + + if (formattedTransaction.data !== undefined && formattedTransaction.input !== undefined) + throw new TransactionDataAndInputError({ + data: formattedTransaction.data, + input: formattedTransaction.input, + }); + else if (formattedTransaction.input !== undefined) { + formattedTransaction.data = formattedTransaction.input; + delete formattedTransaction.input; + } + + return formattedTransaction as Transaction; +} diff --git a/packages/web3-eth/src/index.ts b/packages/web3-eth/src/index.ts index 990d7e018bc..bd21d5112ee 100644 --- a/packages/web3-eth/src/index.ts +++ b/packages/web3-eth/src/index.ts @@ -116,9 +116,10 @@ export default class Web3Eth extends Web3Context { return rpcMethodsWrappers.getTransaction(this, transactionHash, returnType); } - // TODO Format transactions - public async getPendingTransactions() { - return rpcMethods.getPendingTransactions(this.requestManager); + public async getPendingTransactions( + returnType?: ReturnType, + ) { + return rpcMethodsWrappers.getPendingTransactions(this, returnType); } public async getTransactionFromBlock( diff --git a/packages/web3-eth/src/rpc_method_wrappers.ts b/packages/web3-eth/src/rpc_method_wrappers.ts index 723e5c0b399..45fa09aa0b7 100644 --- a/packages/web3-eth/src/rpc_method_wrappers.ts +++ b/packages/web3-eth/src/rpc_method_wrappers.ts @@ -22,6 +22,7 @@ import { convertibleReceiptInfoProperties, convertibleTransactionInfoProperties, } from './convertible_properties'; +import { formatTransaction } from './format_transaction'; import * as rpcMethods from './rpc_methods'; import { BlockFormatted } from './types'; @@ -268,6 +269,16 @@ export async function getTransactionCount( + web3Context: Web3Context, + returnType?: ReturnType, +) { + const response = await rpcMethods.getPendingTransactions(web3Context.requestManager); + return response.map(transaction => + formatTransaction(transaction, returnType ?? web3Context.defaultReturnType), + ); +} + // TODO Needs to convert input to hex string // public async sendTransaction(transaction: Transaction) { // return rpcMethods.sendTransaction(this.web3Context.requestManager, transaction); diff --git a/packages/web3-eth/src/types.ts b/packages/web3-eth/src/types.ts index e66f0aaf62d..3537b6c945f 100644 --- a/packages/web3-eth/src/types.ts +++ b/packages/web3-eth/src/types.ts @@ -43,7 +43,7 @@ export interface Common { export interface Transaction { from?: Address; - to?: Address; + to?: Address | null; value?: NumberType; gas?: NumberType; gasPrice?: NumberType; diff --git a/packages/web3-eth/test/fixtures/rpc_methods_wrappers.ts b/packages/web3-eth/test/fixtures/rpc_methods_wrappers.ts index 727317a1277..67a61ad9b19 100644 --- a/packages/web3-eth/test/fixtures/rpc_methods_wrappers.ts +++ b/packages/web3-eth/test/fixtures/rpc_methods_wrappers.ts @@ -1573,6 +1573,43 @@ export const getTransactionCountValidData: [ ], ]; +// export const getPendingTransactionValidData: [ +// ValidTypes | undefined, +// TransactionInfo[], +// ( +// | TransactionInfoFormatted +// | TransactionInfoFormatted +// | TransactionInfoFormatted +// | TransactionInfoFormatted +// )[], +// ][] = [ +// [ +// undefined, +// [transactionInfo, transactionInfo, transactionInfo], +// [transactionInfo, transactionInfo, transactionInfo], +// ], +// [ +// ValidTypes.HexString, +// [transactionInfo, transactionInfo, transactionInfo], +// [transactionInfo, transactionInfo, transactionInfo], +// ], +// [ +// ValidTypes.Number, +// [transactionInfo, transactionInfo, transactionInfo], +// [transactionInfoNumber, transactionInfoNumber, transactionInfoNumber], +// ], +// [ +// ValidTypes.NumberString, +// [transactionInfo, transactionInfo, transactionInfo], +// [transactionInfoNumberString, transactionInfoNumberString, transactionInfoNumberString], +// ], +// [ +// ValidTypes.BigInt, +// [transactionInfo, transactionInfo, transactionInfo], +// [transactionInfoBigInt, transactionInfoBigInt, transactionInfoBigInt], +// ], +// ]; + export const transactionWithSender: TransactionWithSender = { to: '0x407d73d8a49eeb85d32cf465507dd71d507100c1', type: '0x0', diff --git a/packages/web3-eth/test/unit/format_transaction.test.ts b/packages/web3-eth/test/unit/format_transaction.test.ts index e27c0a3d45f..792836d7037 100644 --- a/packages/web3-eth/test/unit/format_transaction.test.ts +++ b/packages/web3-eth/test/unit/format_transaction.test.ts @@ -1,5 +1,5 @@ import { ValidTypes } from 'web3-utils'; -import { formatTransaction } from '../../src/eth_tx'; +import { formatTransaction } from '../../src/format_transaction'; import { bigIntTransaction, hexStringTransaction, diff --git a/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts b/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts index 01b4f2d284b..b3df4133907 100644 --- a/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts +++ b/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts @@ -42,6 +42,8 @@ describe('web3_eth_methods_no_parameters', () => { }); it('getPendingTransactions', async () => { + (rpcMethods.getPendingTransactions as jest.Mock).mockResolvedValueOnce([]); + await web3Eth.getPendingTransactions(); expect(rpcMethods.getPendingTransactions).toHaveBeenCalledWith(web3Eth.requestManager); }); diff --git a/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts b/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts index 8a3d7442b7c..c8247f7549b 100644 --- a/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts +++ b/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts @@ -92,6 +92,23 @@ describe('web3_eth_methods_with_parameters', () => { }, ); }); + + // TODO - formatTransaction uses transaction.data, but current + // transaction typing only specifies transaction.input + // describe('getPendingTransactions', () => { + // it.each(getPendingTransactionValidData)( + // 'returnType: %s mockRpcResponse: %s output: %s', + // async (returnType, mockRpcResponse, output) => { + // (rpcMethods.getPendingTransactions as jest.Mock).mockResolvedValueOnce( + // mockRpcResponse, + // ); + // expect(await getPendingTransactions(web3Eth, returnType)).toBe(output); + // expect(rpcMethods.getPendingTransactions).toHaveBeenCalledWith( + // web3Eth.requestManager, + // ); + // }, + // ); + // }); }); describe('has multiple parameters', () => { From d6ac3a645e79d063d0ba7765b0ef9800ddbf2a8f Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Sun, 20 Feb 2022 20:00:34 -1000 Subject: [PATCH 107/132] Add TODO to investigate transaction.data --- packages/web3-common/src/eth_execution_api.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/web3-common/src/eth_execution_api.ts b/packages/web3-common/src/eth_execution_api.ts index 795bdb5b546..ad1fd82f533 100644 --- a/packages/web3-common/src/eth_execution_api.ts +++ b/packages/web3-common/src/eth_execution_api.ts @@ -40,6 +40,7 @@ export interface BaseTransaction { readonly nonce: Uint; readonly gas: Uint; readonly value: Uint; + // TODO - Investigate if this should actually be data instead of input readonly input: HexStringBytes; chainId?: Uint; } From 627efdc943c0cb29c73a24fbd63bc5ed790aa925 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Sun, 20 Feb 2022 20:00:51 -1000 Subject: [PATCH 108/132] Add formatting to getChainId response --- packages/web3-eth/src/index.ts | 7 ++++--- packages/web3-eth/src/rpc_method_wrappers.ts | 12 ++++++++++++ .../web3-eth/test/fixtures/rpc_methods_wrappers.ts | 9 +++++++++ .../fixtures/web3_eth_methods_with_parameters.ts | 9 +++++++++ .../unit/web3_eth_methods_no_parameters.test.ts | 5 ----- .../unit/web3_eth_methods_with_parameters.test.ts | 8 ++++++++ ...web3_rpc_method_wrappers_with_parameters.test.ts | 13 +++++++++++++ 7 files changed, 55 insertions(+), 8 deletions(-) diff --git a/packages/web3-eth/src/index.ts b/packages/web3-eth/src/index.ts index bd21d5112ee..6493986833c 100644 --- a/packages/web3-eth/src/index.ts +++ b/packages/web3-eth/src/index.ts @@ -215,9 +215,10 @@ export default class Web3Eth extends Web3Context { return rpcMethods.requestAccounts(this.requestManager); } - // TODO - Format chainId - public async getChainId() { - return rpcMethods.getChainId(this.requestManager); + public async getChainId( + returnType?: ReturnType, + ) { + return rpcMethodsWrappers.getChainId(this, returnType); } // TODO diff --git a/packages/web3-eth/src/rpc_method_wrappers.ts b/packages/web3-eth/src/rpc_method_wrappers.ts index 45fa09aa0b7..34671e5c191 100644 --- a/packages/web3-eth/src/rpc_method_wrappers.ts +++ b/packages/web3-eth/src/rpc_method_wrappers.ts @@ -351,6 +351,18 @@ export async function getFeeHistory( + web3Context: Web3Context, + returnType?: ReturnType, +) { + const response = await rpcMethods.getChainId(web3Context.requestManager); + + return convertToValidType( + response, + returnType ?? web3Context.defaultReturnType, + ) as ValidReturnTypes[ReturnType]; +} + export async function getProof( web3Context: Web3Context, address: Address, diff --git a/packages/web3-eth/test/fixtures/rpc_methods_wrappers.ts b/packages/web3-eth/test/fixtures/rpc_methods_wrappers.ts index 67a61ad9b19..d400a3d84fd 100644 --- a/packages/web3-eth/test/fixtures/rpc_methods_wrappers.ts +++ b/packages/web3-eth/test/fixtures/rpc_methods_wrappers.ts @@ -19,6 +19,7 @@ import { HexStringBytes, Filter, HexString8Bytes, + Numbers, } from 'web3-utils'; import { @@ -2630,3 +2631,11 @@ export const getProofValidData: [ accountObjectBigInt, ], ]; + +export const getChainIdValidData: [ValidTypes | undefined, Uint, Numbers][] = [ + [undefined, '0x3d', '0x3d'], + [ValidTypes.HexString, '0x3d', '0x3d'], + [ValidTypes.Number, '0x3d', 61], + [ValidTypes.NumberString, '0x3d', '61'], + [ValidTypes.BigInt, '0x3d', BigInt('0x3d')], +]; diff --git a/packages/web3-eth/test/fixtures/web3_eth_methods_with_parameters.ts b/packages/web3-eth/test/fixtures/web3_eth_methods_with_parameters.ts index df3614b3697..28c117a652e 100644 --- a/packages/web3-eth/test/fixtures/web3_eth_methods_with_parameters.ts +++ b/packages/web3-eth/test/fixtures/web3_eth_methods_with_parameters.ts @@ -40,6 +40,15 @@ export const getBlockNumberValidData: [ValidTypes | undefined][] = [ [ValidTypes.BigInt], ]; +// Array consists of: returnType parameter +export const getChainIdValidData: [ValidTypes | undefined][] = [ + [undefined], + [ValidTypes.HexString], + [ValidTypes.NumberString], + [ValidTypes.Number], + [ValidTypes.BigInt], +]; + /** * Array consists of: * - array of inputs diff --git a/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts b/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts index b3df4133907..3cdf99c9e5a 100644 --- a/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts +++ b/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts @@ -52,10 +52,5 @@ describe('web3_eth_methods_no_parameters', () => { await web3Eth.requestAccounts(); expect(rpcMethods.requestAccounts).toHaveBeenCalledWith(web3Eth.requestManager); }); - - it('getChainId', async () => { - await web3Eth.getChainId(); - expect(rpcMethods.getChainId).toHaveBeenCalledWith(web3Eth.requestManager); - }); }); }); diff --git a/packages/web3-eth/test/unit/web3_eth_methods_with_parameters.test.ts b/packages/web3-eth/test/unit/web3_eth_methods_with_parameters.test.ts index cd6527a4a75..d5ea58f4235 100644 --- a/packages/web3-eth/test/unit/web3_eth_methods_with_parameters.test.ts +++ b/packages/web3-eth/test/unit/web3_eth_methods_with_parameters.test.ts @@ -11,6 +11,7 @@ import { getBlockTransactionCountValidData, getBlockUncleCountValidData, getBlockValidData, + getChainIdValidData, getCodeValidData, getFeeHistoryValidData, // getCodeValidData, @@ -65,6 +66,13 @@ describe('web3_eth_methods_with_parameters', () => { ); }); }); + + describe('getChainId', () => { + it.each(getChainIdValidData)('returnType: %s', async returnType => { + await web3Eth.getChainId(returnType); + expect(rpcMethodWrappers.getChainId).toHaveBeenCalledWith(web3Eth, returnType); + }); + }); }); describe('has multiple parameters', () => { diff --git a/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts b/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts index c8247f7549b..3a93bd81b5e 100644 --- a/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts +++ b/packages/web3-eth/test/unit/web3_rpc_method_wrappers_with_parameters.test.ts @@ -9,6 +9,7 @@ import { getBlockNumber, getBlockTransactionCount, getBlockUncleCount, + getChainId, getFeeHistory, getGasPrice, getHashRate, @@ -28,6 +29,7 @@ import { getBlockTransactionCountValidData, getBlockUncleCountValidData, getBlockValidData, + getChainIdValidData, getFeeHistoryValidData, getGasPriceValidData, getHashRateValidData, @@ -109,6 +111,17 @@ describe('web3_eth_methods_with_parameters', () => { // }, // ); // }); + + describe('getChainId', () => { + it.each(getChainIdValidData)( + 'returnType: %s mockRpcResponse: %s output: %s', + async (returnType, mockRpcResponse, output) => { + (rpcMethods.getChainId as jest.Mock).mockResolvedValueOnce(mockRpcResponse); + expect(await getChainId(web3Eth, returnType)).toBe(output); + expect(rpcMethods.getChainId).toHaveBeenCalledWith(web3Eth.requestManager); + }, + ); + }); }); describe('has multiple parameters', () => { From 5b8f781516c5e4d9ea53614128f4d4fe141c55eb Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Sun, 20 Feb 2022 20:09:09 -1000 Subject: [PATCH 109/132] Init getNodeInfo --- packages/web3-eth/src/index.ts | 7 +++---- packages/web3-eth/src/rpc_methods.ts | 7 +++++++ .../web3-eth/test/unit/rpc_methods_no_parameters.test.ts | 9 +++++++++ .../test/unit/web3_eth_methods_no_parameters.test.ts | 5 +++++ 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/packages/web3-eth/src/index.ts b/packages/web3-eth/src/index.ts index 6493986833c..8c9f1688398 100644 --- a/packages/web3-eth/src/index.ts +++ b/packages/web3-eth/src/index.ts @@ -221,10 +221,9 @@ export default class Web3Eth extends Web3Context { return rpcMethodsWrappers.getChainId(this, returnType); } - // TODO - // public async getNodeInfo() { - - // } + public async getNodeInfo() { + return rpcMethods.getNodeInfo(this.requestManager); + } // TODO - Format input public async getProof( diff --git a/packages/web3-eth/src/rpc_methods.ts b/packages/web3-eth/src/rpc_methods.ts index 4e5aa4f2ff3..765881ce7bc 100644 --- a/packages/web3-eth/src/rpc_methods.ts +++ b/packages/web3-eth/src/rpc_methods.ts @@ -529,3 +529,10 @@ export async function getProof( params: [address, storageKey, blockNumber], }); } + +export async function getNodeInfo(requestManager: Web3RequestManager) { + return requestManager.send({ + method: 'web3_clientVersion', + params: [], + }); +} diff --git a/packages/web3-eth/test/unit/rpc_methods_no_parameters.test.ts b/packages/web3-eth/test/unit/rpc_methods_no_parameters.test.ts index 16c9c1e72e5..a349e56d196 100644 --- a/packages/web3-eth/test/unit/rpc_methods_no_parameters.test.ts +++ b/packages/web3-eth/test/unit/rpc_methods_no_parameters.test.ts @@ -9,6 +9,7 @@ import { getGasPrice, getHashRate, getMining, + getNodeInfo, getPendingTransactions, getProtocolVersion, getSyncing, @@ -154,5 +155,13 @@ describe('rpc_methods_no_parameters', () => { params: [], }); }); + it('getNodeInfo', async () => { + await getNodeInfo(requestManager); + + expect(requestManagerSendSpy).toHaveBeenCalledWith({ + method: 'web3_clientVersion', + params: [], + }); + }); }); }); diff --git a/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts b/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts index 3cdf99c9e5a..72eb0f10ca6 100644 --- a/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts +++ b/packages/web3-eth/test/unit/web3_eth_methods_no_parameters.test.ts @@ -52,5 +52,10 @@ describe('web3_eth_methods_no_parameters', () => { await web3Eth.requestAccounts(); expect(rpcMethods.requestAccounts).toHaveBeenCalledWith(web3Eth.requestManager); }); + + it('getNodeInfo', async () => { + await web3Eth.getNodeInfo(); + expect(rpcMethods.getNodeInfo).toHaveBeenCalledWith(web3Eth.requestManager); + }); }); }); From edf11f11ff244dd20a70da5fffb3b3f19054cd8c Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Sun, 20 Feb 2022 20:30:13 -1000 Subject: [PATCH 110/132] Revert esModuleInterop change --- templates/tsconfig.json.tmpl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/templates/tsconfig.json.tmpl b/templates/tsconfig.json.tmpl index 33b9f1c8116..7ed7f6b23a4 100644 --- a/templates/tsconfig.json.tmpl +++ b/templates/tsconfig.json.tmpl @@ -1,8 +1,7 @@ { "extends": "../../tsconfig", "compilerOptions": { - "outDir": "dist", - "esModuleInterop": true + "outDir": "dist" }, "include": ["src/**/*"] } From 0d1f59f67c7ff2d878bc6bbda24e3c0687690a1f Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Mon, 21 Feb 2022 17:30:08 -1000 Subject: [PATCH 111/132] Combine networkId and chainId if statements --- packages/web3-eth/src/format_transaction.ts | 22 +++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/web3-eth/src/format_transaction.ts b/packages/web3-eth/src/format_transaction.ts index 8dae27e09b3..49a8d0168f8 100644 --- a/packages/web3-eth/src/format_transaction.ts +++ b/packages/web3-eth/src/format_transaction.ts @@ -45,16 +45,18 @@ export function formatTransaction< } } - if (formattedTransaction.common?.customChain?.networkId !== undefined) - formattedTransaction.common.customChain.networkId = convertToValidType( - formattedTransaction.common.customChain.networkId, - desiredType, - ); - if (formattedTransaction.common?.customChain?.chainId !== undefined) - formattedTransaction.common.customChain.chainId = convertToValidType( - formattedTransaction.common.customChain.chainId, - desiredType, - ); + if (formattedTransaction.common?.customChain !== undefined) { + if (formattedTransaction.common.customChain.networkId !== undefined) + formattedTransaction.common.customChain.networkId = convertToValidType( + formattedTransaction.common.customChain.networkId, + desiredType, + ); + if (formattedTransaction.common.customChain.chainId !== undefined) + formattedTransaction.common.customChain.chainId = convertToValidType( + formattedTransaction.common.customChain.chainId, + desiredType, + ); + } if (formattedTransaction.data !== undefined && formattedTransaction.input !== undefined) throw new TransactionDataAndInputError({ From 825cc0386b996f3095d20466ff77304f61c03152 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Thu, 24 Feb 2022 00:46:55 -1000 Subject: [PATCH 112/132] yarn format --- packages/web3/package.json | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/web3/package.json b/packages/web3/package.json index 9d6dcae5238..4b15838ae00 100644 --- a/packages/web3/package.json +++ b/packages/web3/package.json @@ -5,16 +5,15 @@ "main": "dist/index.js", "repository": "https://github.com/ChainSafe/web3.js", "engines": { - "node": ">=12.0.0" - }, - - + "node": ">=12.0.0" + }, "author": "ChainSafe Systems", "license": "LGPL-3.0", "keywords": [ - "Ethereum", - "JavaScript", - "API" ], + "Ethereum", + "JavaScript", + "API" + ], "files": [ "dist/**/*" ], From 3e3e033f4775d3f2cb03b9b1c1a12664be9f3bab Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Thu, 24 Feb 2022 00:47:12 -1000 Subject: [PATCH 113/132] Add Partial to type of transaction for eth_sendTransaction --- packages/web3-common/src/eth_execution_api.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/web3-common/src/eth_execution_api.ts b/packages/web3-common/src/eth_execution_api.ts index ad1fd82f533..2e29dfafdd7 100644 --- a/packages/web3-common/src/eth_execution_api.ts +++ b/packages/web3-common/src/eth_execution_api.ts @@ -270,7 +270,9 @@ export type EthExecutionAPI = { eth_getCode: (address: Address, blockNumber: BlockNumberOrTag) => HexStringBytes; // https://github.com/ethereum/execution-apis/blob/main/src/eth/submit.json - eth_sendTransaction: (transaction: TransactionWithSender) => HexString32Bytes; + eth_sendTransaction: ( + transaction: TransactionWithSender | Partial, + ) => HexString32Bytes; eth_sendRawTransaction: (transaction: HexStringBytes) => HexString32Bytes; // https://geth.ethereum.org/docs/rpc/pubsub From a5da15324cb8c1484c09c548bdd2e6d9110a0de3 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Thu, 24 Feb 2022 00:47:48 -1000 Subject: [PATCH 114/132] Init transactionReceiptPollingInterval and transactionConfirmationPollingInterval --- packages/web3-core/src/types.ts | 2 ++ packages/web3-core/src/web3_config.ts | 30 +++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/packages/web3-core/src/types.ts b/packages/web3-core/src/types.ts index 4e2862d4e64..8e0972155cd 100644 --- a/packages/web3-core/src/types.ts +++ b/packages/web3-core/src/types.ts @@ -46,6 +46,8 @@ export interface Web3ConfigOptions { transactionBlockTimeout: number; transactionConfirmationBlocks: number; transactionPollingTimeout: number; + transactionReceiptPollingInterval: number; + transactionConfirmationPollingInterval: number; blockHeaderTimeout: number; maxListenersWarningThreshold: number; defaultNetworkId: Numbers | null; diff --git a/packages/web3-core/src/web3_config.ts b/packages/web3-core/src/web3_config.ts index 4cd39f69a24..1ced63601f0 100644 --- a/packages/web3-core/src/web3_config.ts +++ b/packages/web3-core/src/web3_config.ts @@ -22,6 +22,8 @@ export abstract class Web3Config transactionBlockTimeout: 50, transactionConfirmationBlocks: 24, transactionPollingTimeout: 750, + transactionReceiptPollingInterval: 1000, + transactionConfirmationPollingInterval: 13000, blockHeaderTimeout: 10, maxListenersWarningThreshold: 100, defaultNetworkId: null, @@ -118,6 +120,34 @@ export abstract class Web3Config this._config.transactionPollingTimeout = val; } + public get transactionReceiptPollingInterval() { + return this._config.transactionReceiptPollingInterval; + } + + public set transactionReceiptPollingInterval(val) { + this.emit(Web3ConfigEvent.CONFIG_CHANGE, { + name: 'transactionReceiptPollingInterval', + oldValue: this._config.transactionReceiptPollingInterval, + newValue: val, + }); + + this._config.transactionReceiptPollingInterval = val; + } + + public get transactionConfirmationPollingInterval() { + return this._config.transactionConfirmationPollingInterval; + } + + public set transactionConfirmationPollingInterval(val) { + this.emit(Web3ConfigEvent.CONFIG_CHANGE, { + name: 'transactionConfirmationPollingInterval', + oldValue: this._config.transactionConfirmationPollingInterval, + newValue: val, + }); + + this._config.transactionConfirmationPollingInterval = val; + } + public get blockHeaderTimeout() { return this._config.blockHeaderTimeout; } From e711e76e1b22303d550c5b55dba1473e80ea6cd7 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Thu, 24 Feb 2022 00:48:10 -1000 Subject: [PATCH 115/132] Add TODO and Partial to transaction type for sendTransaction --- packages/web3-eth/src/rpc_methods.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/web3-eth/src/rpc_methods.ts b/packages/web3-eth/src/rpc_methods.ts index 765881ce7bc..0502f2bfcaa 100644 --- a/packages/web3-eth/src/rpc_methods.ts +++ b/packages/web3-eth/src/rpc_methods.ts @@ -196,12 +196,14 @@ export async function signTransaction( }); } +// TODO - Validation should be: +// isTransactionWithSender(transaction) +// ? validateTransactionWithSender(transaction) +// : validateTransactionWithSender(transaction, true) with true being a isPartial flag export async function sendTransaction( requestManager: Web3RequestManager, - transaction: TransactionWithSender, + transaction: TransactionWithSender | Partial, ) { - validateTransactionWithSender(transaction); - return requestManager.send({ method: 'eth_sendTransaction', params: [transaction], From 2028c85669d7eb89dda3de6bc0436385cb83910c Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Thu, 24 Feb 2022 00:48:27 -1000 Subject: [PATCH 116/132] WIP sendTransaction and PromiEvent integration --- packages/web3-eth/src/rpc_method_wrappers.ts | 135 ++++++++++++++++++- 1 file changed, 129 insertions(+), 6 deletions(-) diff --git a/packages/web3-eth/src/rpc_method_wrappers.ts b/packages/web3-eth/src/rpc_method_wrappers.ts index 34671e5c191..4bd5f233a1b 100644 --- a/packages/web3-eth/src/rpc_method_wrappers.ts +++ b/packages/web3-eth/src/rpc_method_wrappers.ts @@ -1,7 +1,7 @@ // Disabling because returnTypes must be last param to match 1.x params /* eslint-disable default-param-last */ -import { EthExecutionAPI, TransactionWithSender } from 'web3-common'; +import { EthExecutionAPI, PromiEvent, ReceiptInfo, TransactionWithSender } from 'web3-common'; import { Web3Context } from 'web3-core'; import { Address, @@ -25,7 +25,7 @@ import { import { formatTransaction } from './format_transaction'; import * as rpcMethods from './rpc_methods'; -import { BlockFormatted } from './types'; +import { BlockFormatted, Transaction } from './types'; import { Web3EthExecutionAPI } from './web3_eth_execution_api'; export const getProtocolVersion = async (web3Context: Web3Context) => @@ -278,11 +278,134 @@ export async function getPendingTransactions, + transaction: Transaction, +) { + const formattedTransaction = formatTransaction(transaction, ValidTypes.HexString); + const promiEvent = new PromiEvent(async resolve => { + // TODO - Populate potentially missing gas fields + // if ( + // transaction.gasPrice === undefined && + // (transaction.maxPriorityFeePerGas === undefined || + // transaction.maxFeePerGas === undefined) + // ) { + // Determine transaction type and fill in required gas properties + // } + + promiEvent.emit('sending', formattedTransaction); + + // TODO - If an account is available in wallet, sign transaction and call sendRawTransaction + // https://github.com/ChainSafe/web3.js/blob/b32555cfeedde128c657dabbba201102f691f955/packages/web3-core-method/src/index.js#L720 + + const transactionHash = await rpcMethods.sendTransaction( + web3Context.requestManager, + formattedTransaction, + ); + + promiEvent.emit('sent', formattedTransaction); + promiEvent.emit('transactionHash', transactionHash); + + let transactionReceipt = await rpcMethods.getTransactionReceipt( + web3Context.requestManager, + transactionHash, + ); + + // Transaction hasn't been included in a block yet + if (transactionReceipt === null) + transactionReceipt = await waitForTransactionReceipt(web3Context, transactionHash); + + promiEvent.emit('receipt', transactionReceipt); + // TODO - Format receipt + resolve(transactionReceipt); + + watchTransactionForConfirmations(web3Context, promiEvent, transactionReceipt); + }); + + return promiEvent; +} + +const waitForTransactionReceipt = ( + web3Context: Web3Context, + transactionHash: HexString32Bytes, +): Promise => { + return new Promise(resolve => { + let transactionPollingDuration = 0; + const intervalId = setInterval(async () => { + transactionPollingDuration += web3Context.transactionReceiptPollingInterval; + // TODO - Should probably throw an error + if (transactionPollingDuration >= web3Context.transactionPollingTimeout) + clearInterval(intervalId); + + const response = await rpcMethods.getTransactionReceipt( + web3Context.requestManager, + transactionHash, + ); + + if (response !== null) { + clearInterval(intervalId); + resolve(response); + } + }, web3Context.transactionReceiptPollingInterval); + }); +}; + +const watchTransactionForConfirmations = async ( + web3Context: Web3Context, + transactionPromiEvent: PromiEvent, + transactionReceipt: ReceiptInfo, +) => { + if ( + transactionReceipt === undefined || + transactionReceipt === null || + transactionReceipt.blockHash === undefined || + transactionReceipt.blockHash === null + ) + // TODO - Replace error + throw new Error('Receipt missing or blockHash null'); + + if (transactionReceipt.blockNumber === undefined || transactionReceipt.blockNumber === null) + // TODO - Replace error + throw new Error('Receipt missing block number'); + + // TODO - Should check: (web3Context.requestManager.provider as Web3BaseProvider).supportsSubscriptions + // so a subscription for newBlockHeaders can be made instead of polling + + // Having a transactionReceipt means that the transaction has already been included + // in at least one block, so we start with 1 + let confirmationNumber = 1; + const intervalId = setInterval(async () => { + if (confirmationNumber >= web3Context.transactionConfirmationBlocks) + clearInterval(intervalId); + + const nextBlock = await getBlock( + web3Context, + transactionReceipt.blockNumber + confirmationNumber, + false, + ValidTypes.Number, + ); + if (nextBlock !== null && nextBlock.hash !== null) { + confirmationNumber += 1; + transactionPromiEvent.emit('confirmation', { + confirmationNumber, + receipt: transactionReceipt, + latestBlockHash: nextBlock.hash, + }); + } + }, web3Context.transactionConfirmationPollingInterval); +}; export const sendSignedTransaction = async ( web3Context: Web3Context, From 039bc48206c4fe7611bfc1ee38a5e89c7c3b56e3 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Thu, 24 Feb 2022 20:48:54 -1000 Subject: [PATCH 117/132] Add eslint-disable-next-line --- packages/web3-core/src/web3_context.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/web3-core/src/web3_context.ts b/packages/web3-core/src/web3_context.ts index 4f628ddad46..a0825a21020 100644 --- a/packages/web3-core/src/web3_context.ts +++ b/packages/web3-core/src/web3_context.ts @@ -9,6 +9,7 @@ export class Web3Context< API extends Web3APISpec, RegisteredSubs extends { [key: string]: Web3SubscriptionConstructor; + // eslint-disable-next-line @typescript-eslint/ban-types } = {}, > extends Web3Config { public static readonly providers = Web3RequestManager.providers; From fb32bdc1c96e6469f1905d14c4e7998c5d933c47 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Thu, 24 Feb 2022 20:49:08 -1000 Subject: [PATCH 118/132] Add eslint-disable-next-line --- packages/web3-core/src/web3_subscriptions.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/web3-core/src/web3_subscriptions.ts b/packages/web3-core/src/web3_subscriptions.ts index f32571fd9be..8e6f84dd788 100644 --- a/packages/web3-core/src/web3_subscriptions.ts +++ b/packages/web3-core/src/web3_subscriptions.ts @@ -104,6 +104,7 @@ export abstract class Web3Subscription< export type Web3SubscriptionConstructor< API extends Web3APISpec, + // eslint-disable-next-line @typescript-eslint/no-explicit-any SubscriptionType extends Web3Subscription = Web3Subscription, > = new ( // We accept any type of arguments here and don't deal with this type internally From f87e7392be5004b34c8f0e8401f644961a046a9a Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Thu, 24 Feb 2022 20:49:24 -1000 Subject: [PATCH 119/132] Move TransactionEvents --- packages/web3-eth/src/types.ts | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/packages/web3-eth/src/types.ts b/packages/web3-eth/src/types.ts index 3537b6c945f..26a21717b83 100644 --- a/packages/web3-eth/src/types.ts +++ b/packages/web3-eth/src/types.ts @@ -1,4 +1,11 @@ -import { AccessList, Log, TransactionHash, TransactionInfo, Uncles } from 'web3-common'; +import { + AccessList, + Log, + ReceiptInfo, + TransactionHash, + TransactionInfo, + Uncles, +} from 'web3-common'; import { Address, HexString, @@ -245,3 +252,15 @@ export interface AccountObjectFormatted { readonly accountProof: HexString32Bytes[]; readonly storageProof: StorageProofFormatted[]; } + +export type TransactionEvents = { + sending: Transaction; + sent: Transaction; + transactionHash: HexString32Bytes; + receipt: ReceiptInfo; + confirmation: { + confirmationNumber: number; + receipt: ReceiptInfo; + latestBlockHash: HexString32Bytes; + }; +}; From 2ed9b40b34a95fc73923f96703917f7e0bbde493 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Thu, 24 Feb 2022 20:49:35 -1000 Subject: [PATCH 120/132] eslint fixes --- packages/web3-eth/src/rpc_method_wrappers.ts | 127 +++++++++---------- 1 file changed, 62 insertions(+), 65 deletions(-) diff --git a/packages/web3-eth/src/rpc_method_wrappers.ts b/packages/web3-eth/src/rpc_method_wrappers.ts index 4bd5f233a1b..3e346903c7a 100644 --- a/packages/web3-eth/src/rpc_method_wrappers.ts +++ b/packages/web3-eth/src/rpc_method_wrappers.ts @@ -25,7 +25,7 @@ import { import { formatTransaction } from './format_transaction'; import * as rpcMethods from './rpc_methods'; -import { BlockFormatted, Transaction } from './types'; +import { BlockFormatted, Transaction, TransactionEvents } from './types'; import { Web3EthExecutionAPI } from './web3_eth_execution_api'; export const getProtocolVersion = async (web3Context: Web3Context) => @@ -278,71 +278,15 @@ export async function getPendingTransactions, - transaction: Transaction, -) { - const formattedTransaction = formatTransaction(transaction, ValidTypes.HexString); - const promiEvent = new PromiEvent(async resolve => { - // TODO - Populate potentially missing gas fields - // if ( - // transaction.gasPrice === undefined && - // (transaction.maxPriorityFeePerGas === undefined || - // transaction.maxFeePerGas === undefined) - // ) { - // Determine transaction type and fill in required gas properties - // } - - promiEvent.emit('sending', formattedTransaction); - - // TODO - If an account is available in wallet, sign transaction and call sendRawTransaction - // https://github.com/ChainSafe/web3.js/blob/b32555cfeedde128c657dabbba201102f691f955/packages/web3-core-method/src/index.js#L720 - - const transactionHash = await rpcMethods.sendTransaction( - web3Context.requestManager, - formattedTransaction, - ); - - promiEvent.emit('sent', formattedTransaction); - promiEvent.emit('transactionHash', transactionHash); - - let transactionReceipt = await rpcMethods.getTransactionReceipt( - web3Context.requestManager, - transactionHash, - ); - - // Transaction hasn't been included in a block yet - if (transactionReceipt === null) - transactionReceipt = await waitForTransactionReceipt(web3Context, transactionHash); - - promiEvent.emit('receipt', transactionReceipt); - // TODO - Format receipt - resolve(transactionReceipt); - - watchTransactionForConfirmations(web3Context, promiEvent, transactionReceipt); - }); - - return promiEvent; -} -const waitForTransactionReceipt = ( +const waitForTransactionReceipt = async ( web3Context: Web3Context, transactionHash: HexString32Bytes, -): Promise => { - return new Promise(resolve => { +): Promise => + new Promise(resolve => { let transactionPollingDuration = 0; + // TODO - Promise returned in function argument where a void return was expected + // eslint-disable-next-line @typescript-eslint/no-misused-promises const intervalId = setInterval(async () => { transactionPollingDuration += web3Context.transactionReceiptPollingInterval; // TODO - Should probably throw an error @@ -360,7 +304,6 @@ const waitForTransactionReceipt = ( } }, web3Context.transactionReceiptPollingInterval); }); -}; const watchTransactionForConfirmations = async ( web3Context: Web3Context, @@ -386,17 +329,21 @@ const watchTransactionForConfirmations = async ( // Having a transactionReceipt means that the transaction has already been included // in at least one block, so we start with 1 let confirmationNumber = 1; + // TODO - Promise returned in function argument where a void return was expected + // eslint-disable-next-line @typescript-eslint/no-misused-promises const intervalId = setInterval(async () => { if (confirmationNumber >= web3Context.transactionConfirmationBlocks) clearInterval(intervalId); const nextBlock = await getBlock( web3Context, - transactionReceipt.blockNumber + confirmationNumber, + // TODO - Refactor after input formatting is added to getBlock + (BigInt(transactionReceipt.blockNumber) + BigInt(confirmationNumber)).toString(16), false, ValidTypes.Number, ); - if (nextBlock !== null && nextBlock.hash !== null) { + + if (nextBlock?.hash !== null) { confirmationNumber += 1; transactionPromiEvent.emit('confirmation', { confirmationNumber, @@ -407,6 +354,56 @@ const watchTransactionForConfirmations = async ( }, web3Context.transactionConfirmationPollingInterval); }; +export async function sendTransaction( + web3Context: Web3Context, + transaction: Transaction, +) { + const formattedTransaction = formatTransaction(transaction, ValidTypes.HexString); + // TODO - Promise returned in function argument where a void return was expected + // eslint-disable-next-line @typescript-eslint/no-misused-promises + const promiEvent = new PromiEvent(async resolve => { + // TODO - Populate potentially missing gas fields + // if ( + // transaction.gasPrice === undefined && + // (transaction.maxPriorityFeePerGas === undefined || + // transaction.maxFeePerGas === undefined) + // ) { + // Determine transaction type and fill in required gas properties + // } + + promiEvent.emit('sending', formattedTransaction); + + // TODO - If an account is available in wallet, sign transaction and call sendRawTransaction + // https://github.com/ChainSafe/web3.js/blob/b32555cfeedde128c657dabbba201102f691f955/packages/web3-core-method/src/index.js#L720 + + const transactionHash = await rpcMethods.sendTransaction( + web3Context.requestManager, + formattedTransaction, + ); + + promiEvent.emit('sent', formattedTransaction); + promiEvent.emit('transactionHash', transactionHash); + + let transactionReceipt = await rpcMethods.getTransactionReceipt( + web3Context.requestManager, + transactionHash, + ); + + // Transaction hasn't been included in a block yet + if (transactionReceipt === null) + transactionReceipt = await waitForTransactionReceipt(web3Context, transactionHash); + + promiEvent.emit('receipt', transactionReceipt); + // TODO - Format receipt + resolve(transactionReceipt); + + // TODO - Should this be awaited? + await watchTransactionForConfirmations(web3Context, promiEvent, transactionReceipt); + }); + + return promiEvent; +} + export const sendSignedTransaction = async ( web3Context: Web3Context, transaction: HexStringBytes, From 433ea15160faf98d3f4211815a5e004ef707243d Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Thu, 24 Feb 2022 22:29:22 -1000 Subject: [PATCH 121/132] Update sendSignedTransaction to use PromiEvent --- packages/web3-eth/src/rpc_method_wrappers.ts | 63 +++++++++++++++++--- packages/web3-eth/src/types.ts | 14 ++++- 2 files changed, 67 insertions(+), 10 deletions(-) diff --git a/packages/web3-eth/src/rpc_method_wrappers.ts b/packages/web3-eth/src/rpc_method_wrappers.ts index 3e346903c7a..a7a4fecf897 100644 --- a/packages/web3-eth/src/rpc_method_wrappers.ts +++ b/packages/web3-eth/src/rpc_method_wrappers.ts @@ -25,7 +25,12 @@ import { import { formatTransaction } from './format_transaction'; import * as rpcMethods from './rpc_methods'; -import { BlockFormatted, Transaction, TransactionEvents } from './types'; +import { + BlockFormatted, + Transaction, + SendTransactionEvents, + SendSignedTransactionEvents, +} from './types'; import { Web3EthExecutionAPI } from './web3_eth_execution_api'; export const getProtocolVersion = async (web3Context: Web3Context) => @@ -305,11 +310,13 @@ const waitForTransactionReceipt = async ( }, web3Context.transactionReceiptPollingInterval); }); -const watchTransactionForConfirmations = async ( +function watchTransactionForConfirmations< + PromiEventEventType extends SendTransactionEvents | SendSignedTransactionEvents, +>( web3Context: Web3Context, - transactionPromiEvent: PromiEvent, + transactionPromiEvent: PromiEvent, transactionReceipt: ReceiptInfo, -) => { +) { if ( transactionReceipt === undefined || transactionReceipt === null || @@ -352,7 +359,7 @@ const watchTransactionForConfirmations = async ( }); } }, web3Context.transactionConfirmationPollingInterval); -}; +} export async function sendTransaction( web3Context: Web3Context, @@ -361,7 +368,7 @@ export async function sendTransaction( const formattedTransaction = formatTransaction(transaction, ValidTypes.HexString); // TODO - Promise returned in function argument where a void return was expected // eslint-disable-next-line @typescript-eslint/no-misused-promises - const promiEvent = new PromiEvent(async resolve => { + const promiEvent = new PromiEvent(async resolve => { // TODO - Populate potentially missing gas fields // if ( // transaction.gasPrice === undefined && @@ -397,8 +404,11 @@ export async function sendTransaction( // TODO - Format receipt resolve(transactionReceipt); - // TODO - Should this be awaited? - await watchTransactionForConfirmations(web3Context, promiEvent, transactionReceipt); + watchTransactionForConfirmations( + web3Context, + promiEvent, + transactionReceipt, + ); }); return promiEvent; @@ -407,7 +417,42 @@ export async function sendTransaction( export const sendSignedTransaction = async ( web3Context: Web3Context, transaction: HexStringBytes, -) => rpcMethods.sendRawTransaction(web3Context.requestManager, transaction); +) => { + // TODO - Promise returned in function argument where a void return was expected + // eslint-disable-next-line @typescript-eslint/no-misused-promises + const promiEvent = new PromiEvent(async resolve => { + promiEvent.emit('sending', transaction); + + const transactionHash = await rpcMethods.sendRawTransaction( + web3Context.requestManager, + transaction, + ); + + promiEvent.emit('sent', transaction); + promiEvent.emit('transactionHash', transactionHash); + + let transactionReceipt = await rpcMethods.getTransactionReceipt( + web3Context.requestManager, + transactionHash, + ); + + // Transaction hasn't been included in a block yet + if (transactionReceipt === null) + transactionReceipt = await waitForTransactionReceipt(web3Context, transactionHash); + + promiEvent.emit('receipt', transactionReceipt); + // TODO - Format receipt + resolve(transactionReceipt); + + watchTransactionForConfirmations( + web3Context, + promiEvent, + transactionReceipt, + ); + }); + + return promiEvent; +}; // TODO address can be an address or the index of a local wallet in web3.eth.accounts.wallet // https://web3js.readthedocs.io/en/v1.5.2/web3-eth.html?highlight=sendTransaction#sign diff --git a/packages/web3-eth/src/types.ts b/packages/web3-eth/src/types.ts index 26a21717b83..708b6d39d76 100644 --- a/packages/web3-eth/src/types.ts +++ b/packages/web3-eth/src/types.ts @@ -253,7 +253,7 @@ export interface AccountObjectFormatted { readonly storageProof: StorageProofFormatted[]; } -export type TransactionEvents = { +export type SendTransactionEvents = { sending: Transaction; sent: Transaction; transactionHash: HexString32Bytes; @@ -264,3 +264,15 @@ export type TransactionEvents = { latestBlockHash: HexString32Bytes; }; }; + +export type SendSignedTransactionEvents = { + sending: HexStringBytes; + sent: HexStringBytes; + transactionHash: HexString32Bytes; + receipt: ReceiptInfo; + confirmation: { + confirmationNumber: number; + receipt: ReceiptInfo; + latestBlockHash: HexString32Bytes; + }; +}; From 73a38e939d4b77405e4f32adf6eaccac387a6b02 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Thu, 24 Feb 2022 23:07:21 -1000 Subject: [PATCH 122/132] Init signTransaction --- packages/web3-common/src/eth_execution_api.ts | 4 +++- packages/web3-eth/src/rpc_method_wrappers.ts | 12 ++++++++---- packages/web3-eth/src/rpc_methods.ts | 10 ++++++---- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/packages/web3-common/src/eth_execution_api.ts b/packages/web3-common/src/eth_execution_api.ts index 2e29dfafdd7..9307c2eec42 100644 --- a/packages/web3-common/src/eth_execution_api.ts +++ b/packages/web3-common/src/eth_execution_api.ts @@ -257,7 +257,9 @@ export type EthExecutionAPI = { // https://github.com/ethereum/execution-apis/blob/main/src/eth/sign.json eth_sign: (address: Address, message: HexStringBytes) => HexString256Bytes; - eth_signTransaction: (transaction: TransactionWithSender) => HexStringBytes; + eth_signTransaction: ( + transaction: TransactionWithSender | Partial, + ) => HexStringBytes; // https://github.com/ethereum/execution-apis/blob/main/src/eth/state.json eth_getBalance: (address: Address, blockNumber: BlockNumberOrTag) => Uint; diff --git a/packages/web3-eth/src/rpc_method_wrappers.ts b/packages/web3-eth/src/rpc_method_wrappers.ts index a7a4fecf897..e1424657a62 100644 --- a/packages/web3-eth/src/rpc_method_wrappers.ts +++ b/packages/web3-eth/src/rpc_method_wrappers.ts @@ -462,10 +462,14 @@ export const sign = async ( address: Address, ) => rpcMethods.sign(web3Context.requestManager, address, message); -// TODO Needs to convert input to hex string -// public async signTransaction(transaction: Transaction) { -// return rpcMethods.signTransaction(this.web3Context.requestManager, transaction); -// } +export const signTransaction = async ( + web3Context: Web3Context, + transaction: Transaction, +) => + rpcMethods.signTransaction( + web3Context.requestManager, + formatTransaction(transaction, ValidTypes.HexString), + ); // TODO Decide what to do with transaction.to // https://github.com/ChainSafe/web3.js/pull/4525#issuecomment-982330076 diff --git a/packages/web3-eth/src/rpc_methods.ts b/packages/web3-eth/src/rpc_methods.ts index 0502f2bfcaa..298a552e84f 100644 --- a/packages/web3-eth/src/rpc_methods.ts +++ b/packages/web3-eth/src/rpc_methods.ts @@ -11,7 +11,7 @@ import { HexString8Bytes, } from 'web3-utils'; import { validator } from 'web3-validator'; -import { validateTransactionCall, validateTransactionWithSender } from './validation'; +import { validateTransactionCall } from './validation'; import { Web3EthExecutionAPI } from './web3_eth_execution_api'; export async function getProtocolVersion(requestManager: Web3RequestManager) { @@ -184,12 +184,14 @@ export async function sign( }); } +// TODO - Validation should be: +// isTransactionWithSender(transaction) +// ? validateTransactionWithSender(transaction) +// : validateTransactionWithSender(transaction, true) with true being a isPartial flag export async function signTransaction( requestManager: Web3RequestManager, - transaction: TransactionWithSender, + transaction: TransactionWithSender | Partial, ) { - validateTransactionWithSender(transaction); - return requestManager.send({ method: 'eth_signTransaction', params: [transaction], From 0e75a2d89416f38a9ec65eb76cdf363b7c3e40df Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Fri, 25 Feb 2022 00:41:08 -1000 Subject: [PATCH 123/132] Refactor TransactionCall --- packages/web3-common/src/eth_execution_api.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/web3-common/src/eth_execution_api.ts b/packages/web3-common/src/eth_execution_api.ts index 9307c2eec42..97d37b40d8c 100644 --- a/packages/web3-common/src/eth_execution_api.ts +++ b/packages/web3-common/src/eth_execution_api.ts @@ -24,14 +24,17 @@ export type AccessList = AccessListEntry[]; export type TransactionHash = HexString; export type Uncles = HexString32Bytes[]; -// TODO Should probably support EIP-2930 and EIP-1559 export interface TransactionCall { readonly from?: Address; readonly to: Address; readonly gas?: Uint; readonly gasPrice?: Uint; readonly value?: Uint; - readonly data?: HexString; + readonly data?: HexStringBytes; + readonly type?: HexStringSingleByte; + readonly maxFeePerGas?: Uint; + readonly maxPriorityFeePerGas?: Uint; + readonly accessList?: AccessList; } export interface BaseTransaction { @@ -42,7 +45,7 @@ export interface BaseTransaction { readonly value: Uint; // TODO - Investigate if this should actually be data instead of input readonly input: HexStringBytes; - chainId?: Uint; + readonly chainId?: Uint; } export interface Transaction1559Unsigned extends BaseTransaction { From 05522c965f30f0ddcc2343ba39a4b09f46546e2a Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Fri, 25 Feb 2022 00:41:29 -1000 Subject: [PATCH 124/132] Comment out validation for call --- packages/web3-eth/src/rpc_methods.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/web3-eth/src/rpc_methods.ts b/packages/web3-eth/src/rpc_methods.ts index 298a552e84f..f9425ea7e28 100644 --- a/packages/web3-eth/src/rpc_methods.ts +++ b/packages/web3-eth/src/rpc_methods.ts @@ -11,7 +11,6 @@ import { HexString8Bytes, } from 'web3-utils'; import { validator } from 'web3-validator'; -import { validateTransactionCall } from './validation'; import { Web3EthExecutionAPI } from './web3_eth_execution_api'; export async function getProtocolVersion(requestManager: Web3RequestManager) { @@ -224,12 +223,13 @@ export async function sendRawTransaction( }); } +// TODO - validate transaction export async function call( requestManager: Web3RequestManager, transaction: TransactionCall, blockNumber: BlockNumberOrTag, ) { - validateTransactionCall(transaction); + // validateTransactionCall(transaction); validator.validate(['blockNumberOrTag'], [blockNumber]); return requestManager.send({ From b01dd306114e25395506ce8ddb9e7825b9ebff0b Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Fri, 25 Feb 2022 00:41:48 -1000 Subject: [PATCH 125/132] Init TransactionCall type for web3-eth types --- packages/web3-eth/src/types.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/web3-eth/src/types.ts b/packages/web3-eth/src/types.ts index 708b6d39d76..9ba8cfba62f 100644 --- a/packages/web3-eth/src/types.ts +++ b/packages/web3-eth/src/types.ts @@ -72,6 +72,11 @@ export interface Transaction { s?: HexString; } +export interface TransactionCall + extends Transaction { + to: Address; +} + export interface PopulatedUnsignedBaseTransaction { from: Address; to?: Address; From be06ee5ee2b00da2206ba6aa9a4dfdaf77d485ef Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Fri, 25 Feb 2022 00:42:21 -1000 Subject: [PATCH 126/132] Remove as BaseTransaction from isTransactionCall --- packages/web3-eth/src/validation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web3-eth/src/validation.ts b/packages/web3-eth/src/validation.ts index a4ffd5aaefa..432521c9deb 100644 --- a/packages/web3-eth/src/validation.ts +++ b/packages/web3-eth/src/validation.ts @@ -109,7 +109,7 @@ export function isTransactionCall(value: TransactionCall): boolean { if (value.gasPrice !== undefined && !isHexStrict(value.gasPrice)) return false; if (value.value !== undefined && !isHexStrict(value.value)) return false; if (value.data !== undefined && !isHexStrict(value.data)) return false; - if ((value as BaseTransaction).type !== undefined) return false; + if (value.type !== undefined) return false; if (isTransaction1559Unsigned(value as Transaction1559Unsigned)) return false; if (isTransaction2930Unsigned(value as Transaction2930Unsigned)) return false; From 7afbb423480765e0a8d8d7e13163de208cffa6b0 Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Fri, 25 Feb 2022 00:42:36 -1000 Subject: [PATCH 127/132] Implement call for rpc_method_wrappers --- packages/web3-eth/src/rpc_method_wrappers.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/web3-eth/src/rpc_method_wrappers.ts b/packages/web3-eth/src/rpc_method_wrappers.ts index e1424657a62..11222add2b9 100644 --- a/packages/web3-eth/src/rpc_method_wrappers.ts +++ b/packages/web3-eth/src/rpc_method_wrappers.ts @@ -8,6 +8,7 @@ import { BlockNumberOrTag, convertObjectPropertiesToValidType, convertToValidType, + HexString, HexString32Bytes, HexStringBytes, Uint, @@ -30,6 +31,7 @@ import { Transaction, SendTransactionEvents, SendSignedTransactionEvents, + TransactionCall, } from './types'; import { Web3EthExecutionAPI } from './web3_eth_execution_api'; @@ -473,12 +475,16 @@ export const signTransaction = async ( // TODO Decide what to do with transaction.to // https://github.com/ChainSafe/web3.js/pull/4525#issuecomment-982330076 -// public async call( -// transaction: Transaction & { to: Address }, -// blockNumber: BlockNumberOrTag = this.web3Context.defaultBlock, -// ) { -// return rpcMethods.call(this.web3Context.requestManager, transaction, blockNumber); -// } +export const call = async ( + web3Context: Web3Context, + transaction: TransactionCall, + blockNumber: BlockNumberOrTag = web3Context.defaultBlock, +) => + rpcMethods.call( + web3Context.requestManager, + formatTransaction(transaction, ValidTypes.HexString) as TransactionCall, + convertToValidType(blockNumber, ValidTypes.HexString) as HexString, + ); // TODO Missing param export async function estimateGas( From 96026ec5990cd01a6ccfe33daa68b67de50bd1ad Mon Sep 17 00:00:00 2001 From: Wyatt Barnes Date: Fri, 25 Feb 2022 00:46:36 -1000 Subject: [PATCH 128/132] Uncomment sendTransaction, signTransaction, and call --- packages/web3-eth/src/index.ts | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/packages/web3-eth/src/index.ts b/packages/web3-eth/src/index.ts index 8c9f1688398..6fbd1888a1e 100644 --- a/packages/web3-eth/src/index.ts +++ b/packages/web3-eth/src/index.ts @@ -15,7 +15,7 @@ import { Filter, } from 'web3-utils'; -import { BlockFormatted } from './types'; +import { BlockFormatted, Transaction, TransactionCall } from './types'; import * as rpcMethods from './rpc_methods'; import * as rpcMethodsWrappers from './rpc_method_wrappers'; import { Web3EthExecutionAPI } from './web3_eth_execution_api'; @@ -150,10 +150,9 @@ export default class Web3Eth extends Web3Context { return rpcMethodsWrappers.getTransactionCount(this, address, blockNumber, returnType); } - // TODO Needs to convert input to hex string - // public async sendTransaction(transaction: Transaction) { - // return rpcMethodsWrappers.sendTransaction(this, transaction); - // } + public async sendTransaction(transaction: Transaction) { + return rpcMethodsWrappers.sendTransaction(this, transaction); + } public async sendSignedTransaction(transaction: HexStringBytes) { return rpcMethods.sendRawTransaction(this.requestManager, transaction); @@ -165,19 +164,18 @@ export default class Web3Eth extends Web3Context { return rpcMethods.sign(this.requestManager, message, address); } - // TODO Needs to convert input to hex string - // public async signTransaction(transaction: Transaction) { - // return rpcMethodsWrappers.signTransaction(this, transaction); - // } + public async signTransaction(transaction: Transaction) { + return rpcMethodsWrappers.signTransaction(this, transaction); + } // TODO Decide what to do with transaction.to // https://github.com/ChainSafe/web3.js/pull/4525#issuecomment-982330076 - // public async call( - // transaction: Transaction & { to: Address }, - // blockNumber: BlockNumberOrTag = this.defaultBlock, - // ) { - // return rpcMethodsWrappers.call(this, transaction, blockNumber); - // } + public async call( + transaction: TransactionCall, + blockNumber: BlockNumberOrTag = this.defaultBlock, + ) { + return rpcMethodsWrappers.call(this, transaction, blockNumber); + } // TODO Missing param public async estimateGas( From ec4d18f2ffda95590967881cea53de6fd3f2e1ca Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Tue, 1 Mar 2022 20:10:45 +0500 Subject: [PATCH 129/132] :sparkles: Update estimate gas method to use web3-eth --- packages/web3-eth-contract/package.json | 3 +- packages/web3-eth-contract/src/contract.ts | 77 +++++++++++--------- packages/web3-eth-contract/src/types.ts | 20 +++-- packages/web3-eth/src/rpc_method_wrappers.ts | 3 +- 4 files changed, 60 insertions(+), 43 deletions(-) diff --git a/packages/web3-eth-contract/package.json b/packages/web3-eth-contract/package.json index 312f1aecdd6..e20076ed6cd 100644 --- a/packages/web3-eth-contract/package.json +++ b/packages/web3-eth-contract/package.json @@ -29,7 +29,8 @@ "web3-core": "4.0.0-alpha.0", "web3-eth-abi": "4.0.0-alpha.0", "web3-utils": "4.0.0-alpha.1", - "web3-validator": "0.1.0-alpha.0" + "web3-validator": "0.1.0-alpha.0", + "web3-eth": "4.0.0-alpha.1" }, "devDependencies": { "@humeris/espresso-shot": "^4.0.0", diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index 77486dad3da..804f68d3629 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -14,13 +14,14 @@ import { isAbiFunctionFragment, jsonInterfaceMethodToString, } from 'web3-eth-abi'; +import { estimateGas } from 'web3-eth/src/rpc_method_wrappers'; import { Address, BlockNumberOrTag, BlockTags, - hexToNumber, - toChecksumAddress, HexString, + toChecksumAddress, + ValidTypes, } from 'web3-utils'; import { validator } from 'web3-validator'; import { decodeMethodReturn, encodeEventABI, encodeMethodABI } from './encoding'; @@ -194,17 +195,20 @@ export class Contract // provider: this.currentProvider, // }); }, - estimateGas: async (options?: PayableCallOptions, block?: BlockNumberOrTag) => { + estimateGas: async ( + options?: PayableCallOptions, + returnType?: ReturnType, + ) => { const modifiedOptions = { ...options }; delete modifiedOptions.to; - return this._contractMethodEstimateGas( - abi as AbiFunctionFragment, - args, - modifiedOptions, - block, + return this._contractMethodEstimateGas({ + abi: abi as AbiFunctionFragment, + params: args, + returnType, + options: modifiedOptions, contractOptions, - ); + }); }, encodeABI: () => encodeMethodABI(abi as AbiFunctionFragment, args, data), }; @@ -299,8 +303,10 @@ export class Contract // TODO: Use `web3-eth-tx` package to return `PromiEvent` instead. send: async (options?: PayableCallOptions) => this._contractMethodSend(abi, params, options), - estimateGas: async (options?: PayableCallOptions, block?: BlockNumberOrTag) => - this._contractMethodEstimateGas(abi, params, options, block), + estimateGas: async ( + options?: PayableCallOptions, + returnType?: ReturnType, + ) => this._contractMethodEstimateGas({ abi, params, returnType, options }), encodeABI: () => encodeMethodABI(abi, params), } as unknown as PayableMethodObject< ContractMethod['Inputs'], @@ -314,8 +320,10 @@ export class Contract this._contractMethodCall(abi, params, options, block), send: async (options?: NonPayableCallOptions) => this._contractMethodSend(abi, params, options), - estimateGas: async (options?: NonPayableCallOptions, block?: BlockNumberOrTag) => - this._contractMethodEstimateGas(abi, params, options, block), + estimateGas: async ( + options?: NonPayableCallOptions, + returnType?: ReturnType, + ) => this._contractMethodEstimateGas({ abi, params, returnType, options }), encodeABI: () => encodeMethodABI(abi, params), } as unknown as NonPayableMethodObject< ContractMethod['Inputs'], @@ -371,27 +379,28 @@ export class Contract private async _contractMethodEstimateGas< Options extends PayableCallOptions | NonPayableCallOptions, - >( - abi: AbiFunctionFragment, - params: unknown[], - options?: Options, - block?: BlockNumberOrTag, - contractOptions?: ContractOptions, - ) { - return hexToNumber( - await this.requestManager.send({ - method: 'eth_estimateGas', - params: [ - getEstimateGasParams({ - abi, - params, - options, - contractOptions: contractOptions ?? this.options, - }), - block ?? BlockTags.LATEST, - ], - }), - ); + ReturnType extends ValidTypes = ValidTypes.HexString, + >({ + abi, + params, + returnType, + options, + contractOptions, + }: { + abi: AbiFunctionFragment; + params: unknown[]; + returnType?: ReturnType; + options?: Options; + contractOptions?: ContractOptions; + }) { + const tx = getEstimateGasParams({ + abi, + params, + options, + contractOptions: contractOptions ?? this.options, + }); + + return estimateGas(this, tx, BlockTags.LATEST, returnType); } // eslint-disable-next-line class-methods-use-this diff --git a/packages/web3-eth-contract/src/types.ts b/packages/web3-eth-contract/src/types.ts index 8b7eaf634ba..e49963392cb 100644 --- a/packages/web3-eth-contract/src/types.ts +++ b/packages/web3-eth-contract/src/types.ts @@ -1,7 +1,7 @@ import { EthExecutionAPI, PromiEvent, ReceiptInfo } from 'web3-common'; import { SupportedProviders } from 'web3-core'; import { ContractAbi } from 'web3-eth-abi'; -import { Address, BlockNumberOrTag, Bytes, Filter, HexString, Numbers, Uint } from 'web3-utils'; +import { Address, BlockNumberOrTag, Bytes, Filter, HexString, Uint, ValidTypes } from 'web3-utils'; export interface EventLog { event: string; @@ -43,14 +43,14 @@ export interface ContractInitOptions { export type TransactionReceipt = ReceiptInfo; export interface NonPayableCallOptions { - nonce?: Numbers; - chainId?: Numbers; + nonce?: string; + chainId?: string; from?: Address; to?: Address; data?: HexString; gas?: string; - maxPriorityFeePerGas?: Numbers; - maxFeePerGas?: Numbers; + maxPriorityFeePerGas?: string; + maxFeePerGas?: string; gasPrice?: string; } @@ -76,7 +76,10 @@ export interface NonPayableMethodObject error: Error; } >; - estimateGas(tx?: NonPayableCallOptions): Promise; + estimateGas( + options?: NonPayableCallOptions, + returnType?: ReturnType, + ): Promise; encodeABI(): string; } @@ -98,6 +101,9 @@ export interface PayableMethodObject { error: Error; } >; - estimateGas(tx?: PayableCallOptions): Promise; + estimateGas( + options?: PayableCallOptions, + returnType?: ReturnType, + ): Promise; encodeABI(): HexString; } diff --git a/packages/web3-eth/src/rpc_method_wrappers.ts b/packages/web3-eth/src/rpc_method_wrappers.ts index 11222add2b9..7d3ffba9aa2 100644 --- a/packages/web3-eth/src/rpc_method_wrappers.ts +++ b/packages/web3-eth/src/rpc_method_wrappers.ts @@ -488,7 +488,8 @@ export const call = async ( // TODO Missing param export async function estimateGas( - web3Context: Web3Context, + // The context can have different subscriptions + web3Context: Web3Context, transaction: Partial, blockNumber: BlockNumberOrTag = web3Context.defaultBlock, returnType?: ReturnType, From 5a311746d941c9df679956c4196c0bf4e1936071 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Wed, 2 Mar 2022 15:53:53 +0500 Subject: [PATCH 130/132] :art: Update contract mehtod send to use web3-eth utility functions --- CHANGELOG.md | 1 + .../web3-common/src/web3_event_emitter.ts | 12 ++ packages/web3-eth-contract/src/contract.ts | 37 +++--- packages/web3-eth-contract/src/types.ts | 35 +----- packages/web3-eth/src/rpc_method_wrappers.ts | 111 +++++++++++------- 5 files changed, 101 insertions(+), 95 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d18b8ecdad..706532ca04c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -357,3 +357,4 @@ Released with 1.0.0-beta.37 code base. 4. `recover` function's last param is boolean `hashed`, it is used to indicate if data provided is already hashed or not. By default this function will assume data is not hashed. 5. The `Wallet` no more supports address/number indexing. Have to use `wallet.get` instead. 6. `Wallet.create` function doesn't accepts `entropy` param +7. `contract.method.send()` will resolve to transaction receipt instead of `transactionHash`. User can use `receipt.transactionHash` instead. diff --git a/packages/web3-common/src/web3_event_emitter.ts b/packages/web3-common/src/web3_event_emitter.ts index 9fab7e82916..ffba425135c 100644 --- a/packages/web3-common/src/web3_event_emitter.ts +++ b/packages/web3-common/src/web3_event_emitter.ts @@ -31,4 +31,16 @@ export class Web3EventEmitter implements Web3Emitter public emit>(eventName: K, params: T[K]) { this._emitter.emit(eventName, params); } + + public listenerCount>(eventName: K) { + return this._emitter.listenerCount(eventName); + } + + public listeners>(eventName: K) { + return this._emitter.listeners(eventName); + } + + public eventNames() { + return this._emitter.eventNames(); + } } diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index 804f68d3629..8939e2fb4ca 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -14,7 +14,7 @@ import { isAbiFunctionFragment, jsonInterfaceMethodToString, } from 'web3-eth-abi'; -import { estimateGas } from 'web3-eth/src/rpc_method_wrappers'; +import { estimateGas, sendTransaction } from 'web3-eth/src/rpc_method_wrappers'; import { Address, BlockNumberOrTag, @@ -170,14 +170,19 @@ export class Contract const modifiedOptions = { ...options }; delete modifiedOptions.to; - const txHash = await this._contractMethodSend( + const promiEvent = this._contractMethodSend( abi as AbiFunctionFragment, args, modifiedOptions, contractOptions, ); - return txHash; + // eslint-disable-next-line no-void + void promiEvent.then(res => { + this._address = res.contractAddress; + }); + + return promiEvent; // TODO: Use eth-tx functions to // @@ -301,7 +306,7 @@ export class Contract call: async (options?: PayableCallOptions, block?: BlockNumberOrTag) => this._contractMethodCall(abi, params, options, block), // TODO: Use `web3-eth-tx` package to return `PromiEvent` instead. - send: async (options?: PayableCallOptions) => + send: (options?: PayableCallOptions) => this._contractMethodSend(abi, params, options), estimateGas: async ( options?: PayableCallOptions, @@ -318,7 +323,7 @@ export class Contract arguments: params, call: async (options?: NonPayableCallOptions, block?: BlockNumberOrTag) => this._contractMethodCall(abi, params, options, block), - send: async (options?: NonPayableCallOptions) => + send: (options?: NonPayableCallOptions) => this._contractMethodSend(abi, params, options), estimateGas: async ( options?: NonPayableCallOptions, @@ -355,26 +360,20 @@ export class Contract ); } - private async _contractMethodSend( + private _contractMethodSend( abi: AbiFunctionFragment, params: unknown[], options?: Options, contractOptions?: ContractOptions, ) { - return decodeMethodReturn( + const tx = getSendTxParams({ abi, - await this.requestManager.send({ - method: 'eth_sendTransaction', - params: [ - getSendTxParams({ - abi, - params, - options, - contractOptions: contractOptions ?? this.options, - }), - ], - }), - ); + params, + options, + contractOptions: contractOptions ?? this.options, + }); + + return sendTransaction(this, tx); } private async _contractMethodEstimateGas< diff --git a/packages/web3-eth-contract/src/types.ts b/packages/web3-eth-contract/src/types.ts index e49963392cb..22c4f20e9e6 100644 --- a/packages/web3-eth-contract/src/types.ts +++ b/packages/web3-eth-contract/src/types.ts @@ -1,6 +1,7 @@ -import { EthExecutionAPI, PromiEvent, ReceiptInfo } from 'web3-common'; +import { EthExecutionAPI, ReceiptInfo } from 'web3-common'; import { SupportedProviders } from 'web3-core'; import { ContractAbi } from 'web3-eth-abi'; +import { sendTransaction } from 'web3-eth/src/rpc_method_wrappers'; import { Address, BlockNumberOrTag, Bytes, Filter, HexString, Uint, ValidTypes } from 'web3-utils'; export interface EventLog { @@ -61,21 +62,7 @@ export interface PayableCallOptions extends NonPayableCallOptions { export interface NonPayableMethodObject { arguments: Inputs; call(tx?: NonPayableCallOptions, block?: BlockNumberOrTag): Promise; - send(tx?: NonPayableCallOptions): PromiEvent< - TransactionReceipt, - { - sending: object; - sent: object; - transactionHash: string; - receipt: TransactionReceipt; - confirmation: { - confirmations: number; - receipt: TransactionReceipt; - latestBlockHash: HexString; - }; - error: Error; - } - >; + send(tx?: NonPayableCallOptions): ReturnType; estimateGas( options?: NonPayableCallOptions, returnType?: ReturnType, @@ -86,21 +73,7 @@ export interface NonPayableMethodObject export interface PayableMethodObject { arguments: Inputs; call(tx?: PayableCallOptions, block?: BlockNumberOrTag): Promise; - send(tx?: PayableCallOptions): PromiEvent< - TransactionReceipt, - { - sending: object; - sent: object; - transactionHash: string; - receipt: TransactionReceipt; - confirmation: { - confirmations: number; - receipt: TransactionReceipt; - latestBlockHash: HexString; - }; - error: Error; - } - >; + send(tx?: PayableCallOptions): ReturnType; estimateGas( options?: PayableCallOptions, returnType?: ReturnType, diff --git a/packages/web3-eth/src/rpc_method_wrappers.ts b/packages/web3-eth/src/rpc_method_wrappers.ts index 7d3ffba9aa2..0108e866f2f 100644 --- a/packages/web3-eth/src/rpc_method_wrappers.ts +++ b/packages/web3-eth/src/rpc_method_wrappers.ts @@ -11,6 +11,8 @@ import { HexString, HexString32Bytes, HexStringBytes, + hexToNumber, + numberToHex, Uint, Uint256, ValidReturnTypes, @@ -111,7 +113,9 @@ export const getCode = async ( ) => rpcMethods.getCode(web3Context.requestManager, address, blockNumber); export async function getBlock( - web3Context: Web3Context, + // A context can have any subscriptions + // eslint-disable-next-line @typescript-eslint/no-explicit-any + web3Context: Web3Context, block: HexString32Bytes | BlockNumberOrTag = web3Context.defaultBlock, hydrated = false, returnType?: ReturnType, @@ -287,7 +291,9 @@ export async function getPendingTransactions, + // A context can have any subscriptions + // eslint-disable-next-line @typescript-eslint/no-explicit-any + web3Context: Web3Context, transactionHash: HexString32Bytes, ): Promise => new Promise(resolve => { @@ -315,7 +321,9 @@ const waitForTransactionReceipt = async ( function watchTransactionForConfirmations< PromiEventEventType extends SendTransactionEvents | SendSignedTransactionEvents, >( - web3Context: Web3Context, + // A context can have any subscriptions + // eslint-disable-next-line @typescript-eslint/no-explicit-any + web3Context: Web3Context, transactionPromiEvent: PromiEvent, transactionReceipt: ReceiptInfo, ) { @@ -347,7 +355,9 @@ function watchTransactionForConfirmations< const nextBlock = await getBlock( web3Context, // TODO - Refactor after input formatting is added to getBlock - (BigInt(transactionReceipt.blockNumber) + BigInt(confirmationNumber)).toString(16), + numberToHex( + BigInt(hexToNumber(transactionReceipt.blockNumber)) + BigInt(confirmationNumber), + ), false, ValidTypes.Number, ); @@ -363,54 +373,65 @@ function watchTransactionForConfirmations< }, web3Context.transactionConfirmationPollingInterval); } -export async function sendTransaction( - web3Context: Web3Context, +export function sendTransaction( + // caller can have different subscriptions + web3Context: Web3Context, transaction: Transaction, -) { +): PromiEvent { const formattedTransaction = formatTransaction(transaction, ValidTypes.HexString); - // TODO - Promise returned in function argument where a void return was expected - // eslint-disable-next-line @typescript-eslint/no-misused-promises - const promiEvent = new PromiEvent(async resolve => { - // TODO - Populate potentially missing gas fields - // if ( - // transaction.gasPrice === undefined && - // (transaction.maxPriorityFeePerGas === undefined || - // transaction.maxFeePerGas === undefined) - // ) { - // Determine transaction type and fill in required gas properties - // } - - promiEvent.emit('sending', formattedTransaction); - - // TODO - If an account is available in wallet, sign transaction and call sendRawTransaction - // https://github.com/ChainSafe/web3.js/blob/b32555cfeedde128c657dabbba201102f691f955/packages/web3-core-method/src/index.js#L720 - - const transactionHash = await rpcMethods.sendTransaction( - web3Context.requestManager, - formattedTransaction, - ); + const promiEvent = new PromiEvent(resolve => { + // eslint-disable-next-line @typescript-eslint/no-misused-promises + setImmediate(async () => { + // TODO - Populate potentially missing gas fields + // if ( + // transaction.gasPrice === undefined && + // (transaction.maxPriorityFeePerGas === undefined || + // transaction.maxFeePerGas === undefined) + // ) { + // Determine transaction type and fill in required gas properties + // } + + if (promiEvent.listenerCount('sending') > 0) { + promiEvent.emit('sending', formattedTransaction); + } - promiEvent.emit('sent', formattedTransaction); - promiEvent.emit('transactionHash', transactionHash); + // TODO - If an account is available in wallet, sign transaction and call sendRawTransaction + // https://github.com/ChainSafe/web3.js/blob/b32555cfeedde128c657dabbba201102f691f955/packages/web3-core-method/src/index.js#L720 - let transactionReceipt = await rpcMethods.getTransactionReceipt( - web3Context.requestManager, - transactionHash, - ); + const transactionHash = await rpcMethods.sendTransaction( + web3Context.requestManager, + formattedTransaction, + ); - // Transaction hasn't been included in a block yet - if (transactionReceipt === null) - transactionReceipt = await waitForTransactionReceipt(web3Context, transactionHash); + if (promiEvent.listenerCount('sent') > 0) { + promiEvent.emit('sent', formattedTransaction); + } - promiEvent.emit('receipt', transactionReceipt); - // TODO - Format receipt - resolve(transactionReceipt); + if (promiEvent.listenerCount('transactionHash') > 0) { + promiEvent.emit('transactionHash', transactionHash); + } - watchTransactionForConfirmations( - web3Context, - promiEvent, - transactionReceipt, - ); + let transactionReceipt = await rpcMethods.getTransactionReceipt( + web3Context.requestManager, + transactionHash, + ); + + // Transaction hasn't been included in a block yet + if (transactionReceipt === null) + transactionReceipt = await waitForTransactionReceipt(web3Context, transactionHash); + + promiEvent.emit('receipt', transactionReceipt); + // TODO - Format receipt + resolve(transactionReceipt); + + if (promiEvent.listenerCount('confirmation') > 0) { + watchTransactionForConfirmations( + web3Context, + promiEvent, + transactionReceipt, + ); + } + }); }); return promiEvent; From a479a7dbd5d39d58a4a2a2d2f4c038b773dfc046 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Wed, 2 Mar 2022 16:11:03 +0500 Subject: [PATCH 131/132] :art: Update contract method call to use web3-eth utilities --- packages/web3-eth-contract/src/contract.ts | 23 +++++++------------- packages/web3-eth-contract/src/utils.ts | 9 ++++---- packages/web3-eth/src/rpc_method_wrappers.ts | 9 ++++++-- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index 8939e2fb4ca..ed3798fae8c 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -14,7 +14,7 @@ import { isAbiFunctionFragment, jsonInterfaceMethodToString, } from 'web3-eth-abi'; -import { estimateGas, sendTransaction } from 'web3-eth/src/rpc_method_wrappers'; +import { estimateGas, sendTransaction, call } from 'web3-eth/src/rpc_method_wrappers'; import { Address, BlockNumberOrTag, @@ -343,21 +343,14 @@ export class Contract options?: Options, block?: BlockNumberOrTag, ) { - return decodeMethodReturn( + const tx = getEthTxCallParams({ abi, - await this.requestManager.send({ - method: 'eth_call', - params: [ - getEthTxCallParams({ - abi, - params, - options, - contractOptions: this.options, - }), - block ?? BlockTags.LATEST, - ], - }), - ); + params, + options, + contractOptions: this.options, + }); + + return decodeMethodReturn(abi, await call(this, tx, block)); } private _contractMethodSend( diff --git a/packages/web3-eth-contract/src/utils.ts b/packages/web3-eth-contract/src/utils.ts index 53f969f165a..e5bcc3faca7 100644 --- a/packages/web3-eth-contract/src/utils.ts +++ b/packages/web3-eth-contract/src/utils.ts @@ -1,6 +1,7 @@ -import { TransactionCall, TransactionWithSender } from 'web3-common'; +import { TransactionWithSender } from 'web3-common'; import { AbiFunctionFragment } from 'web3-eth-abi'; import { mergeDeep } from 'web3-utils'; +import { TransactionCall } from 'web3-eth/src/types'; import { encodeMethodABI } from './encoding'; import { Web3ContractError } from './errors'; import { NonPayableCallOptions, PayableCallOptions, ContractOptions } from './types'; @@ -15,7 +16,7 @@ export const getSendTxParams = ({ params: unknown[]; options?: PayableCallOptions | NonPayableCallOptions; contractOptions: ContractOptions; -}): TransactionWithSender & { data: string } => { +}): TransactionCall => { if (!options?.to && !contractOptions.address) { throw new Web3ContractError('Contract address not specified'); } @@ -33,7 +34,7 @@ export const getSendTxParams = ({ data: contractOptions.data, }, options as unknown as Record, - ) as unknown as TransactionWithSender & { data: string }; + ) as unknown as TransactionCall; if (!txParams.data) { txParams = { @@ -114,5 +115,5 @@ export const getEstimateGasParams = ({ }; } - return txParams; + return txParams as TransactionWithSender; }; diff --git a/packages/web3-eth/src/rpc_method_wrappers.ts b/packages/web3-eth/src/rpc_method_wrappers.ts index 0108e866f2f..a99937c456c 100644 --- a/packages/web3-eth/src/rpc_method_wrappers.ts +++ b/packages/web3-eth/src/rpc_method_wrappers.ts @@ -18,6 +18,7 @@ import { ValidReturnTypes, ValidTypes, } from 'web3-utils'; +import { isBlockTag } from 'web3-validator'; import { isHexString32Bytes } from 'web3-validator'; import { convertibleBlockProperties, @@ -497,14 +498,18 @@ export const signTransaction = async ( // TODO Decide what to do with transaction.to // https://github.com/ChainSafe/web3.js/pull/4525#issuecomment-982330076 export const call = async ( - web3Context: Web3Context, + // A context can have any subscriptions + // eslint-disable-next-line @typescript-eslint/no-explicit-any + web3Context: Web3Context, transaction: TransactionCall, blockNumber: BlockNumberOrTag = web3Context.defaultBlock, ) => rpcMethods.call( web3Context.requestManager, formatTransaction(transaction, ValidTypes.HexString) as TransactionCall, - convertToValidType(blockNumber, ValidTypes.HexString) as HexString, + isBlockTag(blockNumber) + ? blockNumber + : (convertToValidType(blockNumber, ValidTypes.HexString) as HexString), ); // TODO Missing param From a5eedc3f6a0f2f7fd5092be46b97a31472f810ed Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Fri, 4 Mar 2022 15:46:09 +0500 Subject: [PATCH 132/132] :art: Fix code introduced in merge conflicts --- packages/web3-eth-contract/src/contract.ts | 18 --------------- packages/web3-eth-contract/src/types.ts | 8 +++---- packages/web3-eth/src/rpc_method_wrappers.ts | 8 ++++--- yarn.lock | 23 +++++++------------- 4 files changed, 17 insertions(+), 40 deletions(-) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index ed3798fae8c..e8da1bc5bcc 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -165,7 +165,6 @@ export class Contract return { arguments: args, - // TODO: Use `web3-eth-tx` package to return `PromiEvent` instead. send: async (options?: PayableCallOptions) => { const modifiedOptions = { ...options }; delete modifiedOptions.to; @@ -183,22 +182,6 @@ export class Contract }); return promiEvent; - - // TODO: Use eth-tx functions to - // - // 1. Get the transaction receipt from the above txHash - // 2. Extract the contract address from the receipt - // 3. Get the code from eth_getCode for the contract address - // 4. Return the contract instance with the new address and the code - // - // return new Contract(this._jsonInterface, contractAddress as HexString, { - // gas: this.options.gas, - // gasPrice: this.options.gasPrice, - // gasLimit: this.options.gasLimit, - // from: this.options.from, - // data: this.options.data, - // provider: this.currentProvider, - // }); }, estimateGas: async ( options?: PayableCallOptions, @@ -305,7 +288,6 @@ export class Contract arguments: params, call: async (options?: PayableCallOptions, block?: BlockNumberOrTag) => this._contractMethodCall(abi, params, options, block), - // TODO: Use `web3-eth-tx` package to return `PromiEvent` instead. send: (options?: PayableCallOptions) => this._contractMethodSend(abi, params, options), estimateGas: async ( diff --git a/packages/web3-eth-contract/src/types.ts b/packages/web3-eth-contract/src/types.ts index 22c4f20e9e6..82eb56d6286 100644 --- a/packages/web3-eth-contract/src/types.ts +++ b/packages/web3-eth-contract/src/types.ts @@ -44,14 +44,14 @@ export interface ContractInitOptions { export type TransactionReceipt = ReceiptInfo; export interface NonPayableCallOptions { - nonce?: string; - chainId?: string; + nonce?: HexString; + chainId?: HexString; from?: Address; to?: Address; data?: HexString; gas?: string; - maxPriorityFeePerGas?: string; - maxFeePerGas?: string; + maxPriorityFeePerGas?: HexString; + maxFeePerGas?: HexString; gasPrice?: string; } diff --git a/packages/web3-eth/src/rpc_method_wrappers.ts b/packages/web3-eth/src/rpc_method_wrappers.ts index e32d206ff53..4b881328716 100644 --- a/packages/web3-eth/src/rpc_method_wrappers.ts +++ b/packages/web3-eth/src/rpc_method_wrappers.ts @@ -382,7 +382,7 @@ function watchTransactionForConfirmations< latestBlockHash: nextBlock.hash, }); } - }, web3Context.transactionConfirmationPollingInterval); + }, web3Context.transactionReceiptPollingInterval ?? web3Context.transactionPollingInterval); } export function sendTransaction( @@ -514,15 +514,17 @@ export const call = async ( web3Context: Web3Context, transaction: TransactionCall, blockNumber: BlockNumberOrTag = web3Context.defaultBlock, -) => +) => { validator.validate(['address'], [transaction.to]); - rpcMethods.call( + + return rpcMethods.call( web3Context.requestManager, formatTransaction(transaction, ValidTypes.HexString) as TransactionCall, isBlockTag(blockNumber) ? blockNumber : (convertToValidType(blockNumber, ValidTypes.HexString) as HexString), ); +}; // TODO Missing param export async function estimateGas( diff --git a/yarn.lock b/yarn.lock index 170a5197f13..772f0b47b7f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3425,10 +3425,10 @@ ethereum-cryptography@^0.2.1: "@noble/secp256k1" "^1.3.3" micro-base "^0.10.0" -ethereumjs-util@^7.0.10, ethereumjs-util@^7.1.4: - version "7.1.4" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.4.tgz#a6885bcdd92045b06f596c7626c3e89ab3312458" - integrity sha512-p6KmuPCX4mZIqsQzXfmSx9Y0l2hqf+VkAiwSisW3UKUFdk8ZkAt+AYaor83z2nSi6CU2zSsXMlD80hAbNEGM0A== +ethereumjs-util@^7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz#b55d7b64dde3e3e45749e4c41288238edec32d23" + integrity sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw== dependencies: "@types/bn.js" "^5.1.0" bn.js "^5.1.2" @@ -3436,10 +3436,10 @@ ethereumjs-util@^7.0.10, ethereumjs-util@^7.1.4: ethereum-cryptography "^0.1.3" rlp "^2.2.4" -ethereumjs-util@^7.1.3: - version "7.1.3" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz#b55d7b64dde3e3e45749e4c41288238edec32d23" - integrity sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw== +ethereumjs-util@^7.1.4: + version "7.1.4" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.4.tgz#a6885bcdd92045b06f596c7626c3e89ab3312458" + integrity sha512-p6KmuPCX4mZIqsQzXfmSx9Y0l2hqf+VkAiwSisW3UKUFdk8ZkAt+AYaor83z2nSi6CU2zSsXMlD80hAbNEGM0A== dependencies: "@types/bn.js" "^5.1.0" bn.js "^5.1.2" @@ -7565,13 +7565,6 @@ wcwidth@^1.0.0: dependencies: defaults "^1.0.3" -web3-utils@4.0.0-alpha.0: - version "4.0.0-alpha.0" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-4.0.0-alpha.0.tgz#ca71c3601c33e3a733d5221ebc4ab57c790f6c58" - integrity sha512-mywnauBZR3Xi7e7RYLUQN9EN5x8jylEz8Qb/fZAJnJtzSEcgXEZ+kuTHIyIJxpDKWoHwlpqnZL4WGsuG+4NiCA== - dependencies: - ethereumjs-util "^7.0.10" - webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"