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 cacheKey = `${args.environment}:${args.baseUrl}`;
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({ type: "meta" })
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 universe = await getUniverse({
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 universe = await getUniverse({
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 universe = await getUniverse({
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 universe = await getUniverse({
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 = resolveAssetIndex(entry.symbol, universe);
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 universe = await getUniverse({
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 universe = await getUniverse({
2869
- baseUrl: resolvedBaseUrl,
2870
- environment: inferredEnvironment,
2871
- fetcher: fetch
2872
- });
2873
- const preparedOrders = orders.map((intent) => {
2874
- const assetIndex = resolveAssetIndex(intent.symbol, universe);
2875
- const limitOrTrigger = intent.trigger ? {
2876
- trigger: {
2877
- isMarket: Boolean(intent.trigger.isMarket),
2878
- triggerPx: toApiDecimal(intent.trigger.triggerPx),
2879
- tpsl: intent.trigger.tpsl
2880
- }
2881
- } : {
2882
- limit: {
2883
- tif: intent.tif ?? "Ioc"
2884
- }
2885
- };
2886
- const order = {
2887
- a: assetIndex,
2888
- b: intent.side === "buy",
2889
- p: toApiDecimal(intent.price),
2890
- s: toApiDecimal(intent.size),
2891
- r: intent.reduceOnly ?? false,
2892
- t: limitOrTrigger,
2893
- ...intent.clientId ? {
2894
- c: normalizeHex(intent.clientId)
2895
- } : {}
2896
- };
2897
- return order;
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,