Address lookup tables (LUTs) let Solana transactions reference many accounts by compact table indexes instead of embedding every account address directly in the transaction message. They are most useful when a transaction touches many accounts: swaps, routing, portfolio actions, batch operations, and anything that risks hitting Solana’s transaction size limits.
Solana Tracker’s Ridge custom RPC methods make LUT discovery practical. Instead of scanning lookup table accounts yourself, you can ask for the exact table shape you need:
- LUTs owned by a wallet authority.
- LUTs that contain one account or token mint.
- LUTs that contain every account in a set.
- A best-effort LUT set for reducing transaction size.
Each Lookup Table RPC method costs 1 credit per call.
When to use these methods
Use the LUT methods when you are building, simulating, or optimizing Solana transactions and need to know whether accounts are already available through lookup tables.
| Goal | Method |
|---|
| Inspect LUTs controlled by a wallet | getLookupTablesByAuthority |
| Find LUTs that contain an account | getLookupTablesByAccount |
| Find LUTs that contain a token mint | getLookupTablesByMint |
| Find LUTs that cover multiple accounts | getLookupTablesByAccounts |
Start with getLookupTablesByAccounts when your goal is transaction optimization. Use the single-account methods when you are exploring where a specific account or mint appears.
RPC endpoint
All examples use JSON-RPC 2.0 over HTTP:
https://rpc-mainnet.solanatracker.io/?api_key=YOUR_API_KEY
Find LUTs by authority
Use getLookupTablesByAuthority to inspect lookup tables owned by a wallet authority. This is helpful for wallets, bots, and infrastructure that maintain their own LUTs.
curl "https://rpc-mainnet.solanatracker.io/?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "getLookupTablesByAuthority",
"params": [{
"authority": "WalletPubkey...",
"limit": 100,
"cursor": null,
"mintsOnly": false,
"includeDeactivated": false
}]
}'
The response is paginated:
{
"lookupTables": [
{
"pubkey": "LUTPubkey...",
"authority": "WalletPubkey...",
"deactivationSlot": 18446744073709551615,
"addressCount": 12,
"addresses": ["Account1...", "Account2..."],
"mints": ["Mint1..."],
"slot": 423867852
}
],
"nextCursor": "LUTPubkey...",
"hasMore": false,
"count": 1
}
deactivationSlot uses 18446744073709551615 to represent an active LUT.
Find LUTs containing one account
Use getLookupTablesByAccount when you already know an account that will appear in a transaction and want to find LUTs that contain it.
curl "https://rpc-mainnet.solanatracker.io/?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "getLookupTablesByAccount",
"params": [{
"account": "SomeAccountPubkey...",
"owner": null,
"limit": 100,
"cursor": null
}]
}'
Matched results include transaction-optimization metadata:
| Field | Meaning |
|---|
addressIndex | Position of the matched account in the LUT |
matchedAccounts | Accounts from your query found in this LUT |
matchedAddressIndices | LUT indexes for the matched accounts |
estimatedBytesSaved | Approximate bytes saved by referencing matched accounts through the LUT |
Find LUTs containing a mint
getLookupTablesByMint is the same lookup pattern as getLookupTablesByAccount, but the parameter name is mint.
{
"jsonrpc": "2.0",
"id": 1,
"method": "getLookupTablesByMint",
"params": [{
"mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"limit": 100
}]
}
Use this when a transaction is token-centric and you want to discover LUTs that already contain the mint address.
Find LUTs for a full account set
getLookupTablesByAccounts has two modes: intersection mode and best-set mode.
Intersection mode
Intersection mode returns LUTs that contain every account you provide. Use it when you need one table that covers the full set.
{
"jsonrpc": "2.0",
"id": 1,
"method": "getLookupTablesByAccounts",
"params": [{
"accounts": ["AccountA...", "AccountB..."],
"owner": null,
"limit": 100,
"cursor": null
}]
}
Best-set mode
Best-set mode is the fastest way to answer: “Which LUTs should I attach to save the most transaction space?”
Set bestSet: true and pass the full account list your transaction needs:
{
"jsonrpc": "2.0",
"id": 1,
"method": "getLookupTablesByAccounts",
"params": [{
"accounts": ["AccountA...", "AccountB...", "AccountC..."],
"bestSet": true,
"maxLookupTables": 8,
"candidateLimit": 5000,
"perAccountLimit": 500
}]
}
The response tells you what the selected LUTs cover:
{
"lookupTables": [
{
"pubkey": "LUT1...",
"matchedAccounts": ["AccountA...", "AccountB..."],
"matchedAddressIndices": [3, 17],
"estimatedBytesSaved": 62
}
],
"coveredAccounts": ["AccountA...", "AccountB..."],
"uncoveredAccounts": ["AccountC..."],
"estimatedBytesSaved": 62,
"count": 1
}
Best-set tuning
| Parameter | Default | Use it when |
|---|
maxLookupTables | 8 | You want to cap how many LUTs your transaction uses |
candidateLimit | 5000 | You need to limit total candidate tables considered |
perAccountLimit | 500 | One account appears in too many LUTs and candidate search is too broad |
For most applications, keep the defaults and only tune after measuring transaction build time and response size.
Example: choose LUTs before building a transaction
The typical flow is:
- Collect the accounts your transaction will reference.
- Call
getLookupTablesByAccounts with bestSet: true.
- Attach returned LUTs to your transaction builder.
- Keep
uncoveredAccounts as normal account keys.
const accounts = [
"AccountA...",
"AccountB...",
"AccountC..."
];
const { result } = await fetch(
"https://rpc-mainnet.solanatracker.io/?api_key=YOUR_API_KEY",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "getLookupTablesByAccounts",
params: [{
accounts,
bestSet: true,
maxLookupTables: 8
}]
})
}
).then(r => r.json());
console.log("Use LUTs:", result.lookupTables.map(lut => lut.pubkey));
console.log("Covered:", result.coveredAccounts);
console.log("Still inline:", result.uncoveredAccounts);
console.log("Estimated bytes saved:", result.estimatedBytesSaved);
Practical tips
- Use
bestSet: true for transaction-size optimization, not for exhaustive discovery.
- Use
owner when you only trust or care about LUTs controlled by a specific authority.
- Use
mintsOnly on authority lookups when you are building token-oriented UX and do not need every stored address.
- Treat
estimatedBytesSaved as a planning signal, then still simulate the final transaction.
- Keep pagination logic for authority, account, and mint searches. Popular accounts can appear in many LUTs.
getLookupTablesByAccounts
Find LUTs for multiple accounts or get a best-fit LUT set.
Credits and Rate Limits
Review credit costs and plan limits for RPC calls.