Skip to main content
Every self-custody member trades from a Gnosis Safe they alone own. The Safe holds your USDC on-chain and is the maker of your orders. The operator deploys and relays it gaslessly — you only ever sign. It starts as 1-of-1: one owner, either your wallet or the signer contract derived from your passkey. It becomes 1-of-2 if you add a signing key — a second key of your own, where either one alone can sign. Calibri is never an owner in any configuration.

How the Safe fits in

What differs between members is what owns the Safe — see Your wallet options:
  • Owner — either your wallet address (EOA) (linked/SIWE wallet, or an email-derived address), or, for a passkey wallet, a signer contract derived from your WebAuthn credential. Either way, this is what signs.
  • Safe (proxy) — the Gnosis Safe owned by that owner. This is the maker of your orders and the destination for deposits.
The owner also determines the signature type your orders use: 2 (POLY_GNOSIS_SAFE) for a wallet EOA, 3 (POLY_1271) for a passkey signer contract. The config below tells you which — see Signed orders. A member with neither a linked wallet nor a passkey is custodial-only.

The bridge module

Every Safe is created with one module enabled: the CctpBridgeModule. It is switched on by the Safe factory in the same transaction that creates the Safe, so no Safe ever exists without it and nobody can set one up differently first. A Safe module is a contract the Safe lets act without owner signatures — so what matters is what the module’s own, immutable code allows. This one allows exactly one thing: moving that network’s USDC, through Circle’s CCTP, to the same Safe address on Polygon. That is what lets USDC sent to your address on Ethereum, Base, Arbitrum or Optimism reach your Safe on Polygon without you signing anything — see Deposits from other networks. On Polygon the module is present but does nothing: there is no route from Polygon to itself. Withdrawals to other networks do not use the module. They leave your Safe on Polygon as an ordinary Safe transaction you sign, which calls Circle’s messenger directly from the Safe — no module and no Calibri contract is involved, and the destination address is part of what you sign. See Withdrawals to other networks. Your Safe has the same address on every supported network, because the factory and the Safe implementation sit at the same address on each. On a network other than Polygon the Safe is created only when it is first needed, by the same permissionless factory, with the same owner your Polygon Safe was created with. Calibri is never an owner there either.
Passkey wallets: your signer contract exists only on Polygon, so no signature from you can be checked on another network. There, the module cannot be switched off and is the only way USDC can leave your Safe — and anything other than USDC sent there cannot be moved today. A signing key added on Polygon does not carry over to other networks. See the caveats.

1. Deploy & register (operator-gasless)

You do not deploy the Safe yourself. When you first read your CTF config, Calibri ensures your Safe exists — the operator deploys it gaslessly (idempotent) and returns the derived Safe address, then registers it so on-chain transfers to it are credited back to your account. Read your member-level wallet config: GET /api/v2/atlas/account/wallet Returns your funding config: proxy_address (your Safe), owner_address (your Safe’s owner — your EOA, or your passkey signer contract), usdc_address, exchange_address, conditional_tokens_address, chain_id, blockchain_key, domain_name, signature_type, safe_setup, and safe_status.
Read every value above from the API rather than copying it from this page. domain_name in particular is hashed into every order signature, so a stale copy produces a signature that will not recover.
safe_status values:
Do not trade on setup_required. An order placed before the approvals land will rest on the book and then fail to settle — worse than being rejected outright. Only ready is safe to trade on.
For a specific market, use GET /api/v2/atlas/account/wallet/markets/:id instead. It returns the same funding config plus the market’s condition_id, yes_token_id, and no_token_id. It returns 404 for a custodial-only market. See Signed orders.

2. Fund the Safe with USDC

Send USDC to your Safe address (proxy_address) on-chain — from any wallet or exchange. Your off-chain balance_safe mirror is credited once the transfer confirms. USDC sent to the same address on Ethereum, Base, Arbitrum or Optimism is bridged to this Safe on Polygon by the module above and credited the same way, less the bridge fee — see Deposits from other networks.
The Safe must actually hold USDC on-chain. On-chain settlement pulls your real collateral from the Safe when a trade matches; balance_safe is only Calibri’s mirror of that on-chain balance.

3. Make the Safe trade-ready

Before its first trade, the Safe must grant three on-chain approvals:
  1. Approve USDC → the exchange — collateral for your fills
  2. setApprovalForAll on ConditionalTokens → the exchange — your outcome tokens
  3. Approve USDC → the operator, capped — the taker fee pulled at settlement
The third is deliberately bounded, not unlimited: it covers many trades and depletes as fees are collected. When it runs low the config asks you to sign once more to top it up, so setup can recur — it is not strictly one-time. A capped allowance means a compromised operator key could take at most that remaining amount, never your Safe balance. These come back in the config as safe_setup.calls — a list of { to, data, operation, nonce, hash }. Sign each as a Safe SafeTx (EIP-712) with your Safe’s owner and relay it (see below). Handle both shapes: the approvals may arrive batched through Safe’s MultiSend as a single call with operation: 1 (DELEGATECALL) — one signature instead of three — or as three separate calls at sequential Safe nonces, which must be relayed in order. Either way, when setup is complete the config reports:

Relaying a setup call

POST /api/v2/atlas/account/wallet/relay Submits a signed Safe transaction. The operator executes Safe.execTransaction and pays gas. Request body:
Required fields: safe, to, data, signature. value defaults to "0" and operation to 0. Calibri rejects with 400 safe does not belong to this member unless safe equals your own derived Safe address, then forwards to the operator relayer. Response:

The SafeTx typed data

The same SafeTx EIP-712 structure is used for setup approvals, redemption, and withdrawals:
Use value = safeTxGas = baseGas = gasPrice = 0, gasToken = refundReceiver = 0x0, operation = 0 (CALL), and nonce = the Safe’s current on-chain nonce(). A withdrawal to another network is the exception: Calibri builds it for you as one MultiSendCallOnly batch (operation = 1) returned with its quote — the fee transfer, the USDC approval to Circle’s messenger, and Circle’s depositForBurn. Sign it exactly as returned and relay it with the quote’s quote_id; Calibri relays such a batch only when it matches that quote byte for byte, once. See Withdrawals to other networks.

Next steps