perp-cli 0.7.4 → 0.7.6

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.
@@ -79,7 +79,7 @@ export function registerAgentCommands(program, getAdapter, isJson) {
79
79
  schemaVersion: "2.0",
80
80
  cliVersion: _pkg.version,
81
81
  generatedAt: new Date().toISOString(),
82
- exchanges: ["pacifica", "hyperliquid", "lighter"],
82
+ exchanges: ["pacifica", "hyperliquid", "lighter", "aster"],
83
83
  errorCodes: errorCodeDocs,
84
84
  commands: program.commands
85
85
  .filter(c => c.name() !== "help")
@@ -102,7 +102,7 @@ export function registerAgentCommands(program, getAdapter, isJson) {
102
102
  schemaVersion: "2.0",
103
103
  cliVersion: _pkg.version,
104
104
  generatedAt: new Date().toISOString(),
105
- exchanges: ["pacifica", "hyperliquid", "lighter"],
105
+ exchanges: ["pacifica", "hyperliquid", "lighter", "aster"],
106
106
  errorCodes: errorCodeDocs,
107
107
  commands: program.commands
108
108
  .filter(c => c.name() !== "help" && c.name() !== "schema")
@@ -118,8 +118,8 @@ export function registerAgentCommands(program, getAdapter, isJson) {
118
118
  printJson(jsonOk({
119
119
  name: "perp-cli",
120
120
  version: _pkg.version,
121
- description: "Multi-DEX Perpetual Futures CLI (Pacifica, Hyperliquid, Lighter) with HIP-3 deployed dex support",
122
- exchanges: ["pacifica", "hyperliquid", "lighter"],
121
+ description: "Multi-DEX Perpetual Futures CLI (Pacifica, Hyperliquid, Lighter, Aster) with HIP-3 deployed dex support",
122
+ exchanges: ["pacifica", "hyperliquid", "lighter", "aster"],
123
123
  capabilities: [
124
124
  {
125
125
  category: "market_data",
@@ -250,7 +250,7 @@ export function registerAgentCommands(program, getAdapter, isJson) {
250
250
  ],
251
251
  notes: [
252
252
  "Always use --json flag for machine-readable output",
253
- "Use -e <exchange> to switch between pacifica, hyperliquid, lighter",
253
+ "Use -e <exchange> to switch between pacifica, hyperliquid, lighter, aster",
254
254
  "Use --dex <name> for HIP-3 deployed perp dexes on Hyperliquid",
255
255
  "Use -n testnet for testnet mode",
256
256
  "Use --client-id or --auto-id on trade commands for retry safety",
package/dist/index.js CHANGED
@@ -48,7 +48,7 @@ const _settings = loadSettings();
48
48
  const _defaultExchange = _settings.defaultExchange || "pacifica";
49
49
  program
50
50
  .name("perp")
51
- .description("Multi-DEX Perpetual Futures CLI (Pacifica, Hyperliquid, Lighter)")
51
+ .description("Multi-DEX Perpetual Futures CLI (Pacifica, Hyperliquid, Lighter, Aster)")
52
52
  .version(_pkg.version)
53
53
  .option("-e, --exchange <exchange>", `Exchange: pacifica, hyperliquid, lighter, aster (default: ${_defaultExchange})`, _defaultExchange)
54
54
  .option("-n, --network <network>", "Network: mainnet or testnet", "mainnet")
@@ -632,13 +632,17 @@ if (rawArgs.length === 0 || (!hasSubcommand && !rawArgs.includes("-h") && !rawAr
632
632
  process.env.LIGHTER_PRIVATE_KEY);
633
633
  // ── ASCII banner ──
634
634
  const banner = [
635
- chalk.cyan(" ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓"),
636
- chalk.cyan(" ┃") + chalk.white.bold(" perp-cli ") + chalk.gray(`v${_pkg.version}`) + " ".repeat(Math.max(0, 32 - _pkg.version.length)) + chalk.cyan("┃"),
637
- chalk.cyan(" ┃") + chalk.gray(" Multi-DEX Perpetual Futures ") + chalk.cyan("┃"),
638
- chalk.cyan(" ┃") + chalk.gray(" Pacifica · Hyperliquid · Lighter ") + chalk.cyan("┃"),
639
- chalk.cyan(" ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛"),
635
+ "",
636
+ chalk.cyan(" ██████╗ ███████╗██████╗ ██████╗ ██████╗██╗ ██╗"),
637
+ chalk.cyan(" ██╔══██╗██╔════╝██╔══██╗██╔══██╗ ██╔════╝██║ ██║"),
638
+ chalk.cyan(" ██████╔╝█████╗ ██████╔╝██████╔╝ ██║ ██║ ██║"),
639
+ chalk.cyan(" ██╔═══╝ ██╔══╝ ██╔══██╗██╔═══╝ ██║ ██║ ██║"),
640
+ chalk.cyan(" ██║ ███████╗██║ ██║██║ ╚██████╗███████╗██║"),
641
+ chalk.cyan(" ╚═╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═════╝╚══════╝╚═╝"),
642
+ "",
643
+ chalk.gray(` 4 exchanges · 19 strategies · v${_pkg.version}`),
640
644
  ];
641
- console.log("\n" + banner.join("\n"));
645
+ console.log(banner.join("\n"));
642
646
  if (!status.hasWallets && !hasEnvKey && !settings.defaultExchange) {
643
647
  // Fresh install — onboarding
644
648
  console.log(chalk.yellow.bold("\n ⚡ Get started:\n"));
@@ -660,7 +664,38 @@ if (rawArgs.length === 0 || (!hasSubcommand && !rawArgs.includes("-h") && !rawAr
660
664
  const adapter = await withTimeout(getAdapterForExchange(ex), 5000);
661
665
  const [balance, positions] = await withTimeout(Promise.all([adapter.getBalance(), adapter.getPositions()]), 5000);
662
666
  const posCount = positions.filter(p => Number(p.size) > 0).length;
663
- return { exchange: ex, ok: true, equity: Number(balance.equity), positions: posCount };
667
+ let spotValue = 0;
668
+ // Include non-USDC spot value for unified accounts (HL, LT)
669
+ try {
670
+ if (ex === "hyperliquid") {
671
+ const { HyperliquidSpotAdapter } = await import("./exchanges/hyperliquid-spot.js");
672
+ const hlSpot = new HyperliquidSpotAdapter(adapter);
673
+ await hlSpot.init();
674
+ const [raw, markets] = await Promise.all([hlSpot.getSpotBalances(), hlSpot.getSpotMarkets()]);
675
+ const priceMap = new Map(markets.map(m => [m.baseToken.toUpperCase(), Number(m.markPrice)]));
676
+ for (const b of raw) {
677
+ const base = b.token.replace(/-SPOT$/i, "").toUpperCase();
678
+ if (base === "USDC" || Number(b.total) <= 0)
679
+ continue;
680
+ spotValue += (priceMap.get(base) ?? 0) * Number(b.total);
681
+ }
682
+ }
683
+ else if (ex === "lighter") {
684
+ const { LighterAdapter } = await import("./exchanges/lighter.js");
685
+ const { LighterSpotAdapter } = await import("./exchanges/lighter-spot.js");
686
+ const ltSpot = new LighterSpotAdapter(adapter);
687
+ await ltSpot.init();
688
+ const [raw, markets] = await Promise.all([ltSpot.getSpotBalances(), ltSpot.getSpotMarkets()]);
689
+ const priceMap = new Map(markets.map(m => [m.baseToken.toUpperCase(), Number(m.markPrice)]));
690
+ for (const b of raw) {
691
+ if (b.token === "USDC" || b.token === "USDC_SPOT" || Number(b.total) <= 0)
692
+ continue;
693
+ spotValue += (priceMap.get(b.token.toUpperCase()) ?? 0) * Number(b.total);
694
+ }
695
+ }
696
+ }
697
+ catch { /* spot not available */ }
698
+ return { exchange: ex, ok: true, equity: Number(balance.equity) + spotValue, positions: posCount };
664
699
  }
665
700
  catch {
666
701
  return { exchange: ex, ok: false, equity: 0, positions: 0 };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "perp-cli",
3
- "version": "0.7.4",
3
+ "version": "0.7.6",
4
4
  "description": "Multi-DEX Perpetual Futures CLI - Pacifica, Hyperliquid, Lighter",
5
5
  "bin": {
6
6
  "perp": "dist/index.js",