Running a Relayer Node
Running a Relayer Node
Secure Config • Encrypted Message Queue
Relayer nodes are the off-chain backbone of SnarkSide’s intent-based architecture. They perform the critical functions of:
Aggregating encrypted user trade intents
Computing valid match candidates off-chain
Generating zero-knowledge proofs for match validity
Submitting compressed batches to the on-chain verifier
Given their sensitive operational role, relayers must be deployed with high reliability, strict cryptographic hygiene, and zero-leak message handling. This guide provides a comprehensive overview for running and hardening a SnarkSide relayer node.
1. System Overview
Each relayer is composed of the following core services:
Intent Aggregator
Receives encrypted trade intents via API or pub/sub
Match Engine
Detects viable trade pairs among encrypted intents
Witness Generator
Produces witness inputs for circuit proofs
Proof Generator
Runs Groth16 proof construction using precompiled keys
Batch Submitter
Posts Merkle root, circuit hash, and proof to on-chain
Encrypted Queue
Maintains encrypted, timestamped message bus for intents
2. Secure Configuration
Environment Variables
Set the following in .env:
RPC_URL=https://<your-l2-rpc>
PRIVATE_KEY=0xabc...
VERIFIER_CONTRACT=0x...
RELAYER_IDENTITY_KEY=<your-ed25519 key>
CIRCUIT_HASH=0x...
QUEUE_ENCRYPTION_KEY=<AES256_GCM key>Recommendations
Never run a relayer from a hot wallet
Use a separate signer for relayer submissions with strict withdrawal constraints
Use a hardened enclave (e.g., Intel SGX, Nitro Enclave) for private key usage and proof generation
Only expose intent intake API behind a proxy with IP allowlists or mutual TLS
3. Encrypted Message Queue
Relayers must never expose decrypted user intents. Every message received is:
Encrypted with user’s ephemeral key using X25519 → AES-256-GCM
Timestamped using a cryptographic nonce (Poseidon or SHA256-DRBG)
Stored in a local ring buffer or Redis queue
Cleared only after:
Proof is successfully posted
A TTL (time-to-live) threshold is exceeded
Queue Structure (encrypted):
{
"intent_id": "0xposeidonhash",
"payload": "base64-encoded ciphertext",
"timestamp": 1717612822,
"ttl": 120,
"ephemeral_pubkey": "0x...",
"circuit_version": "v1.3.4"
}Relayers must not inspect or log decrypted messages, even for debugging.
4. Match Loop Logic
The core of the relayer runs a continuous loop:
while (true) {
const intents = pullEncryptedQueue();
const decrypted = decryptIntents(intents);
const matches = findValidMatches(decrypted);
const witness = generateWitness(matches);
const proof = groth16.prove(witness);
const calldata = formatCalldata(proof);
submitToVerifier(calldata);
}Matching must validate:
Notional equivalence
Margin ratio
Leverage bounds
Intent freshness
All matches are run through the circuit-defined
MatchValidityCircuit
5. Proof Lifecycle
User Intent → Encrypted Message Queue → Relayer → Matching →
Witness Generation → Groth16 Prover → Batch Merkle Root →
Verifier.sol → Compressed on-chain recordRelayers must maintain a local Merkle tree for state commitments
Relayer can be challenged if batch commitment mismatches generated root
Proof caching must use ephemeral disk (e.g.,
/tmp) to avoid trace artifacts
6. Uptime Monitoring
To incentivize honest relayer performance, SnarkSide tracks:
Match frequency per relayer identity
Proof success/failure rate
Time-to-batch latency
Encrypted queue throughput
Future releases will include:
Bonded stake slashing for proof failures
zk-SLA attestations (Service Level Proofs)
Decentralized relayer rotation with MPC fallback
7. Deployment Tips
Prefer containerization via Docker with host resource limits
Separate intent ingestion from match+proof generation via internal RPC
Run proof generation in GPU-enabled environments if available (e.g., CUDA zkSNARK variants)
Use rate limiting and intent deduplication to avoid DoS by spam
8. Sample Config Skeleton
relayer:
id: snarkside-mainnet-relayer-01
rpc_url: https://mainnet.l2.rpc
verifier_contract: 0xabc...
circuit_hash: 0xposeidonhash
encryption_key: $QUEUE_ENCRYPTION_KEY
max_batch_size: 64
match_interval_ms: 1500
prover: local
proof_cache: /tmp/proofs
log_level: info
metrics:
enable: true
endpoint: /metrics9. Local Testing
yarn start:relayer
yarn test:match-simulation
yarn test:proof-submitTests will:
Simulate encrypted intent injection
Match mock trades
Generate Groth16 proof using dummy circuit
Post proof to testnet verifier with dry-run
Conclusion
Running a relayer for SnarkSide is a high-responsibility, cryptographically sensitive task. It requires consistent uptime, verifiable honesty, and strict adherence to privacy principles. Operators are rewarded not for visibility—but for silent accuracy, zero-leak performance, and provable output.
Last updated

