diff --git a/CHANGELOG.md b/CHANGELOG.md index 6edd15446e5..e4a9943a1e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2702,3 +2702,24 @@ If there are any bugs, improvements, optimizations or any new feature proposal f - The callback function provided to the static `Web3.onNewProviderDiscovered` function expects a parameter of type `EIP6963ProvidersMapUpdateEvent` as opposed to `EIP6963AnnounceProviderEvent`. (#7242) ## [Unreleased] + +### Added + +#### web3-core + +- Adds a new property (`customTransactionSchema`) to `Web3ConfigOptions` +- Adds a new property (`config`) to `Web3RequestManager` + +#### web3-eth + +- Adds the same `{transactionSchema?: ValidationSchemaInput}` that exists in `formatTransaction` to `validateTransactionForSigning` + +### Changed + +#### web3-eth + +- Forwards the new `web3Context.config.customTransactionSchema` to `formatTransaction` + +#### web3-eth-personal + +- Forwards the new `web3Context.config.customTransactionSchema` to `formatTransaction` diff --git a/docs/docs/guides/web3_config/index.md b/docs/docs/guides/web3_config/index.md index 42561aedcbc..32f645a465a 100644 --- a/docs/docs/guides/web3_config/index.md +++ b/docs/docs/guides/web3_config/index.md @@ -28,6 +28,7 @@ There is list of configuration params that can be set for modifying behavior of - [defaultCommon](/guides/web3_config/#defaultcommon) - [defaultTransactionType](/guides/web3_config/#defaulttransactiontype) - [defaultMaxPriorityFeePerGas](/guides/web3_config/#defaultmaxpriorityfeepergas) +- [customTransactionSchema](/guides/web3_config/#customTransactionSchema) - [defaultReturnFormat](/guides/web3_config/#defaultreturnformat) ## Global level Config @@ -411,6 +412,9 @@ The `defaultMaxPriorityFeePerGas` option is used to set the [`defaultMaxPriority The default value of `defaultMaxPriorityFeePerGas` is 2500000000 (2.5gwei) in hexstring format. +### [customTransactionSchema](/api/web3-core/class/Web3Config#customTransactionSchema) +The `customTransactionSchema` option is used to allow [`formatTransaction`](/api/web3-eth/function/formatTransaction) to accept a custom schema to validate transactions. A use-case could be: your chain has an extra field in its transactions and you want to write a plugin that makes sending these transactions easier. + ### [defaultReturnFormat](/api/web3-core/class/Web3Config#defaultReturnFormat) The `defaultReturnFormat` option allows users to specify the format in which certain types of data should be returned by default. It is a configuration parameter that can be set at the global level and affects how data is returned across the entire library. ```ts diff --git a/packages/web3-core/CHANGELOG.md b/packages/web3-core/CHANGELOG.md index 18e3e0bf08a..ca126e01d03 100644 --- a/packages/web3-core/CHANGELOG.md +++ b/packages/web3-core/CHANGELOG.md @@ -234,3 +234,8 @@ Documentation: - `setConfig()` fix for `setMaxListenerWarningThreshold` fix (#5079) ## [Unreleased] + +### Added + +- Adds a new property (`customTransactionSchema`) to `Web3ConfigOptions` +- Adds a new property (`config`) to `Web3RequestManager` diff --git a/packages/web3-core/src/types.ts b/packages/web3-core/src/types.ts index b2b655b351a..b6b7d402584 100644 --- a/packages/web3-core/src/types.ts +++ b/packages/web3-core/src/types.ts @@ -23,6 +23,7 @@ import { Web3APIMethod, Web3APIReturnType, } from 'web3-types'; +import { Schema } from 'web3-validator'; export type TransactionTypeParser = (transaction: Transaction) => HexString | undefined; @@ -50,3 +51,8 @@ export interface RequestManagerMiddleware { options?: { [key: string]: unknown }, ): Promise>; } + +export type CustomTransactionSchema = { + type: string; + properties: Record; +}; diff --git a/packages/web3-core/src/web3_config.ts b/packages/web3-core/src/web3_config.ts index f617756ad12..ee397ea9daf 100644 --- a/packages/web3-core/src/web3_config.ts +++ b/packages/web3-core/src/web3_config.ts @@ -25,7 +25,7 @@ import { } from 'web3-types'; import { ConfigHardforkMismatchError, ConfigChainMismatchError } from 'web3-errors'; import { isNullish, toHex } from 'web3-utils'; -import { TransactionTypeParser } from './types.js'; +import { CustomTransactionSchema, TransactionTypeParser } from './types.js'; // eslint-disable-next-line import/no-cycle import { TransactionBuilder } from './web3_context.js'; import { Web3EventEmitter } from './web3_event_emitter.js'; @@ -59,6 +59,7 @@ export interface Web3ConfigOptions { }; transactionBuilder?: TransactionBuilder; transactionTypeParser?: TransactionTypeParser; + customTransactionSchema?: CustomTransactionSchema; defaultReturnFormat: DataFormat; } @@ -101,6 +102,7 @@ export abstract class Web3Config }, transactionBuilder: undefined, transactionTypeParser: undefined, + customTransactionSchema: undefined, defaultReturnFormat: DEFAULT_RETURN_FORMAT, }; @@ -520,6 +522,15 @@ export abstract class Web3Config this.config.transactionTypeParser = val; } + public get customTransactionSchema(): CustomTransactionSchema | undefined { + return this.config.customTransactionSchema; + } + + public set customTransactionSchema(schema: CustomTransactionSchema | undefined) { + this._triggerConfigChange('customTransactionSchema', schema); + this.config.customTransactionSchema = schema; + } + private _triggerConfigChange( config: K, newValue: Web3ConfigOptions[K], diff --git a/packages/web3-core/test/unit/__snapshots__/web3_context.test.ts.snap b/packages/web3-core/test/unit/__snapshots__/web3_context.test.ts.snap index e01ba14a467..7d280405bfb 100644 --- a/packages/web3-core/test/unit/__snapshots__/web3_context.test.ts.snap +++ b/packages/web3-core/test/unit/__snapshots__/web3_context.test.ts.snap @@ -6,6 +6,7 @@ exports[`Web3Context getContextObject should return correct context object 1`] = "config": { "blockHeaderTimeout": 10, "contractDataInputFill": "data", + "customTransactionSchema": undefined, "defaultAccount": undefined, "defaultBlock": "latest", "defaultChain": "mainnet", diff --git a/packages/web3-core/test/unit/web3_config.test.ts b/packages/web3-core/test/unit/web3_config.test.ts index bd250d6386a..7238c1fcb33 100644 --- a/packages/web3-core/test/unit/web3_config.test.ts +++ b/packages/web3-core/test/unit/web3_config.test.ts @@ -49,6 +49,7 @@ const defaultConfig = { defaultReturnFormat: DEFAULT_RETURN_FORMAT, transactionBuilder: undefined, transactionTypeParser: undefined, + customTransactionSchema: undefined, }; const setValue = { string: 'newValue', diff --git a/packages/web3-eth-personal/CHANGELOG.md b/packages/web3-eth-personal/CHANGELOG.md index 33f479b4ef5..abc79b58850 100644 --- a/packages/web3-eth-personal/CHANGELOG.md +++ b/packages/web3-eth-personal/CHANGELOG.md @@ -148,3 +148,7 @@ Documentation: - Dependencies updated ## [Unreleased] + +### Changed + +- Forwards the new `web3Context.config.customTransactionSchema` to `formatTransaction` diff --git a/packages/web3-eth-personal/src/personal.ts b/packages/web3-eth-personal/src/personal.ts index db8d2656703..012a0738803 100644 --- a/packages/web3-eth-personal/src/personal.ts +++ b/packages/web3-eth-personal/src/personal.ts @@ -159,7 +159,7 @@ export class Personal extends Web3Context { * ``` */ public async sendTransaction(tx: Transaction, passphrase: string) { - return rpcWrappers.sendTransaction(this.requestManager, tx, passphrase); + return rpcWrappers.sendTransaction(this.requestManager, tx, passphrase, this.config); } /** * Signs a transaction. This account needs to be unlocked. @@ -204,7 +204,7 @@ export class Personal extends Web3Context { * ``` */ public async signTransaction(tx: Transaction, passphrase: string) { - return rpcWrappers.signTransaction(this.requestManager, tx, passphrase); + return rpcWrappers.signTransaction(this.requestManager, tx, passphrase, this.config); } /** * Calculates an Ethereum specific signature with: diff --git a/packages/web3-eth-personal/src/rpc_method_wrappers.ts b/packages/web3-eth-personal/src/rpc_method_wrappers.ts index 51491714881..451b15074d9 100644 --- a/packages/web3-eth-personal/src/rpc_method_wrappers.ts +++ b/packages/web3-eth-personal/src/rpc_method_wrappers.ts @@ -14,7 +14,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with web3.js. If not, see . */ -import { Web3RequestManager } from 'web3-core'; +import { Web3RequestManager, Web3ConfigOptions } from 'web3-core'; import { toChecksumAddress, utf8ToHex } from 'web3-utils'; import { formatTransaction } from 'web3-eth'; import { Address, EthPersonalAPI, ETH_DATA_FORMAT, HexString, Transaction } from 'web3-types'; @@ -72,8 +72,11 @@ export const sendTransaction = async ( requestManager: Web3RequestManager, tx: Transaction, passphrase: string, + config?: Web3ConfigOptions, ) => { - const formattedTx = formatTransaction(tx, ETH_DATA_FORMAT); + const formattedTx = formatTransaction(tx, ETH_DATA_FORMAT, { + transactionSchema: config?.customTransactionSchema, + }); return personalRpcMethods.sendTransaction(requestManager, formattedTx, passphrase); }; @@ -82,8 +85,11 @@ export const signTransaction = async ( requestManager: Web3RequestManager, tx: Transaction, passphrase: string, + config?: Web3ConfigOptions, ) => { - const formattedTx = formatTransaction(tx, ETH_DATA_FORMAT); + const formattedTx = formatTransaction(tx, ETH_DATA_FORMAT, { + transactionSchema: config?.customTransactionSchema, + }); return personalRpcMethods.signTransaction(requestManager, formattedTx, passphrase); }; diff --git a/packages/web3-eth-personal/test/unit/eth_personal.test.ts b/packages/web3-eth-personal/test/unit/eth_personal.test.ts index fc2d545da10..45104d82d2d 100644 --- a/packages/web3-eth-personal/test/unit/eth_personal.test.ts +++ b/packages/web3-eth-personal/test/unit/eth_personal.test.ts @@ -185,7 +185,11 @@ describe('Personal', () => { await personal.sendTransaction(tx, 'password'); expect(eth.formatTransaction).toHaveBeenCalledTimes(1); - expect(eth.formatTransaction).toHaveBeenCalledWith(tx, ETH_DATA_FORMAT); + expect(eth.formatTransaction).toHaveBeenCalledWith( + tx, + ETH_DATA_FORMAT, + expect.anything(), + ); }); }); @@ -215,7 +219,11 @@ describe('Personal', () => { await personal.signTransaction(tx, 'password'); expect(eth.formatTransaction).toHaveBeenCalledTimes(1); - expect(eth.formatTransaction).toHaveBeenCalledWith(tx, ETH_DATA_FORMAT); + expect(eth.formatTransaction).toHaveBeenCalledWith( + tx, + ETH_DATA_FORMAT, + expect.anything(), + ); }); }); diff --git a/packages/web3-eth/CHANGELOG.md b/packages/web3-eth/CHANGELOG.md index 9005985b2b2..7d1470f593d 100644 --- a/packages/web3-eth/CHANGELOG.md +++ b/packages/web3-eth/CHANGELOG.md @@ -270,3 +270,11 @@ Documentation: - Change method `getTransactionReceipt` to not be casted as `TransactionReceipt` to give proper return type (#7159) ## [Unreleased] + +### Changed + +- Forwards the new `web3Context.config.customTransactionSchema` to `formatTransaction` + +### Added + +- Adds the same `{transactionSchema?: ValidationSchemaInput}` that exists in `formatTransaction` to `validateTransactionForSigning` diff --git a/packages/web3-eth/src/rpc_method_wrappers.ts b/packages/web3-eth/src/rpc_method_wrappers.ts index e5ffe9baf64..9931c56364f 100644 --- a/packages/web3-eth/src/rpc_method_wrappers.ts +++ b/packages/web3-eth/src/rpc_method_wrappers.ts @@ -429,6 +429,7 @@ export async function getTransaction( return isNullish(response) ? response : formatTransaction(response, returnFormat, { + transactionSchema: web3Context.config.customTransactionSchema, fillInputAndData: true, }); } @@ -448,6 +449,7 @@ export async function getPendingTransactions( transaction as unknown as Transaction, returnFormat ?? web3Context.defaultReturnFormat, { + transactionSchema: web3Context.config.customTransactionSchema, fillInputAndData: true, }, ), @@ -488,6 +490,7 @@ export async function getTransactionFromBlock( return isNullish(response) ? response : formatTransaction(response, returnFormat ?? web3Context.defaultReturnFormat, { + transactionSchema: web3Context.config.customTransactionSchema, fillInputAndData: true, }); } @@ -606,6 +609,9 @@ export function sendTransaction< to: getTransactionFromOrToAttr('to', web3Context, transaction), }, ETH_DATA_FORMAT, + { + transactionSchema: web3Context.config.customTransactionSchema, + }, ); try { @@ -847,7 +853,9 @@ export async function signTransaction( ) { const response = await ethRpcMethods.signTransaction( web3Context.requestManager, - formatTransaction(transaction, ETH_DATA_FORMAT), + formatTransaction(transaction, ETH_DATA_FORMAT, { + transactionSchema: web3Context.config.customTransactionSchema, + }), ); // Some clients only return the encoded signed transaction (e.g. Ganache) // while clients such as Geth return the desired SignedTransactionInfoAPI object @@ -862,6 +870,7 @@ export async function signTransaction( returnFormat, ), tx: formatTransaction((response as SignedTransactionInfoAPI).tx, returnFormat, { + transactionSchema: web3Context.config.customTransactionSchema, fillInputAndData: true, }), }; @@ -885,7 +894,9 @@ export async function call( const response = await ethRpcMethods.call( web3Context.requestManager, - formatTransaction(transaction, ETH_DATA_FORMAT), + formatTransaction(transaction, ETH_DATA_FORMAT, { + transactionSchema: web3Context.config.customTransactionSchema, + }), blockNumberFormatted, ); @@ -903,7 +914,9 @@ export async function estimateGas( blockNumber: BlockNumberOrTag = web3Context.defaultBlock, returnFormat: ReturnFormat, ) { - const transactionFormatted = formatTransaction(transaction, ETH_DATA_FORMAT); + const transactionFormatted = formatTransaction(transaction, ETH_DATA_FORMAT, { + transactionSchema: web3Context.config.customTransactionSchema, + }); const blockNumberFormatted = isBlockTag(blockNumber as string) ? (blockNumber as BlockTag) : format({ format: 'uint' }, blockNumber as Numbers, ETH_DATA_FORMAT); @@ -1074,7 +1087,9 @@ export async function createAccessList( const response = (await ethRpcMethods.createAccessList( web3Context.requestManager, - formatTransaction(transaction, ETH_DATA_FORMAT), + formatTransaction(transaction, ETH_DATA_FORMAT, { + transactionSchema: web3Context.config.customTransactionSchema, + }), blockNumberFormatted, )) as unknown as AccessListResult; diff --git a/packages/web3-eth/src/types.ts b/packages/web3-eth/src/types.ts index 9f9de0ec14a..cc3c86cd2ee 100644 --- a/packages/web3-eth/src/types.ts +++ b/packages/web3-eth/src/types.ts @@ -37,6 +37,7 @@ import { TransactionWithFromLocalWalletIndex, TransactionWithToLocalWalletIndex, } from 'web3-types'; +import { Schema } from 'web3-validator'; export type InternalTransaction = FormatType; @@ -105,3 +106,8 @@ export interface TransactionMiddleware { options?: { [key: string]: unknown }, ): Promise; } + +export type CustomTransactionSchema = { + type: string; + properties: Record; +}; diff --git a/packages/web3-eth/src/utils/decode_signed_transaction.ts b/packages/web3-eth/src/utils/decode_signed_transaction.ts index 943ea188e2c..6a313f9b775 100644 --- a/packages/web3-eth/src/utils/decode_signed_transaction.ts +++ b/packages/web3-eth/src/utils/decode_signed_transaction.ts @@ -24,6 +24,7 @@ import { bytesToHex, format, hexToBytes, keccak256 } from 'web3-utils'; import { TransactionFactory } from 'web3-eth-accounts'; import { detectRawTransactionType } from './detect_transaction_type.js'; import { formatTransaction } from './format_transaction.js'; +import { type CustomTransactionSchema } from '../types.js'; /** * Decodes an [RLP](https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp/#top) encoded transaction. @@ -35,7 +36,9 @@ import { formatTransaction } from './format_transaction.js'; export function decodeSignedTransaction( encodedSignedTransaction: HexStringBytes, returnFormat: ReturnFormat, - options: { fillInputAndData?: boolean } = { fillInputAndData: false }, + options: { fillInputAndData?: boolean; transactionSchema?: CustomTransactionSchema } = { + fillInputAndData: false, + }, ): SignedTransactionInfoAPI { return { raw: format({ format: 'bytes' }, encodedSignedTransaction, returnFormat), @@ -48,7 +51,10 @@ export function decodeSignedTransaction( type: detectRawTransactionType(hexToBytes(encodedSignedTransaction)), } as TransactionSignedAPI, returnFormat, - { fillInputAndData: options.fillInputAndData }, + { + fillInputAndData: options.fillInputAndData, + transactionSchema: options.transactionSchema, + }, ), }; } diff --git a/packages/web3-eth/src/utils/format_transaction.ts b/packages/web3-eth/src/utils/format_transaction.ts index 5333254db60..53d29659bbe 100644 --- a/packages/web3-eth/src/utils/format_transaction.ts +++ b/packages/web3-eth/src/utils/format_transaction.ts @@ -20,7 +20,8 @@ import { isNullish, ValidationSchemaInput } from 'web3-validator'; import { mergeDeep, format, bytesToHex, toHex } from 'web3-utils'; import { TransactionDataAndInputError } from 'web3-errors'; -import { transactionInfoSchema, transactionSchema } from '../schemas.js'; +import { transactionInfoSchema } from '../schemas.js'; +import { type CustomTransactionSchema } from '../types.js'; export function formatTransaction< ReturnFormat extends DataFormat = typeof DEFAULT_RETURN_FORMAT, @@ -29,7 +30,7 @@ export function formatTransaction< transaction: TransactionType, returnFormat: ReturnFormat = DEFAULT_RETURN_FORMAT as ReturnFormat, options: { - transactionSchema?: ValidationSchemaInput | typeof transactionSchema; + transactionSchema?: ValidationSchemaInput | CustomTransactionSchema | undefined; fillInputAndData?: boolean; } = { transactionSchema: transactionInfoSchema, diff --git a/packages/web3-eth/src/utils/prepare_transaction_for_signing.ts b/packages/web3-eth/src/utils/prepare_transaction_for_signing.ts index 5213e66c778..cd70e1e265c 100644 --- a/packages/web3-eth/src/utils/prepare_transaction_for_signing.ts +++ b/packages/web3-eth/src/utils/prepare_transaction_for_signing.ts @@ -134,12 +134,16 @@ export const prepareTransactionForSigning = async ( fillGasPrice, fillGasLimit, })) as unknown as PopulatedUnsignedTransaction; - const formattedTransaction = formatTransaction( - populatedTransaction, - ETH_DATA_FORMAT, - ) as unknown as FormatType; + const formattedTransaction = formatTransaction(populatedTransaction, ETH_DATA_FORMAT, { + transactionSchema: web3Context.config.customTransactionSchema, + }) as unknown as FormatType; + validateTransactionForSigning( formattedTransaction as unknown as FormatType, + undefined, + { + transactionSchema: web3Context.config.customTransactionSchema, + }, ); return TransactionFactory.fromTxData( diff --git a/packages/web3-eth/src/validation.ts b/packages/web3-eth/src/validation.ts index a818cc66c10..b318e16dd41 100644 --- a/packages/web3-eth/src/validation.ts +++ b/packages/web3-eth/src/validation.ts @@ -27,7 +27,13 @@ import { TransactionWithSenderAPI, ETH_DATA_FORMAT, } from 'web3-types'; -import { isAddress, isHexStrict, isHexString32Bytes, isNullish, isUInt } from 'web3-validator'; +import { + isAddress, + isHexStrict, + isHexString32Bytes, + isNullish, + isUInt, +} from 'web3-validator'; import { ChainMismatchError, HardforkMismatchError, @@ -48,7 +54,7 @@ import { UnsupportedFeeMarketError, } from 'web3-errors'; import { formatTransaction } from './utils/format_transaction.js'; -import { InternalTransaction } from './types.js'; +import { CustomTransactionSchema, InternalTransaction } from './types.js'; export function isBaseTransaction(value: BaseTransactionAPI): boolean { if (!isNullish(value.to) && !isAddress(value.to)) return false; @@ -282,6 +288,9 @@ export const validateGas = (transaction: InternalTransaction) => { export const validateTransactionForSigning = ( transaction: InternalTransaction, overrideMethod?: (transaction: InternalTransaction) => void, + options: { + transactionSchema?: CustomTransactionSchema; + } = { transactionSchema: undefined }, ) => { if (!isNullish(overrideMethod)) { overrideMethod(transaction); @@ -296,7 +305,9 @@ export const validateTransactionForSigning = ( validateBaseChain(transaction); validateHardfork(transaction); - const formattedTransaction = formatTransaction(transaction as Transaction, ETH_DATA_FORMAT); + const formattedTransaction = formatTransaction(transaction as Transaction, ETH_DATA_FORMAT, { + transactionSchema: options.transactionSchema, + }); validateGas(formattedTransaction); if ( diff --git a/packages/web3-eth/test/fixtures/format_transaction.ts b/packages/web3-eth/test/fixtures/format_transaction.ts index dc91dc7c823..6ab3fa0a9d2 100644 --- a/packages/web3-eth/test/fixtures/format_transaction.ts +++ b/packages/web3-eth/test/fixtures/format_transaction.ts @@ -210,6 +210,40 @@ export const numbersAsBigIntTransaction: FormatType< s: '0x7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0', }; +export type CustomFieldTransaction = Transaction & { feeCurrency: `0x${string}` }; +export const customFieldTransaction: FormatType< + CustomFieldTransaction, + { number: FMT_NUMBER.BIGINT; bytes: typeof DEFAULT_RETURN_FORMAT.bytes } +> = { + from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', + to: '0x3535353535353535353535353535353535353535', + value: BigInt(100000000000), + gas: BigInt(21000), + gasPrice: BigInt(20000000000), + type: BigInt(0), + maxFeePerGas: BigInt(78000000000), + maxPriorityFeePerGas: BigInt(1230000000), + data: '0x', + 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', + feeCurrency: '0x4242424242424242424242424242424242424242', +}; + const dummyTransaction: Transaction = { from: '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', to: '0x3535353535353535353535353535353535353535', diff --git a/packages/web3-eth/test/unit/format_transaction.test.ts b/packages/web3-eth/test/unit/format_transaction.test.ts index 9ce83aaa941..d3c86c077bd 100644 --- a/packages/web3-eth/test/unit/format_transaction.test.ts +++ b/packages/web3-eth/test/unit/format_transaction.test.ts @@ -25,8 +25,11 @@ import { numbersAsStringTransaction, numbersAsNumberTransaction, bytesAsUint8ArrayTransaction, + customFieldTransaction, + CustomFieldTransaction, } from '../fixtures/format_transaction'; import { objectBigintToString } from '../fixtures/system_test_utils'; +import { transactionSchema } from '../../src'; const transactionsDataForNumberTypes: Record> = { [FMT_NUMBER.BIGINT]: numbersAsBigIntTransaction, @@ -116,4 +119,27 @@ describe('formatTransaction', () => { }), ); }); + + it('Accepts a custom schema', () => { + expect( + formatTransaction( + customFieldTransaction, + ).feeCurrency, + ).toBeUndefined(); + expect( + formatTransaction( + customFieldTransaction, + undefined, + { + transactionSchema: { + type: 'object', + properties: { + ...transactionSchema.properties, + feeCurrency: { format: 'address' }, + }, + }, + }, + ).feeCurrency, + ).toBeDefined(); + }); }); diff --git a/packages/web3-eth/test/unit/rpc_method_wrappers/get_transaction.test.ts b/packages/web3-eth/test/unit/rpc_method_wrappers/get_transaction.test.ts index 225a9e106ef..cb1315c56b1 100644 --- a/packages/web3-eth/test/unit/rpc_method_wrappers/get_transaction.test.ts +++ b/packages/web3-eth/test/unit/rpc_method_wrappers/get_transaction.test.ts @@ -21,7 +21,11 @@ import { ethRpcMethods } from 'web3-rpc-methods'; import { getTransaction } from '../../../src/rpc_method_wrappers'; import { mockRpcResponse, testData } from './fixtures/get_transaction'; -import { formatTransaction, transactionInfoSchema } from '../../../src'; +import { + type CustomTransactionSchema, + formatTransaction, + transactionInfoSchema, +} from '../../../src'; jest.mock('web3-rpc-methods'); @@ -57,7 +61,7 @@ describe('getTransaction', () => { const expectedFormattedResult = formatTransaction( mockRpcResponse, expectedReturnFormat, - { transactionSchema: transactionInfoSchema }, + { transactionSchema: transactionInfoSchema as CustomTransactionSchema }, ); (ethRpcMethods.getTransactionByHash as jest.Mock).mockResolvedValueOnce( mockRpcResponse,