opentool 0.8.12 → 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.
@@ -109,6 +109,7 @@ var BUILDER_CODE = {
109
109
  fee: 100
110
110
  };
111
111
  var metaCache = /* @__PURE__ */ new Map();
112
+ var perpDexsCache = /* @__PURE__ */ new Map();
112
113
  var HyperliquidApiError = class extends Error {
113
114
  constructor(message, response) {
114
115
  super(message);
@@ -147,7 +148,8 @@ function createMonotonicNonceFactory(start = Date.now()) {
147
148
  };
148
149
  }
149
150
  async function getUniverse(args) {
150
- const cacheKey = `${args.environment}:${args.baseUrl}`;
151
+ const dexKey = args.dex ? args.dex.trim().toLowerCase() : "";
152
+ const cacheKey = `${args.environment}:${args.baseUrl}:${dexKey}`;
151
153
  const cached = metaCache.get(cacheKey);
152
154
  if (cached && Date.now() - cached.fetchedAt < CACHE_TTL_MS) {
153
155
  return cached.universe;
@@ -155,7 +157,9 @@ async function getUniverse(args) {
155
157
  const response = await args.fetcher(`${args.baseUrl}/info`, {
156
158
  method: "POST",
157
159
  headers: { "content-type": "application/json" },
158
- body: JSON.stringify({ type: "meta" })
160
+ body: JSON.stringify(
161
+ dexKey ? { type: "meta", dex: dexKey } : { type: "meta" }
162
+ )
159
163
  });
160
164
  const json = await response.json().catch(() => null);
161
165
  if (!response.ok || !json?.universe) {
@@ -178,6 +182,76 @@ function resolveAssetIndex(symbol, universe) {
178
182
  }
179
183
  return index;
180
184
  }
185
+ async function getPerpDexs(args) {
186
+ const cacheKey = `${args.environment}:${args.baseUrl}`;
187
+ const cached = perpDexsCache.get(cacheKey);
188
+ if (cached && Date.now() - cached.fetchedAt < CACHE_TTL_MS) {
189
+ return cached.dexs;
190
+ }
191
+ const response = await args.fetcher(`${args.baseUrl}/info`, {
192
+ method: "POST",
193
+ headers: { "content-type": "application/json" },
194
+ body: JSON.stringify({ type: "perpDexs" })
195
+ });
196
+ const json = await response.json().catch(() => null);
197
+ if (!response.ok || !Array.isArray(json)) {
198
+ throw new HyperliquidApiError(
199
+ "Unable to load Hyperliquid perp dex metadata.",
200
+ json ?? { status: response.status }
201
+ );
202
+ }
203
+ perpDexsCache.set(cacheKey, { fetchedAt: Date.now(), dexs: json });
204
+ return json;
205
+ }
206
+ async function resolveDexIndex(args) {
207
+ const dexs = await getPerpDexs(args);
208
+ const target = args.dex.trim().toLowerCase();
209
+ const index = dexs.findIndex(
210
+ (entry) => entry?.name?.toLowerCase() === target
211
+ );
212
+ if (index === -1) {
213
+ throw new Error(`Unknown Hyperliquid perp dex: ${args.dex}`);
214
+ }
215
+ return index;
216
+ }
217
+ async function resolveHyperliquidAssetIndex(args) {
218
+ const trimmed = args.symbol.trim();
219
+ if (!trimmed) {
220
+ throw new Error("Hyperliquid symbol must be a non-empty string.");
221
+ }
222
+ const separator = trimmed.indexOf(":");
223
+ if (separator > 0) {
224
+ const dex = trimmed.slice(0, separator).trim();
225
+ if (!dex) {
226
+ throw new Error("Hyperliquid dex name is required.");
227
+ }
228
+ const dexIndex = await resolveDexIndex({
229
+ baseUrl: args.baseUrl,
230
+ environment: args.environment,
231
+ fetcher: args.fetcher,
232
+ dex
233
+ });
234
+ const universe2 = await getUniverse({
235
+ baseUrl: args.baseUrl,
236
+ environment: args.environment,
237
+ fetcher: args.fetcher,
238
+ dex
239
+ });
240
+ const assetIndex = universe2.findIndex(
241
+ (entry) => entry.name.toUpperCase() === trimmed.toUpperCase()
242
+ );
243
+ if (assetIndex === -1) {
244
+ throw new Error(`Unknown Hyperliquid asset symbol: ${trimmed}`);
245
+ }
246
+ return 1e5 + dexIndex * 1e4 + assetIndex;
247
+ }
248
+ const universe = await getUniverse({
249
+ baseUrl: args.baseUrl,
250
+ environment: args.environment,
251
+ fetcher: args.fetcher
252
+ });
253
+ return resolveAssetIndex(trimmed, universe);
254
+ }
181
255
  function toApiDecimal(value) {
182
256
  if (typeof value === "string") {
183
257
  return value;
@@ -832,12 +906,12 @@ async function placeHyperliquidTwapOrder(options) {
832
906
  assertPositiveDecimal(twap.size, "size");
833
907
  assertPositiveNumber(twap.minutes, "minutes");
834
908
  const env = options.environment ?? "mainnet";
835
- const universe = await getUniverse({
909
+ const asset = await resolveHyperliquidAssetIndex({
910
+ symbol: twap.symbol,
836
911
  baseUrl: API_BASES[env],
837
912
  environment: env,
838
913
  fetcher: fetch
839
914
  });
840
- const asset = resolveAssetIndex(twap.symbol, universe);
841
915
  const action = {
842
916
  type: "twapOrder",
843
917
  twap: {
@@ -854,12 +928,12 @@ async function placeHyperliquidTwapOrder(options) {
854
928
  async function cancelHyperliquidTwapOrder(options) {
855
929
  assertSymbol(options.cancel.symbol);
856
930
  const env = options.environment ?? "mainnet";
857
- const universe = await getUniverse({
931
+ const asset = await resolveHyperliquidAssetIndex({
932
+ symbol: options.cancel.symbol,
858
933
  baseUrl: API_BASES[env],
859
934
  environment: env,
860
935
  fetcher: fetch
861
936
  });
862
- const asset = resolveAssetIndex(options.cancel.symbol, universe);
863
937
  const action = {
864
938
  type: "twapCancel",
865
939
  a: asset,
@@ -871,12 +945,12 @@ async function updateHyperliquidLeverage(options) {
871
945
  assertSymbol(options.input.symbol);
872
946
  assertPositiveNumber(options.input.leverage, "leverage");
873
947
  const env = options.environment ?? "mainnet";
874
- const universe = await getUniverse({
948
+ const asset = await resolveHyperliquidAssetIndex({
949
+ symbol: options.input.symbol,
875
950
  baseUrl: API_BASES[env],
876
951
  environment: env,
877
952
  fetcher: fetch
878
953
  });
879
- const asset = resolveAssetIndex(options.input.symbol, universe);
880
954
  const action = {
881
955
  type: "updateLeverage",
882
956
  asset,
@@ -889,12 +963,12 @@ async function updateHyperliquidIsolatedMargin(options) {
889
963
  assertSymbol(options.input.symbol);
890
964
  assertPositiveNumber(options.input.ntli, "ntli");
891
965
  const env = options.environment ?? "mainnet";
892
- const universe = await getUniverse({
966
+ const asset = await resolveHyperliquidAssetIndex({
967
+ symbol: options.input.symbol,
893
968
  baseUrl: API_BASES[env],
894
969
  environment: env,
895
970
  fetcher: fetch
896
971
  });
897
- const asset = resolveAssetIndex(options.input.symbol, universe);
898
972
  const action = {
899
973
  type: "updateIsolatedMargin",
900
974
  asset,
@@ -997,14 +1071,14 @@ async function submitExchangeAction(options, action) {
997
1071
  }
998
1072
  async function withAssetIndexes(options, entries, mapper) {
999
1073
  const env = options.environment ?? "mainnet";
1000
- const universe = await getUniverse({
1001
- baseUrl: API_BASES[env],
1002
- environment: env,
1003
- fetcher: fetch
1004
- });
1005
1074
  return Promise.all(
1006
1075
  entries.map(async (entry) => {
1007
- const assetIndex = resolveAssetIndex(entry.symbol, universe);
1076
+ const assetIndex = await resolveHyperliquidAssetIndex({
1077
+ symbol: entry.symbol,
1078
+ baseUrl: API_BASES[env],
1079
+ environment: env,
1080
+ fetcher: fetch
1081
+ });
1008
1082
  return mapper(assetIndex, entry);
1009
1083
  })
1010
1084
  );
@@ -1014,12 +1088,12 @@ async function buildOrder(intent, options) {
1014
1088
  assertPositiveDecimal(intent.price, "price");
1015
1089
  assertPositiveDecimal(intent.size, "size");
1016
1090
  const env = options.environment ?? "mainnet";
1017
- const universe = await getUniverse({
1091
+ const assetIndex = await resolveHyperliquidAssetIndex({
1092
+ symbol: intent.symbol,
1018
1093
  baseUrl: API_BASES[env],
1019
1094
  environment: env,
1020
1095
  fetcher: fetch
1021
1096
  });
1022
- const assetIndex = resolveAssetIndex(intent.symbol, universe);
1023
1097
  const limitOrTrigger = intent.trigger ? mapTrigger(intent.trigger) : {
1024
1098
  limit: {
1025
1099
  tif: intent.tif ?? "Ioc"
@@ -1142,37 +1216,39 @@ async function placeHyperliquidOrder(options) {
1142
1216
  }
1143
1217
  const inferredEnvironment = environment ?? "mainnet";
1144
1218
  const resolvedBaseUrl = API_BASES[inferredEnvironment];
1145
- const universe = await getUniverse({
1146
- baseUrl: resolvedBaseUrl,
1147
- environment: inferredEnvironment,
1148
- fetcher: fetch
1149
- });
1150
- const preparedOrders = orders.map((intent) => {
1151
- const assetIndex = resolveAssetIndex(intent.symbol, universe);
1152
- const limitOrTrigger = intent.trigger ? {
1153
- trigger: {
1154
- isMarket: Boolean(intent.trigger.isMarket),
1155
- triggerPx: toApiDecimal(intent.trigger.triggerPx),
1156
- tpsl: intent.trigger.tpsl
1157
- }
1158
- } : {
1159
- limit: {
1160
- tif: intent.tif ?? "Ioc"
1161
- }
1162
- };
1163
- const order = {
1164
- a: assetIndex,
1165
- b: intent.side === "buy",
1166
- p: toApiDecimal(intent.price),
1167
- s: toApiDecimal(intent.size),
1168
- r: intent.reduceOnly ?? false,
1169
- t: limitOrTrigger,
1170
- ...intent.clientId ? {
1171
- c: normalizeHex(intent.clientId)
1172
- } : {}
1173
- };
1174
- return order;
1175
- });
1219
+ const preparedOrders = await Promise.all(
1220
+ orders.map(async (intent) => {
1221
+ const assetIndex = await resolveHyperliquidAssetIndex({
1222
+ symbol: intent.symbol,
1223
+ baseUrl: resolvedBaseUrl,
1224
+ environment: inferredEnvironment,
1225
+ fetcher: fetch
1226
+ });
1227
+ const limitOrTrigger = intent.trigger ? {
1228
+ trigger: {
1229
+ isMarket: Boolean(intent.trigger.isMarket),
1230
+ triggerPx: toApiDecimal(intent.trigger.triggerPx),
1231
+ tpsl: intent.trigger.tpsl
1232
+ }
1233
+ } : {
1234
+ limit: {
1235
+ tif: intent.tif ?? "Ioc"
1236
+ }
1237
+ };
1238
+ const order = {
1239
+ a: assetIndex,
1240
+ b: intent.side === "buy",
1241
+ p: toApiDecimal(intent.price),
1242
+ s: toApiDecimal(intent.size),
1243
+ r: intent.reduceOnly ?? false,
1244
+ t: limitOrTrigger,
1245
+ ...intent.clientId ? {
1246
+ c: normalizeHex(intent.clientId)
1247
+ } : {}
1248
+ };
1249
+ return order;
1250
+ })
1251
+ );
1176
1252
  const action = {
1177
1253
  type: "order",
1178
1254
  orders: preparedOrders,