UNPKG

@saberhq/sail

Version:

Account caching and batched loading for React-based Solana applications.

70 lines (65 loc) 1.75 kB
import type { AccountInfo, Commitment, Connection, PublicKey, } from "@solana/web3.js"; import { SailGetMultipleAccountsError } from ".."; export function chunks<T>(array: readonly T[], size: number): T[][] { return Array.apply<number, T[], T[][]>( 0, new Array(Math.ceil(array.length / size)) as T[] ).map((_, index) => array.slice(index * size, (index + 1) * size)); } const GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE = 99; export const getMultipleAccounts = async ( connection: Connection, keys: readonly PublicKey[], onGetMultipleAccountsError: (err: SailGetMultipleAccountsError) => void, commitment: Commitment = "confirmed" ): Promise<{ keys: readonly PublicKey[]; array: readonly (AccountInfo<Buffer> | null | SailGetMultipleAccountsError)[]; }> => { const result = await Promise.all( chunks(keys, GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE).map( async ( chunk ): Promise< { keys: PublicKey[]; } & ( | { array: (AccountInfo<Buffer> | null)[]; } | { error: SailGetMultipleAccountsError; } ) > => { try { return { keys: chunk, array: await connection.getMultipleAccountsInfo(chunk, commitment), }; } catch (e) { const error = new SailGetMultipleAccountsError(chunk, commitment, e); onGetMultipleAccountsError(error); return { keys: chunk, error, }; } } ) ); const array = result .map((el) => { if ("error" in el) { return el.keys.map(() => el.error); } return el.array; }) .flat(); return { keys, array }; };