@raintree-technology/perps 0.1.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/CHANGELOG.md +33 -0
- package/LICENSE +21 -0
- package/README.md +175 -0
- package/dist/adapters/aevo.d.ts +64 -0
- package/dist/adapters/aevo.js +899 -0
- package/dist/adapters/certification.d.ts +33 -0
- package/dist/adapters/certification.js +99 -0
- package/dist/adapters/decibel/order-manager.d.ts +45 -0
- package/dist/adapters/decibel/order-manager.js +140 -0
- package/dist/adapters/decibel/rest-client.d.ts +176 -0
- package/dist/adapters/decibel/rest-client.js +155 -0
- package/dist/adapters/decibel/ws-feed.d.ts +28 -0
- package/dist/adapters/decibel/ws-feed.js +166 -0
- package/dist/adapters/decibel.d.ts +108 -0
- package/dist/adapters/decibel.js +1377 -0
- package/dist/adapters/hyperliquid.d.ts +63 -0
- package/dist/adapters/hyperliquid.js +797 -0
- package/dist/adapters/index.d.ts +11 -0
- package/dist/adapters/index.js +12 -0
- package/dist/adapters/interface.d.ts +310 -0
- package/dist/adapters/interface.js +15 -0
- package/dist/adapters/orderly.d.ts +70 -0
- package/dist/adapters/orderly.js +936 -0
- package/dist/adapters/paradex.d.ts +69 -0
- package/dist/adapters/paradex.js +862 -0
- package/dist/adapters/utils.d.ts +17 -0
- package/dist/adapters/utils.js +122 -0
- package/dist/cli/command-metadata.d.ts +2 -0
- package/dist/cli/command-metadata.js +44 -0
- package/dist/cli/context.d.ts +14 -0
- package/dist/cli/context.js +59 -0
- package/dist/cli/experience.d.ts +48 -0
- package/dist/cli/experience.js +243 -0
- package/dist/cli/ink/app/AppShell.d.ts +12 -0
- package/dist/cli/ink/app/AppShell.js +32 -0
- package/dist/cli/ink/app/MetricStrip.d.ts +6 -0
- package/dist/cli/ink/app/MetricStrip.js +14 -0
- package/dist/cli/ink/app/Panel.d.ts +9 -0
- package/dist/cli/ink/app/Panel.js +7 -0
- package/dist/cli/ink/app/ascii.d.ts +2 -0
- package/dist/cli/ink/app/ascii.js +46 -0
- package/dist/cli/ink/app/index.d.ts +5 -0
- package/dist/cli/ink/app/index.js +4 -0
- package/dist/cli/ink/app/types.d.ts +15 -0
- package/dist/cli/ink/app/types.js +1 -0
- package/dist/cli/ink/components/PnL.d.ts +12 -0
- package/dist/cli/ink/components/PnL.js +23 -0
- package/dist/cli/ink/components/Spinner.d.ts +13 -0
- package/dist/cli/ink/components/Spinner.js +13 -0
- package/dist/cli/ink/components/Table.d.ts +14 -0
- package/dist/cli/ink/components/Table.js +42 -0
- package/dist/cli/ink/components/WatchHeader.d.ts +10 -0
- package/dist/cli/ink/components/WatchHeader.js +18 -0
- package/dist/cli/ink/components/index.d.ts +4 -0
- package/dist/cli/ink/components/index.js +4 -0
- package/dist/cli/ink/index.d.ts +4 -0
- package/dist/cli/ink/index.js +4 -0
- package/dist/cli/ink/render.d.ts +12 -0
- package/dist/cli/ink/render.js +21 -0
- package/dist/cli/ink/theme.d.ts +29 -0
- package/dist/cli/ink/theme.js +40 -0
- package/dist/cli/network-defaults.d.ts +10 -0
- package/dist/cli/network-defaults.js +35 -0
- package/dist/cli/output.d.ts +11 -0
- package/dist/cli/output.js +115 -0
- package/dist/cli/program.d.ts +18 -0
- package/dist/cli/program.js +164 -0
- package/dist/cli/watch.d.ts +19 -0
- package/dist/cli/watch.js +35 -0
- package/dist/client/index.d.ts +55 -0
- package/dist/client/index.js +157 -0
- package/dist/commands/account/add.d.ts +2 -0
- package/dist/commands/account/add.js +510 -0
- package/dist/commands/account/balances-simple.d.ts +5 -0
- package/dist/commands/account/balances-simple.js +63 -0
- package/dist/commands/account/index.d.ts +2 -0
- package/dist/commands/account/index.js +17 -0
- package/dist/commands/account/ls.d.ts +2 -0
- package/dist/commands/account/ls.js +95 -0
- package/dist/commands/account/positions-simple.d.ts +5 -0
- package/dist/commands/account/positions-simple.js +77 -0
- package/dist/commands/account/remove.d.ts +2 -0
- package/dist/commands/account/remove.js +47 -0
- package/dist/commands/account/set-default.d.ts +2 -0
- package/dist/commands/account/set-default.js +47 -0
- package/dist/commands/agent/index.d.ts +2 -0
- package/dist/commands/agent/index.js +126 -0
- package/dist/commands/arb/alert.d.ts +6 -0
- package/dist/commands/arb/alert.js +88 -0
- package/dist/commands/arb/basis-execute.d.ts +6 -0
- package/dist/commands/arb/basis-execute.js +332 -0
- package/dist/commands/arb/basis.d.ts +6 -0
- package/dist/commands/arb/basis.js +181 -0
- package/dist/commands/arb/compare.d.ts +6 -0
- package/dist/commands/arb/compare.js +216 -0
- package/dist/commands/arb/execute.d.ts +6 -0
- package/dist/commands/arb/execute.js +467 -0
- package/dist/commands/arb/funding.d.ts +6 -0
- package/dist/commands/arb/funding.js +201 -0
- package/dist/commands/arb/history.d.ts +6 -0
- package/dist/commands/arb/history.js +153 -0
- package/dist/commands/arb/index.d.ts +6 -0
- package/dist/commands/arb/index.js +29 -0
- package/dist/commands/arb/positions.d.ts +6 -0
- package/dist/commands/arb/positions.js +158 -0
- package/dist/commands/arb/spread.d.ts +6 -0
- package/dist/commands/arb/spread.js +253 -0
- package/dist/commands/arb/track.d.ts +6 -0
- package/dist/commands/arb/track.js +259 -0
- package/dist/commands/asset/book-simple.d.ts +5 -0
- package/dist/commands/asset/book-simple.js +77 -0
- package/dist/commands/asset/index.d.ts +2 -0
- package/dist/commands/asset/index.js +5 -0
- package/dist/commands/completion.d.ts +2 -0
- package/dist/commands/completion.js +161 -0
- package/dist/commands/config/index.d.ts +5 -0
- package/dist/commands/config/index.js +109 -0
- package/dist/commands/data/index.d.ts +31 -0
- package/dist/commands/data/index.js +1466 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.js +201 -0
- package/dist/commands/exchange/index.d.ts +2 -0
- package/dist/commands/exchange/index.js +107 -0
- package/dist/commands/index.d.ts +2 -0
- package/dist/commands/index.js +48 -0
- package/dist/commands/markets/index.d.ts +2 -0
- package/dist/commands/markets/index.js +5 -0
- package/dist/commands/markets/ls-simple.d.ts +7 -0
- package/dist/commands/markets/ls-simple.js +277 -0
- package/dist/commands/operator/index.d.ts +2 -0
- package/dist/commands/operator/index.js +146 -0
- package/dist/commands/order/cancel-simple.d.ts +5 -0
- package/dist/commands/order/cancel-simple.js +104 -0
- package/dist/commands/order/index.d.ts +2 -0
- package/dist/commands/order/index.js +13 -0
- package/dist/commands/order/limit-simple.d.ts +5 -0
- package/dist/commands/order/limit-simple.js +195 -0
- package/dist/commands/order/market-simple.d.ts +5 -0
- package/dist/commands/order/market-simple.js +190 -0
- package/dist/commands/order/shared.d.ts +17 -0
- package/dist/commands/order/shared.js +51 -0
- package/dist/commands/order/trigger-simple.d.ts +5 -0
- package/dist/commands/order/trigger-simple.js +246 -0
- package/dist/commands/referral/index.d.ts +2 -0
- package/dist/commands/referral/index.js +7 -0
- package/dist/commands/referral/set.d.ts +2 -0
- package/dist/commands/referral/set.js +26 -0
- package/dist/commands/referral/status.d.ts +2 -0
- package/dist/commands/referral/status.js +31 -0
- package/dist/commands/replay/index.d.ts +2 -0
- package/dist/commands/replay/index.js +152 -0
- package/dist/commands/risk/analytics.d.ts +2 -0
- package/dist/commands/risk/analytics.js +64 -0
- package/dist/commands/risk/audit.d.ts +2 -0
- package/dist/commands/risk/audit.js +52 -0
- package/dist/commands/risk/index.d.ts +2 -0
- package/dist/commands/risk/index.js +9 -0
- package/dist/commands/risk/rules.d.ts +2 -0
- package/dist/commands/risk/rules.js +102 -0
- package/dist/commands/server.d.ts +2 -0
- package/dist/commands/server.js +208 -0
- package/dist/commands/setup/index.d.ts +2 -0
- package/dist/commands/setup/index.js +478 -0
- package/dist/commands/signal/index.d.ts +2 -0
- package/dist/commands/signal/index.js +129 -0
- package/dist/commands/state/index.d.ts +2 -0
- package/dist/commands/state/index.js +5 -0
- package/dist/commands/state/show.d.ts +2 -0
- package/dist/commands/state/show.js +105 -0
- package/dist/commands/strategy/index.d.ts +4 -0
- package/dist/commands/strategy/index.js +73 -0
- package/dist/commands/traces/index.d.ts +2 -0
- package/dist/commands/traces/index.js +76 -0
- package/dist/commands/ui/demo.d.ts +9 -0
- package/dist/commands/ui/demo.js +195 -0
- package/dist/commands/ui/index.d.ts +2 -0
- package/dist/commands/ui/index.js +7 -0
- package/dist/commands/ui/terminal.d.ts +2 -0
- package/dist/commands/ui/terminal.js +255 -0
- package/dist/commands/upgrade.d.ts +2 -0
- package/dist/commands/upgrade.js +98 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4 -0
- package/dist/lib/agent/audit.d.ts +12 -0
- package/dist/lib/agent/audit.js +13 -0
- package/dist/lib/agent/gateway.d.ts +13 -0
- package/dist/lib/agent/gateway.js +598 -0
- package/dist/lib/agent/metrics.d.ts +33 -0
- package/dist/lib/agent/metrics.js +175 -0
- package/dist/lib/agent/signature.d.ts +8 -0
- package/dist/lib/agent/signature.js +28 -0
- package/dist/lib/agent/tools.d.ts +28 -0
- package/dist/lib/agent/tools.js +453 -0
- package/dist/lib/agent/x402.d.ts +23 -0
- package/dist/lib/agent/x402.js +62 -0
- package/dist/lib/api-wallet.d.ts +69 -0
- package/dist/lib/api-wallet.js +101 -0
- package/dist/lib/balance-watcher.d.ts +25 -0
- package/dist/lib/balance-watcher.js +83 -0
- package/dist/lib/book-watcher.d.ts +25 -0
- package/dist/lib/book-watcher.js +48 -0
- package/dist/lib/config.d.ts +88 -0
- package/dist/lib/config.js +427 -0
- package/dist/lib/constants.d.ts +50 -0
- package/dist/lib/constants.js +84 -0
- package/dist/lib/contracts.d.ts +7 -0
- package/dist/lib/contracts.js +8 -0
- package/dist/lib/credential-vault.d.ts +22 -0
- package/dist/lib/credential-vault.js +109 -0
- package/dist/lib/db/accounts.d.ts +83 -0
- package/dist/lib/db/accounts.js +203 -0
- package/dist/lib/db/funding-history.d.ts +69 -0
- package/dist/lib/db/funding-history.js +183 -0
- package/dist/lib/db/index.d.ts +11 -0
- package/dist/lib/db/index.js +272 -0
- package/dist/lib/events/bus.d.ts +10 -0
- package/dist/lib/events/bus.js +17 -0
- package/dist/lib/events/types.d.ts +51 -0
- package/dist/lib/events/types.js +1 -0
- package/dist/lib/exchange.d.ts +30 -0
- package/dist/lib/exchange.js +84 -0
- package/dist/lib/execution/journal.d.ts +25 -0
- package/dist/lib/execution/journal.js +158 -0
- package/dist/lib/execution/safety.d.ts +34 -0
- package/dist/lib/execution/safety.js +197 -0
- package/dist/lib/exit-codes.d.ts +18 -0
- package/dist/lib/exit-codes.js +60 -0
- package/dist/lib/fetch.d.ts +18 -0
- package/dist/lib/fetch.js +66 -0
- package/dist/lib/fs-security.d.ts +10 -0
- package/dist/lib/fs-security.js +26 -0
- package/dist/lib/funding-tracker.d.ts +40 -0
- package/dist/lib/funding-tracker.js +118 -0
- package/dist/lib/logger.d.ts +27 -0
- package/dist/lib/logger.js +82 -0
- package/dist/lib/network-model.d.ts +13 -0
- package/dist/lib/network-model.js +30 -0
- package/dist/lib/onboarding.d.ts +133 -0
- package/dist/lib/onboarding.js +1459 -0
- package/dist/lib/operator-state.d.ts +25 -0
- package/dist/lib/operator-state.js +82 -0
- package/dist/lib/orders-watcher.d.ts +24 -0
- package/dist/lib/orders-watcher.js +74 -0
- package/dist/lib/paths.d.ts +20 -0
- package/dist/lib/paths.js +23 -0
- package/dist/lib/portfolio-watcher.d.ts +33 -0
- package/dist/lib/portfolio-watcher.js +95 -0
- package/dist/lib/position-watcher.d.ts +16 -0
- package/dist/lib/position-watcher.js +44 -0
- package/dist/lib/price-watcher.d.ts +15 -0
- package/dist/lib/price-watcher.js +84 -0
- package/dist/lib/prompts.d.ts +32 -0
- package/dist/lib/prompts.js +105 -0
- package/dist/lib/rate-limit.d.ts +32 -0
- package/dist/lib/rate-limit.js +88 -0
- package/dist/lib/risk/analytics.d.ts +39 -0
- package/dist/lib/risk/analytics.js +98 -0
- package/dist/lib/risk/drawdown.d.ts +18 -0
- package/dist/lib/risk/drawdown.js +49 -0
- package/dist/lib/risk/evaluation-log.d.ts +29 -0
- package/dist/lib/risk/evaluation-log.js +61 -0
- package/dist/lib/risk/index.d.ts +4 -0
- package/dist/lib/risk/index.js +4 -0
- package/dist/lib/risk/limits.d.ts +23 -0
- package/dist/lib/risk/limits.js +27 -0
- package/dist/lib/risk/manager.d.ts +32 -0
- package/dist/lib/risk/manager.js +85 -0
- package/dist/lib/risk/policy-middleware.d.ts +33 -0
- package/dist/lib/risk/policy-middleware.js +267 -0
- package/dist/lib/risk/position-sizer.d.ts +9 -0
- package/dist/lib/risk/position-sizer.js +14 -0
- package/dist/lib/risk/rules-store.d.ts +16 -0
- package/dist/lib/risk/rules-store.js +47 -0
- package/dist/lib/schema.d.ts +254 -0
- package/dist/lib/schema.js +199 -0
- package/dist/lib/secrets.d.ts +3 -0
- package/dist/lib/secrets.js +62 -0
- package/dist/lib/settings.d.ts +24 -0
- package/dist/lib/settings.js +86 -0
- package/dist/lib/signals.d.ts +73 -0
- package/dist/lib/signals.js +136 -0
- package/dist/lib/stable-stringify.d.ts +6 -0
- package/dist/lib/stable-stringify.js +17 -0
- package/dist/lib/state-context.d.ts +44 -0
- package/dist/lib/state-context.js +133 -0
- package/dist/lib/strategy/basis-trade.d.ts +2 -0
- package/dist/lib/strategy/basis-trade.js +24 -0
- package/dist/lib/strategy/funding-arb.d.ts +2 -0
- package/dist/lib/strategy/funding-arb.js +23 -0
- package/dist/lib/strategy/interface.d.ts +23 -0
- package/dist/lib/strategy/interface.js +1 -0
- package/dist/lib/strategy/registry.d.ts +4 -0
- package/dist/lib/strategy/registry.js +10 -0
- package/dist/lib/telemetry.d.ts +25 -0
- package/dist/lib/telemetry.js +101 -0
- package/dist/lib/trace-queries.d.ts +20 -0
- package/dist/lib/trace-queries.js +133 -0
- package/dist/lib/trace.d.ts +1 -0
- package/dist/lib/trace.js +4 -0
- package/dist/lib/trade-reputation.d.ts +6 -0
- package/dist/lib/trade-reputation.js +99 -0
- package/dist/lib/ui-tokens.d.ts +21 -0
- package/dist/lib/ui-tokens.js +26 -0
- package/dist/lib/validate.d.ts +39 -0
- package/dist/lib/validate.js +108 -0
- package/dist/lib/validation.d.ts +9 -0
- package/dist/lib/validation.js +64 -0
- package/dist/server/cache.d.ts +38 -0
- package/dist/server/cache.js +56 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.js +89 -0
- package/dist/server/ipc.d.ts +18 -0
- package/dist/server/ipc.js +159 -0
- package/dist/server/subscriptions.d.ts +18 -0
- package/dist/server/subscriptions.js +114 -0
- package/package.json +124 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { createRequire } from "module";
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import { registerCommands } from "../commands/index.js";
|
|
4
|
+
import { loadConfig } from "../lib/config.js";
|
|
5
|
+
import { getAvailableExchanges, setExchange } from "../lib/exchange.js";
|
|
6
|
+
import { getSetting } from "../lib/settings.js";
|
|
7
|
+
import { createContext } from "./context.js";
|
|
8
|
+
import { highlighter, printCommandCompletion, printSessionBanner } from "./experience.js";
|
|
9
|
+
import { commandPathFromCommand, resolveTestnetMode } from "./network-defaults.js";
|
|
10
|
+
import { outputError } from "./output.js";
|
|
11
|
+
const require = createRequire(import.meta.url);
|
|
12
|
+
const pkg = require("../../package.json");
|
|
13
|
+
const commandMeta = new WeakMap();
|
|
14
|
+
function findMeta(command) {
|
|
15
|
+
let current = command;
|
|
16
|
+
while (current) {
|
|
17
|
+
const meta = commandMeta.get(current);
|
|
18
|
+
if (meta)
|
|
19
|
+
return meta;
|
|
20
|
+
current = current.parent;
|
|
21
|
+
}
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
export function createProgram() {
|
|
25
|
+
const program = new Command();
|
|
26
|
+
const availableExchanges = getAvailableExchanges().join(", ");
|
|
27
|
+
const defaultExchange = getConfiguredDefaultExchange();
|
|
28
|
+
program
|
|
29
|
+
.name("perps")
|
|
30
|
+
.description("Universal CLI for perpetual DEXes")
|
|
31
|
+
.showSuggestionAfterError(true)
|
|
32
|
+
.showHelpAfterError()
|
|
33
|
+
.version(pkg.version)
|
|
34
|
+
.option("--json", "Output in JSON format", false)
|
|
35
|
+
.option("--human", "Enable human-first output UX (banner, timing, rich formatting)", false)
|
|
36
|
+
.option("--no-banner", "Disable session header for human-readable output")
|
|
37
|
+
.option("--testnet", "Force testnet network")
|
|
38
|
+
.option("--mainnet", "Force mainnet network")
|
|
39
|
+
.option("-e, --exchange <name>", `Exchange to use (${availableExchanges})`, defaultExchange)
|
|
40
|
+
.option("-v, --verbose", "Show detailed output", false)
|
|
41
|
+
.addHelpText("after", `
|
|
42
|
+
Examples:
|
|
43
|
+
perps markets ls
|
|
44
|
+
perps order market buy BTC 0.01 --idempotency-key demo-001
|
|
45
|
+
perps doctor --network
|
|
46
|
+
`)
|
|
47
|
+
.hook("preAction", async (thisCommand, actionCommand) => {
|
|
48
|
+
const invokedCommand = actionCommand ?? thisCommand;
|
|
49
|
+
const opts = invokedCommand.optsWithGlobals();
|
|
50
|
+
const commandPath = commandPathFromCommand(invokedCommand);
|
|
51
|
+
const exchangeNetworkOverride = getExchangeNetworkOverride(opts.exchange);
|
|
52
|
+
const isHumanMode = opts.human ?? false;
|
|
53
|
+
const verbose = opts.verbose ?? false;
|
|
54
|
+
const isTestnet = resolveTestnetMode({
|
|
55
|
+
argv: process.argv.slice(2),
|
|
56
|
+
commandPath,
|
|
57
|
+
exchangeNetworkOverride,
|
|
58
|
+
fallbackTestnet: getConfiguredTestnetFallback(),
|
|
59
|
+
});
|
|
60
|
+
// Set exchange context
|
|
61
|
+
try {
|
|
62
|
+
setExchange(opts.exchange);
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
outputError(err instanceof Error ? err.message : String(err));
|
|
66
|
+
console.error(highlighter.dim(`Available exchanges: ${getAvailableExchanges().join(", ")}`));
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
let config;
|
|
70
|
+
try {
|
|
71
|
+
config = loadConfig(isTestnet, opts.exchange);
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
outputError(err instanceof Error ? err.message : String(err));
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
const context = createContext(config);
|
|
78
|
+
// Store metadata on the root command
|
|
79
|
+
commandMeta.set(thisCommand, {
|
|
80
|
+
context,
|
|
81
|
+
outputOptions: { json: opts.json },
|
|
82
|
+
exchange: opts.exchange,
|
|
83
|
+
isTestnet,
|
|
84
|
+
commandPath,
|
|
85
|
+
isHumanMode,
|
|
86
|
+
verbose,
|
|
87
|
+
startTime: performance.now(),
|
|
88
|
+
});
|
|
89
|
+
if (!opts.json && isHumanMode && opts.banner && commandPath[0] !== "ui") {
|
|
90
|
+
// Show "ALL" when cross-exchange flags are active
|
|
91
|
+
const subOpts = invokedCommand.opts();
|
|
92
|
+
const bannerExchange = subOpts.all || subOpts.report ? "ALL" : opts.exchange;
|
|
93
|
+
printSessionBanner({
|
|
94
|
+
version: pkg.version,
|
|
95
|
+
commandPath,
|
|
96
|
+
exchange: bannerExchange,
|
|
97
|
+
isTestnet,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
.hook("postAction", (thisCommand) => {
|
|
102
|
+
const meta = commandMeta.get(thisCommand);
|
|
103
|
+
if (!meta)
|
|
104
|
+
return;
|
|
105
|
+
const isJson = meta.outputOptions.json;
|
|
106
|
+
// Only show timing for non-JSON output
|
|
107
|
+
if (!isJson && meta.isHumanMode) {
|
|
108
|
+
const duration = (performance.now() - meta.startTime) / 1000;
|
|
109
|
+
printCommandCompletion(duration);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
registerCommands(program);
|
|
113
|
+
return program;
|
|
114
|
+
}
|
|
115
|
+
export function getContext(command) {
|
|
116
|
+
const meta = findMeta(command);
|
|
117
|
+
if (meta)
|
|
118
|
+
return meta.context;
|
|
119
|
+
throw new Error("Context not found");
|
|
120
|
+
}
|
|
121
|
+
export function getOutputOptions(command) {
|
|
122
|
+
const meta = findMeta(command);
|
|
123
|
+
return meta?.outputOptions ?? { json: false };
|
|
124
|
+
}
|
|
125
|
+
export function getSelectedExchange(command) {
|
|
126
|
+
const meta = findMeta(command);
|
|
127
|
+
return meta?.exchange ?? "hyperliquid";
|
|
128
|
+
}
|
|
129
|
+
export function getVerbose(command) {
|
|
130
|
+
const meta = findMeta(command);
|
|
131
|
+
return meta?.verbose ?? false;
|
|
132
|
+
}
|
|
133
|
+
function getConfiguredDefaultExchange() {
|
|
134
|
+
try {
|
|
135
|
+
const configured = getSetting("defaultExchange");
|
|
136
|
+
return configured?.trim() || "hyperliquid";
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return "hyperliquid";
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function getConfiguredTestnetFallback() {
|
|
143
|
+
try {
|
|
144
|
+
return getSetting("testnetByDefault");
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function getExchangeNetworkOverride(exchangeId) {
|
|
151
|
+
const normalized = exchangeId.trim().toLowerCase();
|
|
152
|
+
const lookup = {
|
|
153
|
+
hyperliquid: process.env.HYPERLIQUID_NETWORK,
|
|
154
|
+
decibel: process.env.DECIBEL_NETWORK,
|
|
155
|
+
aevo: process.env.AEVO_NETWORK,
|
|
156
|
+
orderly: process.env.ORDERLY_NETWORK,
|
|
157
|
+
paradex: process.env.PARADEX_NETWORK,
|
|
158
|
+
};
|
|
159
|
+
const value = lookup[normalized]?.trim().toLowerCase();
|
|
160
|
+
if (value === "testnet" || value === "mainnet") {
|
|
161
|
+
return value;
|
|
162
|
+
}
|
|
163
|
+
return undefined;
|
|
164
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for watch mode terminal display
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Clear terminal screen and move cursor to top-left
|
|
6
|
+
*/
|
|
7
|
+
export declare function clearScreen(): void;
|
|
8
|
+
/**
|
|
9
|
+
* Hide terminal cursor (also registers signal handlers to restore on exit)
|
|
10
|
+
*/
|
|
11
|
+
export declare function hideCursor(): void;
|
|
12
|
+
/**
|
|
13
|
+
* Show terminal cursor
|
|
14
|
+
*/
|
|
15
|
+
export declare function showCursor(): void;
|
|
16
|
+
/**
|
|
17
|
+
* Format current time as HH:MM:SS
|
|
18
|
+
*/
|
|
19
|
+
export declare function formatTimestamp(): string;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for watch mode terminal display
|
|
3
|
+
*/
|
|
4
|
+
import { registerCursorCleanup } from "./experience.js";
|
|
5
|
+
/**
|
|
6
|
+
* Clear terminal screen and move cursor to top-left
|
|
7
|
+
*/
|
|
8
|
+
export function clearScreen() {
|
|
9
|
+
process.stdout.write("\x1b[2J\x1b[H");
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Hide terminal cursor (also registers signal handlers to restore on exit)
|
|
13
|
+
*/
|
|
14
|
+
export function hideCursor() {
|
|
15
|
+
registerCursorCleanup();
|
|
16
|
+
process.stdout.write("\x1b[?25l");
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Show terminal cursor
|
|
20
|
+
*/
|
|
21
|
+
export function showCursor() {
|
|
22
|
+
process.stdout.write("\x1b[?25h");
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Format current time as HH:MM:SS
|
|
26
|
+
*/
|
|
27
|
+
export function formatTimestamp() {
|
|
28
|
+
const now = new Date();
|
|
29
|
+
return now.toLocaleTimeString("en-US", {
|
|
30
|
+
hour12: false,
|
|
31
|
+
hour: "2-digit",
|
|
32
|
+
minute: "2-digit",
|
|
33
|
+
second: "2-digit",
|
|
34
|
+
});
|
|
35
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { AllPerpMetasResponse, SpotMetaResponse } from "@nktkas/hyperliquid";
|
|
2
|
+
import { AllDexsAssetCtxsEvent, SpotAssetCtxsEvent } from "@nktkas/hyperliquid/api/subscription";
|
|
3
|
+
export interface ServerStatus {
|
|
4
|
+
running: boolean;
|
|
5
|
+
testnet: boolean;
|
|
6
|
+
connected: boolean;
|
|
7
|
+
startedAt: number;
|
|
8
|
+
uptime: number;
|
|
9
|
+
cache: {
|
|
10
|
+
hasMids: boolean;
|
|
11
|
+
hasAssetCtxs: boolean;
|
|
12
|
+
hasPerpMetas: boolean;
|
|
13
|
+
hasSpotMeta: boolean;
|
|
14
|
+
hasSpotAssetCtxs: boolean;
|
|
15
|
+
midsAge?: number;
|
|
16
|
+
assetCtxsAge?: number;
|
|
17
|
+
perpMetasAge?: number;
|
|
18
|
+
spotMetaAge?: number;
|
|
19
|
+
spotAssetCtxsAge?: number;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export declare class ServerClient {
|
|
23
|
+
private socket;
|
|
24
|
+
private requestId;
|
|
25
|
+
private pending;
|
|
26
|
+
private buffer;
|
|
27
|
+
connect(): Promise<void>;
|
|
28
|
+
private handleData;
|
|
29
|
+
private request;
|
|
30
|
+
getPrices(coin?: string): Promise<{
|
|
31
|
+
data: Record<string, string>;
|
|
32
|
+
cached_at: number;
|
|
33
|
+
}>;
|
|
34
|
+
getAssetCtxs(): Promise<{
|
|
35
|
+
data: AllDexsAssetCtxsEvent;
|
|
36
|
+
cached_at: number;
|
|
37
|
+
}>;
|
|
38
|
+
getPerpMeta(): Promise<{
|
|
39
|
+
data: AllPerpMetasResponse;
|
|
40
|
+
cached_at: number;
|
|
41
|
+
}>;
|
|
42
|
+
getSpotMeta(): Promise<{
|
|
43
|
+
data: SpotMetaResponse;
|
|
44
|
+
cached_at: number;
|
|
45
|
+
}>;
|
|
46
|
+
getSpotAssetCtxs(): Promise<{
|
|
47
|
+
data: SpotAssetCtxsEvent;
|
|
48
|
+
cached_at: number;
|
|
49
|
+
}>;
|
|
50
|
+
getStatus(): Promise<ServerStatus>;
|
|
51
|
+
shutdown(): Promise<void>;
|
|
52
|
+
close(): void;
|
|
53
|
+
}
|
|
54
|
+
export declare function isServerRunning(): boolean;
|
|
55
|
+
export declare function tryConnectToServer(): Promise<ServerClient | null>;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { connect } from "node:net";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { SERVER_SOCKET_PATH } from "../lib/paths.js";
|
|
4
|
+
const IPC_REQUEST_TIMEOUT_MS = 5_000;
|
|
5
|
+
export class ServerClient {
|
|
6
|
+
socket = null;
|
|
7
|
+
requestId = 0;
|
|
8
|
+
pending = new Map();
|
|
9
|
+
buffer = "";
|
|
10
|
+
async connect() {
|
|
11
|
+
if (this.socket)
|
|
12
|
+
return;
|
|
13
|
+
return new Promise((resolve, reject) => {
|
|
14
|
+
const socket = connect(SERVER_SOCKET_PATH);
|
|
15
|
+
socket.on("connect", () => {
|
|
16
|
+
this.socket = socket;
|
|
17
|
+
resolve();
|
|
18
|
+
});
|
|
19
|
+
socket.on("error", (err) => {
|
|
20
|
+
reject(err);
|
|
21
|
+
});
|
|
22
|
+
socket.on("data", (data) => {
|
|
23
|
+
this.handleData(data.toString());
|
|
24
|
+
});
|
|
25
|
+
socket.on("close", () => {
|
|
26
|
+
this.socket = null;
|
|
27
|
+
// Reject all pending requests
|
|
28
|
+
for (const pending of this.pending.values()) {
|
|
29
|
+
pending.reject(new Error("Connection closed"));
|
|
30
|
+
}
|
|
31
|
+
this.pending.clear();
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
handleData(data) {
|
|
36
|
+
this.buffer += data;
|
|
37
|
+
const lines = this.buffer.split("\n");
|
|
38
|
+
this.buffer = lines.pop() || "";
|
|
39
|
+
for (const line of lines) {
|
|
40
|
+
if (line.trim()) {
|
|
41
|
+
try {
|
|
42
|
+
const response = JSON.parse(line);
|
|
43
|
+
const pending = this.pending.get(response.id);
|
|
44
|
+
if (pending) {
|
|
45
|
+
this.pending.delete(response.id);
|
|
46
|
+
pending.resolve(response);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// Ignore parse errors
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async request(method, params) {
|
|
56
|
+
if (!this.socket) {
|
|
57
|
+
throw new Error("Not connected");
|
|
58
|
+
}
|
|
59
|
+
const id = String(++this.requestId);
|
|
60
|
+
const request = { id, method, params };
|
|
61
|
+
const socket = this.socket;
|
|
62
|
+
if (!socket) {
|
|
63
|
+
throw new Error("Not connected");
|
|
64
|
+
}
|
|
65
|
+
return new Promise((resolve, reject) => {
|
|
66
|
+
const timeoutId = setTimeout(() => {
|
|
67
|
+
if (this.pending.has(id)) {
|
|
68
|
+
this.pending.delete(id);
|
|
69
|
+
reject(new Error("Request timeout"));
|
|
70
|
+
}
|
|
71
|
+
}, IPC_REQUEST_TIMEOUT_MS);
|
|
72
|
+
this.pending.set(id, {
|
|
73
|
+
resolve: (value) => {
|
|
74
|
+
clearTimeout(timeoutId);
|
|
75
|
+
resolve(value);
|
|
76
|
+
},
|
|
77
|
+
reject: (err) => {
|
|
78
|
+
clearTimeout(timeoutId);
|
|
79
|
+
reject(err);
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
socket.write(JSON.stringify(request) + "\n");
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
async getPrices(coin) {
|
|
86
|
+
const response = await this.request("getPrices", coin ? { coin } : undefined);
|
|
87
|
+
if (response.error) {
|
|
88
|
+
throw new Error(response.error);
|
|
89
|
+
}
|
|
90
|
+
return { data: response.result, cached_at: response.cached_at };
|
|
91
|
+
}
|
|
92
|
+
async getAssetCtxs() {
|
|
93
|
+
const response = await this.request("getAssetCtxs");
|
|
94
|
+
if (response.error) {
|
|
95
|
+
throw new Error(response.error);
|
|
96
|
+
}
|
|
97
|
+
return { data: response.result, cached_at: response.cached_at };
|
|
98
|
+
}
|
|
99
|
+
async getPerpMeta() {
|
|
100
|
+
const response = await this.request("getPerpMeta");
|
|
101
|
+
if (response.error) {
|
|
102
|
+
throw new Error(response.error);
|
|
103
|
+
}
|
|
104
|
+
return { data: response.result, cached_at: response.cached_at };
|
|
105
|
+
}
|
|
106
|
+
async getSpotMeta() {
|
|
107
|
+
const response = await this.request("getSpotMeta");
|
|
108
|
+
if (response.error) {
|
|
109
|
+
throw new Error(response.error);
|
|
110
|
+
}
|
|
111
|
+
return { data: response.result, cached_at: response.cached_at };
|
|
112
|
+
}
|
|
113
|
+
async getSpotAssetCtxs() {
|
|
114
|
+
const response = await this.request("getSpotAssetCtxs");
|
|
115
|
+
if (response.error) {
|
|
116
|
+
throw new Error(response.error);
|
|
117
|
+
}
|
|
118
|
+
return { data: response.result, cached_at: response.cached_at };
|
|
119
|
+
}
|
|
120
|
+
async getStatus() {
|
|
121
|
+
const response = await this.request("getStatus");
|
|
122
|
+
if (response.error) {
|
|
123
|
+
throw new Error(response.error);
|
|
124
|
+
}
|
|
125
|
+
return response.result;
|
|
126
|
+
}
|
|
127
|
+
async shutdown() {
|
|
128
|
+
const response = await this.request("shutdown");
|
|
129
|
+
if (response.error) {
|
|
130
|
+
throw new Error(response.error);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
close() {
|
|
134
|
+
if (this.socket) {
|
|
135
|
+
this.socket.destroy();
|
|
136
|
+
this.socket = null;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// Helper to check if server is running
|
|
141
|
+
export function isServerRunning() {
|
|
142
|
+
return existsSync(SERVER_SOCKET_PATH);
|
|
143
|
+
}
|
|
144
|
+
// Helper to try connecting to server
|
|
145
|
+
export async function tryConnectToServer() {
|
|
146
|
+
if (!isServerRunning()) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
const client = new ServerClient();
|
|
151
|
+
await client.connect();
|
|
152
|
+
return client;
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
}
|