foliko 1.0.77 → 1.0.78

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 (36) hide show
  1. package/.agent/data/default.json +31559 -0
  2. package/.agent/data/plugins-state.json +10 -1
  3. package/.claude/settings.local.json +13 -2
  4. package/.env.example +54 -54
  5. package/cli/src/commands/chat.js +1 -1
  6. package/examples/basic.js +1 -1
  7. package/package.json +5 -3
  8. package/plugins/ai-plugin.js +1 -1
  9. package/plugins/ambient-agent/index.js +1 -1
  10. package/plugins/audit-plugin.js +1 -1
  11. package/plugins/default-plugins.js +92 -209
  12. package/plugins/email/index.js +1 -1
  13. package/plugins/extension-executor-plugin.js +326 -0
  14. package/plugins/feishu-plugin.js +1 -1
  15. package/plugins/file-system-plugin.js +57 -6
  16. package/plugins/gate-trading.js +747 -0
  17. package/plugins/install-plugin.js +1 -1
  18. package/plugins/python-executor-plugin.js +1 -1
  19. package/plugins/python-plugin-loader.js +275 -105
  20. package/plugins/rules-plugin.js +1 -1
  21. package/plugins/scheduler-plugin.js +1 -1
  22. package/plugins/session-plugin.js +132 -7
  23. package/plugins/shell-executor-plugin.js +1 -1
  24. package/plugins/storage-plugin.js +24 -1
  25. package/plugins/subagent-plugin.js +2 -2
  26. package/plugins/telegram-plugin.js +1 -1
  27. package/plugins/think-plugin.js +10 -10
  28. package/plugins/tools-plugin.js +1 -1
  29. package/plugins/web-plugin.js +49 -18
  30. package/plugins/weixin-plugin.js +1 -1
  31. package/skills/foliko-dev/SKILL.md +583 -500
  32. package/skills/python-plugin-dev/SKILL.md +238 -266
  33. package/src/core/agent-chat.js +103 -4
  34. package/src/core/agent.js +85 -19
  35. package/src/core/plugin-base.js +43 -0
  36. package/src/executors/mcp-executor.js +126 -22
@@ -0,0 +1,747 @@
1
+ const { Plugin } = require('../src/core/plugin-base')
2
+ class GateTradingPlugin extends Plugin {
3
+ constructor(config = {}) {
4
+ super();
5
+ this.name = 'gate-trading';
6
+ this.version = '1.1.0';
7
+ this.description = 'Gate.io 加密货币交易插件(支持现货+合约)';
8
+ this.priority = 100;
9
+
10
+ // 从 .env 文件读取密钥
11
+ const fs = require('fs');
12
+ const path = require('path');
13
+ this.apiKey = config.apiKey || process.env.GATE_API_KEY|| '';
14
+ this.secretKey = config.secretKey ||process.env.GATE_SECRET_KEY|| '';
15
+ }
16
+
17
+ _createSpotApi() {
18
+ const GateApi = require('gate-api');
19
+ const config = new GateApi.ApiClient();
20
+ config.setApiKeySecret(this.apiKey, this.secretKey);
21
+ return new GateApi.SpotApi(config);
22
+ }
23
+
24
+ _createWalletApi() {
25
+ const GateApi = require('gate-api');
26
+ const config = new GateApi.ApiClient();
27
+ config.setApiKeySecret(this.apiKey, this.secretKey);
28
+ return new GateApi.WalletApi(config);
29
+ }
30
+
31
+ _createFuturesApi() {
32
+ const GateApi = require('gate-api');
33
+ const config = new GateApi.ApiClient();
34
+ config.setApiKeySecret(this.apiKey, this.secretKey);
35
+ return new GateApi.FuturesApi(config);
36
+ }
37
+
38
+ _createPerpetualApi() {
39
+ const GateApi = require('gate-api');
40
+ const config = new GateApi.ApiClient();
41
+ config.setApiKeySecret(this.apiKey, this.secretKey);
42
+ return new GateApi.FuturesApi(config);
43
+ }
44
+
45
+ _checkAuth() {
46
+ if (!this.apiKey || !this.secretKey) {
47
+ throw new Error('请先配置 API 密钥');
48
+ }
49
+ }
50
+
51
+ install(framework) {
52
+ super.install(framework);
53
+ const { z } = require('zod');
54
+
55
+ // 1. 配置 API 密钥
56
+ this.registerTool('gate_configure_api', {
57
+ description: '配置 Gate.io API 密钥(安全存储)',
58
+ inputSchema: z.object({
59
+ api_key: z.string().describe('Gate.io API Key'),
60
+ secret: z.string().describe('Gate.io Secret Key'),
61
+ }),
62
+ execute: async (args) => {
63
+ this.apiKey = args.api_key;
64
+ this.secretKey = args.secret;
65
+ const fs = require('fs');
66
+ fs.writeFileSync(__dirname + '/.env', `GATE_API_KEY=${args.api_key}\nGATE_SECRET_KEY=${args.secret}\n`);
67
+ return { success: true, message: 'Gate API 密钥已成功配置' };
68
+ },
69
+ });
70
+
71
+ // 2. 获取 API 配置状态
72
+ this.registerTool('gate_get_api_status', {
73
+ description: '获取 Gate API 配置状态',
74
+ inputSchema: z.object({}),
75
+ execute: async () => {
76
+ const configured = !!(this.apiKey && this.secretKey);
77
+ return { configured, apiKey: configured ? `${this.apiKey.substring(0, 8)}...` : null, hasSecret: !!this.secretKey };
78
+ },
79
+ });
80
+
81
+ // 3. 清除 API 配置
82
+ this.registerTool('gate_clear_api_config', {
83
+ description: '清除已存储的 Gate API 配置',
84
+ inputSchema: z.object({}),
85
+ execute: async () => {
86
+ this.apiKey = '';
87
+ this.secretKey = '';
88
+ try { require('fs').unlinkSync(__dirname + '/.env'); } catch (e) {}
89
+ return { success: true, message: 'API 配置已清除' };
90
+ },
91
+ });
92
+
93
+ // 4. 测试连接
94
+ this.registerTool('gate_test_connection', {
95
+ description: '测试 Gate.io API 连接和密钥有效性',
96
+ inputSchema: z.object({}),
97
+ execute: async () => {
98
+ try {
99
+ this._checkAuth();
100
+ const spotApi = this._createSpotApi();
101
+ const currencies = await spotApi.listCurrencies();
102
+ return { success: true, message: 'API 连接成功,密钥有效', currencyCount: currencies.body.length };
103
+ } catch (error) { return { success: false, error: error.message }; }
104
+ },
105
+ });
106
+
107
+ // 5. 获取市场信息
108
+ this.registerTool('gate_get_market_info', {
109
+ description: '获取 Gate.io 市场信息',
110
+ inputSchema: z.object({
111
+ currency_pair: z.string().describe('交易对,如 BTC_USDT'),
112
+ info_type: z.enum(['book', 'trades', 'tickers']).optional().describe('信息类型'),
113
+ }),
114
+ execute: async (args) => {
115
+ try {
116
+ this._checkAuth();
117
+ const spotApi = this._createSpotApi();
118
+ const { currency_pair, info_type } = args;
119
+ if (info_type === 'book' || !info_type) {
120
+ const book = await spotApi.listOrderBook(currency_pair, { limit: 10 });
121
+ return { success: true, type: 'order_book', currency_pair, bids: book.body.bids, asks: book.body.asks };
122
+ } else if (info_type === 'tickers') {
123
+ const tickers = await spotApi.listTickers(currency_pair);
124
+ const t = tickers.body.find(x => x.currencyPair === currency_pair) || tickers.body[0];
125
+ return {
126
+ success: true, type: 'ticker', currency_pair: t.currencyPair,
127
+ last: t.last, high_24h: t.high24h, low_24h: t.low24h,
128
+ volume_24h: t.baseVolume, quote_volume_24h: t.quoteVolume, change_percentage_24h: t.changePercentage,
129
+ };
130
+ } else if (info_type === 'trades') {
131
+ const trades = await spotApi.listTrades(currency_pair);
132
+ return { success: true, type: 'trades', currency_pair, trades: trades.body.slice(0, 20) };
133
+ }
134
+ return { success: false, error: '未知的信息类型' };
135
+ } catch (error) { return { success: false, error: error.message }; }
136
+ },
137
+ });
138
+
139
+ // 6. 获取账户余额
140
+ this.registerTool('gate_get_account_balance', {
141
+ description: '获取 Gate.io 账户余额信息',
142
+ inputSchema: z.object({ currency: z.string().optional() }),
143
+ execute: async (args) => {
144
+ try {
145
+ this._checkAuth();
146
+ const spotApi = this._createSpotApi();
147
+ const account = await spotApi.listSpotAccounts();
148
+ let balances = account.body;
149
+ if (args.currency) {
150
+ balances = balances.filter(a => a.currency.toLowerCase() === args.currency.toLowerCase());
151
+ }
152
+ const nonZero = balances.filter(b => parseFloat(b.available) > 0 || parseFloat(b.locked) > 0);
153
+ return {
154
+ success: true,
155
+ balances: nonZero.map(b => ({
156
+ currency: b.currency, available: b.available, locked: b.locked,
157
+ total: parseFloat(b.available) + parseFloat(b.locked),
158
+ })),
159
+ };
160
+ } catch (error) { return { success: false, error: error.message }; }
161
+ },
162
+ });
163
+
164
+ // 7. 创建订单
165
+ this.registerTool('gate_create_order', {
166
+ description: '在 Gate.io 创建交易订单',
167
+ inputSchema: z.object({
168
+ currency_pair: z.string(), side: z.enum(['buy', 'sell']),
169
+ order_type: z.enum(['limit', 'market']), amount: z.string(), price: z.string(), text: z.string().optional(),
170
+ }),
171
+ execute: async (args) => {
172
+ try {
173
+ this._checkAuth();
174
+ const spotApi = this._createSpotApi();
175
+ const order = {
176
+ text: args.text || `order_${Date.now()}`, currency_pair: args.currency_pair,
177
+ type: args.order_type, side: args.side, amount: args.amount,
178
+ };
179
+ if (args.order_type === 'limit' && args.price) order.price = args.price;
180
+ const result = await spotApi.createOrder(order);
181
+ const r = result.body;
182
+ return {
183
+ success: true, order_id: r.id, currency_pair: r.currency_pair,
184
+ type: r.type, side: r.side, amount: r.amount,
185
+ price: r.price, status: r.status, create_time: r.create_time,
186
+ };
187
+ } catch (error) { return { success: false, error: error.message }; }
188
+ },
189
+ });
190
+
191
+ // 8. 取消订单
192
+ this.registerTool('gate_cancel_order', {
193
+ description: '取消 Gate.io 上的指定订单',
194
+ inputSchema: z.object({ currency_pair: z.string(), order_id: z.string() }),
195
+ execute: async (args) => {
196
+ try {
197
+ this._checkAuth();
198
+ const spotApi = this._createSpotApi();
199
+ const result = await spotApi.cancelOrder(args.order_id, args.currency_pair);
200
+ return { success: true, order_id: result.body.id, status: result.body.status, message: '订单已取消' };
201
+ } catch (error) { return { success: false, error: error.message }; }
202
+ },
203
+ });
204
+
205
+ // 9. 获取订单信息
206
+ this.registerTool('gate_get_order_info', {
207
+ description: '获取 Gate.io 指定订单的详细信息',
208
+ inputSchema: z.object({ currency_pair: z.string(), order_id: z.string() }),
209
+ execute: async (args) => {
210
+ try {
211
+ this._checkAuth();
212
+ const spotApi = this._createSpotApi();
213
+ const order = await spotApi.getOrder(args.order_id, args.currency_pair);
214
+ const o = order.body;
215
+ return {
216
+ success: true, order_id: o.id, currency_pair: o.currency_pair,
217
+ type: o.type, side: o.side, amount: o.amount, price: o.price,
218
+ filled_amount: o.filled_amount, status: o.status,
219
+ create_time: o.create_time, update_time: o.update_time,
220
+ };
221
+ } catch (error) { return { success: false, error: error.message }; }
222
+ },
223
+ });
224
+
225
+ // 10. 获取未完成订单
226
+ this.registerTool('gate_get_open_orders', {
227
+ description: '获取 Gate.io 当前所有未完成的订单',
228
+ inputSchema: z.object({ currency_pair: z.string().optional(), limit: z.number().optional() }),
229
+ execute: async (args) => {
230
+ try {
231
+ this._checkAuth();
232
+ const spotApi = this._createSpotApi();
233
+ const result = await spotApi.listAllOpenOrders({ currency_pair: args.currency_pair, limit: args.limit || 100 });
234
+ const orders = (Array.isArray(result.body) ? result.body : []).map(order => ({
235
+ order_id: order.id, currency_pair: order.currency_pair, type: order.type,
236
+ side: order.side, amount: order.amount, price: order.price,
237
+ filled_amount: order.filled_amount, status: order.status, create_time: order.create_time,
238
+ }));
239
+ return { success: true, count: orders.length, orders };
240
+ } catch (error) { return { success: false, error: error.message }; }
241
+ },
242
+ });
243
+
244
+ // 11. 获取 K 线数据
245
+ this.registerTool('gate_get_ohlcv_data', {
246
+ description: '获取 Gate.io K线/烛线数据',
247
+ inputSchema: z.object({
248
+ currency_pair: z.string(), timeframe: z.enum(['10s', '1m', '5m', '15m', '30m', '1h', '4h', '8h', '1d', '7d', '30d']), limit: z.number().optional(),
249
+ }),
250
+ execute: async (args) => {
251
+ try {
252
+ this._checkAuth();
253
+ const spotApi = this._createSpotApi();
254
+ const klines = await spotApi.listCandlesticks(args.currency_pair, { interval: args.timeframe, limit: args.limit || 100 });
255
+ return {
256
+ success: true, currency_pair: args.currency_pair, timeframe: args.timeframe,
257
+ count: klines.body.length,
258
+ klines: klines.body.reverse().map(k => ({
259
+ timestamp: k[0], volume: k[1], open: k[2], high: k[3], low: k[4], close: k[5],
260
+ })),
261
+ };
262
+ } catch (error) { return { success: false, error: error.message }; }
263
+ },
264
+ });
265
+
266
+ // 12. 获取交易对列表
267
+ this.registerTool('gate_get_trading_pairs', {
268
+ description: '获取 Gate.io 支持的所有现货交易对',
269
+ inputSchema: z.object({ quote: z.string().optional() }),
270
+ execute: async (args) => {
271
+ try {
272
+ this._checkAuth();
273
+ const spotApi = this._createSpotApi();
274
+ const allPairs = await spotApi.listCurrencyPairs();
275
+ let pairs = allPairs.body;
276
+ if (args.quote) pairs = pairs.filter(p => p.quote.toLowerCase() === args.quote.toLowerCase());
277
+ return {
278
+ success: true, count: pairs.length,
279
+ pairs: pairs.map(p => ({ id: p.id, base: p.base, quote: p.quote })),
280
+ };
281
+ } catch (error) { return { success: false, error: error.message }; }
282
+ },
283
+ });
284
+
285
+ // 13. 批量取消订单
286
+ this.registerTool('gate_cancel_all_orders', {
287
+ description: '批量取消 Gate.io 上的订单',
288
+ inputSchema: z.object({ currency_pair: z.string().optional() }),
289
+ execute: async (args) => {
290
+ try {
291
+ this._checkAuth();
292
+ const spotApi = this._createSpotApi();
293
+ const result = await spotApi.cancelOrders([], args.currency_pair);
294
+ return { success: true, cancelled_count: result.body.length, message: `已取消 ${result.body.length} 个订单` };
295
+ } catch (error) { return { success: false, error: error.message }; }
296
+ },
297
+ });
298
+
299
+ // 14. 获取充值地址
300
+ this.registerTool('gate_get_deposit_address', {
301
+ description: '获取 Gate.io 充值地址',
302
+ inputSchema: z.object({ currency: z.string(), network: z.string().optional() }),
303
+ execute: async (args) => {
304
+ try {
305
+ this._checkAuth();
306
+ const walletApi = this._createWalletApi();
307
+ const result = await walletApi.generateDepositAddress(args.currency, args.network);
308
+ return {
309
+ success: true, currency: args.currency,
310
+ address: result.body.deposit_addresses?.[0]?.address || result.body.address,
311
+ memo: result.body.deposit_addresses?.[0]?.address_hint,
312
+ };
313
+ } catch (error) { return { success: false, error: error.message }; }
314
+ },
315
+ });
316
+
317
+ // 15. 获取提现记录
318
+ this.registerTool('gate_get_withdrawals', {
319
+ description: '获取 Gate.io 提现记录',
320
+ inputSchema: z.object({ currency: z.string().optional(), limit: z.number().optional() }),
321
+ execute: async (args) => {
322
+ try {
323
+ this._checkAuth();
324
+ const walletApi = this._createWalletApi();
325
+ const result = await walletApi.withdrawals(args.currency, { limit: args.limit || 100 });
326
+ return {
327
+ success: true, count: result.body.length,
328
+ withdrawals: result.body.map(w => ({ id: w.id, currency: w.currency, amount: w.amount, address: w.address, status: w.status, create_time: w.create_time })),
329
+ };
330
+ } catch (error) { return { success: false, error: error.message }; }
331
+ },
332
+ });
333
+
334
+ // 16. 获取充值记录
335
+ this.registerTool('gate_get_deposits', {
336
+ description: '获取 Gate.io 充值记录',
337
+ inputSchema: z.object({ currency: z.string().optional(), limit: z.number().optional() }),
338
+ execute: async (args) => {
339
+ try {
340
+ this._checkAuth();
341
+ const walletApi = this._createWalletApi();
342
+ const result = await walletApi.deposits(args.currency, { limit: args.limit || 100 });
343
+ return {
344
+ success: true, count: result.body.length,
345
+ deposits: result.body.map(d => ({ id: d.id, currency: d.currency, amount: d.amount, address: d.address, status: d.status, create_time: d.create_time })),
346
+ };
347
+ } catch (error) { return { success: false, error: error.message }; }
348
+ },
349
+ });
350
+
351
+ // ========== 合约交易功能 (Futures API) ==========
352
+
353
+ // 17. 获取合约账户余额
354
+ this.registerTool('gate_get_perpetual_balance', {
355
+ description: '获取 Gate.io 合约账户余额',
356
+ inputSchema: z.object({ settle: z.string().optional().describe('结算货币,如 USDT') }),
357
+ execute: async (args) => {
358
+ try {
359
+ this._checkAuth();
360
+ const futuresApi = this._createFuturesApi();
361
+ const settle = (args.settle || 'USDT').toLowerCase();
362
+ const result = await futuresApi.listFuturesAccounts(settle);
363
+ const a = Array.isArray(result.body) ? result.body[0] : result.body;
364
+ return {
365
+ success: true,
366
+ settle,
367
+ order_book: a.order_book || 0,
368
+ available: a.available || 0,
369
+ order_margin: a.order_margin || 0,
370
+ position_margin: a.position_margin || 0,
371
+ equity: a.equity || 0,
372
+ total_size: a.total_size || 0,
373
+ };
374
+ } catch (error) { return { success: false, error: error.message }; }
375
+ },
376
+ });
377
+
378
+ // 18. 获取合约持仓
379
+ this.registerTool('gate_get_perpetual_positions', {
380
+ description: '获取 Gate.io 合约持仓信息',
381
+ inputSchema: z.object({
382
+ settle: z.string().optional().describe('结算货币,如 USDT'),
383
+ contract: z.string().optional().describe('合约名称,如 BTC_USD'),
384
+ }),
385
+ execute: async (args) => {
386
+ try {
387
+ this._checkAuth();
388
+ const futuresApi = this._createFuturesApi();
389
+ const settle = (args.settle || 'USDT').toLowerCase();
390
+ const result = await futuresApi.listPositions(settle);
391
+ let positions = Array.isArray(result.body) ? result.body : [];
392
+ if (args.contract) {
393
+ positions = positions.filter(p => p.contract === args.contract);
394
+ }
395
+ return {
396
+ success: true,
397
+ settle,
398
+ count: positions.length,
399
+ positions: positions.map(p => ({
400
+ contract: p.contract, size: p.size, entry_price: p.entry_price,
401
+ margin: p.margin, leverage: p.leverage, unrealised_pnl: p.unrealised_pnl,
402
+ realised_pnl: p.realised_pnl, mode: p.mode,
403
+ })),
404
+ };
405
+ } catch (error) { return { success: false, error: error.message }; }
406
+ },
407
+ });
408
+
409
+ // 19. 创建合约订单
410
+ this.registerTool('gate_create_perpetual_order', {
411
+ description: '在 Gate.io 创建合约订单',
412
+ inputSchema: z.object({
413
+ settle: z.string().describe('结算货币,如 USDT'),
414
+ contract: z.string().describe('合约名称,如 BTC_USD'),
415
+ side: z.enum(['buy', 'sell']).describe('买入或卖出'),
416
+ size: z.string().describe('数量(正数为开多,负数为开空)'),
417
+ price: z.string().optional().describe('价格(市价单可不填)'),
418
+ order_type: z.enum(['limit', 'market', 'post_only']).optional().describe('订单类型'),
419
+ reduce_only: z.boolean().optional().describe('是否只减仓'),
420
+ }),
421
+ execute: async (args) => {
422
+ try {
423
+ this._checkAuth();
424
+ const futuresApi = this._createFuturesApi();
425
+ const settle = args.settle.toLowerCase();
426
+
427
+ // 构造订单对象 - settle 不能在订单内部
428
+ const order = {
429
+ contract: args.contract,
430
+ size: args.size,
431
+ side: args.side,
432
+ type: args.order_type || 'market',
433
+ };
434
+ if (args.price) order.price = args.price;
435
+ if (args.reduce_only !== undefined) order.reduce_only = args.reduce_only;
436
+
437
+ // SDK签名: createFuturesOrder(settle, futuresOrder, opts)
438
+ const result = await futuresApi.createFuturesOrder(settle, order);
439
+ const r = result.body;
440
+ return {
441
+ success: true,
442
+ id: String(r.id),
443
+ contract: r.contract,
444
+ side: r.side,
445
+ size: r.size,
446
+ price: r.price,
447
+ order_type: r.type,
448
+ status: r.status,
449
+ fill_price: r.fill_price,
450
+ create_time: r.create_time,
451
+ };
452
+ } catch (error) {
453
+ return { success: false, error: error.message }; }
454
+ },
455
+ });
456
+
457
+ // 20. 取消合约订单
458
+ this.registerTool('gate_cancel_perpetual_order', {
459
+ description: '取消 Gate.io 合约订单',
460
+ inputSchema: z.object({
461
+ settle: z.string().describe('结算货币,如 USDT'),
462
+ contract: z.string().describe('合约名称'),
463
+ order_id: z.string().describe('订单ID'),
464
+ }),
465
+ execute: async (args) => {
466
+ try {
467
+ this._checkAuth();
468
+ const futuresApi = this._createFuturesApi();
469
+ const result = await futuresApi.cancelFuturesOrder(args.order_id, args.contract, args.settle);
470
+ return {
471
+ success: true,
472
+ id: String(result.body.id),
473
+ contract: result.body.contract,
474
+ status: result.body.status,
475
+ message: '合约订单已取消',
476
+ };
477
+ } catch (error) { return { success: false, error: error.message }; }
478
+ },
479
+ });
480
+
481
+ // 21. 获取合约订单信息
482
+ this.registerTool('gate_get_perpetual_order_info', {
483
+ description: '获取 Gate.io 合约订单详细信息',
484
+ inputSchema: z.object({
485
+ settle: z.string().describe('结算货币,如 USDT'),
486
+ contract: z.string().describe('合约名称'),
487
+ order_id: z.string().describe('订单ID'),
488
+ }),
489
+ execute: async (args) => {
490
+ try {
491
+ this._checkAuth();
492
+ const futuresApi = this._createFuturesApi();
493
+ const result = await futuresApi.getFuturesOrder(args.order_id, args.contract, args.settle);
494
+ const o = result.body;
495
+ return {
496
+ success: true,
497
+ id: String(o.id),
498
+ contract: o.contract,
499
+ side: o.side,
500
+ size: o.size,
501
+ price: o.price,
502
+ order_type: o.order_type,
503
+ filled_amount: o.filled_amount,
504
+ filled_size: o.filled_size,
505
+ status: o.status,
506
+ create_time: o.create_time,
507
+ update_time: o.update_time,
508
+ };
509
+ } catch (error) { return { success: false, error: error.message }; }
510
+ },
511
+ });
512
+
513
+ // 22. 获取合约未完成订单
514
+ this.registerTool('gate_get_perpetual_open_orders', {
515
+ description: '获取 Gate.io 合约未完成订单',
516
+ inputSchema: z.object({
517
+ settle: z.string().optional().describe('结算货币,如 USDT'),
518
+ contract: z.string().optional().describe('合约名称'),
519
+ }),
520
+ execute: async (args) => {
521
+ try {
522
+ this._checkAuth();
523
+ const futuresApi = this._createFuturesApi();
524
+ const settle = (args.settle || 'USDT').toLowerCase();
525
+
526
+ // SDK签名: listFuturesOrders(settle, status, opts)
527
+ // status: open = 未完成, finished = 已完成
528
+ const status = 'open';
529
+ const opts = {};
530
+ if (args.contract) opts.contract = args.contract;
531
+
532
+ const result = await futuresApi.listFuturesOrders(settle, status, opts);
533
+ const orders = (Array.isArray(result.body) ? result.body : []);
534
+ return {
535
+ success: true,
536
+ settle,
537
+ count: orders.length,
538
+ orders: orders.map(o => ({
539
+ id: String(o.id),
540
+ contract: o.contract,
541
+ side: o.side,
542
+ size: o.size,
543
+ price: o.price,
544
+ order_type: o.type,
545
+ filled_size: o.filled_size,
546
+ status: o.status,
547
+ create_time: o.create_time,
548
+ })),
549
+ };
550
+ } catch (error) { return { success: false, error: error.message }; }
551
+ },
552
+ });
553
+
554
+ // 23. 获取合约市场数据
555
+ this.registerTool('gate_get_perpetual_market', {
556
+ description: '获取 Gate.io 合约市场信息',
557
+ inputSchema: z.object({
558
+ settle: z.string().optional().describe('结算货币,如 USDT'),
559
+ contract: z.string().optional().describe('合约名称'),
560
+ info_type: z.enum(['book', 'trades', 'tickers']).optional().describe('信息类型'),
561
+ }),
562
+ execute: async (args) => {
563
+ try {
564
+ this._checkAuth();
565
+ const futuresApi = this._createFuturesApi();
566
+ const settle = (args.settle || 'USDT').toLowerCase();
567
+ const { info_type, contract } = args;
568
+
569
+ if (info_type === 'book' || !info_type) {
570
+ // SDK签名: listFuturesOrderBook(settle, contract, opts)
571
+ const book = await futuresApi.listFuturesOrderBook(settle, contract || 'BTC_USDT');
572
+ return {
573
+ success: true,
574
+ type: 'order_book',
575
+ contract: contract || 'BTC_USDT',
576
+ settle,
577
+ bids: book.body.bids?.slice(0, 10) || [],
578
+ asks: book.body.asks?.slice(0, 10) || [],
579
+ };
580
+ } else if (info_type === 'tickers') {
581
+ const tickers = await futuresApi.listFuturesTickers(settle);
582
+ let t = Array.isArray(tickers.body) ? tickers.body : [];
583
+ if (contract) t = t.filter(x => x.contract === contract);
584
+ return {
585
+ success: true,
586
+ type: 'tickers',
587
+ settle,
588
+ tickers: t.slice(0, 20).map(x => ({
589
+ contract: x.contract,
590
+ last: x.last,
591
+ mark_price: x.mark_price,
592
+ index_price: x.index_price,
593
+ funding_rate: x.funding_rate,
594
+ volume_24h: x.volume_24h,
595
+ change_24h: x.change_24h,
596
+ })),
597
+ };
598
+ } else if (info_type === 'trades') {
599
+ // SDK签名: listFuturesTrades(contract, settle, opts)
600
+ const trades = await futuresApi.listFuturesTrades(contract || 'BTC_USDT', settle);
601
+ return {
602
+ success: true,
603
+ type: 'trades',
604
+ contract: contract || 'BTC_USDT',
605
+ settle,
606
+ trades: (trades.body || []).slice(0, 20),
607
+ };
608
+ }
609
+ return { success: false, error: '未知的信息类型' };
610
+ } catch (error) { return { success: false, error: error.message }; }
611
+ },
612
+ });
613
+
614
+ // 24. 获取合约K线数据
615
+ this.registerTool('gate_get_perpetual_ohlcv', {
616
+ description: '获取 Gate.io 合约K线数据',
617
+ inputSchema: z.object({
618
+ settle: z.string().optional().describe('结算货币,如 USDT'),
619
+ contract: z.string().describe('合约名称,如 BTC_USD'),
620
+ timeframe: z.enum(['10s', '1m', '5m', '15m', '30m', '1h', '4h', '8h', '1d', '7d', '30d']).optional().describe('时间周期'),
621
+ limit: z.number().optional().describe('返回条数'),
622
+ }),
623
+ execute: async (args) => {
624
+ try {
625
+ this._checkAuth();
626
+ const futuresApi = this._createFuturesApi();
627
+ const settle = (args.settle || 'USDT').toLowerCase();
628
+ // SDK签名: listFuturesCandlesticks(settle, contract, opts)
629
+ const klines = await futuresApi.listFuturesCandlesticks(
630
+ settle,
631
+ args.contract,
632
+ { interval: args.timeframe || '1h', limit: args.limit || 100 }
633
+ );
634
+ return {
635
+ success: true,
636
+ contract: args.contract,
637
+ settle,
638
+ timeframe: args.timeframe || '1h',
639
+ count: (klines.body || []).length,
640
+ klines: (klines.body || []).reverse().map(k => ({
641
+ timestamp: k.t,
642
+ volume: k.v,
643
+ open: k.o,
644
+ high: k.h,
645
+ low: k.l,
646
+ close: k.c,
647
+ })),
648
+ };
649
+ } catch (error) { return { success: false, error: error.message }; }
650
+ },
651
+ });
652
+
653
+ // 25. 获取合约列表
654
+ this.registerTool('gate_get_perpetual_contracts', {
655
+ description: '获取 Gate.io 支持的合约列表',
656
+ inputSchema: z.object({ settle: z.string().optional().describe('结算货币,如 USDT') }),
657
+ execute: async (args) => {
658
+ try {
659
+ this._checkAuth();
660
+ const futuresApi = this._createFuturesApi();
661
+ const settle = (args.settle || 'USDT').toLowerCase();
662
+ const result = await futuresApi.listFuturesContracts(settle);
663
+ return {
664
+ success: true,
665
+ settle,
666
+ count: (result.body || []).length,
667
+ contracts: (result.body || []).slice(0, 50).map(c => ({
668
+ name: c.name,
669
+ base: c.base_currency,
670
+ quote: c.quote_currency,
671
+ quanto_multiplier: c.quanto_multiplier,
672
+ is_inverse: c.is_inverse,
673
+ order_price_round: c.order_price_round,
674
+ funding_rate: c.funding_rate,
675
+ leverage_min: c.leverage_min,
676
+ leverage_max: c.leverage_max,
677
+ })),
678
+ };
679
+ } catch (error) { return { success: false, error: error.message }; }
680
+ },
681
+ });
682
+
683
+ // 26. 取消所有合约订单
684
+ this.registerTool('gate_cancel_all_perpetual_orders', {
685
+ description: '取消 Gate.io 合约所有未完成订单',
686
+ inputSchema: z.object({
687
+ settle: z.string().describe('结算货币,如 USDT'),
688
+ contract: z.string().optional().describe('合约名称(可选)'),
689
+ }),
690
+ execute: async (args) => {
691
+ try {
692
+ this._checkAuth();
693
+ const futuresApi = this._createFuturesApi();
694
+ const result = await futuresApi.cancelFuturesOrders(args.contract, args.settle);
695
+ return {
696
+ success: true,
697
+ cancelled_count: (result.body || []).length,
698
+ message: `已取消 ${(result.body || []).length} 个合约订单`,
699
+ };
700
+ } catch (error) { return { success: false, error: error.message }; }
701
+ },
702
+ });
703
+
704
+ // 27. 设置合约杠杆
705
+ this.registerTool('gate_set_perpetual_leverage', {
706
+ description: '设置 Gate.io 合约杠杆倍数',
707
+ inputSchema: z.object({
708
+ settle: z.string().describe('结算货币,如 USDT'),
709
+ contract: z.string().describe('合约名称'),
710
+ leverage: z.number().describe('杠杆倍数'),
711
+ mode: z.enum(['cross', 'isolated']).optional().describe('仓位模式'),
712
+ }),
713
+ execute: async (args) => {
714
+ try {
715
+ this._checkAuth();
716
+ const futuresApi = this._createFuturesApi();
717
+ // 先获取当前模式
718
+ try {
719
+ const modeResult = await futuresApi.updatePositionCrossMode(args.contract, args.settle, {
720
+ cross_leverage_limit: args.leverage,
721
+ });
722
+ return {
723
+ success: true,
724
+ contract: args.contract,
725
+ leverage: args.leverage,
726
+ mode: modeResult.body,
727
+ message: '杠杆设置成功',
728
+ };
729
+ } catch (e) {
730
+ // 如果 cross mode 失败,尝试 dual mode
731
+ const result = await futuresApi.setPositionMode(args.settle, {
732
+ mode: args.mode || 'both',
733
+ });
734
+ return {
735
+ success: true,
736
+ contract: args.contract,
737
+ leverage: args.leverage,
738
+ message: '杠杆设置成功',
739
+ };
740
+ }
741
+ } catch (error) { return { success: false, error: error.message }; }
742
+ },
743
+ });
744
+
745
+ }
746
+ };
747
+ module.exports ={ GateTradingPlugin };