jcc_hyper_tool 0.1.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 (163) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +394 -0
  3. package/dist/cli/confirm.d.ts +2 -0
  4. package/dist/cli/confirm.d.ts.map +1 -0
  5. package/dist/cli/confirm.js +22 -0
  6. package/dist/cli/confirm.js.map +1 -0
  7. package/dist/cli/index.d.ts +3 -0
  8. package/dist/cli/index.d.ts.map +1 -0
  9. package/dist/cli/index.js +189 -0
  10. package/dist/cli/index.js.map +1 -0
  11. package/dist/cli/perpKline.d.ts +19 -0
  12. package/dist/cli/perpKline.d.ts.map +1 -0
  13. package/dist/cli/perpKline.js +39 -0
  14. package/dist/cli/perpKline.js.map +1 -0
  15. package/dist/cli/stateCli.d.ts +3 -0
  16. package/dist/cli/stateCli.d.ts.map +1 -0
  17. package/dist/cli/stateCli.js +158 -0
  18. package/dist/cli/stateCli.js.map +1 -0
  19. package/dist/cli/strategyCli.d.ts +3 -0
  20. package/dist/cli/strategyCli.d.ts.map +1 -0
  21. package/dist/cli/strategyCli.js +198 -0
  22. package/dist/cli/strategyCli.js.map +1 -0
  23. package/dist/cli/tradingCli.d.ts +3 -0
  24. package/dist/cli/tradingCli.d.ts.map +1 -0
  25. package/dist/cli/tradingCli.js +587 -0
  26. package/dist/cli/tradingCli.js.map +1 -0
  27. package/dist/cli/util.d.ts +28 -0
  28. package/dist/cli/util.d.ts.map +1 -0
  29. package/dist/cli/util.js +62 -0
  30. package/dist/cli/util.js.map +1 -0
  31. package/dist/core/config.d.ts +32 -0
  32. package/dist/core/config.d.ts.map +1 -0
  33. package/dist/core/config.js +101 -0
  34. package/dist/core/config.js.map +1 -0
  35. package/dist/core/errors.d.ts +9 -0
  36. package/dist/core/errors.d.ts.map +1 -0
  37. package/dist/core/errors.js +17 -0
  38. package/dist/core/errors.js.map +1 -0
  39. package/dist/core/hyperliquid/asset.d.ts +24 -0
  40. package/dist/core/hyperliquid/asset.d.ts.map +1 -0
  41. package/dist/core/hyperliquid/asset.js +88 -0
  42. package/dist/core/hyperliquid/asset.js.map +1 -0
  43. package/dist/core/hyperliquid/candles.d.ts +24 -0
  44. package/dist/core/hyperliquid/candles.d.ts.map +1 -0
  45. package/dist/core/hyperliquid/candles.js +113 -0
  46. package/dist/core/hyperliquid/candles.js.map +1 -0
  47. package/dist/core/hyperliquid/client.d.ts +36 -0
  48. package/dist/core/hyperliquid/client.d.ts.map +1 -0
  49. package/dist/core/hyperliquid/client.js +92 -0
  50. package/dist/core/hyperliquid/client.js.map +1 -0
  51. package/dist/core/hyperliquid/exchange.d.ts +14 -0
  52. package/dist/core/hyperliquid/exchange.d.ts.map +1 -0
  53. package/dist/core/hyperliquid/exchange.js +42 -0
  54. package/dist/core/hyperliquid/exchange.js.map +1 -0
  55. package/dist/core/hyperliquid/exchangeParse.d.ts +7 -0
  56. package/dist/core/hyperliquid/exchangeParse.d.ts.map +1 -0
  57. package/dist/core/hyperliquid/exchangeParse.js +44 -0
  58. package/dist/core/hyperliquid/exchangeParse.js.map +1 -0
  59. package/dist/core/hyperliquid/float.d.ts +6 -0
  60. package/dist/core/hyperliquid/float.d.ts.map +1 -0
  61. package/dist/core/hyperliquid/float.js +24 -0
  62. package/dist/core/hyperliquid/float.js.map +1 -0
  63. package/dist/core/hyperliquid/klineCoin.d.ts +10 -0
  64. package/dist/core/hyperliquid/klineCoin.d.ts.map +1 -0
  65. package/dist/core/hyperliquid/klineCoin.js +90 -0
  66. package/dist/core/hyperliquid/klineCoin.js.map +1 -0
  67. package/dist/core/hyperliquid/orders.d.ts +91 -0
  68. package/dist/core/hyperliquid/orders.d.ts.map +1 -0
  69. package/dist/core/hyperliquid/orders.js +116 -0
  70. package/dist/core/hyperliquid/orders.js.map +1 -0
  71. package/dist/core/hyperliquid/prefixedPerpCoin.d.ts +3 -0
  72. package/dist/core/hyperliquid/prefixedPerpCoin.d.ts.map +1 -0
  73. package/dist/core/hyperliquid/prefixedPerpCoin.js +10 -0
  74. package/dist/core/hyperliquid/prefixedPerpCoin.js.map +1 -0
  75. package/dist/core/hyperliquid/signed-exchange.d.ts +10 -0
  76. package/dist/core/hyperliquid/signed-exchange.d.ts.map +1 -0
  77. package/dist/core/hyperliquid/signed-exchange.js +23 -0
  78. package/dist/core/hyperliquid/signed-exchange.js.map +1 -0
  79. package/dist/core/hyperliquid/signing.d.ts +23 -0
  80. package/dist/core/hyperliquid/signing.d.ts.map +1 -0
  81. package/dist/core/hyperliquid/signing.js +65 -0
  82. package/dist/core/hyperliquid/signing.js.map +1 -0
  83. package/dist/core/hyperliquid/types.d.ts +11 -0
  84. package/dist/core/hyperliquid/types.d.ts.map +1 -0
  85. package/dist/core/hyperliquid/types.js +2 -0
  86. package/dist/core/hyperliquid/types.js.map +1 -0
  87. package/dist/core/hyperliquid/watchOrders.d.ts +10 -0
  88. package/dist/core/hyperliquid/watchOrders.d.ts.map +1 -0
  89. package/dist/core/hyperliquid/watchOrders.js +38 -0
  90. package/dist/core/hyperliquid/watchOrders.js.map +1 -0
  91. package/dist/core/state/bracketReconcile.d.ts +23 -0
  92. package/dist/core/state/bracketReconcile.d.ts.map +1 -0
  93. package/dist/core/state/bracketReconcile.js +297 -0
  94. package/dist/core/state/bracketReconcile.js.map +1 -0
  95. package/dist/core/state/cancelOpenPlan.d.ts +23 -0
  96. package/dist/core/state/cancelOpenPlan.d.ts.map +1 -0
  97. package/dist/core/state/cancelOpenPlan.js +126 -0
  98. package/dist/core/state/cancelOpenPlan.js.map +1 -0
  99. package/dist/core/state/gcTradeState.d.ts +13 -0
  100. package/dist/core/state/gcTradeState.d.ts.map +1 -0
  101. package/dist/core/state/gcTradeState.js +48 -0
  102. package/dist/core/state/gcTradeState.js.map +1 -0
  103. package/dist/core/state/gridReconcile.d.ts +46 -0
  104. package/dist/core/state/gridReconcile.d.ts.map +1 -0
  105. package/dist/core/state/gridReconcile.js +307 -0
  106. package/dist/core/state/gridReconcile.js.map +1 -0
  107. package/dist/core/state/intentFactory.d.ts +58 -0
  108. package/dist/core/state/intentFactory.d.ts.map +1 -0
  109. package/dist/core/state/intentFactory.js +95 -0
  110. package/dist/core/state/intentFactory.js.map +1 -0
  111. package/dist/core/state/present.d.ts +17 -0
  112. package/dist/core/state/present.d.ts.map +1 -0
  113. package/dist/core/state/present.js +100 -0
  114. package/dist/core/state/present.js.map +1 -0
  115. package/dist/core/state/runCancelOpen.d.ts +32 -0
  116. package/dist/core/state/runCancelOpen.d.ts.map +1 -0
  117. package/dist/core/state/runCancelOpen.js +101 -0
  118. package/dist/core/state/runCancelOpen.js.map +1 -0
  119. package/dist/core/state/runReconcile.d.ts +20 -0
  120. package/dist/core/state/runReconcile.d.ts.map +1 -0
  121. package/dist/core/state/runReconcile.js +248 -0
  122. package/dist/core/state/runReconcile.js.map +1 -0
  123. package/dist/core/state/schema.d.ts +1161 -0
  124. package/dist/core/state/schema.d.ts.map +1 -0
  125. package/dist/core/state/schema.js +151 -0
  126. package/dist/core/state/schema.js.map +1 -0
  127. package/dist/core/state/snapshot.d.ts +22 -0
  128. package/dist/core/state/snapshot.d.ts.map +1 -0
  129. package/dist/core/state/snapshot.js +115 -0
  130. package/dist/core/state/snapshot.js.map +1 -0
  131. package/dist/core/state/statePaths.d.ts +2 -0
  132. package/dist/core/state/statePaths.d.ts.map +1 -0
  133. package/dist/core/state/statePaths.js +7 -0
  134. package/dist/core/state/statePaths.js.map +1 -0
  135. package/dist/core/state/store.d.ts +12 -0
  136. package/dist/core/state/store.d.ts.map +1 -0
  137. package/dist/core/state/store.js +95 -0
  138. package/dist/core/state/store.js.map +1 -0
  139. package/dist/core/state/types.d.ts +40 -0
  140. package/dist/core/state/types.d.ts.map +1 -0
  141. package/dist/core/state/types.js +2 -0
  142. package/dist/core/state/types.js.map +1 -0
  143. package/dist/core/trading.d.ts +8 -0
  144. package/dist/core/trading.d.ts.map +1 -0
  145. package/dist/core/trading.js +22 -0
  146. package/dist/core/trading.js.map +1 -0
  147. package/dist/core/wallet.d.ts +3 -0
  148. package/dist/core/wallet.d.ts.map +1 -0
  149. package/dist/core/wallet.js +14 -0
  150. package/dist/core/wallet.js.map +1 -0
  151. package/dist/daemon/index.d.ts +3 -0
  152. package/dist/daemon/index.d.ts.map +1 -0
  153. package/dist/daemon/index.js +104 -0
  154. package/dist/daemon/index.js.map +1 -0
  155. package/dist/meta/version.d.ts +2 -0
  156. package/dist/meta/version.d.ts.map +1 -0
  157. package/dist/meta/version.js +12 -0
  158. package/dist/meta/version.js.map +1 -0
  159. package/dist/strategies/grid.d.ts +46 -0
  160. package/dist/strategies/grid.d.ts.map +1 -0
  161. package/dist/strategies/grid.js +101 -0
  162. package/dist/strategies/grid.js.map +1 -0
  163. package/package.json +46 -0
@@ -0,0 +1,95 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { annotateGridSides, gridPriceLevels } from "../../strategies/grid.js";
3
+ export function createBracketIntentRecord(params) {
4
+ const id = randomUUID();
5
+ return {
6
+ kind: "bracket",
7
+ id,
8
+ createdAtMs: params.nowMs,
9
+ updatedAtMs: params.nowMs,
10
+ coin: params.coin,
11
+ dex: params.dex,
12
+ network: params.network,
13
+ entrySide: params.entrySide,
14
+ entryLimitPx: params.entryLimitPx,
15
+ entrySz: params.entrySz,
16
+ tif: params.tif,
17
+ entryReduceOnly: params.entryReduceOnly,
18
+ tpTriggerPx: params.tpTriggerPx,
19
+ slTriggerPx: params.slTriggerPx,
20
+ tpslIsMarket: params.tpslIsMarket ?? true,
21
+ tpslLimitPx: params.tpslLimitPx,
22
+ protectionReduceOnly: params.protectionReduceOnly ?? true,
23
+ phase: "planned",
24
+ expiresAtMs: params.expiresAtMs,
25
+ };
26
+ }
27
+ export function createGridIntentRecord(params) {
28
+ const prices = gridPriceLevels(params.lower, params.upper, params.grids, params.bias);
29
+ const annotated = annotateGridSides(prices, params.lower, params.upper, params.bias);
30
+ const legs = annotated.map((r, index) => ({
31
+ index,
32
+ px: r.px,
33
+ isBuy: r.isBuy,
34
+ legPhase: "pending",
35
+ }));
36
+ const id = randomUUID();
37
+ return {
38
+ kind: "grid",
39
+ id,
40
+ createdAtMs: params.nowMs,
41
+ updatedAtMs: params.nowMs,
42
+ coin: params.coin,
43
+ dex: params.dex,
44
+ network: params.network,
45
+ lower: params.lower,
46
+ upper: params.upper,
47
+ grids: params.grids,
48
+ orderSz: params.orderSz,
49
+ bias: params.bias,
50
+ tif: params.tif,
51
+ reduceOnly: params.reduceOnly,
52
+ maxOrders: params.maxOrders,
53
+ ...(typeof params.replenishGapPx === "number" &&
54
+ Number.isFinite(params.replenishGapPx) &&
55
+ params.replenishGapPx > 0
56
+ ? { replenishGapPx: params.replenishGapPx }
57
+ : {}),
58
+ legs,
59
+ };
60
+ }
61
+ export function createStandaloneTpslIntentRecord(params) {
62
+ const id = randomUUID();
63
+ return {
64
+ kind: "standalone_tpsl",
65
+ id,
66
+ createdAtMs: params.nowMs,
67
+ updatedAtMs: params.nowMs,
68
+ coin: params.coin,
69
+ dex: params.dex,
70
+ side: params.side,
71
+ sz: params.sz,
72
+ triggerPx: params.triggerPx,
73
+ tpsl: params.tpsl,
74
+ isMarket: params.isMarket,
75
+ limitPx: params.limitPx,
76
+ reduceOnly: params.reduceOnly,
77
+ };
78
+ }
79
+ export function createSingleLimitIntentRecord(params) {
80
+ const id = randomUUID();
81
+ return {
82
+ kind: "single_limit",
83
+ id,
84
+ createdAtMs: params.nowMs,
85
+ updatedAtMs: params.nowMs,
86
+ coin: params.coin,
87
+ dex: params.dex,
88
+ entrySide: params.entrySide,
89
+ limitPx: params.limitPx,
90
+ sz: params.sz,
91
+ tif: params.tif,
92
+ reduceOnly: params.reduceOnly,
93
+ };
94
+ }
95
+ //# sourceMappingURL=intentFactory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intentFactory.js","sourceRoot":"","sources":["../../../src/core/state/intentFactory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { IntentRecord, TradeStateFile } from "./schema.js";
2
+ export type TaskSummary = {
3
+ id: string;
4
+ kind: IntentRecord["kind"];
5
+ coin: string;
6
+ dex?: string;
7
+ phase?: string;
8
+ summaryLine: string;
9
+ nextHints: string[];
10
+ detail?: Record<string, unknown>;
11
+ };
12
+ export declare function summarizeIntent(i: IntentRecord): TaskSummary;
13
+ export declare function formatStateList(file: TradeStateFile): {
14
+ tasks: TaskSummary[];
15
+ updatedAtMs: number;
16
+ };
17
+ //# sourceMappingURL=present.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"present.d.ts","sourceRoot":"","sources":["../../../src/core/state/present.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEhE,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC,CAAC;AAsFF,wBAAgB,eAAe,CAAC,CAAC,EAAE,YAAY,GAAG,WAAW,CAW5D;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,cAAc,GAAG;IACrD,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB,CAIA"}
@@ -0,0 +1,100 @@
1
+ function bracketLine(i) {
2
+ const d = {
3
+ entry: { side: i.entrySide, px: i.entryLimitPx, sz: i.entrySz, oid: i.entryOid ?? null },
4
+ tp: { px: i.tpTriggerPx, oid: i.tpOid ?? null },
5
+ sl: { px: i.slTriggerPx, oid: i.slOid ?? null },
6
+ };
7
+ const hints = [];
8
+ if (i.phase === "planned") {
9
+ hints.push("Place entry limit order, then reconcile.");
10
+ }
11
+ else if (i.phase === "entry_pending" || i.phase === "entry_partial") {
12
+ hints.push("Wait for entry to fill; TP/SL activate only after entry is filled.");
13
+ }
14
+ else if (i.phase === "entry_filled") {
15
+ hints.push("Place TP/SL protection pair (reduce-only by default).");
16
+ }
17
+ else if (i.phase === "protection_active") {
18
+ hints.push("Protection working; when TP or SL fills, the other side will be cancelled.");
19
+ }
20
+ return {
21
+ id: i.id,
22
+ kind: "bracket",
23
+ coin: i.coin,
24
+ dex: i.dex,
25
+ phase: i.phase,
26
+ summaryLine: `bracket ${i.coin} [${i.phase}] entry ${i.entrySide} @${i.entryLimitPx} sz=${i.entrySz}`,
27
+ nextHints: hints,
28
+ detail: d,
29
+ };
30
+ }
31
+ function gridLine(i) {
32
+ const counts = {};
33
+ for (const l of i.legs) {
34
+ counts[l.legPhase] = (counts[l.legPhase] ?? 0) + 1;
35
+ }
36
+ const hint = i.legs.every((l) => l.legPhase === "filled") ||
37
+ i.legs.every((l) => l.legPhase !== "open" && l.legPhase !== "partial")
38
+ ? "Grid legs settled or idle; review fills before re-running."
39
+ : "Run reconcile to refresh leg states from open orders.";
40
+ return {
41
+ id: i.id,
42
+ kind: "grid",
43
+ coin: i.coin,
44
+ dex: i.dex,
45
+ phase: `grid:${i.legs.filter((l) => l.legPhase === "filled").length}/${i.legs.length} filled`,
46
+ summaryLine: `grid ${i.coin} levels=${i.grids} [${Object.entries(counts)
47
+ .map(([k, v]) => `${k}=${v}`)
48
+ .join(", ")}]`,
49
+ nextHints: [hint],
50
+ detail: { legs: i.legs.length, counts },
51
+ };
52
+ }
53
+ function tpslStandaloneLine(i) {
54
+ return {
55
+ id: i.id,
56
+ kind: "standalone_tpsl",
57
+ coin: i.coin,
58
+ dex: i.dex,
59
+ phase: i.oid ? "submitted" : "planned",
60
+ summaryLine: `tpsl ${i.coin} ${i.side} ${i.tpsl} trig=${i.triggerPx} sz=${i.sz} oid=${i.oid ?? "n/a"}`,
61
+ nextHints: [
62
+ i.oid
63
+ ? "Trigger order on book; reconcile updates are optional for standalone TP/SL."
64
+ : "Dry-run / pending submission.",
65
+ ],
66
+ detail: { tpsl: i.tpsl, triggerPx: i.triggerPx, isMarket: i.isMarket },
67
+ };
68
+ }
69
+ function singleLine(i) {
70
+ return {
71
+ id: i.id,
72
+ kind: "single_limit",
73
+ coin: i.coin,
74
+ dex: i.dex,
75
+ phase: i.oid ? "live" : "planned",
76
+ summaryLine: `limit ${i.coin} ${i.entrySide} @${i.limitPx} sz=${i.sz} oid=${i.oid ?? "n/a"}`,
77
+ nextHints: i.oid
78
+ ? ["Order submitted; track via open orders / reconcile."]
79
+ : ["Dry-run or pending placement."],
80
+ detail: { oid: i.oid ?? null },
81
+ };
82
+ }
83
+ export function summarizeIntent(i) {
84
+ if (i.kind === "bracket") {
85
+ return bracketLine(i);
86
+ }
87
+ if (i.kind === "grid") {
88
+ return gridLine(i);
89
+ }
90
+ if (i.kind === "standalone_tpsl") {
91
+ return tpslStandaloneLine(i);
92
+ }
93
+ return singleLine(i);
94
+ }
95
+ export function formatStateList(file) {
96
+ const tasks = Object.values(file.intents).map(summarizeIntent);
97
+ tasks.sort((a, b) => a.id.localeCompare(b.id));
98
+ return { tasks, updatedAtMs: file.updatedAtMs };
99
+ }
100
+ //# sourceMappingURL=present.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"present.js","sourceRoot":"","sources":["../../../src/core/state/present.ts"],"names":[],"mappings":"AAaA,SAAS,WAAW,CAAC,CAA6C;IAChE,MAAM,CAAC,GAA4B;QACjC,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC,YAAY,EAAE,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,QAAQ,IAAI,IAAI,EAAE;QACxF,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,EAAE;QAC/C,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,EAAE;KAChD,CAAC;IACF,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1B,KAAK,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;IACzD,CAAC;SAAM,IAAI,CAAC,CAAC,KAAK,KAAK,eAAe,IAAI,CAAC,CAAC,KAAK,KAAK,eAAe,EAAE,CAAC;QACtE,KAAK,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAC;IACnF,CAAC;SAAM,IAAI,CAAC,CAAC,KAAK,KAAK,cAAc,EAAE,CAAC;QACtC,KAAK,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC;IACtE,CAAC;SAAM,IAAI,CAAC,CAAC,KAAK,KAAK,mBAAmB,EAAE,CAAC;QAC3C,KAAK,CAAC,IAAI,CAAC,4EAA4E,CAAC,CAAC;IAC3F,CAAC;IACD,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,GAAG,EAAE,CAAC,CAAC,GAAG;QACV,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,WAAW,EAAE,WAAW,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,YAAY,OAAO,CAAC,CAAC,OAAO,EAAE;QACrG,SAAS,EAAE,KAAK;QAChB,MAAM,EAAE,CAAC;KACV,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,CAA0C;IAC1D,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QACvB,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACrD,CAAC;IACD,MAAM,IAAI,GACR,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC;QAC5C,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC;QACpE,CAAC,CAAC,4DAA4D;QAC9D,CAAC,CAAC,uDAAuD,CAAC;IAC9D,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,GAAG,EAAE,CAAC,CAAC,GAAG;QACV,KAAK,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,SAAS;QAC7F,WAAW,EAAE,QAAQ,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;aACrE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;aAC5B,IAAI,CAAC,IAAI,CAAC,GAAG;QAChB,SAAS,EAAE,CAAC,IAAI,CAAC;QACjB,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE;KACxC,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,CAAqD;IAC/E,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,IAAI,EAAE,iBAAiB;QACvB,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,GAAG,EAAE,CAAC,CAAC,GAAG;QACV,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS;QACtC,WAAW,EAAE,QAAQ,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,SAAS,OAAO,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,IAAI,KAAK,EAAE;QACtG,SAAS,EAAE;YACT,CAAC,CAAC,GAAG;gBACH,CAAC,CAAC,6EAA6E;gBAC/E,CAAC,CAAC,+BAA+B;SACpC;QACD,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE;KACvE,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,CAAkD;IACpE,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,IAAI,EAAE,cAAc;QACpB,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,GAAG,EAAE,CAAC,CAAC,GAAG;QACV,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;QACjC,WAAW,EAAE,SAAS,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,IAAI,KAAK,EAAE;QAC5F,SAAS,EAAE,CAAC,CAAC,GAAG;YACd,CAAC,CAAC,CAAC,qDAAqD,CAAC;YACzD,CAAC,CAAC,CAAC,+BAA+B,CAAC;QACrC,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,IAAI,EAAE;KAC/B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,CAAe;IAC7C,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC;IACD,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC;IACrB,CAAC;IACD,IAAI,CAAC,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;QACjC,OAAO,kBAAkB,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAoB;IAIlD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC/D,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/C,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;AAClD,CAAC"}
@@ -0,0 +1,32 @@
1
+ import type { EffectiveConfig } from "../config.js";
2
+ import type { JsonValue } from "../hyperliquid/types.js";
3
+ export type StateCancelOpenMode = "dry" | "live";
4
+ export type StateCancelOpenWireRow = {
5
+ coin: string;
6
+ dex: string | null;
7
+ assetIndex: number;
8
+ oids: number[];
9
+ action: Record<string, unknown>;
10
+ };
11
+ export type StateCancelOpenResult = {
12
+ mode: StateCancelOpenMode;
13
+ candidatesFromState: number[];
14
+ openOidsOnExchange: number[];
15
+ willCancel: number[];
16
+ skippedNotOpen: number[];
17
+ actionsPlanned?: StateCancelOpenWireRow[];
18
+ actionsExecuted?: Array<StateCancelOpenWireRow & {
19
+ response: JsonValue;
20
+ }>;
21
+ gcRemovedIntentIds: string[];
22
+ };
23
+ export declare function runStateCancelOpen(opts: {
24
+ statePath: string;
25
+ cfg: EffectiveConfig;
26
+ mode: StateCancelOpenMode;
27
+ assumeYes: boolean;
28
+ intentFilter?: string;
29
+ confirmLive?: (prompt: string) => Promise<void>;
30
+ nowMs?: number;
31
+ }): Promise<StateCancelOpenResult>;
32
+ //# sourceMappingURL=runCancelOpen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runCancelOpen.d.ts","sourceRoot":"","sources":["../../../src/core/state/runCancelOpen.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAQpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAiCzD,MAAM,MAAM,mBAAmB,GAAG,KAAK,GAAG,MAAM,CAAC;AAEjD,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,mBAAmB,CAAC;IAC1B,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,CAAC,EAAE,sBAAsB,EAAE,CAAC;IAC1C,eAAe,CAAC,EAAE,KAAK,CAAC,sBAAsB,GAAG;QAAE,QAAQ,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAC1E,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B,CAAC;AAEF,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,eAAe,CAAC;IACrB,IAAI,EAAE,mBAAmB,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAsFjC"}
@@ -0,0 +1,101 @@
1
+ import { requireUserContext } from "../config.js";
2
+ import { ConfigError } from "../errors.js";
3
+ import { perpCoinToExchangeAssetId } from "../hyperliquid/asset.js";
4
+ import { HyperliquidInfoClient } from "../hyperliquid/client.js";
5
+ import { HyperliquidExchangeClient } from "../hyperliquid/exchange.js";
6
+ import { buildCancelOrdersAction } from "../hyperliquid/orders.js";
7
+ import { buildSignedExchangePayload } from "../hyperliquid/signed-exchange.js";
8
+ import { requireTraderWallet } from "../trading.js";
9
+ import { planStateCancelOpen } from "./cancelOpenPlan.js";
10
+ import { garbageCollectTradeState } from "./gcTradeState.js";
11
+ import { normalizeOpenOrders } from "./snapshot.js";
12
+ import { readOrCreateTradeStateFile, writeTradeStateFileAtomic } from "./store.js";
13
+ function isMainnet(cfg) {
14
+ return cfg.network === "mainnet";
15
+ }
16
+ async function resolveAssetIndex(cfg, coin, dex) {
17
+ const info = new HyperliquidInfoClient({ infoOrigin: cfg.infoOrigin });
18
+ const meta = await info.meta(dex);
19
+ const perpDexs = dex ? await info.perpDexs() : undefined;
20
+ return perpCoinToExchangeAssetId({ coin, meta, dex, perpDexs });
21
+ }
22
+ async function postSigned(cfg, wallet, action) {
23
+ const ex = new HyperliquidExchangeClient({ apiOrigin: cfg.infoOrigin });
24
+ const body = await buildSignedExchangePayload(wallet, action, { isMainnet: isMainnet(cfg) });
25
+ return ex.exchange(body);
26
+ }
27
+ export async function runStateCancelOpen(opts) {
28
+ const nowMs = opts.nowMs ?? Date.now();
29
+ const prior = await readOrCreateTradeStateFile(opts.statePath, nowMs);
30
+ const user = requireUserContext(opts.cfg);
31
+ const info = new HyperliquidInfoClient({ infoOrigin: user.infoOrigin });
32
+ let openNorm = normalizeOpenOrders(await info.openOrders(user.userAddress));
33
+ const plan = planStateCancelOpen({
34
+ state: prior,
35
+ openOrders: openNorm,
36
+ intentFilter: opts.intentFilter,
37
+ });
38
+ const buildResolvedActions = async () => {
39
+ const rows = [];
40
+ for (const g of plan.cancelGroups) {
41
+ const assetIndex = await resolveAssetIndex(opts.cfg, g.coin, g.dex);
42
+ rows.push({
43
+ coin: g.coin,
44
+ dex: g.dex ?? null,
45
+ assetIndex,
46
+ oids: g.oids,
47
+ action: buildCancelOrdersAction(assetIndex, g.oids),
48
+ });
49
+ }
50
+ return rows;
51
+ };
52
+ const base = {
53
+ candidatesFromState: plan.candidatesFromState,
54
+ openOidsOnExchange: plan.openOidsOnExchange,
55
+ willCancel: plan.willCancel,
56
+ skippedNotOpen: plan.skippedNotOpen,
57
+ };
58
+ if (opts.mode === "dry") {
59
+ const actionsPlanned = await buildResolvedActions();
60
+ const gc = garbageCollectTradeState({ state: prior, openOrders: openNorm, nowMs });
61
+ await writeTradeStateFileAtomic(opts.statePath, gc.next);
62
+ return {
63
+ mode: "dry",
64
+ ...base,
65
+ actionsPlanned,
66
+ gcRemovedIntentIds: gc.removedIntentIds,
67
+ };
68
+ }
69
+ const actionsExecuted = [];
70
+ if (plan.willCancel.length > 0) {
71
+ const planned = await buildResolvedActions();
72
+ if (!opts.assumeYes) {
73
+ if (!opts.confirmLive) {
74
+ throw new ConfigError("LIVE cancel-open requires --assume-yes or an interactive confirm hook.");
75
+ }
76
+ await opts.confirmLive("LIVE cancel-open will submit cancellations. Type YES to continue:\n");
77
+ }
78
+ const trader = requireTraderWallet(opts.cfg);
79
+ for (const row of planned) {
80
+ const resp = await postSigned(opts.cfg, trader.wallet, row.action);
81
+ actionsExecuted.push({
82
+ coin: row.coin,
83
+ dex: row.dex,
84
+ assetIndex: row.assetIndex,
85
+ oids: row.oids,
86
+ action: row.action,
87
+ response: resp,
88
+ });
89
+ }
90
+ openNorm = normalizeOpenOrders(await info.openOrders(user.userAddress));
91
+ }
92
+ const gc = garbageCollectTradeState({ state: prior, openOrders: openNorm, nowMs });
93
+ await writeTradeStateFileAtomic(opts.statePath, gc.next);
94
+ return {
95
+ mode: "live",
96
+ ...base,
97
+ actionsExecuted,
98
+ gcRemovedIntentIds: gc.removedIntentIds,
99
+ };
100
+ }
101
+ //# sourceMappingURL=runCancelOpen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runCancelOpen.js","sourceRoot":"","sources":["../../../src/core/state/runCancelOpen.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { EffectiveConfig } from "../config.js";
2
+ import { type ReconcileMode } from "./bracketReconcile.js";
3
+ import type { TradeStateFile } from "./schema.js";
4
+ import type { ReconcileAction } from "./types.js";
5
+ export type RunReconcileOptions = {
6
+ statePath: string;
7
+ cfg: EffectiveConfig;
8
+ mode: ReconcileMode;
9
+ assumeYes: boolean;
10
+ intentFilter?: string;
11
+ nowMs?: number;
12
+ confirmLive?: (prompt: string) => Promise<void>;
13
+ };
14
+ export type RunReconcileResult = {
15
+ state: TradeStateFile;
16
+ actionsExecuted: ReconcileAction[];
17
+ dryPlan: ReconcileAction[];
18
+ };
19
+ export declare function runTradeReconcile(opts: RunReconcileOptions): Promise<RunReconcileResult>;
20
+ //# sourceMappingURL=runReconcile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runReconcile.d.ts","sourceRoot":"","sources":["../../../src/core/state/runReconcile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAgBpD,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,uBAAuB,CAAC;AAQ/B,OAAO,KAAK,EAAqC,cAAc,EAAE,MAAM,aAAa,CAAC;AAGrF,OAAO,KAAK,EAAE,eAAe,EAAiB,MAAM,YAAY,CAAC;AAsCjE,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,eAAe,CAAC;IACrB,IAAI,EAAE,aAAa,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,cAAc,CAAC;IACtB,eAAe,EAAE,eAAe,EAAE,CAAC;IACnC,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B,CAAC;AAEF,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA4P9F"}
@@ -0,0 +1,248 @@
1
+ import { requireUserContext } from "../config.js";
2
+ import { ConfigError } from "../errors.js";
3
+ import { perpCoinToExchangeAssetId } from "../hyperliquid/asset.js";
4
+ import { HyperliquidInfoClient } from "../hyperliquid/client.js";
5
+ import { HyperliquidExchangeClient } from "../hyperliquid/exchange.js";
6
+ import { extractOrderOidsFromExchangeResponse } from "../hyperliquid/exchangeParse.js";
7
+ import { buildBracketProtectionOrderAction, buildCancelOrdersAction, buildPlaceOrderAction, } from "../hyperliquid/orders.js";
8
+ import { buildSignedExchangePayload } from "../hyperliquid/signed-exchange.js";
9
+ import { requireTraderWallet } from "../trading.js";
10
+ import { mergeBracketDedupe, reconcileBracketIntent, } from "./bracketReconcile.js";
11
+ import { garbageCollectTradeState } from "./gcTradeState.js";
12
+ import { applyGridCounterOrderSuccess, mergeGridReplenishDedupe, parseUserFills, reconcileGridIntent, } from "./gridReconcile.js";
13
+ import { normalizeOpenOrders, signedPositionSizeForCoin } from "./snapshot.js";
14
+ import { readOrCreateTradeStateFile, writeTradeStateFileAtomic } from "./store.js";
15
+ function isMainnet(cfg) {
16
+ return cfg.network === "mainnet";
17
+ }
18
+ function dedupeKeysForCancelEntry(intent) {
19
+ if (intent.phase === "expired") {
20
+ return ["cancel_entry_ttl"];
21
+ }
22
+ return ["cancel_entry_user"];
23
+ }
24
+ function narrowDedupeForCancelOrder(a) {
25
+ return a.reason === "tp_filled" ? `cancel_sl_after_tp:${a.oid}` : `cancel_tp_after_sl:${a.oid}`;
26
+ }
27
+ async function resolveAssetIndex(cfg, coin, dex) {
28
+ const info = new HyperliquidInfoClient({ infoOrigin: cfg.infoOrigin });
29
+ const meta = await info.meta(dex);
30
+ const perpDexs = dex ? await info.perpDexs() : undefined;
31
+ return perpCoinToExchangeAssetId({ coin, meta, dex, perpDexs });
32
+ }
33
+ async function postSigned(cfg, wallet, action) {
34
+ const ex = new HyperliquidExchangeClient({ apiOrigin: cfg.infoOrigin });
35
+ const body = await buildSignedExchangePayload(wallet, action, { isMainnet: isMainnet(cfg) });
36
+ return ex.exchange(body);
37
+ }
38
+ export async function runTradeReconcile(opts) {
39
+ const nowMs = opts.nowMs ?? Date.now();
40
+ const prior = await readOrCreateTradeStateFile(opts.statePath, nowMs);
41
+ const user = requireUserContext(opts.cfg);
42
+ const info = new HyperliquidInfoClient({ infoOrigin: user.infoOrigin });
43
+ const rawOpen = await info.openOrders(user.userAddress);
44
+ let openNorm = normalizeOpenOrders(rawOpen);
45
+ const ch = await info.clearinghouseState(user.userAddress);
46
+ const needsUserFills = Object.values(prior.intents).some((i) => i.kind === "grid");
47
+ let userFillsRaw;
48
+ if (needsUserFills) {
49
+ userFillsRaw = await info.userFills(user.userAddress);
50
+ }
51
+ const collected = [];
52
+ const dryPlan = [];
53
+ const executed = [];
54
+ const nextIntents = { ...prior.intents };
55
+ let chSnap = ch;
56
+ let liveConfirmed = false;
57
+ for (const [id, intent] of Object.entries(prior.intents)) {
58
+ if (opts.intentFilter && id !== opts.intentFilter) {
59
+ continue;
60
+ }
61
+ if (intent.kind === "grid") {
62
+ const fillRows = parseUserFills(userFillsRaw ?? null);
63
+ const r = reconcileGridIntent(intent, { nowMs, openOrders: openNorm }, { fillRows, mode: opts.mode });
64
+ collected.push(...r.events);
65
+ if (opts.mode === "dry") {
66
+ dryPlan.push(...r.actions);
67
+ nextIntents[id] = mergeGridReplenishDedupe(r.intent, r.dedupeToCommit, "dry", nowMs);
68
+ continue;
69
+ }
70
+ if (r.actions.length === 0) {
71
+ nextIntents[id] = r.intent;
72
+ continue;
73
+ }
74
+ const trader = requireTraderWallet(opts.cfg);
75
+ if (!opts.assumeYes) {
76
+ if (!opts.confirmLive) {
77
+ throw new ConfigError("LIVE reconcile requires --assume-yes or an interactive confirm hook.");
78
+ }
79
+ if (!liveConfirmed) {
80
+ await opts.confirmLive("LIVE reconcile will submit exchange actions. Type YES to continue:\n");
81
+ liveConfirmed = true;
82
+ }
83
+ }
84
+ let assetIndexCache;
85
+ let gridWorking = r.intent;
86
+ for (const act of r.actions) {
87
+ if (act.kind !== "place_grid_counter" && act.kind !== "place_grid_pending_leg") {
88
+ continue;
89
+ }
90
+ if (assetIndexCache === undefined) {
91
+ assetIndexCache = await resolveAssetIndex(opts.cfg, gridWorking.coin, gridWorking.dex);
92
+ }
93
+ const leg = gridWorking.legs[act.legIndex];
94
+ if (!leg) {
95
+ continue;
96
+ }
97
+ const action = buildPlaceOrderAction({
98
+ assetIndex: assetIndexCache,
99
+ isBuy: leg.isBuy,
100
+ limitPx: leg.px,
101
+ sz: gridWorking.orderSz,
102
+ reduceOnly: gridWorking.reduceOnly,
103
+ tif: gridWorking.tif,
104
+ });
105
+ const resp = await postSigned(opts.cfg, trader.wallet, action);
106
+ const oids = extractOrderOidsFromExchangeResponse(resp);
107
+ const placedOid = oids[0];
108
+ if (typeof placedOid !== "number" || !Number.isFinite(placedOid)) {
109
+ const label = act.kind === "place_grid_pending_leg" ? "pending grid leg" : "grid counter limit";
110
+ throw new ConfigError(`LIVE grid: exchange did not return an order id for ${label}.`);
111
+ }
112
+ gridWorking = applyGridCounterOrderSuccess(gridWorking, act.legIndex, placedOid, nowMs);
113
+ gridWorking = mergeGridReplenishDedupe(gridWorking, [act.replenishDedupeKey], "live", nowMs);
114
+ executed.push(act);
115
+ const rawOpenNext = await info.openOrders(user.userAddress);
116
+ openNorm = normalizeOpenOrders(rawOpenNext);
117
+ chSnap = await info.clearinghouseState(user.userAddress);
118
+ }
119
+ nextIntents[id] = gridWorking;
120
+ continue;
121
+ }
122
+ if (intent.kind === "single_limit" || intent.kind === "standalone_tpsl") {
123
+ continue;
124
+ }
125
+ let working = intent;
126
+ const pos = signedPositionSizeForCoin(chSnap, working.coin);
127
+ const snap = {
128
+ nowMs,
129
+ openOrders: openNorm,
130
+ positionSigned: pos,
131
+ };
132
+ const r = reconcileBracketIntent(working, snap, opts.mode);
133
+ working = r.intent;
134
+ collected.push(...r.events);
135
+ if (opts.mode === "dry") {
136
+ dryPlan.push(...r.actions);
137
+ if (r.dedupeToCommit.length > 0) {
138
+ working = mergeBracketDedupe(working, r.dedupeToCommit, "dry", nowMs);
139
+ }
140
+ nextIntents[id] = working;
141
+ continue;
142
+ }
143
+ if (r.actions.length > 0) {
144
+ const trader = requireTraderWallet(opts.cfg);
145
+ if (!opts.assumeYes) {
146
+ if (!opts.confirmLive) {
147
+ throw new ConfigError("LIVE reconcile requires --assume-yes or an interactive confirm hook.");
148
+ }
149
+ if (!liveConfirmed) {
150
+ await opts.confirmLive("LIVE reconcile will submit exchange actions. Type YES to continue:\n");
151
+ liveConfirmed = true;
152
+ }
153
+ }
154
+ let assetIndexCache;
155
+ for (const act of r.actions) {
156
+ if (assetIndexCache === undefined) {
157
+ assetIndexCache = await resolveAssetIndex(opts.cfg, working.coin, working.dex);
158
+ }
159
+ const assetIndex = assetIndexCache;
160
+ if (act.kind === "place_entry_limit") {
161
+ const action = buildPlaceOrderAction({
162
+ assetIndex,
163
+ isBuy: working.entrySide === "buy",
164
+ limitPx: working.entryLimitPx,
165
+ sz: working.entrySz,
166
+ reduceOnly: Boolean(working.entryReduceOnly),
167
+ tif: working.tif,
168
+ });
169
+ const resp = await postSigned(opts.cfg, trader.wallet, action);
170
+ const oids = extractOrderOidsFromExchangeResponse(resp);
171
+ const oid = oids[0];
172
+ if (typeof oid === "number") {
173
+ working = {
174
+ ...working,
175
+ entryOid: oid,
176
+ phase: "entry_pending",
177
+ updatedAtMs: nowMs,
178
+ };
179
+ }
180
+ executed.push(act);
181
+ working = mergeBracketDedupe(working, ["place_entry"], "live", nowMs);
182
+ }
183
+ else if (act.kind === "place_protection_pair") {
184
+ const closeIsBuy = working.entrySide === "sell";
185
+ const isMarket = working.tpslIsMarket;
186
+ const limTp = working.tpslLimitPx ?? working.tpTriggerPx;
187
+ const limSl = working.tpslLimitPx ?? working.slTriggerPx;
188
+ const action = buildBracketProtectionOrderAction({
189
+ assetIndex,
190
+ closeIsBuy,
191
+ sz: working.entrySz,
192
+ reduceOnly: working.protectionReduceOnly !== false,
193
+ tpTriggerPx: working.tpTriggerPx,
194
+ slTriggerPx: working.slTriggerPx,
195
+ isMarket,
196
+ wireLimitPxTp: limTp,
197
+ wireLimitPxSl: limSl,
198
+ });
199
+ const resp = await postSigned(opts.cfg, trader.wallet, action);
200
+ const oids = extractOrderOidsFromExchangeResponse(resp);
201
+ const tpOid = oids[0];
202
+ const slOid = oids[1];
203
+ working = {
204
+ ...working,
205
+ tpOid,
206
+ slOid,
207
+ protectionPlaced: true,
208
+ phase: "protection_active",
209
+ updatedAtMs: nowMs,
210
+ };
211
+ executed.push(act);
212
+ working = mergeBracketDedupe(working, ["place_protection"], "live", nowMs);
213
+ }
214
+ else if (act.kind === "cancel_intent_entry" || act.kind === "cancel_order") {
215
+ const cancelBody = buildCancelOrdersAction(assetIndex, [act.oid]);
216
+ await postSigned(opts.cfg, trader.wallet, cancelBody);
217
+ executed.push(act);
218
+ const keys = act.kind === "cancel_order"
219
+ ? [narrowDedupeForCancelOrder(act)]
220
+ : dedupeKeysForCancelEntry(working);
221
+ working = mergeBracketDedupe(working, keys, "live", nowMs);
222
+ }
223
+ const rawOpenNext = await info.openOrders(user.userAddress);
224
+ openNorm = normalizeOpenOrders(rawOpenNext);
225
+ chSnap = await info.clearinghouseState(user.userAddress);
226
+ }
227
+ }
228
+ nextIntents[id] = working;
229
+ }
230
+ const nextState = {
231
+ version: 1,
232
+ updatedAtMs: nowMs,
233
+ intents: nextIntents,
234
+ events: [...prior.events, ...collected],
235
+ };
236
+ const gc = garbageCollectTradeState({
237
+ state: nextState,
238
+ openOrders: openNorm,
239
+ nowMs,
240
+ });
241
+ await writeTradeStateFileAtomic(opts.statePath, gc.next);
242
+ return {
243
+ state: gc.next,
244
+ actionsExecuted: executed,
245
+ dryPlan,
246
+ };
247
+ }
248
+ //# sourceMappingURL=runReconcile.js.map