> ## Documentation Index
> Fetch the complete documentation index at: https://jephalabs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# QTG Overview

> What QTG is, why it exists, and how it orchestrates cross-exchange asset movements end to end.

# QTG v3 Overview

## What is QTG?

One-liner: **A "secure courier system" that safely automates asset movements between exchanges.**

Think about what it takes to send coins between exchanges. To move USDC from Upbit to Binance:

1. Submit a withdrawal request
2. Confirm the withdrawal went through
3. Confirm it arrived on the other side
4. Intervene manually if something fails...

Do all that manually? 24/7 monitoring? Not realistic. **QTG automates this entire process while providing a security layer that guarantees "nothing moves without explicit approval."**

### The courier company analogy

Comparing QTG to a courier company makes the concept intuitive:

```mermaid theme={null}
flowchart LR
    A["①Intake<br/>(Signal/Movement create)"] --> B["②Inspection<br/>(Plan compile & validate)"]
    B --> C["③Approval<br/>(Operator Approve)"]
    C --> D["④Packaging<br/>(Prepare + Sign)"]
    D --> E["⑤Dispatch<br/>(Submit withdrawal)"]
    E --> F["⑥Tracking<br/>(Observe polling)"]
    F --> G["⑦Delivery Confirmation<br/>(Deposit confirmation)"]
    G --> H["⑧Done<br/>(COMPLETED)"]

    style A fill:#e1f5fe
    style C fill:#fff3e0
    style E fill:#fce4ec
    style H fill:#e8f5e9
```

| Courier company                | QTG                                                  |
| ------------------------------ | ---------------------------------------------------- |
| Shipping request               | Movement Request                                     |
| Delivery route (Seoul → Busan) | Plan Template (Upbit→Bithumb, ETH→CCTP→Base)         |
| Delivery driver                | Executor (CEX adapter, CCTP executor)                |
| Package tracking system        | Observer Worker (polling)                            |
| Delivery signature             | Observe Probe (deposit confirmation, finality check) |
| Incident notification          | Callback Outbox (status change notifications)        |

<Tip>
  QTG is **not** a system that finds the cheapest route. Things like optimal path discovery, price comparison, and automatic rebalancing are handled by external systems (Hummingbot, etc.). QTG focuses solely on **safely executing a "send via this route" command**.
</Tip>

***

## Where QTG fits

Most wallet and key-management platforms compete on **custody** — who holds the keys, in what hardware, behind which treasury UI. QTG competes on a different axis: **operational control depth**, while staying non-custodial.

<Frame caption="QTG sits in the 'deep control, non-custodial' corner — control depth comparable to enterprise custody platforms, without holding your keys.">
  <img src="https://mintcdn.com/jephalabs/a_xNC07UyWXz1hoq/images/qtg-positioning-quadrant.svg?fit=max&auto=format&n=a_xNC07UyWXz1hoq&q=85&s=0fe53a5b6c8d1616a174db957a89bc84" alt="Positioning quadrant: custody depth (horizontal) vs policy and delegation control depth (vertical). QTG sits top-left — deep control, non-custodial — distinct from full-custody platforms (top-right) and bare signing primitives (bottom-left)." style={{ background: "white", borderRadius: "12px", padding: "16px" }} width="651" height="737" data-path="images/qtg-positioning-quadrant.svg" />
</Frame>

The lesson the industry keeps re-learning — Mt. Gox, FTX, Celsius — is that licenses and key-storage tech don't prevent losses. The missing layer is always **operational control**: which transfer is allowed, to where, under what budget, approved by whom, and signed only after the policy passes.

### Direct comparison

|                           | **QTG**                                                                            | Fireblocks                          | Turnkey                     | Coinbase SpendPermission     | raw AWS KMS      |
| ------------------------- | ---------------------------------------------------------------------------------- | ----------------------------------- | --------------------------- | ---------------------------- | ---------------- |
| **Custody model**         | Non-custodial movement control                                                     | Custodial-grade MPC custody         | Non-custodial signing infra | Non-custodial smart wallet   | Self-managed key |
| **Key / signing backend** | HSM (AWS KMS) today, signer-pluggable                                              | MPC / TSS (t-of-n)                  | TEE (Nitro Enclave)         | AA smart contract            | HSM, single key  |
| **Policy-engine depth**   | Deep — dispatch-time allowlist + approval/risk plane + budget ledger + reservation | Deep (TAP)                          | Policy language in TEE      | On-chain spend limits        | None             |
| **Delegation precision**  | Bounded top-up envelopes (caps / expiry / staged)                                  | Co-signer & designated-signer rules | API-key scoping             | 5-dimension spend permission | None             |
| **Strategy-state aware**  | **Designed for** — signal → movement loop                                          | No                                  | No                          | No                           | No               |
| **Treasury UI**           | Focused operator dashboard                                                         | Full                                | No                          | Consumer wallet UX           | No               |
| **Built for**             | **Small quant teams priced out of Fireblocks-tier custody**                        | Enterprises                         | Developers                  | Consumers / dApps            | DIY              |

QTG is a **movement control plane**: signing, policy, and budget are coded into the path *right before your strategy code can touch funds*. You get deep control — allowlists, an approval/risk policy plane, a budget ledger, and reservation gates — while staying non-custodial and priced for a small team. And because QTG sits in your signal → movement loop, it is designed to judge *"this withdrawal is abnormal for this strategy's state"* — context a custody vendor structurally cannot see.

<Note>
  **The threat QTG is built for** isn't an external attacker stealing your keys — it's your own strategy code bugging out at 3am and trying to move 10× the intended size to the wrong venue, in a loop. A valid key just signs it. QTG's policy layer is the gate that stops it.
</Note>

***

## Movement Guard Architecture

```mermaid theme={null}
flowchart TB
    subgraph v3["Movement Guard"]
        direction TB
        subgraph transports["Supported Transports"]
            CEX["CEX<br/>(Upbit, Binance, Bybit, Coinbase, OKX;<br/>Bithumb = Pro)"]
            CCTP["CCTP<br/>(Circle Cross-Chain)"]
            GATEWAY["Gateway<br/>(Circle Unified Balance)"]
            BRIDGE["Bridge<br/>(CCIP, USDT0/LayerZero,<br/>Hyperliquid topup; Stargate = Pro)"]
        end
        subgraph graph["Graph-based Plan"]
            N1["Node 1: Withdrawal"] --> N2["Node 2: Withdrawal confirm"]
            N2 --> N3["Node 3: Deposit confirm"]
        end
    end
    style CEX fill:#e8f5e9
    style CCTP fill:#e3f2fd
    style BRIDGE fill:#f3e5f5,stroke-dasharray: 5 5
```

* **Graph-based Plan Template**: Defines the execution graph as nodes and edges
* **Universal Transport**: CEX (Upbit/Binance/Bybit/Coinbase/OKX, plus Bithumb in Pro), CCTP, CCIP, USDT0/LayerZero, Gateway, and Hyperliquid topup. deBridge is illustrative only — it is not implemented.
* **Executor/Signer Protocol**: A standard interface that allows executors to be written in any language
* **Compiled Plan Hash**: Approval is bound to "this exact plan" — the plan cannot be tampered with after approval

<Info>
  **Why "v3"?** v1 (transfer\_guard) was originally a CEX-only transfer guard. v2 was a step execution refactoring plan, but as the v2 design progressed, the conclusion was "a full redesign is better." v1 was deleted, the v2 planning docs were kept as historical reference only, and v3 started as a clean slate.
</Info>

***

## Why was it built?

### 1. Why it was separated from Hummingbot

Asset movements between exchanges were originally embedded inside the Hummingbot trading bot. The problems were:

* **Trading logic and transfer logic mixed together**: If the bot died, the transfer died with it
* **No security boundary**: Trading strategies called withdrawal APIs directly — a strategy bug meant asset exposure risk
* **Lack of operational visibility**: Hard to track "how far along is this transfer right now"

QTG was separated into an **independent control plane** to solve these problems.

### 2. CEX → Bridge expansion

```mermaid theme={null}
flowchart LR
    subgraph cex["CEX Lane"]
        U1[Upbit] <-->|XRP| B1[Bithumb]
    end
    subgraph onchain["On-chain Lane"]
        U2[Upbit] -->|USDC withdrawal| W1[EVM Wallet]
        W1 -->|CCTP Burn| Circle[Circle Attestation]
        Circle -->|CCTP Mint| W2[Base Chain]
        W2 -->|deposit| DEX[Base DEX]
    end
    style cex fill:#fff3e0
    style onchain fill:#e8f5e9
```

Sending between CEX exchanges alone is straightforward. But for DeFi strategies you need:

* CEX withdrawal → on-chain wallet → bridge to another chain → deposit into a DEX

These multi-hop routes require different protocols at each step (CCTP, CCIP, USDT0/LayerZero, Gateway). v3 handles all of this as **one unified framework**. (deBridge appears in some diagrams as a placeholder for "another bridge protocol" — it is not implemented.)

<Warning>
  The v3.0 runtime is **linear-first** — branching and parallel execution are not yet supported. The data model accommodates a DAG (directed acyclic graph), but the runtime only supports sequential execution. Branching/merging is on the Post v3.0 roadmap.
</Warning>

***

## The full flow at a glance

```mermaid theme={null}
flowchart TB
    subgraph ingest["Phase 1: Intake"]
        CREATE["POST /v3/movements<br/>template_key + intent + params"]
        CREATE --> VALIDATE["Compile plan<br/>snapshot + hash"]
        VALIDATE --> PENDING["PENDING_APPROVAL<br/>pending approval"]
    end

    subgraph approval["Phase 2: Approval"]
        PENDING --> APPROVE{"operator decision"}
        APPROVE -->|"approve<br/>(hash verified)"| APPROVED["APPROVED"]
        APPROVE -->|"reject"| REJECTED["REJECTED ❌"]
        PENDING -->|"TTL exceeded"| EXPIRED["EXPIRED ❌"]
    end

    subgraph execution["Phase 3: Execution"]
        APPROVED --> EXECUTING["EXECUTING"]
        EXECUTING --> DISPATCH["Node Dispatcher<br/>preflight → prepare → sign → submit"]
        DISPATCH --> OBSERVE["Node Observer<br/>status polling"]
        OBSERVE --> ADVANCE["Frontier advance<br/>next node READY"]
        ADVANCE --> |"more nodes"| DISPATCH
    end

    subgraph terminal["Phase 4: Terminal"]
        ADVANCE -->|"all nodes done"| COMPLETED["COMPLETED ✅"]
        DISPATCH -->|"failed"| FAILED["FAILED ❌"]
        OBSERVE -->|"unknown state"| MANUAL["MANUAL_INTERVENTION ⚠️"]
    end

    subgraph side["Side Channels"]
        CALLBACK["Callback Outbox<br/>external notification on state change"]
        TIMELINE["Movement Timeline<br/>full event history"]
    end

    EXECUTING -.-> CALLBACK
    COMPLETED -.-> CALLBACK
    FAILED -.-> CALLBACK

    style ingest fill:#e1f5fe
    style approval fill:#fff3e0
    style execution fill:#fce4ec
    style terminal fill:#e8f5e9
    style REJECTED fill:#ffcdd2
    style EXPIRED fill:#ffcdd2
    style FAILED fill:#ffcdd2
    style COMPLETED fill:#c8e6c9
```

### What happens at each stage?

**Stage 1 — Intake (Movement creation)**

* An external system requests "send this amount using this template"
* The Plan compiler validates the graph + generates a deterministic hash
* This hash is **what gets approved** — it guarantees "what I approved is what gets executed"

**Stage 2 — Approval**

* The operator reviews the compiled\_plan\_hash and approves or rejects
* On approval, frontier nodes transition from `BLOCKED` → `READY`
* If not approved within the TTL, the movement expires automatically

**Stage 3 — Execution**

* The Node Dispatcher picks up READY nodes and executes them:
  * `preflight` → precondition checks (can we withdraw? is the address correct?)
  * `prepare` → prepare the action to execute (create a PreparedAction)
  * `sign` → request a signature from the Signer if needed
  * `submit` → actually execute (submit withdrawal, burn tx, etc.)
* The Node Observer polls submitted nodes waiting for completion
* When a node completes, the frontier advances to the next node

**Stage 4 — Termination**

* All nodes complete → `COMPLETED`
* Unrecoverable failure → `FAILED`
* Ambiguous state (withdrawal went through but deposit not confirmed) → `MANUAL_INTERVENTION`

***

## Concrete Proving Lanes

Routes that are "actually E2E verified" — not just "theoretically possible":

1. **CEX Lane**: withdrawal → withdrawal confirm → deposit confirm (Upbit/Binance/Bybit/Coinbase/OKX; Bithumb via the Pro adapter)
2. **EVM Wallet**: CEX withdrawal → receive/finality confirmation on EVM chain
3. **CCTP Lane**: burn → attestation → mint → mint\_receive\_observe → mint\_finality (5 nodes)
4. **Gateway Lane**: intent (EIP-712 sign + API) → mint → finality (3 nodes)
