Skip to main content

Getting Started

A single-page consolidated reference for getting QTG running, authenticated, and verified. If you want a guided multi-step walkthrough instead, use docs/quickstart/ (4 documents, ~30 minutes end-to-end).

Supported platforms

Toolchain:
  • Python 3.14+
  • uv package manager
  • PostgreSQL (Docker Compose provided)
  • Exchange API keys (live mode only)
  • AWS KMS key (EVM proving lanes) or 1Password CLI (dev quickstart)

Quickstart

Minimum environment variables:
  • MG_DATABASE_URL
  • MG_CALLBACK_HMAC_SECRET
  • MG_CALLBACK_ALLOWED_HOSTS_CSV

Docker

Name the services you want. Starting everything also starts qtg-testnet against the same database, and whichever network bucket was not migrated fails its boot check. The Postgres data volume is external so that docker compose down -v cannot delete it. Compose therefore refuses to start when it is absent, which is the intended signal — see docs/quickstart/01-local-setup.md.

Dashboard

The dashboard provides Gateway balances, CCTP transfer tracking, movement management, and route lookup.

Execution modes

Signer backends

The default proving-lane signer is AWS KMS. For dev or for evaluating QTG without AWS, a local private-key signer provides two key sources:
  • 1Password CLI (recommended for local) — keys fetched on demand from your vault.
  • Plain env var (plain) — development only; plaintext key held in process memory. Do not use for fund movement volume. No sign-without-expose guarantee.
Migrate to AWS KMS (or a future signer backend such as Vault Transit / GCP KMS) before scaling. See docs/reference/signers/local-private-key-signer.md and docs/reference/signers/signer-protocol.md.

Multi-signer bootstrap

For redundancy or rotation overlap, configure additional signers via MG_EXTRA_SIGNERS_JSON. Signer health checks run at bootstrap.

CCTP local signer readiness

Activate the EVM / signer section in .env (copied from .env.example). The retained one-shot command is TESTNET-only and can sign and broadcast through AWS KMS. Its presence is not live approval: use it only with a fresh reviewed operator approval for the exact run. Pytest has no CCTP broadcast authority.

Binance master / sub-account model

Binance sub-account bindings are signed through the master credentials — QTG never holds sub-account trading keys. Declare sub bindings with account_role: "sub" and sub_account_uid, omitting access_key and secret_key. For Binance, sub_account_uid is intentionally the sub-account email (Binance sub-account asset and transfer APIs use email / fromEmail); do not put the numeric subUserId / UID there. Master bindings use account_role: "master" and carry credentials. The Binance master API key must have Enable Sub-Account Management so QTG can read sub balances through /sapi/v3/sub-account/assets. See .env.example for the full binding JSON shape.

CEX logical venue alias

MG_CEX_BINDINGS_JSON maps an alias such as binance_lab to the existing Binance provider. If an alias exists, runtime proving and balance both resolve binding-first. Legacy MG_BINANCE_* settings remain as fallback.

Auth model

Inbound request HMAC

Required headers:
  • X-QTG-Key-Id
  • X-QTG-Timestamp
  • X-QTG-Nonce
  • X-QTG-Signature
Canonical string:
  • PATH is the routed, percent-decoded path the server dispatches on — no origin, no query string.
  • QUERY is 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.
A working signed-sender example is provided in the repository’s examples/ directory.

RBAC — 3 roles

Each API key is bound to exactly one role, enforced per route by the HMAC auth middleware: All mutating routes are mirrored into an append-only audit_events table. Query via GET /v3/audit/events (canonical, admin + operator) or the legacy GET /v3/registry/audit. For agent-namespace tenant isolation, see docs/reference/api/v3-endpoints.md.

Outbound callback HMAC (v3)

Headers:
  • X-QTG-Callback-Timestamp
  • X-QTG-Callback-Nonce
  • X-QTG-Callback-Signature-Version: v3
  • X-QTG-Callback-Signature
v3 includes nonce-based replay defense. Receiver implementation requirements: docs/callback-verification-contract.md. A working receiver example is provided in the repository’s examples/ directory.

Schema bootstrap

PostgreSQL only since v0.1.0. Auto-creating tables at startup is no longer supported — a fresh DB is built from the 3-bucket alembic chain (global / mainnet / testnet):
scripts/quickstart.sh runs these for you. Schema changes ship as new migrations in the same chain.
  • Heads are per-bucket — there is no single global “head” revision; upgrade each bucket to its own @head.
  • Startup validation: on boot the server checks that the schema exists and the alembic head matches before accepting traffic — a drifted or unmigrated DB refuses to boot.
  • Existing databases (schema drift, live deployment): managed by the same alembic_v3/ migration chain.
  • One-off data backfills: scripts/ or explicit operational runbooks.
  • Local and container dependency installation: all aligned on uv.
  • Minimum Python: 3.14 (repo-local default + Docker baseline both aligned).
MG_NETWORK_MODE is required and has no default (mainnet | testnet). The server refuses to boot if it is unset; .env.example ships MG_NETWORK_MODE=mainnet.

Runtime surfaces

QTG runs as a single FastAPI service with a few operator-facing surfaces:
  • REST API — the /v3/* movement, template, registry, and signer endpoints, plus /healthz.
  • Dashboard — a React SPA served against the /dashboard/* endpoints (Gateway balances, CCTP transfer tracking, movement management, route lookup).
  • Runtime workers — when MG_WORKERS_ENABLED=true, 8 always-on workers (dispatcher, observer, recovery, callbacks, expiration, proposal expiry, executor health, audit promotion) run and execute real integrations, plus conditional sidecars behind their own flags.
  • CLI tools — preflight, seed, and import utilities for setup and operations.
The repository also ships examples/ (a callback receiver and a signed sender) and docs/ (design, reference, and operational docs).

Verification commands

Health check — once the server is up, GET /healthz returns:

Important runtime nuances

  • Auto-approve. When MG_AUTO_APPROVE_ENABLED=true and strategy_id is provided, policy-matched requests become APPROVED immediately and manual approval is skipped.
  • Address allowlist. On-chain executors apply the DB-level address guard at dispatch time, not at template registration.
  • Callback v3. Nonce-based replay protection is implemented; receivers must store and reject seen nonces.
  • Signer health. Bootstrap runs a health check on every configured signer.
  • EVM proving signer. Defaults to the local AWS KMS signer bootstrapped via MG_LOCAL_SIGNER_*.
  • EVM RPC endpoints. Default to PublicNode URLs for ~24 mainnet + testnet chains so the dev quickstart works out of the box. Per-chain overrides in MG_EVM_RPC_ENDPOINTS_JSON always win; set MG_EVM_RPC_USE_DEFAULTS=false to disable the table entirely. Live broadcast tools (*_live_preflight, Stage 3 harness) ignore defaults regardless — see reference/rpc-defaults.md.

Where to go next