perp-cli 0.6.4 → 0.7.1
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 +7 -2
- package/dist/api/public/hyperliquid.d.ts +2 -2
- package/dist/api/public/hyperliquid.js +0 -10
- package/dist/api/public/lighter.d.ts +2 -1
- package/dist/api/public/pacifica.d.ts +2 -1
- package/dist/arb/index.d.ts +7 -4
- package/dist/arb/index.js +5 -4
- package/dist/arb/sizing.d.ts +1 -1
- package/dist/arb/state.d.ts +1 -1
- package/dist/arb/state.js +4 -3
- package/dist/arb/utils.d.ts +0 -10
- package/dist/arb/utils.js +0 -42
- package/dist/bot/apex/guard.d.ts +26 -0
- package/dist/bot/apex/guard.js +86 -0
- package/dist/bot/apex/index.d.ts +6 -0
- package/dist/bot/apex/index.js +4 -0
- package/dist/bot/apex/pulse.d.ts +22 -0
- package/dist/bot/apex/pulse.js +107 -0
- package/dist/bot/apex/radar.d.ts +17 -0
- package/dist/bot/apex/radar.js +150 -0
- package/dist/bot/conditions.d.ts +1 -1
- package/dist/bot/config.d.ts +5 -1
- package/dist/bot/config.js +1 -1
- package/dist/bot/engine.d.ts +23 -2
- package/dist/bot/engine.js +296 -351
- package/dist/bot/index.d.ts +16 -0
- package/dist/bot/index.js +10 -0
- package/dist/bot/indicators.d.ts +29 -0
- package/dist/bot/indicators.js +144 -0
- package/dist/bot/reflect.d.ts +34 -0
- package/dist/bot/reflect.js +155 -0
- package/dist/bot/strategies/aggressive-taker.d.ts +36 -0
- package/dist/bot/strategies/aggressive-taker.js +125 -0
- package/dist/bot/strategies/apex-strategy.d.ts +36 -0
- package/dist/bot/strategies/apex-strategy.js +185 -0
- package/dist/bot/strategies/avellaneda-mm.d.ts +27 -0
- package/dist/bot/strategies/avellaneda-mm.js +111 -0
- package/dist/bot/strategies/basis-arb.d.ts +27 -0
- package/dist/bot/strategies/basis-arb.js +97 -0
- package/dist/bot/strategies/claude-agent.d.ts +31 -0
- package/dist/bot/strategies/claude-agent.js +155 -0
- package/dist/bot/strategies/dca-strategy.d.ts +25 -0
- package/dist/bot/strategies/dca-strategy.js +59 -0
- package/dist/bot/strategies/engine-mm.d.ts +29 -0
- package/dist/bot/strategies/engine-mm.js +141 -0
- package/dist/bot/strategies/funding-arb-strategy.d.ts +32 -0
- package/dist/bot/strategies/funding-arb-strategy.js +168 -0
- package/dist/bot/strategies/funding-arb-v2.d.ts +32 -0
- package/dist/bot/strategies/funding-arb-v2.js +222 -0
- package/dist/bot/strategies/funding-auto.d.ts +1 -0
- package/dist/bot/strategies/funding-auto.js +572 -0
- package/dist/bot/strategies/grid-mm.d.ts +25 -0
- package/dist/bot/strategies/grid-mm.js +99 -0
- package/dist/bot/strategies/grid-strategy.d.ts +39 -0
- package/dist/bot/strategies/grid-strategy.js +176 -0
- package/dist/bot/strategies/hedge-agent.d.ts +25 -0
- package/dist/bot/strategies/hedge-agent.js +79 -0
- package/dist/bot/strategies/liquidation-mm.d.ts +25 -0
- package/dist/bot/strategies/liquidation-mm.js +108 -0
- package/dist/bot/strategies/mean-reversion.d.ts +35 -0
- package/dist/bot/strategies/mean-reversion.js +118 -0
- package/dist/bot/strategies/momentum-breakout.d.ts +36 -0
- package/dist/bot/strategies/momentum-breakout.js +159 -0
- package/dist/bot/strategies/regime-mm.d.ts +25 -0
- package/dist/bot/strategies/regime-mm.js +111 -0
- package/dist/bot/strategies/rfq-agent.d.ts +25 -0
- package/dist/bot/strategies/rfq-agent.js +71 -0
- package/dist/bot/strategies/simple-mm.d.ts +25 -0
- package/dist/bot/strategies/simple-mm.js +76 -0
- package/dist/bot/strategy-registry.d.ts +9 -0
- package/dist/bot/strategy-registry.js +14 -0
- package/dist/bot/strategy-types.d.ts +64 -0
- package/dist/bot/strategy-types.js +5 -0
- package/dist/bot/trade-journal.d.ts +27 -0
- package/dist/bot/trade-journal.js +53 -0
- package/dist/bot/tui/BotDashboard.d.ts +49 -0
- package/dist/bot/tui/BotDashboard.js +93 -0
- package/dist/bot/tui/index.d.ts +6 -0
- package/dist/bot/tui/index.js +8 -0
- package/dist/bridge-engine.d.ts +0 -1
- package/dist/bridge-engine.js +0 -1
- package/dist/cache.d.ts +0 -1
- package/dist/cache.js +0 -1
- package/dist/commands/account.d.ts +1 -1
- package/dist/commands/account.js +94 -91
- package/dist/commands/agent.d.ts +1 -1
- package/dist/commands/arb/index.d.ts +1 -1
- package/dist/commands/arb/index.js +1 -1
- package/dist/commands/arb-auto.d.ts +1 -1
- package/dist/commands/arb-auto.js +1 -1
- package/dist/commands/arb.d.ts +1 -1
- package/dist/commands/bot.d.ts +1 -1
- package/dist/commands/bot.js +198 -14
- package/dist/commands/dashboard.d.ts +1 -1
- package/dist/commands/dashboard.js +1 -1
- package/dist/commands/funds.d.ts +1 -1
- package/dist/commands/funds.js +33 -20
- package/dist/commands/history.d.ts +1 -1
- package/dist/commands/history.js +5 -4
- package/dist/commands/manage.d.ts +2 -3
- package/dist/commands/manage.js +11 -18
- package/dist/commands/market.d.ts +1 -1
- package/dist/commands/market.js +7 -7
- package/dist/commands/plan.d.ts +1 -1
- package/dist/commands/rebalance.d.ts +1 -1
- package/dist/commands/rebalance.js +8 -9
- package/dist/commands/risk.d.ts +1 -1
- package/dist/commands/settings.d.ts +1 -1
- package/dist/commands/settings.js +3 -1
- package/dist/commands/trade.d.ts +1 -1
- package/dist/commands/trade.js +39 -52
- package/dist/commands/wallet.d.ts +0 -2
- package/dist/commands/wallet.js +0 -5
- package/dist/constants.d.ts +0 -3
- package/dist/constants.js +0 -4
- package/dist/cross-chain-margin.d.ts +1 -1
- package/dist/dashboard/index.d.ts +4 -0
- package/dist/dashboard/index.js +3 -0
- package/dist/dashboard/server.d.ts +1 -1
- package/dist/dashboard/server.js +1 -1
- package/dist/dashboard/ws-feeds.d.ts +1 -1
- package/dist/event-stream.d.ts +1 -1
- package/dist/exchanges/aster.d.ts +58 -0
- package/dist/exchanges/aster.js +409 -0
- package/dist/exchanges/capabilities.d.ts +74 -0
- package/dist/exchanges/capabilities.js +44 -0
- package/dist/exchanges/hyperliquid-spot.d.ts +1 -1
- package/dist/exchanges/hyperliquid-spot.js +20 -12
- package/dist/exchanges/hyperliquid.d.ts +8 -2
- package/dist/exchanges/hyperliquid.js +21 -6
- package/dist/exchanges/index.d.ts +11 -0
- package/dist/exchanges/index.js +10 -0
- package/dist/exchanges/interface.d.ts +3 -0
- package/dist/exchanges/lighter-spot.d.ts +13 -0
- package/dist/exchanges/lighter-spot.js +98 -26
- package/dist/exchanges/lighter.d.ts +9 -3
- package/dist/exchanges/lighter.js +18 -8
- package/dist/exchanges/nado.d.ts +52 -0
- package/dist/exchanges/nado.js +223 -0
- package/dist/exchanges/pacifica.d.ts +7 -1
- package/dist/exchanges/pacifica.js +17 -2
- package/dist/exchanges/registry.d.ts +13 -0
- package/dist/exchanges/registry.js +37 -0
- package/dist/exchanges/spot-interface.d.ts +9 -0
- package/dist/funding/rates.js +1 -1
- package/dist/index.js +2 -6
- package/dist/jobs.js +1 -1
- package/dist/liquidity.d.ts +1 -2
- package/dist/liquidity.js +12 -5
- package/dist/mcp-server.js +4 -2
- package/dist/pacifica/constants.d.ts +0 -3
- package/dist/pacifica/constants.js +0 -4
- package/dist/pacifica/types/account.d.ts +0 -8
- package/dist/pacifica/types/lake.d.ts +0 -6
- package/dist/pacifica/types/position.d.ts +0 -12
- package/dist/pacifica/types/ws.d.ts +0 -24
- package/dist/pacifica/types/ws.js +1 -41
- package/dist/plan-executor.d.ts +1 -1
- package/dist/rebalance.d.ts +1 -7
- package/dist/rebalance.js +0 -6
- package/dist/risk.d.ts +1 -1
- package/dist/risk.js +3 -1
- package/dist/smart-order.d.ts +1 -1
- package/dist/strategies/dca.d.ts +1 -1
- package/dist/strategies/funding-arb.d.ts +1 -1
- package/dist/strategies/funding-arb.js +193 -181
- package/dist/strategies/grid.d.ts +1 -1
- package/dist/strategies/grid.js +1 -1
- package/dist/strategies/index.d.ts +12 -0
- package/dist/strategies/index.js +7 -0
- package/dist/strategies/split-order.d.ts +1 -1
- package/dist/strategies/trailing-stop.d.ts +1 -1
- package/dist/strategies/twap.d.ts +1 -1
- package/dist/trade-validator.d.ts +1 -1
- package/package.json +7 -1
- package/skills/perp-cli/SKILL.md +20 -0
- package/skills/perp-cli/references/commands.md +22 -8
|
@@ -0,0 +1,223 @@
|
|
|
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
|
+
export class NadoAdapter {
|
|
8
|
+
name = "nado";
|
|
9
|
+
chain = "ink";
|
|
10
|
+
aliases = ["nad"];
|
|
11
|
+
_baseUrl;
|
|
12
|
+
_apiKey;
|
|
13
|
+
constructor(apiKey, testnet = false) {
|
|
14
|
+
this._apiKey = apiKey || process.env.NADO_API_KEY || "";
|
|
15
|
+
this._baseUrl = testnet
|
|
16
|
+
? "https://gateway.test.nado.xyz/v1"
|
|
17
|
+
: "https://gateway.nado.xyz/v1";
|
|
18
|
+
}
|
|
19
|
+
async init() {
|
|
20
|
+
// Verify connectivity
|
|
21
|
+
try {
|
|
22
|
+
await this._get("/markets");
|
|
23
|
+
}
|
|
24
|
+
catch { /* non-critical */ }
|
|
25
|
+
}
|
|
26
|
+
async getMarkets() {
|
|
27
|
+
try {
|
|
28
|
+
const data = await this._get("/markets");
|
|
29
|
+
return (data ?? []).map(m => ({
|
|
30
|
+
symbol: String(m.symbol ?? m.name ?? ""),
|
|
31
|
+
markPrice: String(m.mark_price ?? m.last_price ?? "0"),
|
|
32
|
+
indexPrice: String(m.index_price ?? "0"),
|
|
33
|
+
fundingRate: String(m.funding_rate ?? "0"),
|
|
34
|
+
volume24h: String(m.volume_24h ?? m.volume ?? "0"),
|
|
35
|
+
openInterest: String(m.open_interest ?? "0"),
|
|
36
|
+
maxLeverage: Number(m.max_leverage ?? 50),
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
async getOrderbook(symbol) {
|
|
44
|
+
try {
|
|
45
|
+
const data = await this._get(`/orderbook?symbol=${symbol}`);
|
|
46
|
+
return {
|
|
47
|
+
bids: (data.bids ?? []),
|
|
48
|
+
asks: (data.asks ?? []),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return { bids: [], asks: [] };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async getRecentTrades(symbol, limit = 20) {
|
|
56
|
+
try {
|
|
57
|
+
const data = await this._get(`/trades?symbol=${symbol}&limit=${limit}`);
|
|
58
|
+
return (data ?? []).map(t => ({
|
|
59
|
+
time: Number(t.time ?? t.timestamp ?? 0),
|
|
60
|
+
symbol, side: String(t.side ?? "buy"),
|
|
61
|
+
price: String(t.price ?? "0"), size: String(t.size ?? t.qty ?? "0"), fee: "0",
|
|
62
|
+
}));
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async getFundingHistory(symbol, _limit = 10) {
|
|
69
|
+
try {
|
|
70
|
+
const data = await this._get(`/funding?symbol=${symbol}`);
|
|
71
|
+
return (data ?? []).map(f => ({
|
|
72
|
+
time: Number(f.time ?? 0), rate: String(f.rate ?? "0"), price: null,
|
|
73
|
+
}));
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
async getKlines(symbol, interval, startTime, endTime) {
|
|
80
|
+
try {
|
|
81
|
+
const data = await this._get(`/klines?symbol=${symbol}&interval=${interval}&start=${startTime}&end=${endTime}`);
|
|
82
|
+
return (data ?? []).map(k => ({
|
|
83
|
+
time: Number(k[0]), open: String(k[1]), high: String(k[2]),
|
|
84
|
+
low: String(k[3]), close: String(k[4]), volume: String(k[5]), trades: 0,
|
|
85
|
+
}));
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
async getBalance() {
|
|
92
|
+
if (!this._apiKey)
|
|
93
|
+
throw new Error("Nado API key required. Set NADO_API_KEY.");
|
|
94
|
+
const data = await this._authGet("/account/balance");
|
|
95
|
+
return {
|
|
96
|
+
equity: String(data.equity ?? data.total ?? "0"),
|
|
97
|
+
available: String(data.available ?? data.free ?? "0"),
|
|
98
|
+
marginUsed: String(data.margin_used ?? "0"),
|
|
99
|
+
unrealizedPnl: String(data.unrealized_pnl ?? "0"),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
async getPositions() {
|
|
103
|
+
if (!this._apiKey)
|
|
104
|
+
throw new Error("Nado API key required. Set NADO_API_KEY.");
|
|
105
|
+
const data = await this._authGet("/account/positions");
|
|
106
|
+
return (data ?? []).filter(p => Number(p.size ?? 0) !== 0).map(p => ({
|
|
107
|
+
symbol: String(p.symbol ?? ""), side: Number(p.size ?? 0) > 0 ? "long" : "short",
|
|
108
|
+
size: String(Math.abs(Number(p.size ?? 0))), entryPrice: String(p.entry_price ?? "0"),
|
|
109
|
+
markPrice: String(p.mark_price ?? "0"), liquidationPrice: String(p.liquidation_price ?? "N/A"),
|
|
110
|
+
unrealizedPnl: String(p.unrealized_pnl ?? "0"), leverage: Number(p.leverage ?? 1),
|
|
111
|
+
}));
|
|
112
|
+
}
|
|
113
|
+
async getOpenOrders() {
|
|
114
|
+
if (!this._apiKey)
|
|
115
|
+
throw new Error("Nado API key required. Set NADO_API_KEY.");
|
|
116
|
+
const data = await this._authGet("/account/orders");
|
|
117
|
+
return (data ?? []).map(o => ({
|
|
118
|
+
orderId: String(o.order_id ?? o.id ?? ""), symbol: String(o.symbol ?? ""),
|
|
119
|
+
side: String(o.side ?? "buy").toLowerCase(),
|
|
120
|
+
price: String(o.price ?? "0"), size: String(o.size ?? o.qty ?? "0"),
|
|
121
|
+
filled: String(o.filled ?? "0"), status: String(o.status ?? "open"), type: String(o.type ?? "limit"),
|
|
122
|
+
}));
|
|
123
|
+
}
|
|
124
|
+
async getOrderHistory(limit = 30) {
|
|
125
|
+
if (!this._apiKey)
|
|
126
|
+
throw new Error("Nado API key required. Set NADO_API_KEY.");
|
|
127
|
+
const data = await this._authGet(`/account/orders/history?limit=${limit}`);
|
|
128
|
+
return (data ?? []).map(o => ({
|
|
129
|
+
orderId: String(o.order_id ?? o.id ?? ""), symbol: String(o.symbol ?? ""),
|
|
130
|
+
side: String(o.side ?? "buy").toLowerCase(),
|
|
131
|
+
price: String(o.price ?? "0"), size: String(o.size ?? "0"),
|
|
132
|
+
filled: String(o.filled ?? "0"), status: String(o.status ?? "done"), type: String(o.type ?? "limit"),
|
|
133
|
+
}));
|
|
134
|
+
}
|
|
135
|
+
async getTradeHistory(limit = 30) {
|
|
136
|
+
if (!this._apiKey)
|
|
137
|
+
throw new Error("Nado API key required. Set NADO_API_KEY.");
|
|
138
|
+
const data = await this._authGet(`/account/trades?limit=${limit}`);
|
|
139
|
+
return (data ?? []).map(t => ({
|
|
140
|
+
time: Number(t.time ?? t.timestamp ?? 0), symbol: String(t.symbol ?? ""),
|
|
141
|
+
side: String(t.side ?? "buy").toLowerCase(),
|
|
142
|
+
price: String(t.price ?? "0"), size: String(t.size ?? "0"), fee: String(t.fee ?? "0"),
|
|
143
|
+
}));
|
|
144
|
+
}
|
|
145
|
+
async getFundingPayments(limit = 200) {
|
|
146
|
+
if (!this._apiKey)
|
|
147
|
+
throw new Error("Nado API key required. Set NADO_API_KEY.");
|
|
148
|
+
const data = await this._authGet(`/account/funding?limit=${limit}`);
|
|
149
|
+
return (data ?? []).map(f => ({
|
|
150
|
+
time: Number(f.time ?? 0), symbol: String(f.symbol ?? ""), payment: String(f.payment ?? f.amount ?? "0"),
|
|
151
|
+
}));
|
|
152
|
+
}
|
|
153
|
+
async marketOrder(symbol, side, size) {
|
|
154
|
+
return this._authPost("/orders", { symbol, side, size, type: "market" });
|
|
155
|
+
}
|
|
156
|
+
async limitOrder(symbol, side, price, size, opts) {
|
|
157
|
+
return this._authPost("/orders", { symbol, side, price, size, type: "limit", time_in_force: opts?.tif ?? "GTC", reduce_only: opts?.reduceOnly ?? false });
|
|
158
|
+
}
|
|
159
|
+
async editOrder(symbol, orderId, price, size) {
|
|
160
|
+
return this._authPost(`/orders/${orderId}`, { symbol, price, size });
|
|
161
|
+
}
|
|
162
|
+
async cancelOrder(symbol, orderId) {
|
|
163
|
+
return this._authDelete(`/orders/${orderId}?symbol=${symbol}`);
|
|
164
|
+
}
|
|
165
|
+
async cancelAllOrders(symbol) {
|
|
166
|
+
return this._authDelete(`/orders${symbol ? `?symbol=${symbol}` : ""}`);
|
|
167
|
+
}
|
|
168
|
+
async setLeverage(symbol, leverage, marginMode) {
|
|
169
|
+
return this._authPost("/leverage", { symbol, leverage, margin_mode: marginMode ?? "cross" });
|
|
170
|
+
}
|
|
171
|
+
async stopOrder(symbol, side, size, triggerPrice, opts) {
|
|
172
|
+
return this._authPost("/orders", {
|
|
173
|
+
symbol, side, size, type: opts?.limitPrice ? "stop_limit" : "stop_market",
|
|
174
|
+
trigger_price: triggerPrice, price: opts?.limitPrice, reduce_only: opts?.reduceOnly ?? true,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
async withdraw(amount, destination) {
|
|
178
|
+
return this._authPost("/withdraw", { amount, destination });
|
|
179
|
+
}
|
|
180
|
+
async _get(path) {
|
|
181
|
+
const res = await fetch(`${this._baseUrl}${path}`, {
|
|
182
|
+
headers: { "Accept-Encoding": "gzip" },
|
|
183
|
+
});
|
|
184
|
+
if (!res.ok)
|
|
185
|
+
throw new Error(`GET ${path} failed (${res.status})`);
|
|
186
|
+
return res.json();
|
|
187
|
+
}
|
|
188
|
+
async _authGet(path) {
|
|
189
|
+
if (!this._apiKey)
|
|
190
|
+
throw new Error("Nado API key required. Set NADO_API_KEY.");
|
|
191
|
+
const res = await fetch(`${this._baseUrl}${path}`, {
|
|
192
|
+
headers: { "Accept-Encoding": "gzip", "Authorization": `Bearer ${this._apiKey}` },
|
|
193
|
+
});
|
|
194
|
+
if (!res.ok)
|
|
195
|
+
throw new Error(`GET ${path} failed (${res.status})`);
|
|
196
|
+
return res.json();
|
|
197
|
+
}
|
|
198
|
+
async _authPost(path, body) {
|
|
199
|
+
if (!this._apiKey)
|
|
200
|
+
throw new Error("Nado API key required. Set NADO_API_KEY.");
|
|
201
|
+
const res = await fetch(`${this._baseUrl}${path}`, {
|
|
202
|
+
method: "POST",
|
|
203
|
+
headers: { "Accept-Encoding": "gzip", "Authorization": `Bearer ${this._apiKey}`, "Content-Type": "application/json" },
|
|
204
|
+
body: JSON.stringify(body),
|
|
205
|
+
});
|
|
206
|
+
if (!res.ok)
|
|
207
|
+
throw new Error(`POST ${path} failed (${res.status})`);
|
|
208
|
+
return res.json();
|
|
209
|
+
}
|
|
210
|
+
async _authDelete(path) {
|
|
211
|
+
if (!this._apiKey)
|
|
212
|
+
throw new Error("Nado API key required. Set NADO_API_KEY.");
|
|
213
|
+
const res = await fetch(`${this._baseUrl}${path}`, {
|
|
214
|
+
method: "DELETE",
|
|
215
|
+
headers: { "Accept-Encoding": "gzip", "Authorization": `Bearer ${this._apiKey}` },
|
|
216
|
+
});
|
|
217
|
+
if (!res.ok)
|
|
218
|
+
throw new Error(`DELETE ${path} failed (${res.status})`);
|
|
219
|
+
if (res.status === 204)
|
|
220
|
+
return {};
|
|
221
|
+
return res.json();
|
|
222
|
+
}
|
|
223
|
+
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { Keypair } from "@solana/web3.js";
|
|
2
2
|
import { PacificaClient, type Network } from "../pacifica/index.js";
|
|
3
3
|
import type { ExchangeAdapter, ExchangeMarketInfo, ExchangePosition, ExchangeOrder, ExchangeBalance, ExchangeTrade, ExchangeFundingPayment, ExchangeKline } from "./interface.js";
|
|
4
|
-
import type { SolanaSigner } from "../signer/
|
|
4
|
+
import type { SolanaSigner } from "../signer/index.js";
|
|
5
5
|
export declare class PacificaAdapter implements ExchangeAdapter {
|
|
6
6
|
readonly name = "pacifica";
|
|
7
|
+
readonly chain = "solana";
|
|
8
|
+
readonly aliases: readonly ["pac"];
|
|
7
9
|
private client;
|
|
8
10
|
private _solanaSigner;
|
|
9
11
|
private _hasRealKey;
|
|
@@ -45,6 +47,10 @@ export declare class PacificaAdapter implements ExchangeAdapter {
|
|
|
45
47
|
limitPrice?: string;
|
|
46
48
|
reduceOnly?: boolean;
|
|
47
49
|
}): Promise<unknown>;
|
|
50
|
+
withdraw(amount: string, destination: string, _opts?: {
|
|
51
|
+
assetId?: number;
|
|
52
|
+
routeType?: number;
|
|
53
|
+
}): Promise<unknown>;
|
|
48
54
|
getRecentTrades(symbol: string, _limit?: number): Promise<ExchangeTrade[]>;
|
|
49
55
|
getFundingHistory(symbol: string, limit?: number): Promise<{
|
|
50
56
|
time: number;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { PacificaClient } from "../pacifica/index.js";
|
|
2
|
-
import { LocalSolanaSigner } from "../signer/
|
|
2
|
+
import { LocalSolanaSigner } from "../signer/index.js";
|
|
3
3
|
export class PacificaAdapter {
|
|
4
4
|
name = "pacifica";
|
|
5
|
+
chain = "solana";
|
|
6
|
+
aliases = ["pac"];
|
|
5
7
|
client;
|
|
6
8
|
_solanaSigner;
|
|
7
9
|
_hasRealKey;
|
|
@@ -213,9 +215,22 @@ export class PacificaAdapter {
|
|
|
213
215
|
stop_order: { stop_price: triggerPrice, amount: size, limit_price: opts?.limitPrice },
|
|
214
216
|
}, this.account, this.signMessage);
|
|
215
217
|
}
|
|
218
|
+
async withdraw(amount, destination, _opts) {
|
|
219
|
+
this.ensureSigner();
|
|
220
|
+
return this.client.withdraw({ amount, dest_address: destination }, this.account, this.signMessage);
|
|
221
|
+
}
|
|
216
222
|
async getRecentTrades(symbol, _limit = 20) {
|
|
217
223
|
const trades = await this.client.getTrades(symbol);
|
|
218
|
-
|
|
224
|
+
// Deduplicate by time+price+size+side (API sometimes returns duplicate entries)
|
|
225
|
+
const seen = new Set();
|
|
226
|
+
const unique = trades.filter((t) => {
|
|
227
|
+
const key = `${t.created_at}:${t.price}:${t.amount}:${t.side}`;
|
|
228
|
+
if (seen.has(key))
|
|
229
|
+
return false;
|
|
230
|
+
seen.add(key);
|
|
231
|
+
return true;
|
|
232
|
+
});
|
|
233
|
+
return unique.slice(0, _limit).map((t) => ({
|
|
219
234
|
time: Number(t.created_at ?? 0),
|
|
220
235
|
symbol,
|
|
221
236
|
side: t.side === "bid" ? "buy" : "sell",
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapter registry for plugin-style exchange discovery.
|
|
3
|
+
* New exchanges register here — commands use registry to resolve names/aliases.
|
|
4
|
+
*/
|
|
5
|
+
export interface AdapterRegistration {
|
|
6
|
+
name: string;
|
|
7
|
+
aliases: string[];
|
|
8
|
+
chain: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function registerAdapter(reg: AdapterRegistration): void;
|
|
11
|
+
export declare function getAdapterRegistration(nameOrAlias: string): AdapterRegistration | undefined;
|
|
12
|
+
export declare function listExchanges(): string[];
|
|
13
|
+
export declare function resolveExchangeName(nameOrAlias: string): string;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapter registry for plugin-style exchange discovery.
|
|
3
|
+
* New exchanges register here — commands use registry to resolve names/aliases.
|
|
4
|
+
*/
|
|
5
|
+
const registry = new Map();
|
|
6
|
+
export function registerAdapter(reg) {
|
|
7
|
+
registry.set(reg.name, reg);
|
|
8
|
+
for (const alias of reg.aliases) {
|
|
9
|
+
registry.set(alias, reg);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export function getAdapterRegistration(nameOrAlias) {
|
|
13
|
+
return registry.get(nameOrAlias.toLowerCase());
|
|
14
|
+
}
|
|
15
|
+
export function listExchanges() {
|
|
16
|
+
return [...new Set([...registry.values()].map(r => r.name))];
|
|
17
|
+
}
|
|
18
|
+
export function resolveExchangeName(nameOrAlias) {
|
|
19
|
+
const reg = registry.get(nameOrAlias.toLowerCase());
|
|
20
|
+
return reg?.name ?? nameOrAlias.toLowerCase();
|
|
21
|
+
}
|
|
22
|
+
// ── Built-in adapter registrations ──
|
|
23
|
+
registerAdapter({
|
|
24
|
+
name: "pacifica",
|
|
25
|
+
aliases: ["pac"],
|
|
26
|
+
chain: "solana",
|
|
27
|
+
});
|
|
28
|
+
registerAdapter({
|
|
29
|
+
name: "hyperliquid",
|
|
30
|
+
aliases: ["hl"],
|
|
31
|
+
chain: "evm",
|
|
32
|
+
});
|
|
33
|
+
registerAdapter({
|
|
34
|
+
name: "lighter",
|
|
35
|
+
aliases: ["lt"],
|
|
36
|
+
chain: "ethereum",
|
|
37
|
+
});
|
|
@@ -20,6 +20,15 @@ export interface SpotBalance {
|
|
|
20
20
|
available: string;
|
|
21
21
|
held: string;
|
|
22
22
|
}
|
|
23
|
+
export interface SpotOrderParams {
|
|
24
|
+
symbol: string;
|
|
25
|
+
side: "buy" | "sell";
|
|
26
|
+
/** Price as number or string — adapter rounds to exchange precision automatically */
|
|
27
|
+
price: number | string;
|
|
28
|
+
/** Size as number or string — adapter rounds to exchange precision automatically */
|
|
29
|
+
size: number | string;
|
|
30
|
+
tif?: string;
|
|
31
|
+
}
|
|
23
32
|
export interface SpotAdapter {
|
|
24
33
|
readonly name: string;
|
|
25
34
|
getSpotMarkets(): Promise<SpotMarketInfo[]>;
|
package/dist/funding/rates.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import { toHourlyRate, annualizeRate, computeAnnualSpread, estimateHourlyFunding } from "./normalize.js";
|
|
9
9
|
import { fetchPacificaPrices, fetchHyperliquidMeta, fetchLighterOrderBookDetails, fetchLighterFundingRates as fetchLtFundingRates, } from "../shared-api.js";
|
|
10
10
|
import { getHistoricalAverages } from "./history.js";
|
|
11
|
-
import { SPOT_PERP_TOKEN_MAP, MAX_PRICE_DEVIATION_PCT } from "../exchanges/
|
|
11
|
+
import { SPOT_PERP_TOKEN_MAP, MAX_PRICE_DEVIATION_PCT } from "../exchanges/index.js";
|
|
12
12
|
// ── Default top symbols to track ──
|
|
13
13
|
export const TOP_SYMBOLS = [
|
|
14
14
|
"BTC", "ETH", "SOL", "DOGE", "SUI", "AVAX", "LINK", "ARB",
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,7 @@ import { Keypair } from "@solana/web3.js";
|
|
|
11
11
|
import { tryLoadPrivateKey, parseSolanaKeypair } from "./config.js";
|
|
12
12
|
import { PacificaAdapter } from "./exchanges/pacifica.js";
|
|
13
13
|
import { HyperliquidAdapter } from "./exchanges/hyperliquid.js";
|
|
14
|
+
import { resolveExchangeName } from "./exchanges/registry.js";
|
|
14
15
|
import { registerMarketCommands } from "./commands/market.js";
|
|
15
16
|
import { registerAccountCommands } from "./commands/account.js";
|
|
16
17
|
import { registerTradeCommands } from "./commands/trade.js";
|
|
@@ -80,12 +81,7 @@ let _hlAdapter = null;
|
|
|
80
81
|
let _lighterAdapter = null;
|
|
81
82
|
/** Map short aliases to canonical exchange names. Full names pass through. */
|
|
82
83
|
function resolveExchangeAlias(name) {
|
|
83
|
-
|
|
84
|
-
hl: "hyperliquid",
|
|
85
|
-
lt: "lighter",
|
|
86
|
-
pac: "pacifica",
|
|
87
|
-
};
|
|
88
|
-
return aliases[name.toLowerCase()] ?? name.toLowerCase();
|
|
84
|
+
return resolveExchangeName(name);
|
|
89
85
|
}
|
|
90
86
|
function getExchange() {
|
|
91
87
|
return resolveExchangeAlias(program.opts().exchange);
|
package/dist/jobs.js
CHANGED
|
@@ -146,7 +146,7 @@ function buildEnvString() {
|
|
|
146
146
|
const parts = [];
|
|
147
147
|
for (const k of keys) {
|
|
148
148
|
if (process.env[k])
|
|
149
|
-
parts.push(`${k}='${process.env[k]}'`);
|
|
149
|
+
parts.push(`${k}='${process.env[k].replace(/'/g, "'\"'\"'")}'`);
|
|
150
150
|
}
|
|
151
151
|
return parts.join(" ");
|
|
152
152
|
}
|
package/dist/liquidity.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { ExchangeAdapter } from "./exchanges/
|
|
2
|
-
import type { SpotAdapter } from "./exchanges/spot-interface.js";
|
|
1
|
+
import type { ExchangeAdapter, SpotAdapter } from "./exchanges/index.js";
|
|
3
2
|
export interface LiquidityCheck {
|
|
4
3
|
/** Max executable size (base) within slippage tolerance */
|
|
5
4
|
maxSize: number;
|
package/dist/liquidity.js
CHANGED
|
@@ -11,7 +11,10 @@ export function computeExecutableSize(levels, requestedSizeUsd, maxSlippagePct =
|
|
|
11
11
|
return { maxSize: 0, avgFillPrice: 0, slippagePct: 0, depthUsd: 0, canFillFull: false, recommendedSize: 0 };
|
|
12
12
|
}
|
|
13
13
|
const bestPrice = Number(levels[0][0]);
|
|
14
|
-
|
|
14
|
+
// Detect direction: asks are ascending (price goes up), bids are descending (price goes down)
|
|
15
|
+
const isAscending = levels.length < 2 || Number(levels[1]?.[0] ?? bestPrice) >= bestPrice;
|
|
16
|
+
const slippageLimitUp = bestPrice * (1 + maxSlippagePct / 100);
|
|
17
|
+
const slippageLimitDown = bestPrice * (1 - maxSlippagePct / 100);
|
|
15
18
|
let filledSize = 0;
|
|
16
19
|
let filledNotional = 0;
|
|
17
20
|
let totalDepthUsd = 0;
|
|
@@ -20,9 +23,13 @@ export function computeExecutableSize(levels, requestedSizeUsd, maxSlippagePct =
|
|
|
20
23
|
const size = Number(sizeStr);
|
|
21
24
|
const levelUsd = price * size;
|
|
22
25
|
totalDepthUsd += levelUsd;
|
|
23
|
-
// Stop walking if we exceed slippage tolerance
|
|
24
|
-
if (
|
|
25
|
-
|
|
26
|
+
// Stop walking if we exceed slippage tolerance (direction-aware)
|
|
27
|
+
if (filledSize > 0) {
|
|
28
|
+
if (isAscending && price > slippageLimitUp)
|
|
29
|
+
break;
|
|
30
|
+
if (!isAscending && price < slippageLimitDown)
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
26
33
|
const remainingUsd = requestedSizeUsd - filledNotional;
|
|
27
34
|
if (remainingUsd <= 0)
|
|
28
35
|
break;
|
|
@@ -76,7 +83,7 @@ export async function checkArbLiquidity(longAdapter, shortAdapter, symbol, sizeU
|
|
|
76
83
|
}
|
|
77
84
|
}
|
|
78
85
|
// Use whichever side has less available liquidity
|
|
79
|
-
const executableUsd = Math.min(longCheck.
|
|
86
|
+
const executableUsd = Math.min(longCheck.recommendedSize * longCheck.avgFillPrice, shortCheck.recommendedSize * shortCheck.avgFillPrice);
|
|
80
87
|
// Minimum viable: at least 20% of requested size
|
|
81
88
|
const minViable = sizeUsd * 0.2;
|
|
82
89
|
if (executableUsd < minViable) {
|
package/dist/mcp-server.js
CHANGED
|
@@ -11,7 +11,7 @@ import { createRequire } from "node:module";
|
|
|
11
11
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
12
12
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
13
13
|
import { z } from "zod";
|
|
14
|
-
import {
|
|
14
|
+
import { tryLoadPrivateKey, parseSolanaKeypair } from "./config.js";
|
|
15
15
|
import { PacificaAdapter } from "./exchanges/pacifica.js";
|
|
16
16
|
import { HyperliquidAdapter } from "./exchanges/hyperliquid.js";
|
|
17
17
|
import { LighterAdapter } from "./exchanges/lighter.js";
|
|
@@ -25,7 +25,9 @@ async function getOrCreateAdapter(exchange) {
|
|
|
25
25
|
const key = exchange.toLowerCase();
|
|
26
26
|
if (adapters.has(key))
|
|
27
27
|
return adapters.get(key);
|
|
28
|
-
const pk = await
|
|
28
|
+
const pk = await tryLoadPrivateKey(key);
|
|
29
|
+
if (!pk)
|
|
30
|
+
throw new Error(`No private key configured for ${exchange}. Run: perp init`);
|
|
29
31
|
let adapter;
|
|
30
32
|
switch (key) {
|
|
31
33
|
case "pacifica": {
|
|
@@ -10,9 +10,6 @@ export declare const TESTNET_PROGRAM_ID = "peRPsYCcB1J9jvrs29jiGdjkytxs8uHLmSPLK
|
|
|
10
10
|
export declare const TESTNET_CENTRAL_STATE = "2zPRq1Qvdq5A4Ld6WsH7usgCge4ApZRYfhhf5VAjfXxv";
|
|
11
11
|
export declare const TESTNET_PACIFICA_VAULT = "5SDFdHZGTZbyRYu54CgmRkCGnPHC5pYaN27p7XGLqnBs";
|
|
12
12
|
export declare const TESTNET_USDC_MINT = "USDPqRbLidFGufty2s3oizmDEKdqx7ePTqzDMbf5ZKM";
|
|
13
|
-
export declare const SYSTEM_PROGRAM_ID = "11111111111111111111111111111111";
|
|
14
|
-
export declare const TOKEN_PROGRAM_ID = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
|
|
15
|
-
export declare const ASSOCIATED_TOKEN_PROGRAM_ID = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
|
|
16
13
|
export declare const DEFAULT_EXPIRY_WINDOW = 5000;
|
|
17
14
|
export declare const USDC_DECIMALS = 6;
|
|
18
15
|
export declare const BUILDER_CODE: string;
|
|
@@ -15,10 +15,6 @@ export const TESTNET_PROGRAM_ID = "peRPsYCcB1J9jvrs29jiGdjkytxs8uHLmSPLKKP9ptm";
|
|
|
15
15
|
export const TESTNET_CENTRAL_STATE = "2zPRq1Qvdq5A4Ld6WsH7usgCge4ApZRYfhhf5VAjfXxv";
|
|
16
16
|
export const TESTNET_PACIFICA_VAULT = "5SDFdHZGTZbyRYu54CgmRkCGnPHC5pYaN27p7XGLqnBs";
|
|
17
17
|
export const TESTNET_USDC_MINT = "USDPqRbLidFGufty2s3oizmDEKdqx7ePTqzDMbf5ZKM";
|
|
18
|
-
// Standard Solana Program IDs
|
|
19
|
-
export const SYSTEM_PROGRAM_ID = "11111111111111111111111111111111";
|
|
20
|
-
export const TOKEN_PROGRAM_ID = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
|
|
21
|
-
export const ASSOCIATED_TOKEN_PROGRAM_ID = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
|
|
22
18
|
// Signing defaults
|
|
23
19
|
export const DEFAULT_EXPIRY_WINDOW = 5000; // 5 seconds
|
|
24
20
|
// USDC decimals
|
|
@@ -19,10 +19,6 @@ export interface AccountSettings {
|
|
|
19
19
|
margin_mode: "cross" | "isolated";
|
|
20
20
|
leverage: number;
|
|
21
21
|
}
|
|
22
|
-
export interface SubaccountInfo {
|
|
23
|
-
subaccount_name: string;
|
|
24
|
-
subaccount_address: string;
|
|
25
|
-
}
|
|
26
22
|
export interface TransferFundsParams {
|
|
27
23
|
from_account: string;
|
|
28
24
|
to_account: string;
|
|
@@ -36,7 +32,3 @@ export interface UpdateLeverageParams {
|
|
|
36
32
|
symbol: string;
|
|
37
33
|
leverage: number;
|
|
38
34
|
}
|
|
39
|
-
export interface UpdateMarginModeParams {
|
|
40
|
-
symbol: string;
|
|
41
|
-
is_isolated: boolean;
|
|
42
|
-
}
|
|
@@ -11,15 +11,3 @@ export interface Position {
|
|
|
11
11
|
leverage: number;
|
|
12
12
|
created_at: number;
|
|
13
13
|
}
|
|
14
|
-
export interface PositionTPSL {
|
|
15
|
-
symbol: string;
|
|
16
|
-
side: Side;
|
|
17
|
-
take_profit?: {
|
|
18
|
-
stop_price: string;
|
|
19
|
-
limit_price?: string;
|
|
20
|
-
amount?: string;
|
|
21
|
-
};
|
|
22
|
-
stop_loss?: {
|
|
23
|
-
stop_price: string;
|
|
24
|
-
};
|
|
25
|
-
}
|
|
@@ -1,18 +1,6 @@
|
|
|
1
1
|
export type PublicChannel = "prices" | "book" | "bbo" | "trades" | "candle" | "mark_price_candle";
|
|
2
2
|
export type PrivateChannel = "account_positions" | "account_order_updates" | "account_info" | "account_margin" | "account_leverage" | "account_trades" | "account_twap_orders" | "account_twap_order_updates";
|
|
3
3
|
export type Channel = PublicChannel | PrivateChannel;
|
|
4
|
-
export interface WSSubscription {
|
|
5
|
-
method: "subscribe" | "unsubscribe";
|
|
6
|
-
params: {
|
|
7
|
-
source: Channel;
|
|
8
|
-
[key: string]: unknown;
|
|
9
|
-
};
|
|
10
|
-
}
|
|
11
|
-
export type WSTradingMethod = "create_order" | "create_market_order" | "edit_order" | "batch_order" | "cancel_order" | "cancel_all_orders";
|
|
12
|
-
export interface WSTradingRequest {
|
|
13
|
-
id: string;
|
|
14
|
-
params: Record<string, unknown>;
|
|
15
|
-
}
|
|
16
4
|
export interface WSTradingResponse {
|
|
17
5
|
code: number;
|
|
18
6
|
data: Record<string, unknown>;
|
|
@@ -20,15 +8,3 @@ export interface WSTradingResponse {
|
|
|
20
8
|
t: number;
|
|
21
9
|
type: string;
|
|
22
10
|
}
|
|
23
|
-
export declare const ORDER_UPDATE_FIELDS: Record<string, string>;
|
|
24
|
-
export declare const ACCOUNT_INFO_FIELDS: Record<string, string>;
|
|
25
|
-
export declare const WS_CODES: {
|
|
26
|
-
readonly SUCCESS: 200;
|
|
27
|
-
readonly INVALID_REQUEST: 400;
|
|
28
|
-
readonly INVALID_SIGNATURE: 401;
|
|
29
|
-
readonly INVALID_SIGNER: 402;
|
|
30
|
-
readonly UNAUTHORIZED: 403;
|
|
31
|
-
readonly ENGINE_ERROR: 420;
|
|
32
|
-
readonly RATE_LIMIT: 429;
|
|
33
|
-
readonly UNKNOWN_ERROR: 500;
|
|
34
|
-
};
|
|
@@ -1,41 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export const ORDER_UPDATE_FIELDS = {
|
|
3
|
-
i: "order_id",
|
|
4
|
-
I: "client_order_id",
|
|
5
|
-
u: "account",
|
|
6
|
-
s: "symbol",
|
|
7
|
-
d: "side",
|
|
8
|
-
p: "price",
|
|
9
|
-
a: "amount",
|
|
10
|
-
f: "filled",
|
|
11
|
-
oe: "order_event",
|
|
12
|
-
os: "order_status",
|
|
13
|
-
ot: "order_type",
|
|
14
|
-
li: "last_order_id",
|
|
15
|
-
};
|
|
16
|
-
// Field abbreviation mappings for account info
|
|
17
|
-
export const ACCOUNT_INFO_FIELDS = {
|
|
18
|
-
b: "balance",
|
|
19
|
-
f: "fee_level",
|
|
20
|
-
ae: "account_equity",
|
|
21
|
-
as: "available_to_spend",
|
|
22
|
-
aw: "available_to_withdraw",
|
|
23
|
-
pb: "pending_balance",
|
|
24
|
-
mu: "margin_used",
|
|
25
|
-
cm: "cross_mmr",
|
|
26
|
-
pc: "positions_count",
|
|
27
|
-
oc: "orders_count",
|
|
28
|
-
sc: "stop_orders_count",
|
|
29
|
-
t: "timestamp",
|
|
30
|
-
};
|
|
31
|
-
// WS error codes
|
|
32
|
-
export const WS_CODES = {
|
|
33
|
-
SUCCESS: 200,
|
|
34
|
-
INVALID_REQUEST: 400,
|
|
35
|
-
INVALID_SIGNATURE: 401,
|
|
36
|
-
INVALID_SIGNER: 402,
|
|
37
|
-
UNAUTHORIZED: 403,
|
|
38
|
-
ENGINE_ERROR: 420,
|
|
39
|
-
RATE_LIMIT: 429,
|
|
40
|
-
UNKNOWN_ERROR: 500,
|
|
41
|
-
};
|
|
1
|
+
export {};
|
package/dist/plan-executor.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ExchangeAdapter } from "./exchanges/
|
|
1
|
+
import type { ExchangeAdapter } from "./exchanges/index.js";
|
|
2
2
|
export type PlanAction = "market_order" | "limit_order" | "stop_order" | "cancel_order" | "cancel_all" | "set_leverage" | "close_position" | "wait" | "check_balance" | "check_position";
|
|
3
3
|
export interface PlanStep {
|
|
4
4
|
id: string;
|
package/dist/rebalance.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ExchangeAdapter } from "./exchanges/
|
|
1
|
+
import type { ExchangeAdapter } from "./exchanges/index.js";
|
|
2
2
|
/**
|
|
3
3
|
* Cross-exchange rebalancing engine.
|
|
4
4
|
*
|
|
@@ -48,12 +48,6 @@ export declare function computeRebalancePlan(snapshots: ExchangeBalanceSnapshot[
|
|
|
48
48
|
* Check if an exchange has enough available balance for a given trade size.
|
|
49
49
|
*/
|
|
50
50
|
export declare function hasEnoughBalance(snapshots: ExchangeBalanceSnapshot[], exchange: string, requiredUsd: number, marginBuffer?: number): boolean;
|
|
51
|
-
/**
|
|
52
|
-
* Get the chain/bridge info for an exchange.
|
|
53
|
-
*/
|
|
54
|
-
export declare function getExchangeChain(exchange: string): {
|
|
55
|
-
chain: string;
|
|
56
|
-
};
|
|
57
51
|
/**
|
|
58
52
|
* Describe the bridge route for a rebalance move.
|
|
59
53
|
*/
|
package/dist/rebalance.js
CHANGED
|
@@ -92,12 +92,6 @@ export function hasEnoughBalance(snapshots, exchange, requiredUsd, marginBuffer
|
|
|
92
92
|
return false;
|
|
93
93
|
return snap.available >= requiredUsd * marginBuffer;
|
|
94
94
|
}
|
|
95
|
-
/**
|
|
96
|
-
* Get the chain/bridge info for an exchange.
|
|
97
|
-
*/
|
|
98
|
-
export function getExchangeChain(exchange) {
|
|
99
|
-
return EXCHANGE_CHAINS[exchange];
|
|
100
|
-
}
|
|
101
95
|
/**
|
|
102
96
|
* Describe the bridge route for a rebalance move.
|
|
103
97
|
*/
|
package/dist/risk.d.ts
CHANGED