opentool 0.8.22 → 0.8.23
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
|
@@ -1843,6 +1843,7 @@ var BUILDER_CODE = {
|
|
|
1843
1843
|
fee: 100
|
|
1844
1844
|
};
|
|
1845
1845
|
var metaCache = /* @__PURE__ */ new Map();
|
|
1846
|
+
var spotMetaCache = /* @__PURE__ */ new Map();
|
|
1846
1847
|
var perpDexsCache = /* @__PURE__ */ new Map();
|
|
1847
1848
|
var UNKNOWN_SYMBOL = "UNKNOWN";
|
|
1848
1849
|
var extractDexPrefix = (value) => {
|
|
@@ -1865,6 +1866,14 @@ var normalizeHyperliquidBase = (value) => {
|
|
|
1865
1866
|
if (!normalized || normalized === UNKNOWN_SYMBOL) return null;
|
|
1866
1867
|
return normalized;
|
|
1867
1868
|
};
|
|
1869
|
+
var normalizeSpotTokenName = (value) => {
|
|
1870
|
+
const raw = (value ?? "").trim().toUpperCase();
|
|
1871
|
+
if (!raw) return "";
|
|
1872
|
+
if (raw.endsWith("0") && raw.length > 1) {
|
|
1873
|
+
return raw.slice(0, -1);
|
|
1874
|
+
}
|
|
1875
|
+
return raw;
|
|
1876
|
+
};
|
|
1868
1877
|
var parseHyperliquidPair = (value) => {
|
|
1869
1878
|
if (!value) return null;
|
|
1870
1879
|
const trimmed = value.trim();
|
|
@@ -2011,6 +2020,29 @@ async function getUniverse(args) {
|
|
|
2011
2020
|
metaCache.set(cacheKey, { fetchedAt: Date.now(), universe: json.universe });
|
|
2012
2021
|
return json.universe;
|
|
2013
2022
|
}
|
|
2023
|
+
async function getSpotMeta(args) {
|
|
2024
|
+
const cacheKey = `${args.environment}:${args.baseUrl}`;
|
|
2025
|
+
const cached = spotMetaCache.get(cacheKey);
|
|
2026
|
+
if (cached && Date.now() - cached.fetchedAt < CACHE_TTL_MS) {
|
|
2027
|
+
return { universe: cached.universe, tokens: cached.tokens };
|
|
2028
|
+
}
|
|
2029
|
+
const response = await args.fetcher(`${args.baseUrl}/info`, {
|
|
2030
|
+
method: "POST",
|
|
2031
|
+
headers: { "content-type": "application/json" },
|
|
2032
|
+
body: JSON.stringify({ type: "spotMeta" })
|
|
2033
|
+
});
|
|
2034
|
+
const json = await response.json().catch(() => null);
|
|
2035
|
+
if (!response.ok || !json?.universe) {
|
|
2036
|
+
throw new HyperliquidApiError(
|
|
2037
|
+
"Unable to load Hyperliquid spot metadata.",
|
|
2038
|
+
json ?? { status: response.status }
|
|
2039
|
+
);
|
|
2040
|
+
}
|
|
2041
|
+
const universe = json.universe ?? [];
|
|
2042
|
+
const tokens2 = json.tokens ?? [];
|
|
2043
|
+
spotMetaCache.set(cacheKey, { fetchedAt: Date.now(), universe, tokens: tokens2 });
|
|
2044
|
+
return { universe, tokens: tokens2 };
|
|
2045
|
+
}
|
|
2014
2046
|
function resolveAssetIndex(symbol, universe) {
|
|
2015
2047
|
const [raw] = symbol.split("-");
|
|
2016
2048
|
const target = raw.trim();
|
|
@@ -2054,11 +2086,57 @@ async function resolveDexIndex(args) {
|
|
|
2054
2086
|
}
|
|
2055
2087
|
return index;
|
|
2056
2088
|
}
|
|
2089
|
+
function buildSpotTokenIndexMap(tokens2) {
|
|
2090
|
+
const map = /* @__PURE__ */ new Map();
|
|
2091
|
+
for (const token2 of tokens2) {
|
|
2092
|
+
const name = normalizeSpotTokenName(token2?.name);
|
|
2093
|
+
const index = typeof token2?.index === "number" && Number.isFinite(token2.index) ? token2.index : null;
|
|
2094
|
+
if (!name || index == null) continue;
|
|
2095
|
+
if (!map.has(name) || token2?.isCanonical) {
|
|
2096
|
+
map.set(name, index);
|
|
2097
|
+
}
|
|
2098
|
+
}
|
|
2099
|
+
return map;
|
|
2100
|
+
}
|
|
2101
|
+
function resolveSpotTokenIndex(tokenMap, value) {
|
|
2102
|
+
const normalized = normalizeSpotTokenName(value);
|
|
2103
|
+
if (!normalized) return null;
|
|
2104
|
+
const direct = tokenMap.get(normalized);
|
|
2105
|
+
if (direct != null) return direct;
|
|
2106
|
+
if (!normalized.startsWith("U")) {
|
|
2107
|
+
const prefixed = tokenMap.get(`U${normalized}`);
|
|
2108
|
+
if (prefixed != null) return prefixed;
|
|
2109
|
+
}
|
|
2110
|
+
return null;
|
|
2111
|
+
}
|
|
2112
|
+
function resolveSpotMarketIndex(args) {
|
|
2113
|
+
for (let i = 0; i < args.universe.length; i += 1) {
|
|
2114
|
+
const entry = args.universe[i];
|
|
2115
|
+
const tokens2 = Array.isArray(entry?.tokens) ? entry.tokens : null;
|
|
2116
|
+
const baseToken = tokens2?.[0] ?? entry?.baseToken ?? null;
|
|
2117
|
+
const quoteToken = tokens2?.[1] ?? entry?.quoteToken ?? null;
|
|
2118
|
+
if (baseToken === args.baseToken && quoteToken === args.quoteToken) {
|
|
2119
|
+
if (typeof entry?.index === "number" && Number.isFinite(entry.index)) {
|
|
2120
|
+
return entry.index;
|
|
2121
|
+
}
|
|
2122
|
+
return i;
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2125
|
+
return null;
|
|
2126
|
+
}
|
|
2057
2127
|
async function resolveHyperliquidAssetIndex(args) {
|
|
2058
2128
|
const trimmed = args.symbol.trim();
|
|
2059
2129
|
if (!trimmed) {
|
|
2060
2130
|
throw new Error("Hyperliquid symbol must be a non-empty string.");
|
|
2061
2131
|
}
|
|
2132
|
+
if (trimmed.startsWith("@")) {
|
|
2133
|
+
const rawIndex = trimmed.slice(1).trim();
|
|
2134
|
+
const index = Number(rawIndex);
|
|
2135
|
+
if (!Number.isFinite(index)) {
|
|
2136
|
+
throw new Error(`Hyperliquid spot market index is invalid: ${trimmed}`);
|
|
2137
|
+
}
|
|
2138
|
+
return 1e4 + index;
|
|
2139
|
+
}
|
|
2062
2140
|
const separator = trimmed.indexOf(":");
|
|
2063
2141
|
if (separator > 0) {
|
|
2064
2142
|
const dex = trimmed.slice(0, separator).trim();
|
|
@@ -2085,6 +2163,29 @@ async function resolveHyperliquidAssetIndex(args) {
|
|
|
2085
2163
|
}
|
|
2086
2164
|
return 1e5 + dexIndex * 1e4 + assetIndex;
|
|
2087
2165
|
}
|
|
2166
|
+
const pair = parseHyperliquidPair(trimmed);
|
|
2167
|
+
if (pair) {
|
|
2168
|
+
const { universe: universe2, tokens: tokens2 } = await getSpotMeta({
|
|
2169
|
+
baseUrl: args.baseUrl,
|
|
2170
|
+
environment: args.environment,
|
|
2171
|
+
fetcher: args.fetcher
|
|
2172
|
+
});
|
|
2173
|
+
const tokenMap = buildSpotTokenIndexMap(tokens2);
|
|
2174
|
+
const baseToken = resolveSpotTokenIndex(tokenMap, pair.base);
|
|
2175
|
+
const quoteToken = resolveSpotTokenIndex(tokenMap, pair.quote);
|
|
2176
|
+
if (baseToken == null || quoteToken == null) {
|
|
2177
|
+
throw new Error(`Unknown Hyperliquid spot symbol: ${trimmed}`);
|
|
2178
|
+
}
|
|
2179
|
+
const marketIndex = resolveSpotMarketIndex({
|
|
2180
|
+
universe: universe2,
|
|
2181
|
+
baseToken,
|
|
2182
|
+
quoteToken
|
|
2183
|
+
});
|
|
2184
|
+
if (marketIndex == null) {
|
|
2185
|
+
throw new Error(`Unknown Hyperliquid spot symbol: ${trimmed}`);
|
|
2186
|
+
}
|
|
2187
|
+
return 1e4 + marketIndex;
|
|
2188
|
+
}
|
|
2088
2189
|
const universe = await getUniverse({
|
|
2089
2190
|
baseUrl: args.baseUrl,
|
|
2090
2191
|
environment: args.environment,
|