> ## 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.

# Venue Health Check

> Verify exchange adapter connectivity and run small-amount live transfer tests

# Venue Smoke Test

CLI tooling for verifying exchange-adapter connectivity and validating the full movement lifecycle with a small stablecoin transfer.

Use it after setting up a new exchange, or after changing credentials or withdrawal allowlists, to confirm the live path still works.

## Prerequisites

* QTG is installed and the `qtg` CLI is available.
* API credentials for the target exchange are configured in environment variables (`MG_*`).
* PostgreSQL is running for smoke tests (`MG_DATABASE_URL`).

## Probe — read-only health check

```bash theme={null}
qtg venue probe <venue> [--asset USDC] [--network ethereum]
```

Runs five read-only checks against an exchange adapter. It does not require a DB connection and does not move funds.

### Checks

| # | Probe                        | What it checks                                                 |
| - | ---------------------------- | -------------------------------------------------------------- |
| 1 | `check_wallet_service`       | Deposit/withdrawal service availability and maintenance status |
| 2 | `check_withdrawal_available` | Withdrawal availability, minimum/maximum amount, and fees      |
| 3 | `get_deposit_address`        | Whether a deposit address can be retrieved                     |
| 4 | `list_deposits`              | Recent deposits, up to 5 entries                               |
| 5 | `list_withdrawals`           | Recent withdrawals, up to 5 entries                            |

### Examples

```bash theme={null}
# Binance USDC on Ethereum
qtg venue probe binance

# Upbit USDT on Tron
qtg venue probe upbit --asset USDT --network tron

# Bybit USDC on Arbitrum
qtg venue probe bybit --asset USDC --network arbitrum

# Coinbase USDC on Arbitrum
qtg venue probe coinbase --asset USDC --network arbitrum
```

### Output

The command prints JSON:

```json theme={null}
{
  "venue": "binance",
  "asset": "USDC",
  "network": "ethereum",
  "ok": true,
  "probes": [
    {
      "name": "check_wallet_service",
      "ok": true,
      "elapsed_ms": 234,
      "summary": {
        "withdrawal_enabled": true,
        "deposit_enabled": true,
        "is_maintenance": false
      },
      "error": null,
      "skipped": false
    }
  ],
  "timestamp": "2026-05-26T12:00:00+00:00"
}
```

### Exit Code

| Code | Meaning                                                   |
| ---- | --------------------------------------------------------- |
| 0    | All probes passed                                         |
| 1    | One or more probes failed, but the adapter was reachable  |
| 2    | Configuration error: unknown venue or missing credentials |

### Special behavior

* If the adapter does not support a method (`NotImplementedError`), that probe is marked **skipped** and does not affect the overall result.
* Probes run sequentially. If one fails, the remaining probes still run.

## Smoke — small live transfer

```bash theme={null}
qtg venue smoke <source> --dest <dest> --amount <n> \
    [--asset USDC] [--network ethereum] [--timeout 300] [--no-confirm]
```

Runs the full movement lifecycle for an actual stablecoin transfer from the source exchange to the destination exchange.

### Safety controls

| Limit               | Value                                                          |
| ------------------- | -------------------------------------------------------------- |
| Allowed assets      | USDC, USDT, DAI only                                           |
| Maximum amount      | \$5                                                            |
| Same exchange       | Rejected when source and destination are the same              |
| Confirmation prompt | Required by default before execution; skip with `--no-confirm` |

These limits are hard-coded and cannot be changed through environment variables.

### Flow

```
1. Validate parameters (asset, amount, source != dest)
2. Prompt for confirmation unless --no-confirm is set
3. Bootstrap runtime and connect to the DB
4. Create the smoke.cex_roundtrip template automatically on first use; reuse it idempotently afterward
5. Fetch the deposit address from the destination exchange
6. Create a template-based movement
7. Auto-approve the movement with approver "smoke-cli"
8. Run the Dispatch -> Observe loop every 5 seconds until timeout
9. Print result JSON
```

### Examples

```bash theme={null}
# Binance -> Upbit, 1 USD of USDC, Ethereum network
qtg venue smoke binance --dest upbit --amount 1

# Run without the confirmation prompt
qtg venue smoke binance --dest upbit --amount 2 --no-confirm

# USDT on Tron
qtg venue smoke bybit --dest binance --amount 1 --asset USDT --network tron

# 10-minute timeout
qtg venue smoke upbit --dest binance --amount 1 --timeout 600
```

### Output

```json theme={null}
{
  "movement_id": "550e8400-e29b-41d4-a716-446655440000",
  "strategy_id": "smoke-binance-upbit-20260526T120000",
  "source": "binance",
  "dest": "upbit",
  "asset": "USDC",
  "network": "ethereum",
  "amount": "1",
  "final_state": "COMPLETED",
  "node_states": {
    "withdraw": "COMPLETED",
    "withdraw_observe": "COMPLETED"
  },
  "duration_seconds": 45.2,
  "error": null
}
```

### Exit Code

| Code | Meaning                                                                    |
| ---- | -------------------------------------------------------------------------- |
| 0    | Movement COMPLETED                                                         |
| 1    | Movement failed, timed out, or errored                                     |
| 2    | Parameter validation failed, such as invalid asset or amount above the cap |

### Dashboard integration

Smoke movements appear in the dashboard like regular movements.
The `strategy_id` uses the `smoke-{source}-{dest}-{timestamp}` format, so it can be filtered in the dashboard.

### Template

Smoke tests use the `smoke.cex_roundtrip` template. The first run creates it automatically; later runs reuse the existing template.

Template shape (2-node DAG):

```
withdraw (cex_withdrawal) → withdraw_observe (cex_withdrawal_status)
```

There is no `deposit_observe` node. The smoke test verifies the withdrawal path; deposit confirmation depends on the destination exchange's internal processing.

## Troubleshooting

### `exit 2: unsupported exchange adapter`

Check whether credential environment variables are set for the venue:

```bash theme={null}
# Binance
echo $MG_BINANCE_ACCESS_KEY

# Upbit
echo $MG_UPBIT_ACCESS_KEY

# Bybit
echo $MG_BYBIT_ACCESS_KEY
```

Also check whether `MG_CEX_BINDINGS_JSON` includes the exchange binding.

### Probe passes but smoke fails

* **DB connection**: smoke tests require PostgreSQL. Confirm `MG_DATABASE_URL` is correct.
* **Whitelist**: confirm the destination exchange deposit address is registered in the source exchange withdrawal whitelist.
* **Travel rule**: transfers involving Korean exchanges may require travel-rule information.
* **Network mismatch**: confirm `--network` refers to the same network on both exchanges. Exchange network names can differ, such as `ethereum` vs `ETH` or `tron` vs `TRX`.

### Movement ends in TIMEOUT

The default timeout is 300 seconds, or 5 minutes. Increase `--timeout` during network congestion. CEX withdrawals can take several minutes to tens of minutes depending on exchange-side processing time.
