perp-cli 0.14.2 → 0.15.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 +152 -13
- 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/pacifica.js +83 -13
- package/dist/api/public/urls.d.ts +2 -0
- package/dist/api/public/urls.js +3 -0
- package/dist/arb/utils.d.ts +1 -2
- package/dist/arb/utils.js +1 -2
- 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/strategies/apex-strategy.js +3 -2
- package/dist/bot/strategies/engine-mm.js +6 -5
- package/dist/bot/strategies/funding-arb-strategy.js +9 -9
- package/dist/bot/strategies/funding-arb-utils.d.ts +15 -2
- package/dist/bot/strategies/funding-arb-utils.js +43 -24
- 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.js +23 -12
- package/dist/bot/strategies/spot-perp-executor.d.ts +1 -1
- package/dist/bot/strategies/spot-perp-executor.js +1 -1
- 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 +125 -5
- 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 +4 -4
- package/dist/commands/arb-auto.js +21 -17
- package/dist/commands/arb.d.ts +12 -0
- package/dist/commands/arb.js +61 -143
- 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.js +168 -36
- package/dist/commands/options.d.ts +9 -0
- package/dist/commands/options.js +134 -0
- package/dist/commands/pacifica-earn.d.ts +5 -0
- package/dist/commands/pacifica-earn.js +468 -0
- package/dist/commands/pacifica-orders.d.ts +14 -0
- package/dist/commands/pacifica-orders.js +142 -0
- package/dist/commands/portfolio.js +32 -47
- 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 +63 -58
- 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/dashboard/server.js +1 -1
- package/dist/dashboard/ui.js +1 -1
- package/dist/errors.d.ts +24 -1
- package/dist/errors.js +25 -3
- package/dist/exchanges/arcus/adapter.d.ts +7 -7
- package/dist/exchanges/arcus/adapter.js +12 -12
- 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/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 +9 -4
- package/dist/exchanges/aster.js +125 -55
- package/dist/exchanges/builder-fee.d.ts +1 -1
- package/dist/exchanges/builder-fee.js +13 -2
- package/dist/exchanges/canonical-symbols.d.ts +1 -2
- package/dist/exchanges/canonical-symbols.js +26 -2
- package/dist/exchanges/derive/client.d.ts +37 -0
- package/dist/exchanges/derive/client.js +135 -0
- package/dist/exchanges/derive/options.d.ts +68 -0
- package/dist/exchanges/derive/options.js +360 -0
- package/dist/exchanges/extended/adapter.d.ts +82 -0
- package/dist/exchanges/extended/adapter.js +179 -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 +130 -0
- package/dist/exchanges/extended/public.js +429 -0
- package/dist/exchanges/grvt/adapter.d.ts +86 -0
- package/dist/exchanges/grvt/adapter.js +206 -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-spot.d.ts +1 -1
- package/dist/exchanges/hyperliquid-spot.js +5 -5
- package/dist/exchanges/hyperliquid.d.ts +22 -16
- package/dist/exchanges/hyperliquid.js +80 -55
- package/dist/exchanges/index.d.ts +1 -1
- package/dist/exchanges/index.js +1 -1
- package/dist/exchanges/interface.d.ts +97 -8
- package/dist/exchanges/interface.js +19 -2
- 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 +2 -2
- package/dist/exchanges/lighter-public.js +2 -2
- package/dist/exchanges/lighter-signer.d.ts +1 -1
- package/dist/exchanges/lighter-signer.js +1 -1
- package/dist/exchanges/lighter-spot.d.ts +3 -4
- package/dist/exchanges/lighter-spot.js +6 -7
- package/dist/exchanges/lighter.d.ts +11 -11
- package/dist/exchanges/lighter.js +28 -14
- package/dist/exchanges/ondo/adapter.d.ts +5 -6
- package/dist/exchanges/ondo/adapter.js +16 -14
- 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 +8 -1
- package/dist/exchanges/ondo/public.js +13 -2
- 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/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 +2 -2
- package/dist/exchanges/pacifica-spot.js +3 -3
- 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 +121 -0
- package/dist/exchanges/pacifica-vaults.js +264 -0
- package/dist/exchanges/pacifica.d.ts +32 -5
- package/dist/exchanges/pacifica.js +114 -48
- package/dist/exchanges/precision.d.ts +3 -1
- package/dist/exchanges/precision.js +9 -2
- package/dist/exchanges/qfex/adapter.d.ts +18 -5
- package/dist/exchanges/qfex/adapter.js +32 -12
- 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 +3 -3
- package/dist/exchanges/qfex/public.js +3 -3
- 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 +2 -2
- 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 +148 -0
- package/dist/exchanges/risex/adapter.js +796 -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 +7 -7
- 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 +54 -0
- package/dist/exchanges/txflow/adapter.js +118 -0
- package/dist/exchanges/txflow/client.d.ts +47 -0
- package/dist/exchanges/txflow/client.js +153 -0
- package/dist/exchanges/txflow/public.d.ts +76 -0
- package/dist/exchanges/txflow/public.js +284 -0
- package/dist/exchanges/unknown-symbol.d.ts +29 -0
- package/dist/exchanges/unknown-symbol.js +51 -0
- package/dist/exchanges/variational/adapter.d.ts +71 -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 +6 -7
- package/dist/exchanges/venue-types.js +2 -2
- package/dist/exchanges/venue.d.ts +51 -8
- package/dist/exchanges/venue.js +54 -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 +10 -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 +7 -5
- package/dist/exchanges/venues/lighter.d.ts +1 -1
- package/dist/exchanges/venues/lighter.js +5 -3
- 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 +6 -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 +116 -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 +1 -1
- package/dist/funding/legacy-public.js +9 -4
- package/dist/funding/normalize.d.ts +1 -1
- package/dist/funding/normalize.js +1 -1
- package/dist/funding/rates.d.ts +44 -4
- package/dist/funding/rates.js +56 -12
- 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/mcp-pacifica-earn.d.ts +9 -0
- package/dist/mcp-pacifica-earn.js +58 -0
- package/dist/mcp-server.js +113 -59
- package/dist/pacifica/client.d.ts +67 -4
- package/dist/pacifica/client.js +170 -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/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 +1 -1
- package/dist/trade-validator.d.ts +1 -1
- package/dist/trade-validator.js +9 -4
- package/dist/utils.d.ts +12 -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/index.d.ts +959 -0
- package/dist/ws/index.js +4295 -0
- package/dist/ws/node.d.ts +975 -0
- package/dist/ws/node.js +4366 -0
- package/dist/ws/pacifica-instrument.d.ts +8 -0
- package/dist/ws/pacifica-instrument.js +8 -0
- package/dist/ws-cli/credentials.d.ts +62 -0
- package/dist/ws-cli/credentials.js +126 -0
- package/package.json +58 -10
- package/skills/perp-cli/SKILL.md +62 -9
- package/skills/perp-cli/references/agent-operations.md +7 -0
- package/skills/perp-cli/references/commands.md +76 -5
- package/skills/perp-cli/references/ws-library.md +492 -0
package/dist/exchanges/venue.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Venue definitions — the single source of truth for "which venue, on which
|
|
3
3
|
* network, signed how, funded how, supporting what".
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* One adapter class may serve several
|
|
6
6
|
* venues (LighterAdapter serves `lighter` and `lighter-rh`).
|
|
7
7
|
*
|
|
8
8
|
* Venue definition modules must load adapter code lazily (`import()` inside
|
|
@@ -10,9 +10,21 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { PerpError } from "../errors.js";
|
|
12
12
|
import { isVenueId } from "./venue-types.js";
|
|
13
|
+
import { optionsVenueWords } from "./options-venues.js";
|
|
13
14
|
export const READ_ONLY_CREDENTIALS = {
|
|
14
15
|
pk: null, owsWallet: null, owsPassphrase: null, owsKeyToken: null, agent: null,
|
|
15
16
|
};
|
|
17
|
+
export const OFFICIAL_API = { kind: "official" };
|
|
18
|
+
/** "official" | "unofficial" — the per-row label for mixed-venue tables and JSON. */
|
|
19
|
+
export function apiStatusOf(venue) {
|
|
20
|
+
return getVenue(venue).apiStatus.kind;
|
|
21
|
+
}
|
|
22
|
+
/** Human footnote for an unofficial-API venue; null for an official one. */
|
|
23
|
+
export function unofficialApiNote(def) {
|
|
24
|
+
return def.apiStatus.kind === "unofficial"
|
|
25
|
+
? `${def.displayName}: UNOFFICIAL API — ${def.apiStatus.note}`
|
|
26
|
+
: null;
|
|
27
|
+
}
|
|
16
28
|
// ── Registry ──
|
|
17
29
|
const _venues = new Map();
|
|
18
30
|
const _aliases = new Map();
|
|
@@ -29,8 +41,12 @@ export function registerVenue(def) {
|
|
|
29
41
|
}
|
|
30
42
|
}
|
|
31
43
|
function unknownVenue(input) {
|
|
44
|
+
// An options venue (e.g. derive) is not a perp venue: say where it works instead.
|
|
45
|
+
const optionsOnly = optionsVenueWords().includes(input.toLowerCase())
|
|
46
|
+
? ` — ${input} is options-only: perp -e ${input} options …`
|
|
47
|
+
: "";
|
|
32
48
|
return new PerpError("UNKNOWN_VENUE", `Unknown venue: "${input}"`, {
|
|
33
|
-
remediation: `Use one of: ${[..._venues.keys()].join(", ")}`,
|
|
49
|
+
remediation: `Use one of: ${[..._venues.keys()].join(", ")}${optionsOnly}`,
|
|
34
50
|
});
|
|
35
51
|
}
|
|
36
52
|
/** Resolve a venue id or alias. Throws UNKNOWN_VENUE. */
|
|
@@ -65,7 +81,41 @@ export function networkConfig(def, net) {
|
|
|
65
81
|
}
|
|
66
82
|
return cfg;
|
|
67
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* The uniform refusal for any account / trading / funds / agent / builder / bot action on a venue
|
|
86
|
+
* whose roles do not include `role` (a market-data-only venue such as TxFlow). Raised before any
|
|
87
|
+
* credential is resolved or any request is sent.
|
|
88
|
+
*/
|
|
89
|
+
export function roleUnsupported(def, feature, role = "trading") {
|
|
90
|
+
if (def.gatedRoles !== null && def.gatedRoles.roles.includes(role)) {
|
|
91
|
+
const { reason, remediation } = def.gatedRoles;
|
|
92
|
+
return new PerpError("CAPABILITY_UNSUPPORTED", `${def.id} does not support ${feature} — ${reason}`, {
|
|
93
|
+
venue: def.id, feature, reason, remediation,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
const reason = def.apiStatus.kind === "unofficial"
|
|
97
|
+
? `${def.displayName} is integrated through an unofficial read-only API (market data only)`
|
|
98
|
+
: `${def.displayName} is available for market data only (no ${role} role)`;
|
|
99
|
+
// Precedence: gatedRoles (above: a role switched off this release, e.g. RISEx) → the venue's own
|
|
100
|
+
// readOnlyRemediation (official read-only venues, e.g. Variational) → the generic text (TxFlow).
|
|
101
|
+
const remediation = def.readOnlyRemediation !== undefined
|
|
102
|
+
? def.readOnlyRemediation
|
|
103
|
+
: def.apiStatus.kind === "unofficial"
|
|
104
|
+
? `Trade on the ${def.displayName} website; perp-cli shows ${def.displayName} market data only (perp -e ${def.id} market list|info|funding|book|trades|kline)`
|
|
105
|
+
: `Use the market-data commands for ${def.id} (perp -e ${def.id} market list|funding)`;
|
|
106
|
+
return new PerpError("CAPABILITY_UNSUPPORTED", `${def.id} does not support ${feature} — ${reason}`, {
|
|
107
|
+
venue: def.id, feature, reason, remediation,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
/** Throws roleUnsupported() unless the venue has `role`. */
|
|
111
|
+
export function requireRole(def, role, feature) {
|
|
112
|
+
if (!def.roles.includes(role))
|
|
113
|
+
throw roleUnsupported(def, feature, role);
|
|
114
|
+
}
|
|
68
115
|
export function requireCapabilities(def) {
|
|
116
|
+
// A venue without the trading role is a definite capability refusal, not "not implemented yet".
|
|
117
|
+
if (!def.roles.includes("trading"))
|
|
118
|
+
throw roleUnsupported(def, "trading");
|
|
69
119
|
if (!def.capabilities) {
|
|
70
120
|
throw new PerpError("NOT_IMPLEMENTED", `${def.displayName} does not support trading via API`, {
|
|
71
121
|
remediation: `${def.id} is available for market data only (funding/market commands)`,
|
|
@@ -88,7 +138,7 @@ export function parseVenueRef(ref) {
|
|
|
88
138
|
}
|
|
89
139
|
/**
|
|
90
140
|
* Funding basis for a venue ref. HIP-3 dexes use the Hyperliquid core basis
|
|
91
|
-
* (current behavior preserved;
|
|
141
|
+
* (current behavior preserved; verify against live data).
|
|
92
142
|
* Throws for venues whose basis is per-market; callers must use the market's value.
|
|
93
143
|
*/
|
|
94
144
|
export function fundingBasisOf(ref) {
|
|
@@ -114,7 +164,7 @@ export function settlementIntervalOf(ref) {
|
|
|
114
164
|
/**
|
|
115
165
|
* Refuse a venue whose funding rate is unverified (VenueDefinition.fundingVerified false) as a
|
|
116
166
|
* leg of a funding strategy (arb scan ranking, arb exec / auto, funding bots). Uniform
|
|
117
|
-
* CAPABILITY_UNSUPPORTED
|
|
167
|
+
* CAPABILITY_UNSUPPORTED. Unknown venue refs throw UNKNOWN_VENUE.
|
|
118
168
|
*/
|
|
119
169
|
export function assertFundingArbVenue(ref) {
|
|
120
170
|
const def = getVenue(parseVenueRef(ref).venue);
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Arcus — perps on the Robinhood chain rootchain, USDG collateral
|
|
3
|
-
* (design §4 Arcus column, §10.4, §10.10).
|
|
4
3
|
* Not registered here; the registry module owns registerVenue().
|
|
5
|
-
* Adapter and public-data code are loaded lazily
|
|
4
|
+
* Adapter and public-data code are loaded lazily.
|
|
6
5
|
*/
|
|
7
6
|
import type { VenueDefinition } from "../venue.js";
|
|
8
7
|
export declare const arcusVenue: VenueDefinition;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Arcus — perps on the Robinhood chain rootchain, USDG collateral
|
|
3
|
-
* (design §4 Arcus column, §10.4, §10.10).
|
|
4
3
|
* Not registered here; the registry module owns registerVenue().
|
|
5
|
-
* Adapter and public-data code are loaded lazily
|
|
4
|
+
* Adapter and public-data code are loaded lazily.
|
|
6
5
|
*/
|
|
7
6
|
import { BUILDER_FEE_CAPABILITIES } from "../builder-fee.js";
|
|
8
7
|
const publicData = {
|
|
@@ -50,6 +49,7 @@ export const arcusVenue = {
|
|
|
50
49
|
settlementIntervalHours: 1,
|
|
51
50
|
fundingVerified: true,
|
|
52
51
|
roles: ["marketData", "account", "trading"],
|
|
52
|
+
gatedRoles: null,
|
|
53
53
|
capabilities: {
|
|
54
54
|
marketOrder: "slippageBounded",
|
|
55
55
|
// GTC = GTT at goodTil now + 40 days (ARCUS_GOOD_TIL_HORIZON_MS); GTT kept as the venue alias.
|
|
@@ -83,7 +83,7 @@ export const arcusVenue = {
|
|
|
83
83
|
restrictedRegions: ["US", "CA", "GB"],
|
|
84
84
|
symbolIdentity: "baseTicker",
|
|
85
85
|
publicData,
|
|
86
|
-
//
|
|
86
|
+
// market swaps via router.spot.arcus.xyz, settled on-chain from the master EVM wallet.
|
|
87
87
|
spot: {
|
|
88
88
|
accountModel: "wallet",
|
|
89
89
|
quoteAssets: { mainnet: ["USDG"], testnet: ["USDG"] },
|
|
@@ -99,9 +99,10 @@ export const arcusVenue = {
|
|
|
99
99
|
return spot;
|
|
100
100
|
},
|
|
101
101
|
},
|
|
102
|
-
// Arcus venue limit
|
|
102
|
+
// Arcus venue slippage limit.
|
|
103
103
|
maxSlippageBps: 1000,
|
|
104
104
|
builderFee: BUILDER_FEE_CAPABILITIES["arcus"],
|
|
105
|
+
apiStatus: { kind: "official" },
|
|
105
106
|
async create(ctx) {
|
|
106
107
|
const { ArcusAdapter } = await import("../arcus/adapter.js");
|
|
107
108
|
return new ArcusAdapter(arcusVenue, ctx);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Aster venue definition
|
|
3
|
-
* Adapter + public-data code are loaded lazily
|
|
2
|
+
* Aster venue definition.
|
|
3
|
+
* Adapter + public-data code are loaded lazily.
|
|
4
4
|
*/
|
|
5
5
|
import type { VenueDefinition } from "../venue.js";
|
|
6
6
|
/** Aster client order id (V3 futures "New Order" `newClientOrderId` rule). */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Aster venue definition
|
|
3
|
-
* Adapter + public-data code are loaded lazily
|
|
2
|
+
* Aster venue definition.
|
|
3
|
+
* Adapter + public-data code are loaded lazily.
|
|
4
4
|
*/
|
|
5
5
|
import { BUILDER_FEE_CAPABILITIES } from "../builder-fee.js";
|
|
6
6
|
/** Aster client order id (V3 futures "New Order" `newClientOrderId` rule). */
|
|
@@ -122,6 +122,7 @@ export const asterVenue = {
|
|
|
122
122
|
settlementIntervalHours: "perMarket",
|
|
123
123
|
fundingVerified: true,
|
|
124
124
|
roles: ["marketData", "account", "trading"],
|
|
125
|
+
gatedRoles: null,
|
|
125
126
|
capabilities: {
|
|
126
127
|
// Market = IOC LIMIT at mark ± slippage (adapter marketOrder), never native MARKET.
|
|
127
128
|
marketOrder: "slippageBounded",
|
|
@@ -146,12 +147,12 @@ export const asterVenue = {
|
|
|
146
147
|
},
|
|
147
148
|
// GET /fapi/v1/exchangeInfo rateLimits: REQUEST_WEIGHT 2400/min
|
|
148
149
|
// (ORDERS 1200/min and 300/10s are separate order-count limits, not modeled).
|
|
149
|
-
// Declared only — per
|
|
150
|
+
// Declared only — per the limiter is applied to new venues + lighter-rh.
|
|
150
151
|
rateLimit: { capacity: 2400, refillPerSec: 40, weights: null },
|
|
151
152
|
restrictedRegions: [],
|
|
152
153
|
symbolIdentity: "baseTicker",
|
|
153
154
|
publicData,
|
|
154
|
-
//
|
|
155
|
+
// separate spot account (sapi /api/v3) + /asset/wallet/transfer. Agent signer needs canSpotTrade.
|
|
155
156
|
spot: {
|
|
156
157
|
accountModel: "separate",
|
|
157
158
|
quoteAssets: { mainnet: ["USDT", "USD1"], testnet: ["USDT", "USD1"] },
|
|
@@ -172,5 +173,6 @@ export const asterVenue = {
|
|
|
172
173
|
// (INVALID_PARAMS) at order time; this is only the outer venue-wide bound.
|
|
173
174
|
maxSlippageBps: 5000,
|
|
174
175
|
builderFee: BUILDER_FEE_CAPABILITIES["aster"],
|
|
176
|
+
apiStatus: { kind: "official" },
|
|
175
177
|
create: async (ctx) => (await import("./create-helpers.js")).createAster(ctx),
|
|
176
178
|
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Adapter construction for the pre-existing venues (pacifica / hyperliquid /
|
|
3
3
|
* lighter / lighter-rh / aster) — the single creation path that replaced the
|
|
4
4
|
* three copies in src/index.ts (getAdapter / _initWithOws / getAdapterForExchange)
|
|
5
|
-
* and the MCP server's getOrCreateAdapter
|
|
5
|
+
* and the MCP server's getOrCreateAdapter.
|
|
6
6
|
*
|
|
7
7
|
* Signer tiers, as before: agent (Tier 1) → OWS master (Tier 2) → raw PK (Tier 3).
|
|
8
8
|
* Which tier signs a given request is still decided inside each adapter.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Adapter construction for the pre-existing venues (pacifica / hyperliquid /
|
|
3
3
|
* lighter / lighter-rh / aster) — the single creation path that replaced the
|
|
4
4
|
* three copies in src/index.ts (getAdapter / _initWithOws / getAdapterForExchange)
|
|
5
|
-
* and the MCP server's getOrCreateAdapter
|
|
5
|
+
* and the MCP server's getOrCreateAdapter.
|
|
6
6
|
*
|
|
7
7
|
* Signer tiers, as before: agent (Tier 1) → OWS master (Tier 2) → raw PK (Tier 3).
|
|
8
8
|
* Which tier signs a given request is still decided inside each adapter.
|
|
@@ -84,7 +84,7 @@ export async function createPacifica(ctx) {
|
|
|
84
84
|
adapter = new PacificaAdapter(parseSolanaKeypair(creds.pk), ctx.network, true);
|
|
85
85
|
}
|
|
86
86
|
else {
|
|
87
|
-
// Read-only: no key material. index.ts:143 Keypair.generate() recorded as out of scope
|
|
87
|
+
// Read-only: no key material. index.ts:143 Keypair.generate() recorded as out of scope.
|
|
88
88
|
adapter = new PacificaAdapter(Keypair.generate(), ctx.network, false);
|
|
89
89
|
}
|
|
90
90
|
const agent = await legacyAgentOf(ctx, creds, "pacifica");
|
|
@@ -138,7 +138,7 @@ export async function createHyperliquid(ctx) {
|
|
|
138
138
|
export async function createLighterFamily(venue, ctx) {
|
|
139
139
|
const creds = effectiveCredentials(ctx);
|
|
140
140
|
if (venue === "lighter-rh" && creds.pk !== null) {
|
|
141
|
-
//
|
|
141
|
+
// The Lighter RH master key is an OWS wallet only — no env / raw-PK tier.
|
|
142
142
|
throw new PerpError("NO_ENV_TIER", "Lighter RH does not accept a raw private key (env / --private-key / local wallet)", {
|
|
143
143
|
remediation: "Import the key into OWS (perp wallet import, key via hidden prompt / stdin) and run with --ows <wallet>, or register an agent: perp wallet agent approve lighter-rh",
|
|
144
144
|
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extended (formerly X10) — perps order book on Starknet, USD collateral. MARKET DATA ONLY in this
|
|
3
|
+
* version, through the OFFICIAL public REST API (https://api.docs.extended.exchange/).
|
|
4
|
+
*
|
|
5
|
+
* - roles are ["marketData"]: every account / trading / funds / agent / builder / bot path
|
|
6
|
+
* refuses with CAPABILITY_UNSUPPORTED before any request (venue.ts roleUnsupported(), with the
|
|
7
|
+
* readOnlyRemediation below). There is no Extended order, signing (Stark), transfer or account
|
|
8
|
+
* code at all; trading is planned for a later release.
|
|
9
|
+
* - Hosts (docs "Mainnet" / "Testnet"): mainnet api.starknet.extended.exchange, testnet (Sepolia)
|
|
10
|
+
* api.starknet.sepolia.extended.exchange. The old api.extended.exchange answers 404.
|
|
11
|
+
* - Every request must carry a User-Agent header (docs "Mandatory headers"; none → HTTP 403).
|
|
12
|
+
* - Funding (docs "Get funding rates history", docs.extended.exchange funding-payments): applied
|
|
13
|
+
* once per hour; marketStats.fundingRate is the current hour's ACCRUING rate (recomputed every
|
|
14
|
+
* minute) as a FRACTION per hour — see extended/public.ts.
|
|
15
|
+
* Not registered here; the registry module owns registerVenue().
|
|
16
|
+
*/
|
|
17
|
+
import type { VenueDefinition } from "../venue.js";
|
|
18
|
+
export declare const EXTENDED_DOCS_URL = "https://api.docs.extended.exchange/";
|
|
19
|
+
/** The remediation of every role refusal (owner decision: phase 1 is read-only). */
|
|
20
|
+
export declare const EXTENDED_READ_ONLY_REMEDIATION = "Extended is read-only (market data) in this version; trading is planned for a later release. Market data: perp -e extended market list|prices|info|book|trades|funding|kline";
|
|
21
|
+
export declare const extendedVenue: VenueDefinition;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extended (formerly X10) — perps order book on Starknet, USD collateral. MARKET DATA ONLY in this
|
|
3
|
+
* version, through the OFFICIAL public REST API (https://api.docs.extended.exchange/).
|
|
4
|
+
*
|
|
5
|
+
* - roles are ["marketData"]: every account / trading / funds / agent / builder / bot path
|
|
6
|
+
* refuses with CAPABILITY_UNSUPPORTED before any request (venue.ts roleUnsupported(), with the
|
|
7
|
+
* readOnlyRemediation below). There is no Extended order, signing (Stark), transfer or account
|
|
8
|
+
* code at all; trading is planned for a later release.
|
|
9
|
+
* - Hosts (docs "Mainnet" / "Testnet"): mainnet api.starknet.extended.exchange, testnet (Sepolia)
|
|
10
|
+
* api.starknet.sepolia.extended.exchange. The old api.extended.exchange answers 404.
|
|
11
|
+
* - Every request must carry a User-Agent header (docs "Mandatory headers"; none → HTTP 403).
|
|
12
|
+
* - Funding (docs "Get funding rates history", docs.extended.exchange funding-payments): applied
|
|
13
|
+
* once per hour; marketStats.fundingRate is the current hour's ACCRUING rate (recomputed every
|
|
14
|
+
* minute) as a FRACTION per hour — see extended/public.ts.
|
|
15
|
+
* Not registered here; the registry module owns registerVenue().
|
|
16
|
+
*/
|
|
17
|
+
export const EXTENDED_DOCS_URL = "https://api.docs.extended.exchange/";
|
|
18
|
+
/** The remediation of every role refusal (owner decision: phase 1 is read-only). */
|
|
19
|
+
export const EXTENDED_READ_ONLY_REMEDIATION = "Extended is read-only (market data) in this version; trading is planned for a later release. Market data: perp -e extended market list|prices|info|book|trades|funding|kline";
|
|
20
|
+
/** Lazy: public.ts is only loaded when market data is actually requested. */
|
|
21
|
+
const publicData = {
|
|
22
|
+
async fetchFundingRates(net) {
|
|
23
|
+
return (await import("../extended/public.js")).extendedPublicData.fetchFundingRates(net);
|
|
24
|
+
},
|
|
25
|
+
async fetchMarkets(net) {
|
|
26
|
+
return (await import("../extended/public.js")).extendedPublicData.fetchMarkets(net);
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
export const extendedVenue = {
|
|
30
|
+
id: "extended",
|
|
31
|
+
aliases: ["ext", "x10"],
|
|
32
|
+
displayName: "Extended",
|
|
33
|
+
family: "extended",
|
|
34
|
+
masterKeyKind: "none",
|
|
35
|
+
agentKeyKind: "none",
|
|
36
|
+
secretStorage: { kind: "none", dir: null },
|
|
37
|
+
networks: {
|
|
38
|
+
mainnet: {
|
|
39
|
+
restUrl: "https://api.starknet.extended.exchange/api/v1",
|
|
40
|
+
wsUrl: "wss://api.starknet.extended.exchange/stream.extended.exchange/v1",
|
|
41
|
+
explorerUrl: null,
|
|
42
|
+
signingChainId: null,
|
|
43
|
+
settlementChain: "starknet",
|
|
44
|
+
collateral: ["USD"],
|
|
45
|
+
collateralAssetIndex: null,
|
|
46
|
+
rpcUrl: null,
|
|
47
|
+
depositPins: null,
|
|
48
|
+
},
|
|
49
|
+
testnet: {
|
|
50
|
+
restUrl: "https://api.starknet.sepolia.extended.exchange/api/v1",
|
|
51
|
+
// The docs' SDK config (TESTNET_CONFIG stream_url). Unused (no ws codec); live 2026-10-19 it
|
|
52
|
+
// answered HTTP 403 to a public stream (api.starknet.sepolia… answered 503) — unverified.
|
|
53
|
+
wsUrl: "wss://starknet.sepolia.extended.exchange/stream.extended.exchange/v1",
|
|
54
|
+
explorerUrl: null,
|
|
55
|
+
signingChainId: null,
|
|
56
|
+
settlementChain: "starknet",
|
|
57
|
+
collateral: ["USD"],
|
|
58
|
+
collateralAssetIndex: null,
|
|
59
|
+
rpcUrl: null,
|
|
60
|
+
depositPins: null,
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
// Funding is applied once per hour on every perpetual market; the published rate is per hour.
|
|
64
|
+
fundingRateBasis: { kind: "perHours", hours: 1 },
|
|
65
|
+
settlementIntervalHours: 1,
|
|
66
|
+
// Not verified: the unit / sign of marketStats.fundingRate is not checked against a settled account
|
|
67
|
+
// funding payment (needs an account; RISEx's bar). Partial evidence only: docs + one recorded
|
|
68
|
+
// settlement (src/__tests__/fixtures/extended/funding-settlement-evidence.json — last accruing value
|
|
69
|
+
// == applied print on 8 markets, 5 of them at the baseline). And `_24_5` equities print 0 while
|
|
70
|
+
// their underlying is closed (TSLA_24_5: 34 of 43 weekend prints were 0), so hourly × 8760
|
|
71
|
+
// overstates them. Until settled against payments Extended is not a funding-arb venue.
|
|
72
|
+
fundingVerified: false,
|
|
73
|
+
roles: ["marketData"],
|
|
74
|
+
capabilities: null,
|
|
75
|
+
// Docs "Rate Limits": default tier 1,000 requests/minute per IP, all endpoints throttled by IP.
|
|
76
|
+
// 15/s sustained (900/min) leaves headroom for other processes on the same IP.
|
|
77
|
+
rateLimit: { capacity: 50, refillPerSec: 15, weights: null },
|
|
78
|
+
// docs.extended.exchange/extended-resources/legal/restricted-countries (2026-10-19), Category A;
|
|
79
|
+
// Ukraine is restricted only for Crimea / Donetsk / Kherson / Luhansk / Zaporizhzhia (no alpha-2).
|
|
80
|
+
// Warning-only and shown with credentials — unused while the venue is market data only.
|
|
81
|
+
restrictedRegions: ["AF", "CA", "HK", "CU", "IR", "IQ", "YE", "KP", "RU", "SY", "SC", "GB", "US"],
|
|
82
|
+
symbolIdentity: "baseTicker",
|
|
83
|
+
publicData,
|
|
84
|
+
spot: null,
|
|
85
|
+
// Unused (no trading role); the field is required by the definition shape.
|
|
86
|
+
maxSlippageBps: 1,
|
|
87
|
+
builderFee: null,
|
|
88
|
+
apiStatus: { kind: "official" },
|
|
89
|
+
gatedRoles: null,
|
|
90
|
+
readOnlyRemediation: EXTENDED_READ_ONLY_REMEDIATION,
|
|
91
|
+
// A public-only adapter: market data works, every account / trading method refuses.
|
|
92
|
+
async create(ctx) {
|
|
93
|
+
const { ExtendedPublicAdapter } = await import("../extended/adapter.js");
|
|
94
|
+
return new ExtendedPublicAdapter(extendedVenue, ctx.network);
|
|
95
|
+
},
|
|
96
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GRVT venue definition — MARKET DATA ONLY in this version (official, documented API).
|
|
3
|
+
*
|
|
4
|
+
* GRVT (api-docs.grvt.io) is a hybrid perps exchange (off-chain matching, ZK-validium settlement on
|
|
5
|
+
* GRVT chain 325), USDT collateral. perp-cli reads its public Market Data REST API
|
|
6
|
+
* (`POST https://market-data.grvt.io/full/v1/<endpoint>`, no key) and nothing else:
|
|
7
|
+
* - roles are ["marketData"]: every account / trading / funds / agent / builder / bot path refuses
|
|
8
|
+
* with CAPABILITY_UNSUPPORTED before any request (venue.ts roleUnsupported(), with the
|
|
9
|
+
* readOnlyRemediation below). There is no GRVT order, signing, transfer or account code at all.
|
|
10
|
+
* - funding is unverified (fundingVerified false): the ticker's `funding_rate` is the venue's
|
|
11
|
+
* indicative rate for the active interval (a moving estimate of the next payment, "predicted"),
|
|
12
|
+
* quoted in percent per the market's own funding interval (4 h or 8 h, per instrument). The
|
|
13
|
+
* percent unit is documented for settled history (/full/v1/funding "percentage points") and
|
|
14
|
+
* observed identical in magnitude on the ticker (whose schema says "centibeeps"); it is not yet
|
|
15
|
+
* checked against settled funding payments (an authenticated read) — kept out of arb ranking
|
|
16
|
+
* unless --include-unverified.
|
|
17
|
+
* Not registered here; the registry module owns registerVenue().
|
|
18
|
+
*/
|
|
19
|
+
import type { RateLimitPolicy, VenueDefinition } from "../venue.js";
|
|
20
|
+
export declare const GRVT_DOCS_URL = "https://api-docs.grvt.io";
|
|
21
|
+
/** Uniform refusal text for every write / signer / setup-trading path on GRVT. */
|
|
22
|
+
export declare const GRVT_READ_ONLY_REMEDIATION = "GRVT is read-only (market data) in this version; trading is planned for a later release";
|
|
23
|
+
/**
|
|
24
|
+
* help.grvt.io "What are the rate limitations on Grvt?" — REST Market Data, every tier, per minute:
|
|
25
|
+
* GetInstrument / MiniTicker / Ticker 1500, all others 500 (WS JSON-RPC calls count too). Two token
|
|
26
|
+
* buckets sized so that no 60 s window can exceed the limit (capacity + 60 s × refill ≤ limit).
|
|
27
|
+
*/
|
|
28
|
+
export declare const GRVT_TICKER_RATE_LIMIT: RateLimitPolicy;
|
|
29
|
+
export declare const GRVT_OTHER_RATE_LIMIT: RateLimitPolicy;
|
|
30
|
+
export declare const grvtVenue: VenueDefinition;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GRVT venue definition — MARKET DATA ONLY in this version (official, documented API).
|
|
3
|
+
*
|
|
4
|
+
* GRVT (api-docs.grvt.io) is a hybrid perps exchange (off-chain matching, ZK-validium settlement on
|
|
5
|
+
* GRVT chain 325), USDT collateral. perp-cli reads its public Market Data REST API
|
|
6
|
+
* (`POST https://market-data.grvt.io/full/v1/<endpoint>`, no key) and nothing else:
|
|
7
|
+
* - roles are ["marketData"]: every account / trading / funds / agent / builder / bot path refuses
|
|
8
|
+
* with CAPABILITY_UNSUPPORTED before any request (venue.ts roleUnsupported(), with the
|
|
9
|
+
* readOnlyRemediation below). There is no GRVT order, signing, transfer or account code at all.
|
|
10
|
+
* - funding is unverified (fundingVerified false): the ticker's `funding_rate` is the venue's
|
|
11
|
+
* indicative rate for the active interval (a moving estimate of the next payment, "predicted"),
|
|
12
|
+
* quoted in percent per the market's own funding interval (4 h or 8 h, per instrument). The
|
|
13
|
+
* percent unit is documented for settled history (/full/v1/funding "percentage points") and
|
|
14
|
+
* observed identical in magnitude on the ticker (whose schema says "centibeeps"); it is not yet
|
|
15
|
+
* checked against settled funding payments (an authenticated read) — kept out of arb ranking
|
|
16
|
+
* unless --include-unverified.
|
|
17
|
+
* Not registered here; the registry module owns registerVenue().
|
|
18
|
+
*/
|
|
19
|
+
export const GRVT_DOCS_URL = "https://api-docs.grvt.io";
|
|
20
|
+
/** Uniform refusal text for every write / signer / setup-trading path on GRVT. */
|
|
21
|
+
export const GRVT_READ_ONLY_REMEDIATION = "GRVT is read-only (market data) in this version; trading is planned for a later release";
|
|
22
|
+
/**
|
|
23
|
+
* help.grvt.io "What are the rate limitations on Grvt?" — REST Market Data, every tier, per minute:
|
|
24
|
+
* GetInstrument / MiniTicker / Ticker 1500, all others 500 (WS JSON-RPC calls count too). Two token
|
|
25
|
+
* buckets sized so that no 60 s window can exceed the limit (capacity + 60 s × refill ≤ limit).
|
|
26
|
+
*/
|
|
27
|
+
export const GRVT_TICKER_RATE_LIMIT = { capacity: 750, refillPerSec: 12, weights: null };
|
|
28
|
+
export const GRVT_OTHER_RATE_LIMIT = { capacity: 250, refillPerSec: 4, weights: null };
|
|
29
|
+
/** Lazy: public.ts is only loaded when market data is actually requested. */
|
|
30
|
+
const publicData = {
|
|
31
|
+
async fetchFundingRates(net) {
|
|
32
|
+
return (await import("../grvt/public.js")).grvtPublicData.fetchFundingRates(net);
|
|
33
|
+
},
|
|
34
|
+
async fetchMarkets(net) {
|
|
35
|
+
return (await import("../grvt/public.js")).grvtPublicData.fetchMarkets(net);
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
export const grvtVenue = {
|
|
39
|
+
id: "grvt",
|
|
40
|
+
aliases: ["grv"],
|
|
41
|
+
displayName: "GRVT",
|
|
42
|
+
family: "grvt",
|
|
43
|
+
masterKeyKind: "none",
|
|
44
|
+
agentKeyKind: "none",
|
|
45
|
+
secretStorage: { kind: "none", dir: null },
|
|
46
|
+
networks: {
|
|
47
|
+
// grvt-pysdk grvt_raw_env.py (PROD / TESTNET); the docs' "Try it out" uses the same hosts.
|
|
48
|
+
mainnet: {
|
|
49
|
+
restUrl: "https://market-data.grvt.io",
|
|
50
|
+
wsUrl: "wss://market-data.grvt.io/ws/full",
|
|
51
|
+
explorerUrl: null,
|
|
52
|
+
signingChainId: null,
|
|
53
|
+
settlementChain: "offchain",
|
|
54
|
+
collateral: ["USDT"],
|
|
55
|
+
collateralAssetIndex: null,
|
|
56
|
+
rpcUrl: null,
|
|
57
|
+
depositPins: null,
|
|
58
|
+
},
|
|
59
|
+
testnet: {
|
|
60
|
+
restUrl: "https://market-data.testnet.grvt.io",
|
|
61
|
+
wsUrl: "wss://market-data.testnet.grvt.io/ws/full",
|
|
62
|
+
explorerUrl: null,
|
|
63
|
+
signingChainId: null,
|
|
64
|
+
settlementChain: "offchain",
|
|
65
|
+
collateral: ["USDT"],
|
|
66
|
+
collateralAssetIndex: null,
|
|
67
|
+
rpcUrl: null,
|
|
68
|
+
depositPins: null,
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
// Per instrument: funding_interval_hours is 8 or 4 (live 2026-10-19: 124 × 8 h, 60 × 4 h).
|
|
72
|
+
fundingRateBasis: "perMarket",
|
|
73
|
+
settlementIntervalHours: "perMarket",
|
|
74
|
+
fundingVerified: false,
|
|
75
|
+
roles: ["marketData"],
|
|
76
|
+
// Not a release gate (nothing is implemented and switched off): the venue has no trading code yet.
|
|
77
|
+
gatedRoles: null,
|
|
78
|
+
capabilities: null,
|
|
79
|
+
// "All others" bucket (instruments, book, trade, funding, kline, margin_rules); the ticker bucket
|
|
80
|
+
// is GRVT_TICKER_RATE_LIMIT (grvt/client.ts picks per endpoint).
|
|
81
|
+
rateLimit: GRVT_OTHER_RATE_LIMIT,
|
|
82
|
+
// help.grvt.io/en/articles/9711621-restricted-jurisdictions (also Crimea / Donetsk / Luhansk /
|
|
83
|
+
// Kherson / Zaporizhzhya / Sevastopol regions). Trading needs KYC — relevant once trading lands.
|
|
84
|
+
restrictedRegions: ["US", "PR", "AS", "GU", "MP", "VI", "SG", "HK", "KP", "IR", "MM", "BY", "CU", "AF", "CA", "LY", "RU", "SO", "SS", "SD", "SY"],
|
|
85
|
+
symbolIdentity: "baseTicker",
|
|
86
|
+
publicData,
|
|
87
|
+
spot: null,
|
|
88
|
+
// Unused (no trading role); the field is required by the definition shape.
|
|
89
|
+
maxSlippageBps: 1,
|
|
90
|
+
builderFee: null,
|
|
91
|
+
apiStatus: { kind: "official" },
|
|
92
|
+
readOnlyRemediation: GRVT_READ_ONLY_REMEDIATION,
|
|
93
|
+
// A public-only adapter: market data works, every account / trading method refuses.
|
|
94
|
+
async create(ctx) {
|
|
95
|
+
const { GrvtPublicAdapter } = await import("../grvt/adapter.js");
|
|
96
|
+
return new GrvtPublicAdapter(grvtVenue, ctx.network);
|
|
97
|
+
},
|
|
98
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Hyperliquid venue definition
|
|
2
|
+
* Hyperliquid venue definition.
|
|
3
3
|
* HIP-3 dexes are not venues: they are selected via VenueCreateContext.hlDex.
|
|
4
|
-
* Adapter + public-data code are loaded lazily
|
|
4
|
+
* Adapter + public-data code are loaded lazily.
|
|
5
5
|
*/
|
|
6
6
|
import type { Network, VenueDefinition } from "../venue.js";
|
|
7
7
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Hyperliquid venue definition
|
|
2
|
+
* Hyperliquid venue definition.
|
|
3
3
|
* HIP-3 dexes are not venues: they are selected via VenueCreateContext.hlDex.
|
|
4
|
-
* Adapter + public-data code are loaded lazily
|
|
4
|
+
* Adapter + public-data code are loaded lazily.
|
|
5
5
|
*/
|
|
6
6
|
import { BUILDER_FEE_CAPABILITIES } from "../builder-fee.js";
|
|
7
7
|
/**
|
|
@@ -36,7 +36,7 @@ export const hyperliquidVenue = {
|
|
|
36
36
|
agentKeyKind: "evm",
|
|
37
37
|
secretStorage: { kind: "ows-wallet", dir: null },
|
|
38
38
|
// REST: src/exchanges/hyperliquid.ts; mainnet WS: src/dashboard/ws-feeds.ts.
|
|
39
|
-
// Testnet WS
|
|
39
|
+
// Testnet WS per the HL websocket docs (opened in the 2026-10-13 ws probe). signingChainId: L1 action phantom-agent domain (hyperliquid.ts).
|
|
40
40
|
networks: {
|
|
41
41
|
mainnet: {
|
|
42
42
|
restUrl: "https://api.hyperliquid.xyz",
|
|
@@ -51,7 +51,7 @@ export const hyperliquidVenue = {
|
|
|
51
51
|
},
|
|
52
52
|
testnet: {
|
|
53
53
|
restUrl: "https://api.hyperliquid-testnet.xyz",
|
|
54
|
-
wsUrl:
|
|
54
|
+
wsUrl: "wss://api.hyperliquid-testnet.xyz/ws",
|
|
55
55
|
explorerUrl: null,
|
|
56
56
|
signingChainId: 1337,
|
|
57
57
|
settlementChain: "hyperliquid",
|
|
@@ -65,11 +65,12 @@ export const hyperliquidVenue = {
|
|
|
65
65
|
settlementIntervalHours: 1,
|
|
66
66
|
fundingVerified: true,
|
|
67
67
|
roles: ["marketData", "account", "trading"],
|
|
68
|
-
|
|
68
|
+
gatedRoles: null,
|
|
69
|
+
// marketOrder: IOC limit at a protection price. Declared reference
|
|
69
70
|
// price = l2Book mid ((best bid + best ask) / 2) for native perps, HIP-3 and spot —
|
|
70
71
|
// no runtime substitute; a one-sided/empty book → PRICE_STALE. Rounding: 5 significant
|
|
71
72
|
// figures, max 6 − szDecimals (perp) / 8 − szDecimals (spot) decimals, toward crossing.
|
|
72
|
-
// tpsl stays "separateOrders": HL `normalTpsl` grouping was evaluated
|
|
73
|
+
// tpsl stays "separateOrders": HL `normalTpsl` grouping was evaluated and not
|
|
73
74
|
// used — its children have a fixed size equal to the parent and are fully cancelled when
|
|
74
75
|
// a partially filled parent is cancelled (HL docs, TP/SL orders), so a partially filled
|
|
75
76
|
// IOC entry would be left unprotected; separateOrders sizes TP/SL to the verified fill.
|
|
@@ -92,7 +93,7 @@ export const hyperliquidVenue = {
|
|
|
92
93
|
// HL docs "Rate limits and user limits": REST requests share an aggregated
|
|
93
94
|
// weight of 1200/min per IP. Exchange actions weigh 1 (unbatched); light info
|
|
94
95
|
// requests 2; most info requests 20; userRole 60.
|
|
95
|
-
// Declared only — per
|
|
96
|
+
// Declared only — per the limiter is applied to new venues + lighter-rh.
|
|
96
97
|
rateLimit: {
|
|
97
98
|
capacity: 1200,
|
|
98
99
|
refillPerSec: 20,
|
|
@@ -104,7 +105,7 @@ export const hyperliquidVenue = {
|
|
|
104
105
|
restrictedRegions: [],
|
|
105
106
|
symbolIdentity: "baseTicker",
|
|
106
107
|
publicData,
|
|
107
|
-
//
|
|
108
|
+
// spot USDC is shared with perp margin when the account is unified (isUnifiedAccount, read at init).
|
|
108
109
|
spot: {
|
|
109
110
|
accountModel: "runtime",
|
|
110
111
|
quoteAssets: { mainnet: ["USDC"], testnet: ["USDC"] },
|
|
@@ -122,5 +123,6 @@ export const hyperliquidVenue = {
|
|
|
122
123
|
},
|
|
123
124
|
maxSlippageBps: 5000,
|
|
124
125
|
builderFee: BUILDER_FEE_CAPABILITIES["hyperliquid"],
|
|
126
|
+
apiStatus: { kind: "official" },
|
|
125
127
|
create: async (ctx) => (await import("./create-helpers.js")).createHyperliquid(ctx),
|
|
126
128
|
};
|
|
@@ -10,7 +10,12 @@ import { lighterVenue } from "./lighter.js";
|
|
|
10
10
|
import { ondoVenue } from "./ondo.js";
|
|
11
11
|
import { pacificaVenue } from "./pacifica.js";
|
|
12
12
|
import { qfexVenue } from "./qfex.js";
|
|
13
|
-
|
|
13
|
+
import { risexVenue } from "./risex.js";
|
|
14
|
+
import { txflowVenue } from "./txflow.js";
|
|
15
|
+
import { variationalVenue } from "./variational.js";
|
|
16
|
+
import { grvtVenue } from "./grvt.js";
|
|
17
|
+
import { extendedVenue } from "./extended.js";
|
|
18
|
+
export declare const ALL_VENUES: readonly [import("../venue.js").VenueDefinition, import("../venue.js").VenueDefinition, import("../venue.js").VenueDefinition, import("../venue.js").VenueDefinition, import("../venue.js").VenueDefinition, import("../venue.js").VenueDefinition, import("../venue.js").VenueDefinition, import("../venue.js").VenueDefinition, import("../venue.js").VenueDefinition, import("../venue.js").VenueDefinition, import("../venue.js").VenueDefinition, import("../venue.js").VenueDefinition, import("../venue.js").VenueDefinition];
|
|
14
19
|
/** Idempotent: registers all venues on first call, no-op afterwards. */
|
|
15
20
|
export declare function ensureVenuesRegistered(): void;
|
|
16
|
-
export { pacificaVenue, hyperliquidVenue, lighterVenue, asterVenue, lighterRhVenue, ondoVenue, arcusVenue, qfexVenue, };
|
|
21
|
+
export { pacificaVenue, hyperliquidVenue, lighterVenue, asterVenue, lighterRhVenue, ondoVenue, arcusVenue, qfexVenue, risexVenue, txflowVenue, variationalVenue, grvtVenue, extendedVenue, };
|
|
@@ -11,9 +11,15 @@ import { lighterVenue } from "./lighter.js";
|
|
|
11
11
|
import { ondoVenue } from "./ondo.js";
|
|
12
12
|
import { pacificaVenue } from "./pacifica.js";
|
|
13
13
|
import { qfexVenue } from "./qfex.js";
|
|
14
|
+
import { risexVenue } from "./risex.js";
|
|
15
|
+
import { txflowVenue } from "./txflow.js";
|
|
16
|
+
import { variationalVenue } from "./variational.js";
|
|
17
|
+
import { grvtVenue } from "./grvt.js";
|
|
18
|
+
import { extendedVenue } from "./extended.js";
|
|
14
19
|
export const ALL_VENUES = [
|
|
15
20
|
pacificaVenue, hyperliquidVenue, lighterVenue, asterVenue,
|
|
16
|
-
lighterRhVenue, ondoVenue, arcusVenue, qfexVenue,
|
|
21
|
+
lighterRhVenue, ondoVenue, arcusVenue, qfexVenue, risexVenue, txflowVenue, variationalVenue, grvtVenue,
|
|
22
|
+
extendedVenue,
|
|
17
23
|
];
|
|
18
24
|
/** Idempotent: registers all venues on first call, no-op afterwards. */
|
|
19
25
|
export function ensureVenuesRegistered() {
|
|
@@ -23,4 +29,4 @@ export function ensureVenuesRegistered() {
|
|
|
23
29
|
}
|
|
24
30
|
}
|
|
25
31
|
ensureVenuesRegistered();
|
|
26
|
-
export { pacificaVenue, hyperliquidVenue, lighterVenue, asterVenue, lighterRhVenue, ondoVenue, arcusVenue, qfexVenue, };
|
|
32
|
+
export { pacificaVenue, hyperliquidVenue, lighterVenue, asterVenue, lighterRhVenue, ondoVenue, arcusVenue, qfexVenue, risexVenue, txflowVenue, variationalVenue, grvtVenue, extendedVenue, };
|