opentool 0.8.11 → 0.8.13
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/dist/index.js
CHANGED
|
@@ -1832,6 +1832,7 @@ var BUILDER_CODE = {
|
|
|
1832
1832
|
fee: 100
|
|
1833
1833
|
};
|
|
1834
1834
|
var metaCache = /* @__PURE__ */ new Map();
|
|
1835
|
+
var perpDexsCache = /* @__PURE__ */ new Map();
|
|
1835
1836
|
var HyperliquidApiError = class extends Error {
|
|
1836
1837
|
constructor(message, response) {
|
|
1837
1838
|
super(message);
|
|
@@ -1870,7 +1871,8 @@ function createMonotonicNonceFactory(start = Date.now()) {
|
|
|
1870
1871
|
};
|
|
1871
1872
|
}
|
|
1872
1873
|
async function getUniverse(args) {
|
|
1873
|
-
const
|
|
1874
|
+
const dexKey = args.dex ? args.dex.trim().toLowerCase() : "";
|
|
1875
|
+
const cacheKey = `${args.environment}:${args.baseUrl}:${dexKey}`;
|
|
1874
1876
|
const cached = metaCache.get(cacheKey);
|
|
1875
1877
|
if (cached && Date.now() - cached.fetchedAt < CACHE_TTL_MS) {
|
|
1876
1878
|
return cached.universe;
|
|
@@ -1878,7 +1880,9 @@ async function getUniverse(args) {
|
|
|
1878
1880
|
const response = await args.fetcher(`${args.baseUrl}/info`, {
|
|
1879
1881
|
method: "POST",
|
|
1880
1882
|
headers: { "content-type": "application/json" },
|
|
1881
|
-
body: JSON.stringify(
|
|
1883
|
+
body: JSON.stringify(
|
|
1884
|
+
dexKey ? { type: "meta", dex: dexKey } : { type: "meta" }
|
|
1885
|
+
)
|
|
1882
1886
|
});
|
|
1883
1887
|
const json = await response.json().catch(() => null);
|
|
1884
1888
|
if (!response.ok || !json?.universe) {
|
|
@@ -1901,6 +1905,76 @@ function resolveAssetIndex(symbol, universe) {
|
|
|
1901
1905
|
}
|
|
1902
1906
|
return index;
|
|
1903
1907
|
}
|
|
1908
|
+
async function getPerpDexs(args) {
|
|
1909
|
+
const cacheKey = `${args.environment}:${args.baseUrl}`;
|
|
1910
|
+
const cached = perpDexsCache.get(cacheKey);
|
|
1911
|
+
if (cached && Date.now() - cached.fetchedAt < CACHE_TTL_MS) {
|
|
1912
|
+
return cached.dexs;
|
|
1913
|
+
}
|
|
1914
|
+
const response = await args.fetcher(`${args.baseUrl}/info`, {
|
|
1915
|
+
method: "POST",
|
|
1916
|
+
headers: { "content-type": "application/json" },
|
|
1917
|
+
body: JSON.stringify({ type: "perpDexs" })
|
|
1918
|
+
});
|
|
1919
|
+
const json = await response.json().catch(() => null);
|
|
1920
|
+
if (!response.ok || !Array.isArray(json)) {
|
|
1921
|
+
throw new HyperliquidApiError(
|
|
1922
|
+
"Unable to load Hyperliquid perp dex metadata.",
|
|
1923
|
+
json ?? { status: response.status }
|
|
1924
|
+
);
|
|
1925
|
+
}
|
|
1926
|
+
perpDexsCache.set(cacheKey, { fetchedAt: Date.now(), dexs: json });
|
|
1927
|
+
return json;
|
|
1928
|
+
}
|
|
1929
|
+
async function resolveDexIndex(args) {
|
|
1930
|
+
const dexs = await getPerpDexs(args);
|
|
1931
|
+
const target = args.dex.trim().toLowerCase();
|
|
1932
|
+
const index = dexs.findIndex(
|
|
1933
|
+
(entry) => entry?.name?.toLowerCase() === target
|
|
1934
|
+
);
|
|
1935
|
+
if (index === -1) {
|
|
1936
|
+
throw new Error(`Unknown Hyperliquid perp dex: ${args.dex}`);
|
|
1937
|
+
}
|
|
1938
|
+
return index;
|
|
1939
|
+
}
|
|
1940
|
+
async function resolveHyperliquidAssetIndex(args) {
|
|
1941
|
+
const trimmed = args.symbol.trim();
|
|
1942
|
+
if (!trimmed) {
|
|
1943
|
+
throw new Error("Hyperliquid symbol must be a non-empty string.");
|
|
1944
|
+
}
|
|
1945
|
+
const separator = trimmed.indexOf(":");
|
|
1946
|
+
if (separator > 0) {
|
|
1947
|
+
const dex = trimmed.slice(0, separator).trim();
|
|
1948
|
+
if (!dex) {
|
|
1949
|
+
throw new Error("Hyperliquid dex name is required.");
|
|
1950
|
+
}
|
|
1951
|
+
const dexIndex = await resolveDexIndex({
|
|
1952
|
+
baseUrl: args.baseUrl,
|
|
1953
|
+
environment: args.environment,
|
|
1954
|
+
fetcher: args.fetcher,
|
|
1955
|
+
dex
|
|
1956
|
+
});
|
|
1957
|
+
const universe2 = await getUniverse({
|
|
1958
|
+
baseUrl: args.baseUrl,
|
|
1959
|
+
environment: args.environment,
|
|
1960
|
+
fetcher: args.fetcher,
|
|
1961
|
+
dex
|
|
1962
|
+
});
|
|
1963
|
+
const assetIndex = universe2.findIndex(
|
|
1964
|
+
(entry) => entry.name.toUpperCase() === trimmed.toUpperCase()
|
|
1965
|
+
);
|
|
1966
|
+
if (assetIndex === -1) {
|
|
1967
|
+
throw new Error(`Unknown Hyperliquid asset symbol: ${trimmed}`);
|
|
1968
|
+
}
|
|
1969
|
+
return 1e5 + dexIndex * 1e4 + assetIndex;
|
|
1970
|
+
}
|
|
1971
|
+
const universe = await getUniverse({
|
|
1972
|
+
baseUrl: args.baseUrl,
|
|
1973
|
+
environment: args.environment,
|
|
1974
|
+
fetcher: args.fetcher
|
|
1975
|
+
});
|
|
1976
|
+
return resolveAssetIndex(trimmed, universe);
|
|
1977
|
+
}
|
|
1904
1978
|
function toApiDecimal(value) {
|
|
1905
1979
|
if (typeof value === "string") {
|
|
1906
1980
|
return value;
|
|
@@ -2555,12 +2629,12 @@ async function placeHyperliquidTwapOrder(options) {
|
|
|
2555
2629
|
assertPositiveDecimal(twap.size, "size");
|
|
2556
2630
|
assertPositiveNumber(twap.minutes, "minutes");
|
|
2557
2631
|
const env = options.environment ?? "mainnet";
|
|
2558
|
-
const
|
|
2632
|
+
const asset = await resolveHyperliquidAssetIndex({
|
|
2633
|
+
symbol: twap.symbol,
|
|
2559
2634
|
baseUrl: API_BASES[env],
|
|
2560
2635
|
environment: env,
|
|
2561
2636
|
fetcher: fetch
|
|
2562
2637
|
});
|
|
2563
|
-
const asset = resolveAssetIndex(twap.symbol, universe);
|
|
2564
2638
|
const action = {
|
|
2565
2639
|
type: "twapOrder",
|
|
2566
2640
|
twap: {
|
|
@@ -2577,12 +2651,12 @@ async function placeHyperliquidTwapOrder(options) {
|
|
|
2577
2651
|
async function cancelHyperliquidTwapOrder(options) {
|
|
2578
2652
|
assertSymbol(options.cancel.symbol);
|
|
2579
2653
|
const env = options.environment ?? "mainnet";
|
|
2580
|
-
const
|
|
2654
|
+
const asset = await resolveHyperliquidAssetIndex({
|
|
2655
|
+
symbol: options.cancel.symbol,
|
|
2581
2656
|
baseUrl: API_BASES[env],
|
|
2582
2657
|
environment: env,
|
|
2583
2658
|
fetcher: fetch
|
|
2584
2659
|
});
|
|
2585
|
-
const asset = resolveAssetIndex(options.cancel.symbol, universe);
|
|
2586
2660
|
const action = {
|
|
2587
2661
|
type: "twapCancel",
|
|
2588
2662
|
a: asset,
|
|
@@ -2594,12 +2668,12 @@ async function updateHyperliquidLeverage(options) {
|
|
|
2594
2668
|
assertSymbol(options.input.symbol);
|
|
2595
2669
|
assertPositiveNumber(options.input.leverage, "leverage");
|
|
2596
2670
|
const env = options.environment ?? "mainnet";
|
|
2597
|
-
const
|
|
2671
|
+
const asset = await resolveHyperliquidAssetIndex({
|
|
2672
|
+
symbol: options.input.symbol,
|
|
2598
2673
|
baseUrl: API_BASES[env],
|
|
2599
2674
|
environment: env,
|
|
2600
2675
|
fetcher: fetch
|
|
2601
2676
|
});
|
|
2602
|
-
const asset = resolveAssetIndex(options.input.symbol, universe);
|
|
2603
2677
|
const action = {
|
|
2604
2678
|
type: "updateLeverage",
|
|
2605
2679
|
asset,
|
|
@@ -2612,12 +2686,12 @@ async function updateHyperliquidIsolatedMargin(options) {
|
|
|
2612
2686
|
assertSymbol(options.input.symbol);
|
|
2613
2687
|
assertPositiveNumber(options.input.ntli, "ntli");
|
|
2614
2688
|
const env = options.environment ?? "mainnet";
|
|
2615
|
-
const
|
|
2689
|
+
const asset = await resolveHyperliquidAssetIndex({
|
|
2690
|
+
symbol: options.input.symbol,
|
|
2616
2691
|
baseUrl: API_BASES[env],
|
|
2617
2692
|
environment: env,
|
|
2618
2693
|
fetcher: fetch
|
|
2619
2694
|
});
|
|
2620
|
-
const asset = resolveAssetIndex(options.input.symbol, universe);
|
|
2621
2695
|
const action = {
|
|
2622
2696
|
type: "updateIsolatedMargin",
|
|
2623
2697
|
asset,
|
|
@@ -2720,14 +2794,14 @@ async function submitExchangeAction(options, action) {
|
|
|
2720
2794
|
}
|
|
2721
2795
|
async function withAssetIndexes(options, entries, mapper) {
|
|
2722
2796
|
const env = options.environment ?? "mainnet";
|
|
2723
|
-
const universe = await getUniverse({
|
|
2724
|
-
baseUrl: API_BASES[env],
|
|
2725
|
-
environment: env,
|
|
2726
|
-
fetcher: fetch
|
|
2727
|
-
});
|
|
2728
2797
|
return Promise.all(
|
|
2729
2798
|
entries.map(async (entry) => {
|
|
2730
|
-
const assetIndex =
|
|
2799
|
+
const assetIndex = await resolveHyperliquidAssetIndex({
|
|
2800
|
+
symbol: entry.symbol,
|
|
2801
|
+
baseUrl: API_BASES[env],
|
|
2802
|
+
environment: env,
|
|
2803
|
+
fetcher: fetch
|
|
2804
|
+
});
|
|
2731
2805
|
return mapper(assetIndex, entry);
|
|
2732
2806
|
})
|
|
2733
2807
|
);
|
|
@@ -2737,12 +2811,12 @@ async function buildOrder(intent, options) {
|
|
|
2737
2811
|
assertPositiveDecimal(intent.price, "price");
|
|
2738
2812
|
assertPositiveDecimal(intent.size, "size");
|
|
2739
2813
|
const env = options.environment ?? "mainnet";
|
|
2740
|
-
const
|
|
2814
|
+
const assetIndex = await resolveHyperliquidAssetIndex({
|
|
2815
|
+
symbol: intent.symbol,
|
|
2741
2816
|
baseUrl: API_BASES[env],
|
|
2742
2817
|
environment: env,
|
|
2743
2818
|
fetcher: fetch
|
|
2744
2819
|
});
|
|
2745
|
-
const assetIndex = resolveAssetIndex(intent.symbol, universe);
|
|
2746
2820
|
const limitOrTrigger = intent.trigger ? mapTrigger(intent.trigger) : {
|
|
2747
2821
|
limit: {
|
|
2748
2822
|
tif: intent.tif ?? "Ioc"
|
|
@@ -2865,37 +2939,39 @@ async function placeHyperliquidOrder(options) {
|
|
|
2865
2939
|
}
|
|
2866
2940
|
const inferredEnvironment = environment ?? "mainnet";
|
|
2867
2941
|
const resolvedBaseUrl = API_BASES[inferredEnvironment];
|
|
2868
|
-
const
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
trigger
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2942
|
+
const preparedOrders = await Promise.all(
|
|
2943
|
+
orders.map(async (intent) => {
|
|
2944
|
+
const assetIndex = await resolveHyperliquidAssetIndex({
|
|
2945
|
+
symbol: intent.symbol,
|
|
2946
|
+
baseUrl: resolvedBaseUrl,
|
|
2947
|
+
environment: inferredEnvironment,
|
|
2948
|
+
fetcher: fetch
|
|
2949
|
+
});
|
|
2950
|
+
const limitOrTrigger = intent.trigger ? {
|
|
2951
|
+
trigger: {
|
|
2952
|
+
isMarket: Boolean(intent.trigger.isMarket),
|
|
2953
|
+
triggerPx: toApiDecimal(intent.trigger.triggerPx),
|
|
2954
|
+
tpsl: intent.trigger.tpsl
|
|
2955
|
+
}
|
|
2956
|
+
} : {
|
|
2957
|
+
limit: {
|
|
2958
|
+
tif: intent.tif ?? "Ioc"
|
|
2959
|
+
}
|
|
2960
|
+
};
|
|
2961
|
+
const order = {
|
|
2962
|
+
a: assetIndex,
|
|
2963
|
+
b: intent.side === "buy",
|
|
2964
|
+
p: toApiDecimal(intent.price),
|
|
2965
|
+
s: toApiDecimal(intent.size),
|
|
2966
|
+
r: intent.reduceOnly ?? false,
|
|
2967
|
+
t: limitOrTrigger,
|
|
2968
|
+
...intent.clientId ? {
|
|
2969
|
+
c: normalizeHex(intent.clientId)
|
|
2970
|
+
} : {}
|
|
2971
|
+
};
|
|
2972
|
+
return order;
|
|
2973
|
+
})
|
|
2974
|
+
);
|
|
2899
2975
|
const action = {
|
|
2900
2976
|
type: "order",
|
|
2901
2977
|
orders: preparedOrders,
|