Skip to main content

Shielded JSON-RPC reference

Reference for the shielded JSON-RPC and WebSocket surface used by wallets, SDK authors, and indexers. For the conceptual model see Privacy on Mersennet; for typed helpers see the Shielded SDK.

Activation

Shielded methods are gated by the privacy hard fork. Before activation, mutation methods return -32605 ("method disabled in current chain mode") and read methods return zero/empty values.

Encoding conventionโ€‹

All opaque ZK payloads โ€” proofs, encrypted blobs, intent envelopes โ€” are encoded as bincode over the typed Rust struct, then 0x-hex. The SDK provides these encoders/decoders for free. JSON field names use camelCase to match Ethereum conventions.

Chain & treeโ€‹

prime_getChainConfig()โ€‹

Returns the chain ID, privacy activation height, and feature flags (including DKG epoch parameters).

prime_getShieldedRoot()โ€‹

Returns the current note commitment tree root and block number.

prime_getShieldedBalance({ viewKey, accountTag })โ€‹

Wallet-side helper: scans the tree for notes owned by the account tag derived from the viewing key and returns cumulative balance per asset. The match happens client-side โ€” the chain does not learn the address.

prime_getShieldedNotes(...)โ€‹

Returns encrypted notes for client-side scanning.

prime_getShieldedMarketAggregates(marketId)โ€‹

Public market-level stats: last clearing price, last matched size, intent count for the most recent batch-auction tick.

Shielded mutationsโ€‹

MethodPurpose
prime_submitShieldedTransfer({ shieldedTransferBincodeHex })Private P2P transfer: input nullifiers, output commitments, Noir proof.
prime_submitShield({ shieldBincodeHex })Transparent โ†’ shielded: EOA, amount, new note commitment.
prime_submitUnshield({ unshieldBincodeHex })Shielded โ†’ transparent: spent nullifier, recipient EOA, amount.
prime_submitShieldedOrder({ anchorRootHex, nullifierHex, newCommitmentHex, marketId, side, price, size, ownerPkHex, saltHex, tif?, gasLimit?, maxFeePerGas?, proofBytesHex? })Submit a threshold-encrypted shielded order intent; returns an intentId.
prime_submitLiquidationClaim({ claimBincodeHex })Bonded-liquidator-only encrypted liquidation claim.
prime_submitLiquidationExecute({ executeBincodeHex })Auction winner settles the victim's nullifier; mints bounty + insurance.
prime_registerLiquidator({ bondCommitment, bondAmount })One-time registration with a Pedersen bond (bondAmount >= 10,000 PRIM).

See Risk checks in zero knowledge for the liquidation model.

State proofsโ€‹

MethodPurpose
prime_getStateProof(blockNumberOrTag?)SP1 state-transition proof for a block (or "latest"). Accepts [], ["latest"], ["0x1f4"], or [500].
prime_getLatestStateProof()Alias for prime_getStateProof(["latest"]).
prime_verifyStateProof({ proofBincodeHex })Stateless verifier; returns `{ "ok": true

Response shape (when a proof exists):

{
"blockHeight": 500,
"prevStateRoot": "0xโ€ฆ",
"newStateRoot": "0xโ€ฆ",
"prevNullifierRoot": "0xโ€ฆ",
"newNullifierRoot": "0xโ€ฆ",
"blockHash": "0xโ€ฆ",
"newMarketStateHash": "0xโ€ฆ",
"txCount": 12,
"proofBincodeHex": "0xโ€ฆ",
"proofType": "SP1"
}

If the block carries no proof, the response is { "blockHeight": โ€ฆ, "proof": null, "reason": โ€ฆ }. See Verifiable state.

Selective-disclosure (viewing grants)โ€‹

These methods implement the selective-disclosure grant lifecycle. Reads are authorization gates, not decryption oracles โ€” they return encrypted notes or public clearing context for the SDK to reconstruct client-side.

MethodScopePurpose
prime_viewGrantTokenโ€”Mint a scoped, expiring viewing grant for a grantee.
prime_viewRevokeTokenโ€”Revoke a grant immediately.
prime_viewGrantStatusโ€”Report whether a grant is active, expired, or revoked.
prime_viewPortfolioDigestโ€”Authorized digest of the granted portfolio.
prime_viewNotesโ€”Paginated encrypted notes a grant authorizes (for client decryption).
prime_viewBalancesbalances:readEncrypted notes for reconstructPortfolio; node never decrypts.
prime_viewPositionspositions:readPublic clearing context for reconstructPositions.
prime_viewOrdersorders:readPublic clearing context for reconstructOpenOrders.

Pagination: balance-style reads take (grantIdHex, [limit], [cursorHex]).

WebSocket subscriptionsโ€‹

Subscribe via eth_subscribe (Ethereum-style) or prime_subscribe (Mersennet-specific). Both return a hex subscription ID; events arrive as JSON-RPC notifications.

Ethereum-style: newHeads, newPendingTransactions, logs { address?, topics? }.

Mersennet-specific:

SubscriptionParamsPayload
PrimeOrdersTrades(marketId?){ marketId, price, size, side, ts }
PrimeOrdersBook(marketId){ bids, asks, ts }
BatchAuctionResults(marketId?){ marketId, clearingPrice, matchedSize, intentCount }
newShieldedRoot(){ blockNumber, newRoot, notesAdded, nullifiersAdded }
newClearingPrice(marketId?){ marketId, clearingPrice, matchedSize, intentCount }
newAuctionSettled(marketId?){ marketId, winnerBondCommitment, winningBid }
newStateProof(){ blockNumber, prevStateRoot, newStateRoot, blockHash, txCount, proofType }

Privacy-mode payloads are address-free by construction โ€” CI enforces that no address fields leak into shielded events.

wscat -c ws://46.225.30.187:8546
> {"jsonrpc":"2.0","id":1,"method":"prime_subscribe","params":["newShieldedRoot"]}
< {"jsonrpc":"2.0","id":1,"result":"0x1"}

Error codesโ€‹

CodeMeaning
-32600Invalid request
-32601Method not found
-32602Invalid params
-32603Internal error
-32605Method disabled in current chain mode (privacy inactive)
-32606Proof rejected by verifier
-32607Stale anchor root (note tree advanced past the wallet's snapshot)
-32608Double-spend (nullifier already in the set)
-32609Liquidator not registered / bond below minimum

See alsoโ€‹