Skip to content
Transactions & Accounts

Address Lookup Tables

Compress account addresses in prepared v0 transactions without changing operation semantics.

An Address Lookup Table (ALT) stores account addresses on-chain. A v0 transaction can reference eligible addresses by index instead of repeating their full bytes. This helps account-heavy compositions, but it does not compress instruction payloads or signatures, and it does not remove compute limits.

Supply tables explicitly

Each direct preparation intent accepts transaction.lookupTables, an array of table addresses:

import type {
  GraplClient,
  PreparedTransaction,
  SwapExactInIntent,
} from "@grapl/sdk";
import type { Address } from "@solana/kit";

export async function prepareSwapWithTable(
  client: GraplClient,
  reviewedIntent: SwapExactInIntent,
  lookupTable: Address,
): Promise<PreparedTransaction> {
  return client.prepareSwapExactIn({
    ...reviewedIntent,
    transaction: { ...reviewedIntent.transaction, lookupTables: [lookupTable] },
  });
}

The SDK fetches tables over RPC and validates their owner, layout, discriminator, active status, and warmup. It conservatively rejects deactivating or deactivated tables. In a table's extension slot, only the previously active address prefix is usable; new entries become usable after warmup.

Create and discover tables for a pool

The SDK's locally implemented pool ALT increment exposes explicit creation, extension planning, and discovery helpers. Follow Create and discover pool ALTs for method signatures and lifecycle rules. Your application still owns signatures, submission, confirmation, rent funding, and authority selection. These are separate setup operations, not implicit side effects of a swap.

Check the result

Compare serializedSize and simulation for equivalent operations with and without the table. A smaller message does not promise lower compute usage or a cheaper transaction after setup and rent costs. The final serialized transaction must still fit 1,232 bytes, including signatures.

Oversized compositions fail explicitly; they are never silently split. An ALT is optional, and a supplied table that lacks useful addresses may provide no compression. See transaction lifecycle.

Measured local example

The isolated Pool 6 integration run on 2026-10-12 compared the same donation instructions with and without an active table containing 12 addresses:

MeasurementWithout ALTWith ALT
Serialized v0 transaction607 bytes300 bytes
Executed compute units45,07245,072
Network fee5,000 lamports5,000 lamports

This saved 307 bytes. Setup separately required 3,953,280 lamports of rent funding and 10,000 lamports in transaction fees. These are local fixture measurements, not universal costs or a compute reduction promise. Creation, extension, discovery, a full 256-entry table, and explicit replacement/fallback were also exercised; the SDK still leaves selection and signing to the application.