Infrastructure

Relayer

A relayer broadcasts users' zero-knowledge proofs on-chain so users pay no gas and their wallet never touches the transaction. It charges a flat fee plus a percentage, paid in the transacted token.

What is a Relayer?

A relayer is a node that submits RAIL20 transactions for users. The user signs a message and sends the transfer details; the relayer derives the account keys, builds the zero-knowledge proof, pays the gas, and broadcasts it. Because the user's own wallet never sends the transaction, there is no on-chain link between the user's public address and the pool activity.

Why Use a Relayer?

Transacting directly from your own wallet leaks metadata - your public address, IP, and timing. Routing through a relayer breaks that link, and it lets you transact without holding ETH for gas: the relayer fronts gas and deducts its fee from the transacted token.

Relayer Fee

The relayer fee is a flat amount plus a percentage of the transacted value. Fees are paid to the RAIL20 fee recipient 0xd962c7a67b74EEe8D418189f7917A18577A4775d. There is no on-chain fee-splitting contract and no revenue-sharing tiers.

PoolFlat feePercentage
ETH pool0.00025 ETH0.35%
USDC pool1 USDC0.35%

How It Works

text
1. User signs the RAIL20 message (derives account keys in the browser)
2. User POSTs { signature, pool, amount, recipient } to the relayer (/api/withdraw)
3. Relayer derives the keys, scans the pool, and selects the user's notes
4. Relayer builds the zk-SNARK proof (2 inputs, 2 outputs) and checks nullifier status
5. Relayer submits the transact() call to the token's pool and pays gas
6. Relayer fee (flat + 0.35%) is taken from the transacted token
7. Pool verifies the proof, records nullifiers, inserts commitments

Relayer API

The hosted relayer is served from https://api.rail20.org. Key endpoints:

EndpointPurpose
/api/healthRelayer status and liveness
/api/balanceDerive shielded balance from notes
/api/deposit/preparePrepare a shield (deposit)
/api/withdrawRelay a private withdraw / transfer proof
/api/assetsSupported tokens and pools
/api/intent-statusPoll cross-chain intent settlement

Relaying a Withdrawal

The client sends its account signature and the transfer details; the relayer derives the account keys, builds the zero-knowledge proof, and broadcasts the transaction. The proof is not constructed by the caller.

javascript
// Relay a private withdraw / transfer through the hosted relayer.
const res = await fetch("https://api.rail20.org/api/withdraw", {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify({
    signature,               // wallet signature; derives the account keys
    pool: "usdc",            // "eth" or "usdc" (defaults to "eth")
    amount: "60",            // amount to send
    recipient: bobAddress,   // recipient (shielded address, or public for a withdraw)
    // Batch (max 2, circuit 2-output limit):
    // recipients: [{ address, amount }, { address, amount }]
  }),
});
const { txHash } = await res.json();