Dynamic NFTs on XRPL,
without the hand-waving

Two production-grade patterns ship today on the XRP Ledger. They solve different problems and live in different threat models. Knowing which is which is the whole game.

XLS-20d · XLS-46d · live in mainnet · written by builders, not VCs

The two patterns

"Dynamic NFT" is a marketing word that hides two genuinely different mechanisms. Both are live on XRPL. Both produce metadata that changes after mint. They differ in who you trust and what it costs to update.

PATTERN 1

Mutable URI + server-rendered metadata

The NFT is minted with the tfMutable flag. The URI baked on-chain is stable; the JSON it points to is regenerated on every request by your server.

  • Cheap — no transaction per update.
  • Fast — metadata refresh is one HTTP fetch.
  • Trust model: holder trusts the issuer's server.
  • Use when: state changes often, can be derived from the issuer's data, doesn't need on-chain provability.
PATTERN 2

NFTokenModify (XLS-46d)

The issuer rewrites the NFT's URI on-chain by signing an NFTokenModify transaction. New URI is proven by consensus, not by the issuer's word.

  • Provable — every URI change has a tx hash.
  • Censorship-resistant — no single server controls truth.
  • Trust model: holder trusts the ledger.
  • Use when: provenance matters, regulatory record-keeping applies, the holder needs to verify history without the issuer cooperating.
Most "dynamic NFT" implementations on other chains are Pattern 1 in disguise — the metadata URI is mutable IPFS or the issuer's server. They sell it as "on-chain dynamic" to retail. XRPL gives you both patterns named separately so you can pick on purpose.

Quick decision matrix

ConcernPattern 1: Mutable URIPattern 2: NFTokenModify
Cost per update~0 (one HTTP request)One XRPL transaction fee
Update latencyInstantOne ledger close (~3–5s)
Survives issuer downtimeNo — server gone, metadata goneYes — URI lives in ledger state
Update historyWhatever the server logsOn-chain, queryable forever
Holder can verify state without issuerNoYes
Issuer can revoke past statesYes (replace metadata)No (history is permanent)
Right for: live game stats, profile cards, feed reactionsYesOverkill
Right for: provenance, regulated records, badgesRisky (no audit trail)Yes

Live examples in Kairo Vault

All are on mainnet. Connect a wallet and the Dynamic NFTs sub-tab inside NFT Studio surfaces every mutable-flag NFT you hold, what's changed, and a path to modify the ones you issued.

Living Portfolio Card

Mints once, reflects your wallet's current state forever. Tier evolves as XRP balance crosses thresholds.

PATTERN 1 · taxon 1

Quantum-Proof Badge

Updates as your account's Harvest-Now-Decrypt-Later score changes. Earned after rotating to multi-sig + master-disabled.

PATTERN 1 · taxon 2

Tweet Mint

Capture a tweet as a Living NFT. Engagement tier (Bronze → Silver → Gold → Legendary) updates as likes accumulate.

PATTERN 1 · live now

Sake Bottle Provenance

Brewery-signed NFT for premium sake bottles. Each ageing/storage event becomes a new on-chain entry.

PATTERN 2 · brewery partner pilot

Implementation notes from the Kairo Vault stack

Server metadata endpoints (Pattern 1)

The /api/nft/card/:address, /api/nft/quantum/:address, and /api/nft/tweet/:tweetId endpoints all stamp a SHA-256 content hash onto every response and use it as the ETag. Image URLs auto-bust with ?v={hash} so wallets and marketplaces refresh their cached art the moment the metadata changes. Cache-Control is public, max-age=60, must-revalidate — clients pick up updates within ~1 minute, but no regenerate-on-every-request for hot wallets. If-None-Match short-circuits with 304 Not Modified when nothing has changed.

Mutate service (Pattern 2)

The shared dNftMutateService builds NFTokenModify transactions as pure functions. Validates the issuer r-address and the 64-character hex NFTokenID. Round-trips UTF-8 URI strings (Japanese-language URIs work). Emits the transaction JSON; signing stays with the wallet adapter (Crossmark, GemWallet, WalletConnect, Xaman). Kairo Vault never handles secret material.

Dynamic NFTs sub-tab (consumer surface)

Lists every mutable-flag NFT you hold, grouped by "issued by you" vs "held from other issuers". Per-NFT card surfaces taxon, flags, current URI, and previews the metadata. Refresh re-fetches Pattern-1 metadata; "Modify on-chain" opens a Pattern-2 form for NFTs you issued.

Try it on the live demo → XLS-46d spec on GitHub

What we're not pitching

You don't need a fork of rippled, a sidechain, an oracle network, or an off-chain indexer to ship dynamic NFTs on XRPL. Both patterns above run on stock mainnet today. The only good reason to add infrastructure beyond what's described here is when your specific use case requires something neither pattern provides — and most don't.