Policy validation
The relayer allowlist, v0 signer and account checks, lookup-table resolution, compute/fee limits and rent policy.
The relayer is a restricted fee payer, not a generic signing oracle. It deserializes only v0 transactions and accepts one protocol instruction from the frozen program, optionally preceded by canonical Compute Budget instructions.
Accepted message shape
- Exactly one required signer: the configured relayer, also the message fee payer and protocol instruction payer.
- Exactly one protocol instruction: frozen
private_swaporunshield. - Optional
setComputeUnitLimitandsetComputeUnitPriceinstructions before the protocol operation; duplicates, unsupported variants and unknown instructions are rejected. - At most the one validated LUT used by the configured transaction shape; all loaded addresses are resolved and checked.
- Serialized bytes at or below the configured cap and never above 1,232 bytes.
Account and state policy
Pool, shielded state, tree generation, page directory, page PDA and spent-nullifier PDA are checked against the frozen SDK derivation rules and on-chain ownership/data. The relayer validates a live root and correct account order/privileges. Unshield recipient token accounts must be canonical associated token accounts for the requested recipient and pool mints.
Private Send is permitted only because its actual instruction is Unshield, whose public recipient is arbitrary. No other supported operation gets arbitrary recipient semantics.
Rejected requests
- Arbitrary System Program or SPL Token transfers.
- Unsupported program IDs or program substitution.
- Unknown zkCPMM discriminators, pool/fee administration, liquidity and configuration instructions.
- Unexpected signers, unexplained accounts/instructions or noncanonical account layout.
- Excessive compute units, priority fee, packet size or total fee/rent exposure.
- Unsupported LUT behavior, stale blockhash, spent nullifier, invalid proof/root/account state.
The exact signed message is simulated before submission. The service checks current rent exposure for a spent-nullifier PDA and any page accounts it expects to create or grow, then applies the configured fee cap and reserve.
Relayed instruction construction
The SDK's privateSwap and unshield instruction builders accept an explicit payer. For a sponsored transaction that payer and the v0 TransactionMessage.payerKey are the relayer public key. The wallet does not sign or send its secret to the API; note authorization remains in the proof generated locally.
For the JSON payload and safe API errors, see Relayer API. For process-local coordination limits, see Status, replay & limits.