From 925c225885f35b4404f634aa4b1353561e5b9d1b Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Sat, 23 May 2020 17:33:04 +0800 Subject: [PATCH] feat: add support for getFirstAvailableBlock method --- web3.js/module.d.ts | 1 + web3.js/module.flow.js | 1 + web3.js/src/connection.js | 21 ++++++++++++++++++--- web3.js/test/connection.test.js | 19 +++++++++++++++++++ 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/web3.js/module.d.ts b/web3.js/module.d.ts index f49d189d66..ad995c3e3a 100644 --- a/web3.js/module.d.ts +++ b/web3.js/module.d.ts @@ -219,6 +219,7 @@ declare module '@solana/web3.js' { getBalance(publicKey: PublicKey, commitment?: Commitment): Promise; getBlockTime(slot: number): Promise; getMinimumLedgerSlot(): Promise; + getFirstAvailableBlock(): Promise; getSupply(commitment?: Commitment): Promise>; getLargestAccounts( config?: GetLargestAccountsConfig, diff --git a/web3.js/module.flow.js b/web3.js/module.flow.js index 75ef51ec2e..47c65c9b1b 100644 --- a/web3.js/module.flow.js +++ b/web3.js/module.flow.js @@ -232,6 +232,7 @@ declare module '@solana/web3.js' { getBalance(publicKey: PublicKey, commitment: ?Commitment): Promise; getBlockTime(slot: number): Promise; getMinimumLedgerSlot(): Promise; + getFirstAvailableBlock(): Promise; getSupply(commitment: ?Commitment): Promise>; getLargestAccounts( config: ?GetLargestAccountsConfig, diff --git a/web3.js/src/connection.js b/web3.js/src/connection.js index 21649dc934..ca5abd7e9e 100644 --- a/web3.js/src/connection.js +++ b/web3.js/src/connection.js @@ -417,9 +417,9 @@ const GetBlockTimeRpcResult = struct({ }); /** - * Expected JSON RPC response for the "minimumLedgerSlot" message + * Expected JSON RPC response for the "minimumLedgerSlot" and "getFirstAvailableBlock" messages */ -const MinimumLedgerSlotRpcResult = struct({ +const SlotRpcResult = struct({ jsonrpc: struct.literal('2.0'), id: 'string', error: 'any?', @@ -1081,7 +1081,7 @@ export class Connection { */ async getMinimumLedgerSlot(): Promise { const unsafeRes = await this._rpcRequest('minimumLedgerSlot', []); - const res = MinimumLedgerSlotRpcResult(unsafeRes); + const res = SlotRpcResult(unsafeRes); if (res.error) { throw new Error( 'failed to get minimum ledger slot: ' + res.error.message, @@ -1091,6 +1091,21 @@ export class Connection { return res.result; } + /** + * Fetch the slot of the lowest confirmed block that has not been purged from the ledger + */ + async getFirstAvailableBlock(): Promise { + const unsafeRes = await this._rpcRequest('getFirstAvailableBlock', []); + const res = SlotRpcResult(unsafeRes); + if (res.error) { + throw new Error( + 'failed to get first available block: ' + res.error.message, + ); + } + assert(typeof res.result !== 'undefined'); + return res.result; + } + /** * Fetch information about the current supply */ diff --git a/web3.js/test/connection.test.js b/web3.js/test/connection.test.js index 94cf459b9e..331eacb525 100644 --- a/web3.js/test/connection.test.js +++ b/web3.js/test/connection.test.js @@ -1109,6 +1109,25 @@ test('get minimum ledger slot', async () => { expect(minimumLedgerSlot).toBeGreaterThanOrEqual(0); }); +test('get first available block', async () => { + const connection = new Connection(url); + + mockRpc.push([ + url, + { + method: 'getFirstAvailableBlock', + params: [], + }, + { + error: null, + result: 0, + }, + ]); + + const firstAvailableBlock = await connection.getFirstAvailableBlock(); + expect(firstAvailableBlock).toBeGreaterThanOrEqual(0); +}); + test('get supply', async () => { const connection = new Connection(url);