Skip to content

Commit

Permalink
✨ provider.getFeeData (#202)
Browse files Browse the repository at this point in the history
* Add gas estimation

* Update getFeeData call
  • Loading branch information
dawsbot committed Mar 14, 2023
1 parent c75f377 commit 0ab5a7f
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 2 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@
"name": "JsonRpcProvider",
"path": "src/index.ts",
"import": "{ JsonRpcProvider }",
"limit": "20.24kb"
"limit": "20.32kb"
},
{
"name": "Contract",
"path": "src/index.ts",
"import": "{ Contract }",
"limit": "15.87kb"
"limit": "15.38kb"
}
],
"scripts": {
Expand Down
29 changes: 29 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
- [`getBlock`](#getblock)
- [`getBlockNumber`](#getblocknumber)
- [`getCode`](#getcode)
- [`getFeeData`](#getfeedata)
- [`getGasPrice`](#getgasprice)
- [`getLogs`](#getlogs)
- [`getNetwork`](#getnetwork)
Expand Down Expand Up @@ -1195,6 +1196,34 @@ await jsonRpcProvider().getCode(

<br/>

#### [`getFeeData`](https://eeth.dev/docs/api/classes/JsonRpcProvider#getfeedata)

```typescript
provider.getFeeData(): Promise<FeeData>
```

<details>
<summary>View Example</summary>

```js
import { JsonRpcProvider } from 'essential-eth';
const provider = new JsonRpcProvider('RPC URL HERE' /* Try Infura or POKT */);
```

```javascript
await provider.getFeeData();
// {
// gasPrice: { TinyBig: "14184772639" },
// lastBaseFeePerGas: { TinyBig: "14038523098" },
// maxFeePerGas: { TinyBig: "29577046196" },
// maxPriorityFeePerGas: { TinyBig: "1500000000" }
// }
```

</details>

<br/>

#### [`getGasPrice`](https://eeth.dev/docs/api/classes/JsonRpcProvider#getgasprice)

```typescript
Expand Down
44 changes: 44 additions & 0 deletions src/providers/BaseProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { logger } from '../logger/logger';
import type { TinyBig } from '../shared/tiny-big/tiny-big';
import { tinyBig } from '../shared/tiny-big/tiny-big';
import type { BlockResponse, BlockTag, RPCBlock } from '../types/Block.types';
import type { FeeData } from '../types/FeeData.types';
import type { Filter, FilterByBlockHash } from '../types/Filter.types';
import type { Network } from '../types/Network.types';
import type {
Expand Down Expand Up @@ -455,6 +456,49 @@ export abstract class BaseProvider {
return tinyBig(hexToDecimal(gasUsed));
}

/**
* Returns the current recommended FeeData to use in a transaction.
* For an EIP-1559 transaction, the maxFeePerGas and maxPriorityFeePerGas should be used.
* For legacy transactions and networks which do not support EIP-1559, the gasPrice should be used.Returns an estimate of the amount of gas that would be required to submit transaction to the network.
*
* * [Identical](/docs/api#isd) to [`ethers.provider.getFeeData`](https://docs.ethers.org/v5/api/providers/provider/#Provider-getFeeData) in ethers.js
*
* @returns an object with gas estimates for the network currently
* @example
* ```javascript
* await provider.getFeeData();
* // {
* // gasPrice: { TinyBig: "14184772639" },
* // lastBaseFeePerGas: { TinyBig: "14038523098" },
* // maxFeePerGas: { TinyBig: "29577046196" },
* // maxPriorityFeePerGas: { TinyBig: "1500000000" }
* // }
* ```
*/
public async getFeeData(): Promise<FeeData> {
const [block, gasPrice] = await Promise.all([
this.getBlock('latest'),
this.getGasPrice(),
]);

let lastBaseFeePerGas = null,
maxFeePerGas = null,
maxPriorityFeePerGas = null;

if (block && block.baseFeePerGas) {
// We may want to compute this more accurately in the future,
// using the formula "check if the base fee is correct".
// See: https://eips.ethereum.org/EIPS/eip-1559
lastBaseFeePerGas = block.baseFeePerGas;
maxPriorityFeePerGas = tinyBig('1500000000');
maxFeePerGas = tinyBig(
block.baseFeePerGas.mul(2).add(maxPriorityFeePerGas),
);
}

return { lastBaseFeePerGas, maxFeePerGas, maxPriorityFeePerGas, gasPrice };
}

/**
* Returns transaction receipt event logs that match a specified filter.
* May return `[]` if parameters are too broad, even if logs exist.
Expand Down
35 changes: 35 additions & 0 deletions src/providers/test/json-rpc-provider/get-fee-data.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { StaticJsonRpcProvider } from '@ethersproject/providers';
import { JsonRpcProvider } from '../../JsonRpcProvider';
import { rpcUrls } from './../rpc-urls';

const rpcUrl = rpcUrls.mainnet;

const essentialEthProvider = new JsonRpcProvider(rpcUrl);
const ethersProvider = new StaticJsonRpcProvider(rpcUrl);
describe('provider.getFeeData', () => {
it('should match ethers.js', async () => {
const [ethersFeeData, eeFeeData] = await Promise.all([
ethersProvider.getFeeData(),
essentialEthProvider.getFeeData(),
]);
expect(eeFeeData.gasPrice.toString()).toBe(
// @ts-ignore
ethersFeeData?.gasPrice.toString(),
);
// @ts-ignore
expect(eeFeeData.lastBaseFeePerGas.toString()).toBe(
// @ts-ignore
ethersFeeData?.lastBaseFeePerGas.toString(),
);
// @ts-ignore
expect(eeFeeData.maxFeePerGas.toString()).toBe(
// @ts-ignore
ethersFeeData?.maxFeePerGas.toString(),
);
// @ts-ignore
expect(eeFeeData.maxPriorityFeePerGas.toString()).toBe(
// @ts-ignore
ethersFeeData?.maxPriorityFeePerGas.toString(),
);
});
});
8 changes: 8 additions & 0 deletions src/types/FeeData.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { TinyBig } from '../shared/tiny-big/tiny-big';

export interface FeeData {
gasPrice: TinyBig;
lastBaseFeePerGas: TinyBig | null;
maxFeePerGas: TinyBig | null;
maxPriorityFeePerGas: TinyBig | null;
}

0 comments on commit 0ab5a7f

Please sign in to comment.