Skip to content
This repository was archived by the owner on Mar 5, 2025. It is now read-only.

Commit 69d83e7

Browse files
TemirlanBasitovI744506
and
I744506
authored
allowing to specify percentage-based factors (like 1.125 for 112.5%) (#7332)
* allowing to specify percentage-based factors (like 1.125 for 112.5%) * added change log * implemented with backward compatibility for any existing users logic handled according to number or bigint added unit test * Adjusted method description --------- Co-authored-by: I744506 <temirlan.basitov@sap.com>
1 parent efac906 commit 69d83e7

File tree

3 files changed

+85
-38
lines changed

3 files changed

+85
-38
lines changed

CHANGELOG.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -2754,6 +2754,10 @@ If there are any bugs, improvements, optimizations or any new feature proposal f
27542754

27552755
- update the type for `baseFeePerGas` at `web3.eth.getFeeHistory` to be a number. (#7291)
27562756

2757+
#### web3-eth
2758+
2759+
- Allow specifying percentage based factor in Web3Eth.calculateFeeData Param baseFeePerGasFactor #7332
2760+
27572761
### Fixed
27582762

27592763
#### web3-eth-abi
@@ -2770,4 +2774,4 @@ If there are any bugs, improvements, optimizations or any new feature proposal f
27702774

27712775
#### web3-rpc-providers
27722776

2773-
- PublicNodeProvider was added (#7322)
2777+
- PublicNodeProvider was added (#7322)

packages/web3-eth/src/web3_eth.ts

+59-37
Original file line numberDiff line numberDiff line change
@@ -272,43 +272,57 @@ export class Web3Eth extends Web3Context<Web3EthExecutionAPI, RegisteredSubscrip
272272
}
273273

274274
/**
275-
* Calculates the current Fee Data.
276-
* If the node supports EIP-1559, then `baseFeePerGas` and `maxPriorityFeePerGas` will be returned along with the calculated `maxFeePerGas` value.
277-
* `maxFeePerGas` is calculated as `baseFeePerGas` * `baseFeePerGasFactor` + `maxPriorityFeePerGas`.
278-
* If the node does not support EIP-1559, then the `gasPrice` will be returned and the other values will be undefined.
279-
*
280-
* @param baseFeePerGasFactor (optional) The factor to multiply the `baseFeePerGas` with when calculating `maxFeePerGas`, if the node supports EIP-1559. The default value is 2.
281-
* @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.
282-
* @returns The current fee data.
283-
*
284-
* ```ts
285-
* web3.eth.calculateFeeData().then(console.log);
286-
* > {
287-
* gasPrice: 20000000000n,
288-
* maxFeePerGas: 60000000000n,
289-
* maxPriorityFeePerGas: 20000000000n,
290-
* baseFeePerGas: 20000000000n
291-
* }
292-
*
293-
* web3.eth.calculateFeeData(1n).then(console.log);
294-
* > {
295-
* gasPrice: 20000000000n,
296-
* maxFeePerGas: 40000000000n,
297-
* maxPriorityFeePerGas: 20000000000n,
298-
* baseFeePerGas: 20000000000n
299-
* }
300-
*
301-
* web3.eth.calculateFeeData(3n).then(console.log);
302-
* > {
303-
* gasPrice: 20000000000n,
304-
* maxFeePerGas: 80000000000n,
305-
* maxPriorityFeePerGas: 20000000000n,
306-
* baseFeePerGas: 20000000000n
307-
* }
308-
* ```
309-
*/
275+
* Calculates the current Fee Data.
276+
* If the node supports EIP-1559, then `baseFeePerGas` and `maxPriorityFeePerGas` will be returned along with the calculated `maxFeePerGas` value.
277+
* `maxFeePerGas` is calculated as `baseFeePerGas` * `baseFeePerGasFactor` + `maxPriorityFeePerGas`.
278+
* If the node does not support EIP-1559, then the `gasPrice` will be returned and the other values will be undefined.
279+
*
280+
* @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).
281+
* If a `number` is provided, it will be converted to `bigint` with three decimal precision.
282+
* @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.
283+
* @returns The current fee data.
284+
*
285+
* @example
286+
* web3.eth.calculateFeeData().then(console.log);
287+
* > {
288+
* gasPrice: 20000000000n,
289+
* maxFeePerGas: 60000000000n,
290+
* maxPriorityFeePerGas: 20000000000n,
291+
* baseFeePerGas: 20000000000n
292+
* }
293+
*
294+
* @example
295+
* // Using a `bigint` for baseFeePerGasFactor
296+
* web3.eth.calculateFeeData(1n).then(console.log);
297+
* > {
298+
* gasPrice: 20000000000n,
299+
* maxFeePerGas: 40000000000n,
300+
* maxPriorityFeePerGas: 20000000000n,
301+
* baseFeePerGas: 20000000000n
302+
* }
303+
*
304+
* @example
305+
* // Using a `number` for baseFeePerGasFactor (with decimals)
306+
* web3.eth.calculateFeeData(1.5).then(console.log);
307+
* > {
308+
* gasPrice: 20000000000n,
309+
* maxFeePerGas: 50000000000n, // baseFeePerGasFactor is converted to BigInt(1.500)
310+
* maxPriorityFeePerGas: 20000000000n,
311+
* baseFeePerGas: 20000000000n
312+
* }
313+
*
314+
* @example
315+
* web3.eth.calculateFeeData(3n).then(console.log);
316+
* > {
317+
* gasPrice: 20000000000n,
318+
* maxFeePerGas: 80000000000n,
319+
* maxPriorityFeePerGas: 20000000000n,
320+
* baseFeePerGas: 20000000000n
321+
* }
322+
*/
323+
310324
public async calculateFeeData(
311-
baseFeePerGasFactor = BigInt(2),
325+
baseFeePerGasFactor: bigint | number = BigInt(2),
312326
alternativeMaxPriorityFeePerGas = ethUnitMap.Gwei,
313327
): Promise<FeeData> {
314328
const block = await this.getBlock<{ number: FMT_NUMBER.BIGINT; bytes: FMT_BYTES.HEX }>(
@@ -348,7 +362,15 @@ export class Web3Eth extends Web3Context<Web3EthExecutionAPI, RegisteredSubscrip
348362
// and we multiply the `baseFeePerGas` by `baseFeePerGasFactor`, to allow
349363
// trying to include the transaction in the next few blocks even if the
350364
// baseFeePerGas is increasing fast
351-
maxFeePerGas = baseFeePerGas * baseFeePerGasFactor + maxPriorityFeePerGas;
365+
let baseFeeMultiplier: bigint;
366+
if (typeof baseFeePerGasFactor === 'number') {
367+
// Convert number to bigint with three decimal places
368+
baseFeeMultiplier = BigInt(Math.floor(baseFeePerGasFactor * 1000)) / BigInt(1000);
369+
} else {
370+
// It's already a BigInt, so just use it as-is
371+
baseFeeMultiplier = baseFeePerGasFactor;
372+
}
373+
maxFeePerGas = baseFeePerGas * baseFeeMultiplier + maxPriorityFeePerGas;
352374
}
353375

354376
return { gasPrice, maxFeePerGas, maxPriorityFeePerGas, baseFeePerGas };

packages/web3-eth/test/unit/web3_eth_calculate_fee_data.test.ts

+21
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,25 @@ describe('Web3Eth.calculateFeeData', () => {
8181
baseFeePerGas,
8282
});
8383
});
84+
85+
it('should use default baseFeePerGasFactor if none is provided', async () => {
86+
const gasPrice = BigInt(20 * 1000);
87+
const baseFeePerGas = BigInt(1000);
88+
const maxPriorityFeePerGas = BigInt(100); // this will be used directly
89+
90+
jest.spyOn(ethRpcMethods, 'getBlockByNumber').mockReturnValueOnce({ baseFeePerGas } as any);
91+
jest.spyOn(ethRpcMethods, 'getGasPrice').mockReturnValueOnce(gasPrice as any);
92+
jest.spyOn(ethRpcMethods, 'getMaxPriorityFeePerGas').mockReturnValueOnce(
93+
maxPriorityFeePerGas as any,
94+
);
95+
96+
const feeData = await web3Eth.calculateFeeData(); // no baseFeePerGasFactor passed
97+
const defaultBaseFeePerGasFactor = BigInt(2);
98+
expect(feeData).toMatchObject({
99+
gasPrice,
100+
maxFeePerGas: baseFeePerGas * defaultBaseFeePerGasFactor + maxPriorityFeePerGas,
101+
maxPriorityFeePerGas,
102+
baseFeePerGas,
103+
});
104+
});
84105
});

0 commit comments

Comments
 (0)