Bootstrap & Configuration Reference
Source code:Defines the qtg v3 runtime initialization sequence, configuration model, and FastAPI app wiring.src/qtg/infrastructure/bootstrap.py,src/qtg/pro_loader.py,config.py,main.py
Configuration (Settings)
qtg.config.Settings is a pydantic-settings based settings class. Every setting can be overridden by an environment variable with the MG_ prefix.
Environment variable catalog
Settings load order
PerSettingsConfigDict in pydantic-settings:
.envfile (project root)- Environment variables (
MG_prefix) - Environment variables win over
.env
extra="ignore" is set.
EVM RPC endpoint configuration
MG_EVM_RPC_ENDPOINTS_JSON is a JSON object string whose keys are chain IDs and whose values are RPC URLs.
parse_evm_rpc_endpoints_json() parses it and:
- raises
ValueErrorif the value is not a valid JSON object - skips keys whose value is
Noneor an empty string - converts every key and value to
str
{}) skips CCTP executor and EVM probe registration.
CEX binding configuration
MG_CEX_BINDINGS_JSON is a JSON object string that resolves a logical venue alias into a concrete provider and credential bundle.
Example:
- key = internal QTG exchange key (
binance_lab) provider= concrete adapter factory name (binance)- master credentials and options = values injected when building adapters and fetchers
- a Binance sub binding stores only
sub_account_uid, not credentials - because of current Binance API constraints, that value must be the sub-account email, not a numeric
subUserId/ UID
MG_CEX_BINDINGS_JSONbinding-first- legacy per-adapter credentials and options from
MG_UPBIT_*,MG_BINANCE_*,MG_OKX_*, andMG_BYBIT_*
CCTP Iris configuration
Settings for checking Circle CCTP (Cross-Chain Transfer Protocol) attestations through the Iris API.validate_http_base_url() validates the URL format. It must start with http:// or https://.
Pro-side graceful loading
main.py separates Pro registration into three guarded phases:
collect_pro_dashboard_routers(settings)duringcreate_app()register_pro_factories(settings)at the start oflifespan(), beforebootstrap_runtime(settings=settings)register_pro_routes(app, settings)afterbootstrap_runtime()completes
src/qtg/pro_loader.py. When a Pro distribution is present, the loader reaches the Pro package’s registration hook through this single sanctioned boundary. OSS-only deployments skip these hooks transparently when no Pro package is installed.
Inbound HMAC auth
main.create_app() always installs HMACAuthMiddleware, and actual enforcement is controlled by MG_AUTH_ENABLED.
- if
MG_AUTH_ENABLED=false, the middleware bypasses requests - if
MG_AUTH_ENABLED=true, every/v3/**request except/healthzmust include:X-QTG-Key-IdX-QTG-TimestampX-QTG-NonceX-QTG-Signature
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.
request.state.auth = {key_id, client_id, purpose} is injected.
The key and nonce store is DB-backed. On app startup, app.state.auth_session_factory = AsyncSessionLocal is injected.
Auth seed CLI
Before enablingMG_AUTH_ENABLED=true in an operational environment, seed at least one caller key first.
- creates
ApiClient, or reuses the active client with the same name - creates a new
ApiClientKey - generates a random secret when
--hmac-secretis omitted - prints the result once as JSON on stdout
bootstrap_runtime() initialization sequence
bootstrap_runtime(settings=settings) registers runtime dependencies. The actual sequence in src/qtg/infrastructure/bootstrap.py is:
Stargate is Pro. There is nostargate_enabledbranch in the Freebootstrap.py. Stargate executors register from the Pro package, gated on a Pro-side setting, and are reached only through thepro_loader.register_pro_executors()boundary call shown above.
Representative executors and probes
This document focuses on the core executor families referenced elsewhere indocs/reference/:
All local executors are registered through
LocalExecutorAdapter.
FastAPI app startup sequence
create_app()
whoami, audit, agent_wallet_topups, registry_verify_drift, hyperliquid, ccip_registry, admin_cutover, and admin_signers routers are mounted alongside the core movement/registry/balance routers. Pro-side routers are mounted separately after bootstrap_runtime() via register_pro_routes(app, settings).
lifespan context manager
FastAPI lifespan handles server startup and shutdown.
On startup:
On shutdown:
Important runtime characteristics
-
bootstrap_runtime()runs once fromlifespan: runtime registries are populated at the startup boundary, not when the app object is created. -
Schema is validated, not auto-created:
Base.metadata.create_all()is no longer used. Insteadboot_validate_schema_invariants(settings.network_mode)runs at startup and (a) rejects any non-PostgreSQL dialect (PG-only since v0.1.0), (b) assertspublicand the process-selected network schema exist, and (c) checks the global and selected-network Alembic heads. The unselected network schema and version table are not required or queried. Fresh databases are bootstrapped through the global chain plus one selected network chain, not by the app: -
Runtime is network-class split and process-scoped: sessions are obtained via
session_for(network_class), whileiterate_per_network(...)defaults to the single process-selected network. Registry sync, worker-heartbeat seeding, and worker loops therefore usesettings.network_modeunless a test or explicit administrative caller supplies another target. The in-memory engine/sessionmaker registry retains entries for bothNetworkClassvalues; that capability does not require both physical schemas. -
Audit-descriptor boot check: after Pro routes are mounted,
register_free_audit_descriptors()runs and thenverify_all_mutating_routes_have_descriptors(app, ...)fails fast at boot if any mutating route lacks an audit descriptor (or an@audit_exemptmarker). - Gateway and balance fetcher registration are independent of EVM executor registration: Gateway and CEX balance fetchers can register before any EVM endpoints are available.
-
Worker activation is conditional: background workers run only when
MG_WORKERS_ENABLED=true. Beyond the 8 always-on workers, the conditional workers (evm_nonce_reaper,ccip_stranded_reaper,capital_transfer_followup,balance_snapshot,verify_drift,ccip_drift) are added only when their respective flags are set. See Runtime Workers. -
Logging initialization:
logging.basicConfig(level=logging.INFO)is configured whenmain.pyis imported. -
Toolchain baseline: both local development and the backend Docker image use the
uvlockfile install path. The current minimum supported Python is3.14.
Minimal configuration examples
API-only mode (development / test)
Full operational mode
CCTP-enabled mode
Related documents
- Data Model Reference - table-level detail
- V3 API Endpoints - endpoints exposed by the routers
- Runtime Workers - worker loop details