perp-cli 0.14.3 → 0.16.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.ja.md +243 -0
- package/README.ko.md +243 -0
- package/README.md +138 -405
- package/README.zh.md +243 -0
- package/dist/agent-wallet/store.d.ts +3 -2
- package/dist/agent-wallet/store.js +2 -2
- package/dist/api/public/hyperliquid.js +4 -0
- package/dist/api/public/lighter.d.ts +5 -0
- package/dist/api/public/lighter.js +5 -0
- package/dist/api/public/pacifica.js +85 -15
- package/dist/api/public/urls.d.ts +2 -0
- package/dist/api/public/urls.js +3 -0
- package/dist/arb/sizing.js +4 -2
- package/dist/arb/state.d.ts +6 -0
- package/dist/arb/utils.d.ts +1 -2
- package/dist/arb/utils.js +1 -2
- package/dist/balance-by-address.d.ts +39 -0
- package/dist/balance-by-address.js +44 -0
- package/dist/bot/apex/pulse.js +3 -0
- package/dist/bot/apex/radar.js +2 -1
- package/dist/bot/engine.d.ts +10 -1
- package/dist/bot/engine.js +14 -6
- package/dist/bot/indicators.d.ts +7 -0
- package/dist/bot/indicators.js +16 -0
- package/dist/bot/perp-order.d.ts +4 -4
- package/dist/bot/perp-order.js +5 -5
- package/dist/bot/quarantine.d.ts +1 -1
- package/dist/bot/quarantine.js +1 -1
- package/dist/bot/quote-rules.js +1 -1
- package/dist/bot/strategies/apex-strategy.js +3 -2
- package/dist/bot/strategies/engine-mm.js +6 -5
- package/dist/bot/strategies/funding-arb-strategy.js +12 -5
- package/dist/bot/strategies/funding-arb-utils.d.ts +15 -3
- package/dist/bot/strategies/funding-arb-utils.js +53 -20
- package/dist/bot/strategies/funding-auto.js +2 -2
- package/dist/bot/strategies/liquidation-mm.d.ts +1 -0
- package/dist/bot/strategies/liquidation-mm.js +8 -2
- package/dist/bot/strategies/momentum-breakout.d.ts +1 -0
- package/dist/bot/strategies/momentum-breakout.js +11 -3
- package/dist/bot/strategies/spot-perp-arb-strategy.d.ts +1 -1
- package/dist/bot/strategies/spot-perp-arb-strategy.js +6 -4
- package/dist/bot/strategies/spot-perp-executor.d.ts +1 -1
- package/dist/bot/strategies/spot-perp-executor.js +3 -3
- package/dist/bot/strategy-types.d.ts +2 -1
- package/dist/bot/tui/BotDashboard.d.ts +1 -1
- package/dist/bot/tui/BotDashboard.js +1 -1
- package/dist/cache.js +12 -6
- package/dist/cli-program.d.ts +15 -0
- package/dist/cli-program.js +126 -6
- package/dist/commands/account.js +168 -24
- package/dist/commands/agent-import.d.ts +7 -0
- package/dist/commands/agent-import.js +30 -1
- package/dist/commands/agent.d.ts +6 -3
- package/dist/commands/agent.js +160 -12
- package/dist/commands/arb/index.js +23 -81
- package/dist/commands/arb-auto.d.ts +24 -0
- package/dist/commands/arb-auto.js +175 -97
- package/dist/commands/arb.d.ts +20 -0
- package/dist/commands/arb.js +107 -163
- package/dist/commands/backtest.js +23 -21
- package/dist/commands/bot.js +1 -1
- package/dist/commands/builder.js +1 -1
- package/dist/commands/funds.js +113 -3
- package/dist/commands/init.d.ts +1 -1
- package/dist/commands/init.js +27 -7
- package/dist/commands/manage.js +23 -21
- package/dist/commands/market.d.ts +48 -0
- package/dist/commands/market.js +395 -100
- package/dist/commands/options.d.ts +14 -0
- package/dist/commands/options.js +151 -0
- package/dist/commands/pacifica-earn.d.ts +5 -0
- package/dist/commands/pacifica-earn.js +455 -0
- package/dist/commands/pacifica-orders.d.ts +14 -0
- package/dist/commands/pacifica-orders.js +142 -0
- package/dist/commands/portfolio.d.ts +16 -0
- package/dist/commands/portfolio.js +83 -55
- package/dist/commands/rebalance.d.ts +1 -0
- package/dist/commands/rebalance.js +15 -0
- package/dist/commands/risk.d.ts +11 -2
- package/dist/commands/risk.js +39 -44
- package/dist/commands/trade.d.ts +1 -0
- package/dist/commands/trade.js +67 -62
- package/dist/commands/wallet.js +1 -1
- package/dist/config.d.ts +2 -2
- package/dist/config.js +15 -4
- package/dist/constants.js +6 -0
- package/dist/cross-chain-margin.d.ts +3 -1
- package/dist/cross-chain-margin.js +4 -2
- package/dist/dashboard/server.js +3 -3
- package/dist/dashboard/ui.js +9 -6
- package/dist/errors.d.ts +29 -1
- package/dist/errors.js +35 -3
- package/dist/exchanges/address.d.ts +8 -0
- package/dist/exchanges/address.js +47 -0
- package/dist/exchanges/arcus/adapter.d.ts +16 -12
- package/dist/exchanges/arcus/adapter.js +45 -18
- package/dist/exchanges/arcus/agent.d.ts +1 -1
- package/dist/exchanges/arcus/agent.js +1 -1
- package/dist/exchanges/arcus/client.js +1 -1
- package/dist/exchanges/arcus/public.js +3 -2
- package/dist/exchanges/arcus/signing.d.ts +2 -3
- package/dist/exchanges/arcus/signing.js +1 -1
- package/dist/exchanges/arcus/spot-chain.d.ts +1 -1
- package/dist/exchanges/arcus/spot-chain.js +1 -1
- package/dist/exchanges/arcus/spot-router.d.ts +1 -1
- package/dist/exchanges/arcus/spot-router.js +2 -2
- package/dist/exchanges/arcus/spot.d.ts +2 -3
- package/dist/exchanges/arcus/spot.js +2 -3
- package/dist/exchanges/aster-spot.d.ts +3 -3
- package/dist/exchanges/aster-spot.js +6 -9
- package/dist/exchanges/aster-typed-data.d.ts +1 -1
- package/dist/exchanges/aster-typed-data.js +1 -1
- package/dist/exchanges/aster.d.ts +30 -10
- package/dist/exchanges/aster.js +153 -53
- package/dist/exchanges/builder-fee.d.ts +1 -1
- package/dist/exchanges/builder-fee.js +13 -2
- package/dist/exchanges/canonical-symbols.d.ts +8 -2
- package/dist/exchanges/canonical-symbols.js +46 -2
- package/dist/exchanges/capabilities.d.ts +2 -0
- package/dist/exchanges/capabilities.js +2 -1
- package/dist/exchanges/derive/client.d.ts +37 -0
- package/dist/exchanges/derive/client.js +135 -0
- package/dist/exchanges/derive/options.d.ts +73 -0
- package/dist/exchanges/derive/options.js +379 -0
- package/dist/exchanges/extended/adapter.d.ts +96 -0
- package/dist/exchanges/extended/adapter.js +241 -0
- package/dist/exchanges/extended/client.d.ts +38 -0
- package/dist/exchanges/extended/client.js +88 -0
- package/dist/exchanges/extended/public.d.ts +133 -0
- package/dist/exchanges/extended/public.js +436 -0
- package/dist/exchanges/grvt/adapter.d.ts +100 -0
- package/dist/exchanges/grvt/adapter.js +283 -0
- package/dist/exchanges/grvt/client.d.ts +25 -0
- package/dist/exchanges/grvt/client.js +86 -0
- package/dist/exchanges/grvt/public.d.ts +151 -0
- package/dist/exchanges/grvt/public.js +438 -0
- package/dist/exchanges/hyperliquid-outcome.d.ts +2 -0
- package/dist/exchanges/hyperliquid-outcome.js +29 -1
- package/dist/exchanges/hyperliquid-spot.d.ts +9 -1
- package/dist/exchanges/hyperliquid-spot.js +24 -16
- package/dist/exchanges/hyperliquid.d.ts +199 -22
- package/dist/exchanges/hyperliquid.js +550 -202
- package/dist/exchanges/index.d.ts +1 -1
- package/dist/exchanges/index.js +1 -1
- package/dist/exchanges/interface.d.ts +157 -13
- package/dist/exchanges/interface.js +47 -0
- package/dist/exchanges/ioc-outcome.d.ts +1 -1
- package/dist/exchanges/ioc-outcome.js +1 -1
- package/dist/exchanges/legacy-trading-v2.d.ts +2 -2
- package/dist/exchanges/legacy-trading-v2.js +7 -2
- package/dist/exchanges/lighter-public.d.ts +67 -12
- package/dist/exchanges/lighter-public.js +250 -82
- package/dist/exchanges/lighter-signer.d.ts +1 -1
- package/dist/exchanges/lighter-signer.js +1 -1
- package/dist/exchanges/lighter-spot.d.ts +10 -5
- package/dist/exchanges/lighter-spot.js +105 -97
- package/dist/exchanges/lighter.d.ts +80 -21
- package/dist/exchanges/lighter.js +312 -105
- package/dist/exchanges/ondo/adapter.d.ts +38 -13
- package/dist/exchanges/ondo/adapter.js +86 -27
- package/dist/exchanges/ondo/agent.d.ts +1 -1
- package/dist/exchanges/ondo/agent.js +1 -1
- package/dist/exchanges/ondo/client.d.ts +1 -1
- package/dist/exchanges/ondo/client.js +2 -2
- package/dist/exchanges/ondo/public.d.ts +35 -3
- package/dist/exchanges/ondo/public.js +75 -32
- package/dist/exchanges/ondo/spot.d.ts +2 -2
- package/dist/exchanges/ondo/spot.js +3 -3
- package/dist/exchanges/options-interface.d.ts +158 -0
- package/dist/exchanges/options-interface.js +17 -0
- package/dist/exchanges/options-venues.d.ts +12 -0
- package/dist/exchanges/options-venues.js +35 -0
- package/dist/exchanges/outcome-interface.d.ts +4 -0
- package/dist/exchanges/pacifica-atomic.d.ts +211 -0
- package/dist/exchanges/pacifica-atomic.js +440 -0
- package/dist/exchanges/pacifica-decimal.d.ts +10 -0
- package/dist/exchanges/pacifica-decimal.js +51 -0
- package/dist/exchanges/pacifica-presigned.d.ts +53 -0
- package/dist/exchanges/pacifica-presigned.js +141 -0
- package/dist/exchanges/pacifica-print.d.ts +200 -0
- package/dist/exchanges/pacifica-print.js +417 -0
- package/dist/exchanges/pacifica-spot.d.ts +8 -2
- package/dist/exchanges/pacifica-spot.js +26 -18
- package/dist/exchanges/pacifica-typed-data.d.ts +1 -1
- package/dist/exchanges/pacifica-typed-data.js +1 -1
- package/dist/exchanges/pacifica-vaults.d.ts +130 -0
- package/dist/exchanges/pacifica-vaults.js +277 -0
- package/dist/exchanges/pacifica.d.ts +108 -10
- package/dist/exchanges/pacifica.js +428 -171
- package/dist/exchanges/precision.d.ts +3 -1
- package/dist/exchanges/precision.js +9 -2
- package/dist/exchanges/public-balances.d.ts +25 -0
- package/dist/exchanges/public-balances.js +158 -0
- package/dist/exchanges/public-positions.d.ts +43 -0
- package/dist/exchanges/public-positions.js +154 -0
- package/dist/exchanges/qfex/adapter.d.ts +69 -13
- package/dist/exchanges/qfex/adapter.js +102 -17
- package/dist/exchanges/qfex/agent.d.ts +1 -1
- package/dist/exchanges/qfex/agent.js +1 -1
- package/dist/exchanges/qfex/client.d.ts +1 -1
- package/dist/exchanges/qfex/client.js +1 -1
- package/dist/exchanges/qfex/errors.d.ts +1 -1
- package/dist/exchanges/qfex/errors.js +2 -2
- package/dist/exchanges/qfex/public.d.ts +65 -12
- package/dist/exchanges/qfex/public.js +131 -25
- package/dist/exchanges/qfex/signing.d.ts +2 -2
- package/dist/exchanges/qfex/signing.js +4 -5
- package/dist/exchanges/qfex/ws-transport.d.ts +3 -3
- package/dist/exchanges/qfex/ws-transport.js +3 -3
- package/dist/exchanges/rate-limiter.d.ts +1 -1
- package/dist/exchanges/rate-limiter.js +5 -2
- package/dist/exchanges/registry.d.ts +1 -1
- package/dist/exchanges/registry.js +1 -1
- package/dist/exchanges/risex/adapter.d.ts +160 -0
- package/dist/exchanges/risex/adapter.js +842 -0
- package/dist/exchanges/risex/agent.d.ts +154 -0
- package/dist/exchanges/risex/agent.js +384 -0
- package/dist/exchanges/risex/client.d.ts +47 -0
- package/dist/exchanges/risex/client.js +174 -0
- package/dist/exchanges/risex/nonce.d.ts +43 -0
- package/dist/exchanges/risex/nonce.js +212 -0
- package/dist/exchanges/risex/public.d.ts +64 -0
- package/dist/exchanges/risex/public.js +150 -0
- package/dist/exchanges/risex/session.d.ts +71 -0
- package/dist/exchanges/risex/session.js +171 -0
- package/dist/exchanges/risex/typed-data.d.ts +173 -0
- package/dist/exchanges/risex/typed-data.js +240 -0
- package/dist/exchanges/risex/units.d.ts +29 -0
- package/dist/exchanges/risex/units.js +104 -0
- package/dist/exchanges/slippage.d.ts +1 -1
- package/dist/exchanges/slippage.js +1 -1
- package/dist/exchanges/spot-factory.d.ts +3 -3
- package/dist/exchanges/spot-factory.js +8 -8
- package/dist/exchanges/spot-interface.d.ts +5 -5
- package/dist/exchanges/spot-interface.js +2 -2
- package/dist/exchanges/spot-result.d.ts +3 -3
- package/dist/exchanges/spot-result.js +3 -3
- package/dist/exchanges/trading-v2.d.ts +3 -3
- package/dist/exchanges/trading-v2.js +9 -6
- package/dist/exchanges/txflow/adapter.d.ts +61 -0
- package/dist/exchanges/txflow/adapter.js +150 -0
- package/dist/exchanges/txflow/client.d.ts +47 -0
- package/dist/exchanges/txflow/client.js +155 -0
- package/dist/exchanges/txflow/public.d.ts +87 -0
- package/dist/exchanges/txflow/public.js +355 -0
- package/dist/exchanges/unknown-symbol.d.ts +34 -0
- package/dist/exchanges/unknown-symbol.js +56 -0
- package/dist/exchanges/variational/adapter.d.ts +67 -0
- package/dist/exchanges/variational/adapter.js +137 -0
- package/dist/exchanges/variational/client.d.ts +21 -0
- package/dist/exchanges/variational/client.js +66 -0
- package/dist/exchanges/variational/public.d.ts +126 -0
- package/dist/exchanges/variational/public.js +430 -0
- package/dist/exchanges/venue-types.d.ts +52 -10
- package/dist/exchanges/venue-types.js +82 -11
- package/dist/exchanges/venue.d.ts +150 -11
- package/dist/exchanges/venue.js +126 -4
- package/dist/exchanges/venues/arcus.d.ts +1 -2
- package/dist/exchanges/venues/arcus.js +5 -4
- package/dist/exchanges/venues/aster.d.ts +2 -2
- package/dist/exchanges/venues/aster.js +6 -4
- package/dist/exchanges/venues/create-helpers.d.ts +1 -1
- package/dist/exchanges/venues/create-helpers.js +3 -3
- package/dist/exchanges/venues/extended.d.ts +21 -0
- package/dist/exchanges/venues/extended.js +96 -0
- package/dist/exchanges/venues/grvt.d.ts +30 -0
- package/dist/exchanges/venues/grvt.js +98 -0
- package/dist/exchanges/venues/hyperliquid.d.ts +2 -2
- package/dist/exchanges/venues/hyperliquid.js +19 -8
- package/dist/exchanges/venues/index.d.ts +7 -2
- package/dist/exchanges/venues/index.js +8 -2
- package/dist/exchanges/venues/lighter-family.d.ts +7 -9
- package/dist/exchanges/venues/lighter-family.js +9 -11
- package/dist/exchanges/venues/lighter-rh.d.ts +2 -2
- package/dist/exchanges/venues/lighter-rh.js +20 -8
- package/dist/exchanges/venues/lighter.d.ts +1 -1
- package/dist/exchanges/venues/lighter.js +18 -6
- package/dist/exchanges/venues/ondo.d.ts +1 -1
- package/dist/exchanges/venues/ondo.js +5 -3
- package/dist/exchanges/venues/pacifica.d.ts +2 -2
- package/dist/exchanges/venues/pacifica.js +15 -4
- package/dist/exchanges/venues/qfex.d.ts +1 -1
- package/dist/exchanges/venues/qfex.js +4 -2
- package/dist/exchanges/venues/risex-release.d.ts +14 -0
- package/dist/exchanges/venues/risex-release.js +14 -0
- package/dist/exchanges/venues/risex.d.ts +31 -0
- package/dist/exchanges/venues/risex.js +131 -0
- package/dist/exchanges/venues/txflow.d.ts +18 -0
- package/dist/exchanges/venues/txflow.js +77 -0
- package/dist/exchanges/venues/variational.d.ts +21 -0
- package/dist/exchanges/venues/variational.js +85 -0
- package/dist/execution-log.d.ts +1 -1
- package/dist/funding/legacy-public.d.ts +6 -4
- package/dist/funding/legacy-public.js +42 -41
- package/dist/funding/normalize.d.ts +1 -1
- package/dist/funding/normalize.js +1 -1
- package/dist/funding/rates.d.ts +95 -6
- package/dist/funding/rates.js +99 -19
- package/dist/index.js +7 -6
- package/dist/jobs.d.ts +1 -0
- package/dist/jobs.js +25 -1
- package/dist/landing.d.ts +2 -0
- package/dist/landing.js +1 -1
- package/dist/liquidity.d.ts +3 -1
- package/dist/liquidity.js +8 -4
- package/dist/mcp-pacifica-earn.d.ts +9 -0
- package/dist/mcp-pacifica-earn.js +64 -0
- package/dist/mcp-server.js +211 -68
- package/dist/pacifica/client.d.ts +69 -5
- package/dist/pacifica/client.js +181 -8
- package/dist/pacifica/rate-limit.d.ts +144 -0
- package/dist/pacifica/rate-limit.js +267 -0
- package/dist/pacifica/types/order.d.ts +2 -1
- package/dist/plan-executor.js +7 -2
- package/dist/positions-by-address.d.ts +34 -0
- package/dist/positions-by-address.js +46 -0
- package/dist/rebalance.js +1 -1
- package/dist/risk.d.ts +2 -1
- package/dist/risk.js +2 -4
- package/dist/settings.d.ts +32 -3
- package/dist/signer/ows-evm.d.ts +1 -1
- package/dist/signer/ows-evm.js +1 -1
- package/dist/smart-order.d.ts +1 -1
- package/dist/smart-order.js +1 -1
- package/dist/strategies/funding-arb.d.ts +1 -1
- package/dist/strategies/funding-arb.js +36 -63
- package/dist/trade-validator.js +2 -2
- package/dist/utils.d.ts +22 -3
- package/dist/utils.js +11 -3
- package/dist/venue-health.d.ts +40 -0
- package/dist/venue-health.js +75 -0
- package/dist/withdraw-gate.d.ts +1 -1
- package/dist/withdraw-gate.js +1 -1
- package/dist/ws/arcus-market.d.ts +9 -0
- package/dist/ws/arcus-market.js +9 -0
- package/dist/ws/aster-market.d.ts +33 -0
- package/dist/ws/aster-market.js +30 -0
- package/dist/ws/index.d.ts +980 -0
- package/dist/ws/index.js +4460 -0
- package/dist/ws/lighter-market.d.ts +14 -0
- package/dist/ws/lighter-market.js +13 -0
- package/dist/ws/node.d.ts +996 -0
- package/dist/ws/node.js +4554 -0
- package/dist/ws/pacifica-instrument.d.ts +8 -0
- package/dist/ws/pacifica-instrument.js +8 -0
- package/dist/ws/unclassified.d.ts +16 -0
- package/dist/ws/unclassified.js +43 -0
- package/dist/ws-cli/credentials.d.ts +62 -0
- package/dist/ws-cli/credentials.js +126 -0
- package/package.json +71 -10
- package/skills/perp-cli/SKILL.md +153 -36
- package/skills/perp-cli/package.json +15 -2
- package/skills/perp-cli/references/agent-operations.md +22 -12
- package/skills/perp-cli/references/commands.md +143 -17
- package/skills/perp-cli/references/strategies.md +38 -3
- package/skills/perp-cli/references/ws-library.md +523 -0
- package/skills/perp-cli/scripts/arb-monitor.sh +13 -10
- package/skills/perp-cli/scripts/funding-analysis.sh +57 -29
- package/skills/perp-cli/scripts/preflight.sh +27 -19
- package/skills/perp-cli/scripts/spot-perp-scan.sh +58 -38
- package/skills/perp-cli/scripts/validate-arb.sh +56 -39
- package/dist/cli-spec.d.ts +0 -46
- package/dist/cli-spec.js +0 -81
package/dist/index.js
CHANGED
|
@@ -17,6 +17,7 @@ import { createRequire } from "node:module";
|
|
|
17
17
|
config({ path: resolve(process.env.HOME || "~", ".perp", ".env") });
|
|
18
18
|
import chalk from "chalk";
|
|
19
19
|
import { listVenues } from "./exchanges/venue.js";
|
|
20
|
+
import { optionsVenueWords } from "./exchanges/options-venues.js";
|
|
20
21
|
import { PerpError } from "./errors.js";
|
|
21
22
|
import { loadSettings } from "./settings.js";
|
|
22
23
|
import { jsonError, jsonOk, printCliError, printJson } from "./utils.js";
|
|
@@ -49,7 +50,7 @@ const _defaultExchange = _settings.defaultExchange || "pacifica";
|
|
|
49
50
|
const { program, getAdapterForExchange, isJson } = buildProgram({ defaultExchange: _defaultExchange, version: _pkg.version });
|
|
50
51
|
// Smart landing page: `perp` with no subcommand
|
|
51
52
|
const rawArgs = process.argv.slice(2);
|
|
52
|
-
const _venueWords = listVenues().flatMap(v => [v.id, ...v.aliases]);
|
|
53
|
+
const _venueWords = [...listVenues().flatMap(v => [v.id, ...v.aliases]), ...optionsVenueWords()];
|
|
53
54
|
const hasSubcommand = rawArgs.some((a) => !a.startsWith("-") && ![..._venueWords, "mainnet", "testnet"].includes(a));
|
|
54
55
|
// `history list -n 5` (old record-count flag) → INVALID_PARAMS with the --limit migration, before
|
|
55
56
|
// Commander turns it into a bare "invalid network" usage error.
|
|
@@ -118,18 +119,18 @@ if (rawArgs.length === 0 || (!hasSubcommand && !rawArgs.includes("-h") && !rawAr
|
|
|
118
119
|
const landingVenues = [];
|
|
119
120
|
for (const ex of LANDING_EXCHANGES) {
|
|
120
121
|
const def = getVenue(ex);
|
|
121
|
-
if (def.
|
|
122
|
+
if (!def.roles.includes("account") || await hasCredentials(def.id, NO_CLI_CREDENTIAL_OPTS))
|
|
122
123
|
landingVenues.push(ex);
|
|
123
124
|
}
|
|
124
125
|
const statusResults = await Promise.allSettled(landingVenues.map(async (ex) => {
|
|
125
|
-
if (getVenue(ex).
|
|
126
|
-
return { exchange: ex, marketDataOnly: true, ok: false, equity: 0, positions: 0 };
|
|
126
|
+
if (!getVenue(ex).roles.includes("account")) {
|
|
127
|
+
return { exchange: ex, marketDataOnly: true, unofficialApi: getVenue(ex).apiStatus.kind === "unofficial", ok: false, equity: 0, positions: 0 };
|
|
127
128
|
}
|
|
128
129
|
try {
|
|
129
130
|
const adapter = await withTimeout(getAdapterForExchange(ex), 5000);
|
|
130
131
|
const [balance, positions] = await withTimeout(Promise.all([adapter.getBalance(), adapter.getPositions()]), 5000);
|
|
131
132
|
const posCount = positions.filter(p => Number(p.size) > 0).length;
|
|
132
|
-
// Spot value on top of perp equity for venues with def.spot
|
|
133
|
+
// Spot value on top of perp equity for venues with def.spot. Shared balances
|
|
133
134
|
// (already in perp equity) are skipped; unpriced tokens are excluded + warned.
|
|
134
135
|
let spotValue = 0;
|
|
135
136
|
const spotDef = getVenue(ex);
|
|
@@ -196,7 +197,7 @@ else {
|
|
|
196
197
|
}).catch(async (err) => {
|
|
197
198
|
// Central printer (utils.printCliError): typed PerpError code / remediation / details
|
|
198
199
|
// are preserved (Rule #2: stay loud, keep semantic envelope); generic Errors go
|
|
199
|
-
// through classifyError; CAPABILITY_UNSUPPORTED prints the uniform
|
|
200
|
+
// through classifyError; CAPABILITY_UNSUPPORTED prints the uniform line.
|
|
200
201
|
const { printCliError } = await import("./utils.js");
|
|
201
202
|
printCliError(err, isJson());
|
|
202
203
|
_origExit(1);
|
package/dist/jobs.d.ts
CHANGED
package/dist/jobs.js
CHANGED
|
@@ -4,9 +4,11 @@ import { join } from "node:path";
|
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
5
|
import { randomBytes } from "node:crypto";
|
|
6
6
|
import { parse as parseDotenv } from "dotenv";
|
|
7
|
+
import { getVenue, roleUnsupported, tryResolveVenueId } from "./exchanges/venue.js";
|
|
8
|
+
import "./exchanges/venues/index.js";
|
|
7
9
|
import { PerpError } from "./errors.js";
|
|
8
10
|
import { QFEX_AUTOMATION_VERIFIED, QFEX_REDUCE_ONLY_WIRE, qfexAutomationGate, qfexReduceOnlyGate } from "./exchanges/qfex/signing.js";
|
|
9
|
-
import { startRefusal } from "./exchanges/trading-v2.js";
|
|
11
|
+
import { startRefusal, unsupported } from "./exchanges/trading-v2.js";
|
|
10
12
|
import { scrubSecretEnv, secretEnvNamesIn } from "./secret-env.js";
|
|
11
13
|
const JOBS_DIR = join(homedir(), ".perp", "jobs");
|
|
12
14
|
const LOGS_DIR = join(homedir(), ".perp", "logs");
|
|
@@ -165,6 +167,28 @@ export function startJob(opts) {
|
|
|
165
167
|
if (automation !== null)
|
|
166
168
|
throw startRefusal(what, "it would trade unattended", automation);
|
|
167
169
|
}
|
|
170
|
+
for (const v of new Set([opts.venue, opts.exchange])) {
|
|
171
|
+
const id = v?.toLowerCase();
|
|
172
|
+
const what = `Background job "${opts.strategy}"`;
|
|
173
|
+
// RISEx: unattended trading stays off until its trading path is verified on mainnet (no TP/SL yet).
|
|
174
|
+
if (id === "risex" || id === "rise") {
|
|
175
|
+
// Read-only release (trading role gated): the uniform phase refusal.
|
|
176
|
+
const risex = getVenue("risex");
|
|
177
|
+
if (!risex.roles.includes("trading"))
|
|
178
|
+
throw startRefusal(what, "it would trade unattended", roleUnsupported(risex, "automation"));
|
|
179
|
+
throw startRefusal(what, "it would trade unattended", unsupported("RISEx", "automation", "unattended trading on RISEx is not enabled until its trading path is verified on mainnet (and it has no TP/SL yet)", "Trade RISEx manually with perp trade …"));
|
|
180
|
+
}
|
|
181
|
+
// TxFlow: market data only (unofficial read-only API).
|
|
182
|
+
if (id === "txflow" || id === "txf") {
|
|
183
|
+
throw startRefusal(what, "TxFlow has no trading in perp-cli", unsupported("txflow", "trading", "TxFlow is integrated through an unofficial read-only API (market data only)", "Trade on the TxFlow website"));
|
|
184
|
+
}
|
|
185
|
+
// Any other registered venue without the trading role (Variational, GRVT, Extended: read-only in this version).
|
|
186
|
+
const venueId = id === undefined ? null : tryResolveVenueId(id);
|
|
187
|
+
if (venueId !== null && !getVenue(venueId).roles.includes("trading")) {
|
|
188
|
+
const def = getVenue(venueId);
|
|
189
|
+
throw startRefusal(what, `${def.displayName} has no trading in perp-cli`, roleUnsupported(def, "trading"));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
168
192
|
}
|
|
169
193
|
if (!hasTmux()) {
|
|
170
194
|
throw new Error("tmux is required for background jobs. Install with: brew install tmux");
|
package/dist/landing.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ export type LandingExchangeStatus = {
|
|
|
5
5
|
exchange: string;
|
|
6
6
|
/** Venue has no account API — rendered as market data only. */
|
|
7
7
|
marketDataOnly?: boolean;
|
|
8
|
+
/** Venue is read through an undocumented API (VenueDefinition.apiStatus) — labelled "unofficial API". */
|
|
9
|
+
unofficialApi?: boolean;
|
|
8
10
|
ok: boolean;
|
|
9
11
|
equity: number;
|
|
10
12
|
positions: number;
|
package/dist/landing.js
CHANGED
|
@@ -25,7 +25,7 @@ export function renderLandingExchangeLine(status, asterAgentMissing) {
|
|
|
25
25
|
return ` ${chalk.yellow("⚙")} ${chalk.cyan(exchangeLabel(status.exchange).padEnd(14))} ${chalk.yellow("agent required")} ${chalk.gray("→ perp wallet agent approve aster")}`;
|
|
26
26
|
}
|
|
27
27
|
if (status.marketDataOnly) {
|
|
28
|
-
return ` ${chalk.gray("◇")} ${chalk.cyan(exchangeLabel(status.exchange).padEnd(14))} ${chalk.gray("market data only")}`;
|
|
28
|
+
return ` ${chalk.gray("◇")} ${chalk.cyan(exchangeLabel(status.exchange).padEnd(14))} ${chalk.gray("market data only")}${status.unofficialApi ? chalk.yellow(" (unofficial API)") : ""}`;
|
|
29
29
|
}
|
|
30
30
|
const icon = status.ok ? chalk.green("●") : chalk.red("○");
|
|
31
31
|
const equity = status.ok
|
package/dist/liquidity.d.ts
CHANGED
|
@@ -26,7 +26,9 @@ export declare function computeExecutableSize(levels: [string, string][], reques
|
|
|
26
26
|
* Check liquidity on both sides for an arb entry.
|
|
27
27
|
* Returns adjusted size or 0 if not viable.
|
|
28
28
|
*/
|
|
29
|
-
export declare function checkArbLiquidity(longAdapter: ExchangeAdapter, shortAdapter: ExchangeAdapter, symbol: string, sizeUsd: number, maxSlippagePct?: number, log?: (msg: string) => void
|
|
29
|
+
export declare function checkArbLiquidity(longAdapter: ExchangeAdapter, shortAdapter: ExchangeAdapter, symbol: string, sizeUsd: number, maxSlippagePct?: number, log?: (msg: string) => void,
|
|
30
|
+
/** The short venue's own symbol when it differs (kPEPE ↔ 1000PEPE); default `symbol`. */
|
|
31
|
+
shortSymbol?: string): Promise<{
|
|
30
32
|
viable: boolean;
|
|
31
33
|
adjustedSizeUsd: number;
|
|
32
34
|
longSlippage: number;
|
package/dist/liquidity.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { classifyError } from "./errors.js";
|
|
1
2
|
/**
|
|
2
3
|
* Walk through orderbook levels and compute how much can be filled
|
|
3
4
|
* within the given slippage tolerance.
|
|
@@ -63,11 +64,13 @@ export function computeExecutableSize(levels, requestedSizeUsd, maxSlippagePct =
|
|
|
63
64
|
* Check liquidity on both sides for an arb entry.
|
|
64
65
|
* Returns adjusted size or 0 if not viable.
|
|
65
66
|
*/
|
|
66
|
-
export async function checkArbLiquidity(longAdapter, shortAdapter, symbol, sizeUsd, maxSlippagePct = 0.5, log
|
|
67
|
+
export async function checkArbLiquidity(longAdapter, shortAdapter, symbol, sizeUsd, maxSlippagePct = 0.5, log,
|
|
68
|
+
/** The short venue's own symbol when it differs (kPEPE ↔ 1000PEPE); default `symbol`. */
|
|
69
|
+
shortSymbol = symbol) {
|
|
67
70
|
try {
|
|
68
71
|
const [longOB, shortOB] = await Promise.all([
|
|
69
72
|
longAdapter.getOrderbook(symbol),
|
|
70
|
-
shortAdapter.getOrderbook(
|
|
73
|
+
shortAdapter.getOrderbook(shortSymbol),
|
|
71
74
|
]);
|
|
72
75
|
// For long entry we consume asks, for short entry we consume bids
|
|
73
76
|
const longCheck = computeExecutableSize(longOB.asks, sizeUsd, maxSlippagePct);
|
|
@@ -145,8 +148,9 @@ export async function checkSpotPerpLiquidity(spotAdapter, perpAdapter, spotSymbo
|
|
|
145
148
|
perpSlippage: perpCheck.slippagePct,
|
|
146
149
|
};
|
|
147
150
|
}
|
|
148
|
-
catch {
|
|
149
|
-
|
|
151
|
+
catch (e) {
|
|
152
|
+
const c = classifyError(e);
|
|
153
|
+
log?.(`[LIQ] spot-perp ${spotSymbol}: orderbook fetch failed (${c.code}: ${c.message})`);
|
|
150
154
|
return { viable: false, adjustedSizeUsd: 0, spotSlippage: 0, perpSlippage: 0 };
|
|
151
155
|
}
|
|
152
156
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read-only MCP tools for Pacifica Print and vaults (unauthenticated GETs; nothing is signed).
|
|
3
|
+
* Print deposits / ends and vault deposits / withdrawals are NOT exposed over MCP: the server has
|
|
4
|
+
* no money-moving deposit / withdraw tools (funds moves are CLI-only, `perp funds …`), and these
|
|
5
|
+
* follow the same rule — use `perp print deposit` / `perp vault deposit|withdraw` (with --dry-run).
|
|
6
|
+
*/
|
|
7
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
8
|
+
import type { Network } from "./exchanges/venue-types.js";
|
|
9
|
+
export declare function registerPacificaEarnMcpTools(server: McpServer, network: Network, ok: (data: unknown, meta?: Record<string, unknown>) => string, errOf: (e: unknown, meta?: Record<string, unknown>) => string): void;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { PacificaClient, requireSolanaAddress } from "./pacifica/client.js";
|
|
3
|
+
import { fetchPrintGames, fetchPrintHistory, fetchPrintMarket, fetchPrintPositions, findPrintGame, quotePrintOrder } from "./exchanges/pacifica-print.js";
|
|
4
|
+
import { DEPOSIT_WHITELIST_API_STATUS, readDepositWhitelist, fetchVaults, findVault, heldShares, withdrawWindowAt } from "./exchanges/pacifica-vaults.js";
|
|
5
|
+
export function registerPacificaEarnMcpTools(server, network, ok, errOf) {
|
|
6
|
+
const client = () => new PacificaClient({ network });
|
|
7
|
+
const run = async (meta, f) => {
|
|
8
|
+
try {
|
|
9
|
+
return { content: [{ type: "text", text: ok(await f(), meta) }] };
|
|
10
|
+
}
|
|
11
|
+
catch (e) {
|
|
12
|
+
return { content: [{ type: "text", text: errOf(e, meta) }], isError: true };
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
const address = z.string().refine((v) => { try {
|
|
16
|
+
requireSolanaAddress(v);
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return false;
|
|
21
|
+
} }, "base58 Solana address (32-byte public key; not an EVM address)");
|
|
22
|
+
server.tool("pacifica_print_products", "Pacifica Print products (read-only): game id (e.g. BTC_24H, BTC_7D, BTC_1M), cycle length in days, max leverage, deposit caps, allowed target distance from mark. Print = a strike order that earns a premium each cycle; while resting it fills / is liquidated only at a cycle checkpoint, after a fill it is an ordinary perp position (continuous liquidation).", {}, async () => run({ exchange: "pacifica" }, async () => fetchPrintGames(client())));
|
|
23
|
+
server.tool("pacifica_print_quote", "Validate a Pacifica Print order and preview it (read-only, nothing signed): notional, size on fill, docs-formula liquidation price (an outer bound — a liquidation was observed earlier in one live case; venue trigger unpublished), max loss (deposit + premiums), lock period. The premium is not quoted (the venue's preview is a signed request). Placing the order is CLI-only: perp -e pacifica print deposit … (supports --dry-run).", {
|
|
24
|
+
game: z.string().describe("Print product, e.g. BTC_24H"),
|
|
25
|
+
direction: z.enum(["long", "short"]).describe("long = target below mark, short = target above mark"),
|
|
26
|
+
deposit: z.string().describe("USDC deposit, min 10"),
|
|
27
|
+
strike: z.string().describe("Target price (on the market tick)"),
|
|
28
|
+
leverage: z.string().describe("Whole-number leverage 1 … product max"),
|
|
29
|
+
cycles: z.number().int().optional().describe("Cycles 1 … 1000; omit = roll until cancelled"),
|
|
30
|
+
}, async ({ game, direction, deposit, strike, leverage, cycles }) => run({ exchange: "pacifica", game }, async () => {
|
|
31
|
+
const c = client();
|
|
32
|
+
const g = findPrintGame(await fetchPrintGames(c), game);
|
|
33
|
+
return quotePrintOrder(g, { game: g.game, direction, deposit, strikePrice: strike, leverage, cycles: cycles ?? null }, await fetchPrintMarket(c, g.asset));
|
|
34
|
+
}));
|
|
35
|
+
server.tool("pacifica_print_positions", "Pacifica Print orders of an account (read-only): current orders, or with history=true every order (paginated: limit / cursor). Status printing | cancelling | filled | liquidated | cancelled | completed | ended.", {
|
|
36
|
+
account: address.describe("Pacifica account (Solana address)"),
|
|
37
|
+
history: z.boolean().optional().describe("true = every order (history_summary), default false = current orders"),
|
|
38
|
+
limit: z.number().int().positive().optional(),
|
|
39
|
+
cursor: z.string().optional(),
|
|
40
|
+
}, async ({ account, history, limit, cursor }) => run({ exchange: "pacifica", account }, async () => {
|
|
41
|
+
if (history !== true)
|
|
42
|
+
return { account, positions: await fetchPrintPositions(client(), account) };
|
|
43
|
+
const page = await fetchPrintHistory(client(), account, { limit: limit ?? null, cursor: cursor ?? null });
|
|
44
|
+
return { account, positions: page.items, hasMore: page.hasMore, nextCursor: page.nextCursor };
|
|
45
|
+
}));
|
|
46
|
+
server.tool("pacifica_vaults", "Pacifica vaults (API: lakes), read-only. Without vault: every vault (TVL, NAV per share, fee, lock-up, withdrawal window, config); with account: plus that account's shares. With vault (address, or a nickname matching exactly one vault — an ambiguous nickname is INVALID_PARAMS listing the candidates): one vault plus live account equity, positions, deposit whitelist (unofficial endpoint, advisory) and whether withdrawals are open now. APY is not published (null). Deposits / withdrawals are CLI-only: perp -e pacifica vault deposit|withdraw (supports --dry-run).", {
|
|
47
|
+
vault: z.string().optional().describe("Vault address or exact nickname"),
|
|
48
|
+
account: address.optional().describe("Include this account's shares"),
|
|
49
|
+
}, async ({ vault, account }) => run({ exchange: "pacifica" }, async () => {
|
|
50
|
+
const c = client();
|
|
51
|
+
const vaults = await fetchVaults(c, account ?? null);
|
|
52
|
+
if (vault === undefined)
|
|
53
|
+
return vaults;
|
|
54
|
+
const v = findVault(vaults, vault);
|
|
55
|
+
const [acct, positions, whitelist] = await Promise.all([c.getAccount(v.address), c.getPositions(v.address), readDepositWhitelist(c, v.address)]);
|
|
56
|
+
return {
|
|
57
|
+
...v,
|
|
58
|
+
...(account !== undefined ? { holding: heldShares(v, account) } : {}),
|
|
59
|
+
live: { accountEquity: acct.account_equity ?? null, availableToWithdraw: acct.available_to_withdraw ?? null, positions: positions.map((p) => ({ symbol: p.symbol, side: p.side, amount: p.amount, entryPrice: p.entry_price })) },
|
|
60
|
+
depositWhitelist: { apiStatus: DEPOSIT_WHITELIST_API_STATUS, addresses: whitelist.addresses, error: whitelist.error },
|
|
61
|
+
withdrawWindow: withdrawWindowAt(v.config, Date.now()),
|
|
62
|
+
};
|
|
63
|
+
}));
|
|
64
|
+
}
|