Reading Compressed Assets (DAS)
Compressed NFTs do not have per-asset accounts readable via getAccountInfo. Production apps use the DAS API to fetch asset metadata, compression fields, and merkle proofs for transfers.
Search across all documentation pages
Compressed NFTs do not have per-asset accounts readable via getAccountInfo. Production apps use the DAS API to fetch asset metadata, compression fields, and merkle proofs for transfers.
const asset = await dasRpc("getAsset", { id: "CNFT_ID" });
const proof = await dasRpc("getAssetProof", { id: "CNFT_ID" });const collection = await dasRpc("getAssetsByGroup", {
groupKey: "collection",
groupValue: "COLLECTION_ID",
page: 1,
limit: 100,
});When to reach for this:
const DAS_RPC = process.env.DAS_RPC_URL!;
async function dasRpc<T>(method: string, params: unknown): Promise<T> {
const res = await fetch(DAS_RPC, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params }),
});
const json = await res.json();
if (json.error) throw new Error(json.error.message);
return json.result as T;
}
type DasAsset = {
id: string;
compression?: {
eligible: boolean;
compressed: boolean;
leaf_id: number;
tree: string;
seq: number;
};
content?: { metadata?: { name?: string } };
};
type AssetProof = {
root: string;
proof: string[];
node_index: number;
leaf: string;
tree_id: string;
};
const assetId = "CNFT_ASSET_ID_FROM_PRIOR_QUERY";
const asset = await dasRpc<DasAsset>("getAsset", { id: assetId });
console.log("name:", asset.content?.metadata?.name);
console.log("tree:", asset.compression?.tree);
console.log("leaf:", asset.compression?.leaf_id);
const proof = await dasRpc<AssetProof>("getAssetProof", { id: assetId });
console.log("proof nodes:", proof.proof.length);
console.log("root:", proof.root);import { createSolanaRpc } from "@solana/kit";
// Standard RPC for sending txs; DAS for reads and proofs
const txRpc = createSolanaRpc(process.env.RPC_URL!);What this demonstrates:
getAsset returns compression metadata for cNFTsgetAssetProof supplies sibling hashes for Bubblegum instructionsid consistently - not tree pubkey alonegetAssetProof must match current root - refresh before tx buildgetAssetsByGroup lists collection cNFTs with pagination| Field | Meaning |
|---|---|
compression.tree | Merkle tree account pubkey |
compression.leaf_id | Leaf index in tree |
compression.seq | Sequence for concurrent updates |
id | DAS asset identifier for follow-up calls |
// Cache asset metadata longer than proofs
// proofs TTL: seconds to minutes during active mint windowsid from getAssetsByOwner.seq - rare concurrent update issues. Fix: include latest seq from asset in transfer builder when required.| Alternative | Use When | Don't Use When |
|---|---|---|
| Self-hosted merkle indexer | Full control | Fast MVP |
| Helius/Tensor APIs | Vendor SDK convenience | Standard DAS suffices |
| On-chain only reads | Impossible for full metadata | cNFT products |
Leaves are not full accounts - indexers reconstruct state and expose unified API.
Asset: metadata + compression fields. Proof: merkle siblings for transactions.
Whenever tree root changes - refetch per transaction during active periods.
getAssetsByGroup with collection grouping key/value.
Provider-specific - confirm DAS devnet on dashboard.
Scale API tier; cache metadata; minimize proof fetches.
Typically indicates compressed NFT type in DAS schema.
See rpc-websockets-das-api/the-das-api for general setup.
Follow Metaplex SDK expectation when feeding Bubblegum transfer - use official builders when possible.
Indexer lag - retry; verify mint tx success on explorer.
Different product - cNFT focus here; DAS covers multiple interfaces.
fetch for DAS; kit for transaction send after building with Umi/mpl-bubblegum.
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, and LiteSVM 0.6.x.
Reviewed by Chris St. John·Last updated Jul 16, 2026