perp-cli 0.11.0 → 0.12.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 +30 -25
- package/dist/_stderr-filter.d.ts +0 -0
- package/dist/_stderr-filter.js +30 -0
- package/dist/agent-wallet/expiry.d.ts +15 -0
- package/dist/agent-wallet/expiry.js +26 -0
- package/dist/agent-wallet/lighter-keystore.d.ts +34 -0
- package/dist/agent-wallet/lighter-keystore.js +232 -0
- package/dist/agent-wallet/passphrase.d.ts +13 -0
- package/dist/agent-wallet/passphrase.js +54 -0
- package/dist/agent-wallet/signing-strategy.d.ts +67 -0
- package/dist/agent-wallet/signing-strategy.js +51 -0
- package/dist/agent-wallet/store.d.ts +37 -0
- package/dist/agent-wallet/store.js +172 -0
- package/dist/api/public/_http.d.ts +15 -0
- package/dist/api/public/_http.js +24 -0
- package/dist/api/public/hyperliquid.js +36 -24
- package/dist/api/public/lighter.d.ts +7 -1
- package/dist/api/public/lighter.js +85 -37
- package/dist/api/public/pacifica.js +47 -18
- package/dist/bridge-engine.js +102 -49
- package/dist/cli-spec.js +1 -2
- package/dist/commands/account.js +2 -500
- package/dist/commands/agent.d.ts +8 -2
- package/dist/commands/agent.js +1903 -366
- package/dist/commands/alerts.js +3 -1
- package/dist/commands/arb/index.js +37 -7
- package/dist/commands/arb-auto.js +44 -11
- package/dist/commands/arb.js +83 -34
- package/dist/commands/bot.d.ts +1 -1
- package/dist/commands/bot.js +18 -14
- package/dist/commands/bridge.d.ts +1 -1
- package/dist/commands/bridge.js +4 -4
- package/dist/commands/funds.d.ts +1 -1
- package/dist/commands/funds.js +18 -68
- package/dist/commands/jobs.d.ts +1 -1
- package/dist/commands/jobs.js +2 -2
- package/dist/commands/manage.d.ts +1 -1
- package/dist/commands/manage.js +12 -84
- package/dist/commands/plan.d.ts +1 -1
- package/dist/commands/plan.js +2 -2
- package/dist/commands/portfolio.d.ts +19 -3
- package/dist/commands/portfolio.js +747 -163
- package/dist/commands/rebalance.d.ts +1 -1
- package/dist/commands/rebalance.js +18 -12
- package/dist/commands/risk.js +2 -6
- package/dist/commands/settings.js +30 -53
- package/dist/commands/trade.js +16 -15
- package/dist/commands/wallet.d.ts +2 -1
- package/dist/commands/wallet.js +756 -28
- package/dist/errors.d.ts +64 -0
- package/dist/errors.js +82 -2
- package/dist/event-stream.js +12 -1
- package/dist/exchanges/aster-typed-data.d.ts +156 -0
- package/dist/exchanges/aster-typed-data.js +189 -0
- package/dist/exchanges/aster.d.ts +60 -11
- package/dist/exchanges/aster.js +278 -136
- package/dist/exchanges/hyperliquid.d.ts +14 -0
- package/dist/exchanges/hyperliquid.js +84 -34
- package/dist/exchanges/lighter-spot.js +14 -3
- package/dist/exchanges/lighter.d.ts +66 -0
- package/dist/exchanges/lighter.js +199 -27
- package/dist/exchanges/pacifica-typed-data.d.ts +75 -0
- package/dist/exchanges/pacifica-typed-data.js +74 -0
- package/dist/exchanges/pacifica.d.ts +29 -1
- package/dist/exchanges/pacifica.js +94 -6
- package/dist/funding/rates.js +59 -21
- package/dist/guardrail/perp-guardrail.js +9 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +255 -360
- package/dist/jobs.js +3 -1
- package/dist/mcp-server.js +85 -83
- package/dist/position-history.js +47 -4
- package/dist/settings.d.ts +67 -3
- package/dist/settings.js +1 -2
- package/dist/signer/ows-evm.d.ts +14 -0
- package/dist/signer/ows-evm.js +28 -9
- package/dist/smart-order.d.ts +8 -2
- package/dist/smart-order.js +46 -11
- package/dist/strategies/funding-arb.js +29 -8
- package/dist/trade-validator.js +30 -5
- package/dist/utils.d.ts +10 -0
- package/dist/utils.js +19 -0
- package/package.json +2 -2
- package/skills/perp-cli/SKILL.md +23 -14
- package/skills/perp-cli/references/agent-operations.md +6 -4
- package/skills/perp-cli/references/commands.md +55 -34
- package/skills/perp-cli/scripts/preflight.sh +4 -4
- package/skills/perp-cli/scripts/spot-perp-scan.sh +2 -2
- package/dist/__tests__/alert-logic.test.d.ts +0 -1
- package/dist/__tests__/alert-logic.test.js +0 -107
- package/dist/__tests__/arb-auto-3dex.test.d.ts +0 -1
- package/dist/__tests__/arb-auto-3dex.test.js +0 -397
- package/dist/__tests__/arb-history-stats.test.d.ts +0 -1
- package/dist/__tests__/arb-history-stats.test.js +0 -176
- package/dist/__tests__/arb-logic.test.d.ts +0 -1
- package/dist/__tests__/arb-logic.test.js +0 -84
- package/dist/__tests__/arb-manage.test.d.ts +0 -1
- package/dist/__tests__/arb-manage.test.js +0 -253
- package/dist/__tests__/arb-new-features.test.d.ts +0 -1
- package/dist/__tests__/arb-new-features.test.js +0 -457
- package/dist/__tests__/arb-sizing.test.d.ts +0 -1
- package/dist/__tests__/arb-sizing.test.js +0 -48
- package/dist/__tests__/arb-state.test.d.ts +0 -1
- package/dist/__tests__/arb-state.test.js +0 -284
- package/dist/__tests__/arb-userflow.test.d.ts +0 -1
- package/dist/__tests__/arb-userflow.test.js +0 -945
- package/dist/__tests__/arb-utils.test.d.ts +0 -1
- package/dist/__tests__/arb-utils.test.js +0 -264
- package/dist/__tests__/bot-conditions.test.d.ts +0 -1
- package/dist/__tests__/bot-conditions.test.js +0 -341
- package/dist/__tests__/client-id-tracker.test.d.ts +0 -1
- package/dist/__tests__/client-id-tracker.test.js +0 -137
- package/dist/__tests__/commands/new-atomic-commands.test.d.ts +0 -1
- package/dist/__tests__/commands/new-atomic-commands.test.js +0 -502
- package/dist/__tests__/commands/order-intent.test.d.ts +0 -1
- package/dist/__tests__/commands/order-intent.test.js +0 -600
- package/dist/__tests__/commands/trade-commands.test.d.ts +0 -1
- package/dist/__tests__/commands/trade-commands.test.js +0 -821
- package/dist/__tests__/config.test.d.ts +0 -1
- package/dist/__tests__/config.test.js +0 -86
- package/dist/__tests__/cross-chain-margin.test.d.ts +0 -1
- package/dist/__tests__/cross-chain-margin.test.js +0 -287
- package/dist/__tests__/dex-asset-map.test.d.ts +0 -1
- package/dist/__tests__/dex-asset-map.test.js +0 -191
- package/dist/__tests__/errors.test.d.ts +0 -1
- package/dist/__tests__/errors.test.js +0 -110
- package/dist/__tests__/event-stream.test.d.ts +0 -1
- package/dist/__tests__/event-stream.test.js +0 -276
- package/dist/__tests__/exchanges/interface.test.d.ts +0 -1
- package/dist/__tests__/exchanges/interface.test.js +0 -132
- package/dist/__tests__/exchanges/mock-adapter.d.ts +0 -69
- package/dist/__tests__/exchanges/mock-adapter.js +0 -137
- package/dist/__tests__/execution-log.test.d.ts +0 -1
- package/dist/__tests__/execution-log.test.js +0 -106
- package/dist/__tests__/funding-calc.test.d.ts +0 -1
- package/dist/__tests__/funding-calc.test.js +0 -71
- package/dist/__tests__/funding-history.test.d.ts +0 -1
- package/dist/__tests__/funding-history.test.js +0 -343
- package/dist/__tests__/funding-rates.test.d.ts +0 -1
- package/dist/__tests__/funding-rates.test.js +0 -342
- package/dist/__tests__/funding.test.d.ts +0 -1
- package/dist/__tests__/funding.test.js +0 -173
- package/dist/__tests__/gap-logic.test.d.ts +0 -1
- package/dist/__tests__/gap-logic.test.js +0 -43
- package/dist/__tests__/hip3-dex.test.d.ts +0 -1
- package/dist/__tests__/hip3-dex.test.js +0 -234
- package/dist/__tests__/integration/agent-features.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/agent-features.integration.test.js +0 -553
- package/dist/__tests__/integration/atomic-commands.integration.test.d.ts +0 -13
- package/dist/__tests__/integration/atomic-commands.integration.test.js +0 -246
- package/dist/__tests__/integration/bridge-simulation.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/bridge-simulation.integration.test.js +0 -453
- package/dist/__tests__/integration/bridge-strict.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/bridge-strict.integration.test.js +0 -812
- package/dist/__tests__/integration/bridge.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/bridge.integration.test.js +0 -309
- package/dist/__tests__/integration/cli-e2e.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/cli-e2e.integration.test.js +0 -202
- package/dist/__tests__/integration/dex-arb.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/dex-arb.integration.test.js +0 -116
- package/dist/__tests__/integration/envelope-consistency.integration.test.d.ts +0 -13
- package/dist/__tests__/integration/envelope-consistency.integration.test.js +0 -205
- package/dist/__tests__/integration/hip3-dex.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/hip3-dex.integration.test.js +0 -147
- package/dist/__tests__/integration/hyperliquid.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/hyperliquid.integration.test.js +0 -79
- package/dist/__tests__/integration/lighter.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/lighter.integration.test.js +0 -53
- package/dist/__tests__/integration/new-commands-e2e.integration.test.d.ts +0 -9
- package/dist/__tests__/integration/new-commands-e2e.integration.test.js +0 -236
- package/dist/__tests__/integration/order-verification.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/order-verification.integration.test.js +0 -321
- package/dist/__tests__/integration/pacifica.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/pacifica.integration.test.js +0 -75
- package/dist/__tests__/integration/response-shapes.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/response-shapes.integration.test.js +0 -278
- package/dist/__tests__/liquidity.test.d.ts +0 -1
- package/dist/__tests__/liquidity.test.js +0 -225
- package/dist/__tests__/plan-executor.test.d.ts +0 -1
- package/dist/__tests__/plan-executor.test.js +0 -314
- package/dist/__tests__/position-history.test.d.ts +0 -1
- package/dist/__tests__/position-history.test.js +0 -367
- package/dist/__tests__/retry.test.d.ts +0 -1
- package/dist/__tests__/retry.test.js +0 -310
- package/dist/__tests__/risk-assessment.test.d.ts +0 -1
- package/dist/__tests__/risk-assessment.test.js +0 -288
- package/dist/__tests__/security-adversarial.test.d.ts +0 -1
- package/dist/__tests__/security-adversarial.test.js +0 -574
- package/dist/__tests__/strategies.test.d.ts +0 -1
- package/dist/__tests__/strategies.test.js +0 -539
- package/dist/__tests__/trade-execution.test.d.ts +0 -1
- package/dist/__tests__/trade-execution.test.js +0 -129
- package/dist/__tests__/trade-validator.test.d.ts +0 -1
- package/dist/__tests__/trade-validator.test.js +0 -655
- package/dist/__tests__/utils.test.d.ts +0 -1
- package/dist/__tests__/utils.test.js +0 -76
- package/dist/arb/reconcile.d.ts +0 -28
- package/dist/arb/reconcile.js +0 -162
- package/dist/commands/alert.d.ts +0 -2
- package/dist/commands/alert.js +0 -421
- package/dist/commands/analytics.d.ts +0 -3
- package/dist/commands/analytics.js +0 -311
- package/dist/commands/arb-manage.d.ts +0 -5
- package/dist/commands/arb-manage.js +0 -5
- package/dist/commands/dashboard.d.ts +0 -3
- package/dist/commands/dashboard.js +0 -176
- package/dist/commands/deposit.d.ts +0 -4
- package/dist/commands/deposit.js +0 -573
- package/dist/commands/dex.d.ts +0 -3
- package/dist/commands/dex.js +0 -120
- package/dist/commands/env.d.ts +0 -2
- package/dist/commands/env.js +0 -136
- package/dist/commands/funding.d.ts +0 -3
- package/dist/commands/funding.js +0 -554
- package/dist/commands/gap.d.ts +0 -2
- package/dist/commands/gap.js +0 -305
- package/dist/commands/health.d.ts +0 -2
- package/dist/commands/health.js +0 -67
- package/dist/commands/multileg.d.ts +0 -16
- package/dist/commands/multileg.js +0 -174
- package/dist/commands/ows.d.ts +0 -2
- package/dist/commands/ows.js +0 -887
- package/dist/commands/pnl.d.ts +0 -12
- package/dist/commands/pnl.js +0 -243
- package/dist/commands/run.d.ts +0 -3
- package/dist/commands/run.js +0 -202
- package/dist/commands/stream.d.ts +0 -5
- package/dist/commands/stream.js +0 -200
- package/dist/commands/withdraw.d.ts +0 -3
- package/dist/commands/withdraw.js +0 -187
- package/dist/exchanges/edgex.d.ts +0 -62
- package/dist/exchanges/edgex.js +0 -552
- package/dist/exchanges/nado.d.ts +0 -52
- package/dist/exchanges/nado.js +0 -223
- package/dist/funding/index.d.ts +0 -3
- package/dist/funding/index.js +0 -3
- package/dist/retry.d.ts +0 -74
- package/dist/retry.js +0 -129
- package/dist/ws/market-feed.d.ts +0 -74
- package/dist/ws/market-feed.js +0 -227
package/dist/exchanges/edgex.js
DELETED
|
@@ -1,552 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* edgeX DEX adapter — StarkEx-based perpetual futures exchange.
|
|
3
|
-
* Base: https://pro.edgex.exchange
|
|
4
|
-
*/
|
|
5
|
-
import { randomBytes } from "node:crypto";
|
|
6
|
-
import { keccak_256 } from "@noble/hashes/sha3.js";
|
|
7
|
-
import { pedersen, Point } from "@scure/starknet";
|
|
8
|
-
// ── StarkEx ECDSA helpers ──
|
|
9
|
-
const EC_ORDER = Point.Fn.ORDER;
|
|
10
|
-
const MAX_STARK_VALUE = 1n << 251n;
|
|
11
|
-
const LIMIT_ORDER_WITH_FEES = 3n;
|
|
12
|
-
const ONE_HOUR_MS = 3_600_000;
|
|
13
|
-
const ORDER_EXPIRY_HOURS = 4320; // ~180 days
|
|
14
|
-
function bytesToBigInt(bytes) {
|
|
15
|
-
let result = 0n;
|
|
16
|
-
for (const b of bytes)
|
|
17
|
-
result = (result << 8n) | BigInt(b);
|
|
18
|
-
return result;
|
|
19
|
-
}
|
|
20
|
-
function starkEcdsaSign(msgHash, privKey) {
|
|
21
|
-
const Fn = Point.Fn;
|
|
22
|
-
for (let attempt = 0; attempt < 256; attempt++) {
|
|
23
|
-
const kBig = bytesToBigInt(randomBytes(32)) % EC_ORDER;
|
|
24
|
-
if (kBig === 0n)
|
|
25
|
-
continue;
|
|
26
|
-
const R = Point.BASE.multiply(kBig);
|
|
27
|
-
const r = R.x;
|
|
28
|
-
if (r === 0n || r >= MAX_STARK_VALUE)
|
|
29
|
-
continue;
|
|
30
|
-
const sum = (msgHash + (r * privKey) % EC_ORDER) % EC_ORDER;
|
|
31
|
-
if (sum === 0n)
|
|
32
|
-
continue;
|
|
33
|
-
const w = (kBig * Fn.inv(sum)) % EC_ORDER;
|
|
34
|
-
if (w === 0n || w >= MAX_STARK_VALUE)
|
|
35
|
-
continue;
|
|
36
|
-
const s = Fn.inv(w);
|
|
37
|
-
return { r, s };
|
|
38
|
-
}
|
|
39
|
-
throw new Error("Failed to generate valid StarkEx ECDSA signature");
|
|
40
|
-
}
|
|
41
|
-
function serializeValue(value) {
|
|
42
|
-
if (value === null || value === undefined)
|
|
43
|
-
return "";
|
|
44
|
-
if (typeof value === "boolean")
|
|
45
|
-
return value ? "true" : "false";
|
|
46
|
-
if (typeof value === "number" || typeof value === "bigint")
|
|
47
|
-
return String(value);
|
|
48
|
-
if (typeof value === "string")
|
|
49
|
-
return value;
|
|
50
|
-
if (Array.isArray(value)) {
|
|
51
|
-
if (value.length === 0)
|
|
52
|
-
return "";
|
|
53
|
-
return value.map((v) => serializeValue(v)).join("&");
|
|
54
|
-
}
|
|
55
|
-
if (typeof value === "object") {
|
|
56
|
-
return Object.keys(value)
|
|
57
|
-
.sort()
|
|
58
|
-
.filter((k) => value[k] !== undefined)
|
|
59
|
-
.map((k) => `${k}=${serializeValue(value[k])}`)
|
|
60
|
-
.join("&");
|
|
61
|
-
}
|
|
62
|
-
return String(value);
|
|
63
|
-
}
|
|
64
|
-
function buildSignContent(timestamp, method, path, params) {
|
|
65
|
-
const m = method.toUpperCase();
|
|
66
|
-
if (!params || Object.keys(params).length === 0)
|
|
67
|
-
return `${timestamp}${m}${path}`;
|
|
68
|
-
let paramStr;
|
|
69
|
-
if (m === "GET") {
|
|
70
|
-
paramStr = Object.keys(params).sort().map((k) => `${k}=${params[k]}`).join("&");
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
paramStr = serializeValue(params);
|
|
74
|
-
}
|
|
75
|
-
return `${timestamp}${m}${path}${paramStr}`;
|
|
76
|
-
}
|
|
77
|
-
// ── Adapter ──
|
|
78
|
-
export class EdgeXAdapter {
|
|
79
|
-
name = "edgex";
|
|
80
|
-
chain = "starkex";
|
|
81
|
-
aliases = ["ex"];
|
|
82
|
-
_accountId;
|
|
83
|
-
_starkPrivateKey;
|
|
84
|
-
_baseUrl = "https://pro.edgex.exchange";
|
|
85
|
-
_contracts = new Map();
|
|
86
|
-
_contractById = new Map();
|
|
87
|
-
_marketsCache = null;
|
|
88
|
-
static CACHE_TTL = 60_000; // 60s cache
|
|
89
|
-
constructor(accountId, starkPrivateKey) {
|
|
90
|
-
this._accountId = accountId || process.env.EDGEX_ACCOUNT_ID || "";
|
|
91
|
-
this._starkPrivateKey = starkPrivateKey || process.env.EDGEX_STARK_PRIVATE_KEY || "";
|
|
92
|
-
}
|
|
93
|
-
get isReadOnly() {
|
|
94
|
-
return !this._accountId || !this._starkPrivateKey;
|
|
95
|
-
}
|
|
96
|
-
/** CLI symbol -> API symbol: ETH -> ETHUSD */
|
|
97
|
-
_toApi(symbol) {
|
|
98
|
-
const s = symbol.toUpperCase().replace(/-PERP$/, "");
|
|
99
|
-
if (s.endsWith("USD") || s.endsWith("2USD"))
|
|
100
|
-
return s;
|
|
101
|
-
// Try exact USD suffix first, then 2USD (edgeX uses BNB2USD, XRP2USD, etc.)
|
|
102
|
-
if (this._contracts.has(`${s}USD`))
|
|
103
|
-
return `${s}USD`;
|
|
104
|
-
if (this._contracts.has(`${s}2USD`))
|
|
105
|
-
return `${s}2USD`;
|
|
106
|
-
return `${s}USD`;
|
|
107
|
-
}
|
|
108
|
-
/** API symbol -> CLI symbol: ETHUSD -> ETH, DOGE2USD -> DOGE2 */
|
|
109
|
-
_fromApi(symbol) {
|
|
110
|
-
// BNB2USD → BNB, XRP2USD → XRP, BTCUSD → BTC, 1000PEPE2USD → 1000PEPE
|
|
111
|
-
return symbol.replace(/2USD$/, "").replace(/USD$/, "");
|
|
112
|
-
}
|
|
113
|
-
_getContract(symbol) {
|
|
114
|
-
const apiSym = this._toApi(symbol);
|
|
115
|
-
const c = this._contracts.get(apiSym);
|
|
116
|
-
if (!c)
|
|
117
|
-
throw new Error(`Unknown edgeX contract: ${symbol} (${apiSym})`);
|
|
118
|
-
return c;
|
|
119
|
-
}
|
|
120
|
-
// ── Init ──
|
|
121
|
-
async init() {
|
|
122
|
-
const res = (await this._publicGet("/api/v1/public/meta/getMetaData"));
|
|
123
|
-
const contracts = res?.contractList ?? [];
|
|
124
|
-
for (const c of contracts) {
|
|
125
|
-
const symbol = String(c.contractName ?? "");
|
|
126
|
-
const meta = {
|
|
127
|
-
contractId: String(c.contractId ?? ""),
|
|
128
|
-
symbol,
|
|
129
|
-
tickSize: String(c.tickSize ?? "0.01"),
|
|
130
|
-
stepSize: String(c.stepSize ?? "0.001"),
|
|
131
|
-
starkExSyntheticAssetId: String(c.starkExSyntheticAssetId ?? ""),
|
|
132
|
-
starkExResolution: String(c.starkExResolution ?? ""),
|
|
133
|
-
starkExCollateralAssetId: String(c.starkExCollateralAssetId ?? ""),
|
|
134
|
-
starkExCollateralResolution: String(c.starkExCollateralResolution ?? ""),
|
|
135
|
-
maxLeverage: Number(c.maxLeverage ?? 20),
|
|
136
|
-
};
|
|
137
|
-
this._contracts.set(symbol, meta);
|
|
138
|
-
this._contractById.set(meta.contractId, meta);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
// ── Market Data ──
|
|
142
|
-
async getMarkets() {
|
|
143
|
-
// Return cached data if fresh
|
|
144
|
-
if (this._marketsCache && Date.now() - this._marketsCache.ts < EdgeXAdapter.CACHE_TTL) {
|
|
145
|
-
return this._marketsCache.data;
|
|
146
|
-
}
|
|
147
|
-
// edgeX requires contractId per ticker call (bulk returns empty).
|
|
148
|
-
// With auth headers, Cloudflare is bypassed — fetch top 30 contracts.
|
|
149
|
-
const allContracts = [...this._contractById.values()];
|
|
150
|
-
const TOP_COUNT = 30;
|
|
151
|
-
const topContracts = allContracts.slice(0, TOP_COUNT);
|
|
152
|
-
const results = [];
|
|
153
|
-
const BATCH = 10;
|
|
154
|
-
for (let i = 0; i < topContracts.length; i += BATCH) {
|
|
155
|
-
const batch = topContracts.slice(i, i + BATCH);
|
|
156
|
-
const settled = await Promise.allSettled(batch.map(async (c) => {
|
|
157
|
-
const [tArr, fArr] = await Promise.all([
|
|
158
|
-
this._publicGet("/api/v1/public/quote/getTicker", { contractId: c.contractId }),
|
|
159
|
-
this._publicGet("/api/v1/public/funding/getLatestFundingRate", { contractId: c.contractId }),
|
|
160
|
-
]);
|
|
161
|
-
const t = (Array.isArray(tArr) ? tArr[0] : null);
|
|
162
|
-
const f = (Array.isArray(fArr) ? fArr[0] : null);
|
|
163
|
-
return {
|
|
164
|
-
symbol: this._fromApi(c.symbol),
|
|
165
|
-
markPrice: String(t?.lastPrice ?? t?.oraclePrice ?? "0"),
|
|
166
|
-
indexPrice: String(t?.indexPrice ?? "0"),
|
|
167
|
-
fundingRate: String(f?.fundingRate ?? "0"),
|
|
168
|
-
volume24h: String(t?.value ?? "0"),
|
|
169
|
-
openInterest: String(t?.openInterest ?? "0"),
|
|
170
|
-
maxLeverage: c.maxLeverage,
|
|
171
|
-
};
|
|
172
|
-
}));
|
|
173
|
-
for (const r of settled) {
|
|
174
|
-
if (r.status === "fulfilled")
|
|
175
|
-
results.push(r.value);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
// Add remaining contracts with metadata only
|
|
179
|
-
const fetched = new Set(results.map(r => r.symbol));
|
|
180
|
-
for (const c of allContracts.slice(TOP_COUNT)) {
|
|
181
|
-
const sym = this._fromApi(c.symbol);
|
|
182
|
-
if (!fetched.has(sym)) {
|
|
183
|
-
results.push({ symbol: sym, markPrice: "0", indexPrice: "0", fundingRate: "0", volume24h: "0", openInterest: "0", maxLeverage: c.maxLeverage });
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
this._marketsCache = { data: results, ts: Date.now() };
|
|
187
|
-
return results;
|
|
188
|
-
}
|
|
189
|
-
async getOrderbook(symbol) {
|
|
190
|
-
const c = this._getContract(symbol);
|
|
191
|
-
const res = (await this._publicGet("/api/v1/public/quote/getDepth", {
|
|
192
|
-
contractId: c.contractId,
|
|
193
|
-
level: "15",
|
|
194
|
-
}));
|
|
195
|
-
const depth = Array.isArray(res) ? res[0] : res;
|
|
196
|
-
return {
|
|
197
|
-
bids: depth?.bids ?? [],
|
|
198
|
-
asks: depth?.asks ?? [],
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
async getRecentTrades(symbol, limit = 20) {
|
|
202
|
-
const c = this._getContract(symbol);
|
|
203
|
-
const res = (await this._publicGet("/api/v1/public/quote/getKline", {
|
|
204
|
-
contractId: c.contractId,
|
|
205
|
-
klineType: "1",
|
|
206
|
-
size: String(limit),
|
|
207
|
-
}));
|
|
208
|
-
return (res ?? []).map((k) => ({
|
|
209
|
-
time: Number(k.time ?? 0),
|
|
210
|
-
symbol: this._fromApi(c.symbol),
|
|
211
|
-
side: "buy",
|
|
212
|
-
price: String(k.close ?? "0"),
|
|
213
|
-
size: String(k.volume ?? "0"),
|
|
214
|
-
fee: "0",
|
|
215
|
-
}));
|
|
216
|
-
}
|
|
217
|
-
async getFundingHistory(symbol, _limit = 10) {
|
|
218
|
-
const c = this._getContract(symbol);
|
|
219
|
-
const res = (await this._publicGet("/api/v1/public/funding/getLatestFundingRate"));
|
|
220
|
-
return (res ?? [])
|
|
221
|
-
.filter((f) => String(f.contractId) === c.contractId)
|
|
222
|
-
.map((f) => ({
|
|
223
|
-
time: Number(f.fundingTime ?? Date.now()),
|
|
224
|
-
rate: String(f.fundingRate ?? "0"),
|
|
225
|
-
price: f.price ? String(f.price) : null,
|
|
226
|
-
}));
|
|
227
|
-
}
|
|
228
|
-
async getKlines(symbol, _interval, _startTime, _endTime) {
|
|
229
|
-
const c = this._getContract(symbol);
|
|
230
|
-
const klineTypeMap = {
|
|
231
|
-
"1m": "1", "5m": "5", "15m": "15", "30m": "30",
|
|
232
|
-
"1h": "60", "4h": "240", "1d": "1440",
|
|
233
|
-
};
|
|
234
|
-
const klineType = klineTypeMap[_interval] ?? "60";
|
|
235
|
-
const res = (await this._publicGet("/api/v1/public/quote/getKline", {
|
|
236
|
-
contractId: c.contractId,
|
|
237
|
-
klineType,
|
|
238
|
-
size: "100",
|
|
239
|
-
}));
|
|
240
|
-
return (res ?? []).map((k) => ({
|
|
241
|
-
time: Number(k.time ?? 0),
|
|
242
|
-
open: String(k.open ?? "0"),
|
|
243
|
-
high: String(k.high ?? "0"),
|
|
244
|
-
low: String(k.low ?? "0"),
|
|
245
|
-
close: String(k.close ?? "0"),
|
|
246
|
-
volume: String(k.volume ?? "0"),
|
|
247
|
-
trades: 0,
|
|
248
|
-
}));
|
|
249
|
-
}
|
|
250
|
-
// ── Account ──
|
|
251
|
-
async getBalance() {
|
|
252
|
-
const res = (await this._authGet("/api/v1/private/account/getAccountAsset", {
|
|
253
|
-
accountId: this._accountId,
|
|
254
|
-
}));
|
|
255
|
-
const d = res ?? {};
|
|
256
|
-
const collaterals = (d.collateralAssetModelList ?? []);
|
|
257
|
-
const usdt = collaterals.find((c) => String(c.coinId) === "1000") ?? {};
|
|
258
|
-
const totalEquity = String(d.totalEquity ?? usdt.equity ?? "0");
|
|
259
|
-
const available = String(d.available ?? usdt.available ?? "0");
|
|
260
|
-
const marginUsed = String(d.initialMargin ?? "0");
|
|
261
|
-
const unrealizedPnl = String(d.unrealizedPnl ?? "0");
|
|
262
|
-
return { equity: totalEquity, available, marginUsed, unrealizedPnl };
|
|
263
|
-
}
|
|
264
|
-
async getPositions() {
|
|
265
|
-
const res = (await this._authGet("/api/v1/private/account/getAccountAsset", {
|
|
266
|
-
accountId: this._accountId,
|
|
267
|
-
}));
|
|
268
|
-
const positions = res?.positionList ?? [];
|
|
269
|
-
const posAssets = res?.positionAssetList ?? [];
|
|
270
|
-
const assetMap = new Map();
|
|
271
|
-
for (const pa of posAssets)
|
|
272
|
-
assetMap.set(String(pa.contractId ?? ""), pa);
|
|
273
|
-
return positions
|
|
274
|
-
.filter((p) => Number(p.size ?? 0) !== 0)
|
|
275
|
-
.map((p) => {
|
|
276
|
-
const contractId = String(p.contractId ?? "");
|
|
277
|
-
const meta = this._contractById.get(contractId);
|
|
278
|
-
const pa = assetMap.get(contractId) ?? {};
|
|
279
|
-
const size = Math.abs(Number(p.size ?? 0));
|
|
280
|
-
const side = String(p.side ?? "").toUpperCase() === "SHORT" ? "short" : "long";
|
|
281
|
-
return {
|
|
282
|
-
symbol: this._fromApi(meta?.symbol ?? ""),
|
|
283
|
-
side,
|
|
284
|
-
size: String(size),
|
|
285
|
-
entryPrice: String(p.entryPrice ?? "0"),
|
|
286
|
-
markPrice: String(p.markPrice ?? pa.markPrice ?? "0"),
|
|
287
|
-
liquidationPrice: String(p.liquidationPrice ?? "0"),
|
|
288
|
-
unrealizedPnl: String(p.unrealizedPnl ?? pa.unrealizedPnl ?? "0"),
|
|
289
|
-
leverage: Number(p.leverage ?? 1),
|
|
290
|
-
};
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
|
-
async getOpenOrders() {
|
|
294
|
-
const res = (await this._authGet("/api/v1/private/order/getActiveOrderPage", {
|
|
295
|
-
accountId: this._accountId,
|
|
296
|
-
size: "200",
|
|
297
|
-
}));
|
|
298
|
-
return (res?.dataList ?? []).map((o) => ({
|
|
299
|
-
orderId: String(o.orderId ?? ""),
|
|
300
|
-
symbol: this._fromApi(this._contractById.get(String(o.contractId ?? ""))?.symbol ?? ""),
|
|
301
|
-
side: String(o.side ?? "").toLowerCase(),
|
|
302
|
-
price: String(o.price ?? "0"),
|
|
303
|
-
size: String(o.size ?? "0"),
|
|
304
|
-
filled: String(o.filledSize ?? "0"),
|
|
305
|
-
status: String(o.status ?? ""),
|
|
306
|
-
type: String(o.type ?? ""),
|
|
307
|
-
}));
|
|
308
|
-
}
|
|
309
|
-
async getOrderHistory(_limit = 30) {
|
|
310
|
-
// edgeX doesn't have a dedicated history endpoint easily; return open orders as fallback
|
|
311
|
-
return this.getOpenOrders();
|
|
312
|
-
}
|
|
313
|
-
async getTradeHistory(_limit = 30) {
|
|
314
|
-
return [];
|
|
315
|
-
}
|
|
316
|
-
async getFundingPayments(_limit = 200) {
|
|
317
|
-
return [];
|
|
318
|
-
}
|
|
319
|
-
// ── Trading ──
|
|
320
|
-
async marketOrder(symbol, side, size) {
|
|
321
|
-
const c = this._getContract(symbol);
|
|
322
|
-
// Fetch oracle price for L2 fields
|
|
323
|
-
const ticker = (await this._publicGet("/api/v1/public/quote/getTicker", {
|
|
324
|
-
contractId: c.contractId,
|
|
325
|
-
}));
|
|
326
|
-
const oraclePrice = String(ticker?.data?.oraclePrice ?? ticker?.data?.lastPrice ?? "0");
|
|
327
|
-
const worstPrice = side === "buy"
|
|
328
|
-
? String(Number(oraclePrice) * 1.05)
|
|
329
|
-
: String(Number(oraclePrice) * 0.95);
|
|
330
|
-
const l2Fields = this._computeL2OrderFields(c, side, worstPrice, size);
|
|
331
|
-
return this._authPost("/api/v1/private/order/createOrder", {
|
|
332
|
-
accountId: this._accountId,
|
|
333
|
-
contractId: c.contractId,
|
|
334
|
-
side: side.toUpperCase(),
|
|
335
|
-
type: "MARKET",
|
|
336
|
-
size,
|
|
337
|
-
price: worstPrice,
|
|
338
|
-
timeInForce: "IMMEDIATE_OR_CANCEL",
|
|
339
|
-
...l2Fields,
|
|
340
|
-
});
|
|
341
|
-
}
|
|
342
|
-
async limitOrder(symbol, side, price, size, opts) {
|
|
343
|
-
const c = this._getContract(symbol);
|
|
344
|
-
const l2Fields = this._computeL2OrderFields(c, side, price, size);
|
|
345
|
-
return this._authPost("/api/v1/private/order/createOrder", {
|
|
346
|
-
accountId: this._accountId,
|
|
347
|
-
contractId: c.contractId,
|
|
348
|
-
side: side.toUpperCase(),
|
|
349
|
-
type: "LIMIT",
|
|
350
|
-
size,
|
|
351
|
-
price,
|
|
352
|
-
timeInForce: opts?.tif?.toUpperCase() || "GOOD_TIL_CANCEL",
|
|
353
|
-
reduceOnly: opts?.reduceOnly ? true : undefined,
|
|
354
|
-
...l2Fields,
|
|
355
|
-
});
|
|
356
|
-
}
|
|
357
|
-
async editOrder(symbol, orderId, price, size) {
|
|
358
|
-
const openOrders = await this.getOpenOrders();
|
|
359
|
-
const existing = openOrders.find((o) => o.orderId === orderId);
|
|
360
|
-
const side = existing?.side ?? "buy";
|
|
361
|
-
await this.cancelOrder(symbol, orderId);
|
|
362
|
-
return this.limitOrder(symbol, side, price, size);
|
|
363
|
-
}
|
|
364
|
-
async cancelOrder(_symbol, orderId) {
|
|
365
|
-
return this._authPost("/api/v1/private/order/cancelOrderById", {
|
|
366
|
-
accountId: this._accountId,
|
|
367
|
-
orderIdList: [orderId],
|
|
368
|
-
});
|
|
369
|
-
}
|
|
370
|
-
async cancelAllOrders(symbol) {
|
|
371
|
-
const body = { accountId: this._accountId };
|
|
372
|
-
if (symbol) {
|
|
373
|
-
const c = this._getContract(symbol);
|
|
374
|
-
body.contractId = c.contractId;
|
|
375
|
-
}
|
|
376
|
-
return this._authPost("/api/v1/private/order/cancelAllOrder", body);
|
|
377
|
-
}
|
|
378
|
-
// ── Risk ──
|
|
379
|
-
async setLeverage(symbol, leverage, _marginMode) {
|
|
380
|
-
const c = this._getContract(symbol);
|
|
381
|
-
return this._authPost("/api/v1/private/account/updateLeverageSetting", {
|
|
382
|
-
accountId: this._accountId,
|
|
383
|
-
contractId: c.contractId,
|
|
384
|
-
leverage: String(leverage),
|
|
385
|
-
});
|
|
386
|
-
}
|
|
387
|
-
async stopOrder(symbol, side, size, triggerPrice, opts) {
|
|
388
|
-
const c = this._getContract(symbol);
|
|
389
|
-
const price = opts?.limitPrice ?? triggerPrice;
|
|
390
|
-
const l2Fields = this._computeL2OrderFields(c, side, price, size);
|
|
391
|
-
return this._authPost("/api/v1/private/order/createOrder", {
|
|
392
|
-
accountId: this._accountId,
|
|
393
|
-
contractId: c.contractId,
|
|
394
|
-
side: side.toUpperCase(),
|
|
395
|
-
type: opts?.limitPrice ? "STOP_LIMIT" : "STOP_MARKET",
|
|
396
|
-
size,
|
|
397
|
-
price,
|
|
398
|
-
triggerPrice,
|
|
399
|
-
timeInForce: "GOOD_TIL_CANCEL",
|
|
400
|
-
reduceOnly: opts?.reduceOnly ? true : undefined,
|
|
401
|
-
...l2Fields,
|
|
402
|
-
});
|
|
403
|
-
}
|
|
404
|
-
async withdraw(_amount, _destination) {
|
|
405
|
-
throw new Error("edgeX withdrawal not supported via API. Use the edgeX web UI.");
|
|
406
|
-
}
|
|
407
|
-
// ── L2 Order Signing (Pedersen hash chain + StarkEx ECDSA) ──
|
|
408
|
-
_computeL2OrderFields(contract, side, price, size) {
|
|
409
|
-
const syntheticResolution = BigInt(contract.starkExResolution || "1");
|
|
410
|
-
const collateralResolution = BigInt(contract.starkExCollateralResolution || "1");
|
|
411
|
-
const syntheticAssetId = contract.starkExSyntheticAssetId;
|
|
412
|
-
const collateralAssetId = contract.starkExCollateralAssetId;
|
|
413
|
-
const sizeNum = Math.abs(parseFloat(size));
|
|
414
|
-
const priceNum = parseFloat(price);
|
|
415
|
-
const quantumsAmountSynthetic = BigInt(Math.round(sizeNum * Number(syntheticResolution)));
|
|
416
|
-
const quantumsAmountCollateral = BigInt(Math.round(sizeNum * priceNum * Number(collateralResolution)));
|
|
417
|
-
const quantumsAmountFee = quantumsAmountCollateral / 1000n; // 0.1% fee cap
|
|
418
|
-
const nonce = BigInt("0x" + randomBytes(4).toString("hex"));
|
|
419
|
-
const expirationTimestamp = BigInt(Math.floor((Date.now() + ORDER_EXPIRY_HOURS * ONE_HOUR_MS) / ONE_HOUR_MS));
|
|
420
|
-
let assetIdSell, assetIdBuy;
|
|
421
|
-
let quantumsSell, quantumsBuy;
|
|
422
|
-
if (side === "buy") {
|
|
423
|
-
assetIdSell = collateralAssetId;
|
|
424
|
-
assetIdBuy = syntheticAssetId;
|
|
425
|
-
quantumsSell = quantumsAmountCollateral;
|
|
426
|
-
quantumsBuy = quantumsAmountSynthetic;
|
|
427
|
-
}
|
|
428
|
-
else {
|
|
429
|
-
assetIdSell = syntheticAssetId;
|
|
430
|
-
assetIdBuy = collateralAssetId;
|
|
431
|
-
quantumsSell = quantumsAmountSynthetic;
|
|
432
|
-
quantumsBuy = quantumsAmountCollateral;
|
|
433
|
-
}
|
|
434
|
-
const feeAssetId = collateralAssetId;
|
|
435
|
-
// Pedersen hash chain: hash(hash(hash(assetIdSell, assetIdBuy), feeAssetId), packed)
|
|
436
|
-
const h0 = pedersen(BigInt(assetIdSell), BigInt(assetIdBuy));
|
|
437
|
-
const h1 = pedersen(BigInt(h0), BigInt(feeAssetId));
|
|
438
|
-
// Pack amounts: sell(63 bits) | buy(63 bits) | fee(63 bits) | nonce(32 bits)
|
|
439
|
-
const packed1 = (quantumsSell << 64n) | quantumsBuy;
|
|
440
|
-
const h2 = pedersen(BigInt(h1), packed1);
|
|
441
|
-
// Pack: LIMIT_ORDER_WITH_FEES | positionId(64) | positionId(64) | positionId(64) | expirationTimestamp(32) | nonce(32)
|
|
442
|
-
const positionId = BigInt(this._accountId || "0");
|
|
443
|
-
const packed2 = (LIMIT_ORDER_WITH_FEES << 192n) |
|
|
444
|
-
(positionId << 128n) |
|
|
445
|
-
(positionId << 64n) |
|
|
446
|
-
(positionId);
|
|
447
|
-
const packed2Full = (packed2 << 64n) | (expirationTimestamp << 32n) | nonce;
|
|
448
|
-
const h3Interim = pedersen(BigInt(h2), quantumsAmountFee);
|
|
449
|
-
const msgHash = BigInt(pedersen(h3Interim, packed2Full));
|
|
450
|
-
const privKeyRaw = this._starkPrivateKey.startsWith("0x")
|
|
451
|
-
? this._starkPrivateKey.slice(2)
|
|
452
|
-
: this._starkPrivateKey;
|
|
453
|
-
const privKeyBig = BigInt("0x" + privKeyRaw);
|
|
454
|
-
const { r, s } = starkEcdsaSign(msgHash % EC_ORDER, privKeyBig);
|
|
455
|
-
return {
|
|
456
|
-
l2Nonce: nonce.toString(),
|
|
457
|
-
l2ExpirationTimestamp: expirationTimestamp.toString(),
|
|
458
|
-
l2SignatureR: "0x" + r.toString(16).padStart(64, "0"),
|
|
459
|
-
l2SignatureS: "0x" + s.toString(16).padStart(64, "0"),
|
|
460
|
-
l2QuantumsAmountSynthetic: quantumsAmountSynthetic.toString(),
|
|
461
|
-
l2QuantumsAmountCollateral: quantumsAmountCollateral.toString(),
|
|
462
|
-
l2QuantumsAmountFee: quantumsAmountFee.toString(),
|
|
463
|
-
};
|
|
464
|
-
}
|
|
465
|
-
// ── Auth signing ──
|
|
466
|
-
_signRequest(method, path, params) {
|
|
467
|
-
const timestamp = String(Date.now());
|
|
468
|
-
const signContent = buildSignContent(timestamp, method, path, params);
|
|
469
|
-
const hashBytes = keccak_256(new TextEncoder().encode(signContent));
|
|
470
|
-
const msgHash = bytesToBigInt(hashBytes) % EC_ORDER;
|
|
471
|
-
const privKeyRaw = this._starkPrivateKey.startsWith("0x")
|
|
472
|
-
? this._starkPrivateKey.slice(2)
|
|
473
|
-
: this._starkPrivateKey;
|
|
474
|
-
const privKeyBig = BigInt("0x" + privKeyRaw);
|
|
475
|
-
const { r, s } = starkEcdsaSign(msgHash, privKeyBig);
|
|
476
|
-
return {
|
|
477
|
-
timestamp,
|
|
478
|
-
signature: r.toString(16).padStart(64, "0") +
|
|
479
|
-
s.toString(16).padStart(64, "0"),
|
|
480
|
-
};
|
|
481
|
-
}
|
|
482
|
-
// ── HTTP helpers ──
|
|
483
|
-
async _publicGet(path, params = {}) {
|
|
484
|
-
// If credentials available, use authenticated request to bypass Cloudflare
|
|
485
|
-
if (!this.isReadOnly) {
|
|
486
|
-
return this._authGet(path, params);
|
|
487
|
-
}
|
|
488
|
-
const qs = Object.entries(params)
|
|
489
|
-
.map(([k, v]) => `${k}=${encodeURIComponent(v)}`)
|
|
490
|
-
.join("&");
|
|
491
|
-
const url = `${this._baseUrl}${path}${qs ? `?${qs}` : ""}`;
|
|
492
|
-
const res = await fetch(url, {
|
|
493
|
-
headers: { "Accept": "application/json" },
|
|
494
|
-
});
|
|
495
|
-
if (!res.ok) {
|
|
496
|
-
const text = await res.text();
|
|
497
|
-
throw new Error(`GET ${path} failed (${res.status}): ${text.slice(0, 200)}`);
|
|
498
|
-
}
|
|
499
|
-
const json = (await res.json());
|
|
500
|
-
if (json.code && json.code !== "0" && json.code !== "SUCCESS") {
|
|
501
|
-
throw new Error(`${path}: ${json.msg ?? json.code}`);
|
|
502
|
-
}
|
|
503
|
-
return json.data;
|
|
504
|
-
}
|
|
505
|
-
async _authGet(path, params = {}) {
|
|
506
|
-
if (this.isReadOnly)
|
|
507
|
-
throw new Error("No credentials configured for edgeX. Set EDGEX_ACCOUNT_ID and EDGEX_STARK_PRIVATE_KEY.");
|
|
508
|
-
const { timestamp, signature } = this._signRequest("GET", path, params);
|
|
509
|
-
const qs = Object.entries(params)
|
|
510
|
-
.map(([k, v]) => `${k}=${encodeURIComponent(v)}`)
|
|
511
|
-
.join("&");
|
|
512
|
-
const url = `${this._baseUrl}${path}${qs ? `?${qs}` : ""}`;
|
|
513
|
-
const res = await fetch(url, {
|
|
514
|
-
headers: {
|
|
515
|
-
"X-edgeX-Api-Timestamp": timestamp,
|
|
516
|
-
"X-edgeX-Api-Signature": signature,
|
|
517
|
-
},
|
|
518
|
-
});
|
|
519
|
-
if (!res.ok) {
|
|
520
|
-
const text = await res.text();
|
|
521
|
-
throw new Error(`GET ${path} failed (${res.status}): ${text.slice(0, 200)}`);
|
|
522
|
-
}
|
|
523
|
-
const json = (await res.json());
|
|
524
|
-
if (json.code && json.code !== "0" && json.code !== "SUCCESS") {
|
|
525
|
-
throw new Error(`${path}: ${json.msg ?? json.code}`);
|
|
526
|
-
}
|
|
527
|
-
return json.data;
|
|
528
|
-
}
|
|
529
|
-
async _authPost(path, body) {
|
|
530
|
-
if (this.isReadOnly)
|
|
531
|
-
throw new Error("No credentials configured for edgeX. Set EDGEX_ACCOUNT_ID and EDGEX_STARK_PRIVATE_KEY.");
|
|
532
|
-
const { timestamp, signature } = this._signRequest("POST", path, body);
|
|
533
|
-
const res = await fetch(`${this._baseUrl}${path}`, {
|
|
534
|
-
method: "POST",
|
|
535
|
-
headers: {
|
|
536
|
-
"Content-Type": "application/json",
|
|
537
|
-
"X-edgeX-Api-Timestamp": timestamp,
|
|
538
|
-
"X-edgeX-Api-Signature": signature,
|
|
539
|
-
},
|
|
540
|
-
body: JSON.stringify(body),
|
|
541
|
-
});
|
|
542
|
-
if (!res.ok) {
|
|
543
|
-
const text = await res.text();
|
|
544
|
-
throw new Error(`POST ${path} failed (${res.status}): ${text.slice(0, 200)}`);
|
|
545
|
-
}
|
|
546
|
-
const json = (await res.json());
|
|
547
|
-
if (json.code && json.code !== "0" && json.code !== "SUCCESS") {
|
|
548
|
-
throw new Error(`${path}: ${json.msg ?? json.code}`);
|
|
549
|
-
}
|
|
550
|
-
return json.data;
|
|
551
|
-
}
|
|
552
|
-
}
|
package/dist/exchanges/nado.d.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Nado DEX adapter — Orderbook DEX on Ink L2.
|
|
3
|
-
* API: https://gateway.nado.xyz/v1 (mainnet) / https://gateway.test.nado.xyz/v1 (testnet)
|
|
4
|
-
* Docs: https://docs.nado.xyz/developer-resources/api/gateway
|
|
5
|
-
* Note: API documentation is incomplete — many endpoints are stubbed pending full docs.
|
|
6
|
-
*/
|
|
7
|
-
import type { ExchangeAdapter, ExchangeMarketInfo, ExchangePosition, ExchangeOrder, ExchangeBalance, ExchangeTrade, ExchangeFundingPayment, ExchangeKline } from "./interface.js";
|
|
8
|
-
export declare class NadoAdapter implements ExchangeAdapter {
|
|
9
|
-
readonly name = "nado";
|
|
10
|
-
readonly chain = "ink";
|
|
11
|
-
readonly aliases: readonly ["nad"];
|
|
12
|
-
private _baseUrl;
|
|
13
|
-
private _apiKey;
|
|
14
|
-
constructor(apiKey?: string, testnet?: boolean);
|
|
15
|
-
init(): Promise<void>;
|
|
16
|
-
getMarkets(): Promise<ExchangeMarketInfo[]>;
|
|
17
|
-
getOrderbook(symbol: string): Promise<{
|
|
18
|
-
bids: [string, string][];
|
|
19
|
-
asks: [string, string][];
|
|
20
|
-
}>;
|
|
21
|
-
getRecentTrades(symbol: string, limit?: number): Promise<ExchangeTrade[]>;
|
|
22
|
-
getFundingHistory(symbol: string, _limit?: number): Promise<{
|
|
23
|
-
time: number;
|
|
24
|
-
rate: string;
|
|
25
|
-
price: string | null;
|
|
26
|
-
}[]>;
|
|
27
|
-
getKlines(symbol: string, interval: string, startTime: number, endTime: number): Promise<ExchangeKline[]>;
|
|
28
|
-
getBalance(): Promise<ExchangeBalance>;
|
|
29
|
-
getPositions(): Promise<ExchangePosition[]>;
|
|
30
|
-
getOpenOrders(): Promise<ExchangeOrder[]>;
|
|
31
|
-
getOrderHistory(limit?: number): Promise<ExchangeOrder[]>;
|
|
32
|
-
getTradeHistory(limit?: number): Promise<ExchangeTrade[]>;
|
|
33
|
-
getFundingPayments(limit?: number): Promise<ExchangeFundingPayment[]>;
|
|
34
|
-
marketOrder(symbol: string, side: "buy" | "sell", size: string): Promise<unknown>;
|
|
35
|
-
limitOrder(symbol: string, side: "buy" | "sell", price: string, size: string, opts?: {
|
|
36
|
-
reduceOnly?: boolean;
|
|
37
|
-
tif?: string;
|
|
38
|
-
}): Promise<unknown>;
|
|
39
|
-
editOrder(symbol: string, orderId: string, price: string, size: string): Promise<unknown>;
|
|
40
|
-
cancelOrder(symbol: string, orderId: string): Promise<unknown>;
|
|
41
|
-
cancelAllOrders(symbol?: string): Promise<unknown>;
|
|
42
|
-
setLeverage(symbol: string, leverage: number, marginMode?: "cross" | "isolated"): Promise<unknown>;
|
|
43
|
-
stopOrder(symbol: string, side: "buy" | "sell", size: string, triggerPrice: string, opts?: {
|
|
44
|
-
limitPrice?: string;
|
|
45
|
-
reduceOnly?: boolean;
|
|
46
|
-
}): Promise<unknown>;
|
|
47
|
-
withdraw(amount: string, destination: string): Promise<unknown>;
|
|
48
|
-
private _get;
|
|
49
|
-
private _authGet;
|
|
50
|
-
private _authPost;
|
|
51
|
-
private _authDelete;
|
|
52
|
-
}
|