@continuumdao/ctm-mpc-defi 0.2.16 → 0.2.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,7 +14,10 @@ Before creating, call `get_multi_sign_gas_options({ chainId })` when gas prefere
14
14
 
15
15
  ### After submit (`{ requestId }`)
16
16
 
17
- 1. `wait_for_sign_request_ready` (if needed)
18
- 2. `sign_request_agree` (multi-agree)
19
- 3. `trigger_sign_result`
20
- 4. `broadcast_sign_result`
17
+ Stop here unless the user asks to continue. **Do not** call `wait_for_sign_request_ready` — Join agreement (`sign_request_agree` on peers) may take **days**.
18
+
19
+ When proceeding (user request or workflow, after quorum):
20
+
21
+ 1. `sign_request_agree` (multi-party Join)
22
+ 2. `trigger_sign_result` (originator Get Sig)
23
+ 3. `broadcast_sign_result`
@@ -0,0 +1,63 @@
1
+ ---
2
+ name: circle-cctp
3
+ description: Circle CCTP V2 cross-chain native USDC via Forwarding Service and Continuum MPC multisign.
4
+ ---
5
+
6
+ # Circle CCTP (MCP)
7
+
8
+ Cross-chain **native USDC** via Circle **CCTP V2** and the **Forwarding Service**. The MPC wallet signs **one source-chain batch** (`USDC.approve` + `TokenMessengerV2.depositForBurnWithHook` with `cctp-forward` hook data). Circle attests and submits the **destination mint** — no second sign request, no destination native gas from the KeyGen address.
9
+
10
+ ## Before any transfer
11
+
12
+ 1. `load_defi_protocol({ protocolId: "circle-cctp" })`
13
+ 2. `get_defi_protocol_skill`
14
+ 3. `get_chain_registry` — source chain needs `rpcGateway`
15
+ 4. `get_token_registry` — locate USDC on source chain
16
+
17
+ ## Tool flow
18
+
19
+ | Step | Tool | Creates sign request? |
20
+ |------|------|------------------------|
21
+ | 1. Routes | `ctm_cctp_fetch_supported_routes` | No |
22
+ | 2. Fees | `ctm_cctp_fetch_burn_fees` | No — **required before build** |
23
+ | 3. Balance | `ctm_cctp_fetch_usdc_balance` | No — pre-check USDC ≥ transfer + maxFee |
24
+ | 4. Submit | `ctm_cctp_build_burn_multisign` | Yes → `{ requestId, fees }` |
25
+ | 5. (optional) Status | `ctm_cctp_fetch_transfer_status` | No — after source burn Execute |
26
+
27
+ After `{ requestId }`: `sign_request_agree` → `trigger_sign_result` → `broadcast_sign_result`. **Do not** retry build on success. Fees refresh again at **trigger** on the node app.
28
+
29
+ ## `ctm_cctp_fetch_burn_fees`
30
+
31
+ | Field | Required | Notes |
32
+ |-------|----------|-------|
33
+ | `sourceChainId` | yes | EIP-155 id where burn executes |
34
+ | `destChainId` | yes | EIP-155 destination (mint chain) |
35
+ | `transferAmountHuman` | no | USDC recipient receives (6 decimals); include for `totalBurn` / `totalBurnHuman` |
36
+ | `feeTier` | no | `low` \| `med` (default) \| `high` |
37
+
38
+ Returns `fees` object plus top-level fee fields: `maxFeeHuman`, `forwardFeeLowHuman` / `Med` / `High`, optional `totalBurnHuman`, and `feeSummary`. Pass the full output as `feeSnapshot` to build and balance tools.
39
+
40
+ ## `ctm_cctp_fetch_usdc_balance`
41
+
42
+ Optional `transferAmountHuman` + `feeSnapshot` (from fetch_burn_fees) returns `requiredTotalBurnHuman`, `sufficientForTransfer`, and `feeSummary`.
43
+
44
+ ## `ctm_cctp_build_burn_multisign`
45
+
46
+ | Field | Required | Notes |
47
+ |-------|----------|-------|
48
+ | `keyGenId` | yes | MPC KeyGen |
49
+ | `chainId` | yes | **Source** chain (same as fee quote) |
50
+ | `destChainId` | yes | Destination chain |
51
+ | `purposeText` | yes | Human-readable purpose |
52
+ | `transferAmountHuman` | yes | Same as fee quote |
53
+ | `mintRecipient` | no | Destination address; default executor |
54
+ | `feeSnapshot` | no | Pass `ctm_cctp_fetch_burn_fees` output |
55
+ | `useCustomGas` | no | Chain registry custom gas |
56
+
57
+ Returns `{ requestId, fees }` — `fees` echoes the proposed Forwarding Service max fee and total burn.
58
+
59
+ ## Important
60
+
61
+ - **chainId** on build = **source** chain, not destination.
62
+ - Manual `receiveMessage` on destination is **out of scope** — Forwarding Service only.
63
+ - Solana/non-EVM recipients: follow Circle docs for `mintRecipient` encoding; UI v1 is EVM-only.
@@ -14,7 +14,7 @@ Perpetuals on Arbitrum (42161) and Avalanche (43114) via `@gmx-io/sdk` v2 **clas
14
14
  1. `load_defi_protocol({ protocolId: "gmx" })`
15
15
  2. `ctm_gmx_fetch_markets({ chainId })` — pick `symbol` e.g. `ETH/USD [WETH-USDC]`; each row includes `maxLeverageLabel`
16
16
  3. `ctm_gmx_fetch_market_prices({ chainId, symbol, collateralSymbol })` — index/collateral USD mark
17
- 4. `ctm_gmx_fetch_ohlcv({ chainId, symbol, timeframe: "15m" })` — tabular OHLCV candles (USD index)
17
+ 4. `ctm_gmx_fetch_ohlcv({ chainId, symbol, timeframe: "15m" })` — tabular OHLCV candles (USD index); then **`continuum__prepare_chart_from_rows`** if the operator wants a chart
18
18
  5. `ctm_gmx_fetch_positions({ chainId, executorAddress })` — for close flows
19
19
  6. `get_multi_sign_gas_options({ chainId })` — confirm `useCustomGas` with the user
20
20
  7. `ctm_gmx_build_increase_multisign` or `ctm_gmx_build_decrease_multisign` with `keyGenId`, `chainId`, `purposeText`, `useCustomGas` → **`{ requestId }`**
@@ -63,6 +63,30 @@ Keeper execution is asynchronous (same as perp orders). Execution fee is paid in
63
63
  2. `ctm_gmx_build_stake_gmx_multisign` — approve GMX + `RewardRouter.stakeGmx`
64
64
  3. `ctm_gmx_build_unstake_gmx_multisign` — `RewardRouter.unstakeGmx`
65
65
 
66
+ ## Charting OHLCV (required second step)
67
+
68
+ **Fetching candles does not render a chart.** When the operator asks to chart/graph/plot GMX perp OHLCV:
69
+
70
+ 1. **`ctm_gmx_fetch_ohlcv`** — returns `{ symbol, timeframe, candles }` (USD index; **no volume** on rows → volume pane omitted).
71
+ 2. **Same agent turn** — **`continuum__prepare_chart_from_rows`** with the **full fetch JSON** as **`toolResult`** and a **`title`** (symbol + timeframe + window).
72
+
73
+ ```json
74
+ {
75
+ "title": "ETH/USD 1H — last 7d",
76
+ "toolResult": {
77
+ "symbol": "ETH/USD [WETH-USDC]",
78
+ "timeframe": "1h",
79
+ "candles": [
80
+ { "timestampMs": 1700000000000, "open": "3200", "high": "3250", "low": "3180", "close": "3225", "timeLabel": "..." }
81
+ ]
82
+ }
83
+ }
84
+ ```
85
+
86
+ Increase **`limit`** (max 500) or use a coarser **`timeframe`** for longer history. Default limit is small (~16 bars) — raise **`limit`** when charting a multi-day window.
87
+
88
+ **Never** reply with markdown-only chart descriptions. The UI renders **`continuum/chart/v1`** only from the **`prepare_chart_from_rows`** MCP result. See node skills **`chart-defaults`** / **`chart-periods`**.
89
+
66
90
  ## Troubleshooting
67
91
 
68
92
  | Symptom | Likely cause |
@@ -70,3 +94,4 @@ Keeper execution is asynchronous (same as perp orders). Execution fee is paid in
70
94
  | Agent says custom gas "will fail" without baseFee | Wrong — empty registry fees are valid; use `get_multi_sign_gas_options` |
71
95
  | Multiple duplicate sign requests | Retried `ctm_gmx_build_*` after `{ requestId }` — do not retry on success |
72
96
  | Order pending after broadcast | Normal — GMX keeper executes asynchronously |
97
+ | User asked to chart but only got prose / no widget | Call **`continuum__prepare_chart_from_rows`** with full **`ctm_gmx_fetch_ohlcv`** JSON as **`toolResult`** in the same turn |
@@ -58,7 +58,7 @@ Positions and orders from MCP reflect **live HyperCore state** after prior txs a
58
58
  | List all perp markets + HIP-3 dexes | `ctm_hyperliquid_fetch_markets` |
59
59
  | **Find market by ticker or name** (AAPL, Apple, BTC) | `ctm_hyperliquid_search_markets` |
60
60
  | **Live price** (mark/mid) + short recent bars | `ctm_hyperliquid_fetch_market_snapshot` — use **`snapshot.livePrice.midUsd`** |
61
- | **OHLCV history** (e.g. 15m for last 7 days) | `ctm_hyperliquid_fetch_ohlcv` — `lookbackDays: 7`, `interval: "15m"` |
61
+ | **OHLCV history** (e.g. 15m for last 7 days) | `ctm_hyperliquid_fetch_ohlcv` — then **`continuum__prepare_chart_from_rows`** if user wants a chart |
62
62
  | Account + capacity for one coin | `ctm_hyperliquid_fetch_open_context` |
63
63
  | Open positions | `ctm_hyperliquid_fetch_positions` |
64
64
  | Open orders | `ctm_hyperliquid_fetch_open_orders` |
@@ -182,6 +182,66 @@ Use **`ctm_hyperliquid_fetch_ohlcv`** — not `fetch_market_snapshot` (snapshot
182
182
  - Check **`ohlcv.candleCount`** vs **`ohlcv.expectedBars`** to confirm the full range was returned.
183
183
  - Default lookback if none specified: **1 day**.
184
184
 
185
+ Fetch returns:
186
+
187
+ ```json
188
+ {
189
+ "ohlcv": {
190
+ "coin": "ETH",
191
+ "interval": "1h",
192
+ "candleCount": 73,
193
+ "candles": [
194
+ { "timestampMs": 1700000000000, "open": "1700", "high": "1710", "low": "1690", "close": "1705", "volume": "12345" }
195
+ ]
196
+ },
197
+ "resolvedCoin": "ETH"
198
+ }
199
+ ```
200
+
201
+ ## Charting OHLCV (required second step)
202
+
203
+ **Fetching candles does not render a chart.** The node app only draws candlesticks when **`continuum__prepare_chart_from_rows`** (or **`continuum__prepare_chart`**) returns `kind: continuum/chart/v1`. The widget appears under the **MCP result** row for that chart tool — **not** in the assistant text bubble.
204
+
205
+ When the operator asks to **chart**, **graph**, or **plot** Hyperliquid OHLCV:
206
+
207
+ 1. **`ctm_hyperliquid_fetch_ohlcv`** — get history (same agent turn).
208
+ 2. **`continuum__prepare_chart_from_rows`** — **immediately after**, in the **same turn**. Pass the **full fetch JSON** as **`toolResult`** (entire object from step 1, not just `candles` alone). **`title` is required** — describe asset, interval, and window (e.g. `ETH-PERP 1H — last 3d`), not the user chat verbatim.
209
+
210
+ ```json
211
+ {
212
+ "title": "ETH-PERP 1H — last 3d",
213
+ "toolResult": {
214
+ "ohlcv": {
215
+ "coin": "ETH",
216
+ "interval": "1h",
217
+ "candles": [ "... entire fetch output ..." ]
218
+ },
219
+ "resolvedCoin": "ETH"
220
+ }
221
+ }
222
+ ```
223
+
224
+ Or pass the **complete** step-1 tool result unchanged:
225
+
226
+ ```json
227
+ {
228
+ "title": "ETH-PERP 1H — last 3d",
229
+ "toolResult": { "... paste full ctm_hyperliquid_fetch_ohlcv JSON ..." }
230
+ }
231
+ ```
232
+
233
+ **Never:**
234
+
235
+ - Reply with markdown tables or prose (“chart prepared”, “EMA(50) overlay”, period high/low) **instead of** calling `prepare_chart_from_rows`.
236
+ - Pass `{}` or truncated JSON to the chart tool.
237
+ - Skip the chart tool because fetch already returned candles.
238
+
239
+ **On success:** the MCP result shows `[Chart prepared: … · continuum/chart/v1]` and the interactive chart widget. If that line is missing, **no chart was rendered** — do not tell the user it was.
240
+
241
+ Default overlays (EMA 50, RSI 14, volume pane) are applied inside `prepare_chart_from_rows` when rows include **`volume`**. See node skills **`chart-defaults`** and **`chart-periods`** (initial load). Optional: read MCP resource **`chart_docs`**.
242
+
243
+ Trim to **≤ ~400 bars** for agent chat (`options.maxPoints: 400`) when the fetch returns more than needed — keep the **newest** bars.
244
+
185
245
  ## HIP-3 dexes
186
246
 
187
247
  HIP-3 builder perps (e.g. **XYZ** dex) are **not** in the default native meta alone. `fetch_markets` without `dex` returns **native + every listed HIP-3 dex** in one response.
@@ -196,6 +256,7 @@ HIP-3 builder perps (e.g. **XYZ** dex) are **not** in the default native meta al
196
256
  | Symptom | Likely cause |
197
257
  |---------|----------------|
198
258
  | Agent quotes stale price (e.g. old hourly close) | Use **`snapshot.livePrice.midUsd`**, not a random candle from truncated history; republish defi with live-price fix |
259
+ | User asked to chart but only got prose / no widget | **`fetch_ohlcv` alone does not render** — call **`continuum__prepare_chart_from_rows`** with full fetch **`toolResult`** in the same turn; chart appears under MCP result, not assistant text |
199
260
  | `fetch_market_snapshot` throws on HIP-3 | Missing dex — pass `coin: "xyz:AAPL"` or `dex: "xyz"` |
200
261
  | `availableToBuy` / `availableToSell` is 0 | No perp margin, leverage too high, or USDC still in spot — transfer to perp |
201
262
  | Order succeeds on-chain but no position | Limit not filled yet; IoC may partially/fully reject |