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.
- package/README.md +30 -25
- package/dist/_stderr-filter.d.ts +0 -0
- package/dist/_stderr-filter.js +30 -0
- package/dist/agent-wallet/expiry.d.ts +15 -0
- package/dist/agent-wallet/expiry.js +26 -0
- package/dist/agent-wallet/lighter-keystore.d.ts +34 -0
- package/dist/agent-wallet/lighter-keystore.js +232 -0
- package/dist/agent-wallet/passphrase.d.ts +13 -0
- package/dist/agent-wallet/passphrase.js +54 -0
- package/dist/agent-wallet/signing-strategy.d.ts +67 -0
- package/dist/agent-wallet/signing-strategy.js +51 -0
- package/dist/agent-wallet/store.d.ts +37 -0
- package/dist/agent-wallet/store.js +172 -0
- package/dist/api/public/_http.d.ts +15 -0
- package/dist/api/public/_http.js +24 -0
- package/dist/api/public/hyperliquid.js +36 -24
- package/dist/api/public/lighter.d.ts +7 -1
- package/dist/api/public/lighter.js +85 -37
- package/dist/api/public/pacifica.js +47 -18
- package/dist/bridge-engine.js +102 -49
- package/dist/cli-spec.js +1 -2
- package/dist/commands/account.js +2 -500
- package/dist/commands/agent.d.ts +8 -2
- package/dist/commands/agent.js +1903 -366
- package/dist/commands/alerts.js +3 -1
- package/dist/commands/arb/index.js +37 -7
- package/dist/commands/arb-auto.js +44 -11
- package/dist/commands/arb.js +83 -34
- package/dist/commands/bot.d.ts +1 -1
- package/dist/commands/bot.js +18 -14
- package/dist/commands/bridge.d.ts +1 -1
- package/dist/commands/bridge.js +4 -4
- package/dist/commands/funds.d.ts +1 -1
- package/dist/commands/funds.js +18 -68
- package/dist/commands/jobs.d.ts +1 -1
- package/dist/commands/jobs.js +2 -2
- package/dist/commands/manage.d.ts +1 -1
- package/dist/commands/manage.js +12 -84
- package/dist/commands/plan.d.ts +1 -1
- package/dist/commands/plan.js +2 -2
- package/dist/commands/portfolio.d.ts +19 -3
- package/dist/commands/portfolio.js +747 -163
- package/dist/commands/rebalance.d.ts +1 -1
- package/dist/commands/rebalance.js +18 -12
- package/dist/commands/risk.js +2 -6
- package/dist/commands/settings.js +30 -53
- package/dist/commands/trade.js +16 -15
- package/dist/commands/wallet.d.ts +2 -1
- package/dist/commands/wallet.js +756 -28
- package/dist/errors.d.ts +64 -0
- package/dist/errors.js +82 -2
- package/dist/event-stream.js +12 -1
- package/dist/exchanges/aster-typed-data.d.ts +156 -0
- package/dist/exchanges/aster-typed-data.js +189 -0
- package/dist/exchanges/aster.d.ts +60 -11
- package/dist/exchanges/aster.js +278 -136
- package/dist/exchanges/hyperliquid.d.ts +14 -0
- package/dist/exchanges/hyperliquid.js +84 -34
- package/dist/exchanges/lighter-spot.js +14 -3
- package/dist/exchanges/lighter.d.ts +66 -0
- package/dist/exchanges/lighter.js +199 -27
- package/dist/exchanges/pacifica-typed-data.d.ts +75 -0
- package/dist/exchanges/pacifica-typed-data.js +74 -0
- package/dist/exchanges/pacifica.d.ts +29 -1
- package/dist/exchanges/pacifica.js +94 -6
- package/dist/funding/rates.js +59 -21
- package/dist/guardrail/perp-guardrail.js +9 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +255 -360
- package/dist/jobs.js +3 -1
- package/dist/mcp-server.js +85 -83
- package/dist/position-history.js +47 -4
- package/dist/settings.d.ts +67 -3
- package/dist/settings.js +1 -2
- package/dist/signer/ows-evm.d.ts +14 -0
- package/dist/signer/ows-evm.js +28 -9
- package/dist/smart-order.d.ts +8 -2
- package/dist/smart-order.js +46 -11
- package/dist/strategies/funding-arb.js +29 -8
- package/dist/trade-validator.js +30 -5
- package/dist/utils.d.ts +10 -0
- package/dist/utils.js +19 -0
- package/package.json +2 -2
- package/skills/perp-cli/SKILL.md +23 -14
- package/skills/perp-cli/references/agent-operations.md +6 -4
- package/skills/perp-cli/references/commands.md +55 -34
- package/skills/perp-cli/scripts/preflight.sh +4 -4
- package/skills/perp-cli/scripts/spot-perp-scan.sh +2 -2
- package/dist/__tests__/alert-logic.test.d.ts +0 -1
- package/dist/__tests__/alert-logic.test.js +0 -107
- package/dist/__tests__/arb-auto-3dex.test.d.ts +0 -1
- package/dist/__tests__/arb-auto-3dex.test.js +0 -397
- package/dist/__tests__/arb-history-stats.test.d.ts +0 -1
- package/dist/__tests__/arb-history-stats.test.js +0 -176
- package/dist/__tests__/arb-logic.test.d.ts +0 -1
- package/dist/__tests__/arb-logic.test.js +0 -84
- package/dist/__tests__/arb-manage.test.d.ts +0 -1
- package/dist/__tests__/arb-manage.test.js +0 -253
- package/dist/__tests__/arb-new-features.test.d.ts +0 -1
- package/dist/__tests__/arb-new-features.test.js +0 -457
- package/dist/__tests__/arb-sizing.test.d.ts +0 -1
- package/dist/__tests__/arb-sizing.test.js +0 -48
- package/dist/__tests__/arb-state.test.d.ts +0 -1
- package/dist/__tests__/arb-state.test.js +0 -284
- package/dist/__tests__/arb-userflow.test.d.ts +0 -1
- package/dist/__tests__/arb-userflow.test.js +0 -945
- package/dist/__tests__/arb-utils.test.d.ts +0 -1
- package/dist/__tests__/arb-utils.test.js +0 -264
- package/dist/__tests__/bot-conditions.test.d.ts +0 -1
- package/dist/__tests__/bot-conditions.test.js +0 -341
- package/dist/__tests__/client-id-tracker.test.d.ts +0 -1
- package/dist/__tests__/client-id-tracker.test.js +0 -137
- package/dist/__tests__/commands/new-atomic-commands.test.d.ts +0 -1
- package/dist/__tests__/commands/new-atomic-commands.test.js +0 -502
- package/dist/__tests__/commands/order-intent.test.d.ts +0 -1
- package/dist/__tests__/commands/order-intent.test.js +0 -600
- package/dist/__tests__/commands/trade-commands.test.d.ts +0 -1
- package/dist/__tests__/commands/trade-commands.test.js +0 -821
- package/dist/__tests__/config.test.d.ts +0 -1
- package/dist/__tests__/config.test.js +0 -86
- package/dist/__tests__/cross-chain-margin.test.d.ts +0 -1
- package/dist/__tests__/cross-chain-margin.test.js +0 -287
- package/dist/__tests__/dex-asset-map.test.d.ts +0 -1
- package/dist/__tests__/dex-asset-map.test.js +0 -191
- package/dist/__tests__/errors.test.d.ts +0 -1
- package/dist/__tests__/errors.test.js +0 -110
- package/dist/__tests__/event-stream.test.d.ts +0 -1
- package/dist/__tests__/event-stream.test.js +0 -276
- package/dist/__tests__/exchanges/interface.test.d.ts +0 -1
- package/dist/__tests__/exchanges/interface.test.js +0 -132
- package/dist/__tests__/exchanges/mock-adapter.d.ts +0 -69
- package/dist/__tests__/exchanges/mock-adapter.js +0 -137
- package/dist/__tests__/execution-log.test.d.ts +0 -1
- package/dist/__tests__/execution-log.test.js +0 -106
- package/dist/__tests__/funding-calc.test.d.ts +0 -1
- package/dist/__tests__/funding-calc.test.js +0 -71
- package/dist/__tests__/funding-history.test.d.ts +0 -1
- package/dist/__tests__/funding-history.test.js +0 -343
- package/dist/__tests__/funding-rates.test.d.ts +0 -1
- package/dist/__tests__/funding-rates.test.js +0 -342
- package/dist/__tests__/funding.test.d.ts +0 -1
- package/dist/__tests__/funding.test.js +0 -173
- package/dist/__tests__/gap-logic.test.d.ts +0 -1
- package/dist/__tests__/gap-logic.test.js +0 -43
- package/dist/__tests__/hip3-dex.test.d.ts +0 -1
- package/dist/__tests__/hip3-dex.test.js +0 -234
- package/dist/__tests__/integration/agent-features.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/agent-features.integration.test.js +0 -553
- package/dist/__tests__/integration/atomic-commands.integration.test.d.ts +0 -13
- package/dist/__tests__/integration/atomic-commands.integration.test.js +0 -246
- package/dist/__tests__/integration/bridge-simulation.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/bridge-simulation.integration.test.js +0 -453
- package/dist/__tests__/integration/bridge-strict.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/bridge-strict.integration.test.js +0 -812
- package/dist/__tests__/integration/bridge.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/bridge.integration.test.js +0 -309
- package/dist/__tests__/integration/cli-e2e.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/cli-e2e.integration.test.js +0 -202
- package/dist/__tests__/integration/dex-arb.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/dex-arb.integration.test.js +0 -116
- package/dist/__tests__/integration/envelope-consistency.integration.test.d.ts +0 -13
- package/dist/__tests__/integration/envelope-consistency.integration.test.js +0 -205
- package/dist/__tests__/integration/hip3-dex.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/hip3-dex.integration.test.js +0 -147
- package/dist/__tests__/integration/hyperliquid.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/hyperliquid.integration.test.js +0 -79
- package/dist/__tests__/integration/lighter.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/lighter.integration.test.js +0 -53
- package/dist/__tests__/integration/new-commands-e2e.integration.test.d.ts +0 -9
- package/dist/__tests__/integration/new-commands-e2e.integration.test.js +0 -236
- package/dist/__tests__/integration/order-verification.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/order-verification.integration.test.js +0 -321
- package/dist/__tests__/integration/pacifica.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/pacifica.integration.test.js +0 -75
- package/dist/__tests__/integration/response-shapes.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/response-shapes.integration.test.js +0 -278
- package/dist/__tests__/liquidity.test.d.ts +0 -1
- package/dist/__tests__/liquidity.test.js +0 -225
- package/dist/__tests__/plan-executor.test.d.ts +0 -1
- package/dist/__tests__/plan-executor.test.js +0 -314
- package/dist/__tests__/position-history.test.d.ts +0 -1
- package/dist/__tests__/position-history.test.js +0 -367
- package/dist/__tests__/retry.test.d.ts +0 -1
- package/dist/__tests__/retry.test.js +0 -310
- package/dist/__tests__/risk-assessment.test.d.ts +0 -1
- package/dist/__tests__/risk-assessment.test.js +0 -288
- package/dist/__tests__/security-adversarial.test.d.ts +0 -1
- package/dist/__tests__/security-adversarial.test.js +0 -574
- package/dist/__tests__/strategies.test.d.ts +0 -1
- package/dist/__tests__/strategies.test.js +0 -539
- package/dist/__tests__/trade-execution.test.d.ts +0 -1
- package/dist/__tests__/trade-execution.test.js +0 -129
- package/dist/__tests__/trade-validator.test.d.ts +0 -1
- package/dist/__tests__/trade-validator.test.js +0 -655
- package/dist/__tests__/utils.test.d.ts +0 -1
- package/dist/__tests__/utils.test.js +0 -76
- package/dist/arb/reconcile.d.ts +0 -28
- package/dist/arb/reconcile.js +0 -162
- package/dist/commands/alert.d.ts +0 -2
- package/dist/commands/alert.js +0 -421
- package/dist/commands/analytics.d.ts +0 -3
- package/dist/commands/analytics.js +0 -311
- package/dist/commands/arb-manage.d.ts +0 -5
- package/dist/commands/arb-manage.js +0 -5
- package/dist/commands/dashboard.d.ts +0 -3
- package/dist/commands/dashboard.js +0 -176
- package/dist/commands/deposit.d.ts +0 -4
- package/dist/commands/deposit.js +0 -573
- package/dist/commands/dex.d.ts +0 -3
- package/dist/commands/dex.js +0 -120
- package/dist/commands/env.d.ts +0 -2
- package/dist/commands/env.js +0 -136
- package/dist/commands/funding.d.ts +0 -3
- package/dist/commands/funding.js +0 -554
- package/dist/commands/gap.d.ts +0 -2
- package/dist/commands/gap.js +0 -305
- package/dist/commands/health.d.ts +0 -2
- package/dist/commands/health.js +0 -67
- package/dist/commands/multileg.d.ts +0 -16
- package/dist/commands/multileg.js +0 -174
- package/dist/commands/ows.d.ts +0 -2
- package/dist/commands/ows.js +0 -887
- package/dist/commands/pnl.d.ts +0 -12
- package/dist/commands/pnl.js +0 -243
- package/dist/commands/run.d.ts +0 -3
- package/dist/commands/run.js +0 -202
- package/dist/commands/stream.d.ts +0 -5
- package/dist/commands/stream.js +0 -200
- package/dist/commands/withdraw.d.ts +0 -3
- package/dist/commands/withdraw.js +0 -187
- package/dist/exchanges/edgex.d.ts +0 -62
- package/dist/exchanges/edgex.js +0 -552
- package/dist/exchanges/nado.d.ts +0 -52
- package/dist/exchanges/nado.js +0 -223
- package/dist/funding/index.d.ts +0 -3
- package/dist/funding/index.js +0 -3
- package/dist/retry.d.ts +0 -74
- package/dist/retry.js +0 -129
- package/dist/ws/market-feed.d.ts +0 -74
- package/dist/ws/market-feed.js +0 -227
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
import type { ExchangeAdapter } from "../exchanges/index.js";
|
|
3
|
-
export declare function
|
|
3
|
+
export declare function registerFundsRebalanceCommands(parent: Command, getAdapterForExchange: (exchange: string) => Promise<ExchangeAdapter>, isJson: () => boolean): void;
|
|
@@ -3,8 +3,8 @@ import { formatUsd, makeTable, printJson, jsonOk } from "../utils.js";
|
|
|
3
3
|
import { fetchAllBalances, computeRebalancePlan, describeBridgeRoute, estimateMoveTime, } from "../rebalance.js";
|
|
4
4
|
import { EXCHANGE_TO_CHAIN, executeBestBridge } from "../bridge-engine.js";
|
|
5
5
|
import { loadPrivateKey, parseSolanaKeypair } from "../config.js";
|
|
6
|
-
export function
|
|
7
|
-
const rebalance =
|
|
6
|
+
export function registerFundsRebalanceCommands(parent, getAdapterForExchange, isJson) {
|
|
7
|
+
const rebalance = parent.command("rebalance").description("Cross-exchange balance management");
|
|
8
8
|
// ── rebalance check ──
|
|
9
9
|
rebalance
|
|
10
10
|
.command("check")
|
|
@@ -13,15 +13,18 @@ export function registerRebalanceCommands(program, getAdapterForExchange, isJson
|
|
|
13
13
|
.action(async (opts) => {
|
|
14
14
|
const exchangeNames = opts.exchanges.split(",").map((e) => e.trim());
|
|
15
15
|
const adapters = new Map();
|
|
16
|
+
const unavailable = [];
|
|
16
17
|
for (const name of exchangeNames) {
|
|
17
18
|
try {
|
|
18
19
|
adapters.set(name, await getAdapterForExchange(name));
|
|
19
20
|
}
|
|
20
|
-
catch {
|
|
21
|
-
|
|
21
|
+
catch (e) {
|
|
22
|
+
unavailable.push({ exchange: name, error: e instanceof Error ? e.message : String(e) });
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
25
|
if (adapters.size === 0) {
|
|
26
|
+
if (isJson())
|
|
27
|
+
return printJson(jsonOk({ snapshots: [], unavailable }));
|
|
25
28
|
console.error(chalk.red("\n No exchanges available. Check credentials.\n"));
|
|
26
29
|
return;
|
|
27
30
|
}
|
|
@@ -29,7 +32,7 @@ export function registerRebalanceCommands(program, getAdapterForExchange, isJson
|
|
|
29
32
|
console.log(chalk.cyan("\n Fetching balances across exchanges...\n"));
|
|
30
33
|
const snapshots = await fetchAllBalances(adapters);
|
|
31
34
|
if (isJson())
|
|
32
|
-
return printJson(jsonOk(snapshots));
|
|
35
|
+
return printJson(jsonOk({ snapshots, unavailable }));
|
|
33
36
|
const totalEquity = snapshots.reduce((s, e) => s + e.equity, 0);
|
|
34
37
|
const totalAvailable = snapshots.reduce((s, e) => s + e.available, 0);
|
|
35
38
|
const rows = snapshots.map((s) => {
|
|
@@ -61,15 +64,18 @@ export function registerRebalanceCommands(program, getAdapterForExchange, isJson
|
|
|
61
64
|
.action(async (opts) => {
|
|
62
65
|
const exchangeNames = opts.exchanges.split(",").map((e) => e.trim());
|
|
63
66
|
const adapters = new Map();
|
|
67
|
+
const unavailable = [];
|
|
64
68
|
for (const name of exchangeNames) {
|
|
65
69
|
try {
|
|
66
70
|
adapters.set(name, await getAdapterForExchange(name));
|
|
67
71
|
}
|
|
68
|
-
catch {
|
|
69
|
-
|
|
72
|
+
catch (e) {
|
|
73
|
+
unavailable.push({ exchange: name, error: e instanceof Error ? e.message : String(e) });
|
|
70
74
|
}
|
|
71
75
|
}
|
|
72
76
|
if (adapters.size < 2) {
|
|
77
|
+
if (isJson())
|
|
78
|
+
return printJson(jsonOk({ moves: [], unavailable, error: "Need at least 2 exchanges for rebalancing" }));
|
|
73
79
|
console.error(chalk.red("\n Need at least 2 exchanges for rebalancing.\n"));
|
|
74
80
|
return;
|
|
75
81
|
}
|
|
@@ -81,7 +87,7 @@ export function registerRebalanceCommands(program, getAdapterForExchange, isJson
|
|
|
81
87
|
reserve: parseFloat(opts.reserve),
|
|
82
88
|
});
|
|
83
89
|
if (isJson())
|
|
84
|
-
return printJson(jsonOk(plan));
|
|
90
|
+
return printJson(jsonOk({ ...plan, unavailable }));
|
|
85
91
|
// Show current state
|
|
86
92
|
const rows = plan.snapshots.map((s) => {
|
|
87
93
|
const target = plan.targetPerExchange;
|
|
@@ -109,7 +115,7 @@ export function registerRebalanceCommands(program, getAdapterForExchange, isJson
|
|
|
109
115
|
console.log(chalk.gray(` Time: ${estimateMoveTime(m)}`));
|
|
110
116
|
console.log();
|
|
111
117
|
}
|
|
112
|
-
console.log(chalk.yellow(` To execute: perp rebalance execute --exchanges ${opts.exchanges}\n`));
|
|
118
|
+
console.log(chalk.yellow(` To execute: perp funds rebalance execute --exchanges ${opts.exchanges}\n`));
|
|
113
119
|
});
|
|
114
120
|
// ── rebalance execute ──
|
|
115
121
|
rebalance
|
|
@@ -207,14 +213,14 @@ export function registerRebalanceCommands(program, getAdapterForExchange, isJson
|
|
|
207
213
|
catch (err) {
|
|
208
214
|
console.error(chalk.red(` Bridge failed: ${err instanceof Error ? err.message : err}`));
|
|
209
215
|
if (!isJson())
|
|
210
|
-
console.log(chalk.yellow(` Manual fallback: perp bridge exchange --from ${move.from} --to ${move.to} --amount ${move.amount}\n`));
|
|
216
|
+
console.log(chalk.yellow(` Manual fallback: perp funds bridge exchange --from ${move.from} --to ${move.to} --amount ${move.amount}\n`));
|
|
211
217
|
moveResults.push({ from: move.from, to: move.to, amount: move.amount, status: "bridge_failed", error: err instanceof Error ? err.message : String(err) });
|
|
212
218
|
}
|
|
213
219
|
}
|
|
214
220
|
else {
|
|
215
221
|
if (!isJson()) {
|
|
216
222
|
console.log(chalk.gray(` Step 2: Bridge needed.`));
|
|
217
|
-
console.log(chalk.gray(` Run: perp bridge exchange --from ${move.from} --to ${move.to} --amount ${move.amount}`));
|
|
223
|
+
console.log(chalk.gray(` Run: perp funds bridge exchange --from ${move.from} --to ${move.to} --amount ${move.amount}`));
|
|
218
224
|
console.log();
|
|
219
225
|
}
|
|
220
226
|
moveResults.push({ from: move.from, to: move.to, amount: move.amount, status: "needs_bridge" });
|
|
@@ -222,7 +228,7 @@ export function registerRebalanceCommands(program, getAdapterForExchange, isJson
|
|
|
222
228
|
}
|
|
223
229
|
if (isJson())
|
|
224
230
|
return printJson(jsonOk({ status: "executed", moves: moveResults }));
|
|
225
|
-
console.log(chalk.cyan(" Rebalance initiated. Monitor progress with 'perp rebalance check'.\n"));
|
|
231
|
+
console.log(chalk.cyan(" Rebalance initiated. Monitor progress with 'perp funds rebalance check'.\n"));
|
|
226
232
|
});
|
|
227
233
|
}
|
|
228
234
|
/**
|
package/dist/commands/risk.js
CHANGED
|
@@ -336,14 +336,10 @@ export function registerRiskCommands(program, getAdapterForExchange, isJson) {
|
|
|
336
336
|
}
|
|
337
337
|
});
|
|
338
338
|
});
|
|
339
|
-
|
|
340
|
-
const healthCmd = program
|
|
339
|
+
program
|
|
341
340
|
.command("health")
|
|
342
|
-
.description("
|
|
341
|
+
.description("Adapter health check across all 4 DEX")
|
|
343
342
|
.action(async () => {
|
|
344
|
-
if (!isJson())
|
|
345
|
-
console.log(chalk.yellow(" Use 'perp status --health' instead.\n"));
|
|
346
343
|
await runHealthCheck(isJson);
|
|
347
344
|
});
|
|
348
|
-
healthCmd._hidden = true;
|
|
349
345
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
-
import { printJson, jsonOk,
|
|
2
|
+
import { printJson, jsonOk, withJsonErrors } from "../utils.js";
|
|
3
3
|
import { loadSettings, saveSettings } from "../settings.js";
|
|
4
4
|
import { ENV_FILE, loadEnvFile, setEnvVar, EXCHANGE_ENV_MAP, validateKey } from "./init.js";
|
|
5
5
|
// Resolve exchange alias → env var key
|
|
@@ -34,7 +34,7 @@ export function registerSettingsCommands(program, isJson, getAdapterForExchange)
|
|
|
34
34
|
return printJson(jsonOk(s));
|
|
35
35
|
console.log(chalk.cyan.bold("\n CLI Settings\n"));
|
|
36
36
|
console.log(` Default Exchange: ${s.defaultExchange ? chalk.cyan(s.defaultExchange) : chalk.gray("pacifica (built-in)")}`);
|
|
37
|
-
console.log(` Referrals: ${
|
|
37
|
+
console.log(` Referrals: ${chalk.green("MANDATORY (always on)")}`);
|
|
38
38
|
console.log(chalk.white.bold("\n Referral Codes:"));
|
|
39
39
|
console.log(` Pacifica: ${s.referralCodes.pacifica || chalk.gray("(none)")}`);
|
|
40
40
|
console.log(` Hyperliquid: ${s.referralCodes.hyperliquid || chalk.gray("(none)")}`);
|
|
@@ -48,52 +48,13 @@ export function registerSettingsCommands(program, isJson, getAdapterForExchange)
|
|
|
48
48
|
console.log(chalk.gray(`\n Config: ~/.perp/settings.json\n`));
|
|
49
49
|
});
|
|
50
50
|
});
|
|
51
|
-
//
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
.argument("<action>", "on | off")
|
|
56
|
-
.action(async (action) => {
|
|
57
|
-
await withJsonErrors(isJson(), async () => {
|
|
58
|
-
const s = loadSettings();
|
|
59
|
-
if (action === "on") {
|
|
60
|
-
s.referrals = true;
|
|
61
|
-
// Reset applied flags so referrals get re-sent on next connection
|
|
62
|
-
s.referralApplied = { hyperliquid: false, lighter: false };
|
|
63
|
-
saveSettings(s);
|
|
64
|
-
if (isJson())
|
|
65
|
-
return printJson(jsonOk({ referrals: true }));
|
|
66
|
-
console.log(chalk.green("\n Referrals enabled. Codes will be sent on next connection.\n"));
|
|
67
|
-
if (s.referralCodes.pacifica)
|
|
68
|
-
console.log(` Pacifica builder code: ${s.referralCodes.pacifica}`);
|
|
69
|
-
if (s.referralCodes.hyperliquid)
|
|
70
|
-
console.log(` Hyperliquid referral: ${s.referralCodes.hyperliquid}`);
|
|
71
|
-
if (s.referralCodes.lighter)
|
|
72
|
-
console.log(` Lighter referral: ${s.referralCodes.lighter}`);
|
|
73
|
-
console.log();
|
|
74
|
-
}
|
|
75
|
-
else if (action === "off") {
|
|
76
|
-
s.referrals = false;
|
|
77
|
-
saveSettings(s);
|
|
78
|
-
if (isJson())
|
|
79
|
-
return printJson(jsonOk({ referrals: false }));
|
|
80
|
-
console.log(chalk.yellow("\n Referrals disabled. No codes will be sent.\n"));
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
if (isJson())
|
|
84
|
-
return printJson(jsonError("INVALID_ARGS", `Invalid action "${action}". Usage: perp settings referrals <on|off>`));
|
|
85
|
-
console.error(chalk.red(`\n Usage: perp settings referrals <on|off>\n`));
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
});
|
|
51
|
+
// Note: `settings referrals on/off` removed in v0.12 — referral codes are
|
|
52
|
+
// now mandatory (SSOT-aligned with Pacifica's always-on builder code).
|
|
53
|
+
// To reset applied flags (force re-send on next connection):
|
|
54
|
+
// perp settings set referralApplied.hyperliquid false (and same for lighter)
|
|
89
55
|
// ── settings fees ──
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
.description("Show or sync exchange fee tiers");
|
|
93
|
-
fees
|
|
94
|
-
.command("show")
|
|
95
|
-
.description("Show current fee tiers")
|
|
96
|
-
.action(async () => {
|
|
56
|
+
// Bare `settings fees` shows current tiers (same as `settings fees show`).
|
|
57
|
+
const showFees = async () => {
|
|
97
58
|
await withJsonErrors(isJson(), async () => {
|
|
98
59
|
const s = loadSettings();
|
|
99
60
|
if (isJson())
|
|
@@ -107,7 +68,15 @@ export function registerSettingsCommands(program, isJson, getAdapterForExchange)
|
|
|
107
68
|
console.log(chalk.gray(`\n Sync from exchanges: perp settings fees sync`));
|
|
108
69
|
console.log(chalk.gray(` Manual set: perp settings fees set <exchange> <taker> <maker>\n`));
|
|
109
70
|
});
|
|
110
|
-
}
|
|
71
|
+
};
|
|
72
|
+
const fees = settings
|
|
73
|
+
.command("fees")
|
|
74
|
+
.description("Show or sync exchange fee tiers (default action: show)")
|
|
75
|
+
.action(showFees);
|
|
76
|
+
fees
|
|
77
|
+
.command("show")
|
|
78
|
+
.description("Show current fee tiers")
|
|
79
|
+
.action(showFees);
|
|
111
80
|
fees
|
|
112
81
|
.command("sync")
|
|
113
82
|
.description("Fetch fee tiers from exchange APIs and save")
|
|
@@ -228,9 +197,6 @@ export function registerSettingsCommands(program, isJson, getAdapterForExchange)
|
|
|
228
197
|
}
|
|
229
198
|
s.defaultExchange = value.toLowerCase();
|
|
230
199
|
}
|
|
231
|
-
else if (key === "referrals") {
|
|
232
|
-
s.referrals = value === "true" || value === "on";
|
|
233
|
-
}
|
|
234
200
|
else if (key.startsWith("referralCodes.")) {
|
|
235
201
|
const exchange = key.split(".")[1];
|
|
236
202
|
if (exchange in s.referralCodes) {
|
|
@@ -241,9 +207,20 @@ export function registerSettingsCommands(program, isJson, getAdapterForExchange)
|
|
|
241
207
|
return;
|
|
242
208
|
}
|
|
243
209
|
}
|
|
210
|
+
else if (key.startsWith("referralApplied.")) {
|
|
211
|
+
// Force re-apply: `set referralApplied.hyperliquid false`
|
|
212
|
+
const exchange = key.split(".")[1];
|
|
213
|
+
if (exchange in s.referralApplied) {
|
|
214
|
+
s.referralApplied[exchange] = value === "true" || value === "on";
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
console.error(chalk.red(` Unknown exchange: ${exchange}`));
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
244
221
|
else {
|
|
245
222
|
console.error(chalk.red(` Unknown key: ${key}`));
|
|
246
|
-
console.log(chalk.gray(" Valid keys: default-exchange,
|
|
223
|
+
console.log(chalk.gray(" Valid keys: default-exchange, referralCodes.{pacifica,hyperliquid,lighter}, referralApplied.{hyperliquid,lighter}\n"));
|
|
247
224
|
return;
|
|
248
225
|
}
|
|
249
226
|
saveSettings(s);
|
|
@@ -320,7 +297,7 @@ export function registerSettingsCommands(program, isJson, getAdapterForExchange)
|
|
|
320
297
|
console.log(` File: ${chalk.gray("~/.perp/.env")}\n`);
|
|
321
298
|
}
|
|
322
299
|
else {
|
|
323
|
-
// Raw env var (e.g.
|
|
300
|
+
// Raw env var (e.g. LIGHTER_REFERRAL_CODE, custom vars)
|
|
324
301
|
setEnvVar(name, value);
|
|
325
302
|
if (isJson())
|
|
326
303
|
return printJson(jsonOk({ key: name, file: ENV_FILE }));
|
package/dist/commands/trade.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { printJson, errorAndExit, withJsonErrors, jsonOk, jsonError, symbolMatch, formatUsd } from "../utils.js";
|
|
2
|
+
import { extractErrorMessage } from "../errors.js";
|
|
2
3
|
import { logExecution } from "../execution-log.js";
|
|
3
4
|
import { validateTrade } from "../trade-validator.js";
|
|
4
5
|
import { generateClientId, logClientId, isOrderDuplicate } from "../client-id-tracker.js";
|
|
@@ -108,7 +109,7 @@ export function registerTradeCommands(program, getAdapter, isJson, isDryRun = ()
|
|
|
108
109
|
logExecution({
|
|
109
110
|
type: "market_order", exchange: adapter.name, symbol: symbol.toUpperCase(),
|
|
110
111
|
side: s, size, status: "failed", dryRun: false,
|
|
111
|
-
error:
|
|
112
|
+
error: extractErrorMessage(err),
|
|
112
113
|
meta: { ...(clientId ? { clientOrderId: clientId } : {}), ...(opts.smart ? { smart: true } : {}) },
|
|
113
114
|
});
|
|
114
115
|
throw err;
|
|
@@ -156,7 +157,7 @@ export function registerTradeCommands(program, getAdapter, isJson, isDryRun = ()
|
|
|
156
157
|
logExecution({ type: "market_order", exchange: adapter.name, symbol: symbol.toUpperCase(), side: "buy", size, status: "success", dryRun: false, meta: opts.smart ? { smart: true } : undefined });
|
|
157
158
|
}
|
|
158
159
|
catch (err) {
|
|
159
|
-
logExecution({ type: "market_order", exchange: adapter.name, symbol: symbol.toUpperCase(), side: "buy", size, status: "failed", dryRun: false, error:
|
|
160
|
+
logExecution({ type: "market_order", exchange: adapter.name, symbol: symbol.toUpperCase(), side: "buy", size, status: "failed", dryRun: false, error: extractErrorMessage(err) });
|
|
160
161
|
throw err;
|
|
161
162
|
}
|
|
162
163
|
if (isJson())
|
|
@@ -194,7 +195,7 @@ export function registerTradeCommands(program, getAdapter, isJson, isDryRun = ()
|
|
|
194
195
|
logExecution({ type: "market_order", exchange: adapter.name, symbol: symbol.toUpperCase(), side: "sell", size, status: "success", dryRun: false, meta: opts.smart ? { smart: true } : undefined });
|
|
195
196
|
}
|
|
196
197
|
catch (err) {
|
|
197
|
-
logExecution({ type: "market_order", exchange: adapter.name, symbol: symbol.toUpperCase(), side: "sell", size, status: "failed", dryRun: false, error:
|
|
198
|
+
logExecution({ type: "market_order", exchange: adapter.name, symbol: symbol.toUpperCase(), side: "sell", size, status: "failed", dryRun: false, error: extractErrorMessage(err) });
|
|
198
199
|
throw err;
|
|
199
200
|
}
|
|
200
201
|
if (isJson())
|
|
@@ -282,7 +283,7 @@ export function registerTradeCommands(program, getAdapter, isJson, isDryRun = ()
|
|
|
282
283
|
logExecution({
|
|
283
284
|
type: "limit_order", exchange: adapter.name, symbol: symbol.toUpperCase(),
|
|
284
285
|
side: s, size, price, status: "failed", dryRun: false,
|
|
285
|
-
error:
|
|
286
|
+
error: extractErrorMessage(err),
|
|
286
287
|
meta: clientId ? { clientOrderId: clientId } : undefined,
|
|
287
288
|
});
|
|
288
289
|
throw err;
|
|
@@ -317,7 +318,7 @@ export function registerTradeCommands(program, getAdapter, isJson, isDryRun = ()
|
|
|
317
318
|
console.log(chalk.green(`\n Order ${oid} cancelled on ${adapter.name}.\n`));
|
|
318
319
|
}
|
|
319
320
|
catch (err) {
|
|
320
|
-
logExecution({ type: "cancel", exchange: adapter.name, symbol, side: "cancel", size: "0", status: "failed", dryRun: false, error:
|
|
321
|
+
logExecution({ type: "cancel", exchange: adapter.name, symbol, side: "cancel", size: "0", status: "failed", dryRun: false, error: extractErrorMessage(err), meta: { orderId: oid } });
|
|
321
322
|
throw err;
|
|
322
323
|
}
|
|
323
324
|
return;
|
|
@@ -347,7 +348,7 @@ export function registerTradeCommands(program, getAdapter, isJson, isDryRun = ()
|
|
|
347
348
|
console.log(chalk.green(`\n Order ${oid} cancelled on ${adapter.name}.\n`));
|
|
348
349
|
}
|
|
349
350
|
catch (err) {
|
|
350
|
-
logExecution({ type: "cancel", exchange: adapter.name, symbol, side: "cancel", size: "0", status: "failed", dryRun: false, error:
|
|
351
|
+
logExecution({ type: "cancel", exchange: adapter.name, symbol, side: "cancel", size: "0", status: "failed", dryRun: false, error: extractErrorMessage(err), meta: { orderId: oid } });
|
|
351
352
|
throw err;
|
|
352
353
|
}
|
|
353
354
|
}
|
|
@@ -373,7 +374,7 @@ export function registerTradeCommands(program, getAdapter, isJson, isDryRun = ()
|
|
|
373
374
|
console.log(chalk.green(`\n ${matching.length} order(s) for ${symbol} cancelled on ${adapter.name}.\n`));
|
|
374
375
|
}
|
|
375
376
|
catch (err) {
|
|
376
|
-
logExecution({ type: "cancel", exchange: adapter.name, symbol, side: "cancel", size: "0", status: "failed", dryRun: false, error:
|
|
377
|
+
logExecution({ type: "cancel", exchange: adapter.name, symbol, side: "cancel", size: "0", status: "failed", dryRun: false, error: extractErrorMessage(err), meta: { bySymbol: true } });
|
|
377
378
|
throw err;
|
|
378
379
|
}
|
|
379
380
|
}
|
|
@@ -422,8 +423,8 @@ export function registerTradeCommands(program, getAdapter, isJson, isDryRun = ()
|
|
|
422
423
|
console.log(chalk.green(`\n TWAP job started in background.`));
|
|
423
424
|
console.log(` ID: ${chalk.white.bold(job.id)}`);
|
|
424
425
|
console.log(` Session: ${job.tmuxSession}`);
|
|
425
|
-
console.log(` Logs: ${chalk.gray(`perp
|
|
426
|
-
console.log(` Stop: ${chalk.gray(`perp
|
|
426
|
+
console.log(` Logs: ${chalk.gray(`perp background logs ${job.id}`)}`);
|
|
427
|
+
console.log(` Stop: ${chalk.gray(`perp background stop ${job.id}`)}\n`);
|
|
427
428
|
return;
|
|
428
429
|
}
|
|
429
430
|
const adapter = await getAdapter();
|
|
@@ -484,7 +485,7 @@ export function registerTradeCommands(program, getAdapter, isJson, isDryRun = ()
|
|
|
484
485
|
logExecution({ type: "stop_order", exchange: adapter.name, symbol: symbol.toUpperCase(), side: s, size, price: stopPrice, status: "success", dryRun: false });
|
|
485
486
|
}
|
|
486
487
|
catch (err) {
|
|
487
|
-
logExecution({ type: "stop_order", exchange: adapter.name, symbol: symbol.toUpperCase(), side: s, size, price: stopPrice, status: "failed", dryRun: false, error:
|
|
488
|
+
logExecution({ type: "stop_order", exchange: adapter.name, symbol: symbol.toUpperCase(), side: s, size, price: stopPrice, status: "failed", dryRun: false, error: extractErrorMessage(err) });
|
|
488
489
|
throw err;
|
|
489
490
|
}
|
|
490
491
|
if (isJson())
|
|
@@ -614,7 +615,7 @@ export function registerTradeCommands(program, getAdapter, isJson, isDryRun = ()
|
|
|
614
615
|
});
|
|
615
616
|
}
|
|
616
617
|
catch (err) {
|
|
617
|
-
const msg =
|
|
618
|
+
const msg = extractErrorMessage(err);
|
|
618
619
|
logExecution({
|
|
619
620
|
type: "limit_order", exchange: adapter.name, symbol: sym,
|
|
620
621
|
side: closeSide, size: levelSize, price: level.price,
|
|
@@ -709,13 +710,13 @@ export function registerTradeCommands(program, getAdapter, isJson, isDryRun = ()
|
|
|
709
710
|
logExecution({
|
|
710
711
|
type: "rebalance", exchange: adapter.name, symbol: symbol.toUpperCase(), side: mode,
|
|
711
712
|
size: leverage, status: "failed", dryRun: false,
|
|
712
|
-
error:
|
|
713
|
+
error: extractErrorMessage(err),
|
|
713
714
|
meta: { action: "set_leverage", leverage: parseInt(leverage), mode },
|
|
714
715
|
});
|
|
715
716
|
throw err;
|
|
716
717
|
}
|
|
717
718
|
});
|
|
718
|
-
// grid/dca moved to 'perp
|
|
719
|
+
// grid/dca moved to 'perp strategy grid' / 'perp strategy dca'
|
|
719
720
|
// ── Position Management Shortcuts ──
|
|
720
721
|
trade
|
|
721
722
|
.command("close-all")
|
|
@@ -1080,7 +1081,7 @@ export function registerTradeCommands(program, getAdapter, isJson, isDryRun = ()
|
|
|
1080
1081
|
});
|
|
1081
1082
|
}
|
|
1082
1083
|
catch (err) {
|
|
1083
|
-
const msg =
|
|
1084
|
+
const msg = extractErrorMessage(err);
|
|
1084
1085
|
logExecution({
|
|
1085
1086
|
type: "limit_order", exchange: adapter.name, symbol: sym,
|
|
1086
1087
|
side: s, size: level.size, price: level.price,
|
|
@@ -1104,7 +1105,7 @@ export function registerTradeCommands(program, getAdapter, isJson, isDryRun = ()
|
|
|
1104
1105
|
}
|
|
1105
1106
|
console.log();
|
|
1106
1107
|
});
|
|
1107
|
-
// grid/dca/trailing-stop moved to 'perp
|
|
1108
|
+
// grid/dca/trailing-stop moved to 'perp strategy'
|
|
1108
1109
|
// ── PnL Tracker ──
|
|
1109
1110
|
trade
|
|
1110
1111
|
.command("pnl-track")
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
+
import type { ExchangeAdapter } from "../exchanges/index.js";
|
|
2
3
|
/** Exported for smart landing page in index.ts */
|
|
3
4
|
export declare function getWalletSetupStatus(): {
|
|
4
5
|
hasWallets: boolean;
|
|
@@ -13,4 +14,4 @@ export declare function getWalletSetupStatus(): {
|
|
|
13
14
|
export declare function getActiveWalletKey(exchange: string): string | null;
|
|
14
15
|
/** Get wallet key by name. Returns null if wallet doesn't exist. */
|
|
15
16
|
export declare function getWalletKeyByName(name: string): string | null;
|
|
16
|
-
export declare function registerWalletCommands(program: Command, isJson: () => boolean): void;
|
|
17
|
+
export declare function registerWalletCommands(program: Command, isJson: () => boolean, getAdapter?: () => Promise<ExchangeAdapter>, getPacificaAdapter?: () => unknown): void;
|