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.
Recipe
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:
- Rendering cNFT galleries in wallets
- Fetching proofs before building transfer transactions
- Verifying tree id and leaf index for debugging
- Collection dashboards after mass mint
Working Example
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:
getAssetreturnscompressionmetadata for cNFTsgetAssetProofsupplies sibling hashes for Bubblegum instructions- Use DAS-returned
idconsistently - not tree pubkey alone
Deep Dive
How It Works
- Indexer tracks Bubblegum events and tree account updates
- DAS normalizes compressed assets alongside Core and Token Metadata
getAssetProofmust match current root - refresh before tx buildgetAssetsByGrouplists collection cNFTs with pagination
DAS Fields for cNFTs
| 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 |
TypeScript Notes
// Cache asset metadata longer than proofs
// proofs TTL: seconds to minutes during active mint windowsGotchas
- Using mint pubkey as cNFT id - DAS lookup fails. Fix: use
idfromgetAssetsByOwner. - Stale proof - tx fails with root mismatch. Fix: refetch proof immediately before sign.
- No DAS on public RPC - method missing. Fix: provider URL with DAS enabled.
- Pagination gaps - incomplete collection during mint. Fix: paginate until empty page after mint ends.
- Ignoring
seq- rare concurrent update issues. Fix: include latest seq from asset in transfer builder when required.
Alternatives
| 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 |
FAQs
Why DAS for cNFTs?
Leaves are not full accounts - indexers reconstruct state and expose unified API.
getAsset vs getAssetProof?
Asset: metadata + compression fields. Proof: merkle siblings for transactions.
How often do proofs expire?
Whenever tree root changes - refetch per transaction during active periods.
Collection query method?
getAssetsByGroup with collection grouping key/value.
Devnet support?
Provider-specific - confirm DAS devnet on dashboard.
Rate limits?
Scale API tier; cache metadata; minimize proof fetches.
interface field value?
Typically indicates compressed NFT type in DAS schema.
Link to standard DAS page?
See rpc-websockets-das-api/the-das-api for general setup.
Proof array order?
Follow Metaplex SDK expectation when feeding Bubblegum transfer - use official builders when possible.
Missing asset after mint?
Indexer lag - retry; verify mint tx success on explorer.
Fungible compressed?
Different product - cNFT focus here; DAS covers multiple interfaces.
kit 7.0.0 integration?
fetch for DAS; kit for transaction send after building with Umi/mpl-bubblegum.
Related
- Reading NFTs (DAS API) - general NFT reads
- Transferring cNFTs - use proof in tx
- How Compression Works - proof theory
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.