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.
|
|
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.
|
|
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.
|
|
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:"));
|
package/dist/mcp-server.js
CHANGED
|
@@ -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.
|
|
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
package/skills/perp-cli/SKILL.md
CHANGED
|
@@ -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.
|
|
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
|
|
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
|
-
|
|
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:
|