opentool 0.8.12 → 0.8.14
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/adapters/hyperliquid/index.js +125 -49
- package/dist/adapters/hyperliquid/index.js.map +1 -1
- package/dist/cli/index.d.ts +2 -2
- package/dist/cli/index.js +46 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +171 -49
- package/dist/index.js.map +1 -1
- package/dist/{validate-CilU0rkD.d.ts → validate-CQNmvjez.d.ts} +8 -1
- package/package.json +1 -1
- package/templates/base/package.json +1 -1
|
@@ -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
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
trigger
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
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,
|