Skip to main content

Relayer

Relayers submit transactions on your behalf. Most users interact via relayer for all operations.

Why Relayers?

  1. No ETH needed - Users don't need gas tokens
  2. Privacy - Your EVM address isn't the msg.sender
  3. UX - Single flow regardless of operation type
User creates proof/signature locally


Sends to relayer (off-chain)


Relayer submits tx


Contract verifies proof (not msg.sender)

Authorization Model

OperationAuthorizationHow It Works
Register BPKEIP-712 signatureUser signs typed data, relayer submits
ShieldEIP-2612 permitUser signs permit, relayer pulls tokens
TransferZK proofProof proves BPK ownership — no signature needed
UnshieldZK proofProof proves BPK ownership — no signature needed

Key insight: For transfer and unshield, the ZK proof IS the authorization. The contract verifies the proof, not msg.sender. This means any relayer can submit the transaction without any trust.

SDK Usage

The SDK handles relayer interaction transparently — just pass useRelayer: true:

const client = await createClient({
chainId: 8453,
relayerUrl: 'https://eb-relayer.zkprivacy.dev',
});

const wallet = client.wallet({ spendingKey: keys.spendingKey, account });

await wallet.USD.registerBPK();

await wallet.USD.shield({ amount: 100_000000n, useRelayer: true });

await wallet.USD.transfer({
to: 'zk1qyp5xs...',
amount: 50_000000n,
useRelayer: true,
});

await wallet.USD.unshield(50_000000n, undefined, { useRelayer: true });

The SDK generates the proof or signature locally, sends it to the relayer, and the relayer submits the transaction on-chain. The user never pays gas.

What Relayer Learns

InformationRelayer Knows?
That you're submitting a txYes
Timing of submissionYes
Transfer amountNo (encrypted)
Your identityNo (if using Tor)