Data Schemas

Data Schemas

Intent JSON Schema • UTXO Format


This section provides formal specifications of the key data schemas used across the SnarkSide protocol stack. These formats are designed for verifiability, compactness, ZK-friendliness, and consistent serialization across off-chain and on-chain systems. All fields are either directly committed to within ZK circuits or are required inputs to proof-generating functions, and thus their precision and structure are critical.


1. Intent JSON Schema

Each user trade intent is a fully encrypted, signed data packet that represents their desired position. Intents are never executed on-chain directly — they are matched off-chain and only verified on-chain in ZK batches.

Below is the canonical pre-commitment format for trade intents.

{
  "version": "1.3.4",
  "timestamp": 1717617302,
  "nonce": "0x3ae3ef7d3b5f4f3c",
  "nullifier": "0x7834fdef1ab3920c42d...",
  "ephemeral_pubkey": "0x037aa4d912...",
  "side": "long", // or "short"
  "leverage": 10,
  "notional": "100000000", // in USD e6
  "price_limit": "3300000", // optional, in USD e6
  "expiry": 1717620902,
  "margin_commitment": "0x023e91ab...", // commitment to margin held in CipherVault
  "intent_hash": "0xposeidon_hash(intent_fields...)",
  "signature": "0xeddsa_signature"
}

Field Explanations

  • version: Used to select circuit version and relayer logic

  • timestamp: Unix time; must be within relayer's max drift window

  • nonce: Nonce to prevent replay within the same vault

  • nullifier: Prevents reuse of same intent in batch matches

  • ephemeral_pubkey: Used to encrypt payload to relayer

  • side: Long/short intent, not revealed outside ZK circuit

  • leverage: Integer leverage factor (1–50 supported)

  • notional: Total exposure requested (e.g., $100 USDC = 100000000)

  • price_limit: Optional limit price (if set, intent is not market)

  • margin_commitment: Poseidon hash of committed margin note

  • intent_hash: Circuit-level hash of all public + private fields

  • signature: Signature over hash of pre-commit using user's stealth key


2. UTXO Format (Encrypted Vault Note)

SnarkSide uses a UTXO-based system for vaults to guarantee unlinkability and multi-position privacy. Each note represents a committed margin-backed position or collateral. UTXOs are not reused — spent notes are nullified and new notes created.

{
  "note_type": "margin" | "position",
  "amount": "0x00f391...", // concealed value (commitment)
  "stealth_address": "0x4a1e90...",
  "note_index": 23121,
  "note_commitment": "0xposeidon(...fields)",
  "circuit_hash": "0xabc...",
  "timestamp": 1717617302,
  "nullifier": "0xdef..."
}

Internal Components (Inside Commitment)

Each note internally commits to:

  • Position side (long/short)

  • Entry price

  • Leverage

  • Expiry timestamp

  • Margin amount

  • Owner pubkey

  • Random salt

The commitment is Poseidon-hashed and stored in the Merkle tree inside CipherVault.


Nullifier Format

All nullifiers are constructed via the following deterministic ZK function:

function deriveNullifier(note_commitment, user_secret, nonce) {
  return Poseidon([note_commitment, user_secret, nonce])
}

3. Serialization and Encoding

  • All hashes are 32-byte Poseidon outputs (hex-encoded)

  • Amounts and prices use fixed-point 6 decimals (USD e6 format)

  • All public keys are X25519 or BabyJubJub (depending on module)

  • Signatures use EdDSA (Poseidon-based) over the circuit input hash

  • All encrypted payloads use AES-256-GCM and are prefixed with nonce


4. Integration Examples

Intent Creation (TypeScript)

const intent = {
  version: "1.3.4",
  timestamp: Date.now() / 1000,
  nonce: crypto.randomBytes(8).toString('hex'),
  nullifier: deriveNullifier(userSecret, nonce),
  ephemeral_pubkey: deriveEphemeralKeypair().publicKey,
  side: "long",
  leverage: 10,
  notional: toFixedE6(100),
  price_limit: null,
  expiry: Date.now() / 1000 + 1800,
  margin_commitment: hashMargin(vaultUTXO),
};
intent.signature = signIntent(intent, userStealthPrivKey);

UTXO Creation (Rust/Circom)

component hash_utxo = Poseidon(8);
hash_utxo.inputs[0] <-- value;
hash_utxo.inputs[1] <-- pubkey_x;
hash_utxo.inputs[2] <-- pubkey_y;
hash_utxo.inputs[3] <-- position_side;
hash_utxo.inputs[4] <-- entry_price;
hash_utxo.inputs[5] <-- leverage;
hash_utxo.inputs[6] <-- expiry;
hash_utxo.inputs[7] <-- salt;

signal note_commitment <-- hash_utxo.output;

Conclusion

SnarkSide’s data schemas are structured to provide robust ZK compatibility, deterministic serialization, and flexible off-chain integration. They form the basis for all encrypted trade flows, margin commitments, relayer routing, and proof generation logic. Any deviation from the schema must undergo formal review, circuit update, and trusted setup regeneration.

Last updated