perp-cli 0.12.17 → 0.14.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 (361) hide show
  1. package/README.md +247 -27
  2. package/dist/_stderr-filter.js +0 -1
  3. package/dist/agent-wallet/lighter-keystore.d.ts +11 -0
  4. package/dist/agent-wallet/lighter-keystore.js +92 -10
  5. package/dist/agent-wallet/passphrase.d.ts +1 -1
  6. package/dist/agent-wallet/passphrase.js +16 -3
  7. package/dist/agent-wallet/store.d.ts +37 -4
  8. package/dist/agent-wallet/store.js +132 -0
  9. package/dist/agent-wallet/venue-keystore.d.ts +14 -0
  10. package/dist/agent-wallet/venue-keystore.js +121 -0
  11. package/dist/api/public/hyperliquid.js +4 -4
  12. package/dist/api/public/lighter.js +5 -5
  13. package/dist/api/public/pacifica.d.ts +0 -1
  14. package/dist/api/public/pacifica.js +4 -13
  15. package/dist/api/public/urls.d.ts +9 -1
  16. package/dist/api/public/urls.js +35 -13
  17. package/dist/arb/file-lock.d.ts +11 -0
  18. package/dist/arb/file-lock.js +74 -0
  19. package/dist/arb/index.d.ts +2 -2
  20. package/dist/arb/index.js +2 -2
  21. package/dist/arb/pending-entry.d.ts +32 -0
  22. package/dist/arb/pending-entry.js +77 -0
  23. package/dist/arb/sizing.d.ts +6 -13
  24. package/dist/arb/sizing.js +12 -51
  25. package/dist/arb/state.d.ts +45 -12
  26. package/dist/arb/state.js +214 -42
  27. package/dist/arb/utils.d.ts +20 -6
  28. package/dist/arb/utils.js +43 -39
  29. package/dist/bot/conditions.d.ts +4 -4
  30. package/dist/bot/conditions.js +11 -6
  31. package/dist/bot/config.d.ts +17 -1
  32. package/dist/bot/config.js +48 -12
  33. package/dist/bot/engine.d.ts +61 -2
  34. package/dist/bot/engine.js +610 -144
  35. package/dist/bot/fill-size.d.ts +7 -0
  36. package/dist/bot/fill-size.js +18 -0
  37. package/dist/bot/index.d.ts +1 -1
  38. package/dist/bot/index.js +1 -1
  39. package/dist/bot/perp-order.d.ts +99 -0
  40. package/dist/bot/perp-order.js +299 -0
  41. package/dist/bot/presets.d.ts +7 -0
  42. package/dist/bot/presets.js +17 -0
  43. package/dist/bot/quarantine.d.ts +75 -0
  44. package/dist/bot/quarantine.js +190 -0
  45. package/dist/bot/quote-rules.d.ts +23 -0
  46. package/dist/bot/quote-rules.js +69 -0
  47. package/dist/bot/strategies/avellaneda-mm.d.ts +32 -2
  48. package/dist/bot/strategies/avellaneda-mm.js +72 -70
  49. package/dist/bot/strategies/basis-arb.js +2 -0
  50. package/dist/bot/strategies/dca-strategy.d.ts +2 -0
  51. package/dist/bot/strategies/dca-strategy.js +5 -0
  52. package/dist/bot/strategies/funding-arb-strategy.d.ts +43 -3
  53. package/dist/bot/strategies/funding-arb-strategy.js +571 -380
  54. package/dist/bot/strategies/funding-arb-utils.d.ts +48 -23
  55. package/dist/bot/strategies/funding-arb-utils.js +159 -195
  56. package/dist/bot/strategies/funding-arb-v2.d.ts +32 -0
  57. package/dist/bot/strategies/funding-arb-v2.js +258 -47
  58. package/dist/bot/strategies/funding-auto.js +215 -194
  59. package/dist/bot/strategies/spot-perp-arb-strategy.d.ts +14 -0
  60. package/dist/bot/strategies/spot-perp-arb-strategy.js +217 -50
  61. package/dist/bot/strategies/spot-perp-executor.d.ts +73 -19
  62. package/dist/bot/strategies/spot-perp-executor.js +319 -120
  63. package/dist/bot/strategies/spot-perp-state.d.ts +43 -0
  64. package/dist/bot/strategies/spot-perp-state.js +70 -0
  65. package/dist/bot/strategy-types.d.ts +6 -0
  66. package/dist/bot/tui/BotDashboard.d.ts +7 -2
  67. package/dist/bot/tui/BotDashboard.js +6 -3
  68. package/dist/bridge-engine.d.ts +120 -19
  69. package/dist/bridge-engine.js +710 -422
  70. package/dist/bridge-signers.d.ts +54 -0
  71. package/dist/bridge-signers.js +161 -0
  72. package/dist/cache.d.ts +4 -1
  73. package/dist/cache.js +11 -0
  74. package/dist/cli-flags.d.ts +50 -0
  75. package/dist/cli-flags.js +104 -0
  76. package/dist/cli-program.d.ts +35 -0
  77. package/dist/cli-program.js +286 -0
  78. package/dist/cli-spec.js +1 -1
  79. package/dist/client-id-tracker.js +11 -2
  80. package/dist/commands/account.d.ts +7 -1
  81. package/dist/commands/account.js +70 -92
  82. package/dist/commands/agent-import.d.ts +114 -0
  83. package/dist/commands/agent-import.js +794 -0
  84. package/dist/commands/agent.d.ts +232 -2
  85. package/dist/commands/agent.js +1858 -955
  86. package/dist/commands/alerts.d.ts +1 -0
  87. package/dist/commands/alerts.js +31 -28
  88. package/dist/commands/arb/index.d.ts +60 -1
  89. package/dist/commands/arb/index.js +381 -384
  90. package/dist/commands/arb-auto.d.ts +132 -4
  91. package/dist/commands/arb-auto.js +1474 -967
  92. package/dist/commands/arb.d.ts +3 -1
  93. package/dist/commands/arb.js +62 -30
  94. package/dist/commands/bot.js +127 -47
  95. package/dist/commands/bridge.d.ts +2 -1
  96. package/dist/commands/bridge.js +339 -192
  97. package/dist/commands/builder.d.ts +55 -0
  98. package/dist/commands/builder.js +387 -0
  99. package/dist/commands/funds-onchain.d.ts +32 -0
  100. package/dist/commands/funds-onchain.js +286 -0
  101. package/dist/commands/funds.d.ts +25 -0
  102. package/dist/commands/funds.js +939 -245
  103. package/dist/commands/history.js +72 -45
  104. package/dist/commands/init.d.ts +107 -15
  105. package/dist/commands/init.js +1116 -249
  106. package/dist/commands/jobs.d.ts +2 -1
  107. package/dist/commands/jobs.js +77 -15
  108. package/dist/commands/manage.js +136 -91
  109. package/dist/commands/market.d.ts +4 -1
  110. package/dist/commands/market.js +35 -32
  111. package/dist/commands/outcome.d.ts +10 -0
  112. package/dist/commands/outcome.js +396 -0
  113. package/dist/commands/plan.js +52 -12
  114. package/dist/commands/portfolio.d.ts +1 -0
  115. package/dist/commands/portfolio.js +60 -72
  116. package/dist/commands/rebalance.d.ts +2 -1
  117. package/dist/commands/rebalance.js +33 -43
  118. package/dist/commands/risk.js +46 -19
  119. package/dist/commands/settings.d.ts +1 -0
  120. package/dist/commands/settings.js +246 -51
  121. package/dist/commands/trade.d.ts +50 -0
  122. package/dist/commands/trade.js +1943 -695
  123. package/dist/commands/wallet.d.ts +30 -1
  124. package/dist/commands/wallet.js +316 -337
  125. package/dist/config.d.ts +60 -9
  126. package/dist/config.js +252 -82
  127. package/dist/constants.d.ts +29 -4
  128. package/dist/constants.js +62 -20
  129. package/dist/dashboard/server.d.ts +2 -0
  130. package/dist/dashboard/server.js +9 -6
  131. package/dist/dashboard/ui.js +6 -4
  132. package/dist/dashboard/ws-feeds.js +20 -8
  133. package/dist/dex-asset-map.js +5 -3
  134. package/dist/errors.d.ts +122 -0
  135. package/dist/errors.js +194 -0
  136. package/dist/event-stream.js +75 -19
  137. package/dist/evm-master-tx.d.ts +59 -0
  138. package/dist/evm-master-tx.js +154 -0
  139. package/dist/exchanges/adapter-network.d.ts +10 -0
  140. package/dist/exchanges/adapter-network.js +10 -0
  141. package/dist/exchanges/arcus/adapter.d.ts +196 -0
  142. package/dist/exchanges/arcus/adapter.js +1092 -0
  143. package/dist/exchanges/arcus/agent.d.ts +55 -0
  144. package/dist/exchanges/arcus/agent.js +188 -0
  145. package/dist/exchanges/arcus/client.d.ts +63 -0
  146. package/dist/exchanges/arcus/client.js +285 -0
  147. package/dist/exchanges/arcus/public.d.ts +65 -0
  148. package/dist/exchanges/arcus/public.js +138 -0
  149. package/dist/exchanges/arcus/signing.d.ts +176 -0
  150. package/dist/exchanges/arcus/signing.js +288 -0
  151. package/dist/exchanges/arcus/spot-chain.d.ts +60 -0
  152. package/dist/exchanges/arcus/spot-chain.js +241 -0
  153. package/dist/exchanges/arcus/spot-router.d.ts +177 -0
  154. package/dist/exchanges/arcus/spot-router.js +183 -0
  155. package/dist/exchanges/arcus/spot.d.ts +109 -0
  156. package/dist/exchanges/arcus/spot.js +645 -0
  157. package/dist/exchanges/aster-funds.d.ts +127 -0
  158. package/dist/exchanges/aster-funds.js +252 -0
  159. package/dist/exchanges/aster-nonce.d.ts +2 -0
  160. package/dist/exchanges/aster-nonce.js +107 -0
  161. package/dist/exchanges/aster-spot.d.ts +117 -0
  162. package/dist/exchanges/aster-spot.js +686 -0
  163. package/dist/exchanges/aster-typed-data.d.ts +133 -7
  164. package/dist/exchanges/aster-typed-data.js +121 -7
  165. package/dist/exchanges/aster.d.ts +219 -6
  166. package/dist/exchanges/aster.js +1023 -153
  167. package/dist/exchanges/builder-fee.d.ts +254 -0
  168. package/dist/exchanges/builder-fee.js +421 -0
  169. package/dist/exchanges/canonical-symbols.d.ts +32 -0
  170. package/dist/exchanges/canonical-symbols.js +96 -0
  171. package/dist/exchanges/capabilities.d.ts +7 -1
  172. package/dist/exchanges/capabilities.js +7 -0
  173. package/dist/exchanges/hl-signing.d.ts +165 -0
  174. package/dist/exchanges/hl-signing.js +158 -0
  175. package/dist/exchanges/hyperliquid-outcome.d.ts +211 -0
  176. package/dist/exchanges/hyperliquid-outcome.js +646 -0
  177. package/dist/exchanges/hyperliquid-spot.d.ts +44 -5
  178. package/dist/exchanges/hyperliquid-spot.js +308 -117
  179. package/dist/exchanges/hyperliquid.d.ts +462 -57
  180. package/dist/exchanges/hyperliquid.js +1575 -449
  181. package/dist/exchanges/index.d.ts +6 -0
  182. package/dist/exchanges/index.js +4 -0
  183. package/dist/exchanges/interface.d.ts +63 -10
  184. package/dist/exchanges/interface.js +18 -3
  185. package/dist/exchanges/ioc-outcome.d.ts +44 -0
  186. package/dist/exchanges/ioc-outcome.js +57 -0
  187. package/dist/exchanges/legacy-trading-v2.d.ts +39 -0
  188. package/dist/exchanges/legacy-trading-v2.js +940 -0
  189. package/dist/exchanges/lighter-public.d.ts +43 -0
  190. package/dist/exchanges/lighter-public.js +276 -0
  191. package/dist/exchanges/lighter-rh-deposit.d.ts +62 -0
  192. package/dist/exchanges/lighter-rh-deposit.js +185 -0
  193. package/dist/exchanges/lighter-signer.d.ts +123 -0
  194. package/dist/exchanges/lighter-signer.js +215 -0
  195. package/dist/exchanges/lighter-spot.d.ts +91 -13
  196. package/dist/exchanges/lighter-spot.js +595 -233
  197. package/dist/exchanges/lighter.d.ts +611 -39
  198. package/dist/exchanges/lighter.js +1890 -649
  199. package/dist/exchanges/ondo/adapter.d.ts +166 -0
  200. package/dist/exchanges/ondo/adapter.js +835 -0
  201. package/dist/exchanges/ondo/agent.d.ts +31 -0
  202. package/dist/exchanges/ondo/agent.js +101 -0
  203. package/dist/exchanges/ondo/client.d.ts +60 -0
  204. package/dist/exchanges/ondo/client.js +297 -0
  205. package/dist/exchanges/ondo/funds.d.ts +122 -0
  206. package/dist/exchanges/ondo/funds.js +290 -0
  207. package/dist/exchanges/ondo/public.d.ts +95 -0
  208. package/dist/exchanges/ondo/public.js +214 -0
  209. package/dist/exchanges/ondo/spot.d.ts +127 -0
  210. package/dist/exchanges/ondo/spot.js +392 -0
  211. package/dist/exchanges/outcome-interface.d.ts +140 -0
  212. package/dist/exchanges/outcome-interface.js +16 -0
  213. package/dist/exchanges/pacifica-spot.d.ts +83 -0
  214. package/dist/exchanges/pacifica-spot.js +324 -0
  215. package/dist/exchanges/pacifica-typed-data.d.ts +30 -13
  216. package/dist/exchanges/pacifica-typed-data.js +57 -9
  217. package/dist/exchanges/pacifica.d.ts +288 -4
  218. package/dist/exchanges/pacifica.js +1013 -76
  219. package/dist/exchanges/precision.d.ts +47 -0
  220. package/dist/exchanges/precision.js +209 -0
  221. package/dist/exchanges/qfex/adapter.d.ts +341 -0
  222. package/dist/exchanges/qfex/adapter.js +1383 -0
  223. package/dist/exchanges/qfex/agent.d.ts +58 -0
  224. package/dist/exchanges/qfex/agent.js +188 -0
  225. package/dist/exchanges/qfex/client.d.ts +54 -0
  226. package/dist/exchanges/qfex/client.js +138 -0
  227. package/dist/exchanges/qfex/errors.d.ts +70 -0
  228. package/dist/exchanges/qfex/errors.js +236 -0
  229. package/dist/exchanges/qfex/public.d.ts +122 -0
  230. package/dist/exchanges/qfex/public.js +268 -0
  231. package/dist/exchanges/qfex/signing.d.ts +160 -0
  232. package/dist/exchanges/qfex/signing.js +283 -0
  233. package/dist/exchanges/qfex/ws-transport.d.ts +294 -0
  234. package/dist/exchanges/qfex/ws-transport.js +798 -0
  235. package/dist/exchanges/rate-limiter.d.ts +12 -0
  236. package/dist/exchanges/rate-limiter.js +64 -0
  237. package/dist/exchanges/registry.d.ts +14 -2
  238. package/dist/exchanges/registry.js +20 -32
  239. package/dist/exchanges/slippage.d.ts +37 -0
  240. package/dist/exchanges/slippage.js +70 -0
  241. package/dist/exchanges/spot-factory.d.ts +166 -0
  242. package/dist/exchanges/spot-factory.js +431 -0
  243. package/dist/exchanges/spot-interface.d.ts +98 -4
  244. package/dist/exchanges/spot-interface.js +27 -1
  245. package/dist/exchanges/spot-result.d.ts +79 -0
  246. package/dist/exchanges/spot-result.js +273 -0
  247. package/dist/exchanges/trading-v2.d.ts +117 -0
  248. package/dist/exchanges/trading-v2.js +301 -0
  249. package/dist/exchanges/venue-types.d.ts +231 -0
  250. package/dist/exchanges/venue-types.js +87 -0
  251. package/dist/exchanges/venue.d.ts +211 -0
  252. package/dist/exchanges/venue.js +132 -0
  253. package/dist/exchanges/venues/arcus.d.ts +8 -0
  254. package/dist/exchanges/venues/arcus.js +109 -0
  255. package/dist/exchanges/venues/aster.d.ts +49 -0
  256. package/dist/exchanges/venues/aster.js +176 -0
  257. package/dist/exchanges/venues/create-helpers.d.ts +18 -0
  258. package/dist/exchanges/venues/create-helpers.js +199 -0
  259. package/dist/exchanges/venues/hyperliquid.d.ts +23 -0
  260. package/dist/exchanges/venues/hyperliquid.js +126 -0
  261. package/dist/exchanges/venues/index.d.ts +16 -0
  262. package/dist/exchanges/venues/index.js +26 -0
  263. package/dist/exchanges/venues/lighter-family.d.ts +92 -0
  264. package/dist/exchanges/venues/lighter-family.js +166 -0
  265. package/dist/exchanges/venues/lighter-rh.d.ts +7 -0
  266. package/dist/exchanges/venues/lighter-rh.js +58 -0
  267. package/dist/exchanges/venues/lighter.d.ts +6 -0
  268. package/dist/exchanges/venues/lighter.js +55 -0
  269. package/dist/exchanges/venues/ondo.d.ts +34 -0
  270. package/dist/exchanges/venues/ondo.js +140 -0
  271. package/dist/exchanges/venues/pacifica.d.ts +8 -0
  272. package/dist/exchanges/venues/pacifica.js +95 -0
  273. package/dist/exchanges/venues/qfex.d.ts +28 -0
  274. package/dist/exchanges/venues/qfex.js +132 -0
  275. package/dist/execution-log.js +10 -2
  276. package/dist/funding/legacy-public.d.ts +31 -0
  277. package/dist/funding/legacy-public.js +369 -0
  278. package/dist/funding/normalize.d.ts +28 -16
  279. package/dist/funding/normalize.js +61 -29
  280. package/dist/funding/rates.d.ts +46 -11
  281. package/dist/funding/rates.js +228 -277
  282. package/dist/guardrail/perp-guardrail.js +0 -0
  283. package/dist/index.js +156 -684
  284. package/dist/jobs.d.ts +84 -6
  285. package/dist/jobs.js +239 -41
  286. package/dist/landing.d.ts +7 -2
  287. package/dist/landing.js +19 -3
  288. package/dist/mcp-server.d.ts +14 -4
  289. package/dist/mcp-server.js +820 -402
  290. package/dist/mcp-trade-guard.d.ts +16 -0
  291. package/dist/mcp-trade-guard.js +59 -0
  292. package/dist/pacifica/client.d.ts +41 -10
  293. package/dist/pacifica/client.js +167 -63
  294. package/dist/pacifica/constants.d.ts +0 -1
  295. package/dist/pacifica/constants.js +0 -5
  296. package/dist/pacifica/deposit.d.ts +30 -3
  297. package/dist/pacifica/deposit.js +119 -2
  298. package/dist/pacifica/faucet.d.ts +29 -0
  299. package/dist/pacifica/faucet.js +100 -0
  300. package/dist/pacifica/sign-tx.d.ts +15 -0
  301. package/dist/pacifica/sign-tx.js +41 -0
  302. package/dist/pacifica/types/account.d.ts +28 -4
  303. package/dist/pacifica/types/lake.d.ts +20 -5
  304. package/dist/pacifica/types/lake.js +4 -0
  305. package/dist/pacifica/types/market.d.ts +5 -0
  306. package/dist/pacifica/types/order.d.ts +4 -1
  307. package/dist/pacifica/types/position.d.ts +9 -1
  308. package/dist/plan-executor.d.ts +10 -5
  309. package/dist/plan-executor.js +165 -54
  310. package/dist/position-history.js +13 -0
  311. package/dist/rebalance.d.ts +26 -2
  312. package/dist/rebalance.js +86 -7
  313. package/dist/relay-swap.d.ts +232 -0
  314. package/dist/relay-swap.js +630 -0
  315. package/dist/risk.js +5 -1
  316. package/dist/secret-env.d.ts +15 -0
  317. package/dist/secret-env.js +36 -0
  318. package/dist/settings.d.ts +169 -6
  319. package/dist/settings.js +219 -38
  320. package/dist/signer/ows-evm.d.ts +13 -0
  321. package/dist/signer/ows-evm.js +22 -0
  322. package/dist/smart-order.d.ts +9 -0
  323. package/dist/smart-order.js +53 -8
  324. package/dist/strategies/dca.d.ts +6 -2
  325. package/dist/strategies/dca.js +66 -26
  326. package/dist/strategies/funding-arb.d.ts +11 -1
  327. package/dist/strategies/funding-arb.js +202 -89
  328. package/dist/strategies/grid.d.ts +31 -0
  329. package/dist/strategies/grid.js +89 -11
  330. package/dist/strategies/pending-stop.d.ts +8 -0
  331. package/dist/strategies/pending-stop.js +12 -0
  332. package/dist/strategies/split-order.d.ts +45 -17
  333. package/dist/strategies/split-order.js +157 -91
  334. package/dist/strategies/trailing-stop.d.ts +2 -1
  335. package/dist/strategies/trailing-stop.js +52 -6
  336. package/dist/strategies/twap.d.ts +6 -1
  337. package/dist/strategies/twap.js +39 -11
  338. package/dist/trade-validator.d.ts +22 -0
  339. package/dist/trade-validator.js +119 -15
  340. package/dist/utils/numeric.d.ts +46 -0
  341. package/dist/utils/numeric.js +79 -0
  342. package/dist/utils.d.ts +19 -0
  343. package/dist/utils.js +96 -19
  344. package/dist/withdraw-gate.d.ts +49 -0
  345. package/dist/withdraw-gate.js +131 -0
  346. package/package.json +15 -6
  347. package/skills/perp-cli/SKILL.md +142 -55
  348. package/skills/perp-cli/references/agent-operations.md +110 -56
  349. package/skills/perp-cli/references/commands.md +266 -71
  350. package/skills/perp-cli/references/strategies.md +34 -31
  351. package/skills/perp-cli/scripts/arb-monitor.sh +10 -5
  352. package/skills/perp-cli/scripts/funding-analysis.sh +14 -9
  353. package/skills/perp-cli/scripts/preflight.sh +21 -14
  354. package/skills/perp-cli/scripts/spot-perp-scan.sh +12 -7
  355. package/skills/perp-cli/scripts/validate-arb.sh +31 -15
  356. package/vendor/lighter-signer/SHA256SUMS +2 -0
  357. package/vendor/lighter-signer/VERSION +8 -0
  358. package/vendor/lighter-signer/lighter-signer.wasm +0 -0
  359. package/vendor/lighter-signer/wasm_exec.js +575 -0
  360. package/dist/bot/strategies/funding-arb-v2-strategy.d.ts +0 -42
  361. package/dist/bot/strategies/funding-arb-v2-strategy.js +0 -864
@@ -0,0 +1,286 @@
1
+ /**
2
+ * The perp CLI Commander tree (root options + every command group), built without
3
+ * parsing argv — `src/index.ts` parses it; tests parse full argv through the same tree.
4
+ */
5
+ import { Command } from "commander";
6
+ import { cliCredentialOptsFrom, hasCredentials, resolveCredentials } from "./config.js";
7
+ import { PacificaAdapter } from "./exchanges/pacifica.js";
8
+ import { HyperliquidAdapter } from "./exchanges/hyperliquid.js";
9
+ import { getVenue, listVenues, resolveVenueId, READ_ONLY_CREDENTIALS } from "./exchanges/venue.js";
10
+ import { registerAdapterNetwork } from "./exchanges/adapter-network.js";
11
+ import "./exchanges/venues/index.js";
12
+ import { PerpError } from "./errors.js";
13
+ import { registerMarketCommands } from "./commands/market.js";
14
+ import { registerAccountCommands } from "./commands/account.js";
15
+ import { registerOutcomeCommands } from "./commands/outcome.js";
16
+ import { registerTradeCommands } from "./commands/trade.js";
17
+ // manage commands now register under `wallet manage ...` via registerWalletCommands.
18
+ // stream commands removed — WS feeds still used by dashboard/event-stream internally
19
+ import { registerArbCommands } from "./commands/arb.js";
20
+ import { registerWalletCommands } from "./commands/wallet.js";
21
+ // bridge + rebalance now nested under `funds` — registered inside registerFundsCommands.
22
+ import { registerFundsCommands } from "./commands/funds.js";
23
+ // alert commands removed
24
+ import { registerArbAutoCommands } from "./commands/arb-auto.js";
25
+ import { registerArbManageCommands } from "./commands/arb/index.js";
26
+ // Agent commands now register under `wallet agent ...` via registerWalletCommands.
27
+ import { registerStrategyCommands } from "./commands/bot.js";
28
+ import { registerRiskCommands } from "./commands/risk.js";
29
+ import { registerHistoryCommands } from "./commands/history.js";
30
+ import { registerSettingsCommands } from "./commands/settings.js";
31
+ // dex commands merged into market (hip3) — use --dex flag for markets/balance
32
+ // `plan` is no longer top-level — registered as `strategy plan` inside
33
+ // registerStrategyCommands.
34
+ // funding merged into arb.ts
35
+ import { registerBacktestCommands } from "./commands/backtest.js";
36
+ import { registerPortfolioCommand } from "./commands/portfolio.js";
37
+ import { registerInitCommand } from "./commands/init.js";
38
+ import { registerAlertCommands } from "./commands/alerts.js";
39
+ import { setSharedApiNetwork } from "./shared-api.js";
40
+ import { registerBackgroundCommands } from "./commands/jobs.js";
41
+ import { setQuarantineNetwork } from "./bot/quarantine.js";
42
+ import { addRootSafetyOptions, networkOf, isDryRun, installDryRunGuard } from "./cli-flags.js";
43
+ /**
44
+ * Root-flag secret policy (review L10, SSOT Rule #3): a raw private key on argv (-k) is visible
45
+ * in `ps`, shell history and CI logs — rejected with INVALID_PARAMS and an import remediation.
46
+ * `--passphrase` is deprecated with a loud stderr warning (still accepted: existing scripts) —
47
+ * OWS_PASSPHRASE / stdin are the supported channels.
48
+ */
49
+ let _passphraseWarned = false;
50
+ export function assertNoArgvSecrets(root) {
51
+ const o = root.opts();
52
+ if (o.privateKey !== undefined) {
53
+ throw new PerpError("INVALID_PARAMS", "-k/--private-key is rejected: a raw private key on the command line leaks via ps, shell history and logs", {
54
+ remediation: "Import the key once (hidden prompt / stdin): printf '%s' \"$KEY\" | perp wallet set <exchange>, then select it with -w <name> or --ows <name>",
55
+ });
56
+ }
57
+ if (o.passphrase !== undefined && !_passphraseWarned) {
58
+ _passphraseWarned = true;
59
+ process.stderr.write("[warn] --passphrase on the command line is DEPRECATED and visible in ps / shell history. Use the OWS_PASSPHRASE env var or pipe it on stdin.\n");
60
+ }
61
+ }
62
+ /**
63
+ * `-n` used to be the record count of `history` / `account` subcommands (now `--limit`); it is the
64
+ * root network flag. A numeric `-n` / `--network` value on those commands is a migration error
65
+ * (INVALID_PARAMS "use --limit <n>") instead of the bare "invalid network" usage error. null = no such use.
66
+ */
67
+ export function numericNetworkFlagError(argv) {
68
+ if (!argv.includes("history") && !argv.includes("account"))
69
+ return null;
70
+ for (let i = 0; i < argv.length; i++) {
71
+ const a = argv[i];
72
+ const value = a === "-n" || a === "--network" ? argv[i + 1]
73
+ : a.startsWith("--network=") ? a.slice("--network=".length)
74
+ : /^-n\d+$/.test(a) ? a.slice(2)
75
+ : undefined;
76
+ if (value !== undefined && /^\d+$/.test(value)) {
77
+ return new PerpError("INVALID_PARAMS", `-n is the network flag (mainnet | testnet), not a record count (got "${value}")`, {
78
+ remediation: `The record count is --limit now: use --limit ${value}`,
79
+ });
80
+ }
81
+ }
82
+ return null;
83
+ }
84
+ /** `perp --json` with no subcommand: the landing / usage document (static — no wallet or venue reads). */
85
+ export function landingData(program, version) {
86
+ return {
87
+ name: program.name(),
88
+ version,
89
+ usage: `${program.name()} [options] <command> [args] (add --json for one JSON document on stdout)`,
90
+ help: `${program.name()} <command> --help`,
91
+ commands: program.commands
92
+ .filter(c => c._hidden !== true)
93
+ .map(c => ({ name: c.name(), description: c.description() })),
94
+ };
95
+ }
96
+ export function buildProgram(opts) {
97
+ const { defaultExchange, version } = opts;
98
+ const program = new Command();
99
+ addRootSafetyOptions(program);
100
+ program
101
+ .name("perp")
102
+ .description(`Multi-DEX Perpetual Futures CLI (${listVenues().map(v => v.displayName).join(", ")})`)
103
+ .version(version)
104
+ .option("-e, --exchange <exchange>", `Exchange: ${listVenues().map(v => v.id).join(", ")} (default: ${defaultExchange})`, defaultExchange)
105
+ .option("-k, --private-key <key>", "REJECTED — a raw key on argv leaks via ps / shell history. Import it instead: perp wallet set <exchange> (stdin)")
106
+ .option("--json", "Output raw JSON (for piping)")
107
+ .option("--fields <fields>", "Comma-separated fields to include in JSON output (e.g. totalEquity,positions)")
108
+ .option("--ndjson", "Output newline-delimited JSON (one object per line for streaming)")
109
+ .option("-w, --wallet <name>", "Use a specific wallet by name (from 'perp wallet list')")
110
+ .option("--ows <name>", "Use an OWS (Open Wallet Standard) wallet by name")
111
+ .option("--ows-key <token>", "OWS API key token (ows_key_...) for policy-gated agent access")
112
+ .option("--no-agent", "Bypass agent wallet routing for this run; falls back to OWS master or PK direct")
113
+ .option("--no-builder", "Never attach a configured builder fee (settings builder.<venue>) to this run's orders")
114
+ .option("--passphrase <pp>", "DEPRECATED (visible in ps / shell history) — prefer OWS_PASSPHRASE env or stdin")
115
+ .option("--dex <name>", "HIP-3 deployed perp dex name (Hyperliquid only)")
116
+ .configureOutput({
117
+ writeErr: (str) => {
118
+ if (process.argv.includes("--json")) {
119
+ const msg = str.replace(/^error:\s*/i, "").trim();
120
+ // Use inline envelope (jsonError import not available in sync context)
121
+ console.log(JSON.stringify({
122
+ ok: false,
123
+ error: { code: "CLI_ERROR", message: msg },
124
+ meta: { timestamp: new Date().toISOString() },
125
+ }));
126
+ }
127
+ else {
128
+ process.stderr.write(str);
129
+ }
130
+ },
131
+ });
132
+ let _adapter = null;
133
+ /**
134
+ * One adapter per `${venueId}:${network}:${wallet}:${hlDex}` (design §3 L1 cache key).
135
+ * Every adapter is built by the venue definition's create(ctx) — the single
136
+ * creation path shared with the MCP server (design §10.2).
137
+ */
138
+ const _adapters = new Map();
139
+ function cliCredentialOpts() {
140
+ return cliCredentialOptsFrom(program.opts());
141
+ }
142
+ function currentNetwork() {
143
+ return networkOf(program);
144
+ }
145
+ function adapterCacheKey(venue, network, hlDex) {
146
+ const opts = program.opts();
147
+ const wallet = opts.ows ? `ows:${opts.ows}` : (opts.wallet ?? "default");
148
+ return `${venue}:${network}:${wallet}:${hlDex ?? "-"}`;
149
+ }
150
+ /** restrictedRegions notice: stderr, once per venue per process (design §9.1 #2 — warn, never block). */
151
+ const _restrictedWarned = new Set();
152
+ function warnRestrictedRegions(def) {
153
+ if (def.restrictedRegions.length === 0 || _restrictedWarned.has(def.id))
154
+ return;
155
+ _restrictedWarned.add(def.id);
156
+ process.stderr.write(`[warn] ${def.displayName} is not available to residents of: ${def.restrictedRegions.join(", ")}. Check the venue terms before trading.\n`);
157
+ }
158
+ /**
159
+ * `publicOnly`: build a read-only adapter (credentials never resolved) — used by the
160
+ * public market-data commands so a configured-but-unusable credential (e.g. an OWS
161
+ * master wallet with no Ondo API key) cannot block keyless public reads.
162
+ */
163
+ async function createVenueAdapter(venueInput, dex, publicOnly = false) {
164
+ const def = getVenue(venueInput);
165
+ if (def.create === null) {
166
+ throw new PerpError("NOT_IMPLEMENTED", `${def.displayName} has no account/trading API`, {
167
+ remediation: `${def.id} is market-data only — use the funding/market public commands (e.g. perp arb scan)`,
168
+ });
169
+ }
170
+ const network = currentNetwork();
171
+ const hlDex = def.id === "hyperliquid" ? dex : null;
172
+ const key = publicOnly ? `${def.id}:${network}:public:${hlDex ?? "-"}` : adapterCacheKey(def.id, network, hlDex);
173
+ const cached = _adapters.get(key);
174
+ if (cached)
175
+ return cached;
176
+ const cli = cliCredentialOpts();
177
+ const readOnly = publicOnly || !(await hasCredentials(def.id, cli));
178
+ const credentials = readOnly ? READ_ONLY_CREDENTIALS : await resolveCredentials(def.id, cli, network);
179
+ if (!readOnly)
180
+ warnRestrictedRegions(def);
181
+ const adapter = await def.create({
182
+ network,
183
+ credentials,
184
+ // Commander's `--no-agent` flag sets opts.agent === false (NOT opts.noAgent).
185
+ noAgent: program.opts().agent === false,
186
+ hlDex,
187
+ readOnly,
188
+ // Commander's `--no-builder` sets opts.builder === false.
189
+ noBuilder: program.opts().builder === false,
190
+ });
191
+ _adapters.set(key, adapter);
192
+ registerAdapterNetwork(adapter, network);
193
+ return adapter;
194
+ }
195
+ function getExchange() {
196
+ return resolveVenueId(program.opts().exchange);
197
+ }
198
+ async function getAdapter() {
199
+ _adapter = await createVenueAdapter(getExchange(), program.opts().dex ?? null);
200
+ return _adapter;
201
+ }
202
+ // Sync wrapper for commands that need adapter (lazy init)
203
+ function getAdapterSync() {
204
+ if (!_adapter)
205
+ throw new Error("Adapter not initialized");
206
+ return _adapter;
207
+ }
208
+ function isJson() {
209
+ return !!program.opts().json || process.argv.includes("--ndjson");
210
+ }
211
+ function isDryRunFlag() {
212
+ return isDryRun(program);
213
+ }
214
+ // Helper to get PacificaAdapter specifically (for Pacifica-only commands) — served from the adapter cache.
215
+ function getPacificaAdapter() {
216
+ const a = _adapters.get(adapterCacheKey("pacifica", currentNetwork(), null));
217
+ if (!(a instanceof PacificaAdapter))
218
+ throw new Error("This command requires --exchange pacifica");
219
+ return a;
220
+ }
221
+ // Public market-data adapters (read-only; no credential resolution).
222
+ async function getPublicAdapter() {
223
+ return createVenueAdapter(getExchange(), program.opts().dex ?? null, true);
224
+ }
225
+ async function getPublicAdapterForExchange(rawExchange) {
226
+ return createVenueAdapter(rawExchange, program.opts().dex ?? null, true);
227
+ }
228
+ // Register command groups with async adapter getter
229
+ registerMarketCommands(program, getPublicAdapter, isJson, getPublicAdapterForExchange, getAdapter);
230
+ registerAccountCommands(program, getAdapter, isJson, getAdapterForExchange);
231
+ registerOutcomeCommands(program, getAdapterForExchange, isJson);
232
+ registerTradeCommands(program, getAdapter, isJson, isDryRunFlag, getAdapterForExchange);
233
+ // manage tree wired inside registerWalletCommands below.
234
+ // stream commands removed
235
+ registerArbCommands(program, isJson, getAdapterForExchange);
236
+ registerWalletCommands(program, isJson, getAdapter, getPacificaAdapter, getAdapterForExchange);
237
+ registerFundsCommands(program, getAdapter, isJson, () => networkOf(program), getAdapterForExchange);
238
+ // alert commands removed
239
+ // Helper to get adapter for a specific exchange (used by arb-auto)
240
+ async function getAdapterForExchange(rawExchange) {
241
+ return createVenueAdapter(rawExchange, program.opts().dex ?? null);
242
+ }
243
+ // Helper to get an HL adapter configured for a specific HIP-3 dex ("hl" = core perps)
244
+ async function getHLAdapterForDex(dex) {
245
+ const adapter = await createVenueAdapter("hyperliquid", dex === "hl" ? null : dex);
246
+ if (!(adapter instanceof HyperliquidAdapter))
247
+ throw new Error("hyperliquid venue did not produce a HyperliquidAdapter");
248
+ return adapter;
249
+ }
250
+ registerArbAutoCommands(program, getAdapterForExchange, isJson, getHLAdapterForDex);
251
+ registerArbManageCommands(program, getAdapterForExchange, isJson);
252
+ // `agent` is no longer top-level — registered as `wallet agent` inside
253
+ // registerWalletCommands above.
254
+ // withdraw merged into funds.
255
+ // `rebalance` is no longer top-level — registered as `funds rebalance` inside
256
+ // registerFundsCommands above.
257
+ // Background processes & strategies
258
+ registerBackgroundCommands(program, isJson, getAdapterForExchange);
259
+ registerStrategyCommands(program, getAdapter, getAdapterForExchange, isJson);
260
+ // Agent-friendly commands
261
+ registerRiskCommands(program, getAdapterForExchange, isJson);
262
+ registerHistoryCommands(program, isJson, getAdapterForExchange);
263
+ registerSettingsCommands(program, isJson, getAdapterForExchange);
264
+ // dex commands removed — use 'market hip3' + --dex flag
265
+ // `plan` is no longer top-level — registered as `strategy plan` inside
266
+ // registerStrategyCommands above.
267
+ // funding merged into arb — registerFundingCommands removed
268
+ registerBacktestCommands(program, isJson);
269
+ registerPortfolioCommand(program, getAdapterForExchange, isJson, version, getHLAdapterForDex);
270
+ registerInitCommand(program);
271
+ registerAlertCommands(program, isJson);
272
+ // Switch shared API URLs if --network testnet is used
273
+ // Validates -n and enforces default-deny --dry-run before any action runs.
274
+ installDryRunGuard(program);
275
+ // Secrets on argv (review L10): -k is rejected outright; --passphrase still works but warns loudly.
276
+ program.hook("preAction", () => assertNoArgvSecrets(program));
277
+ // Switch shared API URLs if --network testnet is used
278
+ program.hook("preAction", () => {
279
+ if (networkOf(program) === "testnet")
280
+ setSharedApiNetwork("testnet");
281
+ });
282
+ // Quarantine entries are network-scoped: every command reads / writes them for its -n network.
283
+ // (`perp mcp` re-declares its own network from PERP_NETWORK when the server starts.)
284
+ program.hook("preAction", () => setQuarantineNetwork(networkOf(program)));
285
+ return { program, getAdapterForExchange, isJson };
286
+ }
package/dist/cli-spec.js CHANGED
@@ -75,7 +75,7 @@ export function getCliSpec(program) {
75
75
  "Check error.retryable before retrying failed commands",
76
76
  "Use 'perp --json trade check <symbol> <side> <size>' to validate before trading",
77
77
  "Use 'perp --json market mid <symbol>' for fast price lookups",
78
- "If this CLI is useful, run 'perp settings referrals on' to support development",
78
+ "If this CLI is useful, run 'perp -e hyperliquid wallet manage referral set' (or -e lighter; signs one referral action, supports --dry-run) to support development",
79
79
  ],
80
80
  };
81
81
  }
@@ -15,8 +15,17 @@ export function generateClientId(prefix) {
15
15
  }
16
16
  /** Log a client order ID record */
17
17
  export function logClientId(record) {
18
- ensureDir();
19
- appendFileSync(CLIENT_IDS_FILE, JSON.stringify(record) + "\n", { mode: 0o600 });
18
+ try {
19
+ ensureDir();
20
+ appendFileSync(CLIENT_IDS_FILE, JSON.stringify(record) + "\n", { mode: 0o600 });
21
+ }
22
+ catch (e) {
23
+ // Before the order is sent ("pending") a failed write stops the order. Afterwards the order
24
+ // already has an outcome: a tracking-file failure is warned, never thrown as an order failure.
25
+ if (record.status === "pending")
26
+ throw e;
27
+ process.stderr.write(`[perp] Warning: could not record client id ${record.clientOrderId} as "${record.status}" (${e instanceof Error ? e.message : String(e)})\n`);
28
+ }
20
29
  }
21
30
  /** Look up a client order ID */
22
31
  export function lookupClientId(clientOrderId) {
@@ -1,3 +1,9 @@
1
1
  import { Command } from "commander";
2
- import type { ExchangeAdapter } from "../exchanges/index.js";
2
+ import type { ExchangeAdapter, ExchangeOrder } from "../exchanges/index.js";
3
+ /**
4
+ * Type / Trigger / Price / Size cells of an order row. A trigger order (stop / TP / SL) shows its
5
+ * trigger price; a market-type trigger has no limit price ("market"), and a position-level TP/SL
6
+ * (Pacifica: size 0 — it closes the whole position) shows "position" instead of 0.
7
+ */
8
+ export declare function orderCells(o: ExchangeOrder): [string, string, string, string];
3
9
  export declare function registerAccountCommands(program: Command, getAdapter: () => Promise<ExchangeAdapter>, isJson: () => boolean, getAdapterForExchange?: (exchange: string) => Promise<ExchangeAdapter>): void;