@yuants/vendor-turboflow 1.2.0 → 1.2.1

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 (48) hide show
  1. package/.rush/temp/chunked-rush-logs/vendor-turboflow.build.chunks.jsonl +6 -6
  2. package/.rush/temp/operation/build/all.log +6 -6
  3. package/.rush/temp/operation/build/log-chunks.jsonl +6 -6
  4. package/.rush/temp/operation/build/state.json +1 -1
  5. package/.rush/temp/shrinkwrap-deps.json +1 -1
  6. package/CHANGELOG.json +17 -0
  7. package/CHANGELOG.md +8 -1
  8. package/lib/api/private-api.d.ts +1 -1
  9. package/lib/api/private-api.d.ts.map +1 -1
  10. package/lib/api/private-api.js +3 -2
  11. package/lib/api/private-api.js.map +1 -1
  12. package/lib/api/public-api.d.ts +31 -0
  13. package/lib/api/public-api.d.ts.map +1 -0
  14. package/lib/api/public-api.js +29 -0
  15. package/lib/api/public-api.js.map +1 -0
  16. package/lib/index.d.ts +1 -2
  17. package/lib/index.d.ts.map +1 -1
  18. package/lib/index.js +1 -3
  19. package/lib/index.js.map +1 -1
  20. package/lib/services/exchange.d.ts +2 -0
  21. package/lib/services/exchange.d.ts.map +1 -0
  22. package/lib/services/exchange.js +96 -0
  23. package/lib/services/exchange.js.map +1 -0
  24. package/lib/services/orders/cancelOrder.d.ts.map +1 -1
  25. package/lib/services/orders/cancelOrder.js +21 -28
  26. package/lib/services/orders/cancelOrder.js.map +1 -1
  27. package/lib/services/orders/listOrders.d.ts +2 -2
  28. package/lib/services/orders/listOrders.d.ts.map +1 -1
  29. package/lib/services/orders/listOrders.js +9 -23
  30. package/lib/services/orders/listOrders.js.map +1 -1
  31. package/lib/services/orders/submitOrder.d.ts.map +1 -1
  32. package/lib/services/orders/submitOrder.js +7 -5
  33. package/lib/services/orders/submitOrder.js.map +1 -1
  34. package/package.json +3 -1
  35. package/rush-logs/vendor-turboflow.build.log +6 -6
  36. package/src/api/private-api.ts +4 -3
  37. package/src/api/public-api.ts +65 -0
  38. package/src/index.ts +1 -3
  39. package/src/services/exchange.ts +107 -0
  40. package/src/services/orders/cancelOrder.ts +22 -29
  41. package/src/services/orders/listOrders.ts +11 -28
  42. package/src/services/orders/submitOrder.ts +6 -5
  43. package/temp/package-deps.json +13 -10
  44. package/lib/services/account-actions-with-credential.d.ts +0 -2
  45. package/lib/services/account-actions-with-credential.d.ts.map +0 -1
  46. package/lib/services/account-actions-with-credential.js +0 -60
  47. package/lib/services/account-actions-with-credential.js.map +0 -1
  48. package/src/services/account-actions-with-credential.ts +0 -76
@@ -1 +1 @@
1
- {"version":3,"file":"cancelOrder.js","sourceRoot":"","sources":["../../../src/services/orders/cancelOrder.ts"],"names":[],"mappings":";;;AACA,yCAA2C;AAC3C,uDAAmF;AAE5E,MAAM,iBAAiB,GAAG,KAAK,EAAE,UAAuB,EAAE,KAAa,EAAiB,EAAE;IAC/F,OAAO,CAAC,IAAI,CAAC,IAAI,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,sBAAsB,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IAE/E,IAAI;QACF,kCAAkC;QAClC,MAAM,YAAY,GAAG,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACjD,MAAM,OAAO,GAAG,YAAY,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAEtD,4BAA4B;QAC5B,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,IAAI,KAAK,CAAC,OAAO,EAAE;YACjB,IAAI;gBACF,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACzC,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC;aAC/B;YAAC,OAAO,CAAC,EAAE;gBACV,OAAO,CAAC,IAAI,CAAC,IAAI,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,kCAAkC,EAAE,CAAC,CAAC,CAAC;aAC/E;SACF;QAED,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;YACnB,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;SAC9D;QAED,MAAM,QAAQ,GAAG,MAAM,IAAA,yBAAc,EAAC,UAAU,EAAE;YAChD,OAAO;YACP,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,OAAO;SACR,CAAC,CAAC;QAEH,IAAI,QAAQ,CAAC,KAAK,KAAK,GAAG,EAAE;YAC1B,MAAM,IAAI,KAAK,CAAC,2BAA2B,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC;SAC5D;QAED,OAAO,CAAC,IAAI,CAAC,IAAI,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,WAAW,KAAK,CAAC,QAAQ,yBAAyB,CAAC,CAAC;KAC5F;IAAC,OAAO,KAAK,EAAE;QACd,OAAO,CAAC,KAAK,CAAC,IAAI,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;QAC5E,MAAM,KAAK,CAAC;KACb;AACH,CAAC,CAAC;AAtCW,QAAA,iBAAiB,qBAsC5B","sourcesContent":["import { IOrder } from '@yuants/data-order';\nimport { formatTime } from '@yuants/utils';\nimport { ICredential, cancelOrder as cancelOrderApi } from '../../api/private-api';\n\nexport const cancelOrderAction = async (credential: ICredential, order: IOrder): Promise<void> => {\n console.info(`[${formatTime(Date.now())}] Cancelling order ${order.order_id}`);\n\n try {\n // Parse product_id to get pair_id\n const productParts = order.product_id.split('/');\n const pair_id = productParts[productParts.length - 1];\n\n // Parse comment for pool_id\n let pool_id = 1;\n if (order.comment) {\n try {\n const params = JSON.parse(order.comment);\n pool_id = params.pool_id || 1;\n } catch (e) {\n console.warn(`[${formatTime(Date.now())}] Failed to parse order comment:`, e);\n }\n }\n\n if (!order.order_id) {\n throw new Error('order_id is required for cancelling order');\n }\n\n const response = await cancelOrderApi(credential, {\n pair_id,\n order_id: order.order_id,\n pool_id,\n });\n\n if (response.errno !== '0') {\n throw new Error(`Failed to cancel order: ${response.msg}`);\n }\n\n console.info(`[${formatTime(Date.now())}] Order ${order.order_id} cancelled successfully`);\n } catch (error) {\n console.error(`[${formatTime(Date.now())}] Error cancelling order:`, error);\n throw error;\n }\n};\n"]}
1
+ {"version":3,"file":"cancelOrder.js","sourceRoot":"","sources":["../../../src/services/orders/cancelOrder.ts"],"names":[],"mappings":";;;AACA,yCAA2C;AAC3C,uDAAmF;AAE5E,MAAM,iBAAiB,GAAG,KAAK,EAAE,UAAuB,EAAE,KAAa,EAAiB,EAAE;IAC/F,OAAO,CAAC,IAAI,CAAC,IAAI,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,sBAAsB,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IAE/E,kCAAkC;IAClC,MAAM,YAAY,GAAG,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,YAAY,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEtD,4BAA4B;IAC5B,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,KAAK,CAAC,OAAO,EAAE;QACjB,IAAI;YACF,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACzC,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC;SAC/B;QAAC,OAAO,CAAC,EAAE;YACV,OAAO,CAAC,IAAI,CAAC,IAAI,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,kCAAkC,EAAE,CAAC,CAAC,CAAC;SAC/E;KACF;IAED,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;QACnB,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;KAC9D;IAED,MAAM,QAAQ,GAAG,MAAM,IAAA,yBAAc,EAAC,UAAU,EAAE;QAChD,OAAO;QACP,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,OAAO;KACR,CAAC,CAAC;IAEH,IAAI,QAAQ,CAAC,KAAK,KAAK,KAAK,EAAE;QAC5B,MAAM,IAAI,KAAK,CAAC,2BAA2B,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC;KAC5D;AACH,CAAC,CAAC;AA/BW,QAAA,iBAAiB,qBA+B5B","sourcesContent":["import { IOrder } from '@yuants/data-order';\nimport { formatTime } from '@yuants/utils';\nimport { ICredential, cancelOrder as cancelOrderApi } from '../../api/private-api';\n\nexport const cancelOrderAction = async (credential: ICredential, order: IOrder): Promise<void> => {\n console.info(`[${formatTime(Date.now())}] Cancelling order ${order.order_id}`);\n\n // Parse product_id to get pair_id\n const productParts = order.product_id.split('/');\n const pair_id = productParts[productParts.length - 1];\n\n // Parse comment for pool_id\n let pool_id = 1;\n if (order.comment) {\n try {\n const params = JSON.parse(order.comment);\n pool_id = params.pool_id || 1;\n } catch (e) {\n console.warn(`[${formatTime(Date.now())}] Failed to parse order comment:`, e);\n }\n }\n\n if (!order.order_id) {\n throw new Error('order_id is required for cancelling order');\n }\n\n const response = await cancelOrderApi(credential, {\n pair_id,\n order_id: order.order_id,\n pool_id,\n });\n\n if (response.errno !== '200') {\n throw new Error(`Failed to cancel order: ${response.msg}`);\n }\n};\n"]}
@@ -1,7 +1,7 @@
1
- import { IActionHandlerOfListOrders } from '@yuants/data-order';
1
+ import { IOrder } from '@yuants/data-order';
2
2
  import { ICredential } from '../../api/private-api';
3
3
  /**
4
4
  * List orders implementation
5
5
  */
6
- export declare const listOrders: IActionHandlerOfListOrders<ICredential>;
6
+ export declare const listOrders: (credential: ICredential) => Promise<IOrder[]>;
7
7
  //# sourceMappingURL=listOrders.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"listOrders.d.ts","sourceRoot":"","sources":["../../../src/services/orders/listOrders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAU,MAAM,oBAAoB,CAAC;AAExE,OAAO,EAAE,WAAW,EAAgB,MAAM,uBAAuB,CAAC;AAqDlE;;GAEG;AACH,eAAO,MAAM,UAAU,EAAE,0BAA0B,CAAC,WAAW,CAyB9D,CAAC"}
1
+ {"version":3,"file":"listOrders.d.ts","sourceRoot":"","sources":["../../../src/services/orders/listOrders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAAE,WAAW,EAAgB,MAAM,uBAAuB,CAAC;AAqDlE;;GAEG;AACH,eAAO,MAAM,UAAU,eAAsB,WAAW,KAAG,QAAQ,MAAM,EAAE,CAQ1E,CAAC"}
@@ -24,12 +24,12 @@ const mapOrderDirection = (order_way) => {
24
24
  /**
25
25
  * Map TurboFlow order to Yuan IOrder format
26
26
  */
27
- const mapOrder = (order, account_id) => {
27
+ const mapOrder = (order) => {
28
28
  const volume = parseFloat(order.size) || 0;
29
29
  const price = parseFloat(order.price) || 0;
30
30
  return {
31
31
  order_id: order.id,
32
- account_id,
32
+ account_id: '',
33
33
  product_id: (0, utils_1.encodePath)('PERPETUAL', order.pair_id),
34
34
  order_type: order.order_type.toUpperCase(),
35
35
  order_direction: mapOrderDirection(order.order_way),
@@ -52,27 +52,13 @@ const mapOrder = (order, account_id) => {
52
52
  /**
53
53
  * List orders implementation
54
54
  */
55
- const listOrders = async (credential, account_id) => {
56
- console.info(`[${(0, utils_1.formatTime)(Date.now())}] Listing orders for account: ${account_id}`);
57
- try {
58
- // Get pending orders
59
- const response = await (0, private_api_1.getOrderList)(credential, {
60
- page_num: 1,
61
- page_size: 100,
62
- status: 'Pending',
63
- });
64
- if (response.errno !== '0') {
65
- throw new Error(`Failed to list orders: ${response.msg}`);
66
- }
67
- const orders = response.data.data.map((order) => mapOrder(order, account_id));
68
- console.info(`[${(0, utils_1.formatTime)(Date.now())}] Found ${orders.length} orders`);
69
- return orders;
70
- }
71
- catch (error) {
72
- const errorMessage = error instanceof Error ? error.message : 'Unknown error';
73
- console.error(`[${(0, utils_1.formatTime)(Date.now())}] Failed to list orders for ${account_id}: ${errorMessage}`);
74
- throw new Error(`Failed to list orders: ${errorMessage}`);
75
- }
55
+ const listOrders = async (credential) => {
56
+ const response = await (0, private_api_1.getOrderList)(credential, {
57
+ page_num: 1,
58
+ page_size: 100,
59
+ status: 'Pending',
60
+ });
61
+ return response.data.data.map((order) => mapOrder(order));
76
62
  };
77
63
  exports.listOrders = listOrders;
78
64
  //# sourceMappingURL=listOrders.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"listOrders.js","sourceRoot":"","sources":["../../../src/services/orders/listOrders.ts"],"names":[],"mappings":"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","sourcesContent":["import { IActionHandlerOfListOrders, IOrder } from '@yuants/data-order';\nimport { encodePath, formatTime } from '@yuants/utils';\nimport { ICredential, getOrderList } from '../../api/private-api';\n\ntype OrderDirection = 'OPEN_LONG' | 'OPEN_SHORT' | 'CLOSE_LONG' | 'CLOSE_SHORT';\n\n/**\n * Map TurboFlow order_way to order direction\n * 1: 开多 (Open Long), 2: 平空 (Close Short), 3: 开空 (Open Short), 4: 平多 (Close Long)\n */\nconst mapOrderDirection = (order_way: number): OrderDirection => {\n switch (order_way) {\n case 1:\n return 'OPEN_LONG';\n case 2:\n return 'CLOSE_SHORT';\n case 3:\n return 'OPEN_SHORT';\n case 4:\n return 'CLOSE_LONG';\n default:\n return 'OPEN_LONG';\n }\n};\n\n/**\n * Map TurboFlow order to Yuan IOrder format\n */\nconst mapOrder = (order: any, account_id: string): IOrder => {\n const volume = parseFloat(order.size) || 0;\n const price = parseFloat(order.price) || 0;\n\n return {\n order_id: order.id,\n account_id,\n product_id: encodePath('PERPETUAL', order.pair_id),\n order_type: order.order_type.toUpperCase() as any,\n order_direction: mapOrderDirection(order.order_way),\n volume: Number.isFinite(volume) ? volume : 0,\n price: Number.isFinite(price) && price > 0 ? price : undefined,\n submit_at: new Date(order.created_at).getTime(),\n order_status: order.order_status.toLowerCase(),\n comment: JSON.stringify({\n pool_id: order.pool_id,\n pair_id: order.pair_id,\n coin_code: order.coin_code,\n leverage: order.leverage,\n margin_type: order.margin_type,\n fee_mode: order.fee_mode,\n pos_mode: order.pos_mode,\n position_id: order.position_id,\n }),\n };\n};\n\n/**\n * List orders implementation\n */\nexport const listOrders: IActionHandlerOfListOrders<ICredential> = async (credential, account_id) => {\n console.info(`[${formatTime(Date.now())}] Listing orders for account: ${account_id}`);\n\n try {\n // Get pending orders\n const response = await getOrderList(credential, {\n page_num: 1,\n page_size: 100,\n status: 'Pending',\n });\n\n if (response.errno !== '0') {\n throw new Error(`Failed to list orders: ${response.msg}`);\n }\n\n const orders = response.data.data.map((order) => mapOrder(order, account_id));\n\n console.info(`[${formatTime(Date.now())}] Found ${orders.length} orders`);\n\n return orders;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n console.error(`[${formatTime(Date.now())}] Failed to list orders for ${account_id}: ${errorMessage}`);\n throw new Error(`Failed to list orders: ${errorMessage}`);\n }\n};\n"]}
1
+ {"version":3,"file":"listOrders.js","sourceRoot":"","sources":["../../../src/services/orders/listOrders.ts"],"names":[],"mappings":";;;AACA,yCAA2C;AAC3C,uDAAkE;AAIlE;;;GAGG;AACH,MAAM,iBAAiB,GAAG,CAAC,SAAiB,EAAkB,EAAE;IAC9D,QAAQ,SAAS,EAAE;QACjB,KAAK,CAAC;YACJ,OAAO,WAAW,CAAC;QACrB,KAAK,CAAC;YACJ,OAAO,aAAa,CAAC;QACvB,KAAK,CAAC;YACJ,OAAO,YAAY,CAAC;QACtB,KAAK,CAAC;YACJ,OAAO,YAAY,CAAC;QACtB;YACE,OAAO,WAAW,CAAC;KACtB;AACH,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,QAAQ,GAAG,CAAC,KAAU,EAAU,EAAE;IACtC,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAE3C,OAAO;QACL,QAAQ,EAAE,KAAK,CAAC,EAAE;QAClB,UAAU,EAAE,EAAE;QACd,UAAU,EAAE,IAAA,kBAAU,EAAC,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC;QAClD,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,WAAW,EAAS;QACjD,eAAe,EAAE,iBAAiB,CAAC,KAAK,CAAC,SAAS,CAAC;QACnD,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC5C,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;QAC9D,SAAS,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE;QAC/C,YAAY,EAAE,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE;QAC9C,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC;YACtB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,WAAW,EAAE,KAAK,CAAC,WAAW;SAC/B,CAAC;KACH,CAAC;AACJ,CAAC,CAAC;AAEF;;GAEG;AACI,MAAM,UAAU,GAAG,KAAK,EAAE,UAAuB,EAAqB,EAAE;IAC7E,MAAM,QAAQ,GAAG,MAAM,IAAA,0BAAY,EAAC,UAAU,EAAE;QAC9C,QAAQ,EAAE,CAAC;QACX,SAAS,EAAE,GAAG;QACd,MAAM,EAAE,SAAS;KAClB,CAAC,CAAC;IAEH,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AAC5D,CAAC,CAAC;AARW,QAAA,UAAU,cAQrB","sourcesContent":["import { IOrder } from '@yuants/data-order';\nimport { encodePath } from '@yuants/utils';\nimport { ICredential, getOrderList } from '../../api/private-api';\n\ntype OrderDirection = 'OPEN_LONG' | 'OPEN_SHORT' | 'CLOSE_LONG' | 'CLOSE_SHORT';\n\n/**\n * Map TurboFlow order_way to order direction\n * 1: 开多 (Open Long), 2: 平空 (Close Short), 3: 开空 (Open Short), 4: 平多 (Close Long)\n */\nconst mapOrderDirection = (order_way: number): OrderDirection => {\n switch (order_way) {\n case 1:\n return 'OPEN_LONG';\n case 2:\n return 'CLOSE_SHORT';\n case 3:\n return 'OPEN_SHORT';\n case 4:\n return 'CLOSE_LONG';\n default:\n return 'OPEN_LONG';\n }\n};\n\n/**\n * Map TurboFlow order to Yuan IOrder format\n */\nconst mapOrder = (order: any): IOrder => {\n const volume = parseFloat(order.size) || 0;\n const price = parseFloat(order.price) || 0;\n\n return {\n order_id: order.id,\n account_id: '', // Will be filled in listOrders\n product_id: encodePath('PERPETUAL', order.pair_id),\n order_type: order.order_type.toUpperCase() as any,\n order_direction: mapOrderDirection(order.order_way),\n volume: Number.isFinite(volume) ? volume : 0,\n price: Number.isFinite(price) && price > 0 ? price : undefined,\n submit_at: new Date(order.created_at).getTime(),\n order_status: order.order_status.toLowerCase(),\n comment: JSON.stringify({\n pool_id: order.pool_id,\n pair_id: order.pair_id,\n coin_code: order.coin_code,\n leverage: order.leverage,\n margin_type: order.margin_type,\n fee_mode: order.fee_mode,\n pos_mode: order.pos_mode,\n position_id: order.position_id,\n }),\n };\n};\n\n/**\n * List orders implementation\n */\nexport const listOrders = async (credential: ICredential): Promise<IOrder[]> => {\n const response = await getOrderList(credential, {\n page_num: 1,\n page_size: 100,\n status: 'Pending',\n });\n\n return response.data.data.map((order) => mapOrder(order));\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"submitOrder.d.ts","sourceRoot":"","sources":["../../../src/services/orders/submitOrder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAAE,WAAW,EAAiC,MAAM,uBAAuB,CAAC;AAEnF,eAAO,MAAM,WAAW,eAAsB,WAAW,SAAS,MAAM,KAAG,QAAQ;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CA0DtG,CAAC"}
1
+ {"version":3,"file":"submitOrder.d.ts","sourceRoot":"","sources":["../../../src/services/orders/submitOrder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAAE,WAAW,EAAiC,MAAM,uBAAuB,CAAC;AAEnF,eAAO,MAAM,WAAW,eAAsB,WAAW,SAAS,MAAM,KAAG,QAAQ;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CA2DtG,CAAC"}
@@ -1,12 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.submitOrder = void 0;
4
+ const utils_1 = require("@yuants/utils");
4
5
  const private_api_1 = require("../../api/private-api");
5
6
  const submitOrder = async (credential, order) => {
6
- var _a;
7
+ var _a, _b;
7
8
  // Parse product_id to get pair_id
8
- const productParts = order.product_id.split('/');
9
- const pair_id = productParts[productParts.length - 1];
9
+ const [, _SWAP, _NAME, pair_id] = (0, utils_1.decodePath)(order.product_id);
10
10
  // Determine order_way based on order_direction
11
11
  // 1: 开多 (Open Long), 2: 平空 (Close Short), 3: 开空 (Open Short), 4: 平多 (Close Long)
12
12
  let order_way;
@@ -47,14 +47,16 @@ const submitOrder = async (credential, order) => {
47
47
  order_type,
48
48
  order_way,
49
49
  margin_type: 2,
50
- leverage: 100,
51
- size: order.volume.toString(),
50
+ leverage: 1,
51
+ vol: order.volume,
52
52
  position_mode: 1,
53
53
  time_in_force: 'GTC',
54
54
  fee_mode: 1,
55
55
  order_mode: 1,
56
56
  price: (_a = order.price) === null || _a === void 0 ? void 0 : _a.toString(),
57
57
  });
58
+ if (!((_b = response.data) === null || _b === void 0 ? void 0 : _b.order))
59
+ throw (0, utils_1.newError)('TURBOFLOW_SUBMIT_ORDER_FAILED', { response });
58
60
  return { order_id: response.data.order.id };
59
61
  };
60
62
  exports.submitOrder = submitOrder;
@@ -1 +1 @@
1
- {"version":3,"file":"submitOrder.js","sourceRoot":"","sources":["../../../src/services/orders/submitOrder.ts"],"names":[],"mappings":";;;AAEA,uDAAmF;AAE5E,MAAM,WAAW,GAAG,KAAK,EAAE,UAAuB,EAAE,KAAa,EAAiC,EAAE;;IACzG,kCAAkC;IAClC,MAAM,YAAY,GAAG,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,YAAY,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEtD,+CAA+C;IAC/C,iFAAiF;IACjF,IAAI,SAAwB,CAAC;IAC7B,QAAQ,KAAK,CAAC,eAAe,EAAE;QAC7B,KAAK,WAAW;YACd,SAAS,GAAG,CAAC,CAAC;YACd,MAAM;QACR,KAAK,aAAa;YAChB,SAAS,GAAG,CAAC,CAAC;YACd,MAAM;QACR,KAAK,YAAY;YACf,SAAS,GAAG,CAAC,CAAC;YACd,MAAM;QACR,KAAK,YAAY;YACf,SAAS,GAAG,CAAC,CAAC;YACd,MAAM;QACR;YACE,MAAM,IAAI,KAAK,CAAC,gCAAgC,KAAK,CAAC,eAAe,EAAE,CAAC,CAAC;KAC5E;IAED,uBAAuB;IACvB,IAAI,UAA6D,CAAC;IAClE,QAAQ,KAAK,CAAC,UAAU,EAAE;QACxB,KAAK,OAAO;YACV,UAAU,GAAG,OAAO,CAAC;YACrB,MAAM;QACR,KAAK,QAAQ;YACX,UAAU,GAAG,QAAQ,CAAC;YACtB,MAAM;QACR;YACE,UAAU,GAAG,OAAO,CAAC;KACxB;IAED,0BAA0B;IAE1B,MAAM,QAAQ,GAAG,MAAM,IAAA,yBAAc,EAAC,UAAU,EAAE;QAChD,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;QACtB,OAAO;QACP,OAAO,EAAE,CAAC;QACV,SAAS,EAAE,GAAG;QACd,UAAU;QACV,SAAS;QACT,WAAW,EAAE,CAAC;QACd,QAAQ,EAAE,GAAG;QACb,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE;QAC7B,aAAa,EAAE,CAAC;QAChB,aAAa,EAAE,KAAc;QAC7B,QAAQ,EAAE,CAAC;QACX,UAAU,EAAE,CAAU;QACtB,KAAK,EAAE,MAAA,KAAK,CAAC,KAAK,0CAAE,QAAQ,EAAE;KAC/B,CAAC,CAAC;IAEH,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;AAC9C,CAAC,CAAC;AA1DW,QAAA,WAAW,eA0DtB","sourcesContent":["import { IOrder } from '@yuants/data-order';\nimport { formatTime } from '@yuants/utils';\nimport { ICredential, submitOrder as submitOrderApi } from '../../api/private-api';\n\nexport const submitOrder = async (credential: ICredential, order: IOrder): Promise<{ order_id: string }> => {\n // Parse product_id to get pair_id\n const productParts = order.product_id.split('/');\n const pair_id = productParts[productParts.length - 1];\n\n // Determine order_way based on order_direction\n // 1: 开多 (Open Long), 2: 平空 (Close Short), 3: 开空 (Open Short), 4: 平多 (Close Long)\n let order_way: 1 | 2 | 3 | 4;\n switch (order.order_direction) {\n case 'OPEN_LONG':\n order_way = 1;\n break;\n case 'CLOSE_SHORT':\n order_way = 2;\n break;\n case 'OPEN_SHORT':\n order_way = 3;\n break;\n case 'CLOSE_LONG':\n order_way = 4;\n break;\n default:\n throw new Error(`Unsupported order direction: ${order.order_direction}`);\n }\n\n // Determine order_type\n let order_type: 'limit' | 'market' | 'stop_limit' | 'stop_market';\n switch (order.order_type) {\n case 'LIMIT':\n order_type = 'limit';\n break;\n case 'MARKET':\n order_type = 'market';\n break;\n default:\n order_type = 'limit';\n }\n\n // Build the order request\n\n const response = await submitOrderApi(credential, {\n request_id: Date.now(),\n pair_id,\n pool_id: 2, // usdc\n coin_code: '2', // usdc\n order_type,\n order_way,\n margin_type: 2, // Default to cross margin\n leverage: 100,\n size: order.volume.toString(), // usdc value\n position_mode: 1, // Default to one-way\n time_in_force: 'GTC' as const,\n fee_mode: 1,\n order_mode: 1 as const, // Normal order\n price: order.price?.toString(),\n });\n\n return { order_id: response.data.order.id };\n};\n"]}
1
+ {"version":3,"file":"submitOrder.js","sourceRoot":"","sources":["../../../src/services/orders/submitOrder.ts"],"names":[],"mappings":";;;AACA,yCAAiE;AACjE,uDAAmF;AAE5E,MAAM,WAAW,GAAG,KAAK,EAAE,UAAuB,EAAE,KAAa,EAAiC,EAAE;;IACzG,kCAAkC;IAClC,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,GAAG,IAAA,kBAAU,EAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAE/D,+CAA+C;IAC/C,iFAAiF;IACjF,IAAI,SAAwB,CAAC;IAC7B,QAAQ,KAAK,CAAC,eAAe,EAAE;QAC7B,KAAK,WAAW;YACd,SAAS,GAAG,CAAC,CAAC;YACd,MAAM;QACR,KAAK,aAAa;YAChB,SAAS,GAAG,CAAC,CAAC;YACd,MAAM;QACR,KAAK,YAAY;YACf,SAAS,GAAG,CAAC,CAAC;YACd,MAAM;QACR,KAAK,YAAY;YACf,SAAS,GAAG,CAAC,CAAC;YACd,MAAM;QACR;YACE,MAAM,IAAI,KAAK,CAAC,gCAAgC,KAAK,CAAC,eAAe,EAAE,CAAC,CAAC;KAC5E;IAED,uBAAuB;IACvB,IAAI,UAA6D,CAAC;IAClE,QAAQ,KAAK,CAAC,UAAU,EAAE;QACxB,KAAK,OAAO;YACV,UAAU,GAAG,OAAO,CAAC;YACrB,MAAM;QACR,KAAK,QAAQ;YACX,UAAU,GAAG,QAAQ,CAAC;YACtB,MAAM;QACR;YACE,UAAU,GAAG,OAAO,CAAC;KACxB;IAED,0BAA0B;IAE1B,MAAM,QAAQ,GAAG,MAAM,IAAA,yBAAc,EAAC,UAAU,EAAE;QAChD,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;QACtB,OAAO;QACP,OAAO,EAAE,CAAC;QACV,SAAS,EAAE,GAAG;QACd,UAAU;QACV,SAAS;QACT,WAAW,EAAE,CAAC;QACd,QAAQ,EAAE,CAAC;QACX,GAAG,EAAE,KAAK,CAAC,MAAM;QACjB,aAAa,EAAE,CAAC;QAChB,aAAa,EAAE,KAAc;QAC7B,QAAQ,EAAE,CAAC;QACX,UAAU,EAAE,CAAU;QACtB,KAAK,EAAE,MAAA,KAAK,CAAC,KAAK,0CAAE,QAAQ,EAAE;KAC/B,CAAC,CAAC;IAEH,IAAI,CAAC,CAAA,MAAA,QAAQ,CAAC,IAAI,0CAAE,KAAK,CAAA;QAAE,MAAM,IAAA,gBAAQ,EAAC,+BAA+B,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;IAEzF,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;AAC9C,CAAC,CAAC;AA3DW,QAAA,WAAW,eA2DtB","sourcesContent":["import { IOrder } from '@yuants/data-order';\nimport { decodePath, formatTime, newError } from '@yuants/utils';\nimport { ICredential, submitOrder as submitOrderApi } from '../../api/private-api';\n\nexport const submitOrder = async (credential: ICredential, order: IOrder): Promise<{ order_id: string }> => {\n // Parse product_id to get pair_id\n const [, _SWAP, _NAME, pair_id] = decodePath(order.product_id);\n\n // Determine order_way based on order_direction\n // 1: 开多 (Open Long), 2: 平空 (Close Short), 3: 开空 (Open Short), 4: 平多 (Close Long)\n let order_way: 1 | 2 | 3 | 4;\n switch (order.order_direction) {\n case 'OPEN_LONG':\n order_way = 1;\n break;\n case 'CLOSE_SHORT':\n order_way = 2;\n break;\n case 'OPEN_SHORT':\n order_way = 3;\n break;\n case 'CLOSE_LONG':\n order_way = 4;\n break;\n default:\n throw new Error(`Unsupported order direction: ${order.order_direction}`);\n }\n\n // Determine order_type\n let order_type: 'limit' | 'market' | 'stop_limit' | 'stop_market';\n switch (order.order_type) {\n case 'LIMIT':\n order_type = 'limit';\n break;\n case 'MARKET':\n order_type = 'market';\n break;\n default:\n order_type = 'limit';\n }\n\n // Build the order request\n\n const response = await submitOrderApi(credential, {\n request_id: Date.now(),\n pair_id,\n pool_id: 2, // usdc\n coin_code: '2', // usdc\n order_type,\n order_way,\n margin_type: 2, // Default to cross margin\n leverage: 1,\n vol: order.volume, // usdc value\n position_mode: 1, // Default to one-way\n time_in_force: 'GTC' as const,\n fee_mode: 1,\n order_mode: 1 as const, // Normal order\n price: order.price?.toString(),\n });\n\n if (!response.data?.order) throw newError('TURBOFLOW_SUBMIT_ORDER_FAILED', { response });\n\n return { order_id: response.data.order.id };\n};\n"]}
package/package.json CHANGED
@@ -1,10 +1,12 @@
1
1
  {
2
2
  "name": "@yuants/vendor-turboflow",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "main": "lib/index.js",
5
5
  "dependencies": {
6
6
  "@yuants/protocol": "0.53.0",
7
7
  "@yuants/utils": "0.13.0",
8
+ "@yuants/exchange": "0.1.0",
9
+ "@yuants/data-product": "0.4.19",
8
10
  "@yuants/data-account": "0.8.2",
9
11
  "@yuants/data-order": "0.6.4",
10
12
  "rxjs": "~7.5.6"
@@ -9,15 +9,15 @@ Starting test
9
9
  ---- Pre-compile finished (0ms) ----
10
10
  ---- Compile started ----
11
11
  [typescript] Using TypeScript version 4.7.4
12
- ---- Compile finished (3001ms) ----
12
+ ---- Compile finished (4541ms) ----
13
13
  ---- Bundle started ----
14
- ---- Bundle finished (2ms) ----
14
+ ---- Bundle finished (4ms) ----
15
15
  ---- Post-build started ----
16
16
  ---- Post-build finished (0ms) ----
17
17
  ---- Test started ----
18
- ---- Test finished (2ms) ----
19
- -------------------- Finished (3.313s) --------------------
20
- Project: @yuants/vendor-turboflow@1.2.0
18
+ ---- Test finished (3ms) ----
19
+ -------------------- Finished (4.945s) --------------------
20
+ Project: @yuants/vendor-turboflow@1.2.1
21
21
  Heft version: 0.47.11
22
22
  Node version: v22.14.0
23
- 2025-11-25T11:54:42.712Z no Dockerfile found, skip building docker image
23
+ 2025-11-26T13:18:18.308Z no Dockerfile found, skip building docker image
@@ -50,15 +50,16 @@ export const privateRequest = async (
50
50
  headers['SIGN'] = signatureHex;
51
51
  headers['LANG'] = 'zh-cn';
52
52
 
53
+ const body = method === 'POST' ? JSON.stringify(params) : undefined;
53
54
  const response = await fetch(url.toString(), {
54
55
  method,
55
56
  headers,
56
- body: method === 'POST' ? JSON.stringify(params) : undefined,
57
+ body,
57
58
  });
58
59
 
59
60
  const text = await response.text();
60
61
 
61
- console.info(url.toString(), headers, text);
62
+ console.info(url.toString(), headers, text, params, body);
62
63
 
63
64
  return scopeError('TurboAPIError', { status: response.status, statusText: response.statusText, text }, () =>
64
65
  JSON.parse(text),
@@ -152,7 +153,7 @@ export const submitOrder = createPrivateApi<
152
153
  order_way: 1 | 2 | 3 | 4; // 1:开多 2:平空 3:开空 4:平多
153
154
  margin_type: 1 | 2; // 1:逐仓 2:全仓
154
155
  leverage: number;
155
- size: string; // 交易数量
156
+ vol: number; // 交易数量
156
157
  position_mode: 1 | 2 | 3; // 1:单向 2:双向 3:原子
157
158
  time_in_force: 'GTC' | 'IOC' | 'FOK';
158
159
  fee_mode: 1 | 2; // 1:固定 2:利润分层
@@ -0,0 +1,65 @@
1
+ import { decodeBase58, fromPrivateKey, HmacSHA256, scopeError, signMessageByEd25519 } from '@yuants/utils';
2
+
3
+ export interface ICredential {
4
+ /**
5
+ * ED25519 Private KEY (base58)
6
+ */
7
+ private_key: string;
8
+ }
9
+
10
+ const BASE_URL = 'https://surfv2-api.surf.one';
11
+
12
+ export const publicRequest = async (method: string, path: string, params: any = {}) => {
13
+ const url = new URL(BASE_URL);
14
+ url.pathname = path;
15
+
16
+ if (method === 'GET') {
17
+ for (const [key, value] of Object.entries(params)) {
18
+ url.searchParams.set(key, `${value}`);
19
+ }
20
+ }
21
+
22
+ const response = await fetch(url.toString(), {
23
+ method,
24
+ body: method === 'POST' ? JSON.stringify(params) : undefined,
25
+ });
26
+
27
+ const text = await response.text();
28
+
29
+ console.info(url.toString(), text);
30
+
31
+ return scopeError('TurboAPIError', { status: response.status, statusText: response.statusText, text }, () =>
32
+ JSON.parse(text),
33
+ );
34
+ };
35
+
36
+ export const createPublicApi =
37
+ <T, K>(method: string, path: string) =>
38
+ (params: T): Promise<K> =>
39
+ publicRequest(method, path, params);
40
+
41
+ /**
42
+ * 获取账户信息
43
+ */
44
+ export const getPoolPairList = createPublicApi<
45
+ void,
46
+ {
47
+ errno: string;
48
+ msg: string;
49
+ data: {
50
+ pair_id: string;
51
+ base_token: string;
52
+ quote_token: string;
53
+ base_token_logo: string;
54
+ base_token_name: string;
55
+ volume_24h: string;
56
+ price: string;
57
+ c: string;
58
+ max_leverage: number;
59
+ avg_order_book_fee: string;
60
+ funding_fee_interval: number;
61
+ created_at: string;
62
+ tag_id_list: number[];
63
+ }[];
64
+ }
65
+ >('GET', '/pool/pair/list');
package/src/index.ts CHANGED
@@ -1,3 +1 @@
1
- // Import services
2
- import './services/account-actions-with-credential';
3
- import './services/order-actions-with-credential';
1
+ import './services/exchange';
@@ -0,0 +1,107 @@
1
+ import { IPosition, makeSpotPosition } from '@yuants/data-account';
2
+ import { IOrder } from '@yuants/data-order';
3
+ import { provideExchangeServices } from '@yuants/exchange';
4
+ import { Terminal } from '@yuants/protocol';
5
+ import { getAccountAssets, getAccountInfo, getPositionList, ICredential } from '../api/private-api';
6
+ import { encodePath } from '@yuants/utils';
7
+ import { submitOrder } from './orders/submitOrder';
8
+ import { modifyOrder } from './orders/modifyOrder';
9
+ import { cancelOrderAction } from './orders/cancelOrder';
10
+ import { listOrders } from './orders/listOrders';
11
+ import { getPoolPairList } from '../api/public-api';
12
+ import { IProduct } from '@yuants/data-product';
13
+
14
+ const terminal = Terminal.fromNodeEnv();
15
+
16
+ provideExchangeServices<ICredential>(terminal, {
17
+ name: 'TURBOFLOW',
18
+ credentialSchema: {
19
+ type: 'object',
20
+ required: ['private_key'],
21
+ properties: {
22
+ private_key: {
23
+ type: 'string',
24
+ description: 'ED25519 Private Key (base58 encoded)',
25
+ },
26
+ },
27
+ },
28
+ getCredentialId: async function (credential): Promise<string> {
29
+ const accountInfo = await getAccountInfo(credential);
30
+
31
+ return encodePath('TURBOFLOW', accountInfo.data.account_id);
32
+ },
33
+ listProducts: async () => {
34
+ const data = await getPoolPairList();
35
+ return data.data.map(
36
+ (pair): IProduct => ({
37
+ datasource_id: 'TURBOFLOW',
38
+ product_id: encodePath('TURBOFLOW', 'PERP', pair.base_token, pair.pair_id),
39
+ name: `${pair.base_token}-${pair.quote_token}`,
40
+ quote_currency: pair.quote_token,
41
+ base_currency: pair.base_token,
42
+ price_step: 1e-15,
43
+ volume_step: 1e-15,
44
+ value_scale: 1,
45
+ value_scale_unit: '',
46
+ margin_rate: 1 / pair.max_leverage,
47
+ value_based_cost: 0,
48
+ volume_based_cost: 0,
49
+ max_position: 0,
50
+ max_volume: 0,
51
+ allow_long: true,
52
+ allow_short: true,
53
+ }),
54
+ );
55
+ },
56
+ getPositions: async function (credential) {
57
+ const assetsResponse = await getAccountAssets(credential, {
58
+ fill_coin_sub_info: '1',
59
+ });
60
+
61
+ const assetPositions = assetsResponse.data.list.map((x) =>
62
+ makeSpotPosition({
63
+ position_id: x.coin_code,
64
+ product_id: encodePath('SPOT', x.coin_name),
65
+ volume: parseFloat(x.available_balance),
66
+ free_volume: parseFloat(x.available_balance),
67
+ closable_price: 1,
68
+ }),
69
+ );
70
+
71
+ const positionsResponse = await getPositionList(credential, { status: 'Holding' });
72
+
73
+ const positions: IPosition[] = (positionsResponse.data.data || []).map((position) => {
74
+ const side = position.side === 1 ? 'LONG' : 'SHORT';
75
+ const holdSize = parseFloat(position.hold_size);
76
+ const holdAv = parseFloat(position.hold_av);
77
+ const unpnl = parseFloat(position.unpnl);
78
+ const im = parseFloat(position.im);
79
+
80
+ return {
81
+ position_id: position.id,
82
+ datasource_id: 'TURBOFLOW',
83
+ product_id: encodePath('TURBOFLOW', 'PERP', position.symbol, position.pair_id),
84
+ direction: side,
85
+ volume: holdSize,
86
+ free_volume: holdSize, // Assuming all volume is free
87
+ position_price: holdAv,
88
+ closable_price: holdAv,
89
+ floating_profit: unpnl,
90
+ valuation: holdSize * holdAv,
91
+ margin: im,
92
+ };
93
+ });
94
+
95
+ return [...assetPositions, ...positions];
96
+ },
97
+ getOrders: listOrders,
98
+ getPositionsByProductId: function (credential: ICredential, product_id: string): Promise<IPosition[]> {
99
+ throw new Error('Function not implemented.');
100
+ },
101
+ getOrdersByProductId: function (credential: ICredential, product_id: string): Promise<IOrder[]> {
102
+ throw new Error('Function not implemented.');
103
+ },
104
+ submitOrder: submitOrder,
105
+ modifyOrder: modifyOrder,
106
+ cancelOrder: cancelOrderAction,
107
+ });
@@ -5,39 +5,32 @@ import { ICredential, cancelOrder as cancelOrderApi } from '../../api/private-ap
5
5
  export const cancelOrderAction = async (credential: ICredential, order: IOrder): Promise<void> => {
6
6
  console.info(`[${formatTime(Date.now())}] Cancelling order ${order.order_id}`);
7
7
 
8
- try {
9
- // Parse product_id to get pair_id
10
- const productParts = order.product_id.split('/');
11
- const pair_id = productParts[productParts.length - 1];
8
+ // Parse product_id to get pair_id
9
+ const productParts = order.product_id.split('/');
10
+ const pair_id = productParts[productParts.length - 1];
12
11
 
13
- // Parse comment for pool_id
14
- let pool_id = 1;
15
- if (order.comment) {
16
- try {
17
- const params = JSON.parse(order.comment);
18
- pool_id = params.pool_id || 1;
19
- } catch (e) {
20
- console.warn(`[${formatTime(Date.now())}] Failed to parse order comment:`, e);
21
- }
22
- }
23
-
24
- if (!order.order_id) {
25
- throw new Error('order_id is required for cancelling order');
12
+ // Parse comment for pool_id
13
+ let pool_id = 1;
14
+ if (order.comment) {
15
+ try {
16
+ const params = JSON.parse(order.comment);
17
+ pool_id = params.pool_id || 1;
18
+ } catch (e) {
19
+ console.warn(`[${formatTime(Date.now())}] Failed to parse order comment:`, e);
26
20
  }
21
+ }
27
22
 
28
- const response = await cancelOrderApi(credential, {
29
- pair_id,
30
- order_id: order.order_id,
31
- pool_id,
32
- });
23
+ if (!order.order_id) {
24
+ throw new Error('order_id is required for cancelling order');
25
+ }
33
26
 
34
- if (response.errno !== '0') {
35
- throw new Error(`Failed to cancel order: ${response.msg}`);
36
- }
27
+ const response = await cancelOrderApi(credential, {
28
+ pair_id,
29
+ order_id: order.order_id,
30
+ pool_id,
31
+ });
37
32
 
38
- console.info(`[${formatTime(Date.now())}] Order ${order.order_id} cancelled successfully`);
39
- } catch (error) {
40
- console.error(`[${formatTime(Date.now())}] Error cancelling order:`, error);
41
- throw error;
33
+ if (response.errno !== '200') {
34
+ throw new Error(`Failed to cancel order: ${response.msg}`);
42
35
  }
43
36
  };
@@ -1,5 +1,5 @@
1
- import { IActionHandlerOfListOrders, IOrder } from '@yuants/data-order';
2
- import { encodePath, formatTime } from '@yuants/utils';
1
+ import { IOrder } from '@yuants/data-order';
2
+ import { encodePath } from '@yuants/utils';
3
3
  import { ICredential, getOrderList } from '../../api/private-api';
4
4
 
5
5
  type OrderDirection = 'OPEN_LONG' | 'OPEN_SHORT' | 'CLOSE_LONG' | 'CLOSE_SHORT';
@@ -26,13 +26,13 @@ const mapOrderDirection = (order_way: number): OrderDirection => {
26
26
  /**
27
27
  * Map TurboFlow order to Yuan IOrder format
28
28
  */
29
- const mapOrder = (order: any, account_id: string): IOrder => {
29
+ const mapOrder = (order: any): IOrder => {
30
30
  const volume = parseFloat(order.size) || 0;
31
31
  const price = parseFloat(order.price) || 0;
32
32
 
33
33
  return {
34
34
  order_id: order.id,
35
- account_id,
35
+ account_id: '', // Will be filled in listOrders
36
36
  product_id: encodePath('PERPETUAL', order.pair_id),
37
37
  order_type: order.order_type.toUpperCase() as any,
38
38
  order_direction: mapOrderDirection(order.order_way),
@@ -56,29 +56,12 @@ const mapOrder = (order: any, account_id: string): IOrder => {
56
56
  /**
57
57
  * List orders implementation
58
58
  */
59
- export const listOrders: IActionHandlerOfListOrders<ICredential> = async (credential, account_id) => {
60
- console.info(`[${formatTime(Date.now())}] Listing orders for account: ${account_id}`);
59
+ export const listOrders = async (credential: ICredential): Promise<IOrder[]> => {
60
+ const response = await getOrderList(credential, {
61
+ page_num: 1,
62
+ page_size: 100,
63
+ status: 'Pending',
64
+ });
61
65
 
62
- try {
63
- // Get pending orders
64
- const response = await getOrderList(credential, {
65
- page_num: 1,
66
- page_size: 100,
67
- status: 'Pending',
68
- });
69
-
70
- if (response.errno !== '0') {
71
- throw new Error(`Failed to list orders: ${response.msg}`);
72
- }
73
-
74
- const orders = response.data.data.map((order) => mapOrder(order, account_id));
75
-
76
- console.info(`[${formatTime(Date.now())}] Found ${orders.length} orders`);
77
-
78
- return orders;
79
- } catch (error) {
80
- const errorMessage = error instanceof Error ? error.message : 'Unknown error';
81
- console.error(`[${formatTime(Date.now())}] Failed to list orders for ${account_id}: ${errorMessage}`);
82
- throw new Error(`Failed to list orders: ${errorMessage}`);
83
- }
66
+ return response.data.data.map((order) => mapOrder(order));
84
67
  };
@@ -1,11 +1,10 @@
1
1
  import { IOrder } from '@yuants/data-order';
2
- import { formatTime } from '@yuants/utils';
2
+ import { decodePath, formatTime, newError } from '@yuants/utils';
3
3
  import { ICredential, submitOrder as submitOrderApi } from '../../api/private-api';
4
4
 
5
5
  export const submitOrder = async (credential: ICredential, order: IOrder): Promise<{ order_id: string }> => {
6
6
  // Parse product_id to get pair_id
7
- const productParts = order.product_id.split('/');
8
- const pair_id = productParts[productParts.length - 1];
7
+ const [, _SWAP, _NAME, pair_id] = decodePath(order.product_id);
9
8
 
10
9
  // Determine order_way based on order_direction
11
10
  // 1: 开多 (Open Long), 2: 平空 (Close Short), 3: 开空 (Open Short), 4: 平多 (Close Long)
@@ -50,8 +49,8 @@ export const submitOrder = async (credential: ICredential, order: IOrder): Promi
50
49
  order_type,
51
50
  order_way,
52
51
  margin_type: 2, // Default to cross margin
53
- leverage: 100,
54
- size: order.volume.toString(), // usdc value
52
+ leverage: 1,
53
+ vol: order.volume, // usdc value
55
54
  position_mode: 1, // Default to one-way
56
55
  time_in_force: 'GTC' as const,
57
56
  fee_mode: 1,
@@ -59,5 +58,7 @@ export const submitOrder = async (credential: ICredential, order: IOrder): Promi
59
58
  price: order.price?.toString(),
60
59
  });
61
60
 
61
+ if (!response.data?.order) throw newError('TURBOFLOW_SUBMIT_ORDER_FAILED', { response });
62
+
62
63
  return { order_id: response.data.order.id };
63
64
  };
@@ -1,20 +1,23 @@
1
1
  {
2
- "apps/vendor-turboflow/CHANGELOG.json": "350b7c6800859724fd1ff4a1c4df32e164d854a3",
3
- "apps/vendor-turboflow/CHANGELOG.md": "31fc93ba045c6d26ff202823e59d114cf6c26092",
2
+ "apps/vendor-turboflow/CHANGELOG.json": "18813dc048fa2d00e3bdfafaa7fc9e67219b12da",
3
+ "apps/vendor-turboflow/CHANGELOG.md": "d85f5a83fc01eeb1107f3a3379cb7f34fa271519",
4
4
  "apps/vendor-turboflow/README.md": "084c5960ccac11196467867e63c790f6b14ca3a5",
5
- "apps/vendor-turboflow/package.json": "f246025cb7eef95826dab6e3e14cb7b07b241cd1",
6
- "apps/vendor-turboflow/src/api/private-api.ts": "984f48c4fefbd06372477d55d77d04e5100677c5",
7
- "apps/vendor-turboflow/src/index.ts": "8bdf474409cc344ea02d884afe5d51ec69b1ec09",
8
- "apps/vendor-turboflow/src/services/account-actions-with-credential.ts": "a6bc02ec571edbfe92ee884b17a291d0982536b4",
5
+ "apps/vendor-turboflow/package.json": "feb0499078143b8eb8610f5cc967eeac042c53ae",
6
+ "apps/vendor-turboflow/src/api/private-api.ts": "4b11942303ef65e515911b1d9a8bc654f599ddf4",
7
+ "apps/vendor-turboflow/src/api/public-api.ts": "e5a8e21bf4797e56fdd6b1948b761ede54aa34eb",
8
+ "apps/vendor-turboflow/src/index.ts": "44b85b7532783f7734eaab6f90e426cb84da16eb",
9
+ "apps/vendor-turboflow/src/services/exchange.ts": "cd87240a3e66be141308cffab150e6d600315e95",
9
10
  "apps/vendor-turboflow/src/services/order-actions-with-credential.ts": "65a026635484aca00a22ad1e3a37fdcc87955311",
10
- "apps/vendor-turboflow/src/services/orders/cancelOrder.ts": "1d5f6bdb44c1905be945996e578c7d5667cd021e",
11
- "apps/vendor-turboflow/src/services/orders/listOrders.ts": "01121cbaee641a6ea4fd6c05fee0094c7a74ebfb",
11
+ "apps/vendor-turboflow/src/services/orders/cancelOrder.ts": "722b2cecb9d103df9e68ea54e7e0556d597d0da7",
12
+ "apps/vendor-turboflow/src/services/orders/listOrders.ts": "8e23af975d3395004b2479332a7d9e57dc4514b4",
12
13
  "apps/vendor-turboflow/src/services/orders/modifyOrder.ts": "b833093cf61948efe6007cfc95583ef525201cd1",
13
- "apps/vendor-turboflow/src/services/orders/submitOrder.ts": "a4684d1cdd0529a796d8e2173093e32db7258011",
14
+ "apps/vendor-turboflow/src/services/orders/submitOrder.ts": "c95aa70551f8ce8e6d7ff696082d26145dfc89ac",
14
15
  "apps/vendor-turboflow/tsconfig.json": "5d15ec8bd54da210724db6ed27c0f925f86ee153",
15
- "apps/vendor-turboflow/.rush/temp/shrinkwrap-deps.json": "bd10565593bf1d1988009aa7c17f190815026be9",
16
+ "apps/vendor-turboflow/.rush/temp/shrinkwrap-deps.json": "4db58413c55e23c69bcd2319c8fd3f010f5487e4",
16
17
  "libraries/protocol/temp/package-deps.json": "00d9a96a90bfc0e57ef3b9547151f2970a600402",
17
18
  "libraries/utils/temp/package-deps.json": "4a683c07df7c75079b700111b9f6beb36c74ff7d",
19
+ "libraries/exchange/temp/package-deps.json": "16a4864218e5ef6afb856b728aa0751bb89cc9e8",
20
+ "libraries/data-product/temp/package-deps.json": "c9a00b88e1570374aeb333756f59975d7dcc7400",
18
21
  "libraries/data-account/temp/package-deps.json": "bf8b41c4d878dab0f39ea684fffaf6bc3c74c988",
19
22
  "libraries/data-order/temp/package-deps.json": "4a0272551da88c9eb52150775640b12c31786de8",
20
23
  "tools/toolkit/temp/package-deps.json": "23e053490eb8feade23e4d45de4e54883e322711"
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=account-actions-with-credential.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"account-actions-with-credential.d.ts","sourceRoot":"","sources":["../../src/services/account-actions-with-credential.ts"],"names":[],"mappings":""}