@michaleffffff/mcp-trading-server 3.0.4 → 3.0.7

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.
Files changed (55) hide show
  1. package/CHANGELOG.md +42 -6
  2. package/README.md +49 -414
  3. package/TOOL_EXAMPLES.md +63 -559
  4. package/dist/auth/resolveClient.js +19 -2
  5. package/dist/prompts/tradingGuide.js +16 -23
  6. package/dist/server.js +20 -2
  7. package/dist/services/balanceService.js +4 -4
  8. package/dist/services/marketService.js +48 -12
  9. package/dist/services/poolService.js +45 -44
  10. package/dist/services/tradeService.js +51 -23
  11. package/dist/tools/accountInfo.js +5 -134
  12. package/dist/tools/accountTransfer.js +7 -12
  13. package/dist/tools/adjustMargin.js +1 -1
  14. package/dist/tools/cancelOrders.js +71 -0
  15. package/dist/tools/checkAccountReady.js +75 -0
  16. package/dist/tools/checkApproval.js +1 -1
  17. package/dist/tools/closeAllPositions.js +9 -7
  18. package/dist/tools/closePosition.js +18 -11
  19. package/dist/tools/createPerpMarket.js +1 -1
  20. package/dist/tools/executeTrade.js +6 -6
  21. package/dist/tools/findPool.js +26 -0
  22. package/dist/tools/getAccountSnapshot.js +47 -0
  23. package/dist/tools/getAllTickers.js +5 -4
  24. package/dist/tools/getBaseDetail.js +1 -1
  25. package/dist/tools/getKline.js +7 -4
  26. package/dist/tools/getMyLpHoldings.js +3 -2
  27. package/dist/tools/getNetworkFee.js +1 -1
  28. package/dist/tools/getOrders.js +46 -0
  29. package/dist/tools/getPoolMetadata.js +95 -0
  30. package/dist/tools/getPositionsAll.js +80 -0
  31. package/dist/tools/{getMarketPrice.js → getPrice.js} +8 -5
  32. package/dist/tools/getUserTradingFeeRate.js +66 -3
  33. package/dist/tools/index.js +15 -19
  34. package/dist/tools/listPools.js +53 -0
  35. package/dist/tools/manageLiquidity.js +4 -4
  36. package/dist/tools/manageTpSl.js +234 -0
  37. package/dist/tools/openPositionSimple.js +27 -8
  38. package/dist/tools/searchTools.js +35 -0
  39. package/dist/utils/mappings.js +10 -7
  40. package/package.json +2 -2
  41. package/dist/tools/cancelAllOrders.js +0 -57
  42. package/dist/tools/cancelOrder.js +0 -22
  43. package/dist/tools/getAccountVipInfo.js +0 -20
  44. package/dist/tools/getKlineLatestBar.js +0 -28
  45. package/dist/tools/getOraclePrice.js +0 -22
  46. package/dist/tools/getPoolList.js +0 -17
  47. package/dist/tools/getPoolSymbolAll.js +0 -16
  48. package/dist/tools/getPositions.js +0 -77
  49. package/dist/tools/marketInfo.js +0 -88
  50. package/dist/tools/orderQueries.js +0 -51
  51. package/dist/tools/poolConfig.js +0 -22
  52. package/dist/tools/positionHistory.js +0 -28
  53. package/dist/tools/searchMarket.js +0 -21
  54. package/dist/tools/setTpSl.js +0 -50
  55. package/dist/tools/updateOrderTpSl.js +0 -34
package/TOOL_EXAMPLES.md CHANGED
@@ -1,53 +1,14 @@
1
- # MYX MCP Tool Examples Handbook
1
+ # MYX MCP Tool Examples Handbook (v3.0.4)
2
2
 
3
- This handbook is designed for AI assistants and integrators.
4
- It includes:
5
- - clear parameter unit rules,
6
- - common end-to-end workflows,
7
- - at least one practical call example for every exposed tool.
8
-
9
- > All examples use MCP call payload shape:
10
- > `{ "name": "<tool_name>", "arguments": { ... } }`
11
-
12
- ---
13
-
14
- ## 1) Parameter Units & Precision (Important)
15
-
16
- - **Human-readable by default** (many trading tools): `"100"` means 100 quote tokens (e.g., USDC).
17
- - **Raw-unit override**: use `"raw:<integer>"` when supported by the tool.
18
- - **Price precision**: many low-level trading paths expect **30-decimal raw price**.
19
- - **Token amount precision**: depends on token decimals (e.g., USDC often 6).
20
- - **Slippage (`slippagePct`)**: 4-decimal integer style (e.g., `100 = 1%`, `50 = 0.5%`).
21
- - **Approval tool** (`check_approval`) uses **raw integer amount**.
3
+ This guide provides practical payload examples for the consolidated toolset.
4
+ All examples follow the MCP format: `{ "name": "...", "arguments": { ... } }`.
22
5
 
23
6
  ---
24
7
 
25
- ## 2) Common Operation Flows
8
+ ## 🟢 Trading Operations
26
9
 
27
- ## Flow A: Discover Market → Open Position (Recommended)
28
- 1. `search_market` (keyword or empty keyword list)
29
- 2. `get_market_detail` / `get_market_price`
30
- 3. `get_account` (with `poolId`)
31
- 4. `open_position_simple` (preferred high-level execution)
32
-
33
- ## Flow B: Limit Order Lifecycle
34
- 1. `execute_trade` with `orderType=LIMIT`
35
- 2. `get_open_orders`
36
- 3. `get_order_history`
37
- 4. `cancel_order` or `cancel_all_orders`
38
-
39
- ## Flow C: Balance Troubleshooting
40
- 1. `get_account` (without `poolId`) → wallet view
41
- 2. `get_account` (with `poolId`) → trading-account + margin
42
- 3. `account_deposit` / `account_withdraw` as needed
43
-
44
- ---
45
-
46
- ## 3) Tool-by-Tool Practical Examples
47
-
48
- ## Trading Operations
49
-
50
- ### `open_position_simple`
10
+ ### `open_position_simple` (Recommended)
11
+ High-level tool that computes size and fees automatically.
51
12
  ```json
52
13
  {
53
14
  "name": "open_position_simple",
@@ -55,579 +16,122 @@ It includes:
55
16
  "keyword": "BTC",
56
17
  "direction": "LONG",
57
18
  "collateralAmount": "100",
58
- "leverage": 5,
59
- "orderType": "MARKET",
60
- "autoDeposit": false,
61
- "dryRun": true
19
+ "leverage": 10,
20
+ "tpPrice": "75000",
21
+ "slPrice": "62000"
62
22
  }
63
23
  }
64
24
  ```
65
- Notes:
66
- - `open_position_simple` only accepts open/increase parameters and does not support `tpPrice`, `tpSize`, `slPrice`, `slSize` in the same call.
67
- - If those TP/SL keys are included, the server rejects them as unrecognized fields (strict schema validation).
68
- - Recommended flow: open with `open_position_simple` first, then use `set_tp_sl` (position-level) or `update_order_tp_sl` (order-level).
69
25
 
70
- ### `execute_trade`
26
+ ### `cancel_orders` (Unified)
27
+ Supports three modes: single ID, all in a pool, or all in account.
71
28
  ```json
29
+ // Mode 1: Specific IDs
72
30
  {
73
- "name": "execute_trade",
74
- "arguments": {
75
- "poolId": "0xPOOL_ID",
76
- "positionId": "",
77
- "orderType": "MARKET",
78
- "direction": "LONG",
79
- "collateralAmount": "100",
80
- "size": "0.01",
81
- "price": "65000",
82
- "timeInForce": 0,
83
- "postOnly": false,
84
- "slippagePct": "100",
85
- "executionFeeToken": "0xQUOTE_TOKEN",
86
- "leverage": 5,
87
- "marketId": "0xMARKET_ID"
88
- }
89
- }
90
- ```
91
- Notes:
92
- - `tradingFee` is optional (auto-computed if omitted).
93
- - Amount-like fields support `human:` and `raw:` prefixes.
94
- - `positionId: "0x000...000"` is auto-treated as a new position.
95
-
96
- ### `close_position`
97
- ```json
98
- {
99
- "name": "close_position",
100
- "arguments": {
101
- "poolId": "0xPOOL_ID",
102
- "positionId": "0xPOSITION_ID",
103
- "orderType": "MARKET",
104
- "direction": "LONG",
105
- "collateralAmount": "0",
106
- "size": "0.01",
107
- "price": "65000",
108
- "timeInForce": 0,
109
- "postOnly": false,
110
- "slippagePct": "100",
111
- "executionFeeToken": "0xQUOTE_TOKEN",
112
- "leverage": 5
113
- }
114
- }
115
- ```
116
-
117
- ### `close_all_positions`
118
- ```json
119
- {
120
- "name": "close_all_positions",
121
- "arguments": {
122
- "poolId": "0xPOOL_ID",
123
- "slippagePct": "200"
124
- }
31
+ "name": "cancel_orders",
32
+ "arguments": { "orderIds": ["0x123...", "0x456..."] }
125
33
  }
126
- ```
127
34
 
128
- ### `cancel_order`
129
- ```json
35
+ // Mode 2: Pool-wide
130
36
  {
131
- "name": "cancel_order",
132
- "arguments": {
133
- "orderId": "0xORDER_ID"
134
- }
37
+ "name": "cancel_orders",
38
+ "arguments": { "poolId": "BTC" }
135
39
  }
136
- ```
137
40
 
138
- ### `cancel_all_orders`
139
- ```json
41
+ // Mode 3: Global
140
42
  {
141
- "name": "cancel_all_orders",
142
- "arguments": {
143
- "orderIds": [
144
- "0xORDER_ID_1",
145
- "0xORDER_ID_2"
146
- ]
147
- }
148
- }
149
- ```
150
- Single-ID string is also accepted:
151
- ```json
152
- {
153
- "name": "cancel_all_orders",
154
- "arguments": {
155
- "orderIds": "0xORDER_ID_1"
156
- }
43
+ "name": "cancel_orders",
44
+ "arguments": { "cancelAll": true }
157
45
  }
158
46
  ```
159
47
 
160
- ### `set_tp_sl`
48
+ ### `manage_tp_sl`
49
+ Update existing protection orders or set new ones for a position.
161
50
  ```json
162
51
  {
163
- "name": "set_tp_sl",
52
+ "name": "manage_tp_sl",
164
53
  "arguments": {
165
- "poolId": "0xPOOL_ID",
166
- "positionId": "0xPOSITION_ID",
167
- "direction": "LONG",
54
+ "poolId": "BTC",
55
+ "positionId": "0xABC...",
168
56
  "leverage": 5,
169
- "executionFeeToken": "0xQUOTE_TOKEN",
170
- "tpTriggerType": "GTE",
171
- "tpPrice": "70000",
172
- "tpSize": "0.01",
173
- "slTriggerType": "LTE",
174
- "slPrice": "60000",
175
- "slSize": "0.01",
176
- "slippagePct": "100"
177
- }
178
- }
179
- ```
180
-
181
- ### `update_order_tp_sl`
182
- ```json
183
- {
184
- "name": "update_order_tp_sl",
185
- "arguments": {
186
- "orderId": "0xORDER_ID",
187
- "marketId": "0xMARKET_ID",
188
- "size": "0.01",
189
- "price": "65000",
190
- "tpPrice": "70000",
191
- "tpSize": "0.005",
192
- "slPrice": "60000",
193
- "slSize": "0.005",
194
- "useOrderCollateral": true,
195
- "quoteToken": "0xQUOTE_TOKEN"
196
- }
197
- }
198
- ```
199
- String booleans are also accepted:
200
- ```json
201
- {
202
- "name": "update_order_tp_sl",
203
- "arguments": {
204
- "orderId": "0xORDER_ID",
205
- "marketId": "0xMARKET_ID",
206
- "size": 0.01,
207
- "price": 65000,
208
- "tpPrice": 70000,
209
- "tpSize": 0.005,
210
- "slPrice": 60000,
211
- "slSize": 0.005,
212
- "useOrderCollateral": "true",
213
- "isTpSlOrder": "true",
214
- "quoteToken": "0xQUOTE_TOKEN"
215
- }
216
- }
217
- ```
218
- Note:
219
- - This tool is most reliable for existing TP/SL orders or open positions.
220
- - If an unfilled LIMIT/STOP order returns `Failed to update order`, wait for fill and use `set_tp_sl`.
221
-
222
- ### `adjust_margin`
223
- ```json
224
- {
225
- "name": "adjust_margin",
226
- "arguments": {
227
- "poolId": "0xPOOL_ID",
228
- "positionId": "0xPOSITION_ID",
229
- "adjustAmount": "1"
230
- }
231
- }
232
- ```
233
- Raw precision mode:
234
- ```json
235
- {
236
- "name": "adjust_margin",
237
- "arguments": {
238
- "poolId": "0xPOOL_ID",
239
- "positionId": "0xPOSITION_ID",
240
- "adjustAmount": "raw:1000000"
241
- }
242
- }
243
- ```
244
- Success payload includes normalized raw amount under `data.normalized.adjustAmountRaw`.
245
-
246
- ### `check_approval`
247
- ```json
248
- {
249
- "name": "check_approval",
250
- "arguments": {
251
- "amount": "100000000",
252
- "autoApprove": false
253
- }
254
- }
255
- ```
256
-
257
- ### `get_user_trading_fee_rate`
258
- ```json
259
- {
260
- "name": "get_user_trading_fee_rate",
261
- "arguments": {
262
- "assetClass": 1,
263
- "riskTier": 1
264
- }
265
- }
266
- ```
267
-
268
- ### `get_network_fee`
269
- ```json
270
- {
271
- "name": "get_network_fee",
272
- "arguments": {
273
- "marketId": "0xMARKET_ID"
274
- }
275
- }
276
- ```
277
-
278
- ## Market Data
279
-
280
- ### `search_market`
281
- ```json
282
- {
283
- "name": "search_market",
284
- "arguments": {
285
- "keyword": "ETH",
286
- "limit": 10
287
- }
288
- }
289
- ```
290
-
291
- ### `search_market` (list active markets)
292
- ```json
293
- {
294
- "name": "search_market",
295
- "arguments": {
296
- "keyword": "",
297
- "limit": 20
298
- }
299
- }
300
- ```
301
- Note: this tool may internally fallback to SDK `api.getMarketList()` / `api.getPoolList()` when direct search is empty.
302
-
303
- ### `get_pool_list`
304
- ```json
305
- {
306
- "name": "get_pool_list",
307
- "arguments": {}
308
- }
309
- ```
310
-
311
- ### `get_market_detail`
312
- ```json
313
- {
314
- "name": "get_market_detail",
315
- "arguments": {
316
- "poolId": "BTC"
317
- }
318
- }
319
- ```
320
-
321
- ### `get_pool_info`
322
- ```json
323
- {
324
- "name": "get_pool_info",
325
- "arguments": {
326
- "poolId": "0xPOOL_ID"
327
- }
328
- }
329
- ```
330
- Note: the server auto-retries with oracle/ticker market price when direct on-chain read hits divide-by-zero.
331
-
332
- ### `get_liquidity_info`
333
- ```json
334
- {
335
- "name": "get_liquidity_info",
336
- "arguments": {
337
- "poolId": "0xPOOL_ID",
338
- "marketPrice": "6500000000000000000000000000000000"
339
- }
340
- }
341
- ```
342
-
343
- ### `get_pool_level_config`
344
- ```json
345
- {
346
- "name": "get_pool_level_config",
347
- "arguments": {
348
- "poolId": "0xPOOL_ID"
349
- }
350
- }
351
- ```
352
-
353
- ### `get_market_price`
354
- ```json
355
- {
356
- "name": "get_market_price",
357
- "arguments": {
358
- "poolId": "0xPOOL_ID"
359
- }
360
- }
361
- ```
362
-
363
- ### `get_oracle_price`
364
- ```json
365
- {
366
- "name": "get_oracle_price",
367
- "arguments": {
368
- "poolId": "0xPOOL_ID"
369
- }
370
- }
371
- ```
372
-
373
- ### `get_kline`
374
- ```json
375
- {
376
- "name": "get_kline",
377
- "arguments": {
378
- "poolId": "0xPOOL_ID",
379
- "interval": "15m",
380
- "limit": 100
381
- }
382
- }
383
- ```
384
-
385
- ### `get_kline_latest_bar`
386
- ```json
387
- {
388
- "name": "get_kline_latest_bar",
389
- "arguments": {
390
- "poolId": "0xPOOL_ID",
391
- "interval": "1m"
392
- }
393
- }
394
- ```
395
-
396
- ### `get_all_tickers`
397
- ```json
398
- {
399
- "name": "get_all_tickers",
400
- "arguments": {}
401
- }
402
- ```
403
-
404
- ### `get_pool_symbol_all`
405
- ```json
406
- {
407
- "name": "get_pool_symbol_all",
408
- "arguments": {}
409
- }
410
- ```
411
-
412
- ### `get_base_detail`
413
- ```json
414
- {
415
- "name": "get_base_detail",
416
- "arguments": {
417
- "baseAddress": "0xBASE_TOKEN"
418
- }
419
- }
420
- ```
421
-
422
- ## Account & Query
423
-
424
- ### `get_account`
425
- ```json
426
- {
427
- "name": "get_account",
428
- "arguments": {
429
- "poolId": "0xPOOL_ID"
430
- }
431
- }
432
- ```
433
-
434
- If one section fails, check `data.meta.partial` and section-level `error` fields.
435
-
436
- ### `get_account` (wallet-only view)
437
- ```json
438
- {
439
- "name": "get_account",
440
- "arguments": {}
441
- }
442
- ```
443
-
444
- ### `get_my_lp_holdings`
445
- ```json
446
- {
447
- "name": "get_my_lp_holdings",
448
- "arguments": {}
449
- }
450
- ```
451
- LP asset naming rule in each item:
452
- - `baseLpAssetName`: `mBASE.QUOTE` (e.g. `mBTC.USDC`)
453
- - `quoteLpAssetName`: `mQUOTE.BASE` (e.g. `mUSDC.BTC`)
454
- Include zero-balance pools and optional filtering:
455
- ```json
456
- {
457
- "name": "get_my_lp_holdings",
458
- "arguments": {
459
- "includeZero": true,
460
- "poolIds": [
461
- "0xPOOL_ID_1",
462
- "0xPOOL_ID_2"
463
- ],
464
- "maxPools": 50
57
+ "tpPrice": "80000",
58
+ "slPrice": "55000"
465
59
  }
466
60
  }
467
61
  ```
468
62
 
469
- ### `get_positions`
470
- ```json
471
- {
472
- "name": "get_positions",
473
- "arguments": {}
474
- }
475
- ```
476
-
477
- ### `get_open_orders`
478
- ```json
479
- {
480
- "name": "get_open_orders",
481
- "arguments": {}
482
- }
483
- ```
63
+ ---
484
64
 
485
- ### `get_order_history`
486
- ```json
487
- {
488
- "name": "get_order_history",
489
- "arguments": {
490
- "poolId": "0xPOOL_ID",
491
- "limit": 20
492
- }
493
- }
494
- ```
65
+ ## 🔵 Market Data
495
66
 
496
- ### `get_position_history`
67
+ ### `find_pool`
68
+ Keyword or symbol based discovery.
497
69
  ```json
498
70
  {
499
- "name": "get_position_history",
500
- "arguments": {
501
- "poolId": "0xPOOL_ID",
502
- "limit": 20
503
- }
71
+ "name": "find_pool",
72
+ "arguments": { "keyword": "ETH" }
504
73
  }
505
74
  ```
506
75
 
507
- ### `get_trade_flow`
76
+ ### `get_price`
77
+ Unified price fetching.
508
78
  ```json
509
79
  {
510
- "name": "get_trade_flow",
511
- "arguments": {
512
- "limit": 20
80
+ "name": "get_price",
81
+ "arguments": {
82
+ "poolId": "0x...",
83
+ "priceType": "market"
513
84
  }
514
85
  }
515
86
  ```
516
87
 
517
- ### `get_account_vip_info`
88
+ ### `get_pool_metadata`
89
+ Detailed pool state (Fees, Liquidity, Open Interest).
518
90
  ```json
519
91
  {
520
- "name": "get_account_vip_info",
521
- "arguments": {}
522
- }
523
- ```
524
-
525
- ### `account_deposit`
526
- ```json
527
- {
528
- "name": "account_deposit",
529
- "arguments": {
530
- "amount": "100",
531
- "tokenAddress": "0xQUOTE_TOKEN"
532
- }
92
+ "name": "get_pool_metadata",
93
+ "arguments": { "poolId": "0x..." }
533
94
  }
534
95
  ```
535
96
 
536
- ### `account_withdraw`
537
- ```json
538
- {
539
- "name": "account_withdraw",
540
- "arguments": {
541
- "poolId": "0xPOOL_ID",
542
- "amount": "50",
543
- "isQuoteToken": true
544
- }
545
- }
546
- ```
97
+ ---
547
98
 
548
- ## Liquidity / LP
99
+ ## 🟡 Account & Portfolio
549
100
 
550
- ### `manage_liquidity`
101
+ ### `get_account_snapshot`
102
+ Unified overview. Includes wallet balances and VIP info.
551
103
  ```json
552
104
  {
553
- "name": "manage_liquidity",
554
- "arguments": {
555
- "action": "deposit",
556
- "poolType": "QUOTE",
557
- "poolId": "0xPOOL_ID",
558
- "amount": 100,
559
- "slippage": 0.01
560
- }
561
- }
562
- ```
563
- Alias action example (`remove` == `withdraw`):
564
- ```json
565
- {
566
- "name": "manage_liquidity",
567
- "arguments": {
568
- "action": "remove",
569
- "poolType": "BASE",
570
- "poolId": "0xPOOL_ID",
571
- "amount": 1.5,
572
- "slippage": 0.01
573
- }
574
- }
575
- ```
576
- If operation fails, check `error.message` for concrete reasons (for example `Insufficient Balance`) instead of generic `undefined`.
577
- `poolId` must be valid on the target `chainId`; if uncertain, resolve with `search_market` / `get_pool_list` first.
578
- Success response includes `data.lpAssetNames`:
579
- - `baseLpAssetName`: `mBASE.QUOTE` (e.g. `mBTC.USDC`)
580
- - `quoteLpAssetName`: `mQUOTE.BASE` (e.g. `mUSDC.BTC`)
581
- - `operatedLpAssetName`: LP asset name matching current `poolType`
582
- Example success payload (abridged):
583
- ```json
584
- {
585
- "status": "success",
586
- "data": {
587
- "confirmation": {
588
- "confirmed": true,
589
- "txHash": "0x..."
590
- },
591
- "lpAssetNames": {
592
- "baseSymbol": "BTC",
593
- "quoteSymbol": "USDC",
594
- "baseLpAssetName": "mBTC.USDC",
595
- "quoteLpAssetName": "mUSDC.BTC",
596
- "operatedPoolType": "QUOTE",
597
- "operatedLpAssetName": "mUSDC.BTC"
598
- }
599
- }
105
+ "name": "get_account_snapshot",
106
+ "arguments": { "poolId": "BTC" }
600
107
  }
601
108
  ```
602
109
 
603
- ### `get_lp_price`
110
+ ### `get_orders`
111
+ Unified list for both active (OPEN) and historical (HISTORY) orders.
604
112
  ```json
605
113
  {
606
- "name": "get_lp_price",
607
- "arguments": {
608
- "poolType": "QUOTE",
609
- "poolId": "0xPOOL_ID"
114
+ "name": "get_orders",
115
+ "arguments": {
116
+ "status": "ALL",
117
+ "limit": 10
610
118
  }
611
119
  }
612
120
  ```
613
121
 
614
- ### `create_perp_market`
122
+ ### `get_positions_all`
123
+ Current open positions and closed history.
615
124
  ```json
616
125
  {
617
- "name": "create_perp_market",
618
- "arguments": {
619
- "baseToken": "0xBASE_TOKEN",
620
- "marketId": "0xMARKET_CONFIG_HASH"
621
- }
126
+ "name": "get_positions_all",
127
+ "arguments": { "status": "OPEN" }
622
128
  }
623
129
  ```
624
130
 
625
131
  ---
626
132
 
627
- ## 4) Practical Tips for AI Agents
133
+ ## 💡 Important Rules
628
134
 
629
- - Always discover/validate `poolId` before mutation tools.
630
- - Prefer `open_position_simple` for new-position UX unless strict low-level control is required.
631
- - Before trading, call `get_account` and `check_approval`.
632
- - For limit-order support conversations, include `get_open_orders` and `get_order_history` in the loop.
633
- - If any mutation fails, read structured error fields: `error.code`, `error.hint`, `error.action`.
135
+ 1. **Unit Prefixing**: Use `human:` for readable amounts and `raw:` for exact on-chain units. Default is usually human-readable for high-level tools.
136
+ 2. **Pool Discovery**: Always run `find_pool` first to get the correct `poolId`.
137
+ 3. **Pre-trade Check**: Use `check_account_ready` to ensure enough collateral is in the trading account before opening positions.