diff --git a/web3.js/src/connection.ts b/web3.js/src/connection.ts index 788d5ccc12f..30b71ae5113 100644 --- a/web3.js/src/connection.ts +++ b/web3.js/src/connection.ts @@ -708,6 +708,17 @@ export type PerfSample = { samplePeriodSecs: number; }; +export type Fees = { + /** Recent blockhash */ + blockhash: Blockhash; + /** Calculator for transaction fees */ + feeCalculator: FeeCalculator; + /** @deprecated this value is inaccurate and should not be relied upon */ + lastValidSlot: number; + /** last block height at which a blockhash will be valid */ + lastValidBlockHeight: number; +} + function createRpcClient( url: string, useHttps: boolean, @@ -1559,6 +1570,20 @@ const GetFeeCalculatorRpcResult = jsonRpcResultAndContext( ), ); +/** + * Expected JSON RPC response for the "getFees" message + */ +const GetFeesRpcResult = jsonRpcResultAndContext( + pick({ + blockhash: string(), + feeCalculator: pick({ + lamportsPerSignature: number(), + }), + lastValidSlot: number(), + lastValidBlockHeight: number(), + }), +); + /** * Expected JSON RPC response for the "requestAirdrop" message */ @@ -2935,6 +2960,21 @@ export class Connection { }; } + /** + * Fetch a recent block hash from the ledger, a fee schedule and the last valid block height the block hash is valid for + */ + async getFees( + commitment?: Commitment, + ): Promise> { + const args = this._buildArgs([], commitment, undefined); + const unsafeRes = await this._rpcRequest('getFees', args); + const res = create(unsafeRes, GetFeesRpcResult); + if ('error' in res) { + throw new Error('failed to get fees: ' + res.error.message); + } + return res.result; + } + /** * Fetch a recent blockhash from the cluster * @return {Promise<{blockhash: Blockhash, feeCalculator: FeeCalculator}>} diff --git a/web3.js/test/connection.test.ts b/web3.js/test/connection.test.ts index 344c89bb5c1..896f4d43e44 100644 --- a/web3.js/test/connection.test.ts +++ b/web3.js/test/connection.test.ts @@ -2200,6 +2200,27 @@ describe('Connection', () => { expect(feeCalculator.lamportsPerSignature).to.eq(5000); }); + it('get fees', async () => { + await mockRpcResponse({ + method: 'getFees', + params: [{commitment: 'confirmed'}], + value: { + blockhash: '57zQNBZBEiHsCZFqsaY6h176ioXy5MsSLmcvHkEyaLGy', + feeCalculator: { + lamportsPerSignature: 5000, + }, + lastValidSlot: 5678, + lastValidBlockHeight: 1234, + }, + withContext: true, + }); + + const fees = (await connection.getFees('confirmed')).value; + expect(fees.feeCalculator).not.to.be.null; + expect(fees.lastValidSlot).to.be.greaterThan(0); + expect(fees.lastValidBlockHeight).to.be.greaterThan(0); + }) + it('get block time', async () => { await mockRpcResponse({ method: 'getBlockTime',