From 89a25aa194bcdadad20811b1c3278711d7ea7890 Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Wed, 11 Sep 2024 09:24:31 +0100 Subject: [PATCH] Add `isSolanaRequest` helper (#3195) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds a new `isSolanaRequest` helper function that checks if a given `RpcRequest` comes from the Solana RPC API. This will be used — in a subsequent PR — to create a new Solana-RPC-specific HTTP transport that prevents loss of precision for large integers. --- .../src/__tests__/is-solana-request-test.ts | 12 ++++ .../src/is-solana-request.ts | 69 +++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 packages/rpc-transport-http/src/__tests__/is-solana-request-test.ts create mode 100644 packages/rpc-transport-http/src/is-solana-request.ts diff --git a/packages/rpc-transport-http/src/__tests__/is-solana-request-test.ts b/packages/rpc-transport-http/src/__tests__/is-solana-request-test.ts new file mode 100644 index 000000000000..4f6022ba2b6f --- /dev/null +++ b/packages/rpc-transport-http/src/__tests__/is-solana-request-test.ts @@ -0,0 +1,12 @@ +import { isSolanaRequest } from '../is-solana-request'; + +describe('isSolanaRequest', () => { + it('returns true if the method name is from the Solana RPC API', () => { + const payload = { jsonrpc: '2.0', method: 'getBalance', params: ['1234..5678'] }; + expect(isSolanaRequest(payload)).toBe(true); + }); + it('returns false if the method name is not from the Solana RPC API', () => { + const payload = { jsonrpc: '2.0', method: 'getAssetsByAuthority', params: ['1234..5678'] }; + expect(isSolanaRequest(payload)).toBe(false); + }); +}); diff --git a/packages/rpc-transport-http/src/is-solana-request.ts b/packages/rpc-transport-http/src/is-solana-request.ts new file mode 100644 index 000000000000..cdfb952fe862 --- /dev/null +++ b/packages/rpc-transport-http/src/is-solana-request.ts @@ -0,0 +1,69 @@ +import { isJsonRpcPayload } from '@solana/rpc-spec'; + +const SOLANA_RPC_METHODS = [ + 'getAccountInfo', + 'getBalance', + 'getBlock', + 'getBlockCommitment', + 'getBlockHeight', + 'getBlockProduction', + 'getBlocks', + 'getBlocksWithLimit', + 'getBlockTime', + 'getClusterNodes', + 'getEpochInfo', + 'getEpochSchedule', + 'getFeeForMessage', + 'getFirstAvailableBlock', + 'getGenesisHash', + 'getHealth', + 'getHighestSnapshotSlot', + 'getIdentity', + 'getInflationGovernor', + 'getInflationRate', + 'getInflationReward', + 'getLargestAccounts', + 'getLatestBlockhash', + 'getLeaderSchedule', + 'getMaxRetransmitSlot', + 'getMaxShredInsertSlot', + 'getMinimumBalanceForRentExemption', + 'getMultipleAccounts', + 'getProgramAccounts', + 'getRecentPerformanceSamples', + 'getRecentPrioritizationFees', + 'getSignaturesForAddress', + 'getSignatureStatuses', + 'getSlot', + 'getSlotLeader', + 'getSlotLeaders', + 'getStakeActivation', + 'getStakeMinimumDelegation', + 'getSupply', + 'getTokenAccountBalance', + 'getTokenAccountsByDelegate', + 'getTokenAccountsByOwner', + 'getTokenLargestAccounts', + 'getTokenSupply', + 'getTransaction', + 'getTransactionCount', + 'getVersion', + 'getVoteAccounts', + 'index', + 'isBlockhashValid', + 'minimumLedgerSlot', + 'requestAirdrop', + 'sendTransaction', + 'simulateTransaction', +] as const; + +/** + * Helper function that checks if a given `RpcRequest` comes from the Solana RPC API. + */ +export function isSolanaRequest(payload: unknown): payload is Readonly<{ + jsonrpc: '2.0'; + method: (typeof SOLANA_RPC_METHODS)[number]; + params: unknown; +}> { + return isJsonRpcPayload(payload) && (SOLANA_RPC_METHODS as readonly string[]).includes(payload.method); +}