CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-solana--web3-js

Comprehensive JavaScript SDK for building Solana blockchain applications with modern architecture and type safety

93

1.29x

Evaluation93%

1.29x

Agent success when using this tile

Overview
Eval results
Files

account-management.mddocs/

Account Management

Account data fetching, parsing, and validation with support for various encoding formats and specialized account types.

Capabilities

Account Data Structures

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;

Account Fetching

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);
}

Account Decoding

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);
}

Account Validation

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>[];

RPC Response Parsing

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>;

Specialized Account Types

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 and Options

/**
 * 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-js

docs

account-management.md

core-primitives.md

cryptography.md

encoding-codecs.md

error-handling.md

high-level-utilities.md

index.md

instructions-programs.md

rpc-communication.md

signing-authentication.md

transaction-building.md

tile.json