diff --git a/CHANGELOG.md b/CHANGELOG.md index d9abf6019de..c279326d17a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2754,6 +2754,10 @@ If there are any bugs, improvements, optimizations or any new feature proposal f - update the type for `baseFeePerGas` at `web3.eth.getFeeHistory` to be a number. (#7291) +#### web3-eth + +- Allow specifying percentage based factor in Web3Eth.calculateFeeData Param baseFeePerGasFactor #7332 + ### Fixed #### web3-eth-abi @@ -2770,4 +2774,4 @@ If there are any bugs, improvements, optimizations or any new feature proposal f #### web3-rpc-providers -- PublicNodeProvider was added (#7322) +- PublicNodeProvider was added (#7322) \ No newline at end of file diff --git a/packages/web3-eth/src/web3_eth.ts b/packages/web3-eth/src/web3_eth.ts index 6aa4f2ab89d..4f0a191d9f8 100644 --- a/packages/web3-eth/src/web3_eth.ts +++ b/packages/web3-eth/src/web3_eth.ts @@ -272,43 +272,57 @@ export class Web3Eth extends Web3Context { - * gasPrice: 20000000000n, - * maxFeePerGas: 60000000000n, - * maxPriorityFeePerGas: 20000000000n, - * baseFeePerGas: 20000000000n - * } - * - * web3.eth.calculateFeeData(1n).then(console.log); - * > { - * gasPrice: 20000000000n, - * maxFeePerGas: 40000000000n, - * maxPriorityFeePerGas: 20000000000n, - * baseFeePerGas: 20000000000n - * } - * - * web3.eth.calculateFeeData(3n).then(console.log); - * > { - * gasPrice: 20000000000n, - * maxFeePerGas: 80000000000n, - * maxPriorityFeePerGas: 20000000000n, - * baseFeePerGas: 20000000000n - * } - * ``` - */ + * Calculates the current Fee Data. + * If the node supports EIP-1559, then `baseFeePerGas` and `maxPriorityFeePerGas` will be returned along with the calculated `maxFeePerGas` value. + * `maxFeePerGas` is calculated as `baseFeePerGas` * `baseFeePerGasFactor` + `maxPriorityFeePerGas`. + * If the node does not support EIP-1559, then the `gasPrice` will be returned and the other values will be undefined. + * + * @param baseFeePerGasFactor (optional) The factor to multiply the `baseFeePerGas` with when calculating `maxFeePerGas`, if the node supports EIP-1559. This can be a `bigint` for precise calculation or a `number` to support decimals. The default value is 2 (BigInt). + * If a `number` is provided, it will be converted to `bigint` with three decimal precision. + * @param alternativeMaxPriorityFeePerGas (optional) The alternative `maxPriorityFeePerGas` to use when calculating `maxFeePerGas`, if the node supports EIP-1559 but does not support the method `eth_maxPriorityFeePerGas`. The default value is 1 gwei. + * @returns The current fee data. + * + * @example + * web3.eth.calculateFeeData().then(console.log); + * > { + * gasPrice: 20000000000n, + * maxFeePerGas: 60000000000n, + * maxPriorityFeePerGas: 20000000000n, + * baseFeePerGas: 20000000000n + * } + * + * @example + * // Using a `bigint` for baseFeePerGasFactor + * web3.eth.calculateFeeData(1n).then(console.log); + * > { + * gasPrice: 20000000000n, + * maxFeePerGas: 40000000000n, + * maxPriorityFeePerGas: 20000000000n, + * baseFeePerGas: 20000000000n + * } + * + * @example + * // Using a `number` for baseFeePerGasFactor (with decimals) + * web3.eth.calculateFeeData(1.5).then(console.log); + * > { + * gasPrice: 20000000000n, + * maxFeePerGas: 50000000000n, // baseFeePerGasFactor is converted to BigInt(1.500) + * maxPriorityFeePerGas: 20000000000n, + * baseFeePerGas: 20000000000n + * } + * + * @example + * web3.eth.calculateFeeData(3n).then(console.log); + * > { + * gasPrice: 20000000000n, + * maxFeePerGas: 80000000000n, + * maxPriorityFeePerGas: 20000000000n, + * baseFeePerGas: 20000000000n + * } + */ + public async calculateFeeData( - baseFeePerGasFactor = BigInt(2), + baseFeePerGasFactor: bigint | number = BigInt(2), alternativeMaxPriorityFeePerGas = ethUnitMap.Gwei, ): Promise { const block = await this.getBlock<{ number: FMT_NUMBER.BIGINT; bytes: FMT_BYTES.HEX }>( @@ -348,7 +362,15 @@ export class Web3Eth extends Web3Context { baseFeePerGas, }); }); + + it('should use default baseFeePerGasFactor if none is provided', async () => { + const gasPrice = BigInt(20 * 1000); + const baseFeePerGas = BigInt(1000); + const maxPriorityFeePerGas = BigInt(100); // this will be used directly + + jest.spyOn(ethRpcMethods, 'getBlockByNumber').mockReturnValueOnce({ baseFeePerGas } as any); + jest.spyOn(ethRpcMethods, 'getGasPrice').mockReturnValueOnce(gasPrice as any); + jest.spyOn(ethRpcMethods, 'getMaxPriorityFeePerGas').mockReturnValueOnce( + maxPriorityFeePerGas as any, + ); + + const feeData = await web3Eth.calculateFeeData(); // no baseFeePerGasFactor passed + const defaultBaseFeePerGasFactor = BigInt(2); + expect(feeData).toMatchObject({ + gasPrice, + maxFeePerGas: baseFeePerGas * defaultBaseFeePerGasFactor + maxPriorityFeePerGas, + maxPriorityFeePerGas, + baseFeePerGas, + }); + }); });