@okx_ai/okx-trade-cli 1.2.3-beta.1 → 1.2.4-beta.0

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.
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@
4
4
  import { createRequire as createRequire2 } from "module";
5
5
 
6
6
  // ../core/dist/index.js
7
+ import { ProxyAgent } from "undici";
7
8
  import { createHmac } from "crypto";
8
9
  import fs from "fs";
9
10
  import path from "path";
@@ -1063,9 +1064,13 @@ function vlog(message) {
1063
1064
  var OkxRestClient = class {
1064
1065
  config;
1065
1066
  rateLimiter;
1067
+ dispatcher;
1066
1068
  constructor(config) {
1067
1069
  this.config = config;
1068
1070
  this.rateLimiter = new RateLimiter(3e4, config.verbose);
1071
+ if (config.proxyUrl) {
1072
+ this.dispatcher = new ProxyAgent(config.proxyUrl);
1073
+ }
1069
1074
  }
1070
1075
  logRequest(method, url, auth) {
1071
1076
  if (!this.config.verbose) return;
@@ -1225,12 +1230,16 @@ var OkxRestClient = class {
1225
1230
  const t0 = Date.now();
1226
1231
  let response;
1227
1232
  try {
1228
- response = await fetch(url, {
1233
+ const fetchOptions = {
1229
1234
  method: reqConfig.method,
1230
1235
  headers,
1231
1236
  body: reqConfig.method === "POST" ? bodyJson : void 0,
1232
1237
  signal: AbortSignal.timeout(this.config.timeoutMs)
1233
- });
1238
+ };
1239
+ if (this.dispatcher) {
1240
+ fetchOptions.dispatcher = this.dispatcher;
1241
+ }
1242
+ response = await fetch(url, fetchOptions);
1234
1243
  } catch (error) {
1235
1244
  if (this.config.verbose) {
1236
1245
  const elapsed2 = Date.now() - t0;
@@ -1982,7 +1991,7 @@ function registerAlgoTradeTools() {
1982
1991
  },
1983
1992
  sz: {
1984
1993
  type: "string",
1985
- description: "Contracts to close"
1994
+ description: "Number of contracts to close (NOT USDT amount). Use market_get_instruments to get ctVal for conversion."
1986
1995
  },
1987
1996
  tpTriggerPx: {
1988
1997
  type: "string",
@@ -2077,7 +2086,7 @@ function registerAlgoTradeTools() {
2077
2086
  },
2078
2087
  sz: {
2079
2088
  type: "string",
2080
- description: "Contracts"
2089
+ description: "Number of contracts (NOT USDT amount). Use market_get_instruments to get ctVal for conversion."
2081
2090
  },
2082
2091
  callbackRatio: {
2083
2092
  type: "string",
@@ -2382,7 +2391,7 @@ function registerGridTools() {
2382
2391
  algoOrdType: {
2383
2392
  type: "string",
2384
2393
  enum: ["grid", "contract_grid", "moon_grid"],
2385
- description: "grid=Spot, contract_grid=Contract, moon_grid=Moon"
2394
+ description: "Grid bot type. grid=Spot, contract_grid=Contract, moon_grid=Moon. Must match the bot's actual type when filtering by algoId."
2386
2395
  },
2387
2396
  status: {
2388
2397
  type: "string",
@@ -2394,7 +2403,8 @@ function registerGridTools() {
2394
2403
  description: "e.g. BTC-USDT"
2395
2404
  },
2396
2405
  algoId: {
2397
- type: "string"
2406
+ type: "string",
2407
+ description: "Grid bot algo order ID (returned by grid_create_order or grid_get_orders). This is NOT a normal trade order ID."
2398
2408
  },
2399
2409
  after: {
2400
2410
  type: "string",
@@ -2442,10 +2452,11 @@ function registerGridTools() {
2442
2452
  algoOrdType: {
2443
2453
  type: "string",
2444
2454
  enum: ["grid", "contract_grid", "moon_grid"],
2445
- description: "grid=Spot, contract_grid=Contract, moon_grid=Moon"
2455
+ description: "Must match the bot's actual type (use the algoOrdType value returned by grid_get_orders). grid=Spot, contract_grid=Contract, moon_grid=Moon."
2446
2456
  },
2447
2457
  algoId: {
2448
- type: "string"
2458
+ type: "string",
2459
+ description: "Grid bot algo order ID (returned by grid_create_order or grid_get_orders). This is NOT a normal trade order ID."
2449
2460
  }
2450
2461
  },
2451
2462
  required: ["algoOrdType", "algoId"]
@@ -2474,10 +2485,11 @@ function registerGridTools() {
2474
2485
  algoOrdType: {
2475
2486
  type: "string",
2476
2487
  enum: ["grid", "contract_grid", "moon_grid"],
2477
- description: "grid=Spot, contract_grid=Contract, moon_grid=Moon"
2488
+ description: "Must match the bot's actual type (use the algoOrdType value returned by grid_get_orders). grid=Spot, contract_grid=Contract, moon_grid=Moon."
2478
2489
  },
2479
2490
  algoId: {
2480
- type: "string"
2491
+ type: "string",
2492
+ description: "Grid bot algo order ID (returned by grid_create_order or grid_get_orders). This is NOT a normal trade order ID."
2481
2493
  },
2482
2494
  type: {
2483
2495
  type: "string",
@@ -2485,7 +2497,8 @@ function registerGridTools() {
2485
2497
  description: "filled=executed trades (default); live=pending orders"
2486
2498
  },
2487
2499
  groupId: {
2488
- type: "string"
2500
+ type: "string",
2501
+ description: "Group ID \u2014 a buy-sell pair shares the same groupId. Use to filter a specific grid level."
2489
2502
  },
2490
2503
  after: {
2491
2504
  type: "string",
@@ -2620,12 +2633,13 @@ function registerGridTools() {
2620
2633
  type: "object",
2621
2634
  properties: {
2622
2635
  algoId: {
2623
- type: "string"
2636
+ type: "string",
2637
+ description: "Grid bot algo order ID (returned by grid_create_order or grid_get_orders). This is NOT a normal trade order ID."
2624
2638
  },
2625
2639
  algoOrdType: {
2626
2640
  type: "string",
2627
2641
  enum: ["grid", "contract_grid", "moon_grid"],
2628
- description: "grid=Spot, contract_grid=Contract, moon_grid=Moon"
2642
+ description: "Must match the bot's actual type (use the algoOrdType value returned by grid_get_orders). grid=Spot, contract_grid=Contract, moon_grid=Moon."
2629
2643
  },
2630
2644
  instId: {
2631
2645
  type: "string",
@@ -2757,7 +2771,10 @@ function registerDcaTools() {
2757
2771
  inputSchema: {
2758
2772
  type: "object",
2759
2773
  properties: {
2760
- algoId: { type: "string", description: "Algo order ID of the DCA bot to stop" }
2774
+ algoId: {
2775
+ type: "string",
2776
+ description: "DCA bot algo order ID (returned by dca_create_order or dca_get_orders). This is NOT a normal trade order ID."
2777
+ }
2761
2778
  },
2762
2779
  required: ["algoId"]
2763
2780
  },
@@ -2785,7 +2802,10 @@ function registerDcaTools() {
2785
2802
  enum: ["active", "history"],
2786
2803
  description: "active=running (default); history=stopped"
2787
2804
  },
2788
- algoId: { type: "string" },
2805
+ algoId: {
2806
+ type: "string",
2807
+ description: "DCA bot algo order ID (returned by dca_create_order or dca_get_orders). This is NOT a normal trade order ID."
2808
+ },
2789
2809
  instId: { type: "string", description: "Filter by instrument, e.g. BTC-USDT-SWAP (optional)" },
2790
2810
  after: { type: "string", description: "Pagination: before this algo ID" },
2791
2811
  before: { type: "string", description: "Pagination: after this algo ID" },
@@ -2820,7 +2840,10 @@ function registerDcaTools() {
2820
2840
  inputSchema: {
2821
2841
  type: "object",
2822
2842
  properties: {
2823
- algoId: { type: "string" }
2843
+ algoId: {
2844
+ type: "string",
2845
+ description: "DCA bot algo order ID (returned by dca_create_order or dca_get_orders). This is NOT a normal trade order ID."
2846
+ }
2824
2847
  },
2825
2848
  required: ["algoId"]
2826
2849
  },
@@ -2843,7 +2866,10 @@ function registerDcaTools() {
2843
2866
  inputSchema: {
2844
2867
  type: "object",
2845
2868
  properties: {
2846
- algoId: { type: "string", description: "Algo order ID of the DCA bot" },
2869
+ algoId: {
2870
+ type: "string",
2871
+ description: "DCA bot algo order ID (returned by dca_create_order or dca_get_orders). This is NOT a normal trade order ID."
2872
+ },
2847
2873
  cycleId: { type: "string", description: "Omit to list all cycles; provide to get orders within a cycle" },
2848
2874
  after: { type: "string", description: "Pagination cursor \u2014 applies to cycle-list mode only (when cycleId is omitted)" },
2849
2875
  before: { type: "string", description: "Pagination cursor \u2014 applies to cycle-list mode only (when cycleId is omitted)" },
@@ -3130,639 +3156,645 @@ function registerEarnTools() {
3130
3156
  }
3131
3157
  ];
3132
3158
  }
3133
- var FUTURES_INST_TYPES = ["FUTURES", "SWAP"];
3134
- function normalize5(response) {
3135
- return {
3136
- endpoint: response.endpoint,
3137
- requestTime: response.requestTime,
3138
- data: response.data
3139
- };
3140
- }
3141
- function registerFuturesTools() {
3159
+ function registerOnchainEarnTools() {
3142
3160
  return [
3161
+ // -------------------------------------------------------------------------
3162
+ // Get Offers
3163
+ // -------------------------------------------------------------------------
3143
3164
  {
3144
- name: "futures_place_order",
3145
- module: "futures",
3146
- description: "Place a FUTURES delivery contract order (e.g. instId: BTC-USDT-240329). Optionally attach TP/SL via tpTriggerPx/slTriggerPx. [CAUTION] Executes real trades. Private endpoint. Rate limit: 60 req/s.",
3147
- isWrite: true,
3165
+ name: "onchain_earn_get_offers",
3166
+ module: "earn.onchain",
3167
+ description: "Get available on-chain earn (staking/DeFi) offers. Returns investment products with APY, terms, and limits. Private endpoint. Rate limit: 3 req/s.",
3168
+ isWrite: false,
3148
3169
  inputSchema: {
3149
3170
  type: "object",
3150
3171
  properties: {
3151
- instId: {
3152
- type: "string",
3153
- description: "e.g. BTC-USDT-240329"
3154
- },
3155
- tdMode: {
3156
- type: "string",
3157
- enum: ["cross", "isolated"],
3158
- description: "cross|isolated margin"
3159
- },
3160
- side: {
3161
- type: "string",
3162
- enum: ["buy", "sell"],
3163
- description: "one-way: buy=open long, sell=open short (use reduceOnly=true to close); hedge: combined with posSide"
3164
- },
3165
- posSide: {
3166
- type: "string",
3167
- enum: ["long", "short", "net"],
3168
- description: "net=one-way mode (default); long/short=hedge mode only"
3169
- },
3170
- ordType: {
3171
- type: "string",
3172
- enum: ["market", "limit", "post_only", "fok", "ioc"],
3173
- description: "market(no px)|limit(px req)|post_only(maker)|fok(all-or-cancel)|ioc(partial fill)"
3174
- },
3175
- sz: {
3176
- type: "string",
3177
- description: "Contracts"
3178
- },
3179
- px: {
3180
- type: "string",
3181
- description: "Required for limit/post_only/fok/ioc"
3182
- },
3183
- reduceOnly: {
3184
- type: "boolean",
3185
- description: "Close/reduce only, no new position (one-way mode)"
3186
- },
3187
- clOrdId: {
3188
- type: "string",
3189
- description: "Client order ID (max 32 chars)"
3190
- },
3191
- tpTriggerPx: {
3192
- type: "string",
3193
- description: "TP trigger price; places TP at tpOrdPx"
3194
- },
3195
- tpOrdPx: {
3172
+ productId: {
3196
3173
  type: "string",
3197
- description: "TP order price; -1=market"
3174
+ description: "Specific product ID to query. Omit for all offers."
3198
3175
  },
3199
- slTriggerPx: {
3176
+ protocolType: {
3200
3177
  type: "string",
3201
- description: "SL trigger price; places SL at slOrdPx"
3178
+ description: "Protocol type filter: staking, defi. Omit for all types."
3202
3179
  },
3203
- slOrdPx: {
3180
+ ccy: {
3204
3181
  type: "string",
3205
- description: "SL order price; -1=market"
3182
+ description: "Currency filter, e.g. ETH. Omit for all currencies."
3206
3183
  }
3207
- },
3208
- required: ["instId", "tdMode", "side", "ordType", "sz"]
3184
+ }
3209
3185
  },
3210
3186
  handler: async (rawArgs, context) => {
3211
3187
  const args = asRecord(rawArgs);
3212
- const reduceOnly = args.reduceOnly;
3213
- const tpTriggerPx = readString(args, "tpTriggerPx");
3214
- const tpOrdPx = readString(args, "tpOrdPx");
3215
- const slTriggerPx = readString(args, "slTriggerPx");
3216
- const slOrdPx = readString(args, "slOrdPx");
3217
- const algoEntry = compactObject({ tpTriggerPx, tpOrdPx, slTriggerPx, slOrdPx });
3218
- const attachAlgoOrds = Object.keys(algoEntry).length > 0 ? [algoEntry] : void 0;
3219
- const response = await context.client.privatePost(
3220
- "/api/v5/trade/order",
3188
+ const response = await context.client.privateGet(
3189
+ "/api/v5/finance/staking-defi/offers",
3221
3190
  compactObject({
3222
- instId: requireString(args, "instId"),
3223
- tdMode: requireString(args, "tdMode"),
3224
- side: requireString(args, "side"),
3225
- posSide: readString(args, "posSide"),
3226
- ordType: requireString(args, "ordType"),
3227
- sz: requireString(args, "sz"),
3228
- px: readString(args, "px"),
3229
- reduceOnly: typeof reduceOnly === "boolean" ? String(reduceOnly) : void 0,
3230
- clOrdId: readString(args, "clOrdId"),
3231
- tag: context.config.sourceTag,
3232
- attachAlgoOrds
3191
+ productId: readString(args, "productId"),
3192
+ protocolType: readString(args, "protocolType"),
3193
+ ccy: readString(args, "ccy")
3233
3194
  }),
3234
- privateRateLimit("futures_place_order", 60)
3195
+ privateRateLimit("onchain_earn_get_offers", 3)
3235
3196
  );
3236
- return normalize5(response);
3197
+ return normalizeResponse(response);
3237
3198
  }
3238
3199
  },
3200
+ // -------------------------------------------------------------------------
3201
+ // Purchase
3202
+ // -------------------------------------------------------------------------
3239
3203
  {
3240
- name: "futures_cancel_order",
3241
- module: "futures",
3242
- description: "Cancel an unfilled FUTURES delivery order. Private endpoint. Rate limit: 60 req/s.",
3204
+ name: "onchain_earn_purchase",
3205
+ module: "earn.onchain",
3206
+ description: "Purchase on-chain earn (staking/DeFi) product. [CAUTION] Moves real funds into staking/DeFi product. Not supported in demo/simulated trading mode. Private endpoint. Rate limit: 2 req/s.",
3243
3207
  isWrite: true,
3244
3208
  inputSchema: {
3245
3209
  type: "object",
3246
3210
  properties: {
3247
- instId: {
3211
+ productId: {
3248
3212
  type: "string",
3249
- description: "e.g. BTC-USDT-240329"
3213
+ description: "Product ID to purchase"
3250
3214
  },
3251
- ordId: {
3252
- type: "string"
3215
+ investData: {
3216
+ type: "array",
3217
+ description: "Investment data array: [{ccy, amt}]. Each item specifies currency and amount.",
3218
+ items: {
3219
+ type: "object",
3220
+ properties: {
3221
+ ccy: { type: "string", description: "Currency, e.g. ETH" },
3222
+ amt: { type: "string", description: "Amount to invest" }
3223
+ },
3224
+ required: ["ccy", "amt"]
3225
+ }
3253
3226
  },
3254
- clOrdId: {
3227
+ term: {
3255
3228
  type: "string",
3256
- description: "Client order ID"
3229
+ description: "Investment term in days. Required for fixed-term products."
3230
+ },
3231
+ tag: {
3232
+ type: "string",
3233
+ description: "Order tag for tracking (optional)."
3257
3234
  }
3258
3235
  },
3259
- required: ["instId"]
3236
+ required: ["productId", "investData"]
3260
3237
  },
3261
3238
  handler: async (rawArgs, context) => {
3239
+ assertNotDemo(context.config, "onchain_earn_purchase");
3262
3240
  const args = asRecord(rawArgs);
3263
3241
  const response = await context.client.privatePost(
3264
- "/api/v5/trade/cancel-order",
3242
+ "/api/v5/finance/staking-defi/purchase",
3265
3243
  compactObject({
3266
- instId: requireString(args, "instId"),
3267
- ordId: readString(args, "ordId"),
3268
- clOrdId: readString(args, "clOrdId")
3244
+ productId: requireString(args, "productId"),
3245
+ investData: args.investData,
3246
+ term: readString(args, "term"),
3247
+ tag: readString(args, "tag")
3269
3248
  }),
3270
- privateRateLimit("futures_cancel_order", 60)
3249
+ privateRateLimit("onchain_earn_purchase", 2)
3271
3250
  );
3272
- return normalize5(response);
3251
+ return normalizeResponse(response);
3273
3252
  }
3274
3253
  },
3254
+ // -------------------------------------------------------------------------
3255
+ // Redeem
3256
+ // -------------------------------------------------------------------------
3275
3257
  {
3276
- name: "futures_get_order",
3277
- module: "futures",
3278
- description: "Get details of a single FUTURES delivery order by ordId or clOrdId. Private endpoint. Rate limit: 60 req/s.",
3279
- isWrite: false,
3258
+ name: "onchain_earn_redeem",
3259
+ module: "earn.onchain",
3260
+ description: "Redeem on-chain earn (staking/DeFi) investment. [CAUTION] Withdraws funds from staking/DeFi product. Some products may have lock periods. Not supported in demo mode. Private endpoint. Rate limit: 2 req/s.",
3261
+ isWrite: true,
3280
3262
  inputSchema: {
3281
3263
  type: "object",
3282
3264
  properties: {
3283
- instId: {
3284
- type: "string",
3285
- description: "e.g. BTC-USDT-240329"
3286
- },
3287
3265
  ordId: {
3288
3266
  type: "string",
3289
- description: "Provide ordId or clOrdId"
3267
+ description: "Order ID to redeem"
3290
3268
  },
3291
- clOrdId: {
3269
+ protocolType: {
3292
3270
  type: "string",
3293
- description: "Provide ordId or clOrdId"
3271
+ description: "Protocol type: staking, defi"
3272
+ },
3273
+ allowEarlyRedeem: {
3274
+ type: "boolean",
3275
+ description: "Allow early redemption for fixed-term products (may incur penalties). Default false."
3294
3276
  }
3295
3277
  },
3296
- required: ["instId"]
3278
+ required: ["ordId", "protocolType"]
3297
3279
  },
3298
3280
  handler: async (rawArgs, context) => {
3281
+ assertNotDemo(context.config, "onchain_earn_redeem");
3299
3282
  const args = asRecord(rawArgs);
3300
- const response = await context.client.privateGet(
3301
- "/api/v5/trade/order",
3283
+ const response = await context.client.privatePost(
3284
+ "/api/v5/finance/staking-defi/redeem",
3302
3285
  compactObject({
3303
- instId: requireString(args, "instId"),
3304
- ordId: readString(args, "ordId"),
3305
- clOrdId: readString(args, "clOrdId")
3286
+ ordId: requireString(args, "ordId"),
3287
+ protocolType: requireString(args, "protocolType"),
3288
+ allowEarlyRedeem: readBoolean(args, "allowEarlyRedeem")
3306
3289
  }),
3307
- privateRateLimit("futures_get_order", 60)
3290
+ privateRateLimit("onchain_earn_redeem", 2)
3308
3291
  );
3309
- return normalize5(response);
3292
+ return normalizeResponse(response);
3310
3293
  }
3311
3294
  },
3295
+ // -------------------------------------------------------------------------
3296
+ // Cancel
3297
+ // -------------------------------------------------------------------------
3312
3298
  {
3313
- name: "futures_get_orders",
3314
- module: "futures",
3315
- description: "Query FUTURES open orders, history (last 7 days), or archive (up to 3 months). Private. Rate limit: 20 req/s.",
3316
- isWrite: false,
3299
+ name: "onchain_earn_cancel",
3300
+ module: "earn.onchain",
3301
+ description: "Cancel pending on-chain earn purchase. [CAUTION] Cancels a pending investment order. Not supported in demo mode. Private endpoint. Rate limit: 2 req/s.",
3302
+ isWrite: true,
3317
3303
  inputSchema: {
3318
3304
  type: "object",
3319
3305
  properties: {
3320
- status: {
3321
- type: "string",
3322
- enum: ["open", "history", "archive"],
3323
- description: "open=active, history=7d, archive=3mo"
3324
- },
3325
- instType: {
3326
- type: "string",
3327
- enum: [...FUTURES_INST_TYPES],
3328
- description: "FUTURES (default) or SWAP"
3329
- },
3330
- instId: {
3306
+ ordId: {
3331
3307
  type: "string",
3332
- description: "e.g. BTC-USDT-240329"
3308
+ description: "Order ID to cancel"
3333
3309
  },
3334
- ordType: {
3310
+ protocolType: {
3335
3311
  type: "string",
3336
- description: "Order type filter"
3337
- },
3338
- state: {
3339
- type: "string",
3340
- description: "canceled|filled"
3341
- },
3342
- after: {
3343
- type: "string",
3344
- description: "Pagination: before this order ID"
3345
- },
3346
- before: {
3347
- type: "string",
3348
- description: "Pagination: after this order ID"
3349
- },
3350
- begin: {
3351
- type: "string",
3352
- description: "Start time (ms)"
3353
- },
3354
- end: {
3355
- type: "string",
3356
- description: "End time (ms)"
3357
- },
3358
- limit: {
3359
- type: "number",
3360
- description: "Max results (default 100)"
3312
+ description: "Protocol type: staking, defi"
3361
3313
  }
3362
- }
3314
+ },
3315
+ required: ["ordId", "protocolType"]
3363
3316
  },
3364
3317
  handler: async (rawArgs, context) => {
3318
+ assertNotDemo(context.config, "onchain_earn_cancel");
3365
3319
  const args = asRecord(rawArgs);
3366
- const status = readString(args, "status") ?? "open";
3367
- const instType = readString(args, "instType") ?? "FUTURES";
3368
- assertEnum(instType, "instType", FUTURES_INST_TYPES);
3369
- const path4 = status === "archive" ? "/api/v5/trade/orders-history-archive" : status === "history" ? "/api/v5/trade/orders-history" : "/api/v5/trade/orders-pending";
3370
- const response = await context.client.privateGet(
3371
- path4,
3372
- compactObject({
3373
- instType,
3374
- instId: readString(args, "instId"),
3375
- ordType: readString(args, "ordType"),
3376
- state: readString(args, "state"),
3377
- after: readString(args, "after"),
3378
- before: readString(args, "before"),
3379
- begin: readString(args, "begin"),
3380
- end: readString(args, "end"),
3381
- limit: readNumber(args, "limit")
3382
- }),
3383
- privateRateLimit("futures_get_orders", 20)
3320
+ const response = await context.client.privatePost(
3321
+ "/api/v5/finance/staking-defi/cancel",
3322
+ {
3323
+ ordId: requireString(args, "ordId"),
3324
+ protocolType: requireString(args, "protocolType")
3325
+ },
3326
+ privateRateLimit("onchain_earn_cancel", 2)
3384
3327
  );
3385
- return normalize5(response);
3328
+ return normalizeResponse(response);
3386
3329
  }
3387
3330
  },
3331
+ // -------------------------------------------------------------------------
3332
+ // Get Active Orders
3333
+ // -------------------------------------------------------------------------
3388
3334
  {
3389
- name: "futures_get_positions",
3390
- module: "futures",
3391
- description: "Get current FUTURES delivery contract positions. Private endpoint. Rate limit: 10 req/s.",
3335
+ name: "onchain_earn_get_active_orders",
3336
+ module: "earn.onchain",
3337
+ description: "Get active on-chain earn orders. Returns current staking/DeFi investments. Private endpoint. Rate limit: 3 req/s.",
3392
3338
  isWrite: false,
3393
3339
  inputSchema: {
3394
3340
  type: "object",
3395
3341
  properties: {
3396
- instType: {
3342
+ productId: {
3397
3343
  type: "string",
3398
- enum: [...FUTURES_INST_TYPES],
3399
- description: "FUTURES (default) or SWAP"
3344
+ description: "Filter by product ID. Omit for all."
3400
3345
  },
3401
- instId: {
3346
+ protocolType: {
3402
3347
  type: "string",
3403
- description: "e.g. BTC-USDT-240329"
3348
+ description: "Filter by protocol type: staking, defi. Omit for all."
3404
3349
  },
3405
- posId: {
3406
- type: "string"
3350
+ ccy: {
3351
+ type: "string",
3352
+ description: "Filter by currency, e.g. ETH. Omit for all."
3353
+ },
3354
+ state: {
3355
+ type: "string",
3356
+ description: "Filter by state: 8 (pending), 13 (cancelling), 9 (onchain), 1 (earning), 2 (redeeming). Omit for all."
3407
3357
  }
3408
3358
  }
3409
3359
  },
3410
3360
  handler: async (rawArgs, context) => {
3411
3361
  const args = asRecord(rawArgs);
3412
- const instType = readString(args, "instType") ?? "FUTURES";
3413
- assertEnum(instType, "instType", FUTURES_INST_TYPES);
3414
3362
  const response = await context.client.privateGet(
3415
- "/api/v5/account/positions",
3363
+ "/api/v5/finance/staking-defi/orders-active",
3416
3364
  compactObject({
3417
- instType,
3418
- instId: readString(args, "instId"),
3419
- posId: readString(args, "posId")
3365
+ productId: readString(args, "productId"),
3366
+ protocolType: readString(args, "protocolType"),
3367
+ ccy: readString(args, "ccy"),
3368
+ state: readString(args, "state")
3420
3369
  }),
3421
- privateRateLimit("futures_get_positions", 10)
3370
+ privateRateLimit("onchain_earn_get_active_orders", 3)
3422
3371
  );
3423
- return normalize5(response);
3372
+ return normalizeResponse(response);
3424
3373
  }
3425
3374
  },
3375
+ // -------------------------------------------------------------------------
3376
+ // Get Order History
3377
+ // -------------------------------------------------------------------------
3426
3378
  {
3427
- name: "futures_get_fills",
3428
- module: "futures",
3429
- description: "Get FUTURES fill details. archive=false: last 3 days. archive=true: up to 3 months. Private. Rate limit: 20 req/s.",
3379
+ name: "onchain_earn_get_order_history",
3380
+ module: "earn.onchain",
3381
+ description: "Get on-chain earn order history. Returns past staking/DeFi investments including redeemed orders. Private endpoint. Rate limit: 3 req/s.",
3430
3382
  isWrite: false,
3431
3383
  inputSchema: {
3432
3384
  type: "object",
3433
3385
  properties: {
3434
- archive: {
3435
- type: "boolean",
3436
- description: "true=up to 3 months; false=last 3 days (default)"
3437
- },
3438
- instType: {
3386
+ productId: {
3439
3387
  type: "string",
3440
- enum: [...FUTURES_INST_TYPES],
3441
- description: "FUTURES (default) or SWAP"
3388
+ description: "Filter by product ID. Omit for all."
3442
3389
  },
3443
- instId: {
3390
+ protocolType: {
3444
3391
  type: "string",
3445
- description: "Instrument ID filter"
3392
+ description: "Filter by protocol type: staking, defi. Omit for all."
3446
3393
  },
3447
- ordId: {
3394
+ ccy: {
3448
3395
  type: "string",
3449
- description: "Order ID filter"
3396
+ description: "Filter by currency, e.g. ETH. Omit for all."
3450
3397
  },
3451
3398
  after: {
3452
3399
  type: "string",
3453
- description: "Pagination: before this bill ID"
3400
+ description: "Pagination: return results before this order ID"
3454
3401
  },
3455
3402
  before: {
3456
3403
  type: "string",
3457
- description: "Pagination: after this bill ID"
3458
- },
3459
- begin: {
3460
- type: "string",
3461
- description: "Start time (ms)"
3462
- },
3463
- end: {
3464
- type: "string",
3465
- description: "End time (ms)"
3404
+ description: "Pagination: return results after this order ID"
3466
3405
  },
3467
3406
  limit: {
3468
- type: "number",
3469
- description: "Max results (default 100 or 20 for archive)"
3407
+ type: "string",
3408
+ description: "Max results to return (default 100, max 100)"
3470
3409
  }
3471
3410
  }
3472
3411
  },
3473
3412
  handler: async (rawArgs, context) => {
3474
3413
  const args = asRecord(rawArgs);
3475
- const archive = readBoolean(args, "archive") ?? false;
3476
- const instType = readString(args, "instType") ?? "FUTURES";
3477
- assertEnum(instType, "instType", FUTURES_INST_TYPES);
3478
- const path4 = archive ? "/api/v5/trade/fills-history" : "/api/v5/trade/fills";
3479
3414
  const response = await context.client.privateGet(
3480
- path4,
3415
+ "/api/v5/finance/staking-defi/orders-history",
3481
3416
  compactObject({
3482
- instType,
3483
- instId: readString(args, "instId"),
3484
- ordId: readString(args, "ordId"),
3417
+ productId: readString(args, "productId"),
3418
+ protocolType: readString(args, "protocolType"),
3419
+ ccy: readString(args, "ccy"),
3485
3420
  after: readString(args, "after"),
3486
3421
  before: readString(args, "before"),
3487
- begin: readString(args, "begin"),
3488
- end: readString(args, "end"),
3489
- limit: readNumber(args, "limit") ?? (archive ? 20 : void 0)
3422
+ limit: readString(args, "limit")
3490
3423
  }),
3491
- privateRateLimit("futures_get_fills", 20)
3424
+ privateRateLimit("onchain_earn_get_order_history", 3)
3492
3425
  );
3493
- return normalize5(response);
3426
+ return normalizeResponse(response);
3494
3427
  }
3495
3428
  }
3496
3429
  ];
3497
3430
  }
3498
- function registerOnchainEarnTools() {
3431
+ function registerAllEarnTools() {
3432
+ return [
3433
+ ...registerEarnTools(),
3434
+ ...registerOnchainEarnTools()
3435
+ ];
3436
+ }
3437
+ var FUTURES_INST_TYPES = ["FUTURES", "SWAP"];
3438
+ function normalize5(response) {
3439
+ return {
3440
+ endpoint: response.endpoint,
3441
+ requestTime: response.requestTime,
3442
+ data: response.data
3443
+ };
3444
+ }
3445
+ function registerFuturesTools() {
3499
3446
  return [
3500
- // -------------------------------------------------------------------------
3501
- // Get Offers
3502
- // -------------------------------------------------------------------------
3503
3447
  {
3504
- name: "onchain_earn_get_offers",
3505
- module: "earn.onchain",
3506
- description: "Get available on-chain earn (staking/DeFi) offers. Returns investment products with APY, terms, and limits. Private endpoint. Rate limit: 3 req/s.",
3507
- isWrite: false,
3448
+ name: "futures_place_order",
3449
+ module: "futures",
3450
+ description: "Place a FUTURES delivery contract order (e.g. instId: BTC-USDT-240329). Optionally attach TP/SL via tpTriggerPx/slTriggerPx. [CAUTION] Executes real trades. Private endpoint. Rate limit: 60 req/s.",
3451
+ isWrite: true,
3508
3452
  inputSchema: {
3509
3453
  type: "object",
3510
3454
  properties: {
3511
- productId: {
3455
+ instId: {
3512
3456
  type: "string",
3513
- description: "Specific product ID to query. Omit for all offers."
3457
+ description: "e.g. BTC-USDT-240329"
3514
3458
  },
3515
- protocolType: {
3459
+ tdMode: {
3516
3460
  type: "string",
3517
- description: "Protocol type filter: staking, defi. Omit for all types."
3461
+ enum: ["cross", "isolated"],
3462
+ description: "cross|isolated margin"
3518
3463
  },
3519
- ccy: {
3464
+ side: {
3520
3465
  type: "string",
3521
- description: "Currency filter, e.g. ETH. Omit for all currencies."
3466
+ enum: ["buy", "sell"],
3467
+ description: "one-way: buy=open long, sell=open short (use reduceOnly=true to close); hedge: combined with posSide"
3468
+ },
3469
+ posSide: {
3470
+ type: "string",
3471
+ enum: ["long", "short", "net"],
3472
+ description: "net=one-way mode (default); long/short=hedge mode only"
3473
+ },
3474
+ ordType: {
3475
+ type: "string",
3476
+ enum: ["market", "limit", "post_only", "fok", "ioc"],
3477
+ description: "market(no px)|limit(px req)|post_only(maker)|fok(all-or-cancel)|ioc(partial fill)"
3478
+ },
3479
+ sz: {
3480
+ type: "string",
3481
+ description: "Number of contracts (NOT USDT amount). Use market_get_instruments to get ctVal for conversion."
3482
+ },
3483
+ px: {
3484
+ type: "string",
3485
+ description: "Required for limit/post_only/fok/ioc"
3486
+ },
3487
+ reduceOnly: {
3488
+ type: "boolean",
3489
+ description: "Close/reduce only, no new position (one-way mode)"
3490
+ },
3491
+ clOrdId: {
3492
+ type: "string",
3493
+ description: "Client order ID (max 32 chars)"
3494
+ },
3495
+ tpTriggerPx: {
3496
+ type: "string",
3497
+ description: "TP trigger price; places TP at tpOrdPx"
3498
+ },
3499
+ tpOrdPx: {
3500
+ type: "string",
3501
+ description: "TP order price; -1=market"
3502
+ },
3503
+ slTriggerPx: {
3504
+ type: "string",
3505
+ description: "SL trigger price; places SL at slOrdPx"
3506
+ },
3507
+ slOrdPx: {
3508
+ type: "string",
3509
+ description: "SL order price; -1=market"
3522
3510
  }
3523
- }
3511
+ },
3512
+ required: ["instId", "tdMode", "side", "ordType", "sz"]
3524
3513
  },
3525
3514
  handler: async (rawArgs, context) => {
3526
3515
  const args = asRecord(rawArgs);
3527
- const response = await context.client.privateGet(
3528
- "/api/v5/finance/staking-defi/offers",
3516
+ const reduceOnly = args.reduceOnly;
3517
+ const tpTriggerPx = readString(args, "tpTriggerPx");
3518
+ const tpOrdPx = readString(args, "tpOrdPx");
3519
+ const slTriggerPx = readString(args, "slTriggerPx");
3520
+ const slOrdPx = readString(args, "slOrdPx");
3521
+ const algoEntry = compactObject({ tpTriggerPx, tpOrdPx, slTriggerPx, slOrdPx });
3522
+ const attachAlgoOrds = Object.keys(algoEntry).length > 0 ? [algoEntry] : void 0;
3523
+ const response = await context.client.privatePost(
3524
+ "/api/v5/trade/order",
3529
3525
  compactObject({
3530
- productId: readString(args, "productId"),
3531
- protocolType: readString(args, "protocolType"),
3532
- ccy: readString(args, "ccy")
3526
+ instId: requireString(args, "instId"),
3527
+ tdMode: requireString(args, "tdMode"),
3528
+ side: requireString(args, "side"),
3529
+ posSide: readString(args, "posSide"),
3530
+ ordType: requireString(args, "ordType"),
3531
+ sz: requireString(args, "sz"),
3532
+ px: readString(args, "px"),
3533
+ reduceOnly: typeof reduceOnly === "boolean" ? String(reduceOnly) : void 0,
3534
+ clOrdId: readString(args, "clOrdId"),
3535
+ tag: context.config.sourceTag,
3536
+ attachAlgoOrds
3533
3537
  }),
3534
- privateRateLimit("onchain_earn_get_offers", 3)
3538
+ privateRateLimit("futures_place_order", 60)
3535
3539
  );
3536
- return normalizeResponse(response);
3540
+ return normalize5(response);
3537
3541
  }
3538
3542
  },
3539
- // -------------------------------------------------------------------------
3540
- // Purchase
3541
- // -------------------------------------------------------------------------
3542
3543
  {
3543
- name: "onchain_earn_purchase",
3544
- module: "earn.onchain",
3545
- description: "Purchase on-chain earn (staking/DeFi) product. [CAUTION] Moves real funds into staking/DeFi product. Not supported in demo/simulated trading mode. Private endpoint. Rate limit: 2 req/s.",
3544
+ name: "futures_cancel_order",
3545
+ module: "futures",
3546
+ description: "Cancel an unfilled FUTURES delivery order. Private endpoint. Rate limit: 60 req/s.",
3546
3547
  isWrite: true,
3547
3548
  inputSchema: {
3548
3549
  type: "object",
3549
3550
  properties: {
3550
- productId: {
3551
+ instId: {
3551
3552
  type: "string",
3552
- description: "Product ID to purchase"
3553
- },
3554
- investData: {
3555
- type: "array",
3556
- description: "Investment data array: [{ccy, amt}]. Each item specifies currency and amount.",
3557
- items: {
3558
- type: "object",
3559
- properties: {
3560
- ccy: { type: "string", description: "Currency, e.g. ETH" },
3561
- amt: { type: "string", description: "Amount to invest" }
3562
- },
3563
- required: ["ccy", "amt"]
3564
- }
3553
+ description: "e.g. BTC-USDT-240329"
3565
3554
  },
3566
- term: {
3567
- type: "string",
3568
- description: "Investment term in days. Required for fixed-term products."
3555
+ ordId: {
3556
+ type: "string"
3569
3557
  },
3570
- tag: {
3558
+ clOrdId: {
3571
3559
  type: "string",
3572
- description: "Order tag for tracking (optional)."
3560
+ description: "Client order ID"
3573
3561
  }
3574
3562
  },
3575
- required: ["productId", "investData"]
3563
+ required: ["instId"]
3576
3564
  },
3577
3565
  handler: async (rawArgs, context) => {
3578
- assertNotDemo(context.config, "onchain_earn_purchase");
3579
3566
  const args = asRecord(rawArgs);
3580
3567
  const response = await context.client.privatePost(
3581
- "/api/v5/finance/staking-defi/purchase",
3568
+ "/api/v5/trade/cancel-order",
3582
3569
  compactObject({
3583
- productId: requireString(args, "productId"),
3584
- investData: args.investData,
3585
- term: readString(args, "term"),
3586
- tag: readString(args, "tag")
3570
+ instId: requireString(args, "instId"),
3571
+ ordId: readString(args, "ordId"),
3572
+ clOrdId: readString(args, "clOrdId")
3587
3573
  }),
3588
- privateRateLimit("onchain_earn_purchase", 2)
3574
+ privateRateLimit("futures_cancel_order", 60)
3589
3575
  );
3590
- return normalizeResponse(response);
3576
+ return normalize5(response);
3591
3577
  }
3592
3578
  },
3593
- // -------------------------------------------------------------------------
3594
- // Redeem
3595
- // -------------------------------------------------------------------------
3596
3579
  {
3597
- name: "onchain_earn_redeem",
3598
- module: "earn.onchain",
3599
- description: "Redeem on-chain earn (staking/DeFi) investment. [CAUTION] Withdraws funds from staking/DeFi product. Some products may have lock periods. Not supported in demo mode. Private endpoint. Rate limit: 2 req/s.",
3600
- isWrite: true,
3580
+ name: "futures_get_order",
3581
+ module: "futures",
3582
+ description: "Get details of a single FUTURES delivery order by ordId or clOrdId. Private endpoint. Rate limit: 60 req/s.",
3583
+ isWrite: false,
3601
3584
  inputSchema: {
3602
3585
  type: "object",
3603
3586
  properties: {
3604
- ordId: {
3587
+ instId: {
3605
3588
  type: "string",
3606
- description: "Order ID to redeem"
3589
+ description: "e.g. BTC-USDT-240329"
3607
3590
  },
3608
- protocolType: {
3591
+ ordId: {
3609
3592
  type: "string",
3610
- description: "Protocol type: staking, defi"
3593
+ description: "Provide ordId or clOrdId"
3611
3594
  },
3612
- allowEarlyRedeem: {
3613
- type: "boolean",
3614
- description: "Allow early redemption for fixed-term products (may incur penalties). Default false."
3595
+ clOrdId: {
3596
+ type: "string",
3597
+ description: "Provide ordId or clOrdId"
3615
3598
  }
3616
3599
  },
3617
- required: ["ordId", "protocolType"]
3600
+ required: ["instId"]
3618
3601
  },
3619
3602
  handler: async (rawArgs, context) => {
3620
- assertNotDemo(context.config, "onchain_earn_redeem");
3621
3603
  const args = asRecord(rawArgs);
3622
- const response = await context.client.privatePost(
3623
- "/api/v5/finance/staking-defi/redeem",
3604
+ const response = await context.client.privateGet(
3605
+ "/api/v5/trade/order",
3624
3606
  compactObject({
3625
- ordId: requireString(args, "ordId"),
3626
- protocolType: requireString(args, "protocolType"),
3627
- allowEarlyRedeem: readBoolean(args, "allowEarlyRedeem")
3607
+ instId: requireString(args, "instId"),
3608
+ ordId: readString(args, "ordId"),
3609
+ clOrdId: readString(args, "clOrdId")
3628
3610
  }),
3629
- privateRateLimit("onchain_earn_redeem", 2)
3611
+ privateRateLimit("futures_get_order", 60)
3630
3612
  );
3631
- return normalizeResponse(response);
3613
+ return normalize5(response);
3632
3614
  }
3633
3615
  },
3634
- // -------------------------------------------------------------------------
3635
- // Cancel
3636
- // -------------------------------------------------------------------------
3637
3616
  {
3638
- name: "onchain_earn_cancel",
3639
- module: "earn.onchain",
3640
- description: "Cancel pending on-chain earn purchase. [CAUTION] Cancels a pending investment order. Not supported in demo mode. Private endpoint. Rate limit: 2 req/s.",
3641
- isWrite: true,
3617
+ name: "futures_get_orders",
3618
+ module: "futures",
3619
+ description: "Query FUTURES open orders, history (last 7 days), or archive (up to 3 months). Private. Rate limit: 20 req/s.",
3620
+ isWrite: false,
3642
3621
  inputSchema: {
3643
3622
  type: "object",
3644
3623
  properties: {
3645
- ordId: {
3624
+ status: {
3646
3625
  type: "string",
3647
- description: "Order ID to cancel"
3626
+ enum: ["open", "history", "archive"],
3627
+ description: "open=active, history=7d, archive=3mo"
3648
3628
  },
3649
- protocolType: {
3629
+ instType: {
3650
3630
  type: "string",
3651
- description: "Protocol type: staking, defi"
3631
+ enum: [...FUTURES_INST_TYPES],
3632
+ description: "FUTURES (default) or SWAP"
3633
+ },
3634
+ instId: {
3635
+ type: "string",
3636
+ description: "e.g. BTC-USDT-240329"
3637
+ },
3638
+ ordType: {
3639
+ type: "string",
3640
+ description: "Order type filter"
3641
+ },
3642
+ state: {
3643
+ type: "string",
3644
+ description: "canceled|filled"
3645
+ },
3646
+ after: {
3647
+ type: "string",
3648
+ description: "Pagination: before this order ID"
3649
+ },
3650
+ before: {
3651
+ type: "string",
3652
+ description: "Pagination: after this order ID"
3653
+ },
3654
+ begin: {
3655
+ type: "string",
3656
+ description: "Start time (ms)"
3657
+ },
3658
+ end: {
3659
+ type: "string",
3660
+ description: "End time (ms)"
3661
+ },
3662
+ limit: {
3663
+ type: "number",
3664
+ description: "Max results (default 100)"
3652
3665
  }
3653
- },
3654
- required: ["ordId", "protocolType"]
3666
+ }
3655
3667
  },
3656
3668
  handler: async (rawArgs, context) => {
3657
- assertNotDemo(context.config, "onchain_earn_cancel");
3658
3669
  const args = asRecord(rawArgs);
3659
- const response = await context.client.privatePost(
3660
- "/api/v5/finance/staking-defi/cancel",
3661
- {
3662
- ordId: requireString(args, "ordId"),
3663
- protocolType: requireString(args, "protocolType")
3664
- },
3665
- privateRateLimit("onchain_earn_cancel", 2)
3670
+ const status = readString(args, "status") ?? "open";
3671
+ const instType = readString(args, "instType") ?? "FUTURES";
3672
+ assertEnum(instType, "instType", FUTURES_INST_TYPES);
3673
+ const path4 = status === "archive" ? "/api/v5/trade/orders-history-archive" : status === "history" ? "/api/v5/trade/orders-history" : "/api/v5/trade/orders-pending";
3674
+ const response = await context.client.privateGet(
3675
+ path4,
3676
+ compactObject({
3677
+ instType,
3678
+ instId: readString(args, "instId"),
3679
+ ordType: readString(args, "ordType"),
3680
+ state: readString(args, "state"),
3681
+ after: readString(args, "after"),
3682
+ before: readString(args, "before"),
3683
+ begin: readString(args, "begin"),
3684
+ end: readString(args, "end"),
3685
+ limit: readNumber(args, "limit")
3686
+ }),
3687
+ privateRateLimit("futures_get_orders", 20)
3666
3688
  );
3667
- return normalizeResponse(response);
3689
+ return normalize5(response);
3668
3690
  }
3669
3691
  },
3670
- // -------------------------------------------------------------------------
3671
- // Get Active Orders
3672
- // -------------------------------------------------------------------------
3673
3692
  {
3674
- name: "onchain_earn_get_active_orders",
3675
- module: "earn.onchain",
3676
- description: "Get active on-chain earn orders. Returns current staking/DeFi investments. Private endpoint. Rate limit: 3 req/s.",
3693
+ name: "futures_get_positions",
3694
+ module: "futures",
3695
+ description: "Get current FUTURES delivery contract positions. Private endpoint. Rate limit: 10 req/s.",
3677
3696
  isWrite: false,
3678
3697
  inputSchema: {
3679
3698
  type: "object",
3680
3699
  properties: {
3681
- productId: {
3682
- type: "string",
3683
- description: "Filter by product ID. Omit for all."
3684
- },
3685
- protocolType: {
3700
+ instType: {
3686
3701
  type: "string",
3687
- description: "Filter by protocol type: staking, defi. Omit for all."
3702
+ enum: [...FUTURES_INST_TYPES],
3703
+ description: "FUTURES (default) or SWAP"
3688
3704
  },
3689
- ccy: {
3705
+ instId: {
3690
3706
  type: "string",
3691
- description: "Filter by currency, e.g. ETH. Omit for all."
3707
+ description: "e.g. BTC-USDT-240329"
3692
3708
  },
3693
- state: {
3694
- type: "string",
3695
- description: "Filter by state: 8 (pending), 13 (cancelling), 9 (onchain), 1 (earning), 2 (redeeming). Omit for all."
3709
+ posId: {
3710
+ type: "string"
3696
3711
  }
3697
3712
  }
3698
3713
  },
3699
3714
  handler: async (rawArgs, context) => {
3700
3715
  const args = asRecord(rawArgs);
3716
+ const instType = readString(args, "instType") ?? "FUTURES";
3717
+ assertEnum(instType, "instType", FUTURES_INST_TYPES);
3701
3718
  const response = await context.client.privateGet(
3702
- "/api/v5/finance/staking-defi/orders-active",
3719
+ "/api/v5/account/positions",
3703
3720
  compactObject({
3704
- productId: readString(args, "productId"),
3705
- protocolType: readString(args, "protocolType"),
3706
- ccy: readString(args, "ccy"),
3707
- state: readString(args, "state")
3721
+ instType,
3722
+ instId: readString(args, "instId"),
3723
+ posId: readString(args, "posId")
3708
3724
  }),
3709
- privateRateLimit("onchain_earn_get_active_orders", 3)
3725
+ privateRateLimit("futures_get_positions", 10)
3710
3726
  );
3711
- return normalizeResponse(response);
3727
+ return normalize5(response);
3712
3728
  }
3713
3729
  },
3714
- // -------------------------------------------------------------------------
3715
- // Get Order History
3716
- // -------------------------------------------------------------------------
3717
3730
  {
3718
- name: "onchain_earn_get_order_history",
3719
- module: "earn.onchain",
3720
- description: "Get on-chain earn order history. Returns past staking/DeFi investments including redeemed orders. Private endpoint. Rate limit: 3 req/s.",
3731
+ name: "futures_get_fills",
3732
+ module: "futures",
3733
+ description: "Get FUTURES fill details. archive=false: last 3 days. archive=true: up to 3 months. Private. Rate limit: 20 req/s.",
3721
3734
  isWrite: false,
3722
3735
  inputSchema: {
3723
3736
  type: "object",
3724
3737
  properties: {
3725
- productId: {
3738
+ archive: {
3739
+ type: "boolean",
3740
+ description: "true=up to 3 months; false=last 3 days (default)"
3741
+ },
3742
+ instType: {
3726
3743
  type: "string",
3727
- description: "Filter by product ID. Omit for all."
3744
+ enum: [...FUTURES_INST_TYPES],
3745
+ description: "FUTURES (default) or SWAP"
3728
3746
  },
3729
- protocolType: {
3747
+ instId: {
3730
3748
  type: "string",
3731
- description: "Filter by protocol type: staking, defi. Omit for all."
3749
+ description: "Instrument ID filter"
3732
3750
  },
3733
- ccy: {
3751
+ ordId: {
3734
3752
  type: "string",
3735
- description: "Filter by currency, e.g. ETH. Omit for all."
3753
+ description: "Order ID filter"
3736
3754
  },
3737
3755
  after: {
3738
3756
  type: "string",
3739
- description: "Pagination: return results before this order ID"
3757
+ description: "Pagination: before this bill ID"
3740
3758
  },
3741
3759
  before: {
3742
3760
  type: "string",
3743
- description: "Pagination: return results after this order ID"
3761
+ description: "Pagination: after this bill ID"
3744
3762
  },
3745
- limit: {
3763
+ begin: {
3746
3764
  type: "string",
3747
- description: "Max results to return (default 100, max 100)"
3765
+ description: "Start time (ms)"
3766
+ },
3767
+ end: {
3768
+ type: "string",
3769
+ description: "End time (ms)"
3770
+ },
3771
+ limit: {
3772
+ type: "number",
3773
+ description: "Max results (default 100 or 20 for archive)"
3748
3774
  }
3749
3775
  }
3750
3776
  },
3751
3777
  handler: async (rawArgs, context) => {
3752
3778
  const args = asRecord(rawArgs);
3779
+ const archive = readBoolean(args, "archive") ?? false;
3780
+ const instType = readString(args, "instType") ?? "FUTURES";
3781
+ assertEnum(instType, "instType", FUTURES_INST_TYPES);
3782
+ const path4 = archive ? "/api/v5/trade/fills-history" : "/api/v5/trade/fills";
3753
3783
  const response = await context.client.privateGet(
3754
- "/api/v5/finance/staking-defi/orders-history",
3784
+ path4,
3755
3785
  compactObject({
3756
- productId: readString(args, "productId"),
3757
- protocolType: readString(args, "protocolType"),
3758
- ccy: readString(args, "ccy"),
3786
+ instType,
3787
+ instId: readString(args, "instId"),
3788
+ ordId: readString(args, "ordId"),
3759
3789
  after: readString(args, "after"),
3760
3790
  before: readString(args, "before"),
3761
- limit: readString(args, "limit")
3791
+ begin: readString(args, "begin"),
3792
+ end: readString(args, "end"),
3793
+ limit: readNumber(args, "limit") ?? (archive ? 20 : void 0)
3762
3794
  }),
3763
- privateRateLimit("onchain_earn_get_order_history", 3)
3795
+ privateRateLimit("futures_get_fills", 20)
3764
3796
  );
3765
- return normalizeResponse(response);
3797
+ return normalize5(response);
3766
3798
  }
3767
3799
  }
3768
3800
  ];
@@ -4284,7 +4316,7 @@ function registerOptionTools() {
4284
4316
  },
4285
4317
  sz: {
4286
4318
  type: "string",
4287
- description: "Number of contracts"
4319
+ description: "Number of contracts (NOT USDT amount). Use market_get_instruments to get ctVal for conversion."
4288
4320
  },
4289
4321
  px: {
4290
4322
  type: "string",
@@ -4391,7 +4423,7 @@ function registerOptionTools() {
4391
4423
  instId: { type: "string", description: "e.g. BTC-USD-241227-50000-C" },
4392
4424
  ordId: { type: "string" },
4393
4425
  clOrdId: { type: "string" },
4394
- newSz: { type: "string", description: "New quantity (contracts)" },
4426
+ newSz: { type: "string", description: "New number of contracts (NOT USDT amount)" },
4395
4427
  newPx: { type: "string", description: "New price" }
4396
4428
  },
4397
4429
  required: ["instId"]
@@ -4763,17 +4795,20 @@ function registerSpotTradeTools() {
4763
4795
  description: "e.g. BTC-USDT"
4764
4796
  },
4765
4797
  ordId: {
4766
- type: "string"
4798
+ type: "string",
4799
+ description: "Order ID"
4767
4800
  },
4768
4801
  clOrdId: {
4769
4802
  type: "string",
4770
4803
  description: "Client order ID"
4771
4804
  },
4772
4805
  newSz: {
4773
- type: "string"
4806
+ type: "string",
4807
+ description: "New order size in base currency (e.g. BTC amount)"
4774
4808
  },
4775
4809
  newPx: {
4776
- type: "string"
4810
+ type: "string",
4811
+ description: "New order price"
4777
4812
  },
4778
4813
  newClOrdId: {
4779
4814
  type: "string",
@@ -4948,7 +4983,7 @@ function registerSpotTradeTools() {
4948
4983
  properties: {
4949
4984
  instId: { type: "string", description: "e.g. BTC-USDT" },
4950
4985
  algoId: { type: "string", description: "Algo order ID" },
4951
- newSz: { type: "string" },
4986
+ newSz: { type: "string", description: "New order size in base currency (e.g. BTC amount)" },
4952
4987
  newTpTriggerPx: { type: "string", description: "New TP trigger price" },
4953
4988
  newTpOrdPx: { type: "string", description: "New TP order price; -1=market" },
4954
4989
  newSlTriggerPx: { type: "string", description: "New SL trigger price" },
@@ -5353,7 +5388,7 @@ function registerSwapTradeTools() {
5353
5388
  },
5354
5389
  sz: {
5355
5390
  type: "string",
5356
- description: "Contracts (e.g. '1'; BTC-USDT-SWAP: 1ct=0.01 BTC)"
5391
+ description: "Number of contracts (NOT USDT amount). Use market_get_instruments to get ctVal for conversion."
5357
5392
  },
5358
5393
  px: {
5359
5394
  type: "string",
@@ -5618,7 +5653,7 @@ function registerSwapTradeTools() {
5618
5653
  properties: {
5619
5654
  instId: { type: "string", description: "e.g. BTC-USDT-SWAP" },
5620
5655
  algoId: { type: "string", description: "Algo order ID" },
5621
- newSz: { type: "string", description: "New quantity (contracts)" },
5656
+ newSz: { type: "string", description: "New number of contracts (NOT USDT amount)" },
5622
5657
  newTpTriggerPx: { type: "string", description: "New TP trigger price" },
5623
5658
  newTpOrdPx: { type: "string", description: "New TP order price; -1=market" },
5624
5659
  newSlTriggerPx: { type: "string", description: "New SL trigger price" },
@@ -5971,8 +6006,7 @@ function allToolSpecs() {
5971
6006
  ...registerAlgoTradeTools(),
5972
6007
  ...registerAccountTools(),
5973
6008
  ...registerBotTools(),
5974
- ...registerEarnTools(),
5975
- ...registerOnchainEarnTools(),
6009
+ ...registerAllEarnTools(),
5976
6010
  ...registerAuditTools()
5977
6011
  ];
5978
6012
  }
@@ -6095,6 +6129,13 @@ function loadConfig(cli) {
6095
6129
  "Set OKX_TIMEOUT_MS as a positive integer in milliseconds."
6096
6130
  );
6097
6131
  }
6132
+ const rawProxyUrl = toml.proxy_url?.trim();
6133
+ if (rawProxyUrl && !rawProxyUrl.startsWith("http://") && !rawProxyUrl.startsWith("https://")) {
6134
+ throw new ConfigError(
6135
+ `Invalid proxy URL "${rawProxyUrl}".`,
6136
+ "proxy_url must start with http:// or https://. SOCKS proxies are not supported."
6137
+ );
6138
+ }
6098
6139
  return {
6099
6140
  ...creds,
6100
6141
  baseUrl,
@@ -6105,6 +6146,7 @@ function loadConfig(cli) {
6105
6146
  site,
6106
6147
  userAgent: cli.userAgent,
6107
6148
  sourceTag: cli.sourceTag ?? DEFAULT_SOURCE_TAG,
6149
+ proxyUrl: rawProxyUrl || void 0,
6108
6150
  verbose: cli.verbose ?? false
6109
6151
  };
6110
6152
  }
@@ -6338,7 +6380,7 @@ function readCliVersion() {
6338
6380
  return "0.0.0";
6339
6381
  }
6340
6382
  var CLI_VERSION = readCliVersion();
6341
- var GIT_HASH = true ? "7777cc2" : "dev";
6383
+ var GIT_HASH = true ? "ecce5a7" : "dev";
6342
6384
  var Report = class {
6343
6385
  lines = [];
6344
6386
  add(key, value) {
@@ -7086,7 +7128,7 @@ var HELP_TREE = {
7086
7128
  description: "Contract DCA (Martingale) bot \u2014 leveraged recurring buys on futures/swaps",
7087
7129
  commands: {
7088
7130
  orders: {
7089
- usage: "okx bot dca orders [--history]",
7131
+ usage: "okx bot dca orders [--algoId <id>] [--instId <id>] [--history]",
7090
7132
  description: "List active or historical Contract DCA bot orders"
7091
7133
  },
7092
7134
  details: {
@@ -9261,7 +9303,9 @@ async function cmdDcaStop(run, opts) {
9261
9303
  }
9262
9304
  async function cmdDcaOrders(run, opts) {
9263
9305
  const result = await run("dca_get_orders", {
9264
- status: opts.history ? "history" : "active"
9306
+ status: opts.history ? "history" : "active",
9307
+ algoId: opts.algoId,
9308
+ instId: opts.instId
9265
9309
  });
9266
9310
  const orders = getData7(result) ?? [];
9267
9311
  if (opts.json) return printJson(orders);
@@ -9380,7 +9424,7 @@ function cmdOnchainEarnOrderHistory(run, v) {
9380
9424
  // src/index.ts
9381
9425
  var _require2 = createRequire2(import.meta.url);
9382
9426
  var CLI_VERSION2 = _require2("../package.json").version;
9383
- var GIT_HASH2 = true ? "7777cc2" : "dev";
9427
+ var GIT_HASH2 = true ? "ecce5a7" : "dev";
9384
9428
  function handleConfigCommand(action, rest, json, lang, force) {
9385
9429
  if (action === "init") return cmdConfigInit(lang === "zh" ? "zh" : "en");
9386
9430
  if (action === "show") return cmdConfigShow(json);
@@ -9811,7 +9855,7 @@ function handleBotGridCommand(run, v, rest, json) {
9811
9855
  }
9812
9856
  function handleBotDcaCommand(run, subAction, v, json) {
9813
9857
  if (subAction === "orders")
9814
- return cmdDcaOrders(run, { history: v.history ?? false, json });
9858
+ return cmdDcaOrders(run, { algoId: v.algoId, instId: v.instId, history: v.history ?? false, json });
9815
9859
  if (subAction === "details")
9816
9860
  return cmdDcaDetails(run, { algoId: v.algoId, json });
9817
9861
  if (subAction === "sub-orders")