@vtxmacro/cli 2026.9.52 → 2026.9.53
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/bin/vtx-service-bootstrap.js +13 -3
- package/bin/vtx-service-launcher.js +12 -2
- package/bin/vtx.js +385 -274
- package/package.json +1 -1
|
@@ -16,7 +16,7 @@ import { fileURLToPath } from "node:url";
|
|
|
16
16
|
// agent-cli-release.json
|
|
17
17
|
var agent_cli_release_default = {
|
|
18
18
|
package_name: "@vtxmacro/cli",
|
|
19
|
-
package_version: "2026.9.
|
|
19
|
+
package_version: "2026.9.53",
|
|
20
20
|
codex_package_name: "@openai/codex",
|
|
21
21
|
codex_version: "0.153.3",
|
|
22
22
|
copilot_sdk_package_name: "@github/copilot-sdk",
|
|
@@ -200,6 +200,14 @@ var runtime_policy_generated_default = {
|
|
|
200
200
|
host_liveness_heartbeat_interval_ms: 3e4,
|
|
201
201
|
host_liveness_recovery_nudge_ttl_ms: 1e4
|
|
202
202
|
}
|
|
203
|
+
},
|
|
204
|
+
server_runtime: {
|
|
205
|
+
prompt_rescue: {
|
|
206
|
+
client_long_poll_seconds: 20,
|
|
207
|
+
client_claim_http_timeout_milliseconds: 25e3,
|
|
208
|
+
client_presence_heartbeat_interval_milliseconds: 3e4,
|
|
209
|
+
client_presence_http_timeout_milliseconds: 5e3
|
|
210
|
+
}
|
|
203
211
|
}
|
|
204
212
|
}
|
|
205
213
|
},
|
|
@@ -244,7 +252,7 @@ var runtime_policy_generated_default = {
|
|
|
244
252
|
exchange: {
|
|
245
253
|
hyperliquid: {
|
|
246
254
|
client_public_read_budget: {
|
|
247
|
-
max_weight:
|
|
255
|
+
max_weight: 1200,
|
|
248
256
|
window_seconds: 60,
|
|
249
257
|
cooldown_seconds: 60,
|
|
250
258
|
metadata_ttl_seconds: 300,
|
|
@@ -255,6 +263,7 @@ var runtime_policy_generated_default = {
|
|
|
255
263
|
},
|
|
256
264
|
read_budget: {
|
|
257
265
|
weights: {
|
|
266
|
+
exchange: 1,
|
|
258
267
|
exchangeStatus: 2,
|
|
259
268
|
clearinghouseState: 2,
|
|
260
269
|
spotClearinghouseState: 2,
|
|
@@ -285,7 +294,8 @@ var runtime_policy_generated_default = {
|
|
|
285
294
|
authorizedAgents: 20,
|
|
286
295
|
agents: 20,
|
|
287
296
|
apiWallets: 20
|
|
288
|
-
}
|
|
297
|
+
},
|
|
298
|
+
exchange_action_batch_size: 40
|
|
289
299
|
}
|
|
290
300
|
}
|
|
291
301
|
}
|
|
@@ -83,6 +83,14 @@ var runtime_policy_generated_default = {
|
|
|
83
83
|
host_liveness_heartbeat_interval_ms: 3e4,
|
|
84
84
|
host_liveness_recovery_nudge_ttl_ms: 1e4
|
|
85
85
|
}
|
|
86
|
+
},
|
|
87
|
+
server_runtime: {
|
|
88
|
+
prompt_rescue: {
|
|
89
|
+
client_long_poll_seconds: 20,
|
|
90
|
+
client_claim_http_timeout_milliseconds: 25e3,
|
|
91
|
+
client_presence_heartbeat_interval_milliseconds: 3e4,
|
|
92
|
+
client_presence_http_timeout_milliseconds: 5e3
|
|
93
|
+
}
|
|
86
94
|
}
|
|
87
95
|
}
|
|
88
96
|
},
|
|
@@ -127,7 +135,7 @@ var runtime_policy_generated_default = {
|
|
|
127
135
|
exchange: {
|
|
128
136
|
hyperliquid: {
|
|
129
137
|
client_public_read_budget: {
|
|
130
|
-
max_weight:
|
|
138
|
+
max_weight: 1200,
|
|
131
139
|
window_seconds: 60,
|
|
132
140
|
cooldown_seconds: 60,
|
|
133
141
|
metadata_ttl_seconds: 300,
|
|
@@ -138,6 +146,7 @@ var runtime_policy_generated_default = {
|
|
|
138
146
|
},
|
|
139
147
|
read_budget: {
|
|
140
148
|
weights: {
|
|
149
|
+
exchange: 1,
|
|
141
150
|
exchangeStatus: 2,
|
|
142
151
|
clearinghouseState: 2,
|
|
143
152
|
spotClearinghouseState: 2,
|
|
@@ -168,7 +177,8 @@ var runtime_policy_generated_default = {
|
|
|
168
177
|
authorizedAgents: 20,
|
|
169
178
|
agents: 20,
|
|
170
179
|
apiWallets: 20
|
|
171
|
-
}
|
|
180
|
+
},
|
|
181
|
+
exchange_action_batch_size: 40
|
|
172
182
|
}
|
|
173
183
|
}
|
|
174
184
|
}
|
package/bin/vtx.js
CHANGED
|
@@ -77,7 +77,7 @@ var init_agent_cli_release = __esm({
|
|
|
77
77
|
"agent-cli-release.json"() {
|
|
78
78
|
agent_cli_release_default = {
|
|
79
79
|
package_name: "@vtxmacro/cli",
|
|
80
|
-
package_version: "2026.9.
|
|
80
|
+
package_version: "2026.9.53",
|
|
81
81
|
codex_package_name: "@openai/codex",
|
|
82
82
|
codex_version: "0.153.3",
|
|
83
83
|
copilot_sdk_package_name: "@github/copilot-sdk",
|
|
@@ -20541,6 +20541,14 @@ var init_runtime_policy_generated = __esm({
|
|
|
20541
20541
|
host_liveness_heartbeat_interval_ms: 3e4,
|
|
20542
20542
|
host_liveness_recovery_nudge_ttl_ms: 1e4
|
|
20543
20543
|
}
|
|
20544
|
+
},
|
|
20545
|
+
server_runtime: {
|
|
20546
|
+
prompt_rescue: {
|
|
20547
|
+
client_long_poll_seconds: 20,
|
|
20548
|
+
client_claim_http_timeout_milliseconds: 25e3,
|
|
20549
|
+
client_presence_heartbeat_interval_milliseconds: 3e4,
|
|
20550
|
+
client_presence_http_timeout_milliseconds: 5e3
|
|
20551
|
+
}
|
|
20544
20552
|
}
|
|
20545
20553
|
}
|
|
20546
20554
|
},
|
|
@@ -20585,7 +20593,7 @@ var init_runtime_policy_generated = __esm({
|
|
|
20585
20593
|
exchange: {
|
|
20586
20594
|
hyperliquid: {
|
|
20587
20595
|
client_public_read_budget: {
|
|
20588
|
-
max_weight:
|
|
20596
|
+
max_weight: 1200,
|
|
20589
20597
|
window_seconds: 60,
|
|
20590
20598
|
cooldown_seconds: 60,
|
|
20591
20599
|
metadata_ttl_seconds: 300,
|
|
@@ -20596,6 +20604,7 @@ var init_runtime_policy_generated = __esm({
|
|
|
20596
20604
|
},
|
|
20597
20605
|
read_budget: {
|
|
20598
20606
|
weights: {
|
|
20607
|
+
exchange: 1,
|
|
20599
20608
|
exchangeStatus: 2,
|
|
20600
20609
|
clearinghouseState: 2,
|
|
20601
20610
|
spotClearinghouseState: 2,
|
|
@@ -20626,7 +20635,8 @@ var init_runtime_policy_generated = __esm({
|
|
|
20626
20635
|
authorizedAgents: 20,
|
|
20627
20636
|
agents: 20,
|
|
20628
20637
|
apiWallets: 20
|
|
20629
|
-
}
|
|
20638
|
+
},
|
|
20639
|
+
exchange_action_batch_size: 40
|
|
20630
20640
|
}
|
|
20631
20641
|
}
|
|
20632
20642
|
}
|
|
@@ -42519,6 +42529,14 @@ var init_runtime_policy_generated2 = __esm({
|
|
|
42519
42529
|
host_liveness_heartbeat_interval_ms: 3e4,
|
|
42520
42530
|
host_liveness_recovery_nudge_ttl_ms: 1e4
|
|
42521
42531
|
}
|
|
42532
|
+
},
|
|
42533
|
+
server_runtime: {
|
|
42534
|
+
prompt_rescue: {
|
|
42535
|
+
client_long_poll_seconds: 20,
|
|
42536
|
+
client_claim_http_timeout_milliseconds: 25e3,
|
|
42537
|
+
client_presence_heartbeat_interval_milliseconds: 3e4,
|
|
42538
|
+
client_presence_http_timeout_milliseconds: 5e3
|
|
42539
|
+
}
|
|
42522
42540
|
}
|
|
42523
42541
|
}
|
|
42524
42542
|
},
|
|
@@ -42563,7 +42581,7 @@ var init_runtime_policy_generated2 = __esm({
|
|
|
42563
42581
|
exchange: {
|
|
42564
42582
|
hyperliquid: {
|
|
42565
42583
|
client_public_read_budget: {
|
|
42566
|
-
max_weight:
|
|
42584
|
+
max_weight: 1200,
|
|
42567
42585
|
window_seconds: 60,
|
|
42568
42586
|
cooldown_seconds: 60,
|
|
42569
42587
|
metadata_ttl_seconds: 300,
|
|
@@ -42574,6 +42592,7 @@ var init_runtime_policy_generated2 = __esm({
|
|
|
42574
42592
|
},
|
|
42575
42593
|
read_budget: {
|
|
42576
42594
|
weights: {
|
|
42595
|
+
exchange: 1,
|
|
42577
42596
|
exchangeStatus: 2,
|
|
42578
42597
|
clearinghouseState: 2,
|
|
42579
42598
|
spotClearinghouseState: 2,
|
|
@@ -42604,7 +42623,8 @@ var init_runtime_policy_generated2 = __esm({
|
|
|
42604
42623
|
authorizedAgents: 20,
|
|
42605
42624
|
agents: 20,
|
|
42606
42625
|
apiWallets: 20
|
|
42607
|
-
}
|
|
42626
|
+
},
|
|
42627
|
+
exchange_action_batch_size: 40
|
|
42608
42628
|
}
|
|
42609
42629
|
}
|
|
42610
42630
|
}
|
|
@@ -48546,7 +48566,7 @@ var init_runtime_redaction = __esm({
|
|
|
48546
48566
|
});
|
|
48547
48567
|
|
|
48548
48568
|
// lib/runtime/hyperliquid-public-read.ts
|
|
48549
|
-
var policy, weights, budgets, unpersistedBudgets, cache, pending2, PREFIX, abortError2, checkAbort, wait, storage, loadBudget, saveBudget, withBudgetLock, admit, cooldown, reserveHyperliquidPublicReads, readHyperliquidPublicInfo;
|
|
48569
|
+
var policy, weights, budgets, unpersistedBudgets, cache, pending2, PREFIX, abortError2, checkAbort, wait, storage, loadBudget, saveBudget, withBudgetLock, HyperliquidPublicReadError, cooldownError, admit, cooldown, cacheTtlMs, eligibleCache, reserveHyperliquidPublicReads, releaseHyperliquidPublicReadReservation, admitHyperliquidExchangeRequest, recordHyperliquidExchangeResponse, readHyperliquidPublicInfo;
|
|
48550
48570
|
var init_hyperliquid_public_read = __esm({
|
|
48551
48571
|
"lib/runtime/hyperliquid-public-read.ts"() {
|
|
48552
48572
|
"use strict";
|
|
@@ -48618,31 +48638,54 @@ var init_hyperliquid_public_read = __esm({
|
|
|
48618
48638
|
}
|
|
48619
48639
|
return work();
|
|
48620
48640
|
};
|
|
48621
|
-
|
|
48641
|
+
HyperliquidPublicReadError = class extends Error {
|
|
48642
|
+
constructor(code, message, requestType, status, retryAfterMs, requiredWeight, usedWeight, maxWeight) {
|
|
48643
|
+
super(message);
|
|
48644
|
+
this.code = code;
|
|
48645
|
+
this.requestType = requestType;
|
|
48646
|
+
this.status = status;
|
|
48647
|
+
this.retryAfterMs = retryAfterMs;
|
|
48648
|
+
this.requiredWeight = requiredWeight;
|
|
48649
|
+
this.usedWeight = usedWeight;
|
|
48650
|
+
this.maxWeight = maxWeight;
|
|
48651
|
+
this.name = "HyperliquidPublicReadError";
|
|
48652
|
+
}
|
|
48653
|
+
};
|
|
48654
|
+
cooldownError = (requestType, until) => new HyperliquidPublicReadError(
|
|
48655
|
+
"public_cooldown_active",
|
|
48656
|
+
"Hyperliquid public request cooldown is active.",
|
|
48657
|
+
requestType,
|
|
48658
|
+
void 0,
|
|
48659
|
+
Math.max(0, until - Date.now())
|
|
48660
|
+
);
|
|
48661
|
+
admit = async (apiUrl, requestType, signal, bundleWeight, bundleId, deadlineMs) => {
|
|
48622
48662
|
const key = `${PREFIX}${apiUrl}`;
|
|
48623
48663
|
const weight = bundleWeight ?? weights[requestType] ?? policy.default_request_weight;
|
|
48624
|
-
if (!(weight > 0 && weight <= policy.max_weight)) throw new
|
|
48664
|
+
if (!(weight > 0 && weight <= policy.max_weight)) throw new HyperliquidPublicReadError("public_budget_exhausted", "Hyperliquid public request exceeds the available allowance.", requestType, void 0, void 0, weight, void 0, policy.max_weight);
|
|
48625
48665
|
for (; ; ) {
|
|
48626
48666
|
checkAbort(signal);
|
|
48627
|
-
const delay2 = await withBudgetLock(key, signal, () => {
|
|
48667
|
+
const { delay: delay2, usedWeight } = await withBudgetLock(key, signal, () => {
|
|
48628
48668
|
const now = Date.now();
|
|
48629
48669
|
const budget = loadBudget(key);
|
|
48630
48670
|
budget.reservations = budget.reservations.filter((r) => r.at > now - policy.window_seconds * 1e3);
|
|
48631
|
-
if (budget.cooldownUntil > now) throw
|
|
48671
|
+
if (budget.cooldownUntil > now) throw cooldownError(requestType, budget.cooldownUntil);
|
|
48632
48672
|
let used = budget.reservations.reduce((sum, r) => sum + r.weight, 0);
|
|
48673
|
+
const usedWeight2 = used;
|
|
48633
48674
|
if (used + weight <= policy.max_weight) {
|
|
48634
48675
|
budget.reservations.push({ at: now, weight, ...bundleId ? { id: bundleId } : {} });
|
|
48635
48676
|
saveBudget(key, budget);
|
|
48636
|
-
return 0;
|
|
48677
|
+
return { delay: 0, usedWeight: usedWeight2 };
|
|
48637
48678
|
}
|
|
48638
48679
|
for (const reservation of budget.reservations) {
|
|
48639
48680
|
used -= reservation.weight;
|
|
48640
|
-
if (used + weight <= policy.max_weight) return Math.max(1, reservation.at + policy.window_seconds * 1e3 - now);
|
|
48681
|
+
if (used + weight <= policy.max_weight) return { delay: Math.max(1, reservation.at + policy.window_seconds * 1e3 - now), usedWeight: usedWeight2 };
|
|
48641
48682
|
}
|
|
48642
48683
|
throw new Error("Invalid Hyperliquid public read budget.");
|
|
48643
48684
|
});
|
|
48644
48685
|
if (!delay2) return;
|
|
48645
|
-
if (bundleWeight != null
|
|
48686
|
+
if (bundleWeight != null || deadlineMs != null && Date.now() + delay2 >= deadlineMs) {
|
|
48687
|
+
throw new HyperliquidPublicReadError("public_budget_exhausted", "Hyperliquid local public request allowance is exhausted.", requestType, void 0, delay2, weight, usedWeight, policy.max_weight);
|
|
48688
|
+
}
|
|
48646
48689
|
await wait(delay2, signal);
|
|
48647
48690
|
}
|
|
48648
48691
|
};
|
|
@@ -48657,29 +48700,70 @@ var init_hyperliquid_public_read = __esm({
|
|
|
48657
48700
|
saveBudget(key, budget);
|
|
48658
48701
|
});
|
|
48659
48702
|
};
|
|
48660
|
-
|
|
48703
|
+
cacheTtlMs = (body, options) => {
|
|
48704
|
+
const requestType = String(body.type);
|
|
48705
|
+
return (["meta", "spotMeta", "perpDexs"].includes(requestType) ? policy.metadata_ttl_seconds : requestType === "userFees" ? policy.user_fees_ttl_seconds : options.cacheAccountMode && ["userAbstraction", "userDexAbstraction"].includes(requestType) ? policy.account_mode_ttl_seconds : 0) * 1e3;
|
|
48706
|
+
};
|
|
48707
|
+
eligibleCache = (apiUrl, body, options) => {
|
|
48708
|
+
const ttl = cacheTtlMs(body, options);
|
|
48709
|
+
const existing = cache.get(`${apiUrl}:${JSON.stringify(body)}`);
|
|
48710
|
+
const horizon = Math.max(Date.now(), options.cacheValidUntilMs ?? Date.now());
|
|
48711
|
+
return ttl > 0 && existing && Date.now() >= existing.fetchedAtMs && horizon - existing.fetchedAtMs < ttl ? existing : void 0;
|
|
48712
|
+
};
|
|
48713
|
+
reserveHyperliquidPublicReads = async (endpoint, bodies, signal, options = {}) => {
|
|
48661
48714
|
const apiUrl = endpoint.replace(/\/$/, "");
|
|
48662
|
-
const
|
|
48663
|
-
const id2 = crypto.randomUUID();
|
|
48664
|
-
const admittedAtMs = Date.now();
|
|
48665
|
-
await admit(apiUrl, "bundle", signal, weight, id2);
|
|
48715
|
+
const cached2 = /* @__PURE__ */ new Map();
|
|
48666
48716
|
const remaining = /* @__PURE__ */ new Map();
|
|
48717
|
+
let weight = 0;
|
|
48667
48718
|
for (const body of bodies) {
|
|
48668
48719
|
const key = JSON.stringify(body);
|
|
48720
|
+
const hit = eligibleCache(apiUrl, body, options);
|
|
48721
|
+
if (hit) {
|
|
48722
|
+
cached2.set(key, hit);
|
|
48723
|
+
continue;
|
|
48724
|
+
}
|
|
48669
48725
|
remaining.set(key, (remaining.get(key) ?? 0) + 1);
|
|
48726
|
+
weight += weights[String(body.type)] ?? policy.default_request_weight;
|
|
48670
48727
|
}
|
|
48671
|
-
|
|
48728
|
+
const id2 = crypto.randomUUID();
|
|
48729
|
+
const admittedAtMs = Date.now();
|
|
48730
|
+
if (weight) await admit(apiUrl, "bundle", signal, weight, id2, options.cacheValidUntilMs);
|
|
48731
|
+
return { id: id2, closed: false, endpoint: apiUrl, expiresAtMs: admittedAtMs + policy.window_seconds * 1e3, remaining, cached: cached2, cacheValidUntilMs: options.cacheValidUntilMs };
|
|
48732
|
+
};
|
|
48733
|
+
releaseHyperliquidPublicReadReservation = async (reservation) => {
|
|
48734
|
+
reservation.closed = true;
|
|
48735
|
+
const key = `${PREFIX}${reservation.endpoint}`;
|
|
48736
|
+
await withBudgetLock(key, void 0, () => {
|
|
48737
|
+
const budget = loadBudget(key);
|
|
48738
|
+
const row = budget.reservations.find((entry) => entry.id === reservation.id);
|
|
48739
|
+
if (row) {
|
|
48740
|
+
const unused = [...reservation.remaining].reduce((sum, [body, count4]) => sum + (weights[String(JSON.parse(body).type)] ?? policy.default_request_weight) * count4, 0);
|
|
48741
|
+
row.weight = Math.max(0, row.weight - unused);
|
|
48742
|
+
budget.reservations = budget.reservations.filter((entry) => entry.weight > 0);
|
|
48743
|
+
saveBudget(key, budget);
|
|
48744
|
+
}
|
|
48745
|
+
reservation.remaining.clear();
|
|
48746
|
+
});
|
|
48747
|
+
};
|
|
48748
|
+
admitHyperliquidExchangeRequest = async (endpoint, action, signal) => {
|
|
48749
|
+
const batchLength = Math.max(0, ...[action.orders, action.cancels, action.modifies].filter(Array.isArray).map((value) => value.length));
|
|
48750
|
+
const weight = weights.exchange + Math.floor(batchLength / runtime_policy_generated_default.exchange.hyperliquid.read_budget.exchange_action_batch_size);
|
|
48751
|
+
await admit(endpoint.replace(/\/$/, ""), "exchange", signal, weight);
|
|
48752
|
+
};
|
|
48753
|
+
recordHyperliquidExchangeResponse = async (endpoint, response) => {
|
|
48754
|
+
if (response.status === 429) await cooldown(endpoint.replace(/\/$/, ""), response.headers.get("Retry-After"));
|
|
48672
48755
|
};
|
|
48673
48756
|
readHyperliquidPublicInfo = async (endpoint, body, options = {}) => {
|
|
48674
48757
|
const apiUrl = endpoint.replace(/\/$/, "");
|
|
48675
48758
|
const requestType = String(body.type ?? "info");
|
|
48676
|
-
const
|
|
48759
|
+
const cacheOptions = { ...options, cacheValidUntilMs: options.reservation?.cacheValidUntilMs ?? options.cacheValidUntilMs };
|
|
48760
|
+
const ttlMs = cacheTtlMs(body, cacheOptions);
|
|
48677
48761
|
const key = `${apiUrl}:${JSON.stringify(body)}`;
|
|
48678
48762
|
checkAbort(options.signal);
|
|
48679
|
-
if (
|
|
48763
|
+
if (ttlMs) {
|
|
48680
48764
|
for (; ; ) {
|
|
48681
|
-
const existing =
|
|
48682
|
-
if (existing
|
|
48765
|
+
const existing = options.reservation?.cached.get(JSON.stringify(body)) ?? eligibleCache(apiUrl, body, cacheOptions);
|
|
48766
|
+
if (existing) return existing;
|
|
48683
48767
|
const running = pending2.get(key);
|
|
48684
48768
|
if (!running) break;
|
|
48685
48769
|
await new Promise((resolve13, reject) => {
|
|
@@ -48697,26 +48781,31 @@ var init_hyperliquid_public_read = __esm({
|
|
|
48697
48781
|
}
|
|
48698
48782
|
}
|
|
48699
48783
|
let settled;
|
|
48700
|
-
if (
|
|
48784
|
+
if (ttlMs) pending2.set(key, new Promise((resolve13) => {
|
|
48701
48785
|
settled = resolve13;
|
|
48702
48786
|
}));
|
|
48703
48787
|
try {
|
|
48704
48788
|
const reservedKey = JSON.stringify(body);
|
|
48705
48789
|
const remaining = options.reservation?.remaining.get(reservedKey) ?? 0;
|
|
48706
48790
|
if (options.reservation?.endpoint === apiUrl && remaining > 0) {
|
|
48707
|
-
if (Date.now() >= options.reservation.expiresAtMs) throw
|
|
48791
|
+
if (Date.now() >= options.reservation.expiresAtMs) throw new HyperliquidPublicReadError("public_budget_exhausted", "Hyperliquid public read reservation expired.", requestType);
|
|
48708
48792
|
await withBudgetLock(`${PREFIX}${apiUrl}`, options.signal, () => {
|
|
48793
|
+
if (options.reservation.closed) throw new HyperliquidPublicReadError("public_budget_exhausted", "Hyperliquid public read bundle is closed.", requestType);
|
|
48794
|
+
if ((options.reservation.remaining.get(reservedKey) ?? 0) <= 0) throw new HyperliquidPublicReadError("public_budget_exhausted", "Hyperliquid request is outside its admitted bundle.", requestType);
|
|
48709
48795
|
const budget = loadBudget(`${PREFIX}${apiUrl}`);
|
|
48710
48796
|
const row = budget.reservations.find((entry) => entry.id === options.reservation.id);
|
|
48711
|
-
if (!row || Date.now() >= options.reservation.expiresAtMs) throw
|
|
48797
|
+
if (!row || Date.now() >= options.reservation.expiresAtMs) throw new HyperliquidPublicReadError("public_budget_exhausted", "Hyperliquid public read reservation expired.", requestType);
|
|
48712
48798
|
row.at = Date.now();
|
|
48713
48799
|
budget.reservations.sort((a, b2) => a.at - b2.at);
|
|
48800
|
+
options.reservation.remaining.set(reservedKey, (options.reservation.remaining.get(reservedKey) ?? 0) - 1);
|
|
48714
48801
|
saveBudget(`${PREFIX}${apiUrl}`, budget);
|
|
48715
48802
|
});
|
|
48716
|
-
|
|
48717
|
-
|
|
48803
|
+
} else if (options.reservation) throw new HyperliquidPublicReadError("public_budget_exhausted", "Hyperliquid request is outside its admitted bundle.", requestType);
|
|
48804
|
+
else await admit(apiUrl, requestType, options.signal, void 0, void 0, options.deadlineMs);
|
|
48718
48805
|
checkAbort(options.signal);
|
|
48719
|
-
if (
|
|
48806
|
+
if (options.reservation?.closed) throw new HyperliquidPublicReadError("public_budget_exhausted", "Hyperliquid public read bundle is closed.", requestType);
|
|
48807
|
+
const cooldownUntil = loadBudget(`${PREFIX}${apiUrl}`).cooldownUntil;
|
|
48808
|
+
if (cooldownUntil > Date.now()) throw cooldownError(requestType, cooldownUntil);
|
|
48720
48809
|
const response = await fetch(`${apiUrl}/info`, {
|
|
48721
48810
|
method: "POST",
|
|
48722
48811
|
headers: { "Content-Type": "application/json" },
|
|
@@ -48724,22 +48813,31 @@ var init_hyperliquid_public_read = __esm({
|
|
|
48724
48813
|
signal: options.signal
|
|
48725
48814
|
});
|
|
48726
48815
|
if (response.status === 429) await cooldown(apiUrl, response.headers.get("Retry-After"));
|
|
48727
|
-
const payload = await response.json().catch(() =>
|
|
48816
|
+
const payload = await response.json().catch((error48) => {
|
|
48817
|
+
if (error48 instanceof SyntaxError) return {};
|
|
48818
|
+
throw error48;
|
|
48819
|
+
});
|
|
48728
48820
|
if (!response.ok) {
|
|
48729
48821
|
const detail = sanitizeRuntimeDiagnosticValue(typeof payload?.response === "string" ? payload.response : typeof payload?.detail === "string" ? payload.detail : "");
|
|
48822
|
+
if (response.status === 429) throw new HyperliquidPublicReadError("public_rate_limited", "Hyperliquid public API returned HTTP 429.", requestType, 429);
|
|
48730
48823
|
throw Object.assign(new Error(`Hyperliquid info request failed (${response.status}) request_type=${requestType}.${detail ? ` ${detail}` : ""}`), {
|
|
48731
48824
|
status: response.status,
|
|
48732
48825
|
requestType
|
|
48733
48826
|
});
|
|
48734
48827
|
}
|
|
48735
48828
|
const result2 = { payload, fetchedAtMs: Date.now() };
|
|
48736
|
-
if (
|
|
48829
|
+
if (ttlMs) {
|
|
48737
48830
|
cache.set(key, result2);
|
|
48738
48831
|
while (cache.size > policy.cache_max_entries) cache.delete(cache.keys().next().value);
|
|
48739
48832
|
}
|
|
48740
48833
|
return result2;
|
|
48834
|
+
} catch (error48) {
|
|
48835
|
+
if (options.signal?.aborted || error48 instanceof HyperliquidPublicReadError) throw error48;
|
|
48836
|
+
if (error48 instanceof TypeError) throw new HyperliquidPublicReadError("public_network_error", "Hyperliquid public request network failure.", requestType);
|
|
48837
|
+
if (error48 instanceof Error && (error48.name === "TimeoutError" || error48.name === "AbortError")) throw new HyperliquidPublicReadError("public_timeout", "Hyperliquid public request timed out.", requestType);
|
|
48838
|
+
throw error48;
|
|
48741
48839
|
} finally {
|
|
48742
|
-
if (
|
|
48840
|
+
if (ttlMs) {
|
|
48743
48841
|
pending2.delete(key);
|
|
48744
48842
|
settled?.();
|
|
48745
48843
|
}
|
|
@@ -50736,273 +50834,283 @@ var init_hyperliquid_account_state_adapter = __esm({
|
|
|
50736
50834
|
dexNames,
|
|
50737
50835
|
staleIf429MaxAgeMs
|
|
50738
50836
|
}) => {
|
|
50739
|
-
const
|
|
50740
|
-
...await readHyperliquidPublicInfo(apiUrl, { type: "userFees", user: walletAddress }, { signal: input.signal }).catch((error48) => {
|
|
50741
|
-
if (input.signal?.aborted) throw error48;
|
|
50742
|
-
return { payload: null, fetchedAtMs: Date.now() };
|
|
50743
|
-
}).then((result2) => ({ payload: result2.payload, capturedAt: new Date(result2.fetchedAtMs).toISOString() }))
|
|
50744
|
-
}))() : Promise.resolve(null);
|
|
50745
|
-
const exactAccountModePromise = input.includeExactAccountMode === true ? (async () => {
|
|
50746
|
-
const abstractionRead = await readHyperliquidPublicInfo(apiUrl, { type: "userAbstraction", user: walletAddress }, { signal: input.signal, cacheAccountMode: true });
|
|
50747
|
-
const userAbstraction = abstractionRead.payload;
|
|
50748
|
-
let capturedAtMs = abstractionRead.fetchedAtMs;
|
|
50749
|
-
const preliminaryMode = extractCanonicalHyperliquidAccountMode(userAbstraction);
|
|
50750
|
-
if (!preliminaryMode) {
|
|
50751
|
-
throw new Error("Exact Hyperliquid userAbstraction response is invalid.");
|
|
50752
|
-
}
|
|
50753
|
-
let userDexAbstraction;
|
|
50754
|
-
if (preliminaryMode === "default" || preliminaryMode === "disabled") {
|
|
50755
|
-
const dexRead = await readHyperliquidPublicInfo(apiUrl, { type: "userDexAbstraction", user: walletAddress }, { signal: input.signal, cacheAccountMode: true });
|
|
50756
|
-
userDexAbstraction = dexRead.payload;
|
|
50757
|
-
capturedAtMs = Math.min(capturedAtMs, dexRead.fetchedAtMs);
|
|
50758
|
-
}
|
|
50759
|
-
return {
|
|
50760
|
-
accountMode: resolveExactHyperliquidAccountMode(
|
|
50761
|
-
userAbstraction,
|
|
50762
|
-
userDexAbstraction
|
|
50763
|
-
),
|
|
50764
|
-
capturedAt: new Date(capturedAtMs).toISOString()
|
|
50765
|
-
};
|
|
50766
|
-
})() : Promise.resolve(null);
|
|
50767
|
-
await Promise.all([userFeesPromise, exactAccountModePromise]);
|
|
50768
|
-
const metadataByDex = /* @__PURE__ */ new Map();
|
|
50769
|
-
if (input.includeEffectiveTakerRate === true) {
|
|
50770
|
-
await Promise.all(["", ...dexNames].map(async (dex) => {
|
|
50771
|
-
try {
|
|
50772
|
-
metadataByDex.set(dex, await fetchHyperliquidInfoPayload(apiUrl, { type: "meta", ...dex ? { dex } : {} }, input.signal));
|
|
50773
|
-
} catch (error48) {
|
|
50774
|
-
if (input.signal?.aborted) throw error48;
|
|
50775
|
-
metadataByDex.set(dex, null);
|
|
50776
|
-
}
|
|
50777
|
-
}));
|
|
50778
|
-
}
|
|
50837
|
+
const metadataBodies = input.includeEffectiveTakerRate === true ? ["", ...dexNames].map((dex) => ({ type: "meta", ...dex ? { dex } : {} })) : [];
|
|
50779
50838
|
const reservation = await reserveHyperliquidPublicReads(apiUrl, [
|
|
50780
50839
|
{ type: "clearinghouseState", user: walletAddress },
|
|
50781
50840
|
...dexNames.map((dex) => ({ type: "clearinghouseState", user: walletAddress, dex })),
|
|
50782
50841
|
{ type: "spotClearinghouseState", user: walletAddress },
|
|
50783
|
-
...input.includeActiveAssetData === false ? [] : activeAssetRequestTypes.map((type) => ({ type, user: walletAddress, coin: symbol2 }))
|
|
50784
|
-
|
|
50785
|
-
|
|
50786
|
-
|
|
50787
|
-
|
|
50788
|
-
|
|
50789
|
-
|
|
50790
|
-
|
|
50791
|
-
)
|
|
50842
|
+
...input.includeActiveAssetData === false ? [] : activeAssetRequestTypes.map((type) => ({ type, user: walletAddress, coin: symbol2 })),
|
|
50843
|
+
...input.includeEffectiveTakerRate === true ? [{ type: "userFees", user: walletAddress }, ...metadataBodies] : [],
|
|
50844
|
+
...input.includeExactAccountMode === true ? [
|
|
50845
|
+
{ type: "userAbstraction", user: walletAddress },
|
|
50846
|
+
{ type: "userDexAbstraction", user: walletAddress }
|
|
50847
|
+
] : []
|
|
50848
|
+
], input.signal, { cacheAccountMode: true, cacheValidUntilMs: input.publicReadDeadlineMs });
|
|
50849
|
+
try {
|
|
50850
|
+
const userFeesPromise = input.includeEffectiveTakerRate === true ? (async () => ({
|
|
50851
|
+
...await readHyperliquidPublicInfo(apiUrl, { type: "userFees", user: walletAddress }, { signal: input.signal, reservation }).catch((error48) => {
|
|
50852
|
+
if (input.signal?.aborted || error48 instanceof HyperliquidPublicReadError || isRateLimitError(error48)) throw error48;
|
|
50853
|
+
return { payload: null, fetchedAtMs: Date.now() };
|
|
50854
|
+
}).then((result2) => ({ payload: result2.payload, capturedAt: new Date(result2.fetchedAtMs).toISOString() }))
|
|
50855
|
+
}))() : Promise.resolve(null);
|
|
50856
|
+
const exactAccountModePromise = input.includeExactAccountMode === true ? (async () => {
|
|
50857
|
+
const abstractionRead = await readHyperliquidPublicInfo(apiUrl, { type: "userAbstraction", user: walletAddress }, { signal: input.signal, reservation, cacheAccountMode: true });
|
|
50858
|
+
const userAbstraction = abstractionRead.payload;
|
|
50859
|
+
let capturedAtMs = abstractionRead.fetchedAtMs;
|
|
50860
|
+
const preliminaryMode = extractCanonicalHyperliquidAccountMode(userAbstraction);
|
|
50861
|
+
if (!preliminaryMode) {
|
|
50862
|
+
throw new Error("Exact Hyperliquid userAbstraction response is invalid.");
|
|
50863
|
+
}
|
|
50864
|
+
let userDexAbstraction;
|
|
50865
|
+
if (preliminaryMode === "default" || preliminaryMode === "disabled") {
|
|
50866
|
+
const dexRead = await readHyperliquidPublicInfo(apiUrl, { type: "userDexAbstraction", user: walletAddress }, { signal: input.signal, reservation, cacheAccountMode: true });
|
|
50867
|
+
userDexAbstraction = dexRead.payload;
|
|
50868
|
+
capturedAtMs = Math.min(capturedAtMs, dexRead.fetchedAtMs);
|
|
50869
|
+
}
|
|
50870
|
+
return {
|
|
50871
|
+
accountMode: resolveExactHyperliquidAccountMode(
|
|
50872
|
+
userAbstraction,
|
|
50873
|
+
userDexAbstraction
|
|
50874
|
+
),
|
|
50875
|
+
capturedAt: new Date(capturedAtMs).toISOString()
|
|
50876
|
+
};
|
|
50877
|
+
})() : Promise.resolve(null);
|
|
50878
|
+
await Promise.all([userFeesPromise, exactAccountModePromise]);
|
|
50879
|
+
const metadataByDex = /* @__PURE__ */ new Map();
|
|
50792
50880
|
if (input.includeEffectiveTakerRate === true) {
|
|
50793
|
-
|
|
50794
|
-
|
|
50795
|
-
|
|
50796
|
-
|
|
50797
|
-
|
|
50798
|
-
|
|
50799
|
-
{ type: "clearinghouseState", user: walletAddress, dex: dexName },
|
|
50800
|
-
input.signal,
|
|
50801
|
-
reservation
|
|
50802
|
-
);
|
|
50803
|
-
if (input.includeEffectiveTakerRate === true) {
|
|
50804
|
-
requirePromptClearinghouseState(response, dexName);
|
|
50881
|
+
await Promise.all(["", ...dexNames].map(async (dex) => {
|
|
50882
|
+
try {
|
|
50883
|
+
metadataByDex.set(dex, await fetchHyperliquidInfoPayload(apiUrl, { type: "meta", ...dex ? { dex } : {} }, input.signal, reservation));
|
|
50884
|
+
} catch (error48) {
|
|
50885
|
+
if (input.signal?.aborted || error48 instanceof HyperliquidPublicReadError || isRateLimitError(error48)) throw error48;
|
|
50886
|
+
metadataByDex.set(dex, null);
|
|
50805
50887
|
}
|
|
50806
|
-
|
|
50807
|
-
dex: dexName,
|
|
50808
|
-
payload: prefixHip3PositionCoins(response, dexName),
|
|
50809
|
-
rawPayload: response
|
|
50810
|
-
};
|
|
50811
|
-
})
|
|
50812
|
-
);
|
|
50813
|
-
const selectedPayload = selectedDex ? dexResponses.find((entry) => entry.dex === selectedDex)?.payload : defaultResponse;
|
|
50814
|
-
if (!selectedPayload) {
|
|
50815
|
-
throw new Error(`Missing selected Hyperliquid clearinghouse state for DEX ${selectedDex}.`);
|
|
50888
|
+
}));
|
|
50816
50889
|
}
|
|
50817
|
-
|
|
50818
|
-
|
|
50819
|
-
defaultResponse,
|
|
50820
|
-
...dexResponses.map((entry) => entry.payload)
|
|
50821
|
-
]),
|
|
50822
|
-
selectedPayload,
|
|
50823
|
-
dexPayloads: [
|
|
50824
|
-
{ dex: "", payload: defaultResponse },
|
|
50825
|
-
...dexResponses.map(({ dex, rawPayload }) => ({ dex, payload: rawPayload }))
|
|
50826
|
-
],
|
|
50827
|
-
capturedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
50828
|
-
};
|
|
50829
|
-
})();
|
|
50830
|
-
const spotPromise = (async () => {
|
|
50831
|
-
let payload;
|
|
50832
|
-
try {
|
|
50833
|
-
payload = await fetchHyperliquidInfoPayload(
|
|
50890
|
+
const perpsPromise = (async () => {
|
|
50891
|
+
const defaultResponse = await fetchHyperliquidInfoPayload(
|
|
50834
50892
|
apiUrl,
|
|
50835
|
-
{ type: "
|
|
50893
|
+
{ type: "clearinghouseState", user: walletAddress },
|
|
50836
50894
|
input.signal,
|
|
50837
50895
|
reservation
|
|
50838
50896
|
);
|
|
50839
|
-
|
|
50840
|
-
|
|
50841
|
-
|
|
50842
|
-
|
|
50897
|
+
if (input.includeEffectiveTakerRate === true) {
|
|
50898
|
+
requirePromptClearinghouseState(defaultResponse, "default");
|
|
50899
|
+
}
|
|
50900
|
+
const dexResponses = await Promise.all(
|
|
50901
|
+
dexNames.map(async (dexName) => {
|
|
50902
|
+
const response = await fetchHyperliquidInfoPayload(
|
|
50903
|
+
apiUrl,
|
|
50904
|
+
{ type: "clearinghouseState", user: walletAddress, dex: dexName },
|
|
50905
|
+
input.signal,
|
|
50906
|
+
reservation
|
|
50907
|
+
);
|
|
50908
|
+
if (input.includeEffectiveTakerRate === true) {
|
|
50909
|
+
requirePromptClearinghouseState(response, dexName);
|
|
50910
|
+
}
|
|
50911
|
+
return {
|
|
50912
|
+
dex: dexName,
|
|
50913
|
+
payload: prefixHip3PositionCoins(response, dexName),
|
|
50914
|
+
rawPayload: response
|
|
50915
|
+
};
|
|
50916
|
+
})
|
|
50917
|
+
);
|
|
50918
|
+
const selectedPayload = selectedDex ? dexResponses.find((entry) => entry.dex === selectedDex)?.payload : defaultResponse;
|
|
50919
|
+
if (!selectedPayload) {
|
|
50920
|
+
throw new Error(`Missing selected Hyperliquid clearinghouse state for DEX ${selectedDex}.`);
|
|
50843
50921
|
}
|
|
50844
|
-
|
|
50845
|
-
|
|
50846
|
-
|
|
50847
|
-
|
|
50848
|
-
|
|
50849
|
-
|
|
50850
|
-
|
|
50922
|
+
return {
|
|
50923
|
+
payload: aggregateClearinghouseResponses([
|
|
50924
|
+
defaultResponse,
|
|
50925
|
+
...dexResponses.map((entry) => entry.payload)
|
|
50926
|
+
]),
|
|
50927
|
+
selectedPayload,
|
|
50928
|
+
dexPayloads: [
|
|
50929
|
+
{ dex: "", payload: defaultResponse },
|
|
50930
|
+
...dexResponses.map(({ dex, rawPayload }) => ({ dex, payload: rawPayload }))
|
|
50931
|
+
],
|
|
50932
|
+
capturedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
50933
|
+
};
|
|
50934
|
+
})();
|
|
50935
|
+
const spotPromise = (async () => {
|
|
50936
|
+
let payload;
|
|
50851
50937
|
try {
|
|
50852
|
-
|
|
50938
|
+
payload = await fetchHyperliquidInfoPayload(
|
|
50853
50939
|
apiUrl,
|
|
50854
|
-
{ type:
|
|
50940
|
+
{ type: "spotClearinghouseState", user: walletAddress },
|
|
50855
50941
|
input.signal,
|
|
50856
50942
|
reservation
|
|
50857
50943
|
);
|
|
50858
|
-
return { payload, type: typeName };
|
|
50859
50944
|
} catch (error48) {
|
|
50860
|
-
lastError = error48;
|
|
50861
50945
|
recordInfoRateLimitCooldownFromError(apiUrl, error48, staleIf429MaxAgeMs);
|
|
50862
|
-
if (
|
|
50863
|
-
|
|
50864
|
-
rememberUnsupportedUserActiveAssetKey(activeAssetCacheKey);
|
|
50946
|
+
if (input.forceRefresh || input.includeEffectiveTakerRate === true) {
|
|
50947
|
+
throw error48;
|
|
50865
50948
|
}
|
|
50949
|
+
payload = {};
|
|
50866
50950
|
}
|
|
50867
|
-
|
|
50868
|
-
|
|
50869
|
-
|
|
50870
|
-
|
|
50871
|
-
|
|
50872
|
-
|
|
50873
|
-
|
|
50874
|
-
|
|
50875
|
-
|
|
50876
|
-
|
|
50877
|
-
|
|
50878
|
-
|
|
50879
|
-
|
|
50880
|
-
|
|
50881
|
-
|
|
50882
|
-
|
|
50883
|
-
|
|
50884
|
-
|
|
50885
|
-
|
|
50886
|
-
|
|
50887
|
-
|
|
50888
|
-
}
|
|
50889
|
-
let effectiveTakerRates;
|
|
50890
|
-
if (input.includeEffectiveTakerRate === true) {
|
|
50891
|
-
const feeSymbols = [...new Set([
|
|
50892
|
-
...input.feeSymbols ?? [symbol2],
|
|
50893
|
-
...parseInfoPositions(perpsResponse).filter((position) => Number(position.size) !== 0).map((position) => position.symbol)
|
|
50894
|
-
].map(normalizeHyperliquidMarketSymbol).filter(Boolean))].sort();
|
|
50895
|
-
const feeDexes = [...new Set(feeSymbols.map(getHyperliquidMarketDex))];
|
|
50896
|
-
const metadata = await Promise.all(feeDexes.map(async (dex) => {
|
|
50897
|
-
try {
|
|
50898
|
-
const payload = metadataByDex.get(dex) ?? null;
|
|
50899
|
-
return [dex, payload];
|
|
50900
|
-
} catch (error48) {
|
|
50901
|
-
if (input.signal?.aborted) throw error48;
|
|
50902
|
-
return [dex, null];
|
|
50951
|
+
return { payload, capturedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
50952
|
+
})();
|
|
50953
|
+
const activeAssetPromise = input.includeActiveAssetData === false ? Promise.resolve(null) : (async () => {
|
|
50954
|
+
let lastError = null;
|
|
50955
|
+
for (const typeName of activeAssetRequestTypes) {
|
|
50956
|
+
try {
|
|
50957
|
+
const payload = await fetchHyperliquidInfoPayload(
|
|
50958
|
+
apiUrl,
|
|
50959
|
+
{ type: typeName, user: walletAddress, coin: symbol2 },
|
|
50960
|
+
input.signal,
|
|
50961
|
+
reservation
|
|
50962
|
+
);
|
|
50963
|
+
return { payload, type: typeName };
|
|
50964
|
+
} catch (error48) {
|
|
50965
|
+
lastError = error48;
|
|
50966
|
+
recordInfoRateLimitCooldownFromError(apiUrl, error48, staleIf429MaxAgeMs);
|
|
50967
|
+
if (isRateLimitError(error48)) throw error48;
|
|
50968
|
+
if (typeName === "userActiveAssetData" && isUnsupportedUserActiveAssetError(error48)) {
|
|
50969
|
+
rememberUnsupportedUserActiveAssetKey(activeAssetCacheKey);
|
|
50970
|
+
}
|
|
50971
|
+
}
|
|
50903
50972
|
}
|
|
50904
|
-
|
|
50905
|
-
|
|
50906
|
-
|
|
50907
|
-
|
|
50908
|
-
|
|
50909
|
-
|
|
50910
|
-
|
|
50911
|
-
|
|
50912
|
-
|
|
50913
|
-
|
|
50914
|
-
|
|
50915
|
-
|
|
50916
|
-
|
|
50917
|
-
|
|
50918
|
-
|
|
50919
|
-
|
|
50920
|
-
|
|
50921
|
-
|
|
50922
|
-
|
|
50923
|
-
|
|
50924
|
-
|
|
50925
|
-
|
|
50926
|
-
|
|
50973
|
+
throw lastError instanceof Error ? lastError : new Error("Failed to fetch browser active asset data.");
|
|
50974
|
+
})();
|
|
50975
|
+
const [perpsResult, spotResult, activeAssetResult, userFeesResult, exactAccountMode] = await Promise.all([
|
|
50976
|
+
perpsPromise,
|
|
50977
|
+
spotPromise,
|
|
50978
|
+
activeAssetPromise,
|
|
50979
|
+
userFeesPromise,
|
|
50980
|
+
exactAccountModePromise
|
|
50981
|
+
]);
|
|
50982
|
+
const perpsResponse = perpsResult.payload;
|
|
50983
|
+
const accountSummaryPerpsResponse = input.scopeAccountSummaryToSelectedDex === true ? perpsResult.selectedPayload : perpsResponse;
|
|
50984
|
+
const spotResponse = spotResult.payload;
|
|
50985
|
+
const userFeesResponse = userFeesResult?.payload ?? null;
|
|
50986
|
+
if (input.includeEffectiveTakerRate === true) {
|
|
50987
|
+
requirePromptSpotState(spotResponse);
|
|
50988
|
+
}
|
|
50989
|
+
let takerRate;
|
|
50990
|
+
if (input.includeEffectiveTakerRate === true) {
|
|
50991
|
+
const raw = userFeesResponse?.userCrossRate;
|
|
50992
|
+
if ((typeof raw === "number" || typeof raw === "string" && raw.trim() !== "") && Number.isFinite(Number(raw)) && Number(raw) >= 0 && Number(raw) < 1) takerRate = Number(raw);
|
|
50993
|
+
}
|
|
50994
|
+
let effectiveTakerRates;
|
|
50995
|
+
if (input.includeEffectiveTakerRate === true) {
|
|
50996
|
+
const feeSymbols = [...new Set([
|
|
50997
|
+
...input.feeSymbols ?? [symbol2],
|
|
50998
|
+
...parseInfoPositions(perpsResponse).filter((position) => Number(position.size) !== 0).map((position) => position.symbol)
|
|
50999
|
+
].map(normalizeHyperliquidMarketSymbol).filter(Boolean))].sort();
|
|
51000
|
+
const feeDexes = [...new Set(feeSymbols.map(getHyperliquidMarketDex))];
|
|
51001
|
+
const metadata = await Promise.all(feeDexes.map(async (dex) => {
|
|
51002
|
+
try {
|
|
51003
|
+
const payload = metadataByDex.get(dex) ?? null;
|
|
51004
|
+
return [dex, payload];
|
|
51005
|
+
} catch (error48) {
|
|
51006
|
+
if (input.signal?.aborted) throw error48;
|
|
51007
|
+
return [dex, null];
|
|
51008
|
+
}
|
|
51009
|
+
}));
|
|
51010
|
+
effectiveTakerRates = effectiveHyperliquidTakerRates(feeSymbols, userFeesResponse ?? {}, Object.fromEntries(metadata));
|
|
51011
|
+
}
|
|
51012
|
+
const accountStateConfig = input.config.client_runtime_hyperliquid_account_state;
|
|
51013
|
+
const summaryPerpsResponse = exactAccountMode ? { ...accountSummaryPerpsResponse, accountMode: exactAccountMode.accountMode } : accountSummaryPerpsResponse;
|
|
51014
|
+
const accountSummaryOptions = {
|
|
51015
|
+
spotDominatesMinTotalUsd: accountStateConfig?.spot_dominates_min_total_usd,
|
|
51016
|
+
spotDominatesPerpsMultiplier: accountStateConfig?.spot_dominates_perps_multiplier,
|
|
51017
|
+
mirroredAccountValueAbsoluteToleranceUsd: accountStateConfig?.mirrored_account_value_absolute_tolerance_usd,
|
|
51018
|
+
mirroredAccountValueRelativeTolerance: accountStateConfig?.mirrored_account_value_relative_tolerance
|
|
51019
|
+
};
|
|
51020
|
+
const walletSummary = exactAccountMode && input.scopeAccountSummaryToSelectedDex !== true ? buildServerPromptRescueAccountSummary(
|
|
51021
|
+
perpsResponse,
|
|
51022
|
+
spotResponse,
|
|
51023
|
+
exactAccountMode.accountMode,
|
|
51024
|
+
accountSummaryOptions
|
|
51025
|
+
) : buildAccountSummaryFromInfoResponses(
|
|
51026
|
+
perpsResponse,
|
|
51027
|
+
spotResponse,
|
|
51028
|
+
accountSummaryOptions
|
|
51029
|
+
);
|
|
51030
|
+
const normalizedSummary = input.scopeAccountSummaryToSelectedDex === true ? {
|
|
51031
|
+
...buildAccountSummaryFromInfoResponses(
|
|
51032
|
+
summaryPerpsResponse,
|
|
51033
|
+
{},
|
|
51034
|
+
accountSummaryOptions
|
|
51035
|
+
),
|
|
51036
|
+
balances: walletSummary.balances
|
|
51037
|
+
} : exactAccountMode ? buildServerPromptRescueAccountSummary(
|
|
51038
|
+
accountSummaryPerpsResponse,
|
|
51039
|
+
spotResponse,
|
|
51040
|
+
exactAccountMode.accountMode,
|
|
51041
|
+
accountSummaryOptions
|
|
51042
|
+
) : buildAccountSummaryFromInfoResponses(
|
|
50927
51043
|
summaryPerpsResponse,
|
|
50928
|
-
|
|
51044
|
+
spotResponse,
|
|
50929
51045
|
accountSummaryOptions
|
|
50930
|
-
)
|
|
50931
|
-
|
|
50932
|
-
|
|
50933
|
-
|
|
50934
|
-
|
|
50935
|
-
|
|
50936
|
-
|
|
50937
|
-
|
|
50938
|
-
|
|
50939
|
-
|
|
50940
|
-
|
|
50941
|
-
|
|
50942
|
-
|
|
50943
|
-
|
|
50944
|
-
|
|
50945
|
-
|
|
50946
|
-
|
|
50947
|
-
|
|
50948
|
-
|
|
50949
|
-
|
|
50950
|
-
|
|
50951
|
-
|
|
50952
|
-
|
|
50953
|
-
|
|
50954
|
-
|
|
50955
|
-
|
|
50956
|
-
|
|
50957
|
-
|
|
50958
|
-
|
|
50959
|
-
|
|
50960
|
-
|
|
50961
|
-
|
|
50962
|
-
|
|
50963
|
-
|
|
50964
|
-
|
|
50965
|
-
|
|
50966
|
-
|
|
50967
|
-
|
|
50968
|
-
|
|
50969
|
-
|
|
50970
|
-
|
|
50971
|
-
|
|
50972
|
-
|
|
50973
|
-
|
|
50974
|
-
|
|
50975
|
-
|
|
50976
|
-
|
|
50977
|
-
|
|
50978
|
-
|
|
50979
|
-
|
|
50980
|
-
|
|
50981
|
-
|
|
50982
|
-
|
|
50983
|
-
|
|
50984
|
-
|
|
50985
|
-
|
|
50986
|
-
|
|
50987
|
-
|
|
50988
|
-
|
|
50989
|
-
|
|
50990
|
-
|
|
50991
|
-
|
|
50992
|
-
|
|
50993
|
-
...takerRate == null ? {} : { takerRate },
|
|
50994
|
-
...effectiveTakerRates == null ? {} : { effectiveTakerRates },
|
|
50995
|
-
...exactAccountMode == null || userFeesResult == null ? {} : {
|
|
50996
|
-
promptRescueEvidence: {
|
|
50997
|
-
capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
50998
|
-
perpsCapturedAt: perpsResult.capturedAt,
|
|
50999
|
-
spotCapturedAt: spotResult.capturedAt,
|
|
51000
|
-
feesCapturedAt: userFeesResult.capturedAt,
|
|
51001
|
-
accountModeCapturedAt: exactAccountMode.capturedAt,
|
|
51002
|
-
accountModeSource: "canonical"
|
|
51046
|
+
);
|
|
51047
|
+
const accountSummary = {
|
|
51048
|
+
...normalizedSummary,
|
|
51049
|
+
...input.scopeAccountSummaryToSelectedDex === true ? {} : {
|
|
51050
|
+
perp_dex_accounts: perpsResult.dexPayloads.filter(({ payload }) => hasCompletePerpDexAccountMetrics(payload)).map(({ dex, payload }) => {
|
|
51051
|
+
const summary = buildServerPromptRescueAccountSummary({
|
|
51052
|
+
...payload,
|
|
51053
|
+
crossMaintenanceMarginUsed: firstFiniteNumber([
|
|
51054
|
+
payload.crossMaintenanceMarginUsed,
|
|
51055
|
+
payload.marginSummary?.crossMaintenanceMarginUsed,
|
|
51056
|
+
payload.marginSummary?.totalMaintenanceMargin
|
|
51057
|
+
])
|
|
51058
|
+
}, {}, "disabled", accountSummaryOptions);
|
|
51059
|
+
const accountValue = Number(payload.marginSummary.accountValue);
|
|
51060
|
+
const calculatedAvailable = accountValue - summary.total_margin_used;
|
|
51061
|
+
const availableMargin = summary.maintenance_margin > 0 ? Math.max(calculatedAvailable, Math.max(0, accountValue - 4 * summary.maintenance_margin), summary.withdrawable) : Math.max(calculatedAvailable, summary.withdrawable);
|
|
51062
|
+
return {
|
|
51063
|
+
dex,
|
|
51064
|
+
account_value: accountValue,
|
|
51065
|
+
total_margin_used: summary.total_margin_used,
|
|
51066
|
+
available_margin: availableMargin,
|
|
51067
|
+
withdrawable: summary.withdrawable,
|
|
51068
|
+
maintenance_margin: summary.maintenance_margin,
|
|
51069
|
+
cross_account_leverage: summary.cross_account_leverage,
|
|
51070
|
+
total_unrealized_pnl: summary.total_unrealized_pnl ?? 0
|
|
51071
|
+
};
|
|
51072
|
+
})
|
|
51073
|
+
},
|
|
51074
|
+
...exactAccountMode == null ? {} : { account_mode: exactAccountMode.accountMode, mode_source: "canonical" },
|
|
51075
|
+
address: walletAddress,
|
|
51076
|
+
dex: input.scopeAccountSummaryToSelectedDex === true ? selectedDex : "all",
|
|
51077
|
+
market_type: "perp"
|
|
51078
|
+
};
|
|
51079
|
+
const activeAssetPayload = activeAssetResult?.payload ?? null;
|
|
51080
|
+
const activeAssetType = activeAssetResult?.type ?? "promptAccountState";
|
|
51081
|
+
const normalizedActiveAsset = normalizeActiveAssetData(activeAssetPayload, symbol2);
|
|
51082
|
+
const markPrice = toPositiveFinite(normalizedActiveAsset.mark_price, toPositiveFinite(input.tickerPrice));
|
|
51083
|
+
const fallbackLeverage = toPositiveFinite(input.leverage, 1);
|
|
51084
|
+
const availableBase = Math.max(0, toFinite(accountSummary.available_margin, 0));
|
|
51085
|
+
const availableToTrade = {
|
|
51086
|
+
symbol: symbol2,
|
|
51087
|
+
available_to_trade_buy: Math.max(0, toFinite(normalizedActiveAsset.available_to_trade_buy, availableBase)),
|
|
51088
|
+
available_to_trade_sell: Math.max(0, toFinite(normalizedActiveAsset.available_to_trade_sell, availableBase)),
|
|
51089
|
+
max_trade_size_buy: Math.max(0, toFinite(normalizedActiveAsset.max_trade_size_buy, availableBase * fallbackLeverage)),
|
|
51090
|
+
max_trade_size_sell: Math.max(0, toFinite(normalizedActiveAsset.max_trade_size_sell, availableBase * fallbackLeverage)),
|
|
51091
|
+
mark_price: markPrice,
|
|
51092
|
+
source: `browser_exchange:${activeAssetType}`
|
|
51093
|
+
};
|
|
51094
|
+
return {
|
|
51095
|
+
accountSummary,
|
|
51096
|
+
availableToTrade,
|
|
51097
|
+
positions: parseInfoPositions(perpsResponse),
|
|
51098
|
+
...takerRate == null ? {} : { takerRate },
|
|
51099
|
+
...effectiveTakerRates == null ? {} : { effectiveTakerRates },
|
|
51100
|
+
...exactAccountMode == null || userFeesResult == null ? {} : {
|
|
51101
|
+
promptRescueEvidence: {
|
|
51102
|
+
capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
51103
|
+
perpsCapturedAt: perpsResult.capturedAt,
|
|
51104
|
+
spotCapturedAt: spotResult.capturedAt,
|
|
51105
|
+
feesCapturedAt: userFeesResult.capturedAt,
|
|
51106
|
+
accountModeCapturedAt: exactAccountMode.capturedAt,
|
|
51107
|
+
accountModeSource: "canonical"
|
|
51108
|
+
}
|
|
51003
51109
|
}
|
|
51004
|
-
}
|
|
51005
|
-
}
|
|
51110
|
+
};
|
|
51111
|
+
} finally {
|
|
51112
|
+
await releaseHyperliquidPublicReadReservation(reservation);
|
|
51113
|
+
}
|
|
51006
51114
|
};
|
|
51007
51115
|
fetchBrowserUserFills = async (input) => {
|
|
51008
51116
|
configureHyperliquidMarketSymbolCasing(input.config.client_runtime_hyperliquid_case_sensitive_symbols);
|
|
@@ -85510,9 +85618,11 @@ var init_hyperliquid_client = __esm({
|
|
|
85510
85618
|
}
|
|
85511
85619
|
}
|
|
85512
85620
|
try {
|
|
85621
|
+
await admitHyperliquidExchangeRequest(apiUrl, input.payload.action, input.signal);
|
|
85513
85622
|
assertFreshPreparedExecutionContext(input.preparedContext);
|
|
85514
85623
|
} catch (preparedContextError) {
|
|
85515
85624
|
await settleDurableMutation("rejected");
|
|
85625
|
+
if (isAbortLikeError(preparedContextError) || preparedContextError instanceof HyperliquidPublicReadError) throw preparedContextError;
|
|
85516
85626
|
throw new RuntimeExecutionError(
|
|
85517
85627
|
preparedContextError instanceof Error ? preparedContextError.message : "Prepared exchange context expired before dispatch.",
|
|
85518
85628
|
"local_safety_block"
|
|
@@ -85545,6 +85655,7 @@ var init_hyperliquid_client = __esm({
|
|
|
85545
85655
|
body: serializedPayload
|
|
85546
85656
|
});
|
|
85547
85657
|
responseStatus = response.status;
|
|
85658
|
+
await recordHyperliquidExchangeResponse(apiUrl, response);
|
|
85548
85659
|
const payload = await response.json().catch(() => ({}));
|
|
85549
85660
|
if (!response.ok) {
|
|
85550
85661
|
await settleDurableMutation("transport_ambiguous");
|