perp-cli 0.11.0 → 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 (240) 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/bridge-engine.js +102 -49
  21. package/dist/cli-spec.js +1 -2
  22. package/dist/commands/account.js +2 -500
  23. package/dist/commands/agent.d.ts +8 -2
  24. package/dist/commands/agent.js +1903 -366
  25. package/dist/commands/alerts.js +3 -1
  26. package/dist/commands/arb/index.js +37 -7
  27. package/dist/commands/arb-auto.js +44 -11
  28. package/dist/commands/arb.js +83 -34
  29. package/dist/commands/bot.d.ts +1 -1
  30. package/dist/commands/bot.js +18 -14
  31. package/dist/commands/bridge.d.ts +1 -1
  32. package/dist/commands/bridge.js +4 -4
  33. package/dist/commands/funds.d.ts +1 -1
  34. package/dist/commands/funds.js +18 -68
  35. package/dist/commands/jobs.d.ts +1 -1
  36. package/dist/commands/jobs.js +2 -2
  37. package/dist/commands/manage.d.ts +1 -1
  38. package/dist/commands/manage.js +12 -84
  39. package/dist/commands/plan.d.ts +1 -1
  40. package/dist/commands/plan.js +2 -2
  41. package/dist/commands/portfolio.d.ts +19 -3
  42. package/dist/commands/portfolio.js +747 -163
  43. package/dist/commands/rebalance.d.ts +1 -1
  44. package/dist/commands/rebalance.js +18 -12
  45. package/dist/commands/risk.js +2 -6
  46. package/dist/commands/settings.js +30 -53
  47. package/dist/commands/trade.js +16 -15
  48. package/dist/commands/wallet.d.ts +2 -1
  49. package/dist/commands/wallet.js +756 -28
  50. package/dist/errors.d.ts +64 -0
  51. package/dist/errors.js +82 -2
  52. package/dist/event-stream.js +12 -1
  53. package/dist/exchanges/aster-typed-data.d.ts +156 -0
  54. package/dist/exchanges/aster-typed-data.js +189 -0
  55. package/dist/exchanges/aster.d.ts +60 -11
  56. package/dist/exchanges/aster.js +278 -136
  57. package/dist/exchanges/hyperliquid.d.ts +14 -0
  58. package/dist/exchanges/hyperliquid.js +84 -34
  59. package/dist/exchanges/lighter-spot.js +14 -3
  60. package/dist/exchanges/lighter.d.ts +66 -0
  61. package/dist/exchanges/lighter.js +199 -27
  62. package/dist/exchanges/pacifica-typed-data.d.ts +75 -0
  63. package/dist/exchanges/pacifica-typed-data.js +74 -0
  64. package/dist/exchanges/pacifica.d.ts +29 -1
  65. package/dist/exchanges/pacifica.js +94 -6
  66. package/dist/funding/rates.js +59 -21
  67. package/dist/guardrail/perp-guardrail.js +9 -1
  68. package/dist/index.d.ts +1 -1
  69. package/dist/index.js +255 -360
  70. package/dist/jobs.js +3 -1
  71. package/dist/mcp-server.js +85 -83
  72. package/dist/position-history.js +47 -4
  73. package/dist/settings.d.ts +67 -3
  74. package/dist/settings.js +1 -2
  75. package/dist/signer/ows-evm.d.ts +14 -0
  76. package/dist/signer/ows-evm.js +28 -9
  77. package/dist/smart-order.d.ts +8 -2
  78. package/dist/smart-order.js +46 -11
  79. package/dist/strategies/funding-arb.js +29 -8
  80. package/dist/trade-validator.js +30 -5
  81. package/dist/utils.d.ts +10 -0
  82. package/dist/utils.js +19 -0
  83. package/package.json +2 -2
  84. package/skills/perp-cli/SKILL.md +23 -14
  85. package/skills/perp-cli/references/agent-operations.md +6 -4
  86. package/skills/perp-cli/references/commands.md +55 -34
  87. package/skills/perp-cli/scripts/preflight.sh +4 -4
  88. package/skills/perp-cli/scripts/spot-perp-scan.sh +2 -2
  89. package/dist/__tests__/alert-logic.test.d.ts +0 -1
  90. package/dist/__tests__/alert-logic.test.js +0 -107
  91. package/dist/__tests__/arb-auto-3dex.test.d.ts +0 -1
  92. package/dist/__tests__/arb-auto-3dex.test.js +0 -397
  93. package/dist/__tests__/arb-history-stats.test.d.ts +0 -1
  94. package/dist/__tests__/arb-history-stats.test.js +0 -176
  95. package/dist/__tests__/arb-logic.test.d.ts +0 -1
  96. package/dist/__tests__/arb-logic.test.js +0 -84
  97. package/dist/__tests__/arb-manage.test.d.ts +0 -1
  98. package/dist/__tests__/arb-manage.test.js +0 -253
  99. package/dist/__tests__/arb-new-features.test.d.ts +0 -1
  100. package/dist/__tests__/arb-new-features.test.js +0 -457
  101. package/dist/__tests__/arb-sizing.test.d.ts +0 -1
  102. package/dist/__tests__/arb-sizing.test.js +0 -48
  103. package/dist/__tests__/arb-state.test.d.ts +0 -1
  104. package/dist/__tests__/arb-state.test.js +0 -284
  105. package/dist/__tests__/arb-userflow.test.d.ts +0 -1
  106. package/dist/__tests__/arb-userflow.test.js +0 -945
  107. package/dist/__tests__/arb-utils.test.d.ts +0 -1
  108. package/dist/__tests__/arb-utils.test.js +0 -264
  109. package/dist/__tests__/bot-conditions.test.d.ts +0 -1
  110. package/dist/__tests__/bot-conditions.test.js +0 -341
  111. package/dist/__tests__/client-id-tracker.test.d.ts +0 -1
  112. package/dist/__tests__/client-id-tracker.test.js +0 -137
  113. package/dist/__tests__/commands/new-atomic-commands.test.d.ts +0 -1
  114. package/dist/__tests__/commands/new-atomic-commands.test.js +0 -502
  115. package/dist/__tests__/commands/order-intent.test.d.ts +0 -1
  116. package/dist/__tests__/commands/order-intent.test.js +0 -600
  117. package/dist/__tests__/commands/trade-commands.test.d.ts +0 -1
  118. package/dist/__tests__/commands/trade-commands.test.js +0 -821
  119. package/dist/__tests__/config.test.d.ts +0 -1
  120. package/dist/__tests__/config.test.js +0 -86
  121. package/dist/__tests__/cross-chain-margin.test.d.ts +0 -1
  122. package/dist/__tests__/cross-chain-margin.test.js +0 -287
  123. package/dist/__tests__/dex-asset-map.test.d.ts +0 -1
  124. package/dist/__tests__/dex-asset-map.test.js +0 -191
  125. package/dist/__tests__/errors.test.d.ts +0 -1
  126. package/dist/__tests__/errors.test.js +0 -110
  127. package/dist/__tests__/event-stream.test.d.ts +0 -1
  128. package/dist/__tests__/event-stream.test.js +0 -276
  129. package/dist/__tests__/exchanges/interface.test.d.ts +0 -1
  130. package/dist/__tests__/exchanges/interface.test.js +0 -132
  131. package/dist/__tests__/exchanges/mock-adapter.d.ts +0 -69
  132. package/dist/__tests__/exchanges/mock-adapter.js +0 -137
  133. package/dist/__tests__/execution-log.test.d.ts +0 -1
  134. package/dist/__tests__/execution-log.test.js +0 -106
  135. package/dist/__tests__/funding-calc.test.d.ts +0 -1
  136. package/dist/__tests__/funding-calc.test.js +0 -71
  137. package/dist/__tests__/funding-history.test.d.ts +0 -1
  138. package/dist/__tests__/funding-history.test.js +0 -343
  139. package/dist/__tests__/funding-rates.test.d.ts +0 -1
  140. package/dist/__tests__/funding-rates.test.js +0 -342
  141. package/dist/__tests__/funding.test.d.ts +0 -1
  142. package/dist/__tests__/funding.test.js +0 -173
  143. package/dist/__tests__/gap-logic.test.d.ts +0 -1
  144. package/dist/__tests__/gap-logic.test.js +0 -43
  145. package/dist/__tests__/hip3-dex.test.d.ts +0 -1
  146. package/dist/__tests__/hip3-dex.test.js +0 -234
  147. package/dist/__tests__/integration/agent-features.integration.test.d.ts +0 -1
  148. package/dist/__tests__/integration/agent-features.integration.test.js +0 -553
  149. package/dist/__tests__/integration/atomic-commands.integration.test.d.ts +0 -13
  150. package/dist/__tests__/integration/atomic-commands.integration.test.js +0 -246
  151. package/dist/__tests__/integration/bridge-simulation.integration.test.d.ts +0 -1
  152. package/dist/__tests__/integration/bridge-simulation.integration.test.js +0 -453
  153. package/dist/__tests__/integration/bridge-strict.integration.test.d.ts +0 -1
  154. package/dist/__tests__/integration/bridge-strict.integration.test.js +0 -812
  155. package/dist/__tests__/integration/bridge.integration.test.d.ts +0 -1
  156. package/dist/__tests__/integration/bridge.integration.test.js +0 -309
  157. package/dist/__tests__/integration/cli-e2e.integration.test.d.ts +0 -1
  158. package/dist/__tests__/integration/cli-e2e.integration.test.js +0 -202
  159. package/dist/__tests__/integration/dex-arb.integration.test.d.ts +0 -1
  160. package/dist/__tests__/integration/dex-arb.integration.test.js +0 -116
  161. package/dist/__tests__/integration/envelope-consistency.integration.test.d.ts +0 -13
  162. package/dist/__tests__/integration/envelope-consistency.integration.test.js +0 -205
  163. package/dist/__tests__/integration/hip3-dex.integration.test.d.ts +0 -1
  164. package/dist/__tests__/integration/hip3-dex.integration.test.js +0 -147
  165. package/dist/__tests__/integration/hyperliquid.integration.test.d.ts +0 -1
  166. package/dist/__tests__/integration/hyperliquid.integration.test.js +0 -79
  167. package/dist/__tests__/integration/lighter.integration.test.d.ts +0 -1
  168. package/dist/__tests__/integration/lighter.integration.test.js +0 -53
  169. package/dist/__tests__/integration/new-commands-e2e.integration.test.d.ts +0 -9
  170. package/dist/__tests__/integration/new-commands-e2e.integration.test.js +0 -236
  171. package/dist/__tests__/integration/order-verification.integration.test.d.ts +0 -1
  172. package/dist/__tests__/integration/order-verification.integration.test.js +0 -321
  173. package/dist/__tests__/integration/pacifica.integration.test.d.ts +0 -1
  174. package/dist/__tests__/integration/pacifica.integration.test.js +0 -75
  175. package/dist/__tests__/integration/response-shapes.integration.test.d.ts +0 -1
  176. package/dist/__tests__/integration/response-shapes.integration.test.js +0 -278
  177. package/dist/__tests__/liquidity.test.d.ts +0 -1
  178. package/dist/__tests__/liquidity.test.js +0 -225
  179. package/dist/__tests__/plan-executor.test.d.ts +0 -1
  180. package/dist/__tests__/plan-executor.test.js +0 -314
  181. package/dist/__tests__/position-history.test.d.ts +0 -1
  182. package/dist/__tests__/position-history.test.js +0 -367
  183. package/dist/__tests__/retry.test.d.ts +0 -1
  184. package/dist/__tests__/retry.test.js +0 -310
  185. package/dist/__tests__/risk-assessment.test.d.ts +0 -1
  186. package/dist/__tests__/risk-assessment.test.js +0 -288
  187. package/dist/__tests__/security-adversarial.test.d.ts +0 -1
  188. package/dist/__tests__/security-adversarial.test.js +0 -574
  189. package/dist/__tests__/strategies.test.d.ts +0 -1
  190. package/dist/__tests__/strategies.test.js +0 -539
  191. package/dist/__tests__/trade-execution.test.d.ts +0 -1
  192. package/dist/__tests__/trade-execution.test.js +0 -129
  193. package/dist/__tests__/trade-validator.test.d.ts +0 -1
  194. package/dist/__tests__/trade-validator.test.js +0 -655
  195. package/dist/__tests__/utils.test.d.ts +0 -1
  196. package/dist/__tests__/utils.test.js +0 -76
  197. package/dist/arb/reconcile.d.ts +0 -28
  198. package/dist/arb/reconcile.js +0 -162
  199. package/dist/commands/alert.d.ts +0 -2
  200. package/dist/commands/alert.js +0 -421
  201. package/dist/commands/analytics.d.ts +0 -3
  202. package/dist/commands/analytics.js +0 -311
  203. package/dist/commands/arb-manage.d.ts +0 -5
  204. package/dist/commands/arb-manage.js +0 -5
  205. package/dist/commands/dashboard.d.ts +0 -3
  206. package/dist/commands/dashboard.js +0 -176
  207. package/dist/commands/deposit.d.ts +0 -4
  208. package/dist/commands/deposit.js +0 -573
  209. package/dist/commands/dex.d.ts +0 -3
  210. package/dist/commands/dex.js +0 -120
  211. package/dist/commands/env.d.ts +0 -2
  212. package/dist/commands/env.js +0 -136
  213. package/dist/commands/funding.d.ts +0 -3
  214. package/dist/commands/funding.js +0 -554
  215. package/dist/commands/gap.d.ts +0 -2
  216. package/dist/commands/gap.js +0 -305
  217. package/dist/commands/health.d.ts +0 -2
  218. package/dist/commands/health.js +0 -67
  219. package/dist/commands/multileg.d.ts +0 -16
  220. package/dist/commands/multileg.js +0 -174
  221. package/dist/commands/ows.d.ts +0 -2
  222. package/dist/commands/ows.js +0 -887
  223. package/dist/commands/pnl.d.ts +0 -12
  224. package/dist/commands/pnl.js +0 -243
  225. package/dist/commands/run.d.ts +0 -3
  226. package/dist/commands/run.js +0 -202
  227. package/dist/commands/stream.d.ts +0 -5
  228. package/dist/commands/stream.js +0 -200
  229. package/dist/commands/withdraw.d.ts +0 -3
  230. package/dist/commands/withdraw.js +0 -187
  231. package/dist/exchanges/edgex.d.ts +0 -62
  232. package/dist/exchanges/edgex.js +0 -552
  233. package/dist/exchanges/nado.d.ts +0 -52
  234. package/dist/exchanges/nado.js +0 -223
  235. package/dist/funding/index.d.ts +0 -3
  236. package/dist/funding/index.js +0 -3
  237. package/dist/retry.d.ts +0 -74
  238. package/dist/retry.js +0 -129
  239. package/dist/ws/market-feed.d.ts +0 -74
  240. 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;