Zcash Solana Deploy
Multi-chain · inscriptions · IPFS

One recipe, served on two chains.

RAGU inscribes NFTs on Zcash's transparent layer, mirrors the same collections to Solana via Metaplex Core, and serves both from a single catalog. The art lives on IPFS — the ownership lives on-chain.

Z721 transparent standard MPL-Core on Solana IPFS off-chain art

Dashboard

syncing…
Inscriptions 0 across all collections
Collections 0 live on two chains
Holders 0 unique owners
Volume 0 ZEC all-time traded

Mint activity

last 14 days

By chain

Same collections, same IPFS metadata — minted independently on each chain.

Recent inscriptions

live feed
ItemCollectionChainOwnerAge

How it works

RAGU is a thin protocol over two very different chains. The trick is to keep everything that can be shared off-chain, and let each chain do ownership its own native way.

1

Pin the art

Collection metadata and assets go to IPFS once. Each token resolves to ipfs://<root>/<index>.json.

2

Inscribe on Zcash

A tiny OP_RETURN records the collection and token index. The token "lives" on a carrier UTXO; transferring it is just spending that output.

3

Mirror on Solana

A Metaplex Core asset is created with its uri pointed at the same IPFS file. One metadata record, two chains.

4

Serve from one catalog

A unified API normalizes Zcash indexer state and Solana's DAS into a single shape your app and marketplace read from.

Why off-chain art? The chain only needs a pointer. Keeping bytes off-chain makes minting cheap and keeps the same artwork addressable from any chain — the whole reason RAGU can be multi-chain at all.

Architecture

A shared off-chain layer feeds two chain adapters; both surface into one catalog the storefront reads from.

Shared off-chain layerIPFS / Arweave — same CIDs, same metadata Zcash · Z721OP_RETURN + carrier UTXO Solana · Metaplex Coreuri → same IPFS · DAS API Unified catalog APIone normalized shape Marketplace + dashboardone UI, both chains

Zcash · Z721

Zcash's transparent layer behaves like Bitcoin, but has no native NFT primitive — so Z721 builds one. Data goes in an 80-byte OP_RETURN; ownership follows a carrier UTXO; an indexer enforces the rules.

// inscribe a mint: collection txid + token index → OP_RETURN payload
const payload = z721.encodeMint({ collectionTxid, tokenIndex: 42 });
// 41 bytes — well under the 80-byte ceiling
Transfers are real spends. Whoever controls the carrier UTXO owns the token. That's what makes trustless, on-chain trades possible later.

Solana · Metaplex Core

On Solana there's almost no protocol to write: Metaplex Core handles ownership, transfers, and royalties, and DAS handles indexing. RAGU just creates an asset whose uri is the same IPFS file Zcash points at.

await create(umi, {
  asset,
  name: 'Genesis #42',
  uri:  'ipfs://<root>/42.json',   // ← identical to the Z721 token
  collection,
}).sendAndConfirm(umi);

Unified catalog

Each chain gets an adapter that normalizes to one token shape. The catalog hides the asymmetry — Zcash names/images are resolved from IPFS, Solana's come straight from DAS.

{ chain, collectionId, tokenId, owner,
  name, image, uri, attributes, status }

A single owner query merges holdings across both wallets:

GET /catalog/owners?zcash=t1…&solana=So1…
→ { count: 2, tokens: [ {chain:'zcash'…}, {chain:'solana'…} ] }

API reference

MethodPathReturns
GET/api/statsDashboard totals, activity, chain split, recent feed
GET/catalog/collectionsAll collections across chains
GET/catalog/tokens/:chain/:collection/:idOne normalized token
GET/catalog/owners?zcash=&solana=Merged holdings for a user
GET/healthzHealth check (for Render)

Deploy on Render

This dashboard is a plain Node web service. Push it to a Git repo and create a Render web service, or drop in the included render.yaml blueprint.

RuntimeNode
Build commandnpm install
Start commandnpm start
Health check/healthz
Port. The server reads process.env.PORT, which Render sets automatically — no config needed.