@solsonar/solana-alt-cache
v0.2.0
Published
Address Lookup Table cache for Solana. Preload + lazy fetch + synchronous resolve of all account keys for a VersionedTransaction without per-tx RPC overhead.
Downloads
231
Maintainers
Readme
@solsonar/solana-alt-cache
Address Lookup Table cache for Solana. Preload + lazy fetch + synchronous resolve of all account keys for a VersionedTransaction — no per-tx RPC overhead.
import { Connection } from '@solana/web3.js';
import { AltCache } from '@solsonar/solana-alt-cache';
const connection = new Connection('https://your-rpc-url.com');
const altCache = new AltCache({ connection });
await altCache.preload(KNOWN_ALT_ADDRESSES);
// hot path — synchronous, zero RPC
const allKeys = altCache.resolve(versionedTx);
if (!allKeys) {
// miss — lazy fetch already fired, this tx skipped for now
return;
}
// allKeys is `[static..., loadedWritable..., loadedReadonly...]` — exactly the
// order Solana uses, so `instruction.accountKeyIndexes[i]` indexes into it.Why this exists
Address Lookup Tables are how modern Solana transactions reference more accounts than the legacy 35-account ceiling allows. A v0 VersionedTransaction carries addressTableLookups — pointers to on-chain ALT accounts plus indices into them. Until you fetch and parse the referenced ALTs, you only see the static portion of the tx's account list.
For most Solana applications (validators, RPC nodes) the runtime does this for you. For anything that processes raw transactions — shred listeners, indexers, MEV bots, simulators — you have to do it yourself, and the obvious implementation (one RPC call per tx) defeats the purpose of being on-chain-adjacent in the first place.
This package solves the cache + lazy fill problem cleanly.
- Synchronous
resolve()— no RPC on the hot path. - Batched
preload()— one RPC call for up to 100 ALTs. - Background lazy fetch — on miss, the missing ALTs are fetched in the background. The next time the same ALT shows up,
resolve()returns. - Deduplication — concurrent misses for the same ALT result in one RPC call, not many.
- Event-driven — no
console.loginside the library.
What this package does not do
- It does not listen for transactions. Pair with
@solsonar/solana-shred-parseror your favourite@solana/web3.jsRPC subscription. - It does not parse transactions or instructions — you get a string array of account keys back, and you decode the rest yourself.
- It does not handle ALT lifecycle (deactivation, deletion). It assumes ALTs are stable once seen — true for production-grade routers like Jupiter, where ALTs are extended but rarely re-created.
Install
npm install @solsonar/solana-alt-cache @solana/web3.js@solana/web3.js@^1.91.0 is a peer dependency.
Requires Node 18+.
How resolve works
resolve(vtx)
│
├─ vtx has no ALT lookups → return staticAccountKeys (fast path)
│
├─ all referenced ALTs in cache
│ → return [static..., loadedWritable..., loadedReadonly...]
│ (canonical Solana order — safe to index with accountKeyIndexes)
│
└─ at least one ALT missing
→ schedule background _lazyFetch(missing)
→ return null
→ next tx using the same ALT will succeedHit rate climbs to ~95%+ within minutes in production once your "popular" ALTs (Jupiter, large DEX routers) are loaded.
API
new AltCache(options)
| option | type | default | notes |
| ------------ | --------------------- | ------------- | ------------------------------------------------------ |
| connection | Connection | required | @solana/web3.js Connection (or compatible shape) |
| commitment | string | 'confirmed' | RPC commitment for getMultipleAccountsInfo |
| batchSize | number | 100 | ALTs per RPC call (Solana RPC limit is 100) |
Methods
preload(addrs: string[])— batched RPC fetch + parse.resolve(vtx)— sync. Returnsstring[](base58) ornull.has(addr),get(addr),size()— cache introspection.stats()—{ hits, misses, lazyFetches, preloaded, errors, cached }.
Events
| event | payload |
| --------------- | ---------------------------------------------------- |
| 'preloaded' | { count, total, durationMs } |
| 'lazyFetched' | { addrs: string[], count } |
| 'error' | (err: Error) |
Constants
import {
ALT_HEADER_SIZE, // 56
PUBKEY_SIZE, // 32
DEFAULT_BATCH_SIZE, // 100
DEFAULT_COMMITMENT, // 'confirmed'
} from '@solsonar/solana-alt-cache';Examples
See examples/:
resolve-tx.js— fetch a tx by signature, resolve its ALTs.preload-known.js— preload a list of ALTs from a JSON file, print stats.
Pairs well with
@solsonar/solana-shred-parser— UDP shred listener that emitsVersionedTransactions. Feed them intoaltCache.resolve()and you have full account visibility.@solsonar/yellowstone-grpc-client— Yellowstone Geyser client.
License
MIT
