perp-cli 0.9.8 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. package/README.md +30 -25
  2. package/dist/_stderr-filter.d.ts +0 -0
  3. package/dist/_stderr-filter.js +30 -0
  4. package/dist/agent-wallet/expiry.d.ts +15 -0
  5. package/dist/agent-wallet/expiry.js +26 -0
  6. package/dist/agent-wallet/lighter-keystore.d.ts +34 -0
  7. package/dist/agent-wallet/lighter-keystore.js +232 -0
  8. package/dist/agent-wallet/passphrase.d.ts +13 -0
  9. package/dist/agent-wallet/passphrase.js +54 -0
  10. package/dist/agent-wallet/signing-strategy.d.ts +67 -0
  11. package/dist/agent-wallet/signing-strategy.js +51 -0
  12. package/dist/agent-wallet/store.d.ts +37 -0
  13. package/dist/agent-wallet/store.js +172 -0
  14. package/dist/api/public/_http.d.ts +15 -0
  15. package/dist/api/public/_http.js +24 -0
  16. package/dist/api/public/hyperliquid.js +36 -24
  17. package/dist/api/public/lighter.d.ts +7 -1
  18. package/dist/api/public/lighter.js +85 -37
  19. package/dist/api/public/pacifica.js +47 -18
  20. package/dist/bot/engine.js +23 -4
  21. package/dist/bot/presets.js +3 -3
  22. package/dist/bot/strategies/funding-arb-strategy.d.ts +0 -23
  23. package/dist/bot/strategies/funding-arb-strategy.js +41 -176
  24. package/dist/bot/strategies/funding-auto.js +2 -2
  25. package/dist/bridge-engine.js +102 -49
  26. package/dist/cli-spec.js +1 -2
  27. package/dist/commands/account.js +2 -500
  28. package/dist/commands/agent.d.ts +8 -2
  29. package/dist/commands/agent.js +1903 -366
  30. package/dist/commands/alerts.js +3 -1
  31. package/dist/commands/arb/index.js +37 -7
  32. package/dist/commands/arb-auto.js +44 -11
  33. package/dist/commands/arb.js +83 -34
  34. package/dist/commands/bot.d.ts +1 -1
  35. package/dist/commands/bot.js +20 -16
  36. package/dist/commands/bridge.d.ts +1 -1
  37. package/dist/commands/bridge.js +4 -4
  38. package/dist/commands/funds.d.ts +1 -1
  39. package/dist/commands/funds.js +18 -68
  40. package/dist/commands/jobs.d.ts +1 -1
  41. package/dist/commands/jobs.js +2 -2
  42. package/dist/commands/manage.d.ts +1 -1
  43. package/dist/commands/manage.js +12 -84
  44. package/dist/commands/plan.d.ts +1 -1
  45. package/dist/commands/plan.js +2 -2
  46. package/dist/commands/portfolio.d.ts +19 -3
  47. package/dist/commands/portfolio.js +747 -163
  48. package/dist/commands/rebalance.d.ts +1 -1
  49. package/dist/commands/rebalance.js +18 -12
  50. package/dist/commands/risk.js +2 -6
  51. package/dist/commands/settings.js +30 -53
  52. package/dist/commands/trade.js +16 -15
  53. package/dist/commands/wallet.d.ts +2 -1
  54. package/dist/commands/wallet.js +1122 -176
  55. package/dist/config.d.ts +9 -0
  56. package/dist/config.js +55 -9
  57. package/dist/errors.d.ts +64 -0
  58. package/dist/errors.js +82 -2
  59. package/dist/event-stream.js +12 -1
  60. package/dist/exchanges/aster-typed-data.d.ts +156 -0
  61. package/dist/exchanges/aster-typed-data.js +189 -0
  62. package/dist/exchanges/aster.d.ts +60 -11
  63. package/dist/exchanges/aster.js +278 -136
  64. package/dist/exchanges/hyperliquid.d.ts +14 -0
  65. package/dist/exchanges/hyperliquid.js +88 -34
  66. package/dist/exchanges/lighter-spot.js +19 -5
  67. package/dist/exchanges/lighter.d.ts +66 -0
  68. package/dist/exchanges/lighter.js +213 -31
  69. package/dist/exchanges/pacifica-typed-data.d.ts +75 -0
  70. package/dist/exchanges/pacifica-typed-data.js +74 -0
  71. package/dist/exchanges/pacifica.d.ts +29 -1
  72. package/dist/exchanges/pacifica.js +94 -6
  73. package/dist/funding/rates.js +59 -21
  74. package/dist/guardrail/contracts.d.ts +14 -0
  75. package/dist/guardrail/contracts.js +72 -0
  76. package/dist/guardrail/perp-guardrail.d.ts +21 -0
  77. package/dist/guardrail/perp-guardrail.js +145 -0
  78. package/dist/index.d.ts +1 -1
  79. package/dist/index.js +307 -362
  80. package/dist/jobs.js +3 -1
  81. package/dist/mcp-server.js +92 -88
  82. package/dist/position-history.js +47 -4
  83. package/dist/settings.d.ts +69 -3
  84. package/dist/settings.js +3 -2
  85. package/dist/signer/index.d.ts +2 -0
  86. package/dist/signer/index.js +2 -0
  87. package/dist/signer/ows-evm.d.ts +32 -0
  88. package/dist/signer/ows-evm.js +86 -0
  89. package/dist/signer/ows-loader.d.ts +2 -0
  90. package/dist/signer/ows-loader.js +6 -0
  91. package/dist/signer/ows-solana.d.ts +25 -0
  92. package/dist/signer/ows-solana.js +56 -0
  93. package/dist/smart-order.d.ts +8 -2
  94. package/dist/smart-order.js +46 -11
  95. package/dist/strategies/funding-arb.js +29 -8
  96. package/dist/trade-validator.js +30 -5
  97. package/dist/utils.d.ts +10 -0
  98. package/dist/utils.js +19 -0
  99. package/package.json +4 -2
  100. package/skills/perp-cli/SKILL.md +23 -14
  101. package/skills/perp-cli/references/agent-operations.md +6 -4
  102. package/skills/perp-cli/references/commands.md +55 -34
  103. package/skills/perp-cli/scripts/preflight.sh +4 -4
  104. package/skills/perp-cli/scripts/spot-perp-scan.sh +2 -2
  105. package/dist/__tests__/alert-logic.test.d.ts +0 -1
  106. package/dist/__tests__/alert-logic.test.js +0 -107
  107. package/dist/__tests__/arb-auto-3dex.test.d.ts +0 -1
  108. package/dist/__tests__/arb-auto-3dex.test.js +0 -397
  109. package/dist/__tests__/arb-history-stats.test.d.ts +0 -1
  110. package/dist/__tests__/arb-history-stats.test.js +0 -176
  111. package/dist/__tests__/arb-logic.test.d.ts +0 -1
  112. package/dist/__tests__/arb-logic.test.js +0 -84
  113. package/dist/__tests__/arb-manage.test.d.ts +0 -1
  114. package/dist/__tests__/arb-manage.test.js +0 -253
  115. package/dist/__tests__/arb-new-features.test.d.ts +0 -1
  116. package/dist/__tests__/arb-new-features.test.js +0 -457
  117. package/dist/__tests__/arb-sizing.test.d.ts +0 -1
  118. package/dist/__tests__/arb-sizing.test.js +0 -48
  119. package/dist/__tests__/arb-state.test.d.ts +0 -1
  120. package/dist/__tests__/arb-state.test.js +0 -284
  121. package/dist/__tests__/arb-userflow.test.d.ts +0 -1
  122. package/dist/__tests__/arb-userflow.test.js +0 -945
  123. package/dist/__tests__/arb-utils.test.d.ts +0 -1
  124. package/dist/__tests__/arb-utils.test.js +0 -264
  125. package/dist/__tests__/bot-conditions.test.d.ts +0 -1
  126. package/dist/__tests__/bot-conditions.test.js +0 -341
  127. package/dist/__tests__/client-id-tracker.test.d.ts +0 -1
  128. package/dist/__tests__/client-id-tracker.test.js +0 -137
  129. package/dist/__tests__/commands/new-atomic-commands.test.d.ts +0 -1
  130. package/dist/__tests__/commands/new-atomic-commands.test.js +0 -502
  131. package/dist/__tests__/commands/order-intent.test.d.ts +0 -1
  132. package/dist/__tests__/commands/order-intent.test.js +0 -600
  133. package/dist/__tests__/commands/trade-commands.test.d.ts +0 -1
  134. package/dist/__tests__/commands/trade-commands.test.js +0 -821
  135. package/dist/__tests__/config.test.d.ts +0 -1
  136. package/dist/__tests__/config.test.js +0 -86
  137. package/dist/__tests__/cross-chain-margin.test.d.ts +0 -1
  138. package/dist/__tests__/cross-chain-margin.test.js +0 -287
  139. package/dist/__tests__/dex-asset-map.test.d.ts +0 -1
  140. package/dist/__tests__/dex-asset-map.test.js +0 -191
  141. package/dist/__tests__/errors.test.d.ts +0 -1
  142. package/dist/__tests__/errors.test.js +0 -110
  143. package/dist/__tests__/event-stream.test.d.ts +0 -1
  144. package/dist/__tests__/event-stream.test.js +0 -276
  145. package/dist/__tests__/exchanges/interface.test.d.ts +0 -1
  146. package/dist/__tests__/exchanges/interface.test.js +0 -132
  147. package/dist/__tests__/exchanges/mock-adapter.d.ts +0 -69
  148. package/dist/__tests__/exchanges/mock-adapter.js +0 -137
  149. package/dist/__tests__/execution-log.test.d.ts +0 -1
  150. package/dist/__tests__/execution-log.test.js +0 -106
  151. package/dist/__tests__/funding-calc.test.d.ts +0 -1
  152. package/dist/__tests__/funding-calc.test.js +0 -71
  153. package/dist/__tests__/funding-history.test.d.ts +0 -1
  154. package/dist/__tests__/funding-history.test.js +0 -343
  155. package/dist/__tests__/funding-rates.test.d.ts +0 -1
  156. package/dist/__tests__/funding-rates.test.js +0 -342
  157. package/dist/__tests__/funding.test.d.ts +0 -1
  158. package/dist/__tests__/funding.test.js +0 -173
  159. package/dist/__tests__/gap-logic.test.d.ts +0 -1
  160. package/dist/__tests__/gap-logic.test.js +0 -43
  161. package/dist/__tests__/hip3-dex.test.d.ts +0 -1
  162. package/dist/__tests__/hip3-dex.test.js +0 -234
  163. package/dist/__tests__/integration/agent-features.integration.test.d.ts +0 -1
  164. package/dist/__tests__/integration/agent-features.integration.test.js +0 -553
  165. package/dist/__tests__/integration/atomic-commands.integration.test.d.ts +0 -13
  166. package/dist/__tests__/integration/atomic-commands.integration.test.js +0 -246
  167. package/dist/__tests__/integration/bridge-simulation.integration.test.d.ts +0 -1
  168. package/dist/__tests__/integration/bridge-simulation.integration.test.js +0 -453
  169. package/dist/__tests__/integration/bridge-strict.integration.test.d.ts +0 -1
  170. package/dist/__tests__/integration/bridge-strict.integration.test.js +0 -812
  171. package/dist/__tests__/integration/bridge.integration.test.d.ts +0 -1
  172. package/dist/__tests__/integration/bridge.integration.test.js +0 -309
  173. package/dist/__tests__/integration/cli-e2e.integration.test.d.ts +0 -1
  174. package/dist/__tests__/integration/cli-e2e.integration.test.js +0 -202
  175. package/dist/__tests__/integration/dex-arb.integration.test.d.ts +0 -1
  176. package/dist/__tests__/integration/dex-arb.integration.test.js +0 -116
  177. package/dist/__tests__/integration/envelope-consistency.integration.test.d.ts +0 -13
  178. package/dist/__tests__/integration/envelope-consistency.integration.test.js +0 -205
  179. package/dist/__tests__/integration/hip3-dex.integration.test.d.ts +0 -1
  180. package/dist/__tests__/integration/hip3-dex.integration.test.js +0 -147
  181. package/dist/__tests__/integration/hyperliquid.integration.test.d.ts +0 -1
  182. package/dist/__tests__/integration/hyperliquid.integration.test.js +0 -79
  183. package/dist/__tests__/integration/lighter.integration.test.d.ts +0 -1
  184. package/dist/__tests__/integration/lighter.integration.test.js +0 -53
  185. package/dist/__tests__/integration/new-commands-e2e.integration.test.d.ts +0 -9
  186. package/dist/__tests__/integration/new-commands-e2e.integration.test.js +0 -236
  187. package/dist/__tests__/integration/order-verification.integration.test.d.ts +0 -1
  188. package/dist/__tests__/integration/order-verification.integration.test.js +0 -321
  189. package/dist/__tests__/integration/pacifica.integration.test.d.ts +0 -1
  190. package/dist/__tests__/integration/pacifica.integration.test.js +0 -75
  191. package/dist/__tests__/integration/response-shapes.integration.test.d.ts +0 -1
  192. package/dist/__tests__/integration/response-shapes.integration.test.js +0 -278
  193. package/dist/__tests__/liquidity.test.d.ts +0 -1
  194. package/dist/__tests__/liquidity.test.js +0 -225
  195. package/dist/__tests__/plan-executor.test.d.ts +0 -1
  196. package/dist/__tests__/plan-executor.test.js +0 -314
  197. package/dist/__tests__/position-history.test.d.ts +0 -1
  198. package/dist/__tests__/position-history.test.js +0 -367
  199. package/dist/__tests__/retry.test.d.ts +0 -1
  200. package/dist/__tests__/retry.test.js +0 -310
  201. package/dist/__tests__/risk-assessment.test.d.ts +0 -1
  202. package/dist/__tests__/risk-assessment.test.js +0 -288
  203. package/dist/__tests__/security-adversarial.test.d.ts +0 -1
  204. package/dist/__tests__/security-adversarial.test.js +0 -574
  205. package/dist/__tests__/strategies.test.d.ts +0 -1
  206. package/dist/__tests__/strategies.test.js +0 -539
  207. package/dist/__tests__/trade-execution.test.d.ts +0 -1
  208. package/dist/__tests__/trade-execution.test.js +0 -129
  209. package/dist/__tests__/trade-validator.test.d.ts +0 -1
  210. package/dist/__tests__/trade-validator.test.js +0 -655
  211. package/dist/__tests__/utils.test.d.ts +0 -1
  212. package/dist/__tests__/utils.test.js +0 -76
  213. package/dist/arb/reconcile.d.ts +0 -28
  214. package/dist/arb/reconcile.js +0 -162
  215. package/dist/commands/alert.d.ts +0 -2
  216. package/dist/commands/alert.js +0 -421
  217. package/dist/commands/analytics.d.ts +0 -3
  218. package/dist/commands/analytics.js +0 -311
  219. package/dist/commands/arb-manage.d.ts +0 -5
  220. package/dist/commands/arb-manage.js +0 -5
  221. package/dist/commands/dashboard.d.ts +0 -3
  222. package/dist/commands/dashboard.js +0 -176
  223. package/dist/commands/deposit.d.ts +0 -4
  224. package/dist/commands/deposit.js +0 -573
  225. package/dist/commands/dex.d.ts +0 -3
  226. package/dist/commands/dex.js +0 -120
  227. package/dist/commands/env.d.ts +0 -2
  228. package/dist/commands/env.js +0 -136
  229. package/dist/commands/funding.d.ts +0 -3
  230. package/dist/commands/funding.js +0 -554
  231. package/dist/commands/gap.d.ts +0 -2
  232. package/dist/commands/gap.js +0 -305
  233. package/dist/commands/health.d.ts +0 -2
  234. package/dist/commands/health.js +0 -67
  235. package/dist/commands/multileg.d.ts +0 -16
  236. package/dist/commands/multileg.js +0 -174
  237. package/dist/commands/pnl.d.ts +0 -12
  238. package/dist/commands/pnl.js +0 -243
  239. package/dist/commands/run.d.ts +0 -3
  240. package/dist/commands/run.js +0 -202
  241. package/dist/commands/stream.d.ts +0 -5
  242. package/dist/commands/stream.js +0 -200
  243. package/dist/commands/withdraw.d.ts +0 -3
  244. package/dist/commands/withdraw.js +0 -187
  245. package/dist/exchanges/edgex.d.ts +0 -62
  246. package/dist/exchanges/edgex.js +0 -552
  247. package/dist/exchanges/nado.d.ts +0 -52
  248. package/dist/exchanges/nado.js +0 -223
  249. package/dist/funding/index.d.ts +0 -3
  250. package/dist/funding/index.js +0 -3
  251. package/dist/retry.d.ts +0 -74
  252. package/dist/retry.js +0 -129
  253. package/dist/ws/market-feed.d.ts +0 -74
  254. package/dist/ws/market-feed.js +0 -227
@@ -1,120 +0,0 @@
1
- import chalk from "chalk";
2
- import { HyperliquidAdapter } from "../exchanges/hyperliquid.js";
3
- import { printJson, jsonOk, jsonError, makeTable, formatUsd, withJsonErrors } from "../utils.js";
4
- export function registerDexCommands(program, getAdapter, isJson) {
5
- const dex = program.command("dex").description("HIP-3 deployed perp dex commands (Hyperliquid)");
6
- // ── dex list ──
7
- dex
8
- .command("list")
9
- .description("List all available HIP-3 deployed perp dexes")
10
- .action(async () => {
11
- await withJsonErrors(isJson(), async () => {
12
- const adapter = await getAdapter();
13
- if (!(adapter instanceof HyperliquidAdapter)) {
14
- if (isJson())
15
- return printJson(jsonError("INVALID_EXCHANGE", "HIP-3 dexes are only available on Hyperliquid. Use -e hyperliquid."));
16
- console.error(chalk.red("\n HIP-3 dexes are only available on Hyperliquid. Use -e hyperliquid.\n"));
17
- return;
18
- }
19
- const dexes = await adapter.listDeployedDexes();
20
- if (isJson())
21
- return printJson(jsonOk(dexes));
22
- if (dexes.length === 0) {
23
- console.log(chalk.gray("\n No deployed dexes found.\n"));
24
- return;
25
- }
26
- console.log(chalk.cyan.bold("\n HIP-3 Deployed Perp DEXes\n"));
27
- const rows = dexes.map(d => [
28
- chalk.white.bold(d.name),
29
- chalk.gray(d.deployer.slice(0, 10) + "..."),
30
- String(d.assets.length),
31
- d.assets.slice(0, 5).join(", ") + (d.assets.length > 5 ? ` +${d.assets.length - 5}` : ""),
32
- ]);
33
- console.log(makeTable(["DEX", "Deployer", "Assets", "Markets"], rows));
34
- console.log(chalk.gray(`\n Use --dex <name> to trade on a deployed dex.\n`));
35
- console.log(chalk.gray(` Example: perp -e hyperliquid --dex xyz market list\n`));
36
- });
37
- });
38
- // ── dex markets <dex-name> ──
39
- dex
40
- .command("markets <dexName>")
41
- .description("List all markets on a specific HIP-3 dex")
42
- .action(async (dexName) => {
43
- await withJsonErrors(isJson(), async () => {
44
- const adapter = await getAdapter();
45
- if (!(adapter instanceof HyperliquidAdapter)) {
46
- if (isJson())
47
- return printJson(jsonError("INVALID_EXCHANGE", "HIP-3 dexes are only available on Hyperliquid. Use -e hyperliquid."));
48
- console.error(chalk.red("\n HIP-3 dexes are only available on Hyperliquid. Use -e hyperliquid.\n"));
49
- return;
50
- }
51
- // Temporarily switch dex, fetch markets, then restore
52
- const prevDex = adapter.dex;
53
- adapter.setDex(dexName);
54
- try {
55
- const markets = await adapter.getMarkets();
56
- if (isJson())
57
- return printJson(jsonOk({ dex: dexName, markets }));
58
- if (markets.length === 0) {
59
- console.log(chalk.gray(`\n No markets found on dex "${dexName}".\n`));
60
- return;
61
- }
62
- console.log(chalk.cyan.bold(`\n ${dexName.toUpperCase()} DEX Markets\n`));
63
- const rows = markets.map(m => [
64
- chalk.white.bold(m.symbol),
65
- `$${formatUsd(m.markPrice)}`,
66
- m.fundingRate !== "0" ? `${(Number(m.fundingRate) * 100).toFixed(4)}%` : chalk.gray("-"),
67
- `$${formatUsd(m.volume24h)}`,
68
- `$${formatUsd(m.openInterest)}`,
69
- `${m.maxLeverage}x`,
70
- ]);
71
- console.log(makeTable(["Symbol", "Mark Price", "Funding", "24h Volume", "OI", "Max Lev"], rows));
72
- console.log(chalk.gray(`\n Trade: perp -e hyperliquid --dex ${dexName} trade market <symbol> <side> <size>\n`));
73
- }
74
- finally {
75
- adapter.setDex(prevDex);
76
- }
77
- });
78
- });
79
- // ── dex balance <dex-name> ──
80
- dex
81
- .command("balance <dexName>")
82
- .description("Show balance on a specific HIP-3 dex")
83
- .action(async (dexName) => {
84
- await withJsonErrors(isJson(), async () => {
85
- const adapter = await getAdapter();
86
- if (!(adapter instanceof HyperliquidAdapter)) {
87
- if (isJson())
88
- return printJson(jsonError("INVALID_EXCHANGE", "HIP-3 dexes are only available on Hyperliquid. Use -e hyperliquid."));
89
- console.error(chalk.red("\n HIP-3 dexes are only available on Hyperliquid. Use -e hyperliquid.\n"));
90
- return;
91
- }
92
- const prevDex = adapter.dex;
93
- adapter.setDex(dexName);
94
- try {
95
- const [balance, positions] = await Promise.all([
96
- adapter.getBalance(),
97
- adapter.getPositions(),
98
- ]);
99
- if (isJson())
100
- return printJson(jsonOk({ dex: dexName, balance, positions }));
101
- console.log(chalk.cyan.bold(`\n ${dexName.toUpperCase()} DEX Balance\n`));
102
- console.log(` Equity: $${formatUsd(balance.equity)}`);
103
- console.log(` Available: $${formatUsd(balance.available)}`);
104
- console.log(` Margin Used: $${formatUsd(balance.marginUsed)}`);
105
- console.log(` uPnL: $${formatUsd(balance.unrealizedPnl)}`);
106
- if (positions.length > 0) {
107
- console.log(chalk.white.bold("\n Positions:"));
108
- for (const p of positions) {
109
- const color = p.side === "long" ? chalk.green : chalk.red;
110
- console.log(` ${color(p.side.toUpperCase().padEnd(5))} ${chalk.white(p.symbol.padEnd(16))} ${p.size.padEnd(10)} entry: $${Number(p.entryPrice).toFixed(2)} pnl: $${Number(p.unrealizedPnl).toFixed(2)}`);
111
- }
112
- }
113
- console.log();
114
- }
115
- finally {
116
- adapter.setDex(prevDex);
117
- }
118
- });
119
- });
120
- }
@@ -1,2 +0,0 @@
1
- import { Command } from "commander";
2
- export declare function registerEnvCommands(program: Command, isJson: () => boolean): void;
@@ -1,136 +0,0 @@
1
- import chalk from "chalk";
2
- import { printJson, jsonOk } from "../utils.js";
3
- import { ENV_FILE, loadEnvFile, setEnvVar, EXCHANGE_ENV_MAP, validateKey } from "./init.js";
4
- // Resolve exchange alias → env var key
5
- function resolveEnvKey(nameOrKey) {
6
- // Direct env var name
7
- const upper = nameOrKey.toUpperCase();
8
- for (const info of Object.values(EXCHANGE_ENV_MAP)) {
9
- if (info.envKey === upper)
10
- return { envKey: info.envKey, chain: info.chain };
11
- }
12
- // Exchange name alias
13
- const info = EXCHANGE_ENV_MAP[nameOrKey.toLowerCase()];
14
- if (info)
15
- return { envKey: info.envKey, chain: info.chain };
16
- // Common aliases
17
- const aliases = { hl: "hyperliquid", pac: "pacifica", lt: "lighter" };
18
- const aliased = aliases[nameOrKey.toLowerCase()];
19
- if (aliased)
20
- return resolveEnvKey(aliased);
21
- return null;
22
- }
23
- export function registerEnvCommands(program, isJson) {
24
- const env = program.command("env").description("Manage ~/.perp/.env configuration");
25
- // ── perp env show ──
26
- env
27
- .command("show")
28
- .description("Show current configuration")
29
- .action(async () => {
30
- const stored = loadEnvFile();
31
- const entries = [];
32
- for (const [exchange, info] of Object.entries(EXCHANGE_ENV_MAP)) {
33
- const fromFile = stored[info.envKey];
34
- const fromEnv = process.env[info.envKey];
35
- if (fromFile) {
36
- entries.push({ name: exchange, chain: info.chain, key: fromFile, source: "~/.perp/.env" });
37
- }
38
- else if (fromEnv) {
39
- entries.push({ name: exchange, chain: info.chain, key: fromEnv, source: "environment" });
40
- }
41
- }
42
- // Derive addresses
43
- const results = [];
44
- for (const entry of entries) {
45
- const { valid, address } = await validateKey(entry.chain, entry.key);
46
- results.push({ name: entry.name, address: valid ? address : "(invalid key)", source: entry.source });
47
- }
48
- if (isJson()) {
49
- const data = results.map((r) => ({ exchange: r.name, address: r.address, source: r.source }));
50
- return printJson(jsonOk({ envFile: ENV_FILE, exchanges: data }));
51
- }
52
- console.log(chalk.cyan.bold("\n perp-cli Configuration\n"));
53
- console.log(` File: ${chalk.gray(ENV_FILE)}\n`);
54
- if (results.length === 0) {
55
- console.log(chalk.gray(" No keys configured. Run 'perp init' or 'perp env set <exchange> <key>'\n"));
56
- return;
57
- }
58
- for (const { name, address, source } of results) {
59
- console.log(` ${chalk.cyan(name.padEnd(14))} ${chalk.green(address)} ${chalk.gray(source)}`);
60
- }
61
- console.log();
62
- });
63
- // ── perp env set <exchange|key> <value> ──
64
- env
65
- .command("set <name> <value>")
66
- .description("Set a key (exchange name or env var name)")
67
- .action(async (name, value) => {
68
- const resolved = resolveEnvKey(name);
69
- if (resolved) {
70
- // Validate the key
71
- const { valid, address } = await validateKey(resolved.chain, value);
72
- if (!valid) {
73
- if (isJson()) {
74
- const { jsonError } = await import("../utils.js");
75
- return printJson(jsonError("INVALID_PARAMS", `Invalid ${resolved.chain} private key`));
76
- }
77
- console.error(chalk.red(`\n Invalid ${resolved.chain} private key.\n`));
78
- process.exit(1);
79
- }
80
- const normalized = resolved.chain === "evm"
81
- ? (value.startsWith("0x") ? value : `0x${value}`)
82
- : value;
83
- setEnvVar(resolved.envKey, normalized);
84
- if (isJson())
85
- return printJson(jsonOk({ key: resolved.envKey, address, file: ENV_FILE }));
86
- console.log(chalk.green(`\n ${resolved.envKey} set.`));
87
- console.log(` Address: ${chalk.gray(address)}`);
88
- console.log(` File: ${chalk.gray("~/.perp/.env")}\n`);
89
- }
90
- else {
91
- // Raw env var (e.g. LIGHTER_API_KEY, custom vars)
92
- setEnvVar(name, value);
93
- if (isJson())
94
- return printJson(jsonOk({ key: name, file: ENV_FILE }));
95
- console.log(chalk.green(`\n ${name} set.`));
96
- console.log(` File: ${chalk.gray("~/.perp/.env")}\n`);
97
- }
98
- });
99
- // ── perp env remove <name> ──
100
- env
101
- .command("remove <name>")
102
- .description("Remove a key from ~/.perp/.env")
103
- .action(async (name) => {
104
- const resolved = resolveEnvKey(name);
105
- const envKey = resolved?.envKey || name;
106
- const env = loadEnvFile();
107
- if (!(envKey in env)) {
108
- if (isJson()) {
109
- const { jsonError } = await import("../utils.js");
110
- return printJson(jsonError("NOT_FOUND", `${envKey} not found in ~/.perp/.env`));
111
- }
112
- console.log(chalk.gray(`\n ${envKey} not found in ~/.perp/.env\n`));
113
- return;
114
- }
115
- delete env[envKey];
116
- // Rewrite file
117
- const { writeFileSync } = await import("fs");
118
- const lines = ["# perp-cli configuration", "# Generated by 'perp init' — edit freely", ""];
119
- for (const [k, v] of Object.entries(env))
120
- lines.push(`${k}=${v}`);
121
- lines.push("");
122
- writeFileSync(ENV_FILE, lines.join("\n"), { mode: 0o600 });
123
- if (isJson())
124
- return printJson(jsonOk({ removed: envKey }));
125
- console.log(chalk.yellow(`\n ${envKey} removed from ~/.perp/.env\n`));
126
- });
127
- // ── perp env path ──
128
- env
129
- .command("path")
130
- .description("Print env file path")
131
- .action(() => {
132
- if (isJson())
133
- return printJson(jsonOk({ path: ENV_FILE }));
134
- console.log(ENV_FILE);
135
- });
136
- }
@@ -1,3 +0,0 @@
1
- import { Command } from "commander";
2
- import type { ExchangeAdapter } from "../exchanges/interface.js";
3
- export declare function registerFundingCommands(program: Command, isJson: () => boolean, getAdapterForExchange?: (exchange: string) => Promise<ExchangeAdapter>): void;