Comprehensive JavaScript SDK for building Solana blockchain applications with modern architecture and type safety
93
Evaluation — 93%
↑ 1.29xAgent success when using this tile
Account data fetching, parsing, and validation with support for various encoding formats and specialized account types.
Core account information and data representations.
/**
* Base account information returned by RPC
*/
interface BaseAccount {
/** Account balance in lamports */
lamports: Lamports;
/** Program that owns this account */
programId: Address;
/** Whether this account contains executable code */
executable: boolean;
/** Rent epoch for rent collection */
rentEpoch?: bigint;
}
/**
* Complete account with address and decoded data
*/
interface Account<TData, TAddress = Address> extends BaseAccount {
/** Account address */
address: TAddress;
/** Decoded account data */
data: TData;
}
/**
* Account with raw encoded data
*/
interface EncodedAccount<TAddress = Address> extends BaseAccount {
/** Account address */
address: TAddress;
/** Raw account data as Uint8Array */
data: Uint8Array;
}
/**
* Account that may or may not exist
*/
type MaybeAccount<TData, TAddress = Address> = Account<TData, TAddress> | null;
/**
* Encoded account that may or may not exist
*/
type MaybeEncodedAccount<TAddress = Address> = EncodedAccount<TAddress> | null;Retrieve account data from the blockchain with various encoding options.
/**
* Fetch account with base64-encoded data
* @param rpc - RPC client instance
* @param address - Account address to fetch
* @param config - Optional fetch configuration
* @returns Promise resolving to account with Uint8Array data or null
*/
function fetchEncodedAccount<TAddress extends Address>(
rpc: Rpc<GetAccountInfoApi>,
address: TAddress,
config?: FetchAccountConfig
): Promise<MaybeEncodedAccount<TAddress>>;
/**
* Fetch account with JSON-parsed data
* @param rpc - RPC client instance
* @param address - Account address to fetch
* @param config - Optional fetch configuration
* @returns Promise resolving to account with parsed data or null
*/
function fetchJsonParsedAccount<TData, TAddress extends Address = Address>(
rpc: Rpc<GetAccountInfoApi>,
address: TAddress,
config?: FetchAccountConfig
): Promise<MaybeAccount<TData, TAddress>>;
/**
* Fetch multiple accounts with encoded data
* @param rpc - RPC client instance
* @param addresses - Array of addresses to fetch
* @param config - Optional fetch configuration
* @returns Promise resolving to array of accounts or null values
*/
function fetchEncodedAccounts<TAddress extends Address>(
rpc: Rpc<GetMultipleAccountsApi>,
addresses: TAddress[],
config?: FetchAccountsConfig
): Promise<MaybeEncodedAccount<TAddress>[]>;
/**
* Fetch multiple accounts with JSON-parsed data
* @param rpc - RPC client instance
* @param addresses - Array of addresses to fetch
* @param config - Optional fetch configuration
* @returns Promise resolving to array of accounts with parsed data
*/
function fetchJsonParsedAccounts<TData, TAddress extends Address = Address>(
rpc: Rpc<GetMultipleAccountsApi>,
addresses: TAddress[],
config?: FetchAccountsConfig
): Promise<MaybeAccount<TData, TAddress>[]>;Usage Examples:
import {
fetchEncodedAccount,
fetchJsonParsedAccount,
createSolanaRpc,
address
} from "@solana/web3.js";
const rpc = createSolanaRpc("https://api.devnet.solana.com");
// Fetch encoded account data
const encodedAccount = await fetchEncodedAccount(
rpc,
address("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA")
);
if (encodedAccount) {
console.log("Account data:", encodedAccount.data);
console.log("Lamports:", encodedAccount.lamports);
}
// Fetch JSON-parsed token account
interface TokenAccount {
mint: string;
owner: string;
amount: string;
delegate?: string;
state: "initialized" | "uninitialized" | "frozen";
}
const tokenAccount = await fetchJsonParsedAccount<TokenAccount>(
rpc,
address("your-token-account-address"),
{ encoding: "jsonParsed" }
);
if (tokenAccount) {
console.log("Token mint:", tokenAccount.data.mint);
console.log("Owner:", tokenAccount.data.owner);
}Convert raw account data to typed structures using codecs.
/**
* Decode account data using a provided codec
* @param encodedAccount - Account with raw data
* @param decoder - Codec decoder for the data type
* @returns Account with decoded data
*/
function decodeAccount<TData, TAddress extends Address>(
encodedAccount: EncodedAccount<TAddress>,
decoder: Decoder<Uint8Array, TData>
): Account<TData, TAddress>;Usage Examples:
import {
fetchEncodedAccount,
decodeAccount,
getStructCodec,
getU64Codec,
address
} from "@solana/web3.js";
// Define account data structure
interface MyAccountData {
value: bigint;
owner: Address;
}
// Create decoder
const accountDecoder = getStructCodec({
value: getU64Codec(),
owner: getAddressCodec()
});
// Fetch and decode
const encodedAccount = await fetchEncodedAccount(rpc, myAddress);
if (encodedAccount) {
const decodedAccount = decodeAccount(encodedAccount, accountDecoder);
console.log("Decoded value:", decodedAccount.data.value);
}Validate and assert account states and data integrity.
/**
* Assert that an account has been decoded (not raw bytes)
* @param account - Account to check
* @throws SolanaError if account data is not decoded
*/
function assertAccountDecoded<TData>(
account: Account<TData> | EncodedAccount
): asserts account is Account<TData>;
/**
* Assert that all accounts in array have been decoded
* @param accounts - Array of accounts to check
* @throws SolanaError if any account data is not decoded
*/
function assertAccountsDecoded<TData>(
accounts: (Account<TData> | EncodedAccount)[]
): asserts accounts is Account<TData>[];
/**
* Assert that a maybe account exists (is not null)
* @param account - Maybe account to check
* @throws SolanaError if account is null
*/
function assertAccountExists<TData, TAddress>(
account: MaybeAccount<TData, TAddress>
): asserts account is Account<TData, TAddress>;
/**
* Assert that all maybe accounts exist
* @param accounts - Array of maybe accounts to check
* @throws SolanaError if any account is null
*/
function assertAccountsExist<TData, TAddress>(
accounts: MaybeAccount<TData, TAddress>[]
): asserts accounts is Account<TData, TAddress>[];Parse raw RPC responses into structured account data.
/**
* Parse RPC account response with base64 encoding
* @param rpcAccount - Raw RPC account response
* @returns Parsed account with Uint8Array data
*/
function parseBase64RpcAccount<TAddress extends Address>(
rpcAccount: RpcAccount,
address: TAddress
): EncodedAccount<TAddress>;
/**
* Parse RPC account response with base58 encoding
* @param rpcAccount - Raw RPC account response
* @returns Parsed account with Uint8Array data
*/
function parseBase58RpcAccount<TAddress extends Address>(
rpcAccount: RpcAccount,
address: TAddress
): EncodedAccount<TAddress>;
/**
* Parse RPC account response with JSON encoding
* @param rpcAccount - Raw RPC account response
* @returns Parsed account with structured data
*/
function parseJsonRpcAccount<TData, TAddress extends Address>(
rpcAccount: RpcAccount,
address: TAddress
): Account<TData, TAddress>;Pre-defined parsers for common Solana account types.
/**
* Address lookup table account data
*/
interface AddressLookupTableAccount {
addresses: Address[];
authority?: Address;
deactivationSlot: Slot;
}
/**
* Token account data structure
*/
interface TokenAccount {
mint: Address;
owner: Address;
amount: bigint;
delegate?: Address;
state: "initialized" | "uninitialized" | "frozen";
isNative?: bigint;
delegatedAmount: bigint;
closeAuthority?: Address;
}
/**
* Token mint account data
*/
interface MintAccount {
mintAuthority?: Address;
supply: bigint;
decimals: number;
isInitialized: boolean;
freezeAuthority?: Address;
}
/**
* Stake account data
*/
interface StakeAccount {
meta: {
rentExemptReserve: Lamports;
authorized: {
staker: Address;
withdrawer: Address;
};
lockup: {
unixTimestamp: UnixTimestamp;
epoch: bigint;
custodian: Address;
};
};
stake?: {
delegation: {
voterPubkey: Address;
stake: Lamports;
activationEpoch: bigint;
deactivationEpoch: bigint;
};
creditsObserved: bigint;
};
}/**
* Configuration for fetching single accounts
*/
interface FetchAccountConfig {
/** Commitment level for the request */
commitment?: Commitment;
/** Minimum context slot for the request */
minContextSlot?: Slot;
/** Data encoding format */
encoding?: "base58" | "base64" | "jsonParsed";
/** Data slice to retrieve */
dataSlice?: {
offset: number;
length: number;
};
}
/**
* Configuration for fetching multiple accounts
*/
interface FetchAccountsConfig extends FetchAccountConfig {
/** Maximum number of accounts per request */
batchSize?: number;
}
/**
* RPC account response structure
*/
interface RpcAccount {
/** Account balance in lamports */
lamports: number;
/** Base64 or base58 encoded data */
data: [string, string] | string;
/** Program owner */
owner: string;
/** Whether account is executable */
executable: boolean;
/** Rent epoch */
rentEpoch: number;
}
/**
* Account size constant
*/
const BASE_ACCOUNT_SIZE = 128;Advanced Usage Examples:
import {
fetchEncodedAccounts,
assertAccountsExist,
assertAccountsDecoded,
createSolanaRpc
} from "@solana/web3.js";
const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");
// Batch fetch with validation
const addresses = [
address("account1..."),
address("account2..."),
address("account3...")
];
const accounts = await fetchEncodedAccounts(rpc, addresses, {
commitment: "confirmed",
batchSize: 100
});
// Validate all accounts exist
assertAccountsExist(accounts);
// Now accounts is typed as Account<Uint8Array>[] (no nulls)
console.log("All accounts loaded:", accounts.length);
// Process accounts with error handling
for (const account of accounts) {
try {
// Decode account data here
console.log(`Account ${account.address} has ${account.lamports} lamports`);
} catch (error) {
console.error(`Failed to process account ${account.address}:`, error);
}
}Install with Tessl CLI
npx tessl i tessl/npm-solana--web3-jsdocs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10