perp-cli 0.3.5 → 0.3.7

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.
@@ -62,6 +62,23 @@ export class LighterAdapter {
62
62
  ? this._accountIndexInit
63
63
  : json.accounts[0].account_index;
64
64
  }
65
+ // Auto-generate API key if we have PK but no API key and account exists
66
+ if (!this._apiKey && this._accountIndex >= 0) {
67
+ try {
68
+ const { privateKey: apiKey } = await this.setupApiKey();
69
+ this._apiKey = apiKey;
70
+ // Save to .env for future use
71
+ try {
72
+ const { setEnvVar } = await import("../commands/init.js");
73
+ setEnvVar("LIGHTER_API_KEY", apiKey);
74
+ setEnvVar("LIGHTER_ACCOUNT_INDEX", String(this._accountIndex));
75
+ }
76
+ catch { /* non-critical — env save may fail in some contexts */ }
77
+ }
78
+ catch {
79
+ // Auto-setup failed (no gas, network issue, etc.) — continue in read-only mode
80
+ }
81
+ }
65
82
  // Initialize signer for trading if we have an API key
66
83
  if (this._apiKey) {
67
84
  const { LighterSignerClient } = require("lighter-sdk");
package/dist/index.js CHANGED
@@ -48,7 +48,7 @@ const _defaultExchange = _settings.defaultExchange || "pacifica";
48
48
  program
49
49
  .name("perp")
50
50
  .description("Multi-DEX Perpetual Futures CLI (Pacifica, Hyperliquid, Lighter)")
51
- .version("0.3.5")
51
+ .version("0.3.7")
52
52
  .option("-e, --exchange <exchange>", `Exchange: pacifica, hyperliquid, lighter (default: ${_defaultExchange})`, _defaultExchange)
53
53
  .option("-n, --network <network>", "Network: mainnet or testnet", "mainnet")
54
54
  .option("-k, --private-key <key>", "Private key")
@@ -383,7 +383,7 @@ if (rawArgs.length === 0 || (!hasSubcommand && !rawArgs.includes("-h") && !rawAr
383
383
  process.env.LIGHTER_PRIVATE_KEY);
384
384
  if (!status.hasWallets && !hasEnvKey && !settings.defaultExchange) {
385
385
  // Fresh install — onboarding
386
- console.log(chalk.cyan.bold("\n Welcome to perp-cli!") + chalk.gray(" v0.3.5\n"));
386
+ console.log(chalk.cyan.bold("\n Welcome to perp-cli!") + chalk.gray(" v0.3.7\n"));
387
387
  console.log(" Multi-DEX perpetual futures CLI for Pacifica, Hyperliquid, and Lighter.\n");
388
388
  console.log(` Get started: ${chalk.cyan("perp init")}`);
389
389
  console.log(chalk.gray(`\n Or explore without a wallet:`));
@@ -396,7 +396,7 @@ if (rawArgs.length === 0 || (!hasSubcommand && !rawArgs.includes("-h") && !rawAr
396
396
  // Configured — show status overview
397
397
  const defaultEx = settings.defaultExchange || "pacifica";
398
398
  const activeEntries = Object.entries(status.active);
399
- console.log(chalk.cyan.bold("\n perp-cli") + chalk.gray(" v0.3.5\n"));
399
+ console.log(chalk.cyan.bold("\n perp-cli") + chalk.gray(" v0.3.7\n"));
400
400
  console.log(` Default exchange: ${chalk.cyan(defaultEx)}`);
401
401
  if (activeEntries.length > 0) {
402
402
  console.log(chalk.white.bold("\n Wallets:"));
@@ -56,7 +56,7 @@ function err(error, meta) {
56
56
  return JSON.stringify({ ok: false, error, meta }, null, 2);
57
57
  }
58
58
  // ── MCP Server ──
59
- const server = new McpServer({ name: "perp-cli", version: "0.3.5" }, { capabilities: { tools: {}, resources: {} } });
59
+ const server = new McpServer({ name: "perp-cli", version: "0.3.7" }, { capabilities: { tools: {}, resources: {} } });
60
60
  // ============================================================
61
61
  // Market Data tools (read-only, no private key needed)
62
62
  // ============================================================
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "perp-cli",
3
- "version": "0.3.5",
3
+ "version": "0.3.7",
4
4
  "description": "Multi-DEX Perpetual Futures CLI - Pacifica, Hyperliquid, Lighter",
5
5
  "bin": {
6
6
  "perp": "./dist/index.js",
@@ -5,7 +5,7 @@ allowed-tools: "Bash(perp:*), Bash(npx perp-cli:*), Bash(npx -y perp-cli:*)"
5
5
  license: MIT
6
6
  metadata:
7
7
  author: hypurrquant
8
- version: "0.3.5"
8
+ version: "0.3.7"
9
9
  mcp-server: perp-cli
10
10
  ---
11
11
 
@@ -79,8 +79,15 @@ perp --json portfolio # unified multi-exchange view
79
79
 
80
80
  ### Trade execution (MANDATORY checklist)
81
81
  ```
82
+ BEFORE ANY TRADE:
83
+ 0. perp --json portfolio → check TOTAL equity + per-exchange balances
84
+ - Single position notional < 25% of TOTAL equity
85
+ - Each exchange MUST have sufficient balance for its leg
86
+ - Notional ≠ margin required. Check available balance on EACH exchange.
87
+ - If balance is insufficient, bridge first or reduce size.
88
+
82
89
  1. perp --json risk status → check risk level (STOP if critical)
83
- 2. perp --json -e <EX> account info → verify balance
90
+ 2. perp --json -e <EX> account info → verify EXCHANGE-SPECIFIC balance
84
91
  3. perp --json -e <EX> market mid <SYM> → current price
85
92
  4. perp --json risk check --notional <$> --leverage <L> → risk pre-check
86
93
  5. perp --json -e <EX> trade check <SYM> <SIDE> <SIZE> → trade validation
@@ -89,6 +96,34 @@ perp --json portfolio # unified multi-exchange view
89
96
  8. perp --json -e <EX> account positions → verify result + check liquidation price
90
97
  ```
91
98
 
99
+ ### Post-entry monitoring (MANDATORY while positions are open)
100
+ ```
101
+ Every 15 minutes:
102
+ perp --json risk status → overall risk level + violations
103
+ perp --json risk liquidation-distance → % from liq price for ALL positions
104
+ perp --json -e <EX> account positions → check each position P&L
105
+
106
+ Every 1 hour (at funding settlement):
107
+ perp --json arb rates → is spread still profitable?
108
+ perp --json portfolio → total equity across exchanges
109
+ Compare both legs' unrealized P&L — they should roughly offset
110
+
111
+ Exit triggers:
112
+ - Spread below breakeven (including fees) → show exit plan, get user approval
113
+ - risk status level = "critical" or canTrade = false → reduce immediately
114
+ - One leg closed unexpectedly → close the other leg IMMEDIATELY
115
+ - Target hold duration reached → re-evaluate or exit
116
+ ```
117
+
118
+ ### Knowing your capital (CHECK BEFORE ANY DECISION)
119
+ ```
120
+ perp --json wallet show → configured wallets + addresses
121
+ perp --json wallet balance → on-chain USDC (in wallet, NOT on exchange)
122
+ perp --json -e <EX> account info → exchange balance (available for trading)
123
+ perp --json portfolio → unified view: equity, margin, P&L per exchange
124
+ ```
125
+ **On-chain balance ≠ exchange balance.** Always check both. Capital must be deposited to exchange before trading.
126
+
92
127
  For full command reference, see `references/commands.md`.
93
128
  For agent-specific operations (setup flows, deposit/withdraw, order types, idempotency), see `references/agent-operations.md`.
94
129
  For autonomous strategies (funding rate arb, risk management, opportunity cost), see `references/strategies.md`.
@@ -82,22 +82,14 @@ perp --json arb rates
82
82
  ```
83
83
 
84
84
  ### Lighter API Key Setup
85
- Lighter requires a separate API key in addition to the EVM private key. **`wallet set` handles this automatically:**
85
+ Lighter uses a separate API key for trading, but **this is handled automatically**.
86
+ When `LIGHTER_PRIVATE_KEY` is set (env var or `wallet set`), the CLI auto-generates and saves the API key on first use.
86
87
 
87
- ```bash
88
- # wallet set automatically generates & registers API key + saves to .env
89
- perp --json wallet set lt 0xEVM_KEY
90
- # → saves LIGHTER_PRIVATE_KEY, LIGHTER_API_KEY, LIGHTER_ACCOUNT_INDEX to ~/.perp/.env
91
- ```
92
-
93
- If auto-setup failed (e.g. no ETH for gas), retry manually:
88
+ If auto-setup fails (e.g. no ETH for gas on Lighter chain), retry manually:
94
89
  ```bash
95
90
  perp --json -e lighter manage setup-api-key
96
- # → generates API key, registers on-chain, auto-saves to ~/.perp/.env
97
91
  ```
98
92
 
99
- **Note:** On-chain registration requires a small amount of ETH on the Lighter chain for gas.
100
-
101
93
  ### Using the Same EVM Key for Multiple Exchanges
102
94
  One EVM private key works for both Hyperliquid and Lighter:
103
95
  ```bash
@@ -310,6 +310,26 @@ Rules of thumb:
310
310
  - **Total margin used < 60% of total equity** — leave buffer for adverse moves
311
311
  - **Capital in transit (bridging) counts as "at risk"** — it's not available for margin
312
312
 
313
+ ### Per-Exchange Balance Constraints
314
+
315
+ **CRITICAL: You can only trade with the balance available ON THAT EXCHANGE.**
316
+
317
+ Each exchange holds its own separate balance. Before entering any arb:
318
+ ```bash
319
+ perp --json -e <EX_A> account info # check available balance on exchange A
320
+ perp --json -e <EX_B> account info # check available balance on exchange B
321
+ ```
322
+
323
+ **Size each leg to fit the available balance on that exchange:**
324
+ ```
325
+ Wrong: total portfolio = $65 → 25% = $16 per leg → but Exchange A only has $10
326
+ Right: Exchange A has $10, Exchange B has $15 → max leg size = $10 (limited by smaller side)
327
+ ```
328
+
329
+ If one exchange has insufficient balance:
330
+ - Reduce position size to fit the smaller balance, OR
331
+ - Bridge capital first (but account for bridge fees + time + unhedged risk during transit)
332
+
313
333
  ### Stop Loss for Arb Positions
314
334
 
315
335
  Even "market-neutral" arb can lose money if: