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
@@ -1,2 +1,3 @@
1
1
  import { Command } from "commander";
2
+ import "../exchanges/venues/index.js";
2
3
  export declare function registerAlertCommands(program: Command, isJson: () => boolean): void;
@@ -5,6 +5,11 @@ import { validateBotToken as validateDiscordBot, sendDiscordDM, openDMChannel }
5
5
  import { validateTelegramBot, sendTelegramMessage, getRecentChatId } from "../telegram.js";
6
6
  import { printJson, jsonOk } from "../utils.js";
7
7
  import { fetchAllFundingRates } from "../funding-rates.js";
8
+ import "../exchanges/venues/index.js";
9
+ import { resolveVenueId, getVenue } from "../exchanges/venue.js";
10
+ import { PerpError } from "../errors.js";
11
+ import { scrubSecretEnv } from "../secret-env.js";
12
+ import { networkOf } from "../cli-flags.js";
8
13
  function ask(rl, question) {
9
14
  return new Promise((resolve) => rl.question(question, (answer) => resolve(answer.trim())));
10
15
  }
@@ -99,8 +104,7 @@ export function registerAlertCommands(program, isJson) {
99
104
  .action(async () => {
100
105
  const settings = loadSettings();
101
106
  if (!hasAnyService(settings.alerts)) {
102
- console.log(chalk.red(" Not configured. Run: perp alerts setup\n"));
103
- return;
107
+ throw new PerpError("INVALID_PARAMS", "No alert messaging service (Telegram / Discord) is configured", { remediation: "Run: perp alerts setup" });
104
108
  }
105
109
  const msg = `[TEST] perp-cli alert system is working. ${new Date().toISOString()}`;
106
110
  try {
@@ -110,9 +114,9 @@ export function registerAlertCommands(program, isJson) {
110
114
  console.log(chalk.green(` Test message sent! (${serviceStatus(settings.alerts).join(", ")})\n`));
111
115
  }
112
116
  catch (err) {
113
- if (isJson())
114
- return printJson(jsonOk({ error: String(err) }));
115
- console.log(chalk.red(` Failed: ${err instanceof Error ? err.message : err}\n`));
117
+ throw new PerpError("EXCHANGE_ERROR", `Test alert failed: ${err instanceof Error ? err.message : String(err)}`, {
118
+ remediation: "Check the bot token / chat id or webhook: perp alerts setup",
119
+ });
116
120
  }
117
121
  });
118
122
  // ── alerts add ──
@@ -122,7 +126,7 @@ export function registerAlertCommands(program, isJson) {
122
126
  .argument("[symbol]", "Symbol to monitor (e.g. ETH, BTC)")
123
127
  .argument("[threshold]", "Annual funding rate % threshold")
124
128
  .option("--all", "Monitor all symbols")
125
- .option("--exchange <ex>", "Filter by exchange (hl, pac, lt)")
129
+ .option("--exchange <ex>", "Filter by venue id or alias (e.g. hl, pac, lt, ast, lighter-rh, ondo, arcus, qfex)")
126
130
  .option("--below", "Alert when rate drops below threshold (default: above)")
127
131
  .action((symbol, thresholdStr, opts) => {
128
132
  const sym = opts.all ? "*" : symbol?.toUpperCase();
@@ -136,8 +140,12 @@ export function registerAlertCommands(program, isJson) {
136
140
  console.log(chalk.red(" Threshold must be a positive number (annual %)\n"));
137
141
  return;
138
142
  }
139
- const aliasMap = { hl: "hyperliquid", pac: "pacifica", lt: "lighter" };
140
- const exchange = opts.exchange ? (aliasMap[opts.exchange.toLowerCase()] || opts.exchange.toLowerCase()) : "*";
143
+ // Unknown venue → UNKNOWN_VENUE (a stored rule with a typo would never match).
144
+ // `--exchange` is also the root option (-e, --exchange), which commander gives to the root
145
+ // program: read it there when it was passed on the command line (never its default venue).
146
+ const rootExchange = program.getOptionValueSource("exchange") === "cli" ? String(program.opts().exchange) : undefined;
147
+ const filter = opts.exchange ?? rootExchange;
148
+ const exchange = filter !== undefined ? resolveVenueId(filter) : "*";
141
149
  const settings = loadSettings();
142
150
  const rule = {
143
151
  id: `${sym}-${exchange}-${Date.now()}`,
@@ -240,13 +248,11 @@ export function registerAlertCommands(program, isJson) {
240
248
  .action(async (opts) => {
241
249
  const settings = loadSettings();
242
250
  if (!hasAnyService(settings.alerts)) {
243
- console.log(chalk.red(" No messaging service configured. Run: perp alerts setup\n"));
244
- return;
251
+ throw new PerpError("INVALID_PARAMS", "No alert messaging service (Telegram / Discord) is configured", { remediation: "Run: perp alerts setup" });
245
252
  }
246
253
  const rules = settings.alerts.rules.filter(r => r.enabled);
247
254
  if (rules.length === 0) {
248
- console.log(chalk.red(" No active alert rules. Add one: perp alerts add ETH 30\n"));
249
- return;
255
+ throw new PerpError("INVALID_PARAMS", "No active alert rules", { remediation: "Add one: perp alerts add ETH 30" });
250
256
  }
251
257
  const intervalSec = parseInt(opts.interval || String(settings.alerts.intervalSec)) || 300;
252
258
  const cooldownMin = parseInt(opts.cooldown || String(settings.alerts.cooldownMin)) || 60;
@@ -254,27 +260,23 @@ export function registerAlertCommands(program, isJson) {
254
260
  if (opts.background) {
255
261
  const { execSync } = await import("child_process");
256
262
  try {
257
- execSync("which tmux", { stdio: "ignore" });
263
+ execSync("which tmux", { stdio: "ignore", env: scrubSecretEnv(process.env) });
258
264
  }
259
265
  catch {
260
266
  console.log(chalk.red(" tmux required for --background. Install: brew install tmux\n"));
261
267
  return;
262
268
  }
263
269
  const session = `perp-alerts-${Date.now().toString(36)}`;
264
- const nodeCmd = process.argv[0];
265
- const cliPath = process.argv[1];
266
- const args = [
270
+ // The daemon reads public funding rates + settings.json only: no key material is
271
+ // handed to it (SSOT Rule #3) — launchTmuxChild strips secret env vars.
272
+ const { launchTmuxChild } = await import("../jobs.js");
273
+ launchTmuxChild(session, [
274
+ // Same network as the parent (review L6): the daemon reads that network's funding rates.
275
+ "-n", networkOf(program),
267
276
  "alerts", "start",
268
277
  "--interval", String(intervalSec),
269
278
  "--cooldown", String(cooldownMin),
270
- ].join(" ");
271
- // Pass through env vars for keys
272
- // L2 agent key + indices now live in ~/.perp keystore + settings.agents (SSOT Rule #3),
273
- // not env. Only Tier 3 master PKs need passthrough.
274
- const envKeys = ["LIGHTER_PRIVATE_KEY", "HL_PRIVATE_KEY", "PACIFICA_PRIVATE_KEY", "ASTER_PRIVATE_KEY", "PRIVATE_KEY"];
275
- const envStr = envKeys.filter(k => process.env[k]).map(k => `${k}='${process.env[k]}'`).join(" ");
276
- const cmd = `${envStr} ${nodeCmd} ${cliPath} ${args}`;
277
- execSync(`tmux new-session -d -s ${session} '${cmd.replace(/'/g, "'\\''")}'`);
279
+ ], null, false);
278
280
  if (isJson())
279
281
  return printJson(jsonOk({ status: "started", session, rules: rules.length, interval: intervalSec }));
280
282
  console.log(chalk.green(`\n Alert daemon started in background.`));
@@ -323,7 +325,7 @@ export function registerAlertCommands(program, isJson) {
323
325
  continue;
324
326
  cooldowns.set(cooldownKey, Date.now());
325
327
  alertCount++;
326
- const exAbbr = rate.exchange === "pacifica" ? "PAC" : rate.exchange === "hyperliquid" ? "HL" : "LT";
328
+ const exAbbr = getVenue(rate.exchange).displayName;
327
329
  const sign = rate.annualizedPct > 0 ? "+" : "";
328
330
  const msg = [
329
331
  `${comparison.symbol} funding alert`,
@@ -362,17 +364,18 @@ export function registerAlertCommands(program, isJson) {
362
364
  .action(async () => {
363
365
  const { execSync } = await import("child_process");
364
366
  try {
365
- const sessions = execSync("tmux list-sessions -F '#{session_name}'", { encoding: "utf-8" })
366
- .trim().split("\n").filter(s => s.startsWith("perp-alerts-"));
367
+ const sessions = execSync("tmux list-sessions -F '#{session_name}'", { encoding: "utf-8", env: scrubSecretEnv(process.env) })
368
+ .trim().split("\n").filter(s => /^perp-alerts-[A-Za-z0-9_-]+$/.test(s));
367
369
  if (sessions.length === 0) {
368
370
  if (isJson())
369
371
  return printJson(jsonOk({ status: "none" }));
370
372
  console.log(chalk.gray(" No alert daemon running.\n"));
371
373
  return;
372
374
  }
375
+ const { killTmuxSession } = await import("../jobs.js");
373
376
  for (const session of sessions) {
374
377
  try {
375
- execSync(`tmux kill-session -t ${session}`);
378
+ killTmuxSession(session);
376
379
  }
377
380
  catch { /* already dead */ }
378
381
  }
@@ -1,3 +1,62 @@
1
1
  import { Command } from "commander";
2
- import { type ExchangeAdapter } from "../../exchanges/index.js";
2
+ import { type ExchangeAdapter, type ExchangePosition } from "../../exchanges/index.js";
3
+ import { type ExecutionRecord } from "../../execution-log.js";
4
+ /**
5
+ * Venues an arb leg can sit on: every registered trading venue with a configured
6
+ * credential source (registry order). Never a hard-coded list — a venue added to the
7
+ * registry is covered by `arb status` / `arb close` without touching this file.
8
+ */
9
+ export declare function listArbVenues(): Promise<string[]>;
10
+ /**
11
+ * Positions of every venue in `venues`. A venue whose adapter cannot be built or whose
12
+ * positions read fails is an error (Rule #2): an unread venue is not "no positions" —
13
+ * a hidden leg would make a live pair look closed.
14
+ */
15
+ export declare function readArbVenuePositions(venues: readonly string[], getAdapter: (exchange: string) => Promise<ExchangeAdapter>): Promise<{
16
+ exchange: string;
17
+ position: ExchangePosition;
18
+ }[]>;
19
+ /**
20
+ * State-file entries the venues do not confirm: no live pair with the same symbol and
21
+ * legs. `arb status` reports them apart from the live pairs (the venue is the source of truth).
22
+ */
23
+ export declare function staleArbStateEntries(persisted: ReadonlyArray<{
24
+ id: string;
25
+ symbol: string;
26
+ longExchange: string;
27
+ shortExchange: string;
28
+ entryTime: string;
29
+ mode?: "perp-perp" | "spot-perp";
30
+ spotExchange?: string;
31
+ }>, livePerpPerp: ReadonlyArray<{
32
+ symbol: string;
33
+ longExchange: string;
34
+ shortExchange: string;
35
+ }>, liveSpotPerp: ReadonlyArray<{
36
+ symbol: string;
37
+ spotExchange: string;
38
+ perpExchange: string;
39
+ }>): {
40
+ id: string;
41
+ symbol: string;
42
+ mode: "perp-perp" | "spot-perp";
43
+ longExchange: string;
44
+ shortExchange: string;
45
+ entryTime: string;
46
+ reason: string;
47
+ }[];
48
+ export type ArbPairProvenance = "state" | "executionLog" | "inferred";
49
+ /**
50
+ * Whether a live long/short pair was opened by arb: an arb state entry for exactly these legs
51
+ * ("state"), else the latest successful arb_entry for exactly these legs in the execution log —
52
+ * combined (meta.arbPairId / meta.longExchange + shortExchange) or per-leg (meta.leg long on the
53
+ * long venue + leg short on the short venue within 10 min) — with no successful arb_close of the
54
+ * pair after it ("executionLog"). Anything else is "inferred". Never a symbol-only match.
55
+ */
56
+ export declare function arbPairProvenance(symbol: string, longExchange: string, shortExchange: string, persisted: ReadonlyArray<{
57
+ symbol: string;
58
+ longExchange: string;
59
+ shortExchange: string;
60
+ mode?: "perp-perp" | "spot-perp";
61
+ }>, records: ReadonlyArray<ExecutionRecord>): ArbPairProvenance;
3
62
  export declare function registerArbManageCommands(program: Command, getAdapterForExchange: (exchange: string) => Promise<ExchangeAdapter>, isJson: () => boolean): void;