04 - Going Live
Settings required to move from dry-run to real operation. Enable auth, wire callbacks, start workers, deploy with Docker, and configure the address allowlist.
1. Enable Workers
The key setting for moving from dry-run to live:2. Configure Exchange Credentials
To use the CEX executor, you need exchange API keys:These credentials are plaintext on disk. That is a deliberate tradeoff, and it is survivable — but only if your exchange-side IP restriction and withdrawal address whitelist are configured. See Security Tradeoffs § Exchange credentials before you deposit real capital.
3. Configure EVM / Signer (CCTP, Gateway)
To use on-chain executors:Details: Signer protocol, CCTP bridge lane
4. Enable HMAC Auth
4-1. Create API Keys
key_id and secret safely.
4-2. HMAC Signing on the Client
Canonical string layout:PATHis the routed, percent-decoded path the server dispatches on — no origin, no query string.QUERYis the query exactly as sent: no leading?, no sorting, empty string if absent. Sorting before signing transmits bytes you did not sign, and every such request 401s.
4-3. curl Example (With Signature)
4-4. Access Scope by Role
Access is governed by a 3-role axis (admin / operator / agent), set
per key with --role on seed_auth_client. Each route maps to the set of
roles allowed to call it; admin has the widest reach.
Capital-transfer surface (operator + admin):
Details: Auth rollout, v3 API endpoints
5. Wire Callbacks
5-1. Callback Configuration
callback: {"url": "..."} when creating a movement, a callback is delivered on every state change.
5-2. Implement the Callback Receiver
The receiving server should validate:- Signature verification -
X-QTG-Callback-Signatureheader - Timestamp freshness - within 5 minutes
- Reject duplicate nonces - replay defense
- 200 OK response - 4xx is permanent failure, 5xx is retried
Full contract: Callback verification contract Example: Callback receiver example
6. Address Allowlist
The address guard is applied at dispatch time to on-chain executors (CCTP, Gateway, CCIP, Stargate, USDT0, ERC-20 transfer) and to CEX withdrawals. Register the wallet addresses funds move between — not token contracts.Register Addresses
POST /dashboard/allowed-addresses, operator UI /governance/allowlist).
Avoid raw SQL INSERTs — they bypass the audit log, actor attribution, and the
cooling-period stamp.
- EVM addresses are normalized to lowercase automatically
- Revoke with
python -m qtg.interfaces.tools.revoke_allowed_address --allowed-address-id <id> --reason ...(soft-delete, preferred over deletion) - A row is
(chain_family, address, chain_id?)— no token scope. An allowlisted address accepts any token, and omitting--chain-idmatches every chain. - A CEX withdrawal also needs the destination registered in the exchange’s own
whitelist; QTG checks both and fails with
ADDRESS_NOT_WHITELISTEDwhen the exchange address book does not match.
Details: Runbook — Address Allowlist Management · CEX Stuck Node Recovery
7. Docker Deployment
qtg-testnet and two throwaway test
databases; starting everything runs a mainnet and a testnet app against the same
database, and the one whose bucket was not migrated fails its boot schema check.
Service layout:
One database holds one network bucket, so run one of the two app services — not both.
See operator-network-access.md for production exposure topology.
Docker uses the project-root.envthroughenv_file: ../.env.MG_DATABASE_URLis overridden in docker-compose to use the PostgreSQL hostname.
8. Live Cutover Checklist
Things to confirm before production cutover:-
MG_WORKERS_ENABLED=trueconfigured - Exchange API keys configured and balances checked
- EVM RPC endpoints configured (if using on-chain paths)
- Signer configured and preflight passing (if using on-chain paths)
-
MG_AUTH_ENABLED=trueplus API keys issued - Callback secret configured plus receiving server ready
- Address allowlist registered (on-chain paths and CEX withdrawal destinations)
- CEX withdrawal destinations also registered in the exchange’s own whitelist
- Small-value live test - verify end-to-end with a real small transfer, not dry-run
- Dashboard access confirmed
- Callback receiver verification confirmed (signature, nonce, timestamp)
Operational procedures: Secret Rotation · CEX Stuck Node
Replace default RPC endpoints
The quickstart ships PublicNode-based defaults, which are rate-limited and not suitable for live transfers. For production:- Pick a provider per chain (Alchemy, Infura, QuickNode, or self-hosted).
-
Override per-chain in
.env— keep defaults for any chain you do not yet intend to enable: -
In air-gapped or regulated environments, also set
MG_EVM_RPC_USE_DEFAULTS=falseto block any silent fallback to PublicNode.
MG_EVM_RPC_USE_DEFAULTS=true. Set those
explicit URLs before running them.
See rpc-defaults.md for the full shipped chain
list and the CCIP path caveat.