diff --git a/web3.js/flow-typed/superstruct.js b/web3.js/flow-typed/superstruct.js index 212fb20527..7333cae28e 100644 --- a/web3.js/flow-typed/superstruct.js +++ b/web3.js/flow-typed/superstruct.js @@ -4,7 +4,7 @@ declare module 'superstruct' { union(schema: any): any; list(schema: any): any; literal(schema: any): any; - + tuple(schema: any): any; }; declare module.exports: { diff --git a/web3.js/src/connection.js b/web3.js/src/connection.js index fb44a4e9ec..f6caf56406 100644 --- a/web3.js/src/connection.js +++ b/web3.js/src/connection.js @@ -390,6 +390,18 @@ const GetMinimumBalanceForRentExemptionRpcResult = jsonRpcResult('number'); */ const GetBlocksSinceRpcResult = jsonRpcResult(struct.list(['number'])); +/** + * Expected JSON RPC response for the "getBlock" message + */ +const GetBlockRpcResult = jsonRpcResult( + struct.list([ + struct.tuple([ + struct.list(['number']), + struct.union([struct({Ok: 'null'}), struct({Err: 'object'})]), + ]), + ]), +); + /** * Expected JSON RPC response for the "getRecentBlockhash" message */ @@ -904,6 +916,25 @@ export class Connection { return res.result; } + /** + * Fetch a list of Transactions and transaction statuses from the cluster + */ + async getBlock( + slot: number, + ): Promise< + Array<[Transaction, SignatureSuccess] | [Transaction, TransactionError]>, + > { + const unsafeRes = await this._rpcRequest('getBlock', [slot]); + const result = GetBlockRpcResult(unsafeRes); + if (result.error) { + throw new Error(result.error.message); + } + assert(typeof result.result !== 'undefined'); + return result.result.map(result => { + return [Transaction.from(result[0]), result[1]]; + }); + } + /** * Request an allocation of lamports to the specified account */ diff --git a/web3.js/test/connection.test.js b/web3.js/test/connection.test.js index f3f9839d44..99452bbda1 100644 --- a/web3.js/test/connection.test.js +++ b/web3.js/test/connection.test.js @@ -462,6 +462,21 @@ test('get blocks since slot', async () => { await expect(connection.getBlocksSince(10000)).rejects.toThrow(errorMessage); }); +test('get block', async () => { + if (mockRpcEnabled) { + console.log('non-live test skipped'); + return; + } + const connection = new Connection(url); + + // These test cases need to be updated when upstream solana RPC api is fleshed out + const zeroTransactions = await connection.getBlock(0); + expect(zeroTransactions.length).toBe(0); + + const oneTransaction = await connection.getBlock(1); + expect(oneTransaction.length).toBe(1); +}); + test('get recent blockhash', async () => { const connection = new Connection(url);