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/commands/account.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { listConfiguredAccountVenues } from "../config.js";
|
|
2
|
-
import { makeTable, formatUsd, formatPnl, printJson, jsonOk, jsonError, symbolMatch } from "../utils.js";
|
|
2
|
+
import { makeTable, formatUsd, formatPnl, printJson, jsonOk, jsonError, symbolMatch, withJsonErrors } from "../utils.js";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { hasPacificaSdk, isDexCapable } from "../exchanges/capabilities.js";
|
|
5
5
|
import { PerpError } from "../errors.js";
|
|
6
6
|
import { unsupported } from "../exchanges/trading-v2.js";
|
|
7
|
+
/** The configured Pacifica account of an account read; keyless → NO_SIGNER_AVAILABLE (never the throwaway keypair's). */
|
|
8
|
+
function pacificaAccount(adapter) {
|
|
9
|
+
const read = adapter.accountForReads;
|
|
10
|
+
return typeof read === "function" ? read.call(adapter) : adapter.publicKey;
|
|
11
|
+
}
|
|
7
12
|
function pac(adapter) {
|
|
8
13
|
if (!hasPacificaSdk(adapter))
|
|
9
14
|
throw new Error("Market settings are only available on Pacifica.");
|
|
@@ -28,8 +33,14 @@ export function registerAccountCommands(program, getAdapter, isJson, getAdapterF
|
|
|
28
33
|
// user what to run and exit non-zero so scripts can detect the rename.
|
|
29
34
|
account
|
|
30
35
|
.command("balance")
|
|
31
|
-
.description("
|
|
32
|
-
.
|
|
36
|
+
.description("Any account's balances by public address, keyless (--address). Your own balance: 'perp portfolio' (renamed in v0.12)")
|
|
37
|
+
.option("--address <address>", "Read this public address — keyless (hyperliquid, lighter, lighter-rh, risex: 0x address; pacifica: Solana address). Without -e: every venue that supports it")
|
|
38
|
+
.option("--account-index <n>", "With --address on Lighter: only this account (sub-account) of the address")
|
|
39
|
+
.action(async (opts) => {
|
|
40
|
+
if (opts.address !== undefined) {
|
|
41
|
+
const explicitExchange = program.getOptionValueSource?.("exchange") === "cli";
|
|
42
|
+
return void await withJsonErrors(isJson(), () => balanceByAddress(opts.address, explicitExchange ? String(program.opts().exchange) : null, opts));
|
|
43
|
+
}
|
|
33
44
|
const msg = "'account balance' was renamed in v0.12 — use 'portfolio' instead.";
|
|
34
45
|
const remediation = "perp portfolio # all exchanges\nperp portfolio -e <exchange> # single exchange detail";
|
|
35
46
|
if (isJson()) {
|
|
@@ -47,9 +58,8 @@ export function registerAccountCommands(program, getAdapter, isJson, getAdapterF
|
|
|
47
58
|
async function fetchHip3Data(hlAdapter, fetcher) {
|
|
48
59
|
const dexes = await hlAdapter.listDeployedDexes();
|
|
49
60
|
const results = await Promise.allSettled(dexes.map(async (d) => {
|
|
50
|
-
//
|
|
51
|
-
const dexAdapter =
|
|
52
|
-
dexAdapter.setDex(d.name);
|
|
61
|
+
// An independent per-dex adapter (a prototype copy + setDex emptied the native adapter's maps)
|
|
62
|
+
const dexAdapter = hlAdapter.forDex(d.name);
|
|
53
63
|
const items = await fetcher(dexAdapter);
|
|
54
64
|
return { dex: d.name, items };
|
|
55
65
|
}));
|
|
@@ -58,12 +68,158 @@ export function registerAccountCommands(program, getAdapter, isJson, getAdapterF
|
|
|
58
68
|
.map(r => r.value)
|
|
59
69
|
.filter(r => r.items.length > 0);
|
|
60
70
|
}
|
|
71
|
+
/** `account balance --address`: keyless public read (registry: VenuePublicData.fetchBalanceByAddress). */
|
|
72
|
+
async function balanceByAddress(address, venue, opts) {
|
|
73
|
+
const { readBalanceByAddress, readBalanceByAddressAll } = await import("../balance-by-address.js");
|
|
74
|
+
const { networkOf } = await import("../cli-flags.js");
|
|
75
|
+
let accountIndex;
|
|
76
|
+
if (opts.accountIndex !== undefined) {
|
|
77
|
+
if (!/^\d+$/.test(opts.accountIndex.trim()))
|
|
78
|
+
throw new PerpError("INVALID_PARAMS", `--account-index must be a whole number, got "${opts.accountIndex}"`);
|
|
79
|
+
accountIndex = Number(opts.accountIndex);
|
|
80
|
+
}
|
|
81
|
+
const net = networkOf(program);
|
|
82
|
+
const balanceRows = (d) => {
|
|
83
|
+
const row = (label, b) => [
|
|
84
|
+
label, `$${formatUsd(b.equity)}`, `$${formatUsd(b.available)}`, `$${formatUsd(b.marginUsed)}`, formatPnl(b.unrealizedPnl),
|
|
85
|
+
];
|
|
86
|
+
return [
|
|
87
|
+
...(d.balance !== null ? [row(d.accountMode !== undefined ? `native (${d.accountMode})` : "account", d.balance)] : []),
|
|
88
|
+
...(d.accounts ?? []).map(a => row(`account ${a.accountIndex}`, a.balance)),
|
|
89
|
+
...Object.entries(d.dexes ?? {}).map(([dex, b]) => row(chalk.magenta(`dex ${dex}`), b)),
|
|
90
|
+
];
|
|
91
|
+
};
|
|
92
|
+
const spotRows = (d) => [
|
|
93
|
+
...(d.spot ?? []).map(s => ["-", s.token, s.total, s.available, s.held]),
|
|
94
|
+
...(d.accounts ?? []).flatMap(a => a.spot.map(s => [String(a.accountIndex), s.token, s.total, s.available, s.held])),
|
|
95
|
+
];
|
|
96
|
+
const extras = (d) => {
|
|
97
|
+
const b = d.balance;
|
|
98
|
+
if (b === null)
|
|
99
|
+
return [];
|
|
100
|
+
return ["usdcBalance", "borrowedUsdc", "pendingInterest", "availableToWithdraw"].filter(k => k in b).map(k => `${k}: ${b[k] === null ? "-" : String(b[k])}`);
|
|
101
|
+
};
|
|
102
|
+
const printVenue = (ex, d) => {
|
|
103
|
+
console.log(chalk.cyan.bold(`\n ${ex}`));
|
|
104
|
+
const rows = balanceRows(d);
|
|
105
|
+
if (rows.length > 0)
|
|
106
|
+
console.log(makeTable(["Account", "Equity", "Available", "Margin Used", "uPnL"], rows));
|
|
107
|
+
const x = extras(d);
|
|
108
|
+
if (x.length > 0)
|
|
109
|
+
console.log(chalk.gray(` ${x.join(" ")}`));
|
|
110
|
+
const sr = spotRows(d);
|
|
111
|
+
if (sr.length > 0)
|
|
112
|
+
console.log(makeTable(["Acct", "Spot token", "Total", "Available", "Held"], sr));
|
|
113
|
+
if (rows.length === 0 && sr.length === 0)
|
|
114
|
+
console.log(chalk.gray(" no balance (see notes)"));
|
|
115
|
+
};
|
|
116
|
+
if (venue !== null) {
|
|
117
|
+
const r = await readBalanceByAddress(venue, net, address, { accountIndex });
|
|
118
|
+
if (isJson()) {
|
|
119
|
+
return printJson(jsonOk({ exchange: r.venue, address, ...r.data }, {
|
|
120
|
+
exchange: r.venue, address, source: "public",
|
|
121
|
+
...(r.warnings.length > 0 ? { warnings: r.warnings, errors: r.errors } : {}),
|
|
122
|
+
...(r.notes.length > 0 ? { notes: r.notes } : {}),
|
|
123
|
+
}));
|
|
124
|
+
}
|
|
125
|
+
for (const w of r.warnings)
|
|
126
|
+
console.log(chalk.yellow(` ${w}`));
|
|
127
|
+
printVenue(r.venue, r.data);
|
|
128
|
+
for (const n of r.notes)
|
|
129
|
+
console.log(chalk.gray(` ${n}`));
|
|
130
|
+
console.log();
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const all = await readBalanceByAddressAll(net, address, { accountIndex });
|
|
134
|
+
if (isJson()) {
|
|
135
|
+
return printJson(jsonOk({
|
|
136
|
+
venues: all.venues,
|
|
137
|
+
...(Object.keys(all.errors).length > 0 ? { errors: all.errors } : {}),
|
|
138
|
+
...(Object.keys(all.notes).length > 0 ? { notes: all.notes } : {}),
|
|
139
|
+
}, { address, source: "public", ...(all.warnings.length > 0 ? { warnings: all.warnings } : {}) }));
|
|
140
|
+
}
|
|
141
|
+
for (const [ex, d] of Object.entries(all.venues))
|
|
142
|
+
printVenue(ex, d);
|
|
143
|
+
console.log();
|
|
144
|
+
for (const [ex, e] of Object.entries(all.errors))
|
|
145
|
+
console.log(chalk.gray(` ${ex}: ${e.code} ${e.message}`));
|
|
146
|
+
for (const [ex, n] of Object.entries(all.notes))
|
|
147
|
+
console.log(chalk.gray(` ${ex}: ${n.join("; ")}`));
|
|
148
|
+
}
|
|
149
|
+
/** `account positions --address`: keyless public read (registry: VenuePublicData.fetchPositionsByAddress). */
|
|
150
|
+
async function positionsByAddress(address, venue, opts) {
|
|
151
|
+
const { readPositionsByAddress, readPositionsByAddressAll } = await import("../positions-by-address.js");
|
|
152
|
+
const { networkOf } = await import("../cli-flags.js");
|
|
153
|
+
let accountIndex;
|
|
154
|
+
if (opts.accountIndex !== undefined) {
|
|
155
|
+
if (!/^\d+$/.test(opts.accountIndex.trim()))
|
|
156
|
+
throw new PerpError("INVALID_PARAMS", `--account-index must be a whole number, got "${opts.accountIndex}"`);
|
|
157
|
+
accountIndex = Number(opts.accountIndex);
|
|
158
|
+
}
|
|
159
|
+
const net = networkOf(program);
|
|
160
|
+
const row = (p, ex) => [
|
|
161
|
+
chalk.white.bold(p.symbol),
|
|
162
|
+
...(ex !== null ? [chalk.gray(ex)] : []),
|
|
163
|
+
p.dex != null ? chalk.magenta(p.dex) : p.accountIndex !== undefined ? chalk.gray(String(p.accountIndex)) : chalk.gray("-"),
|
|
164
|
+
p.side === "long" ? chalk.green("LONG") : chalk.red("SHORT"),
|
|
165
|
+
p.size,
|
|
166
|
+
`$${formatUsd(p.entryPrice)}`,
|
|
167
|
+
`$${formatUsd(p.markPrice)}`,
|
|
168
|
+
p.liquidationPrice === null ? chalk.gray("-") : `$${formatUsd(p.liquidationPrice)}`,
|
|
169
|
+
formatPnl(p.unrealizedPnl),
|
|
170
|
+
`${p.leverage}x`,
|
|
171
|
+
];
|
|
172
|
+
if (venue !== null) {
|
|
173
|
+
const r = await readPositionsByAddress(venue, net, address, { accountIndex, symbol: opts.symbol });
|
|
174
|
+
if (isJson()) {
|
|
175
|
+
return printJson(jsonOk(r.positions, {
|
|
176
|
+
exchange: r.venue, address, source: "public",
|
|
177
|
+
...(r.warnings.length > 0 ? { warnings: r.warnings, errors: r.errors } : {}),
|
|
178
|
+
...(r.notes.length > 0 ? { notes: r.notes } : {}),
|
|
179
|
+
}));
|
|
180
|
+
}
|
|
181
|
+
for (const w of r.warnings)
|
|
182
|
+
console.log(chalk.yellow(` ${w}`));
|
|
183
|
+
if (r.positions.length === 0) {
|
|
184
|
+
console.log(chalk.gray(`\n No open positions for ${address} on ${r.venue}${r.notes.length > 0 ? ` (${r.notes.join("; ")})` : ""}.\n`));
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
console.log(makeTable(["Symbol", "Dex/Acct", "Side", "Size", "Entry", "Mark", "Liq", "PnL", "Lev"], r.positions.map(p => row(p, null))));
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const all = await readPositionsByAddressAll(net, address, { accountIndex, symbol: opts.symbol });
|
|
191
|
+
if (isJson()) {
|
|
192
|
+
return printJson(jsonOk({
|
|
193
|
+
venues: all.venues,
|
|
194
|
+
...(Object.keys(all.errors).length > 0 ? { errors: all.errors } : {}),
|
|
195
|
+
...(Object.keys(all.notes).length > 0 ? { notes: all.notes } : {}),
|
|
196
|
+
}, { address, source: "public", ...(all.warnings.length > 0 ? { warnings: all.warnings } : {}) }));
|
|
197
|
+
}
|
|
198
|
+
const rows = Object.entries(all.venues).flatMap(([ex, ps]) => ps.map(p => row(p, ex)));
|
|
199
|
+
if (rows.length > 0)
|
|
200
|
+
console.log(makeTable(["Symbol", "Exch", "Dex/Acct", "Side", "Size", "Entry", "Mark", "Liq", "PnL", "Lev"], rows));
|
|
201
|
+
else
|
|
202
|
+
console.log(chalk.gray(`\n No open positions for ${address} on ${Object.keys(all.venues).join(", ") || "any venue"}.\n`));
|
|
203
|
+
for (const [ex, e] of Object.entries(all.errors))
|
|
204
|
+
console.log(chalk.gray(` ${ex}: ${e.code} ${e.message}`));
|
|
205
|
+
for (const [ex, n] of Object.entries(all.notes))
|
|
206
|
+
console.log(chalk.gray(` ${ex}: ${n.join("; ")}`));
|
|
207
|
+
}
|
|
61
208
|
account
|
|
62
209
|
.command("positions")
|
|
63
|
-
.description("Show open positions")
|
|
210
|
+
.description("Show open positions (yours; or any account's, keyless, with --address)")
|
|
64
211
|
.option("--hip3", "Include HIP-3 dex positions (Hyperliquid)")
|
|
212
|
+
.option("--address <address>", "Read this public address instead of your account — keyless (hyperliquid, lighter, lighter-rh, risex: 0x address; pacifica: Solana address). Without -e: every venue that supports it")
|
|
213
|
+
.option("--account-index <n>", "With --address on Lighter: only this account (sub-account) of the address")
|
|
214
|
+
.option("--symbol <symbol>", "With --address: only this market (plain asset, e.g. BTC)")
|
|
65
215
|
.action(async (opts) => {
|
|
66
216
|
const explicitExchange = program.getOptionValueSource?.("exchange") === "cli";
|
|
217
|
+
if (opts.address !== undefined) {
|
|
218
|
+
return void await withJsonErrors(isJson(), () => positionsByAddress(opts.address, explicitExchange ? String(program.opts().exchange) : null, opts));
|
|
219
|
+
}
|
|
220
|
+
if (opts.accountIndex !== undefined || opts.symbol !== undefined) {
|
|
221
|
+
throw new PerpError("INVALID_PARAMS", "--account-index / --symbol apply to --address reads", { remediation: "Add --address <address>, or drop the option" });
|
|
222
|
+
}
|
|
67
223
|
if (!explicitExchange && getAdapterForExchange) {
|
|
68
224
|
const EXCHANGES = await listConfiguredAccountVenues();
|
|
69
225
|
const allRows = [];
|
|
@@ -316,7 +472,7 @@ export function registerAccountCommands(program, getAdapter, isJson, getAdapterF
|
|
|
316
472
|
// Pacifica: use dedicated SDK endpoint
|
|
317
473
|
if (hasPacificaSdk(adapter)) {
|
|
318
474
|
const sdk = adapter.sdk;
|
|
319
|
-
const settings = await sdk.getAccountSettings(adapter
|
|
475
|
+
const settings = await sdk.getAccountSettings(pacificaAccount(adapter));
|
|
320
476
|
if (isJson())
|
|
321
477
|
return printJson(jsonOk(settings));
|
|
322
478
|
// GET /account/settings returns an object; per-market entries are in `margin_settings`
|
|
@@ -404,7 +560,8 @@ export function registerAccountCommands(program, getAdapter, isJson, getAdapterF
|
|
|
404
560
|
.description("Margin details for a specific symbol position")
|
|
405
561
|
.action(async (symbol) => {
|
|
406
562
|
const sym = symbol.toUpperCase();
|
|
407
|
-
|
|
563
|
+
// Errors: the one envelope (code, status, remediation) and exit 1 via withJsonErrors.
|
|
564
|
+
return void await withJsonErrors(isJson(), async () => {
|
|
408
565
|
const adapter = await getAdapter();
|
|
409
566
|
const [balance, positions] = await Promise.all([
|
|
410
567
|
adapter.getBalance(),
|
|
@@ -452,20 +609,7 @@ export function registerAccountCommands(program, getAdapter, isJson, getAdapterF
|
|
|
452
609
|
console.log(` Liquidation: ${pos.liquidationPrice === null ? chalk.gray("-") : `$${formatUsd(pos.liquidationPrice)}`}`);
|
|
453
610
|
console.log(` Unrealized PnL: ${formatPnl(pos.unrealizedPnl)}`);
|
|
454
611
|
console.log();
|
|
455
|
-
}
|
|
456
|
-
catch (err) {
|
|
457
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
458
|
-
if (isJson()) {
|
|
459
|
-
const { classifyError } = await import("../errors.js");
|
|
460
|
-
const classified = classifyError(err);
|
|
461
|
-
return printJson(jsonError(classified.code, classified.message, {
|
|
462
|
-
status: classified.status,
|
|
463
|
-
retryable: classified.retryable,
|
|
464
|
-
}));
|
|
465
|
-
}
|
|
466
|
-
console.error(chalk.red(`Error: ${msg}`));
|
|
467
|
-
process.exitCode = 1;
|
|
468
|
-
}
|
|
612
|
+
});
|
|
469
613
|
});
|
|
470
614
|
// ── PnL Report ──
|
|
471
615
|
account
|
|
@@ -609,7 +753,7 @@ export function registerAccountCommands(program, getAdapter, isJson, getAdapterF
|
|
|
609
753
|
}
|
|
610
754
|
const p = pac(adapter);
|
|
611
755
|
const sdk = p.sdk;
|
|
612
|
-
const orders = await sdk.getTWAPOrders(p
|
|
756
|
+
const orders = await sdk.getTWAPOrders(pacificaAccount(p));
|
|
613
757
|
if (isJson())
|
|
614
758
|
return printJson(jsonOk(orders));
|
|
615
759
|
if (!orders || orders.length === 0) {
|
|
@@ -90,6 +90,13 @@ export declare function importSecretLineCount(venue: VenueId): number;
|
|
|
90
90
|
export declare function importSecretFromLines(venue: VenueId, lines: string[]): ImportSecret;
|
|
91
91
|
/** Read the secret: hidden TTY prompt, else piped stdin (ondo: 2 lines key id + secret; others: 1 line). */
|
|
92
92
|
export declare function readImportSecret(venue: VenueId): Promise<ImportSecret>;
|
|
93
|
+
/**
|
|
94
|
+
* Venues whose keys cannot be imported. TxFlow: market-data-only (unofficial read-only API).
|
|
95
|
+
* RISEx: perp-cli trades only with a signer it registered itself and then restricted ON-CHAIN to
|
|
96
|
+
* the trading permission; a signer created in the RISEx app keeps every permission (including
|
|
97
|
+
* deposit / withdraw), so it is never stored here.
|
|
98
|
+
*/
|
|
99
|
+
export declare function assertImportSupported(venue: VenueId, network: Network): void;
|
|
93
100
|
/** Venues whose import cannot be checked against the venue (stored as "unverified"). */
|
|
94
101
|
export declare const UNVERIFIED_IMPORT_VENUES: readonly VenueId[];
|
|
95
102
|
/**
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
import chalk from "chalk";
|
|
25
25
|
import { PerpError, classifyError } from "../errors.js";
|
|
26
26
|
import { acquireLock, releaseLock, getAgent, setAgent, deleteAgent, listAgents, agentNetworkOf, agentSourceOf, getVenueAgent, setVenueAgent, deleteVenueAgent, } from "../agent-wallet/store.js";
|
|
27
|
-
import { getVenue, networkConfig } from "../exchanges/venue.js";
|
|
27
|
+
import { getVenue, networkConfig, roleUnsupported } from "../exchanges/venue.js";
|
|
28
|
+
import { unsupported } from "../exchanges/trading-v2.js";
|
|
28
29
|
import { LIGHTER_RH_RESERVED_KEY_INDEXES } from "../exchanges/venues/lighter-family.js";
|
|
29
30
|
import { loadOws } from "../signer/ows-loader.js";
|
|
30
31
|
import { defaultAgentName, isLighterFamilyVenue, parseExpiresIn, promptHidden, qfexWithdrawKeyWarning } from "./agent.js";
|
|
@@ -67,6 +68,11 @@ export function importSecretLabel(venue) {
|
|
|
67
68
|
case "arcus": return "Arcus API key private key (Ed25519)";
|
|
68
69
|
case "ondo": return "Ondo API secret";
|
|
69
70
|
case "qfex": return "QFEX API secret";
|
|
71
|
+
case "risex": return "RISEx signer private key";
|
|
72
|
+
case "txflow": return "TxFlow key (not supported)";
|
|
73
|
+
case "variational": return "Variational key (not supported)";
|
|
74
|
+
case "grvt": return "GRVT key (not supported)";
|
|
75
|
+
case "extended": return "Extended key (not supported)";
|
|
70
76
|
}
|
|
71
77
|
}
|
|
72
78
|
/**
|
|
@@ -154,6 +160,20 @@ function redacted(err, secrets, venue) {
|
|
|
154
160
|
details.remediation = scrub(e.remediation, forms);
|
|
155
161
|
return new PerpError(e.code, scrub(e.message, forms), details);
|
|
156
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* Venues whose keys cannot be imported. TxFlow: market-data-only (unofficial read-only API).
|
|
165
|
+
* RISEx: perp-cli trades only with a signer it registered itself and then restricted ON-CHAIN to
|
|
166
|
+
* the trading permission; a signer created in the RISEx app keeps every permission (including
|
|
167
|
+
* deposit / withdraw), so it is never stored here.
|
|
168
|
+
*/
|
|
169
|
+
export function assertImportSupported(venue, network) {
|
|
170
|
+
const def = getVenue(venue);
|
|
171
|
+
if (!def.roles.includes("trading"))
|
|
172
|
+
throw roleUnsupported(def, "agentImport");
|
|
173
|
+
if (venue === "risex") {
|
|
174
|
+
throw unsupported("risex", "agentImport", "perp-cli only uses RISEx signers it registered and restricted on-chain to trading-only permissions; an app-created signer keeps deposit / withdraw permissions", `Register a restricted signer with your master wallet: perp${network === "testnet" ? " -n testnet" : ""} wallet agent approve risex --master <ows-wallet>`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
157
177
|
/** Venues whose import cannot be checked against the venue (stored as "unverified"). */
|
|
158
178
|
export const UNVERIFIED_IMPORT_VENUES = ["pacifica"];
|
|
159
179
|
/**
|
|
@@ -722,6 +742,8 @@ async function importQfex(p, agentName, s, replacing) {
|
|
|
722
742
|
* appears in a thrown error.
|
|
723
743
|
*/
|
|
724
744
|
export async function importVenueAgent(p) {
|
|
745
|
+
// Refused before the secret is even inspected (nothing read, stored or sent).
|
|
746
|
+
assertImportSupported(p.venue, p.network);
|
|
725
747
|
const secrets = secretsOf(p.secret);
|
|
726
748
|
if (secrets.some(x => x.trim().length === 0))
|
|
727
749
|
throw new PerpError("INVALID_PARAMS", "Empty key — nothing was imported");
|
|
@@ -751,6 +773,13 @@ export async function importVenueAgent(p) {
|
|
|
751
773
|
case "lighter":
|
|
752
774
|
case "lighter-rh":
|
|
753
775
|
return await importLighter(p, p.venue, agentName, key, replacing);
|
|
776
|
+
case "risex":
|
|
777
|
+
case "txflow":
|
|
778
|
+
case "variational":
|
|
779
|
+
case "grvt":
|
|
780
|
+
case "extended":
|
|
781
|
+
// Unreachable: assertImportSupported() refused these before the lock.
|
|
782
|
+
throw new PerpError("CAPABILITY_UNSUPPORTED", `${p.venue} keys cannot be imported`);
|
|
754
783
|
}
|
|
755
784
|
}
|
|
756
785
|
catch (err) {
|
package/dist/commands/agent.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Command, Option } from "commander";
|
|
2
|
-
import { loadSettings, type OndoAgentMeta, type ArcusAgentMeta, type QfexAgentMeta } from "../settings.js";
|
|
2
|
+
import { loadSettings, type OndoAgentMeta, type ArcusAgentMeta, type QfexAgentMeta, type RisexAgentMeta } from "../settings.js";
|
|
3
3
|
import "../exchanges/venues/index.js";
|
|
4
4
|
import type { Network, VenueId } from "../exchanges/venue-types.js";
|
|
5
5
|
import { type LighterVenueId } from "../exchanges/venues/lighter-family.js";
|
|
@@ -27,7 +27,7 @@ export interface VerifyResult {
|
|
|
27
27
|
/** Extract the agent list from a Pacifica /agent/list envelope; throws on an unrecognized shape. */
|
|
28
28
|
export declare function parsePacAgentList(json: unknown): unknown[];
|
|
29
29
|
/**
|
|
30
|
-
* Confirmation of the account a QFEX key was resolved to
|
|
30
|
+
* Confirmation of the account a QFEX key was resolved to. In a terminal: a
|
|
31
31
|
* y/N prompt showing the UUID. Without one (piped stdin, --json): only an explicit --account-id
|
|
32
32
|
* that equals the resolved account counts — the resolved UUID is printed on stderr either way.
|
|
33
33
|
*/
|
|
@@ -94,6 +94,9 @@ export type ApproveAgentOutcome = {
|
|
|
94
94
|
} | {
|
|
95
95
|
venue: "arcus";
|
|
96
96
|
meta: ArcusAgentMeta;
|
|
97
|
+
} | {
|
|
98
|
+
venue: "risex";
|
|
99
|
+
meta: RisexAgentMeta;
|
|
97
100
|
} | {
|
|
98
101
|
venue: LighterVenueId;
|
|
99
102
|
agentName: string;
|
|
@@ -131,7 +134,7 @@ export declare function qfexWithdrawKeyWarning(meta: Pick<QfexAgentMeta, "agentN
|
|
|
131
134
|
/** Venues `wallet agent rotate` (and `approve --rotate`) can rotate. */
|
|
132
135
|
type RotatableVenue = "aster" | "hyperliquid" | "pacifica" | LighterVenueId;
|
|
133
136
|
type RotatedAgentOutcome = Exclude<ApproveAgentOutcome, {
|
|
134
|
-
venue: "ondo" | "arcus";
|
|
137
|
+
venue: "ondo" | "arcus" | "risex";
|
|
135
138
|
}>;
|
|
136
139
|
export interface RotateAgentParams {
|
|
137
140
|
exchange: RotatableVenue;
|