perp-cli 0.12.15 → 0.14.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 +278 -31
- package/dist/_stderr-filter.js +0 -1
- package/dist/agent-wallet/lighter-keystore.d.ts +11 -0
- package/dist/agent-wallet/lighter-keystore.js +92 -10
- package/dist/agent-wallet/passphrase.d.ts +1 -1
- package/dist/agent-wallet/passphrase.js +16 -3
- package/dist/agent-wallet/store.d.ts +37 -4
- package/dist/agent-wallet/store.js +132 -0
- package/dist/agent-wallet/venue-keystore.d.ts +14 -0
- package/dist/agent-wallet/venue-keystore.js +121 -0
- package/dist/api/public/hyperliquid.js +4 -4
- package/dist/api/public/lighter.js +5 -5
- package/dist/api/public/pacifica.d.ts +0 -1
- package/dist/api/public/pacifica.js +4 -13
- package/dist/api/public/urls.d.ts +9 -1
- package/dist/api/public/urls.js +35 -13
- package/dist/arb/file-lock.d.ts +11 -0
- package/dist/arb/file-lock.js +74 -0
- package/dist/arb/index.d.ts +2 -2
- package/dist/arb/index.js +2 -2
- package/dist/arb/pending-entry.d.ts +32 -0
- package/dist/arb/pending-entry.js +77 -0
- package/dist/arb/sizing.d.ts +6 -13
- package/dist/arb/sizing.js +12 -51
- package/dist/arb/state.d.ts +45 -12
- package/dist/arb/state.js +214 -42
- package/dist/arb/utils.d.ts +20 -6
- package/dist/arb/utils.js +43 -39
- package/dist/bot/conditions.d.ts +4 -4
- package/dist/bot/conditions.js +11 -6
- package/dist/bot/config.d.ts +17 -1
- package/dist/bot/config.js +48 -12
- package/dist/bot/engine.d.ts +61 -2
- package/dist/bot/engine.js +610 -144
- package/dist/bot/fill-size.d.ts +7 -0
- package/dist/bot/fill-size.js +18 -0
- package/dist/bot/index.d.ts +1 -1
- package/dist/bot/index.js +1 -1
- package/dist/bot/perp-order.d.ts +99 -0
- package/dist/bot/perp-order.js +299 -0
- package/dist/bot/presets.d.ts +7 -0
- package/dist/bot/presets.js +17 -0
- package/dist/bot/quarantine.d.ts +75 -0
- package/dist/bot/quarantine.js +190 -0
- package/dist/bot/quote-rules.d.ts +23 -0
- package/dist/bot/quote-rules.js +69 -0
- package/dist/bot/strategies/avellaneda-mm.d.ts +32 -2
- package/dist/bot/strategies/avellaneda-mm.js +72 -70
- package/dist/bot/strategies/basis-arb.js +2 -0
- package/dist/bot/strategies/dca-strategy.d.ts +2 -0
- package/dist/bot/strategies/dca-strategy.js +5 -0
- package/dist/bot/strategies/funding-arb-strategy.d.ts +43 -3
- package/dist/bot/strategies/funding-arb-strategy.js +571 -380
- package/dist/bot/strategies/funding-arb-utils.d.ts +48 -23
- package/dist/bot/strategies/funding-arb-utils.js +159 -195
- package/dist/bot/strategies/funding-arb-v2.d.ts +32 -0
- package/dist/bot/strategies/funding-arb-v2.js +258 -47
- package/dist/bot/strategies/funding-auto.js +215 -194
- package/dist/bot/strategies/spot-perp-arb-strategy.d.ts +14 -0
- package/dist/bot/strategies/spot-perp-arb-strategy.js +217 -50
- package/dist/bot/strategies/spot-perp-executor.d.ts +73 -19
- package/dist/bot/strategies/spot-perp-executor.js +319 -120
- package/dist/bot/strategies/spot-perp-state.d.ts +43 -0
- package/dist/bot/strategies/spot-perp-state.js +70 -0
- package/dist/bot/strategy-types.d.ts +6 -0
- package/dist/bot/tui/BotDashboard.d.ts +7 -2
- package/dist/bot/tui/BotDashboard.js +6 -3
- package/dist/bridge-engine.d.ts +120 -19
- package/dist/bridge-engine.js +710 -422
- package/dist/bridge-signers.d.ts +54 -0
- package/dist/bridge-signers.js +161 -0
- package/dist/cache.d.ts +4 -1
- package/dist/cache.js +11 -0
- package/dist/cli-flags.d.ts +50 -0
- package/dist/cli-flags.js +104 -0
- package/dist/cli-program.d.ts +35 -0
- package/dist/cli-program.js +286 -0
- package/dist/cli-spec.js +1 -1
- package/dist/client-id-tracker.js +11 -2
- package/dist/commands/account.d.ts +7 -1
- package/dist/commands/account.js +74 -84
- package/dist/commands/agent-import.d.ts +114 -0
- package/dist/commands/agent-import.js +794 -0
- package/dist/commands/agent.d.ts +232 -2
- package/dist/commands/agent.js +1858 -955
- package/dist/commands/alerts.d.ts +1 -0
- package/dist/commands/alerts.js +31 -28
- package/dist/commands/arb/index.d.ts +60 -1
- package/dist/commands/arb/index.js +381 -384
- package/dist/commands/arb-auto.d.ts +132 -4
- package/dist/commands/arb-auto.js +1474 -967
- package/dist/commands/arb.d.ts +3 -1
- package/dist/commands/arb.js +62 -30
- package/dist/commands/bot.js +127 -47
- package/dist/commands/bridge.d.ts +2 -1
- package/dist/commands/bridge.js +339 -192
- package/dist/commands/builder.d.ts +55 -0
- package/dist/commands/builder.js +387 -0
- package/dist/commands/funds-onchain.d.ts +32 -0
- package/dist/commands/funds-onchain.js +286 -0
- package/dist/commands/funds.d.ts +25 -0
- package/dist/commands/funds.js +939 -245
- package/dist/commands/history.js +72 -45
- package/dist/commands/init.d.ts +107 -15
- package/dist/commands/init.js +1116 -249
- package/dist/commands/jobs.d.ts +2 -1
- package/dist/commands/jobs.js +77 -15
- package/dist/commands/manage.js +136 -91
- package/dist/commands/market.d.ts +4 -1
- package/dist/commands/market.js +35 -32
- package/dist/commands/outcome.d.ts +10 -0
- package/dist/commands/outcome.js +396 -0
- package/dist/commands/plan.js +52 -12
- package/dist/commands/portfolio.d.ts +1 -0
- package/dist/commands/portfolio.js +60 -72
- package/dist/commands/rebalance.d.ts +2 -1
- package/dist/commands/rebalance.js +33 -43
- package/dist/commands/risk.js +46 -19
- package/dist/commands/settings.d.ts +1 -0
- package/dist/commands/settings.js +246 -51
- package/dist/commands/trade.d.ts +50 -0
- package/dist/commands/trade.js +1943 -695
- package/dist/commands/wallet.d.ts +30 -1
- package/dist/commands/wallet.js +316 -337
- package/dist/config.d.ts +60 -9
- package/dist/config.js +252 -82
- package/dist/constants.d.ts +29 -4
- package/dist/constants.js +62 -20
- package/dist/dashboard/server.d.ts +2 -0
- package/dist/dashboard/server.js +9 -6
- package/dist/dashboard/ui.js +6 -4
- package/dist/dashboard/ws-feeds.js +20 -8
- package/dist/dex-asset-map.js +5 -3
- package/dist/errors.d.ts +122 -0
- package/dist/errors.js +194 -0
- package/dist/event-stream.js +75 -19
- package/dist/evm-master-tx.d.ts +59 -0
- package/dist/evm-master-tx.js +154 -0
- package/dist/exchanges/adapter-network.d.ts +10 -0
- package/dist/exchanges/adapter-network.js +10 -0
- package/dist/exchanges/arcus/adapter.d.ts +196 -0
- package/dist/exchanges/arcus/adapter.js +1092 -0
- package/dist/exchanges/arcus/agent.d.ts +55 -0
- package/dist/exchanges/arcus/agent.js +188 -0
- package/dist/exchanges/arcus/client.d.ts +63 -0
- package/dist/exchanges/arcus/client.js +285 -0
- package/dist/exchanges/arcus/public.d.ts +65 -0
- package/dist/exchanges/arcus/public.js +138 -0
- package/dist/exchanges/arcus/signing.d.ts +176 -0
- package/dist/exchanges/arcus/signing.js +288 -0
- package/dist/exchanges/arcus/spot-chain.d.ts +60 -0
- package/dist/exchanges/arcus/spot-chain.js +241 -0
- package/dist/exchanges/arcus/spot-router.d.ts +177 -0
- package/dist/exchanges/arcus/spot-router.js +183 -0
- package/dist/exchanges/arcus/spot.d.ts +109 -0
- package/dist/exchanges/arcus/spot.js +645 -0
- package/dist/exchanges/aster-funds.d.ts +127 -0
- package/dist/exchanges/aster-funds.js +252 -0
- package/dist/exchanges/aster-nonce.d.ts +2 -0
- package/dist/exchanges/aster-nonce.js +107 -0
- package/dist/exchanges/aster-spot.d.ts +117 -0
- package/dist/exchanges/aster-spot.js +686 -0
- package/dist/exchanges/aster-typed-data.d.ts +133 -7
- package/dist/exchanges/aster-typed-data.js +121 -7
- package/dist/exchanges/aster.d.ts +219 -6
- package/dist/exchanges/aster.js +1023 -153
- package/dist/exchanges/builder-fee.d.ts +254 -0
- package/dist/exchanges/builder-fee.js +421 -0
- package/dist/exchanges/canonical-symbols.d.ts +32 -0
- package/dist/exchanges/canonical-symbols.js +96 -0
- package/dist/exchanges/capabilities.d.ts +7 -1
- package/dist/exchanges/capabilities.js +7 -0
- package/dist/exchanges/hl-signing.d.ts +165 -0
- package/dist/exchanges/hl-signing.js +158 -0
- package/dist/exchanges/hyperliquid-outcome.d.ts +211 -0
- package/dist/exchanges/hyperliquid-outcome.js +646 -0
- package/dist/exchanges/hyperliquid-spot.d.ts +44 -5
- package/dist/exchanges/hyperliquid-spot.js +308 -117
- package/dist/exchanges/hyperliquid.d.ts +462 -57
- package/dist/exchanges/hyperliquid.js +1575 -449
- package/dist/exchanges/index.d.ts +6 -0
- package/dist/exchanges/index.js +4 -0
- package/dist/exchanges/interface.d.ts +63 -10
- package/dist/exchanges/interface.js +18 -3
- package/dist/exchanges/ioc-outcome.d.ts +44 -0
- package/dist/exchanges/ioc-outcome.js +57 -0
- package/dist/exchanges/legacy-trading-v2.d.ts +39 -0
- package/dist/exchanges/legacy-trading-v2.js +940 -0
- package/dist/exchanges/lighter-public.d.ts +43 -0
- package/dist/exchanges/lighter-public.js +276 -0
- package/dist/exchanges/lighter-rh-deposit.d.ts +62 -0
- package/dist/exchanges/lighter-rh-deposit.js +185 -0
- package/dist/exchanges/lighter-signer.d.ts +123 -0
- package/dist/exchanges/lighter-signer.js +215 -0
- package/dist/exchanges/lighter-spot.d.ts +91 -13
- package/dist/exchanges/lighter-spot.js +595 -233
- package/dist/exchanges/lighter.d.ts +611 -39
- package/dist/exchanges/lighter.js +1890 -649
- package/dist/exchanges/ondo/adapter.d.ts +166 -0
- package/dist/exchanges/ondo/adapter.js +835 -0
- package/dist/exchanges/ondo/agent.d.ts +31 -0
- package/dist/exchanges/ondo/agent.js +101 -0
- package/dist/exchanges/ondo/client.d.ts +60 -0
- package/dist/exchanges/ondo/client.js +297 -0
- package/dist/exchanges/ondo/funds.d.ts +122 -0
- package/dist/exchanges/ondo/funds.js +290 -0
- package/dist/exchanges/ondo/public.d.ts +95 -0
- package/dist/exchanges/ondo/public.js +214 -0
- package/dist/exchanges/ondo/spot.d.ts +127 -0
- package/dist/exchanges/ondo/spot.js +392 -0
- package/dist/exchanges/outcome-interface.d.ts +140 -0
- package/dist/exchanges/outcome-interface.js +16 -0
- package/dist/exchanges/pacifica-spot.d.ts +83 -0
- package/dist/exchanges/pacifica-spot.js +324 -0
- package/dist/exchanges/pacifica-typed-data.d.ts +30 -13
- package/dist/exchanges/pacifica-typed-data.js +57 -9
- package/dist/exchanges/pacifica.d.ts +288 -4
- package/dist/exchanges/pacifica.js +1013 -76
- package/dist/exchanges/precision.d.ts +47 -0
- package/dist/exchanges/precision.js +209 -0
- package/dist/exchanges/qfex/adapter.d.ts +341 -0
- package/dist/exchanges/qfex/adapter.js +1383 -0
- package/dist/exchanges/qfex/agent.d.ts +58 -0
- package/dist/exchanges/qfex/agent.js +188 -0
- package/dist/exchanges/qfex/client.d.ts +54 -0
- package/dist/exchanges/qfex/client.js +138 -0
- package/dist/exchanges/qfex/errors.d.ts +70 -0
- package/dist/exchanges/qfex/errors.js +236 -0
- package/dist/exchanges/qfex/public.d.ts +122 -0
- package/dist/exchanges/qfex/public.js +268 -0
- package/dist/exchanges/qfex/signing.d.ts +160 -0
- package/dist/exchanges/qfex/signing.js +283 -0
- package/dist/exchanges/qfex/ws-transport.d.ts +294 -0
- package/dist/exchanges/qfex/ws-transport.js +798 -0
- package/dist/exchanges/rate-limiter.d.ts +12 -0
- package/dist/exchanges/rate-limiter.js +64 -0
- package/dist/exchanges/registry.d.ts +14 -2
- package/dist/exchanges/registry.js +20 -32
- package/dist/exchanges/slippage.d.ts +37 -0
- package/dist/exchanges/slippage.js +70 -0
- package/dist/exchanges/spot-factory.d.ts +166 -0
- package/dist/exchanges/spot-factory.js +431 -0
- package/dist/exchanges/spot-interface.d.ts +98 -4
- package/dist/exchanges/spot-interface.js +27 -1
- package/dist/exchanges/spot-result.d.ts +79 -0
- package/dist/exchanges/spot-result.js +273 -0
- package/dist/exchanges/trading-v2.d.ts +117 -0
- package/dist/exchanges/trading-v2.js +301 -0
- package/dist/exchanges/venue-types.d.ts +231 -0
- package/dist/exchanges/venue-types.js +87 -0
- package/dist/exchanges/venue.d.ts +211 -0
- package/dist/exchanges/venue.js +132 -0
- package/dist/exchanges/venues/arcus.d.ts +8 -0
- package/dist/exchanges/venues/arcus.js +109 -0
- package/dist/exchanges/venues/aster.d.ts +49 -0
- package/dist/exchanges/venues/aster.js +176 -0
- package/dist/exchanges/venues/create-helpers.d.ts +18 -0
- package/dist/exchanges/venues/create-helpers.js +199 -0
- package/dist/exchanges/venues/hyperliquid.d.ts +23 -0
- package/dist/exchanges/venues/hyperliquid.js +126 -0
- package/dist/exchanges/venues/index.d.ts +16 -0
- package/dist/exchanges/venues/index.js +26 -0
- package/dist/exchanges/venues/lighter-family.d.ts +92 -0
- package/dist/exchanges/venues/lighter-family.js +166 -0
- package/dist/exchanges/venues/lighter-rh.d.ts +7 -0
- package/dist/exchanges/venues/lighter-rh.js +58 -0
- package/dist/exchanges/venues/lighter.d.ts +6 -0
- package/dist/exchanges/venues/lighter.js +55 -0
- package/dist/exchanges/venues/ondo.d.ts +34 -0
- package/dist/exchanges/venues/ondo.js +140 -0
- package/dist/exchanges/venues/pacifica.d.ts +8 -0
- package/dist/exchanges/venues/pacifica.js +95 -0
- package/dist/exchanges/venues/qfex.d.ts +28 -0
- package/dist/exchanges/venues/qfex.js +132 -0
- package/dist/execution-log.js +10 -2
- package/dist/funding/legacy-public.d.ts +31 -0
- package/dist/funding/legacy-public.js +369 -0
- package/dist/funding/normalize.d.ts +28 -16
- package/dist/funding/normalize.js +61 -29
- package/dist/funding/rates.d.ts +46 -11
- package/dist/funding/rates.js +228 -277
- package/dist/guardrail/perp-guardrail.js +0 -0
- package/dist/index.js +157 -682
- package/dist/jobs.d.ts +84 -6
- package/dist/jobs.js +239 -41
- package/dist/landing.d.ts +14 -0
- package/dist/landing.js +36 -0
- package/dist/mcp-server.d.ts +14 -4
- package/dist/mcp-server.js +820 -402
- package/dist/mcp-trade-guard.d.ts +16 -0
- package/dist/mcp-trade-guard.js +59 -0
- package/dist/pacifica/client.d.ts +41 -10
- package/dist/pacifica/client.js +167 -63
- package/dist/pacifica/constants.d.ts +0 -1
- package/dist/pacifica/constants.js +0 -5
- package/dist/pacifica/deposit.d.ts +30 -3
- package/dist/pacifica/deposit.js +119 -2
- package/dist/pacifica/faucet.d.ts +29 -0
- package/dist/pacifica/faucet.js +100 -0
- package/dist/pacifica/sign-tx.d.ts +15 -0
- package/dist/pacifica/sign-tx.js +41 -0
- package/dist/pacifica/types/account.d.ts +28 -4
- package/dist/pacifica/types/lake.d.ts +20 -5
- package/dist/pacifica/types/lake.js +4 -0
- package/dist/pacifica/types/market.d.ts +5 -0
- package/dist/pacifica/types/order.d.ts +4 -1
- package/dist/pacifica/types/position.d.ts +9 -1
- package/dist/plan-executor.d.ts +10 -5
- package/dist/plan-executor.js +165 -54
- package/dist/position-history.js +13 -0
- package/dist/rebalance.d.ts +26 -2
- package/dist/rebalance.js +86 -7
- package/dist/relay-swap.d.ts +232 -0
- package/dist/relay-swap.js +630 -0
- package/dist/risk.js +5 -1
- package/dist/secret-env.d.ts +15 -0
- package/dist/secret-env.js +36 -0
- package/dist/settings.d.ts +169 -6
- package/dist/settings.js +219 -38
- package/dist/signer/ows-evm.d.ts +13 -0
- package/dist/signer/ows-evm.js +22 -0
- package/dist/smart-order.d.ts +9 -0
- package/dist/smart-order.js +53 -8
- package/dist/strategies/dca.d.ts +6 -2
- package/dist/strategies/dca.js +66 -26
- package/dist/strategies/funding-arb.d.ts +11 -1
- package/dist/strategies/funding-arb.js +202 -89
- package/dist/strategies/grid.d.ts +31 -0
- package/dist/strategies/grid.js +89 -11
- package/dist/strategies/pending-stop.d.ts +8 -0
- package/dist/strategies/pending-stop.js +12 -0
- package/dist/strategies/split-order.d.ts +45 -17
- package/dist/strategies/split-order.js +157 -91
- package/dist/strategies/trailing-stop.d.ts +2 -1
- package/dist/strategies/trailing-stop.js +52 -6
- package/dist/strategies/twap.d.ts +6 -1
- package/dist/strategies/twap.js +39 -11
- package/dist/trade-validator.d.ts +22 -0
- package/dist/trade-validator.js +119 -15
- package/dist/utils/numeric.d.ts +46 -0
- package/dist/utils/numeric.js +79 -0
- package/dist/utils.d.ts +19 -0
- package/dist/utils.js +96 -19
- package/dist/withdraw-gate.d.ts +49 -0
- package/dist/withdraw-gate.js +131 -0
- package/package.json +15 -6
- package/skills/perp-cli/SKILL.md +338 -134
- package/skills/perp-cli/references/agent-operations.md +181 -92
- package/skills/perp-cli/references/commands.md +475 -132
- package/skills/perp-cli/references/strategies.md +44 -38
- package/skills/perp-cli/scripts/arb-monitor.sh +22 -17
- package/skills/perp-cli/scripts/funding-analysis.sh +20 -10
- package/skills/perp-cli/scripts/preflight.sh +21 -14
- package/skills/perp-cli/scripts/spot-perp-scan.sh +12 -7
- package/skills/perp-cli/scripts/validate-arb.sh +33 -16
- package/vendor/lighter-signer/SHA256SUMS +2 -0
- package/vendor/lighter-signer/VERSION +8 -0
- package/vendor/lighter-signer/lighter-signer.wasm +0 -0
- package/vendor/lighter-signer/wasm_exec.js +575 -0
- package/dist/bot/strategies/funding-arb-v2-strategy.d.ts +0 -42
- package/dist/bot/strategies/funding-arb-v2-strategy.js +0 -864
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type ExecutionRecord } from "./execution-log.js";
|
|
2
|
+
import type { ExchangeAdapter } from "./exchanges/interface.js";
|
|
3
|
+
import type { Network } from "./exchanges/venue-types.js";
|
|
4
|
+
/** Refuse a reduce-only order up front on a venue whose reduce-only orders are gated (uniform CAPABILITY_UNSUPPORTED). */
|
|
5
|
+
export declare function mcpReduceOnlyGate(adapter: ExchangeAdapter): void;
|
|
6
|
+
/** PERP_NETWORK → network. Unset = "mainnet" (documented default); any other value must parse. */
|
|
7
|
+
export declare function resolveMcpNetwork(env: string | undefined): Network;
|
|
8
|
+
/** Pre-send gate for an MCP order: quarantine (non-reduce-only), then local risk limits (never forced). */
|
|
9
|
+
export declare function mcpPreTradeGate(adapter: ExchangeAdapter, p: {
|
|
10
|
+
symbol: string;
|
|
11
|
+
size: number;
|
|
12
|
+
price: number | null;
|
|
13
|
+
reduceOnly: boolean;
|
|
14
|
+
}, log: (msg: string) => void): Promise<void>;
|
|
15
|
+
/** Execution-log entry for an MCP order (source + network recorded in meta). */
|
|
16
|
+
export declare function logMcpExecution(network: Network, record: Omit<ExecutionRecord, "id" | "timestamp" | "dryRun">): ExecutionRecord;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP write-path safety (review N4): the MCP `trade_execute` / `trade_close` tools go through
|
|
3
|
+
* the same gates as `perp trade`:
|
|
4
|
+
*
|
|
5
|
+
* - network: PERP_NETWORK, validated by the same parser as `-n` (unset = mainnet, the
|
|
6
|
+
* documented default — never a silent substitution for an invalid value);
|
|
7
|
+
* - quarantine: a non-reduce-only order on a quarantined symbol is refused (an earlier
|
|
8
|
+
* unknown outcome must be resolved by a human first);
|
|
9
|
+
* - local risk limits: enforceOrderRisk with force=false — there is NO force override over
|
|
10
|
+
* MCP (an agent must not be able to bypass the user's limits);
|
|
11
|
+
* - execution log: every placed / failed order is appended to ~/.perp/executions.jsonl,
|
|
12
|
+
* tagged source "mcp" and the network;
|
|
13
|
+
* - venue gates: a reduce-only order (trade_execute reduceOnly, trade_close) on a venue whose
|
|
14
|
+
* reduce-only orders are currently refused (none today) fails with the uniform
|
|
15
|
+
* CAPABILITY_UNSUPPORTED before any read or send (mcpReduceOnlyGate).
|
|
16
|
+
*/
|
|
17
|
+
import { parseNetwork } from "./cli-flags.js";
|
|
18
|
+
import { PerpError } from "./errors.js";
|
|
19
|
+
import { logExecution } from "./execution-log.js";
|
|
20
|
+
import { quarantineEntryFor } from "./bot/quarantine.js";
|
|
21
|
+
import { enforceOrderRisk } from "./trade-validator.js";
|
|
22
|
+
import { reduceOnlyGateOf } from "./exchanges/trading-v2.js";
|
|
23
|
+
/** Refuse a reduce-only order up front on a venue whose reduce-only orders are gated (uniform CAPABILITY_UNSUPPORTED). */
|
|
24
|
+
export function mcpReduceOnlyGate(adapter) {
|
|
25
|
+
const gate = reduceOnlyGateOf(adapter);
|
|
26
|
+
if (gate !== null)
|
|
27
|
+
throw gate;
|
|
28
|
+
}
|
|
29
|
+
/** PERP_NETWORK → network. Unset = "mainnet" (documented default); any other value must parse. */
|
|
30
|
+
export function resolveMcpNetwork(env) {
|
|
31
|
+
if (env === undefined)
|
|
32
|
+
return "mainnet";
|
|
33
|
+
return parseNetwork(env);
|
|
34
|
+
}
|
|
35
|
+
/** Pre-send gate for an MCP order: quarantine (non-reduce-only), then local risk limits (never forced). */
|
|
36
|
+
export async function mcpPreTradeGate(adapter, p, log) {
|
|
37
|
+
if (p.reduceOnly)
|
|
38
|
+
mcpReduceOnlyGate(adapter);
|
|
39
|
+
if (!p.reduceOnly) {
|
|
40
|
+
const q = quarantineEntryFor(p.symbol, log);
|
|
41
|
+
if (q !== null) {
|
|
42
|
+
throw new PerpError("RISK_VIOLATION", `${p.symbol} is quarantined by ${q.strategy}: ${q.reason}`, {
|
|
43
|
+
exchange: adapter.name,
|
|
44
|
+
remediation: `${q.remediation} — only reduce-only orders are accepted until a human clears it (perp strategy quarantine-clear ${p.symbol})`,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
await enforceOrderRisk(adapter, {
|
|
49
|
+
symbol: p.symbol,
|
|
50
|
+
size: p.size,
|
|
51
|
+
...(p.price !== null ? { price: p.price } : {}),
|
|
52
|
+
reduceOnly: p.reduceOnly,
|
|
53
|
+
force: false,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
/** Execution-log entry for an MCP order (source + network recorded in meta). */
|
|
57
|
+
export function logMcpExecution(network, record) {
|
|
58
|
+
return logExecution({ ...record, dryRun: false, meta: { ...(record.meta ?? {}), source: "mcp", network } });
|
|
59
|
+
}
|
|
@@ -1,21 +1,47 @@
|
|
|
1
1
|
import { type Network } from "./constants.js";
|
|
2
2
|
import type { MarketInfo, PriceInfo, Orderbook, Trade, Kline, KlineInterval, AggLevel, AccountInfo, AccountSettings, Position, OrderInfo, MarketOrderParams, LimitOrderParams, StopOrderParams, EditOrderParams, CancelOrderParams, CancelAllOrdersParams, TWAPParams, CancelTWAPParams, TPSLParams, UpdateLeverageParams, WithdrawParams, TransferFundsParams, BatchAction, CreateLakeParams, LakeDepositParams, LakeWithdrawParams } from "./types/index.js";
|
|
3
3
|
type SignMessageFn = (message: Uint8Array) => Promise<Uint8Array>;
|
|
4
|
+
/** Per-request timeout of a POST (fetch + body read). */
|
|
5
|
+
export declare const PACIFICA_POST_TIMEOUT_MS = 15000;
|
|
4
6
|
export interface PacificaClientConfig {
|
|
5
7
|
network?: Network;
|
|
6
8
|
baseUrl?: string;
|
|
7
9
|
apiKey?: string;
|
|
8
|
-
builderCode?: string;
|
|
9
10
|
}
|
|
10
11
|
export declare class PacificaClient {
|
|
11
12
|
private baseUrl;
|
|
12
13
|
private apiKey?;
|
|
13
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Agent-wallet pubkey for the current request signer, set by the adapter when an
|
|
16
|
+
* agent wallet (not the master) is signing. When present, signed bodies carry the
|
|
17
|
+
* `agent_wallet` field (with account = master) so Pacifica verifies the signature
|
|
18
|
+
* against the agent key. Undefined for master/PK signers.
|
|
19
|
+
*/
|
|
20
|
+
private requestAgentWallet?;
|
|
21
|
+
/** Attach (or clear) the agent wallet used for subsequent signed requests. */
|
|
22
|
+
setRequestAgentWallet(agentWallet?: string): void;
|
|
23
|
+
/** Build a signed POST body, attaching agent_wallet when an agent is the active signer. */
|
|
24
|
+
private signedBody;
|
|
14
25
|
constructor(config?: PacificaClientConfig);
|
|
15
26
|
private headers;
|
|
16
27
|
private get;
|
|
28
|
+
/**
|
|
29
|
+
* Signed POST. Every path except the listing reads (READ_POST_PATHS) is an account write: once
|
|
30
|
+
* the request is on the wire a connection reset / timeout / 5xx / unreadable body leaves the
|
|
31
|
+
* outcome unknown → ORDER_PENDING (sendFailure), never a retryable network error. No connection
|
|
32
|
+
* at all → not sent. A 4xx is the venue's refusal and keeps the plain `POST <path> failed
|
|
33
|
+
* (<status>): <body>` error the adapters map (422 business codes) — except on
|
|
34
|
+
* DEFINITE_4XX_PATHS, where it is a definite ACTION_REJECTED (429 stays the plain error →
|
|
35
|
+
* RATE_LIMITED). A fetch timeout (PACIFICA_POST_TIMEOUT_MS) on a write is ORDER_PENDING too;
|
|
36
|
+
* on a listing read a timeout is TIMEOUT and any other transport failure EXCHANGE_UNREACHABLE.
|
|
37
|
+
*/
|
|
17
38
|
private post;
|
|
18
|
-
|
|
39
|
+
/**
|
|
40
|
+
* `builder_code` is attached only when the caller passes one — the adapter decides
|
|
41
|
+
* (settings builder.pacifica + confirmed approval, src/exchanges/builder-fee.ts).
|
|
42
|
+
* null = no builder code (the default, and always for spot: err 108).
|
|
43
|
+
*/
|
|
44
|
+
private withBuilderCode;
|
|
19
45
|
getInfo(): Promise<MarketInfo[]>;
|
|
20
46
|
getPrices(): Promise<PriceInfo[]>;
|
|
21
47
|
getBook(symbol: string, aggLevel?: AggLevel): Promise<Orderbook>;
|
|
@@ -26,7 +52,7 @@ export declare class PacificaClient {
|
|
|
26
52
|
cursor?: string;
|
|
27
53
|
}): Promise<unknown>;
|
|
28
54
|
getAccount(account: string): Promise<AccountInfo>;
|
|
29
|
-
getAccountSettings(account: string): Promise<AccountSettings
|
|
55
|
+
getAccountSettings(account: string): Promise<AccountSettings>;
|
|
30
56
|
getPositions(account: string): Promise<Position[]>;
|
|
31
57
|
getOrders(account: string): Promise<OrderInfo[]>;
|
|
32
58
|
getOrderHistory(account: string, opts?: {
|
|
@@ -56,9 +82,9 @@ export declare class PacificaClient {
|
|
|
56
82
|
}): Promise<unknown>;
|
|
57
83
|
getOrderHistoryById(orderId: number): Promise<unknown>;
|
|
58
84
|
getTWAPOrders(account: string): Promise<unknown[]>;
|
|
59
|
-
createMarketOrder(params: MarketOrderParams, account: string, signMessage: SignMessageFn): Promise<unknown>;
|
|
60
|
-
createLimitOrder(params: LimitOrderParams, account: string, signMessage: SignMessageFn): Promise<unknown>;
|
|
61
|
-
createStopOrder(params: StopOrderParams, account: string, signMessage: SignMessageFn): Promise<unknown>;
|
|
85
|
+
createMarketOrder(params: MarketOrderParams, account: string, signMessage: SignMessageFn, builderCode: string | null): Promise<unknown>;
|
|
86
|
+
createLimitOrder(params: LimitOrderParams, account: string, signMessage: SignMessageFn, builderCode: string | null): Promise<unknown>;
|
|
87
|
+
createStopOrder(params: StopOrderParams, account: string, signMessage: SignMessageFn, builderCode: string | null): Promise<unknown>;
|
|
62
88
|
editOrder(params: EditOrderParams, account: string, signMessage: SignMessageFn): Promise<unknown>;
|
|
63
89
|
cancelOrder(params: CancelOrderParams, account: string, signMessage: SignMessageFn): Promise<unknown>;
|
|
64
90
|
cancelAllOrders(params: CancelAllOrdersParams, account: string, signMessage: SignMessageFn): Promise<unknown>;
|
|
@@ -66,23 +92,28 @@ export declare class PacificaClient {
|
|
|
66
92
|
symbol: string;
|
|
67
93
|
order_id: number;
|
|
68
94
|
}, account: string, signMessage: SignMessageFn): Promise<unknown>;
|
|
95
|
+
/** create_twap_order documents no builder_code, so a TWAP never carries one (builder-fee.ts). */
|
|
69
96
|
createTWAP(params: TWAPParams, account: string, signMessage: SignMessageFn): Promise<unknown>;
|
|
70
97
|
cancelTWAP(params: CancelTWAPParams, account: string, signMessage: SignMessageFn): Promise<unknown>;
|
|
71
|
-
setTPSL(params: TPSLParams, account: string, signMessage: SignMessageFn): Promise<unknown>;
|
|
98
|
+
setTPSL(params: TPSLParams, account: string, signMessage: SignMessageFn, builderCode: string | null): Promise<unknown>;
|
|
72
99
|
updateLeverage(params: UpdateLeverageParams, account: string, signMessage: SignMessageFn): Promise<unknown>;
|
|
73
100
|
updateMarginMode(params: {
|
|
74
101
|
symbol: string;
|
|
75
102
|
is_isolated: boolean;
|
|
76
103
|
}, account: string, signMessage: SignMessageFn): Promise<unknown>;
|
|
77
104
|
withdraw(params: WithdrawParams, account: string, signMessage: SignMessageFn): Promise<unknown>;
|
|
78
|
-
createSubaccount(subaccountName: string, account: string, signMessage: SignMessageFn): Promise<unknown>;
|
|
79
105
|
listSubaccounts(account: string, signMessage: SignMessageFn): Promise<unknown>;
|
|
80
106
|
transferFunds(params: TransferFundsParams, account: string, signMessage: SignMessageFn): Promise<unknown>;
|
|
81
107
|
bindAgentWallet(agentWallet: string, account: string, signMessage: SignMessageFn): Promise<unknown>;
|
|
82
108
|
listAgentWallets(account: string, signMessage: SignMessageFn): Promise<unknown>;
|
|
83
109
|
revokeAgentWallet(agentWallet: string, account: string, signMessage: SignMessageFn): Promise<unknown>;
|
|
84
110
|
revokeAllAgentWallets(account: string, signMessage: SignMessageFn): Promise<unknown>;
|
|
85
|
-
|
|
111
|
+
/**
|
|
112
|
+
* API Config Key (rate-limit key). Docs (api/rate-limits/api-config-keys): the request body is
|
|
113
|
+
* account / signature / timestamp / expiry_window only; python-sdk rest/api_config_keys.py signs
|
|
114
|
+
* type "create_api_key" with `signature_payload = {}`.
|
|
115
|
+
*/
|
|
116
|
+
createApiKey(account: string, signMessage: SignMessageFn): Promise<unknown>;
|
|
86
117
|
listApiKeys(account: string, signMessage: SignMessageFn): Promise<unknown>;
|
|
87
118
|
revokeApiKey(apiKey: string, account: string, signMessage: SignMessageFn): Promise<unknown>;
|
|
88
119
|
createLake(params: CreateLakeParams, account: string, signMessage: SignMessageFn): Promise<unknown>;
|
package/dist/pacifica/client.js
CHANGED
|
@@ -1,14 +1,49 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { buildSignedRequest } from "./signing.js";
|
|
1
|
+
import { getNetworkConfig } from "./constants.js";
|
|
2
|
+
import { buildSignedRequest, buildAgentSignedRequest } from "./signing.js";
|
|
3
|
+
import { PerpError, extractErrorMessage, orderNotSent, orderOutcomeUnknown, sendFailure } from "../errors.js";
|
|
4
|
+
import { invalidateCache } from "../cache.js";
|
|
5
|
+
/** Per-request timeout of a POST (fetch + body read). */
|
|
6
|
+
export const PACIFICA_POST_TIMEOUT_MS = 15_000;
|
|
7
|
+
/**
|
|
8
|
+
* Account-setting writes whose HTTP 4xx is the venue's explicit refusal (nothing changed).
|
|
9
|
+
* docs.pacifica.fi (api-documentation/api/rest-api):
|
|
10
|
+
* account/update-leverage: "Status 400: Invalid request parameters" — {"error": "Invalid leverage", "code": 400}
|
|
11
|
+
* orders/create-position-tp-sl: "Status 400: Bad request" — {"error": "Position not found", "code": 400}
|
|
12
|
+
* Both pages list only "Status 500: Internal server error" besides.
|
|
13
|
+
*/
|
|
14
|
+
const DEFINITE_4XX_PATHS = new Set(["/positions/tpsl", "/account/leverage"]);
|
|
15
|
+
/** POST endpoints that only read (signed listings): a failure there is an ordinary read error. */
|
|
16
|
+
const READ_POST_PATHS = new Set(["/account/subaccount/list", "/agent/list", "/account/api_keys"]);
|
|
3
17
|
export class PacificaClient {
|
|
4
18
|
baseUrl;
|
|
5
19
|
apiKey;
|
|
6
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Agent-wallet pubkey for the current request signer, set by the adapter when an
|
|
22
|
+
* agent wallet (not the master) is signing. When present, signed bodies carry the
|
|
23
|
+
* `agent_wallet` field (with account = master) so Pacifica verifies the signature
|
|
24
|
+
* against the agent key. Undefined for master/PK signers.
|
|
25
|
+
*/
|
|
26
|
+
requestAgentWallet;
|
|
27
|
+
/** Attach (or clear) the agent wallet used for subsequent signed requests. */
|
|
28
|
+
setRequestAgentWallet(agentWallet) {
|
|
29
|
+
this.requestAgentWallet = agentWallet;
|
|
30
|
+
}
|
|
31
|
+
/** Build a signed POST body, attaching agent_wallet when an agent is the active signer. */
|
|
32
|
+
async signedBody(operationType, payload, account, signMessage) {
|
|
33
|
+
try {
|
|
34
|
+
return await (this.requestAgentWallet
|
|
35
|
+
? buildAgentSignedRequest(operationType, payload, account, this.requestAgentWallet, signMessage)
|
|
36
|
+
: buildSignedRequest(operationType, payload, account, signMessage));
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
// Signing failed before any request was sent: definitely not placed (never ORDER_PENDING).
|
|
40
|
+
throw orderNotSent("pacifica", operationType, e);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
7
43
|
constructor(config = {}) {
|
|
8
44
|
this.baseUrl =
|
|
9
45
|
config.baseUrl || getNetworkConfig(config.network).restUrl;
|
|
10
46
|
this.apiKey = config.apiKey;
|
|
11
|
-
this.builderCode = config.builderCode || BUILDER_CODE;
|
|
12
47
|
}
|
|
13
48
|
headers() {
|
|
14
49
|
const h = { "Content-Type": "application/json" };
|
|
@@ -36,23 +71,77 @@ export class PacificaClient {
|
|
|
36
71
|
}
|
|
37
72
|
return json;
|
|
38
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Signed POST. Every path except the listing reads (READ_POST_PATHS) is an account write: once
|
|
76
|
+
* the request is on the wire a connection reset / timeout / 5xx / unreadable body leaves the
|
|
77
|
+
* outcome unknown → ORDER_PENDING (sendFailure), never a retryable network error. No connection
|
|
78
|
+
* at all → not sent. A 4xx is the venue's refusal and keeps the plain `POST <path> failed
|
|
79
|
+
* (<status>): <body>` error the adapters map (422 business codes) — except on
|
|
80
|
+
* DEFINITE_4XX_PATHS, where it is a definite ACTION_REJECTED (429 stays the plain error →
|
|
81
|
+
* RATE_LIMITED). A fetch timeout (PACIFICA_POST_TIMEOUT_MS) on a write is ORDER_PENDING too;
|
|
82
|
+
* on a listing read a timeout is TIMEOUT and any other transport failure EXCHANGE_UNREACHABLE.
|
|
83
|
+
*/
|
|
39
84
|
async post(path, body) {
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
85
|
+
const write = !READ_POST_PATHS.has(path);
|
|
86
|
+
const what = `POST ${path}`;
|
|
87
|
+
const remediation = `Do NOT resubmit — the request may have been executed. Check open orders, positions and balances first: perp -e pacifica account orders / portfolio`;
|
|
88
|
+
try {
|
|
89
|
+
let res;
|
|
90
|
+
let text;
|
|
91
|
+
try {
|
|
92
|
+
res = await fetch(`${this.baseUrl}${path}`, {
|
|
93
|
+
method: "POST",
|
|
94
|
+
headers: this.headers(),
|
|
95
|
+
body: JSON.stringify(body),
|
|
96
|
+
signal: AbortSignal.timeout(PACIFICA_POST_TIMEOUT_MS),
|
|
97
|
+
});
|
|
98
|
+
text = await res.text();
|
|
99
|
+
}
|
|
100
|
+
catch (e) {
|
|
101
|
+
if (write)
|
|
102
|
+
throw sendFailure("pacifica", what, e, remediation);
|
|
103
|
+
// Signed listing read: nothing can have been executed — an ordinary retryable read failure.
|
|
104
|
+
const timedOut = e instanceof Error && (e.name === "TimeoutError" || e.name === "AbortError");
|
|
105
|
+
throw new PerpError(timedOut ? "TIMEOUT" : "EXCHANGE_UNREACHABLE", `Pacifica ${what} ${timedOut ? `timed out after ${PACIFICA_POST_TIMEOUT_MS} ms` : `failed: ${extractErrorMessage(e)}`} (read-only listing; nothing was changed)`, {
|
|
106
|
+
exchange: "pacifica",
|
|
107
|
+
remediation: "Retry; if it keeps failing check the network and Pacifica's status",
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
if (write && res.status >= 500) {
|
|
111
|
+
throw orderOutcomeUnknown("pacifica", what, new Error(`HTTP ${res.status}: ${text.slice(0, 200)}`), remediation);
|
|
112
|
+
}
|
|
113
|
+
if (!res.ok) {
|
|
114
|
+
if (DEFINITE_4XX_PATHS.has(path) && res.status >= 400 && res.status < 500 && res.status !== 429) {
|
|
115
|
+
throw new PerpError("ACTION_REJECTED", `Pacifica ${what} refused (HTTP ${res.status}, nothing was changed): ${text.slice(0, 300)}`, {
|
|
116
|
+
exchange: "pacifica",
|
|
117
|
+
httpStatus: res.status,
|
|
118
|
+
remediation: "The venue rejected the request — fix the parameters named in the message and retry",
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
throw new Error(`POST ${path} failed (${res.status}): ${text}`);
|
|
122
|
+
}
|
|
123
|
+
try {
|
|
124
|
+
return JSON.parse(text);
|
|
125
|
+
}
|
|
126
|
+
catch (e) {
|
|
127
|
+
if (!write)
|
|
128
|
+
throw e;
|
|
129
|
+
throw orderOutcomeUnknown("pacifica", what, new Error(`unreadable response (HTTP ${res.status}): ${text.slice(0, 200)}`), remediation);
|
|
130
|
+
}
|
|
48
131
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return { ...payload, builder_code: this.builderCode };
|
|
132
|
+
finally {
|
|
133
|
+
// Every POST is an account write (order / cancel / TP/SL / leverage / transfer): drop the
|
|
134
|
+
// shared acct: disk cache so no later read serves the pre-write positions / orders.
|
|
135
|
+
invalidateCache("acct");
|
|
54
136
|
}
|
|
55
|
-
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* `builder_code` is attached only when the caller passes one — the adapter decides
|
|
140
|
+
* (settings builder.pacifica + confirmed approval, src/exchanges/builder-fee.ts).
|
|
141
|
+
* null = no builder code (the default, and always for spot: err 108).
|
|
142
|
+
*/
|
|
143
|
+
withBuilderCode(payload, builderCode) {
|
|
144
|
+
return builderCode === null ? payload : { ...payload, builder_code: builderCode };
|
|
56
145
|
}
|
|
57
146
|
// ==================== PUBLIC ENDPOINTS ====================
|
|
58
147
|
async getInfo() {
|
|
@@ -158,135 +247,150 @@ export class PacificaClient {
|
|
|
158
247
|
return this.get("/orders/twap", { account });
|
|
159
248
|
}
|
|
160
249
|
// ==================== AUTHENTICATED POST ENDPOINTS ====================
|
|
161
|
-
async createMarketOrder(params, account, signMessage) {
|
|
162
|
-
const payload = this.
|
|
163
|
-
const body = await
|
|
250
|
+
async createMarketOrder(params, account, signMessage, builderCode) {
|
|
251
|
+
const payload = this.withBuilderCode({ ...params }, builderCode);
|
|
252
|
+
const body = await this.signedBody("create_market_order", payload, account, signMessage);
|
|
164
253
|
return this.post("/orders/create_market", body);
|
|
165
254
|
}
|
|
166
|
-
async createLimitOrder(params, account, signMessage) {
|
|
167
|
-
const payload = this.
|
|
168
|
-
const body = await
|
|
255
|
+
async createLimitOrder(params, account, signMessage, builderCode) {
|
|
256
|
+
const payload = this.withBuilderCode({ ...params }, builderCode);
|
|
257
|
+
const body = await this.signedBody("create_order", payload, account, signMessage);
|
|
169
258
|
return this.post("/orders/create", body);
|
|
170
259
|
}
|
|
171
|
-
async createStopOrder(params, account, signMessage) {
|
|
172
|
-
|
|
260
|
+
async createStopOrder(params, account, signMessage, builderCode) {
|
|
261
|
+
// builder_code applies to every order-creation endpoint, stop orders included (builder-program docs).
|
|
262
|
+
const payload = this.withBuilderCode({ ...params }, builderCode);
|
|
263
|
+
const body = await this.signedBody("create_stop_order", payload, account, signMessage);
|
|
173
264
|
return this.post("/orders/stop/create", body);
|
|
174
265
|
}
|
|
175
266
|
async editOrder(params, account, signMessage) {
|
|
176
|
-
const body = await
|
|
267
|
+
const body = await this.signedBody("edit_order", params, account, signMessage);
|
|
177
268
|
return this.post("/orders/edit", body);
|
|
178
269
|
}
|
|
179
270
|
async cancelOrder(params, account, signMessage) {
|
|
180
|
-
const body = await
|
|
271
|
+
const body = await this.signedBody("cancel_order", params, account, signMessage);
|
|
181
272
|
return this.post("/orders/cancel", body);
|
|
182
273
|
}
|
|
183
274
|
async cancelAllOrders(params, account, signMessage) {
|
|
184
|
-
const body = await
|
|
275
|
+
const body = await this.signedBody("cancel_all_orders", params, account, signMessage);
|
|
185
276
|
return this.post("/orders/cancel_all", body);
|
|
186
277
|
}
|
|
187
278
|
async cancelStopOrder(params, account, signMessage) {
|
|
188
|
-
const body = await
|
|
279
|
+
const body = await this.signedBody("cancel_stop_order", params, account, signMessage);
|
|
189
280
|
return this.post("/orders/stop/cancel", body);
|
|
190
281
|
}
|
|
282
|
+
/** create_twap_order documents no builder_code, so a TWAP never carries one (builder-fee.ts). */
|
|
191
283
|
async createTWAP(params, account, signMessage) {
|
|
192
|
-
const
|
|
193
|
-
const body = await buildSignedRequest("create_twap_order", payload, account, signMessage);
|
|
284
|
+
const body = await this.signedBody("create_twap_order", { ...params }, account, signMessage);
|
|
194
285
|
return this.post("/orders/twap/create", body);
|
|
195
286
|
}
|
|
196
287
|
async cancelTWAP(params, account, signMessage) {
|
|
197
|
-
const body = await
|
|
288
|
+
const body = await this.signedBody("cancel_twap_order", params, account, signMessage);
|
|
198
289
|
return this.post("/orders/twap/cancel", body);
|
|
199
290
|
}
|
|
200
|
-
async setTPSL(params, account, signMessage) {
|
|
201
|
-
|
|
291
|
+
async setTPSL(params, account, signMessage, builderCode) {
|
|
292
|
+
// Position TP/SL creates orders and therefore takes builder_code too (POST /positions/tpsl).
|
|
293
|
+
const payload = this.withBuilderCode({ ...params }, builderCode);
|
|
294
|
+
const body = await this.signedBody("set_position_tpsl", payload, account, signMessage);
|
|
202
295
|
return this.post("/positions/tpsl", body);
|
|
203
296
|
}
|
|
204
297
|
async updateLeverage(params, account, signMessage) {
|
|
205
|
-
const body = await
|
|
298
|
+
const body = await this.signedBody("update_leverage", params, account, signMessage);
|
|
206
299
|
return this.post("/account/leverage", body);
|
|
207
300
|
}
|
|
208
301
|
async updateMarginMode(params, account, signMessage) {
|
|
209
|
-
const body = await
|
|
302
|
+
const body = await this.signedBody("update_margin_mode", params, account, signMessage);
|
|
210
303
|
return this.post("/account/margin", body);
|
|
211
304
|
}
|
|
212
305
|
async withdraw(params, account, signMessage) {
|
|
213
|
-
const body = await
|
|
306
|
+
const body = await this.signedBody("withdraw", params, account, signMessage);
|
|
214
307
|
return this.post("/account/withdraw", body);
|
|
215
308
|
}
|
|
216
309
|
// ==================== SUBACCOUNT ====================
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
return this.post("/account/subaccount/create", confirmBody);
|
|
224
|
-
}
|
|
310
|
+
// POST /account/subaccount/create is not implemented. Docs (rest-api/subaccounts/create-subaccount):
|
|
311
|
+
// "Both the main account and subaccount must sign to establish the relationship." — the body is
|
|
312
|
+
// {main_account, subaccount, main_signature, sub_signature, timestamp, expiry_window}; the
|
|
313
|
+
// subaccount keypair signs {account: <main>} ("subaccount_initiate") and the main account signs
|
|
314
|
+
// {signature: <sub_signature>} ("subaccount_confirm") (python-sdk rest/create_subaccount.py).
|
|
315
|
+
// perp-cli has no second (subaccount) keypair source, so `manage sub create` is gated.
|
|
225
316
|
async listSubaccounts(account, signMessage) {
|
|
226
|
-
const body = await
|
|
317
|
+
const body = await this.signedBody("list_subaccounts", {}, account, signMessage);
|
|
227
318
|
return this.post("/account/subaccount/list", body);
|
|
228
319
|
}
|
|
229
320
|
async transferFunds(params, account, signMessage) {
|
|
230
|
-
const body = await
|
|
321
|
+
const body = await this.signedBody("transfer_funds", params, account, signMessage);
|
|
231
322
|
return this.post("/account/subaccount/transfer", body);
|
|
232
323
|
}
|
|
233
324
|
// ==================== AGENT WALLET ====================
|
|
234
325
|
async bindAgentWallet(agentWallet, account, signMessage) {
|
|
235
|
-
const body = await
|
|
326
|
+
const body = await this.signedBody("bind_agent_wallet", { agent_wallet: agentWallet }, account, signMessage);
|
|
236
327
|
return this.post("/agent/bind", body);
|
|
237
328
|
}
|
|
238
329
|
async listAgentWallets(account, signMessage) {
|
|
239
|
-
const body = await
|
|
330
|
+
const body = await this.signedBody("list_agent_wallets", {}, account, signMessage);
|
|
240
331
|
return this.post("/agent/list", body);
|
|
241
332
|
}
|
|
242
333
|
async revokeAgentWallet(agentWallet, account, signMessage) {
|
|
243
|
-
const body = await
|
|
334
|
+
const body = await this.signedBody("revoke_agent_wallet", { agent_wallet: agentWallet }, account, signMessage);
|
|
244
335
|
return this.post("/agent/revoke", body);
|
|
245
336
|
}
|
|
246
337
|
async revokeAllAgentWallets(account, signMessage) {
|
|
247
|
-
const body = await
|
|
338
|
+
const body = await this.signedBody("revoke_all_agent_wallets", {}, account, signMessage);
|
|
248
339
|
return this.post("/agent/revoke_all", body);
|
|
249
340
|
}
|
|
250
341
|
// ==================== API KEYS ====================
|
|
251
|
-
|
|
252
|
-
|
|
342
|
+
/**
|
|
343
|
+
* API Config Key (rate-limit key). Docs (api/rate-limits/api-config-keys): the request body is
|
|
344
|
+
* account / signature / timestamp / expiry_window only; python-sdk rest/api_config_keys.py signs
|
|
345
|
+
* type "create_api_key" with `signature_payload = {}`.
|
|
346
|
+
*/
|
|
347
|
+
async createApiKey(account, signMessage) {
|
|
348
|
+
const body = await this.signedBody("create_api_key", {}, account, signMessage);
|
|
253
349
|
return this.post("/account/api_keys/create", body);
|
|
254
350
|
}
|
|
255
351
|
async listApiKeys(account, signMessage) {
|
|
256
|
-
const body = await
|
|
352
|
+
const body = await this.signedBody("list_api_keys", {}, account, signMessage);
|
|
257
353
|
return this.post("/account/api_keys", body);
|
|
258
354
|
}
|
|
259
355
|
async revokeApiKey(apiKey, account, signMessage) {
|
|
260
|
-
const body = await
|
|
356
|
+
const body = await this.signedBody("revoke_api_key", { api_key: apiKey }, account, signMessage);
|
|
261
357
|
return this.post("/account/api_keys/revoke", body);
|
|
262
358
|
}
|
|
263
359
|
// ==================== LAKE ====================
|
|
264
360
|
async createLake(params, account, signMessage) {
|
|
265
|
-
|
|
361
|
+
// Optional fields are omitted, not sent as null (the signed payload must equal the body).
|
|
362
|
+
const payload = {};
|
|
363
|
+
if (params.manager !== null)
|
|
364
|
+
payload.manager = params.manager;
|
|
365
|
+
if (params.nickname !== null)
|
|
366
|
+
payload.nickname = params.nickname;
|
|
367
|
+
if (params.initial_deposit !== null)
|
|
368
|
+
payload.initial_deposit = params.initial_deposit;
|
|
369
|
+
const body = await this.signedBody("create_lake", payload, account, signMessage);
|
|
266
370
|
return this.post("/lake/create", body);
|
|
267
371
|
}
|
|
268
372
|
async depositToLake(params, account, signMessage) {
|
|
269
|
-
const body = await
|
|
373
|
+
const body = await this.signedBody("deposit_to_lake", params, account, signMessage);
|
|
270
374
|
return this.post("/lake/deposit", body);
|
|
271
375
|
}
|
|
272
376
|
async withdrawFromLake(params, account, signMessage) {
|
|
273
|
-
const body = await
|
|
377
|
+
const body = await this.signedBody("withdraw_from_lake", params, account, signMessage);
|
|
274
378
|
return this.post("/lake/withdraw", body);
|
|
275
379
|
}
|
|
276
380
|
// ==================== BUILDER CODE ====================
|
|
277
381
|
async approveBuilderCode(params, account, signMessage) {
|
|
278
|
-
const body = await
|
|
382
|
+
const body = await this.signedBody("approve_builder_code", params, account, signMessage);
|
|
279
383
|
return this.post("/account/builder_codes/approve", body);
|
|
280
384
|
}
|
|
281
385
|
async revokeBuilderCode(params, account, signMessage) {
|
|
282
|
-
const body = await
|
|
386
|
+
const body = await this.signedBody("revoke_builder_code", params, account, signMessage);
|
|
283
387
|
return this.post("/account/builder_codes/revoke", body);
|
|
284
388
|
}
|
|
285
389
|
async getBuilderApprovals(account) {
|
|
286
390
|
return this.get("/account/builder_codes/approvals", { account });
|
|
287
391
|
}
|
|
288
392
|
async updateBuilderFeeRate(params, account, signMessage) {
|
|
289
|
-
const body = await
|
|
393
|
+
const body = await this.signedBody("update_builder_code_fee_rate", params, account, signMessage);
|
|
290
394
|
return this.post("/builder/update_fee_rate", body);
|
|
291
395
|
}
|
|
292
396
|
async getBuilderOverview(account) {
|
|
@@ -300,7 +404,7 @@ export class PacificaClient {
|
|
|
300
404
|
}
|
|
301
405
|
// ==================== REFERRAL ====================
|
|
302
406
|
async claimReferralCode(params, account, signMessage) {
|
|
303
|
-
const body = await
|
|
407
|
+
const body = await this.signedBody("claim_referral_code", params, account, signMessage);
|
|
304
408
|
return this.post("/referral/user/code/claim", body);
|
|
305
409
|
}
|
|
306
410
|
// ==================== BATCH ====================
|
|
@@ -12,7 +12,6 @@ export declare const TESTNET_PACIFICA_VAULT = "5SDFdHZGTZbyRYu54CgmRkCGnPHC5pYaN
|
|
|
12
12
|
export declare const TESTNET_USDC_MINT = "USDPqRbLidFGufty2s3oizmDEKdqx7ePTqzDMbf5ZKM";
|
|
13
13
|
export declare const DEFAULT_EXPIRY_WINDOW = 5000;
|
|
14
14
|
export declare const USDC_DECIMALS = 6;
|
|
15
|
-
export declare const BUILDER_CODE = "PERPCLI";
|
|
16
15
|
export type Network = "mainnet" | "testnet";
|
|
17
16
|
export declare function getNetworkConfig(network?: Network): {
|
|
18
17
|
restUrl: string;
|
|
@@ -19,11 +19,6 @@ export const TESTNET_USDC_MINT = "USDPqRbLidFGufty2s3oizmDEKdqx7ePTqzDMbf5ZKM";
|
|
|
19
19
|
export const DEFAULT_EXPIRY_WINDOW = 5000; // 5 seconds
|
|
20
20
|
// USDC decimals
|
|
21
21
|
export const USDC_DECIMALS = 6;
|
|
22
|
-
// Builder code — 0% fee, used for Pacifica hackathon tracking
|
|
23
|
-
// The actual 3-way fallback (env → settings.referralCodes.pacifica → "PERPCLI") is
|
|
24
|
-
// resolved in index.ts before constructing PacificaAdapter. This constant is only
|
|
25
|
-
// a last-resort default for direct PacificaClient usage without a builderCode arg.
|
|
26
|
-
export const BUILDER_CODE = "PERPCLI";
|
|
27
22
|
export function getNetworkConfig(network = "mainnet") {
|
|
28
23
|
if (network === "testnet") {
|
|
29
24
|
return {
|
|
@@ -4,11 +4,38 @@ import { type Network } from "./constants.js";
|
|
|
4
4
|
* Build a Pacifica deposit instruction.
|
|
5
5
|
*
|
|
6
6
|
* @param userPubkey - User's wallet public key
|
|
7
|
-
* @param amount - Amount in USDC (e.g
|
|
7
|
+
* @param amount - Amount in USDC as a plain decimal string with at most 6 decimals (e.g. "100", "99.5");
|
|
8
|
+
* scaled exactly (no float math). Anything else → INVALID_PARAMS.
|
|
8
9
|
* @param network - mainnet or testnet
|
|
9
10
|
*/
|
|
10
|
-
export declare function buildDepositInstruction(userPubkey: PublicKey, amount:
|
|
11
|
+
export declare function buildDepositInstruction(userPubkey: PublicKey, amount: string, network?: Network): Promise<TransactionInstruction>;
|
|
11
12
|
/**
|
|
12
13
|
* Build and send a deposit transaction.
|
|
13
14
|
*/
|
|
14
|
-
export declare function deposit(connection: Connection, userPubkey: PublicKey, amount:
|
|
15
|
+
export declare function deposit(connection: Connection, userPubkey: PublicKey, amount: string, signTransaction: (tx: Transaction) => Promise<Transaction>, network?: Network): Promise<TransactionSignature>;
|
|
16
|
+
/** Highest relayer fee (USDC) the CLI signs for a relayed deposit. Above it the transaction is refused. */
|
|
17
|
+
export declare const PACIFICA_RELAY_FEE_CAP_USDC = 1;
|
|
18
|
+
/**
|
|
19
|
+
* Verify a RELAYER-BUILT transaction before the master Solana key signs it. The relayer is an
|
|
20
|
+
* untrusted HTTP service (PERP_RELAYER_URL): whatever it returns is signed only when it is
|
|
21
|
+
* exactly
|
|
22
|
+
* - ONE pinned Pacifica deposit instruction — the program id, every account (user, user USDC
|
|
23
|
+
* ATA, central state, vault, mint, …, in order, same signer / writable flags) and the data
|
|
24
|
+
* `buildDepositInstruction` would produce for `declared.netAmount`;
|
|
25
|
+
* - any number of ComputeBudget instructions (they move no funds);
|
|
26
|
+
* - at most ONE relayer fee transfer: an SPL Token Transfer / TransferChecked of exactly
|
|
27
|
+
* `declared.fee` USDC from the user's USDC account, authority = user, to the token account the
|
|
28
|
+
* build response declared (`feeRecipient`), with fee ≤ PACIFICA_RELAY_FEE_CAP_USDC;
|
|
29
|
+
* and fee + netAmount equals the amount the user asked to deposit, and the fee payer is not the
|
|
30
|
+
* user (the relayer sponsors gas). Anything else → POLICY_DENIED, nothing is signed.
|
|
31
|
+
*/
|
|
32
|
+
export declare function assertRelayedDepositTransaction(tx: Transaction, ctx: {
|
|
33
|
+
user: PublicKey;
|
|
34
|
+
requestedAmount: string;
|
|
35
|
+
network: Network;
|
|
36
|
+
declared: {
|
|
37
|
+
fee: number;
|
|
38
|
+
netAmount: number;
|
|
39
|
+
feeRecipient: string | null;
|
|
40
|
+
};
|
|
41
|
+
}): Promise<void>;
|