@raintree-technology/perps 0.1.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 (316) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/LICENSE +21 -0
  3. package/README.md +175 -0
  4. package/dist/adapters/aevo.d.ts +64 -0
  5. package/dist/adapters/aevo.js +899 -0
  6. package/dist/adapters/certification.d.ts +33 -0
  7. package/dist/adapters/certification.js +99 -0
  8. package/dist/adapters/decibel/order-manager.d.ts +45 -0
  9. package/dist/adapters/decibel/order-manager.js +140 -0
  10. package/dist/adapters/decibel/rest-client.d.ts +176 -0
  11. package/dist/adapters/decibel/rest-client.js +155 -0
  12. package/dist/adapters/decibel/ws-feed.d.ts +28 -0
  13. package/dist/adapters/decibel/ws-feed.js +166 -0
  14. package/dist/adapters/decibel.d.ts +108 -0
  15. package/dist/adapters/decibel.js +1377 -0
  16. package/dist/adapters/hyperliquid.d.ts +63 -0
  17. package/dist/adapters/hyperliquid.js +797 -0
  18. package/dist/adapters/index.d.ts +11 -0
  19. package/dist/adapters/index.js +12 -0
  20. package/dist/adapters/interface.d.ts +310 -0
  21. package/dist/adapters/interface.js +15 -0
  22. package/dist/adapters/orderly.d.ts +70 -0
  23. package/dist/adapters/orderly.js +936 -0
  24. package/dist/adapters/paradex.d.ts +69 -0
  25. package/dist/adapters/paradex.js +862 -0
  26. package/dist/adapters/utils.d.ts +17 -0
  27. package/dist/adapters/utils.js +122 -0
  28. package/dist/cli/command-metadata.d.ts +2 -0
  29. package/dist/cli/command-metadata.js +44 -0
  30. package/dist/cli/context.d.ts +14 -0
  31. package/dist/cli/context.js +59 -0
  32. package/dist/cli/experience.d.ts +48 -0
  33. package/dist/cli/experience.js +243 -0
  34. package/dist/cli/ink/app/AppShell.d.ts +12 -0
  35. package/dist/cli/ink/app/AppShell.js +32 -0
  36. package/dist/cli/ink/app/MetricStrip.d.ts +6 -0
  37. package/dist/cli/ink/app/MetricStrip.js +14 -0
  38. package/dist/cli/ink/app/Panel.d.ts +9 -0
  39. package/dist/cli/ink/app/Panel.js +7 -0
  40. package/dist/cli/ink/app/ascii.d.ts +2 -0
  41. package/dist/cli/ink/app/ascii.js +46 -0
  42. package/dist/cli/ink/app/index.d.ts +5 -0
  43. package/dist/cli/ink/app/index.js +4 -0
  44. package/dist/cli/ink/app/types.d.ts +15 -0
  45. package/dist/cli/ink/app/types.js +1 -0
  46. package/dist/cli/ink/components/PnL.d.ts +12 -0
  47. package/dist/cli/ink/components/PnL.js +23 -0
  48. package/dist/cli/ink/components/Spinner.d.ts +13 -0
  49. package/dist/cli/ink/components/Spinner.js +13 -0
  50. package/dist/cli/ink/components/Table.d.ts +14 -0
  51. package/dist/cli/ink/components/Table.js +42 -0
  52. package/dist/cli/ink/components/WatchHeader.d.ts +10 -0
  53. package/dist/cli/ink/components/WatchHeader.js +18 -0
  54. package/dist/cli/ink/components/index.d.ts +4 -0
  55. package/dist/cli/ink/components/index.js +4 -0
  56. package/dist/cli/ink/index.d.ts +4 -0
  57. package/dist/cli/ink/index.js +4 -0
  58. package/dist/cli/ink/render.d.ts +12 -0
  59. package/dist/cli/ink/render.js +21 -0
  60. package/dist/cli/ink/theme.d.ts +29 -0
  61. package/dist/cli/ink/theme.js +40 -0
  62. package/dist/cli/network-defaults.d.ts +10 -0
  63. package/dist/cli/network-defaults.js +35 -0
  64. package/dist/cli/output.d.ts +11 -0
  65. package/dist/cli/output.js +115 -0
  66. package/dist/cli/program.d.ts +18 -0
  67. package/dist/cli/program.js +164 -0
  68. package/dist/cli/watch.d.ts +19 -0
  69. package/dist/cli/watch.js +35 -0
  70. package/dist/client/index.d.ts +55 -0
  71. package/dist/client/index.js +157 -0
  72. package/dist/commands/account/add.d.ts +2 -0
  73. package/dist/commands/account/add.js +510 -0
  74. package/dist/commands/account/balances-simple.d.ts +5 -0
  75. package/dist/commands/account/balances-simple.js +63 -0
  76. package/dist/commands/account/index.d.ts +2 -0
  77. package/dist/commands/account/index.js +17 -0
  78. package/dist/commands/account/ls.d.ts +2 -0
  79. package/dist/commands/account/ls.js +95 -0
  80. package/dist/commands/account/positions-simple.d.ts +5 -0
  81. package/dist/commands/account/positions-simple.js +77 -0
  82. package/dist/commands/account/remove.d.ts +2 -0
  83. package/dist/commands/account/remove.js +47 -0
  84. package/dist/commands/account/set-default.d.ts +2 -0
  85. package/dist/commands/account/set-default.js +47 -0
  86. package/dist/commands/agent/index.d.ts +2 -0
  87. package/dist/commands/agent/index.js +126 -0
  88. package/dist/commands/arb/alert.d.ts +6 -0
  89. package/dist/commands/arb/alert.js +88 -0
  90. package/dist/commands/arb/basis-execute.d.ts +6 -0
  91. package/dist/commands/arb/basis-execute.js +332 -0
  92. package/dist/commands/arb/basis.d.ts +6 -0
  93. package/dist/commands/arb/basis.js +181 -0
  94. package/dist/commands/arb/compare.d.ts +6 -0
  95. package/dist/commands/arb/compare.js +216 -0
  96. package/dist/commands/arb/execute.d.ts +6 -0
  97. package/dist/commands/arb/execute.js +467 -0
  98. package/dist/commands/arb/funding.d.ts +6 -0
  99. package/dist/commands/arb/funding.js +201 -0
  100. package/dist/commands/arb/history.d.ts +6 -0
  101. package/dist/commands/arb/history.js +153 -0
  102. package/dist/commands/arb/index.d.ts +6 -0
  103. package/dist/commands/arb/index.js +29 -0
  104. package/dist/commands/arb/positions.d.ts +6 -0
  105. package/dist/commands/arb/positions.js +158 -0
  106. package/dist/commands/arb/spread.d.ts +6 -0
  107. package/dist/commands/arb/spread.js +253 -0
  108. package/dist/commands/arb/track.d.ts +6 -0
  109. package/dist/commands/arb/track.js +259 -0
  110. package/dist/commands/asset/book-simple.d.ts +5 -0
  111. package/dist/commands/asset/book-simple.js +77 -0
  112. package/dist/commands/asset/index.d.ts +2 -0
  113. package/dist/commands/asset/index.js +5 -0
  114. package/dist/commands/completion.d.ts +2 -0
  115. package/dist/commands/completion.js +161 -0
  116. package/dist/commands/config/index.d.ts +5 -0
  117. package/dist/commands/config/index.js +109 -0
  118. package/dist/commands/data/index.d.ts +31 -0
  119. package/dist/commands/data/index.js +1466 -0
  120. package/dist/commands/doctor.d.ts +2 -0
  121. package/dist/commands/doctor.js +201 -0
  122. package/dist/commands/exchange/index.d.ts +2 -0
  123. package/dist/commands/exchange/index.js +107 -0
  124. package/dist/commands/index.d.ts +2 -0
  125. package/dist/commands/index.js +48 -0
  126. package/dist/commands/markets/index.d.ts +2 -0
  127. package/dist/commands/markets/index.js +5 -0
  128. package/dist/commands/markets/ls-simple.d.ts +7 -0
  129. package/dist/commands/markets/ls-simple.js +277 -0
  130. package/dist/commands/operator/index.d.ts +2 -0
  131. package/dist/commands/operator/index.js +146 -0
  132. package/dist/commands/order/cancel-simple.d.ts +5 -0
  133. package/dist/commands/order/cancel-simple.js +104 -0
  134. package/dist/commands/order/index.d.ts +2 -0
  135. package/dist/commands/order/index.js +13 -0
  136. package/dist/commands/order/limit-simple.d.ts +5 -0
  137. package/dist/commands/order/limit-simple.js +195 -0
  138. package/dist/commands/order/market-simple.d.ts +5 -0
  139. package/dist/commands/order/market-simple.js +190 -0
  140. package/dist/commands/order/shared.d.ts +17 -0
  141. package/dist/commands/order/shared.js +51 -0
  142. package/dist/commands/order/trigger-simple.d.ts +5 -0
  143. package/dist/commands/order/trigger-simple.js +246 -0
  144. package/dist/commands/referral/index.d.ts +2 -0
  145. package/dist/commands/referral/index.js +7 -0
  146. package/dist/commands/referral/set.d.ts +2 -0
  147. package/dist/commands/referral/set.js +26 -0
  148. package/dist/commands/referral/status.d.ts +2 -0
  149. package/dist/commands/referral/status.js +31 -0
  150. package/dist/commands/replay/index.d.ts +2 -0
  151. package/dist/commands/replay/index.js +152 -0
  152. package/dist/commands/risk/analytics.d.ts +2 -0
  153. package/dist/commands/risk/analytics.js +64 -0
  154. package/dist/commands/risk/audit.d.ts +2 -0
  155. package/dist/commands/risk/audit.js +52 -0
  156. package/dist/commands/risk/index.d.ts +2 -0
  157. package/dist/commands/risk/index.js +9 -0
  158. package/dist/commands/risk/rules.d.ts +2 -0
  159. package/dist/commands/risk/rules.js +102 -0
  160. package/dist/commands/server.d.ts +2 -0
  161. package/dist/commands/server.js +208 -0
  162. package/dist/commands/setup/index.d.ts +2 -0
  163. package/dist/commands/setup/index.js +478 -0
  164. package/dist/commands/signal/index.d.ts +2 -0
  165. package/dist/commands/signal/index.js +129 -0
  166. package/dist/commands/state/index.d.ts +2 -0
  167. package/dist/commands/state/index.js +5 -0
  168. package/dist/commands/state/show.d.ts +2 -0
  169. package/dist/commands/state/show.js +105 -0
  170. package/dist/commands/strategy/index.d.ts +4 -0
  171. package/dist/commands/strategy/index.js +73 -0
  172. package/dist/commands/traces/index.d.ts +2 -0
  173. package/dist/commands/traces/index.js +76 -0
  174. package/dist/commands/ui/demo.d.ts +9 -0
  175. package/dist/commands/ui/demo.js +195 -0
  176. package/dist/commands/ui/index.d.ts +2 -0
  177. package/dist/commands/ui/index.js +7 -0
  178. package/dist/commands/ui/terminal.d.ts +2 -0
  179. package/dist/commands/ui/terminal.js +255 -0
  180. package/dist/commands/upgrade.d.ts +2 -0
  181. package/dist/commands/upgrade.js +98 -0
  182. package/dist/index.d.ts +2 -0
  183. package/dist/index.js +4 -0
  184. package/dist/lib/agent/audit.d.ts +12 -0
  185. package/dist/lib/agent/audit.js +13 -0
  186. package/dist/lib/agent/gateway.d.ts +13 -0
  187. package/dist/lib/agent/gateway.js +598 -0
  188. package/dist/lib/agent/metrics.d.ts +33 -0
  189. package/dist/lib/agent/metrics.js +175 -0
  190. package/dist/lib/agent/signature.d.ts +8 -0
  191. package/dist/lib/agent/signature.js +28 -0
  192. package/dist/lib/agent/tools.d.ts +28 -0
  193. package/dist/lib/agent/tools.js +453 -0
  194. package/dist/lib/agent/x402.d.ts +23 -0
  195. package/dist/lib/agent/x402.js +62 -0
  196. package/dist/lib/api-wallet.d.ts +69 -0
  197. package/dist/lib/api-wallet.js +101 -0
  198. package/dist/lib/balance-watcher.d.ts +25 -0
  199. package/dist/lib/balance-watcher.js +83 -0
  200. package/dist/lib/book-watcher.d.ts +25 -0
  201. package/dist/lib/book-watcher.js +48 -0
  202. package/dist/lib/config.d.ts +88 -0
  203. package/dist/lib/config.js +427 -0
  204. package/dist/lib/constants.d.ts +50 -0
  205. package/dist/lib/constants.js +84 -0
  206. package/dist/lib/contracts.d.ts +7 -0
  207. package/dist/lib/contracts.js +8 -0
  208. package/dist/lib/credential-vault.d.ts +22 -0
  209. package/dist/lib/credential-vault.js +109 -0
  210. package/dist/lib/db/accounts.d.ts +83 -0
  211. package/dist/lib/db/accounts.js +203 -0
  212. package/dist/lib/db/funding-history.d.ts +69 -0
  213. package/dist/lib/db/funding-history.js +183 -0
  214. package/dist/lib/db/index.d.ts +11 -0
  215. package/dist/lib/db/index.js +272 -0
  216. package/dist/lib/events/bus.d.ts +10 -0
  217. package/dist/lib/events/bus.js +17 -0
  218. package/dist/lib/events/types.d.ts +51 -0
  219. package/dist/lib/events/types.js +1 -0
  220. package/dist/lib/exchange.d.ts +30 -0
  221. package/dist/lib/exchange.js +84 -0
  222. package/dist/lib/execution/journal.d.ts +25 -0
  223. package/dist/lib/execution/journal.js +158 -0
  224. package/dist/lib/execution/safety.d.ts +34 -0
  225. package/dist/lib/execution/safety.js +197 -0
  226. package/dist/lib/exit-codes.d.ts +18 -0
  227. package/dist/lib/exit-codes.js +60 -0
  228. package/dist/lib/fetch.d.ts +18 -0
  229. package/dist/lib/fetch.js +66 -0
  230. package/dist/lib/fs-security.d.ts +10 -0
  231. package/dist/lib/fs-security.js +26 -0
  232. package/dist/lib/funding-tracker.d.ts +40 -0
  233. package/dist/lib/funding-tracker.js +118 -0
  234. package/dist/lib/logger.d.ts +27 -0
  235. package/dist/lib/logger.js +82 -0
  236. package/dist/lib/network-model.d.ts +13 -0
  237. package/dist/lib/network-model.js +30 -0
  238. package/dist/lib/onboarding.d.ts +133 -0
  239. package/dist/lib/onboarding.js +1459 -0
  240. package/dist/lib/operator-state.d.ts +25 -0
  241. package/dist/lib/operator-state.js +82 -0
  242. package/dist/lib/orders-watcher.d.ts +24 -0
  243. package/dist/lib/orders-watcher.js +74 -0
  244. package/dist/lib/paths.d.ts +20 -0
  245. package/dist/lib/paths.js +23 -0
  246. package/dist/lib/portfolio-watcher.d.ts +33 -0
  247. package/dist/lib/portfolio-watcher.js +95 -0
  248. package/dist/lib/position-watcher.d.ts +16 -0
  249. package/dist/lib/position-watcher.js +44 -0
  250. package/dist/lib/price-watcher.d.ts +15 -0
  251. package/dist/lib/price-watcher.js +84 -0
  252. package/dist/lib/prompts.d.ts +32 -0
  253. package/dist/lib/prompts.js +105 -0
  254. package/dist/lib/rate-limit.d.ts +32 -0
  255. package/dist/lib/rate-limit.js +88 -0
  256. package/dist/lib/risk/analytics.d.ts +39 -0
  257. package/dist/lib/risk/analytics.js +98 -0
  258. package/dist/lib/risk/drawdown.d.ts +18 -0
  259. package/dist/lib/risk/drawdown.js +49 -0
  260. package/dist/lib/risk/evaluation-log.d.ts +29 -0
  261. package/dist/lib/risk/evaluation-log.js +61 -0
  262. package/dist/lib/risk/index.d.ts +4 -0
  263. package/dist/lib/risk/index.js +4 -0
  264. package/dist/lib/risk/limits.d.ts +23 -0
  265. package/dist/lib/risk/limits.js +27 -0
  266. package/dist/lib/risk/manager.d.ts +32 -0
  267. package/dist/lib/risk/manager.js +85 -0
  268. package/dist/lib/risk/policy-middleware.d.ts +33 -0
  269. package/dist/lib/risk/policy-middleware.js +267 -0
  270. package/dist/lib/risk/position-sizer.d.ts +9 -0
  271. package/dist/lib/risk/position-sizer.js +14 -0
  272. package/dist/lib/risk/rules-store.d.ts +16 -0
  273. package/dist/lib/risk/rules-store.js +47 -0
  274. package/dist/lib/schema.d.ts +254 -0
  275. package/dist/lib/schema.js +199 -0
  276. package/dist/lib/secrets.d.ts +3 -0
  277. package/dist/lib/secrets.js +62 -0
  278. package/dist/lib/settings.d.ts +24 -0
  279. package/dist/lib/settings.js +86 -0
  280. package/dist/lib/signals.d.ts +73 -0
  281. package/dist/lib/signals.js +136 -0
  282. package/dist/lib/stable-stringify.d.ts +6 -0
  283. package/dist/lib/stable-stringify.js +17 -0
  284. package/dist/lib/state-context.d.ts +44 -0
  285. package/dist/lib/state-context.js +133 -0
  286. package/dist/lib/strategy/basis-trade.d.ts +2 -0
  287. package/dist/lib/strategy/basis-trade.js +24 -0
  288. package/dist/lib/strategy/funding-arb.d.ts +2 -0
  289. package/dist/lib/strategy/funding-arb.js +23 -0
  290. package/dist/lib/strategy/interface.d.ts +23 -0
  291. package/dist/lib/strategy/interface.js +1 -0
  292. package/dist/lib/strategy/registry.d.ts +4 -0
  293. package/dist/lib/strategy/registry.js +10 -0
  294. package/dist/lib/telemetry.d.ts +25 -0
  295. package/dist/lib/telemetry.js +101 -0
  296. package/dist/lib/trace-queries.d.ts +20 -0
  297. package/dist/lib/trace-queries.js +133 -0
  298. package/dist/lib/trace.d.ts +1 -0
  299. package/dist/lib/trace.js +4 -0
  300. package/dist/lib/trade-reputation.d.ts +6 -0
  301. package/dist/lib/trade-reputation.js +99 -0
  302. package/dist/lib/ui-tokens.d.ts +21 -0
  303. package/dist/lib/ui-tokens.js +26 -0
  304. package/dist/lib/validate.d.ts +39 -0
  305. package/dist/lib/validate.js +108 -0
  306. package/dist/lib/validation.d.ts +9 -0
  307. package/dist/lib/validation.js +64 -0
  308. package/dist/server/cache.d.ts +38 -0
  309. package/dist/server/cache.js +56 -0
  310. package/dist/server/index.d.ts +2 -0
  311. package/dist/server/index.js +89 -0
  312. package/dist/server/ipc.d.ts +18 -0
  313. package/dist/server/ipc.js +159 -0
  314. package/dist/server/subscriptions.d.ts +18 -0
  315. package/dist/server/subscriptions.js +114 -0
  316. package/package.json +124 -0
@@ -0,0 +1,164 @@
1
+ import { createRequire } from "module";
2
+ import { Command } from "commander";
3
+ import { registerCommands } from "../commands/index.js";
4
+ import { loadConfig } from "../lib/config.js";
5
+ import { getAvailableExchanges, setExchange } from "../lib/exchange.js";
6
+ import { getSetting } from "../lib/settings.js";
7
+ import { createContext } from "./context.js";
8
+ import { highlighter, printCommandCompletion, printSessionBanner } from "./experience.js";
9
+ import { commandPathFromCommand, resolveTestnetMode } from "./network-defaults.js";
10
+ import { outputError } from "./output.js";
11
+ const require = createRequire(import.meta.url);
12
+ const pkg = require("../../package.json");
13
+ const commandMeta = new WeakMap();
14
+ function findMeta(command) {
15
+ let current = command;
16
+ while (current) {
17
+ const meta = commandMeta.get(current);
18
+ if (meta)
19
+ return meta;
20
+ current = current.parent;
21
+ }
22
+ return undefined;
23
+ }
24
+ export function createProgram() {
25
+ const program = new Command();
26
+ const availableExchanges = getAvailableExchanges().join(", ");
27
+ const defaultExchange = getConfiguredDefaultExchange();
28
+ program
29
+ .name("perps")
30
+ .description("Universal CLI for perpetual DEXes")
31
+ .showSuggestionAfterError(true)
32
+ .showHelpAfterError()
33
+ .version(pkg.version)
34
+ .option("--json", "Output in JSON format", false)
35
+ .option("--human", "Enable human-first output UX (banner, timing, rich formatting)", false)
36
+ .option("--no-banner", "Disable session header for human-readable output")
37
+ .option("--testnet", "Force testnet network")
38
+ .option("--mainnet", "Force mainnet network")
39
+ .option("-e, --exchange <name>", `Exchange to use (${availableExchanges})`, defaultExchange)
40
+ .option("-v, --verbose", "Show detailed output", false)
41
+ .addHelpText("after", `
42
+ Examples:
43
+ perps markets ls
44
+ perps order market buy BTC 0.01 --idempotency-key demo-001
45
+ perps doctor --network
46
+ `)
47
+ .hook("preAction", async (thisCommand, actionCommand) => {
48
+ const invokedCommand = actionCommand ?? thisCommand;
49
+ const opts = invokedCommand.optsWithGlobals();
50
+ const commandPath = commandPathFromCommand(invokedCommand);
51
+ const exchangeNetworkOverride = getExchangeNetworkOverride(opts.exchange);
52
+ const isHumanMode = opts.human ?? false;
53
+ const verbose = opts.verbose ?? false;
54
+ const isTestnet = resolveTestnetMode({
55
+ argv: process.argv.slice(2),
56
+ commandPath,
57
+ exchangeNetworkOverride,
58
+ fallbackTestnet: getConfiguredTestnetFallback(),
59
+ });
60
+ // Set exchange context
61
+ try {
62
+ setExchange(opts.exchange);
63
+ }
64
+ catch (err) {
65
+ outputError(err instanceof Error ? err.message : String(err));
66
+ console.error(highlighter.dim(`Available exchanges: ${getAvailableExchanges().join(", ")}`));
67
+ process.exit(1);
68
+ }
69
+ let config;
70
+ try {
71
+ config = loadConfig(isTestnet, opts.exchange);
72
+ }
73
+ catch (err) {
74
+ outputError(err instanceof Error ? err.message : String(err));
75
+ process.exit(1);
76
+ }
77
+ const context = createContext(config);
78
+ // Store metadata on the root command
79
+ commandMeta.set(thisCommand, {
80
+ context,
81
+ outputOptions: { json: opts.json },
82
+ exchange: opts.exchange,
83
+ isTestnet,
84
+ commandPath,
85
+ isHumanMode,
86
+ verbose,
87
+ startTime: performance.now(),
88
+ });
89
+ if (!opts.json && isHumanMode && opts.banner && commandPath[0] !== "ui") {
90
+ // Show "ALL" when cross-exchange flags are active
91
+ const subOpts = invokedCommand.opts();
92
+ const bannerExchange = subOpts.all || subOpts.report ? "ALL" : opts.exchange;
93
+ printSessionBanner({
94
+ version: pkg.version,
95
+ commandPath,
96
+ exchange: bannerExchange,
97
+ isTestnet,
98
+ });
99
+ }
100
+ })
101
+ .hook("postAction", (thisCommand) => {
102
+ const meta = commandMeta.get(thisCommand);
103
+ if (!meta)
104
+ return;
105
+ const isJson = meta.outputOptions.json;
106
+ // Only show timing for non-JSON output
107
+ if (!isJson && meta.isHumanMode) {
108
+ const duration = (performance.now() - meta.startTime) / 1000;
109
+ printCommandCompletion(duration);
110
+ }
111
+ });
112
+ registerCommands(program);
113
+ return program;
114
+ }
115
+ export function getContext(command) {
116
+ const meta = findMeta(command);
117
+ if (meta)
118
+ return meta.context;
119
+ throw new Error("Context not found");
120
+ }
121
+ export function getOutputOptions(command) {
122
+ const meta = findMeta(command);
123
+ return meta?.outputOptions ?? { json: false };
124
+ }
125
+ export function getSelectedExchange(command) {
126
+ const meta = findMeta(command);
127
+ return meta?.exchange ?? "hyperliquid";
128
+ }
129
+ export function getVerbose(command) {
130
+ const meta = findMeta(command);
131
+ return meta?.verbose ?? false;
132
+ }
133
+ function getConfiguredDefaultExchange() {
134
+ try {
135
+ const configured = getSetting("defaultExchange");
136
+ return configured?.trim() || "hyperliquid";
137
+ }
138
+ catch {
139
+ return "hyperliquid";
140
+ }
141
+ }
142
+ function getConfiguredTestnetFallback() {
143
+ try {
144
+ return getSetting("testnetByDefault");
145
+ }
146
+ catch {
147
+ return false;
148
+ }
149
+ }
150
+ function getExchangeNetworkOverride(exchangeId) {
151
+ const normalized = exchangeId.trim().toLowerCase();
152
+ const lookup = {
153
+ hyperliquid: process.env.HYPERLIQUID_NETWORK,
154
+ decibel: process.env.DECIBEL_NETWORK,
155
+ aevo: process.env.AEVO_NETWORK,
156
+ orderly: process.env.ORDERLY_NETWORK,
157
+ paradex: process.env.PARADEX_NETWORK,
158
+ };
159
+ const value = lookup[normalized]?.trim().toLowerCase();
160
+ if (value === "testnet" || value === "mainnet") {
161
+ return value;
162
+ }
163
+ return undefined;
164
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Utilities for watch mode terminal display
3
+ */
4
+ /**
5
+ * Clear terminal screen and move cursor to top-left
6
+ */
7
+ export declare function clearScreen(): void;
8
+ /**
9
+ * Hide terminal cursor (also registers signal handlers to restore on exit)
10
+ */
11
+ export declare function hideCursor(): void;
12
+ /**
13
+ * Show terminal cursor
14
+ */
15
+ export declare function showCursor(): void;
16
+ /**
17
+ * Format current time as HH:MM:SS
18
+ */
19
+ export declare function formatTimestamp(): string;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Utilities for watch mode terminal display
3
+ */
4
+ import { registerCursorCleanup } from "./experience.js";
5
+ /**
6
+ * Clear terminal screen and move cursor to top-left
7
+ */
8
+ export function clearScreen() {
9
+ process.stdout.write("\x1b[2J\x1b[H");
10
+ }
11
+ /**
12
+ * Hide terminal cursor (also registers signal handlers to restore on exit)
13
+ */
14
+ export function hideCursor() {
15
+ registerCursorCleanup();
16
+ process.stdout.write("\x1b[?25l");
17
+ }
18
+ /**
19
+ * Show terminal cursor
20
+ */
21
+ export function showCursor() {
22
+ process.stdout.write("\x1b[?25h");
23
+ }
24
+ /**
25
+ * Format current time as HH:MM:SS
26
+ */
27
+ export function formatTimestamp() {
28
+ const now = new Date();
29
+ return now.toLocaleTimeString("en-US", {
30
+ hour12: false,
31
+ hour: "2-digit",
32
+ minute: "2-digit",
33
+ second: "2-digit",
34
+ });
35
+ }
@@ -0,0 +1,55 @@
1
+ import { AllPerpMetasResponse, SpotMetaResponse } from "@nktkas/hyperliquid";
2
+ import { AllDexsAssetCtxsEvent, SpotAssetCtxsEvent } from "@nktkas/hyperliquid/api/subscription";
3
+ export interface ServerStatus {
4
+ running: boolean;
5
+ testnet: boolean;
6
+ connected: boolean;
7
+ startedAt: number;
8
+ uptime: number;
9
+ cache: {
10
+ hasMids: boolean;
11
+ hasAssetCtxs: boolean;
12
+ hasPerpMetas: boolean;
13
+ hasSpotMeta: boolean;
14
+ hasSpotAssetCtxs: boolean;
15
+ midsAge?: number;
16
+ assetCtxsAge?: number;
17
+ perpMetasAge?: number;
18
+ spotMetaAge?: number;
19
+ spotAssetCtxsAge?: number;
20
+ };
21
+ }
22
+ export declare class ServerClient {
23
+ private socket;
24
+ private requestId;
25
+ private pending;
26
+ private buffer;
27
+ connect(): Promise<void>;
28
+ private handleData;
29
+ private request;
30
+ getPrices(coin?: string): Promise<{
31
+ data: Record<string, string>;
32
+ cached_at: number;
33
+ }>;
34
+ getAssetCtxs(): Promise<{
35
+ data: AllDexsAssetCtxsEvent;
36
+ cached_at: number;
37
+ }>;
38
+ getPerpMeta(): Promise<{
39
+ data: AllPerpMetasResponse;
40
+ cached_at: number;
41
+ }>;
42
+ getSpotMeta(): Promise<{
43
+ data: SpotMetaResponse;
44
+ cached_at: number;
45
+ }>;
46
+ getSpotAssetCtxs(): Promise<{
47
+ data: SpotAssetCtxsEvent;
48
+ cached_at: number;
49
+ }>;
50
+ getStatus(): Promise<ServerStatus>;
51
+ shutdown(): Promise<void>;
52
+ close(): void;
53
+ }
54
+ export declare function isServerRunning(): boolean;
55
+ export declare function tryConnectToServer(): Promise<ServerClient | null>;
@@ -0,0 +1,157 @@
1
+ import { connect } from "node:net";
2
+ import { existsSync } from "node:fs";
3
+ import { SERVER_SOCKET_PATH } from "../lib/paths.js";
4
+ const IPC_REQUEST_TIMEOUT_MS = 5_000;
5
+ export class ServerClient {
6
+ socket = null;
7
+ requestId = 0;
8
+ pending = new Map();
9
+ buffer = "";
10
+ async connect() {
11
+ if (this.socket)
12
+ return;
13
+ return new Promise((resolve, reject) => {
14
+ const socket = connect(SERVER_SOCKET_PATH);
15
+ socket.on("connect", () => {
16
+ this.socket = socket;
17
+ resolve();
18
+ });
19
+ socket.on("error", (err) => {
20
+ reject(err);
21
+ });
22
+ socket.on("data", (data) => {
23
+ this.handleData(data.toString());
24
+ });
25
+ socket.on("close", () => {
26
+ this.socket = null;
27
+ // Reject all pending requests
28
+ for (const pending of this.pending.values()) {
29
+ pending.reject(new Error("Connection closed"));
30
+ }
31
+ this.pending.clear();
32
+ });
33
+ });
34
+ }
35
+ handleData(data) {
36
+ this.buffer += data;
37
+ const lines = this.buffer.split("\n");
38
+ this.buffer = lines.pop() || "";
39
+ for (const line of lines) {
40
+ if (line.trim()) {
41
+ try {
42
+ const response = JSON.parse(line);
43
+ const pending = this.pending.get(response.id);
44
+ if (pending) {
45
+ this.pending.delete(response.id);
46
+ pending.resolve(response);
47
+ }
48
+ }
49
+ catch {
50
+ // Ignore parse errors
51
+ }
52
+ }
53
+ }
54
+ }
55
+ async request(method, params) {
56
+ if (!this.socket) {
57
+ throw new Error("Not connected");
58
+ }
59
+ const id = String(++this.requestId);
60
+ const request = { id, method, params };
61
+ const socket = this.socket;
62
+ if (!socket) {
63
+ throw new Error("Not connected");
64
+ }
65
+ return new Promise((resolve, reject) => {
66
+ const timeoutId = setTimeout(() => {
67
+ if (this.pending.has(id)) {
68
+ this.pending.delete(id);
69
+ reject(new Error("Request timeout"));
70
+ }
71
+ }, IPC_REQUEST_TIMEOUT_MS);
72
+ this.pending.set(id, {
73
+ resolve: (value) => {
74
+ clearTimeout(timeoutId);
75
+ resolve(value);
76
+ },
77
+ reject: (err) => {
78
+ clearTimeout(timeoutId);
79
+ reject(err);
80
+ },
81
+ });
82
+ socket.write(JSON.stringify(request) + "\n");
83
+ });
84
+ }
85
+ async getPrices(coin) {
86
+ const response = await this.request("getPrices", coin ? { coin } : undefined);
87
+ if (response.error) {
88
+ throw new Error(response.error);
89
+ }
90
+ return { data: response.result, cached_at: response.cached_at };
91
+ }
92
+ async getAssetCtxs() {
93
+ const response = await this.request("getAssetCtxs");
94
+ if (response.error) {
95
+ throw new Error(response.error);
96
+ }
97
+ return { data: response.result, cached_at: response.cached_at };
98
+ }
99
+ async getPerpMeta() {
100
+ const response = await this.request("getPerpMeta");
101
+ if (response.error) {
102
+ throw new Error(response.error);
103
+ }
104
+ return { data: response.result, cached_at: response.cached_at };
105
+ }
106
+ async getSpotMeta() {
107
+ const response = await this.request("getSpotMeta");
108
+ if (response.error) {
109
+ throw new Error(response.error);
110
+ }
111
+ return { data: response.result, cached_at: response.cached_at };
112
+ }
113
+ async getSpotAssetCtxs() {
114
+ const response = await this.request("getSpotAssetCtxs");
115
+ if (response.error) {
116
+ throw new Error(response.error);
117
+ }
118
+ return { data: response.result, cached_at: response.cached_at };
119
+ }
120
+ async getStatus() {
121
+ const response = await this.request("getStatus");
122
+ if (response.error) {
123
+ throw new Error(response.error);
124
+ }
125
+ return response.result;
126
+ }
127
+ async shutdown() {
128
+ const response = await this.request("shutdown");
129
+ if (response.error) {
130
+ throw new Error(response.error);
131
+ }
132
+ }
133
+ close() {
134
+ if (this.socket) {
135
+ this.socket.destroy();
136
+ this.socket = null;
137
+ }
138
+ }
139
+ }
140
+ // Helper to check if server is running
141
+ export function isServerRunning() {
142
+ return existsSync(SERVER_SOCKET_PATH);
143
+ }
144
+ // Helper to try connecting to server
145
+ export async function tryConnectToServer() {
146
+ if (!isServerRunning()) {
147
+ return null;
148
+ }
149
+ try {
150
+ const client = new ServerClient();
151
+ await client.connect();
152
+ return client;
153
+ }
154
+ catch {
155
+ return null;
156
+ }
157
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerAddCommand(account: Command): void;