perp-cli 0.9.8 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. package/README.md +30 -25
  2. package/dist/_stderr-filter.d.ts +0 -0
  3. package/dist/_stderr-filter.js +30 -0
  4. package/dist/agent-wallet/expiry.d.ts +15 -0
  5. package/dist/agent-wallet/expiry.js +26 -0
  6. package/dist/agent-wallet/lighter-keystore.d.ts +34 -0
  7. package/dist/agent-wallet/lighter-keystore.js +232 -0
  8. package/dist/agent-wallet/passphrase.d.ts +13 -0
  9. package/dist/agent-wallet/passphrase.js +54 -0
  10. package/dist/agent-wallet/signing-strategy.d.ts +67 -0
  11. package/dist/agent-wallet/signing-strategy.js +51 -0
  12. package/dist/agent-wallet/store.d.ts +37 -0
  13. package/dist/agent-wallet/store.js +172 -0
  14. package/dist/api/public/_http.d.ts +15 -0
  15. package/dist/api/public/_http.js +24 -0
  16. package/dist/api/public/hyperliquid.js +36 -24
  17. package/dist/api/public/lighter.d.ts +7 -1
  18. package/dist/api/public/lighter.js +85 -37
  19. package/dist/api/public/pacifica.js +47 -18
  20. package/dist/bot/engine.js +23 -4
  21. package/dist/bot/presets.js +3 -3
  22. package/dist/bot/strategies/funding-arb-strategy.d.ts +0 -23
  23. package/dist/bot/strategies/funding-arb-strategy.js +41 -176
  24. package/dist/bot/strategies/funding-auto.js +2 -2
  25. package/dist/bridge-engine.js +102 -49
  26. package/dist/cli-spec.js +1 -2
  27. package/dist/commands/account.js +2 -500
  28. package/dist/commands/agent.d.ts +8 -2
  29. package/dist/commands/agent.js +1903 -366
  30. package/dist/commands/alerts.js +3 -1
  31. package/dist/commands/arb/index.js +37 -7
  32. package/dist/commands/arb-auto.js +44 -11
  33. package/dist/commands/arb.js +83 -34
  34. package/dist/commands/bot.d.ts +1 -1
  35. package/dist/commands/bot.js +20 -16
  36. package/dist/commands/bridge.d.ts +1 -1
  37. package/dist/commands/bridge.js +4 -4
  38. package/dist/commands/funds.d.ts +1 -1
  39. package/dist/commands/funds.js +18 -68
  40. package/dist/commands/jobs.d.ts +1 -1
  41. package/dist/commands/jobs.js +2 -2
  42. package/dist/commands/manage.d.ts +1 -1
  43. package/dist/commands/manage.js +12 -84
  44. package/dist/commands/plan.d.ts +1 -1
  45. package/dist/commands/plan.js +2 -2
  46. package/dist/commands/portfolio.d.ts +19 -3
  47. package/dist/commands/portfolio.js +747 -163
  48. package/dist/commands/rebalance.d.ts +1 -1
  49. package/dist/commands/rebalance.js +18 -12
  50. package/dist/commands/risk.js +2 -6
  51. package/dist/commands/settings.js +30 -53
  52. package/dist/commands/trade.js +16 -15
  53. package/dist/commands/wallet.d.ts +2 -1
  54. package/dist/commands/wallet.js +1122 -176
  55. package/dist/config.d.ts +9 -0
  56. package/dist/config.js +55 -9
  57. package/dist/errors.d.ts +64 -0
  58. package/dist/errors.js +82 -2
  59. package/dist/event-stream.js +12 -1
  60. package/dist/exchanges/aster-typed-data.d.ts +156 -0
  61. package/dist/exchanges/aster-typed-data.js +189 -0
  62. package/dist/exchanges/aster.d.ts +60 -11
  63. package/dist/exchanges/aster.js +278 -136
  64. package/dist/exchanges/hyperliquid.d.ts +14 -0
  65. package/dist/exchanges/hyperliquid.js +88 -34
  66. package/dist/exchanges/lighter-spot.js +19 -5
  67. package/dist/exchanges/lighter.d.ts +66 -0
  68. package/dist/exchanges/lighter.js +213 -31
  69. package/dist/exchanges/pacifica-typed-data.d.ts +75 -0
  70. package/dist/exchanges/pacifica-typed-data.js +74 -0
  71. package/dist/exchanges/pacifica.d.ts +29 -1
  72. package/dist/exchanges/pacifica.js +94 -6
  73. package/dist/funding/rates.js +59 -21
  74. package/dist/guardrail/contracts.d.ts +14 -0
  75. package/dist/guardrail/contracts.js +72 -0
  76. package/dist/guardrail/perp-guardrail.d.ts +21 -0
  77. package/dist/guardrail/perp-guardrail.js +145 -0
  78. package/dist/index.d.ts +1 -1
  79. package/dist/index.js +307 -362
  80. package/dist/jobs.js +3 -1
  81. package/dist/mcp-server.js +92 -88
  82. package/dist/position-history.js +47 -4
  83. package/dist/settings.d.ts +69 -3
  84. package/dist/settings.js +3 -2
  85. package/dist/signer/index.d.ts +2 -0
  86. package/dist/signer/index.js +2 -0
  87. package/dist/signer/ows-evm.d.ts +32 -0
  88. package/dist/signer/ows-evm.js +86 -0
  89. package/dist/signer/ows-loader.d.ts +2 -0
  90. package/dist/signer/ows-loader.js +6 -0
  91. package/dist/signer/ows-solana.d.ts +25 -0
  92. package/dist/signer/ows-solana.js +56 -0
  93. package/dist/smart-order.d.ts +8 -2
  94. package/dist/smart-order.js +46 -11
  95. package/dist/strategies/funding-arb.js +29 -8
  96. package/dist/trade-validator.js +30 -5
  97. package/dist/utils.d.ts +10 -0
  98. package/dist/utils.js +19 -0
  99. package/package.json +4 -2
  100. package/skills/perp-cli/SKILL.md +23 -14
  101. package/skills/perp-cli/references/agent-operations.md +6 -4
  102. package/skills/perp-cli/references/commands.md +55 -34
  103. package/skills/perp-cli/scripts/preflight.sh +4 -4
  104. package/skills/perp-cli/scripts/spot-perp-scan.sh +2 -2
  105. package/dist/__tests__/alert-logic.test.d.ts +0 -1
  106. package/dist/__tests__/alert-logic.test.js +0 -107
  107. package/dist/__tests__/arb-auto-3dex.test.d.ts +0 -1
  108. package/dist/__tests__/arb-auto-3dex.test.js +0 -397
  109. package/dist/__tests__/arb-history-stats.test.d.ts +0 -1
  110. package/dist/__tests__/arb-history-stats.test.js +0 -176
  111. package/dist/__tests__/arb-logic.test.d.ts +0 -1
  112. package/dist/__tests__/arb-logic.test.js +0 -84
  113. package/dist/__tests__/arb-manage.test.d.ts +0 -1
  114. package/dist/__tests__/arb-manage.test.js +0 -253
  115. package/dist/__tests__/arb-new-features.test.d.ts +0 -1
  116. package/dist/__tests__/arb-new-features.test.js +0 -457
  117. package/dist/__tests__/arb-sizing.test.d.ts +0 -1
  118. package/dist/__tests__/arb-sizing.test.js +0 -48
  119. package/dist/__tests__/arb-state.test.d.ts +0 -1
  120. package/dist/__tests__/arb-state.test.js +0 -284
  121. package/dist/__tests__/arb-userflow.test.d.ts +0 -1
  122. package/dist/__tests__/arb-userflow.test.js +0 -945
  123. package/dist/__tests__/arb-utils.test.d.ts +0 -1
  124. package/dist/__tests__/arb-utils.test.js +0 -264
  125. package/dist/__tests__/bot-conditions.test.d.ts +0 -1
  126. package/dist/__tests__/bot-conditions.test.js +0 -341
  127. package/dist/__tests__/client-id-tracker.test.d.ts +0 -1
  128. package/dist/__tests__/client-id-tracker.test.js +0 -137
  129. package/dist/__tests__/commands/new-atomic-commands.test.d.ts +0 -1
  130. package/dist/__tests__/commands/new-atomic-commands.test.js +0 -502
  131. package/dist/__tests__/commands/order-intent.test.d.ts +0 -1
  132. package/dist/__tests__/commands/order-intent.test.js +0 -600
  133. package/dist/__tests__/commands/trade-commands.test.d.ts +0 -1
  134. package/dist/__tests__/commands/trade-commands.test.js +0 -821
  135. package/dist/__tests__/config.test.d.ts +0 -1
  136. package/dist/__tests__/config.test.js +0 -86
  137. package/dist/__tests__/cross-chain-margin.test.d.ts +0 -1
  138. package/dist/__tests__/cross-chain-margin.test.js +0 -287
  139. package/dist/__tests__/dex-asset-map.test.d.ts +0 -1
  140. package/dist/__tests__/dex-asset-map.test.js +0 -191
  141. package/dist/__tests__/errors.test.d.ts +0 -1
  142. package/dist/__tests__/errors.test.js +0 -110
  143. package/dist/__tests__/event-stream.test.d.ts +0 -1
  144. package/dist/__tests__/event-stream.test.js +0 -276
  145. package/dist/__tests__/exchanges/interface.test.d.ts +0 -1
  146. package/dist/__tests__/exchanges/interface.test.js +0 -132
  147. package/dist/__tests__/exchanges/mock-adapter.d.ts +0 -69
  148. package/dist/__tests__/exchanges/mock-adapter.js +0 -137
  149. package/dist/__tests__/execution-log.test.d.ts +0 -1
  150. package/dist/__tests__/execution-log.test.js +0 -106
  151. package/dist/__tests__/funding-calc.test.d.ts +0 -1
  152. package/dist/__tests__/funding-calc.test.js +0 -71
  153. package/dist/__tests__/funding-history.test.d.ts +0 -1
  154. package/dist/__tests__/funding-history.test.js +0 -343
  155. package/dist/__tests__/funding-rates.test.d.ts +0 -1
  156. package/dist/__tests__/funding-rates.test.js +0 -342
  157. package/dist/__tests__/funding.test.d.ts +0 -1
  158. package/dist/__tests__/funding.test.js +0 -173
  159. package/dist/__tests__/gap-logic.test.d.ts +0 -1
  160. package/dist/__tests__/gap-logic.test.js +0 -43
  161. package/dist/__tests__/hip3-dex.test.d.ts +0 -1
  162. package/dist/__tests__/hip3-dex.test.js +0 -234
  163. package/dist/__tests__/integration/agent-features.integration.test.d.ts +0 -1
  164. package/dist/__tests__/integration/agent-features.integration.test.js +0 -553
  165. package/dist/__tests__/integration/atomic-commands.integration.test.d.ts +0 -13
  166. package/dist/__tests__/integration/atomic-commands.integration.test.js +0 -246
  167. package/dist/__tests__/integration/bridge-simulation.integration.test.d.ts +0 -1
  168. package/dist/__tests__/integration/bridge-simulation.integration.test.js +0 -453
  169. package/dist/__tests__/integration/bridge-strict.integration.test.d.ts +0 -1
  170. package/dist/__tests__/integration/bridge-strict.integration.test.js +0 -812
  171. package/dist/__tests__/integration/bridge.integration.test.d.ts +0 -1
  172. package/dist/__tests__/integration/bridge.integration.test.js +0 -309
  173. package/dist/__tests__/integration/cli-e2e.integration.test.d.ts +0 -1
  174. package/dist/__tests__/integration/cli-e2e.integration.test.js +0 -202
  175. package/dist/__tests__/integration/dex-arb.integration.test.d.ts +0 -1
  176. package/dist/__tests__/integration/dex-arb.integration.test.js +0 -116
  177. package/dist/__tests__/integration/envelope-consistency.integration.test.d.ts +0 -13
  178. package/dist/__tests__/integration/envelope-consistency.integration.test.js +0 -205
  179. package/dist/__tests__/integration/hip3-dex.integration.test.d.ts +0 -1
  180. package/dist/__tests__/integration/hip3-dex.integration.test.js +0 -147
  181. package/dist/__tests__/integration/hyperliquid.integration.test.d.ts +0 -1
  182. package/dist/__tests__/integration/hyperliquid.integration.test.js +0 -79
  183. package/dist/__tests__/integration/lighter.integration.test.d.ts +0 -1
  184. package/dist/__tests__/integration/lighter.integration.test.js +0 -53
  185. package/dist/__tests__/integration/new-commands-e2e.integration.test.d.ts +0 -9
  186. package/dist/__tests__/integration/new-commands-e2e.integration.test.js +0 -236
  187. package/dist/__tests__/integration/order-verification.integration.test.d.ts +0 -1
  188. package/dist/__tests__/integration/order-verification.integration.test.js +0 -321
  189. package/dist/__tests__/integration/pacifica.integration.test.d.ts +0 -1
  190. package/dist/__tests__/integration/pacifica.integration.test.js +0 -75
  191. package/dist/__tests__/integration/response-shapes.integration.test.d.ts +0 -1
  192. package/dist/__tests__/integration/response-shapes.integration.test.js +0 -278
  193. package/dist/__tests__/liquidity.test.d.ts +0 -1
  194. package/dist/__tests__/liquidity.test.js +0 -225
  195. package/dist/__tests__/plan-executor.test.d.ts +0 -1
  196. package/dist/__tests__/plan-executor.test.js +0 -314
  197. package/dist/__tests__/position-history.test.d.ts +0 -1
  198. package/dist/__tests__/position-history.test.js +0 -367
  199. package/dist/__tests__/retry.test.d.ts +0 -1
  200. package/dist/__tests__/retry.test.js +0 -310
  201. package/dist/__tests__/risk-assessment.test.d.ts +0 -1
  202. package/dist/__tests__/risk-assessment.test.js +0 -288
  203. package/dist/__tests__/security-adversarial.test.d.ts +0 -1
  204. package/dist/__tests__/security-adversarial.test.js +0 -574
  205. package/dist/__tests__/strategies.test.d.ts +0 -1
  206. package/dist/__tests__/strategies.test.js +0 -539
  207. package/dist/__tests__/trade-execution.test.d.ts +0 -1
  208. package/dist/__tests__/trade-execution.test.js +0 -129
  209. package/dist/__tests__/trade-validator.test.d.ts +0 -1
  210. package/dist/__tests__/trade-validator.test.js +0 -655
  211. package/dist/__tests__/utils.test.d.ts +0 -1
  212. package/dist/__tests__/utils.test.js +0 -76
  213. package/dist/arb/reconcile.d.ts +0 -28
  214. package/dist/arb/reconcile.js +0 -162
  215. package/dist/commands/alert.d.ts +0 -2
  216. package/dist/commands/alert.js +0 -421
  217. package/dist/commands/analytics.d.ts +0 -3
  218. package/dist/commands/analytics.js +0 -311
  219. package/dist/commands/arb-manage.d.ts +0 -5
  220. package/dist/commands/arb-manage.js +0 -5
  221. package/dist/commands/dashboard.d.ts +0 -3
  222. package/dist/commands/dashboard.js +0 -176
  223. package/dist/commands/deposit.d.ts +0 -4
  224. package/dist/commands/deposit.js +0 -573
  225. package/dist/commands/dex.d.ts +0 -3
  226. package/dist/commands/dex.js +0 -120
  227. package/dist/commands/env.d.ts +0 -2
  228. package/dist/commands/env.js +0 -136
  229. package/dist/commands/funding.d.ts +0 -3
  230. package/dist/commands/funding.js +0 -554
  231. package/dist/commands/gap.d.ts +0 -2
  232. package/dist/commands/gap.js +0 -305
  233. package/dist/commands/health.d.ts +0 -2
  234. package/dist/commands/health.js +0 -67
  235. package/dist/commands/multileg.d.ts +0 -16
  236. package/dist/commands/multileg.js +0 -174
  237. package/dist/commands/pnl.d.ts +0 -12
  238. package/dist/commands/pnl.js +0 -243
  239. package/dist/commands/run.d.ts +0 -3
  240. package/dist/commands/run.js +0 -202
  241. package/dist/commands/stream.d.ts +0 -5
  242. package/dist/commands/stream.js +0 -200
  243. package/dist/commands/withdraw.d.ts +0 -3
  244. package/dist/commands/withdraw.js +0 -187
  245. package/dist/exchanges/edgex.d.ts +0 -62
  246. package/dist/exchanges/edgex.js +0 -552
  247. package/dist/exchanges/nado.d.ts +0 -52
  248. package/dist/exchanges/nado.js +0 -223
  249. package/dist/funding/index.d.ts +0 -3
  250. package/dist/funding/index.js +0 -3
  251. package/dist/retry.d.ts +0 -74
  252. package/dist/retry.js +0 -129
  253. package/dist/ws/market-feed.d.ts +0 -74
  254. package/dist/ws/market-feed.js +0 -227
@@ -1,234 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- /**
3
- * Unit tests for HIP-3 deployed perp dex support.
4
- *
5
- * Tests the parsing logic for allPerpMetas, dex-specific meta/markets,
6
- * and the dex getter/setter behavior — all without real API calls.
7
- */
8
- // ── Mock data matching real Hyperliquid API responses ──
9
- const MOCK_ALL_PERP_METAS = [
10
- // Entry 0: native/validator perps
11
- {
12
- universe: [
13
- { name: "BTC", szDecimals: 5, maxLeverage: 40 },
14
- { name: "ETH", szDecimals: 4, maxLeverage: 25 },
15
- { name: "SOL", szDecimals: 2, maxLeverage: 20 },
16
- ],
17
- marginTables: [],
18
- collateralToken: 0,
19
- },
20
- // Entry 1: "xyz" dex
21
- {
22
- universe: [
23
- { name: "xyz:XYZ100", szDecimals: 4, maxLeverage: 30 },
24
- { name: "xyz:TSLA", szDecimals: 3, maxLeverage: 10 },
25
- { name: "xyz:NVDA", szDecimals: 3, maxLeverage: 20 },
26
- { name: "xyz:GOLD", szDecimals: 3, maxLeverage: 10 },
27
- ],
28
- marginTables: [],
29
- collateralToken: 0,
30
- },
31
- // Entry 2: "vntl" dex
32
- {
33
- universe: [
34
- { name: "vntl:SPACEX", szDecimals: 2, maxLeverage: 5 },
35
- { name: "vntl:OPENAI", szDecimals: 2, maxLeverage: 5 },
36
- { name: "vntl:ANTHROPIC", szDecimals: 2, maxLeverage: 5 },
37
- ],
38
- marginTables: [],
39
- collateralToken: 360,
40
- },
41
- // Entry 3: empty dex (edge case)
42
- {
43
- universe: [],
44
- marginTables: [],
45
- collateralToken: 0,
46
- },
47
- ];
48
- const MOCK_DEX_META = {
49
- universe: [
50
- { name: "xyz:TSLA", szDecimals: 3, maxLeverage: 10 },
51
- { name: "xyz:NVDA", szDecimals: 3, maxLeverage: 20 },
52
- ],
53
- };
54
- const MOCK_DEX_CTXS = [
55
- { markPx: "392.26", funding: "-0.0000239162", openInterest: "39985.292", dayNtlVlm: "3054400.08", oraclePx: "392.00" },
56
- { markPx: "175.94", funding: "-0.0000094967", openInterest: "392790.598", dayNtlVlm: "38782380.60", oraclePx: "176.00" },
57
- ];
58
- const MOCK_DEX_CLEARINGHOUSE = {
59
- marginSummary: { accountValue: "1000.00", totalMarginUsed: "200.00" },
60
- crossMarginSummary: { accountValue: "1000.00", totalMarginUsed: "200.00" },
61
- withdrawable: "800.00",
62
- assetPositions: [
63
- {
64
- position: {
65
- coin: "xyz:TSLA",
66
- szi: "5.0",
67
- entryPx: "380.00",
68
- positionValue: "1961.30",
69
- liquidationPx: "350.00",
70
- unrealizedPnl: "61.30",
71
- leverage: { value: 2 },
72
- },
73
- },
74
- {
75
- position: {
76
- coin: "xyz:NVDA",
77
- szi: "-10.0",
78
- entryPx: "180.00",
79
- positionValue: "1759.40",
80
- liquidationPx: "210.00",
81
- unrealizedPnl: "40.60",
82
- leverage: { value: 3 },
83
- },
84
- },
85
- ],
86
- };
87
- // ── Tests ──
88
- describe("HIP-3 Deployed Perps — listDeployedDexes parsing", () => {
89
- it("extracts dex names from asset prefixes, skipping native perps", () => {
90
- // Simulate the parsing logic from listDeployedDexes
91
- const allMetas = MOCK_ALL_PERP_METAS;
92
- const dexes = [];
93
- for (let i = 1; i < allMetas.length; i++) {
94
- const meta = allMetas[i];
95
- const universe = meta.universe ?? [];
96
- if (universe.length === 0)
97
- continue;
98
- const firstAsset = universe[0].name;
99
- const colonIdx = firstAsset.indexOf(":");
100
- const dexName = colonIdx > 0 ? firstAsset.slice(0, colonIdx) : `dex-${i}`;
101
- dexes.push({
102
- name: dexName,
103
- assets: universe.map((a) => a.name),
104
- });
105
- }
106
- expect(dexes).toHaveLength(2); // xyz, vntl (empty one skipped)
107
- expect(dexes[0].name).toBe("xyz");
108
- expect(dexes[0].assets).toEqual(["xyz:XYZ100", "xyz:TSLA", "xyz:NVDA", "xyz:GOLD"]);
109
- expect(dexes[1].name).toBe("vntl");
110
- expect(dexes[1].assets).toContain("vntl:SPACEX");
111
- expect(dexes[1].assets).toContain("vntl:ANTHROPIC");
112
- });
113
- it("skips entries with empty universe", () => {
114
- const allMetas = MOCK_ALL_PERP_METAS;
115
- const nonEmpty = allMetas.slice(1).filter((m) => m.universe.length > 0);
116
- expect(nonEmpty).toHaveLength(2);
117
- });
118
- it("handles response with only native perps", () => {
119
- const onlyNative = [MOCK_ALL_PERP_METAS[0]];
120
- const dexes = [];
121
- for (let i = 1; i < onlyNative.length; i++) {
122
- dexes.push("should-not-reach");
123
- }
124
- expect(dexes).toHaveLength(0);
125
- });
126
- });
127
- describe("HIP-3 Deployed Perps — dex-specific market parsing", () => {
128
- it("parses metaAndAssetCtxs with dex param correctly", () => {
129
- const universe = MOCK_DEX_META.universe;
130
- const ctxs = MOCK_DEX_CTXS;
131
- const markets = universe.map((asset, i) => {
132
- const ctx = ctxs[i] ?? {};
133
- return {
134
- symbol: asset.name,
135
- markPrice: String(ctx.markPx ?? "0"),
136
- indexPrice: String(ctx.oraclePx ?? "0"),
137
- fundingRate: String(ctx.funding ?? "0"),
138
- volume24h: String(ctx.dayNtlVlm ?? "0"),
139
- openInterest: String(ctx.openInterest ?? "0"),
140
- maxLeverage: Number(asset.maxLeverage ?? 50),
141
- };
142
- });
143
- expect(markets).toHaveLength(2);
144
- expect(markets[0].symbol).toBe("xyz:TSLA");
145
- expect(markets[0].markPrice).toBe("392.26");
146
- expect(markets[0].fundingRate).toBe("-0.0000239162");
147
- expect(markets[0].maxLeverage).toBe(10);
148
- expect(markets[1].symbol).toBe("xyz:NVDA");
149
- expect(Number(markets[1].volume24h)).toBeGreaterThan(1_000_000);
150
- expect(markets[1].maxLeverage).toBe(20);
151
- });
152
- it("asset map is built from dex universe", () => {
153
- const assetMap = new Map();
154
- MOCK_DEX_META.universe.forEach((asset, idx) => {
155
- assetMap.set(asset.name, idx);
156
- });
157
- expect(assetMap.get("xyz:TSLA")).toBe(0);
158
- expect(assetMap.get("xyz:NVDA")).toBe(1);
159
- expect(assetMap.get("BTC")).toBeUndefined(); // native asset not in dex
160
- });
161
- });
162
- describe("HIP-3 Deployed Perps — dex-specific balance/positions parsing", () => {
163
- it("parses clearinghouseState with dex param", () => {
164
- const s = MOCK_DEX_CLEARINGHOUSE;
165
- const margin = s.marginSummary ?? {};
166
- const cross = s.crossMarginSummary ?? {};
167
- const equity = Number(margin.accountValue ?? cross.accountValue ?? 0);
168
- const available = Number(s.withdrawable ?? 0);
169
- const marginUsed = Number(margin.totalMarginUsed ?? cross.totalMarginUsed ?? 0);
170
- expect(equity).toBe(1000);
171
- expect(available).toBe(800);
172
- expect(marginUsed).toBe(200);
173
- });
174
- it("parses dex positions with prefixed coin names", () => {
175
- const positions = MOCK_DEX_CLEARINGHOUSE.assetPositions
176
- .filter((p) => Number(p.position.szi) !== 0)
177
- .map((p) => {
178
- const pos = p.position;
179
- const szi = Number(pos.szi);
180
- return {
181
- symbol: pos.coin,
182
- side: szi > 0 ? "long" : "short",
183
- size: String(Math.abs(szi)),
184
- entryPrice: pos.entryPx,
185
- unrealizedPnl: pos.unrealizedPnl,
186
- };
187
- });
188
- expect(positions).toHaveLength(2);
189
- expect(positions[0].symbol).toBe("xyz:TSLA");
190
- expect(positions[0].side).toBe("long");
191
- expect(positions[0].size).toBe("5");
192
- expect(positions[1].symbol).toBe("xyz:NVDA");
193
- expect(positions[1].side).toBe("short");
194
- expect(positions[1].size).toBe("10");
195
- });
196
- });
197
- describe("HIP-3 Deployed Perps — setDex behavior", () => {
198
- it("setDex clears asset map and sets dex name", () => {
199
- const assetMap = new Map();
200
- assetMap.set("BTC", 0);
201
- assetMap.set("ETH", 1);
202
- let dex = "";
203
- // Simulate setDex("xyz")
204
- dex = "xyz";
205
- assetMap.clear();
206
- expect(dex).toBe("xyz");
207
- expect(assetMap.size).toBe(0);
208
- });
209
- it("empty dex string means native perps", () => {
210
- let dex = "xyz";
211
- dex = "";
212
- expect(dex).toBeFalsy();
213
- expect(!dex).toBe(true); // Used as condition: if (this._dex) { ... }
214
- });
215
- });
216
- describe("HIP-3 — dex name extraction edge cases", () => {
217
- it("handles single-char prefix", () => {
218
- const name = "a:BTC";
219
- const prefix = name.slice(0, name.indexOf(":"));
220
- expect(prefix).toBe("a");
221
- });
222
- it("handles no colon (fallback to dex-N)", () => {
223
- const name = "UNKNOWN";
224
- const colonIdx = name.indexOf(":");
225
- const dexName = colonIdx > 0 ? name.slice(0, colonIdx) : "dex-1";
226
- expect(dexName).toBe("dex-1");
227
- });
228
- it("handles multiple colons (takes first)", () => {
229
- const name = "abc:def:GHI";
230
- const colonIdx = name.indexOf(":");
231
- const dexName = name.slice(0, colonIdx);
232
- expect(dexName).toBe("abc");
233
- });
234
- });