@continuumdao/ctm-mpc-defi 0.2.20 → 0.2.24

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.
Files changed (96) hide show
  1. package/dist/agent/catalog.cjs +256 -46
  2. package/dist/agent/catalog.cjs.map +1 -1
  3. package/dist/agent/catalog.d.ts +606 -154
  4. package/dist/agent/catalog.js +250 -47
  5. package/dist/agent/catalog.js.map +1 -1
  6. package/dist/agent/skills/gmx/SKILL.md +30 -0
  7. package/dist/agent/skills/hyperliquid/SKILL.md +32 -0
  8. package/dist/agent/skills/uniswap-v4/SKILL.md +83 -0
  9. package/dist/chains/evm/index.cjs +5 -1
  10. package/dist/chains/evm/index.cjs.map +1 -1
  11. package/dist/chains/evm/index.d.ts +4 -4
  12. package/dist/chains/evm/index.js +5 -1
  13. package/dist/chains/evm/index.js.map +1 -1
  14. package/dist/chains/near/index.d.ts +1 -1
  15. package/dist/chains/solana/index.d.ts +1 -1
  16. package/dist/core/index.cjs +25 -0
  17. package/dist/core/index.cjs.map +1 -1
  18. package/dist/core/index.d.ts +11 -36
  19. package/dist/core/index.js +23 -1
  20. package/dist/core/index.js.map +1 -1
  21. package/dist/eip712Multisign-xhXpUYp3.d.ts +36 -0
  22. package/dist/{envelope-CpBUh9eP.d.ts → envelope-C_bfuKab.d.ts} +3 -1
  23. package/dist/index.cjs +371 -13
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.ts +6 -5
  26. package/dist/index.js +369 -14
  27. package/dist/index.js.map +1 -1
  28. package/dist/protocols/evm/aave-v4/index.cjs +5 -1
  29. package/dist/protocols/evm/aave-v4/index.cjs.map +1 -1
  30. package/dist/protocols/evm/aave-v4/index.d.ts +1 -1
  31. package/dist/protocols/evm/aave-v4/index.js +5 -1
  32. package/dist/protocols/evm/aave-v4/index.js.map +1 -1
  33. package/dist/protocols/evm/circle-cctp/index.cjs +5 -1
  34. package/dist/protocols/evm/circle-cctp/index.cjs.map +1 -1
  35. package/dist/protocols/evm/circle-cctp/index.d.ts +2 -2
  36. package/dist/protocols/evm/circle-cctp/index.js +5 -1
  37. package/dist/protocols/evm/circle-cctp/index.js.map +1 -1
  38. package/dist/protocols/evm/curve-dao/index.cjs +5 -1
  39. package/dist/protocols/evm/curve-dao/index.cjs.map +1 -1
  40. package/dist/protocols/evm/curve-dao/index.d.ts +2 -2
  41. package/dist/protocols/evm/curve-dao/index.js +5 -1
  42. package/dist/protocols/evm/curve-dao/index.js.map +1 -1
  43. package/dist/protocols/evm/ethena/index.cjs +5 -1
  44. package/dist/protocols/evm/ethena/index.cjs.map +1 -1
  45. package/dist/protocols/evm/ethena/index.d.ts +1 -1
  46. package/dist/protocols/evm/ethena/index.js +5 -1
  47. package/dist/protocols/evm/ethena/index.js.map +1 -1
  48. package/dist/protocols/evm/euler-v2/index.cjs +5 -1
  49. package/dist/protocols/evm/euler-v2/index.cjs.map +1 -1
  50. package/dist/protocols/evm/euler-v2/index.d.ts +1 -1
  51. package/dist/protocols/evm/euler-v2/index.js +5 -1
  52. package/dist/protocols/evm/euler-v2/index.js.map +1 -1
  53. package/dist/protocols/evm/gmx/index.cjs +44 -1
  54. package/dist/protocols/evm/gmx/index.cjs.map +1 -1
  55. package/dist/protocols/evm/gmx/index.d.ts +23 -3
  56. package/dist/protocols/evm/gmx/index.js +43 -2
  57. package/dist/protocols/evm/gmx/index.js.map +1 -1
  58. package/dist/protocols/evm/hyperliquid/index.cjs +483 -208
  59. package/dist/protocols/evm/hyperliquid/index.cjs.map +1 -1
  60. package/dist/protocols/evm/hyperliquid/index.d.ts +168 -53
  61. package/dist/protocols/evm/hyperliquid/index.js +472 -210
  62. package/dist/protocols/evm/hyperliquid/index.js.map +1 -1
  63. package/dist/protocols/evm/lido/index.cjs +5 -1
  64. package/dist/protocols/evm/lido/index.cjs.map +1 -1
  65. package/dist/protocols/evm/lido/index.d.ts +1 -1
  66. package/dist/protocols/evm/lido/index.js +5 -1
  67. package/dist/protocols/evm/lido/index.js.map +1 -1
  68. package/dist/protocols/evm/maple/index.cjs +5 -1
  69. package/dist/protocols/evm/maple/index.cjs.map +1 -1
  70. package/dist/protocols/evm/maple/index.d.ts +1 -1
  71. package/dist/protocols/evm/maple/index.js +5 -1
  72. package/dist/protocols/evm/maple/index.js.map +1 -1
  73. package/dist/protocols/evm/morpho/index.cjs +5 -1
  74. package/dist/protocols/evm/morpho/index.cjs.map +1 -1
  75. package/dist/protocols/evm/morpho/index.d.ts +1 -1
  76. package/dist/protocols/evm/morpho/index.js +5 -1
  77. package/dist/protocols/evm/morpho/index.js.map +1 -1
  78. package/dist/protocols/evm/permit2/index.cjs +4 -0
  79. package/dist/protocols/evm/permit2/index.cjs.map +1 -1
  80. package/dist/protocols/evm/permit2/index.d.ts +1 -1
  81. package/dist/protocols/evm/permit2/index.js +4 -0
  82. package/dist/protocols/evm/permit2/index.js.map +1 -1
  83. package/dist/protocols/evm/sky/index.cjs +5 -1
  84. package/dist/protocols/evm/sky/index.cjs.map +1 -1
  85. package/dist/protocols/evm/sky/index.d.ts +1 -1
  86. package/dist/protocols/evm/sky/index.js +5 -1
  87. package/dist/protocols/evm/sky/index.js.map +1 -1
  88. package/dist/protocols/evm/uniswap-v4/index.cjs +1415 -13
  89. package/dist/protocols/evm/uniswap-v4/index.cjs.map +1 -1
  90. package/dist/protocols/evm/uniswap-v4/index.d.ts +353 -4
  91. package/dist/protocols/evm/uniswap-v4/index.js +1357 -15
  92. package/dist/protocols/evm/uniswap-v4/index.js.map +1 -1
  93. package/dist/{registry-Bv5o37_w.d.ts → registry-DxDSPQ-p.d.ts} +1 -1
  94. package/dist/{types-BfjWdw1j.d.ts → types-PZrvtjv8.d.ts} +2 -0
  95. package/dist/{types-DUeNJLr9.d.ts → types-RZWOTm8c.d.ts} +1 -1
  96. package/package.json +2 -2
@@ -348,6 +348,12 @@ async function hyperliquidFetchOpenOrders(args) {
348
348
  const orders = await hyperliquidInfoPost(args.chainId, req);
349
349
  return { orders: orders ?? [] };
350
350
  }
351
+ async function hyperliquidFetchFrontendOpenOrders(args) {
352
+ const req = { type: "frontendOpenOrders", user: args.user };
353
+ if (args.dex?.trim()) req.dex = args.dex.trim();
354
+ const orders = await hyperliquidInfoPost(args.chainId, req);
355
+ return { orders: orders ?? [] };
356
+ }
351
357
  async function hyperliquidFetchUserVaultEquities(args) {
352
358
  const rows = await hyperliquidInfoPost(args.chainId, {
353
359
  type: "userVaultEquities",
@@ -984,6 +990,9 @@ function finalizeMultisign(input) {
984
990
  bodyForSign.value = valueWei.toString();
985
991
  }
986
992
  if (clientId) bodyForSign.clientId = clientId;
993
+ if (input.expiryDate != null && input.expiryDate > 0) {
994
+ bodyForSign.expiryDate = Math.floor(input.expiryDate);
995
+ }
987
996
  return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) };
988
997
  }
989
998
  function routerSwapGasLimitFromEstimate(estimatedGas, chainGasLimit) {
@@ -1147,7 +1156,8 @@ async function buildEvmMultisignBatch(args) {
1147
1156
  destinationChainID: String(chainId),
1148
1157
  destinationAddress: args.destinationAddress ?? steps[0].to,
1149
1158
  legs,
1150
- extraJSON: Object.keys(extraJSON).length > 0 ? extraJSON : void 0
1159
+ extraJSON: Object.keys(extraJSON).length > 0 ? extraJSON : void 0,
1160
+ expiryDate: context.expiryDate
1151
1161
  });
1152
1162
  const pv = args.payableValueWei;
1153
1163
  if (pv != null && pv > 0n) {
@@ -1155,8 +1165,404 @@ async function buildEvmMultisignBatch(args) {
1155
1165
  }
1156
1166
  return result;
1157
1167
  }
1168
+ var EIP712_SIGN_REQUEST_KIND = "eip712";
1169
+ function msgHashNo0x(digest) {
1170
+ return digest.startsWith("0x") ? digest.slice(2) : digest;
1171
+ }
1172
+ function eip712SignatureText(domain, primaryType) {
1173
+ return JSON.stringify({
1174
+ kind: "EIP-712",
1175
+ ...typeof domain.name === "string" ? { name: domain.name } : {},
1176
+ primaryType
1177
+ });
1178
+ }
1179
+ function jsonStringifyForAudit(value) {
1180
+ return JSON.stringify(value, (_, v) => typeof v === "bigint" ? v.toString() : v);
1181
+ }
1182
+ function eip712MsgRawHex(typedData, delivery) {
1183
+ const envelope = {
1184
+ version: 1,
1185
+ ...typedData,
1186
+ delivery
1187
+ };
1188
+ return viem.stringToHex(jsonStringifyForAudit(envelope));
1189
+ }
1190
+ function buildEip712MultisignBody(args) {
1191
+ const { typedData, delivery } = args;
1192
+ const digest = viem.hashTypedData({
1193
+ domain: typedData.domain,
1194
+ types: typedData.types,
1195
+ primaryType: typedData.primaryType,
1196
+ message: typedData.message
1197
+ });
1198
+ const extraJSON = {
1199
+ signRequestKind: EIP712_SIGN_REQUEST_KIND,
1200
+ eip712: {
1201
+ version: 1,
1202
+ digest,
1203
+ domain: typedData.domain,
1204
+ types: typedData.types,
1205
+ primaryType: typedData.primaryType,
1206
+ message: typedData.message
1207
+ },
1208
+ delivery
1209
+ };
1210
+ return finalizeMultisign({
1211
+ keyGen: args.keyGen,
1212
+ purposeText: args.purposeText,
1213
+ purposeSuffix: args.purposeSuffix,
1214
+ destinationChainID: args.destinationChainID,
1215
+ destinationAddress: args.destinationAddress,
1216
+ extraJSON,
1217
+ expiryDate: args.expiryDate,
1218
+ legs: [
1219
+ {
1220
+ msgHash: msgHashNo0x(digest),
1221
+ msgRaw: eip712MsgRawHex(typedData, delivery),
1222
+ destinationAddress: args.destinationAddress,
1223
+ signatureText: eip712SignatureText(typedData.domain, typedData.primaryType),
1224
+ audit: {
1225
+ kind: "EIP712",
1226
+ primaryType: typedData.primaryType,
1227
+ deliveryKind: delivery.kind,
1228
+ ...args.audit ?? {}
1229
+ },
1230
+ feeSnapshot: {}
1231
+ }
1232
+ ]
1233
+ });
1234
+ }
1235
+ var EXCHANGE_DOMAIN = {
1236
+ name: "Exchange",
1237
+ version: "1",
1238
+ chainId: 1337,
1239
+ verifyingContract: "0x0000000000000000000000000000000000000000"
1240
+ };
1241
+ var AGENT_TYPES = {
1242
+ Agent: [
1243
+ { name: "source", type: "string" },
1244
+ { name: "connectionId", type: "bytes32" }
1245
+ ]
1246
+ };
1247
+ function adjustMsgpackValue(value) {
1248
+ if (Array.isArray(value)) return value.map(adjustMsgpackValue);
1249
+ if (typeof value === "object" && value !== null) {
1250
+ const result = {};
1251
+ for (const key of Object.keys(value)) {
1252
+ const entry = value[key];
1253
+ if (entry !== void 0) result[key] = adjustMsgpackValue(entry);
1254
+ }
1255
+ return result;
1256
+ }
1257
+ if (typeof value === "number" && Number.isInteger(value) && (value >= 4294967296 || value < -2147483648)) {
1258
+ return BigInt(value);
1259
+ }
1260
+ return value;
1261
+ }
1262
+ function toUint64Bytes(n) {
1263
+ const bytes = new Uint8Array(8);
1264
+ new DataView(bytes.buffer).setBigUint64(0, BigInt(n));
1265
+ return bytes;
1266
+ }
1267
+ function concatBytes(...parts) {
1268
+ const total = parts.reduce((sum, p) => sum + p.length, 0);
1269
+ const out = new Uint8Array(total);
1270
+ let offset = 0;
1271
+ for (const p of parts) {
1272
+ out.set(p, offset);
1273
+ offset += p.length;
1274
+ }
1275
+ return out;
1276
+ }
1277
+ function hexToBytes(hex) {
1278
+ const h = hex.startsWith("0x") ? hex.slice(2) : hex;
1279
+ const bytes = new Uint8Array(h.length / 2);
1280
+ for (let i = 0; i < bytes.length; i++) {
1281
+ bytes[i] = parseInt(h.slice(i * 2, i * 2 + 2), 16);
1282
+ }
1283
+ return bytes;
1284
+ }
1285
+ function createHyperliquidL1ActionHash(args) {
1286
+ const { action, nonce, vaultAddress, expiresAfter } = args;
1287
+ const actionBytes = msgpack.encode(adjustMsgpackValue(action));
1288
+ const nonceBytes = toUint64Bytes(nonce);
1289
+ const vaultMarker = vaultAddress ? new Uint8Array([1]) : new Uint8Array([0]);
1290
+ const vaultBytes = vaultAddress ? hexToBytes(vaultAddress) : new Uint8Array();
1291
+ const expiresMarker = expiresAfter !== void 0 ? new Uint8Array([0]) : new Uint8Array();
1292
+ const expiresBytes = expiresAfter !== void 0 ? toUint64Bytes(expiresAfter) : new Uint8Array();
1293
+ const bytes = concatBytes(actionBytes, nonceBytes, vaultMarker, vaultBytes, expiresMarker, expiresBytes);
1294
+ return viem.keccak256(bytes);
1295
+ }
1296
+ function buildHyperliquidAgentTypedData(args) {
1297
+ const connectionId = createHyperliquidL1ActionHash(args);
1298
+ const source = args.isTestnet ? "b" : "a";
1299
+ return {
1300
+ domain: EXCHANGE_DOMAIN,
1301
+ types: AGENT_TYPES,
1302
+ primaryType: "Agent",
1303
+ message: {
1304
+ source,
1305
+ connectionId
1306
+ },
1307
+ connectionId,
1308
+ nonce: args.nonce,
1309
+ action: args.action
1310
+ };
1311
+ }
1312
+ function buildHyperliquidUpdateLeverageAction(args) {
1313
+ const leverage = Math.trunc(args.leverage);
1314
+ if (!Number.isFinite(leverage) || leverage < 1) {
1315
+ throw new Error("leverage must be a positive integer");
1316
+ }
1317
+ return {
1318
+ type: "updateLeverage",
1319
+ asset: args.asset,
1320
+ isCross: args.isCross !== false,
1321
+ leverage
1322
+ };
1323
+ }
1324
+ function hyperliquidFloatToWire(value) {
1325
+ const n = typeof value === "number" ? value : Number.parseFloat(String(value).trim());
1326
+ if (!Number.isFinite(n)) throw new Error("Invalid Hyperliquid wire number.");
1327
+ const rounded = n.toFixed(8);
1328
+ if (Math.abs(Number.parseFloat(rounded) - n) >= 1e-12) {
1329
+ throw new Error(`Hyperliquid wire value ${value} has too many decimal places.`);
1330
+ }
1331
+ const normalized = Number(rounded === "-0" ? "0" : rounded);
1332
+ return String(normalized);
1333
+ }
1334
+ function hyperliquidL1TifFromKey(tif) {
1335
+ const key = String(tif ?? "gtc").trim().toLowerCase();
1336
+ if (key === "alo") return "Alo";
1337
+ if (key === "ioc") return "Ioc";
1338
+ if (key === "gtc") return "Gtc";
1339
+ throw new Error(`Unknown time-in-force: ${tif}. Use alo, gtc, or ioc.`);
1340
+ }
1341
+ function buildHyperliquidLimitOrderWire(args) {
1342
+ return {
1343
+ a: args.asset,
1344
+ b: args.isBuy,
1345
+ p: hyperliquidFloatToWire(args.limitPxHuman),
1346
+ s: hyperliquidFloatToWire(args.szHuman),
1347
+ r: Boolean(args.reduceOnly),
1348
+ t: { limit: { tif: hyperliquidL1TifFromKey(args.tif) } }
1349
+ };
1350
+ }
1351
+ function buildHyperliquidTriggerOrderWire(args) {
1352
+ const mode = args.tpslExecMode ?? "limit_at_trigger";
1353
+ const triggerPx = hyperliquidFloatToWire(args.triggerPxHuman);
1354
+ const limitPx = mode === "market" ? triggerPx : hyperliquidFloatToWire(args.limitPxHuman ?? args.triggerPxHuman);
1355
+ return {
1356
+ a: args.asset,
1357
+ b: args.isBuy,
1358
+ p: limitPx,
1359
+ s: hyperliquidFloatToWire(args.szHuman),
1360
+ r: true,
1361
+ t: {
1362
+ trigger: {
1363
+ isMarket: mode === "market",
1364
+ triggerPx,
1365
+ tpsl: args.tpsl
1366
+ }
1367
+ }
1368
+ };
1369
+ }
1370
+ function validateHyperliquidTpslGeometry(args) {
1371
+ const entry = Number.parseFloat(String(args.entryPxHuman).trim());
1372
+ const tp = args.takeProfitTriggerPxHuman?.trim() != null && args.takeProfitTriggerPxHuman.trim() !== "" ? Number.parseFloat(args.takeProfitTriggerPxHuman.trim()) : null;
1373
+ const sl = args.stopLossTriggerPxHuman?.trim() != null && args.stopLossTriggerPxHuman.trim() !== "" ? Number.parseFloat(args.stopLossTriggerPxHuman.trim()) : null;
1374
+ if (!Number.isFinite(entry)) throw new Error("Invalid entry limit price for TP/SL validation.");
1375
+ if (tp != null && !Number.isFinite(tp)) throw new Error("Invalid take-profit trigger price.");
1376
+ if (sl != null && !Number.isFinite(sl)) throw new Error("Invalid stop-loss trigger price.");
1377
+ if (args.isBuy) {
1378
+ if (sl != null && sl >= entry) {
1379
+ throw new Error("Long stop-loss must be below entry price.");
1380
+ }
1381
+ if (tp != null && tp <= entry) {
1382
+ throw new Error("Long take-profit must be above entry price.");
1383
+ }
1384
+ } else {
1385
+ if (sl != null && sl <= entry) {
1386
+ throw new Error("Short stop-loss must be above entry price.");
1387
+ }
1388
+ if (tp != null && tp >= entry) {
1389
+ throw new Error("Short take-profit must be below entry price.");
1390
+ }
1391
+ }
1392
+ }
1393
+ function buildHyperliquidNormalTpslOrderWires(args) {
1394
+ validateHyperliquidTpslGeometry({
1395
+ isBuy: args.isBuy,
1396
+ entryPxHuman: args.limitPxHuman,
1397
+ takeProfitTriggerPxHuman: args.takeProfitTriggerPxHuman,
1398
+ stopLossTriggerPxHuman: args.stopLossTriggerPxHuman
1399
+ });
1400
+ const orders = [
1401
+ buildHyperliquidLimitOrderWire({
1402
+ asset: args.asset,
1403
+ isBuy: args.isBuy,
1404
+ limitPxHuman: args.limitPxHuman,
1405
+ szHuman: args.szHuman,
1406
+ tif: args.tif
1407
+ })
1408
+ ];
1409
+ const closeIsBuy = !args.isBuy;
1410
+ const tp = args.takeProfitTriggerPxHuman?.trim();
1411
+ const sl = args.stopLossTriggerPxHuman?.trim();
1412
+ if (tp) {
1413
+ orders.push(
1414
+ buildHyperliquidTriggerOrderWire({
1415
+ asset: args.asset,
1416
+ isBuy: closeIsBuy,
1417
+ szHuman: args.szHuman,
1418
+ triggerPxHuman: tp,
1419
+ tpsl: "tp",
1420
+ tpslExecMode: args.tpslExecMode
1421
+ })
1422
+ );
1423
+ }
1424
+ if (sl) {
1425
+ orders.push(
1426
+ buildHyperliquidTriggerOrderWire({
1427
+ asset: args.asset,
1428
+ isBuy: closeIsBuy,
1429
+ szHuman: args.szHuman,
1430
+ triggerPxHuman: sl,
1431
+ tpsl: "sl",
1432
+ tpslExecMode: args.tpslExecMode
1433
+ })
1434
+ );
1435
+ }
1436
+ return orders;
1437
+ }
1438
+ function buildHyperliquidOrderAction(args) {
1439
+ return {
1440
+ type: "order",
1441
+ orders: args.orders,
1442
+ grouping: args.grouping ?? "na"
1443
+ };
1444
+ }
1445
+
1446
+ // src/protocols/evm/hyperliquid/exchangeMultisign.ts
1447
+ var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
1448
+ async function buildHyperliquidLimitOrderWithTpslMultisign(args) {
1449
+ const marketKind = args.marketKind ?? "perp";
1450
+ const { asset } = await hyperliquidResolveAsset({
1451
+ chainId: args.chainId,
1452
+ coin: args.coin,
1453
+ marketKind,
1454
+ dex: args.dex
1455
+ });
1456
+ const tp = args.takeProfitTriggerPxHuman?.trim();
1457
+ const sl = args.stopLossTriggerPxHuman?.trim();
1458
+ if (!tp && !sl) {
1459
+ throw new Error("At least one of takeProfitTriggerPxHuman or stopLossTriggerPxHuman is required for bracket orders.");
1460
+ }
1461
+ const orderWires = buildHyperliquidNormalTpslOrderWires({
1462
+ asset,
1463
+ isBuy: args.isBuy,
1464
+ limitPxHuman: args.limitPxHuman,
1465
+ szHuman: args.szHuman,
1466
+ tif: args.tif,
1467
+ takeProfitTriggerPxHuman: tp || void 0,
1468
+ stopLossTriggerPxHuman: sl || void 0,
1469
+ tpslExecMode: args.tpslExecMode
1470
+ });
1471
+ const action = buildHyperliquidOrderAction({
1472
+ orders: orderWires,
1473
+ grouping: "normalTpsl"
1474
+ });
1475
+ const nonce = args.nonce ?? Date.now();
1476
+ const isTestnet = args.chainId === 998;
1477
+ const typed = buildHyperliquidAgentTypedData({ action, nonce, isTestnet });
1478
+ return buildEip712MultisignBody({
1479
+ keyGen: args.keyGen,
1480
+ purposeText: args.purposeText,
1481
+ destinationChainID: String(args.chainId),
1482
+ destinationAddress: ZERO_ADDRESS,
1483
+ typedData: {
1484
+ domain: typed.domain,
1485
+ types: typed.types,
1486
+ primaryType: typed.primaryType,
1487
+ message: typed.message
1488
+ },
1489
+ delivery: {
1490
+ kind: "hyperliquid_exchange",
1491
+ chainId: args.chainId,
1492
+ isTestnet,
1493
+ action,
1494
+ nonce
1495
+ },
1496
+ audit: {
1497
+ protocol: "hyperliquid",
1498
+ action: "limitOrderWithTpsl",
1499
+ coin: args.coin,
1500
+ marketKind,
1501
+ asset,
1502
+ isBuy: args.isBuy,
1503
+ limitPxHuman: args.limitPxHuman,
1504
+ szHuman: args.szHuman,
1505
+ takeProfitTriggerPxHuman: tp ?? null,
1506
+ stopLossTriggerPxHuman: sl ?? null,
1507
+ tpslExecMode: args.tpslExecMode ?? "limit_at_trigger",
1508
+ grouping: "normalTpsl",
1509
+ nonce,
1510
+ connectionId: typed.connectionId
1511
+ }
1512
+ });
1513
+ }
1514
+ async function buildHyperliquidUpdateLeverageMultisign(args) {
1515
+ const marketKind = args.marketKind ?? "perp";
1516
+ const { asset } = await hyperliquidResolveAsset({
1517
+ chainId: args.chainId,
1518
+ coin: args.coin,
1519
+ marketKind,
1520
+ dex: args.dex
1521
+ });
1522
+ const action = buildHyperliquidUpdateLeverageAction({
1523
+ asset,
1524
+ leverage: args.leverage,
1525
+ isCross: args.isCross
1526
+ });
1527
+ const nonce = args.nonce ?? Date.now();
1528
+ const isTestnet = args.chainId === 998;
1529
+ const typed = buildHyperliquidAgentTypedData({ action, nonce, isTestnet });
1530
+ return buildEip712MultisignBody({
1531
+ keyGen: args.keyGen,
1532
+ purposeText: args.purposeText,
1533
+ destinationChainID: String(args.chainId),
1534
+ destinationAddress: ZERO_ADDRESS,
1535
+ typedData: {
1536
+ domain: typed.domain,
1537
+ types: typed.types,
1538
+ primaryType: typed.primaryType,
1539
+ message: typed.message
1540
+ },
1541
+ delivery: {
1542
+ kind: "hyperliquid_exchange",
1543
+ chainId: args.chainId,
1544
+ isTestnet,
1545
+ action,
1546
+ nonce
1547
+ },
1548
+ audit: {
1549
+ protocol: "hyperliquid",
1550
+ action: "updateLeverage",
1551
+ coin: args.coin,
1552
+ marketKind,
1553
+ asset,
1554
+ leverage: action.leverage,
1555
+ isCross: action.isCross,
1556
+ nonce,
1557
+ connectionId: typed.connectionId
1558
+ }
1559
+ });
1560
+ }
1158
1561
 
1159
1562
  // src/protocols/evm/hyperliquid/multisign.ts
1563
+ function hasHyperliquidBracketTpsl(args) {
1564
+ return Boolean(args.takeProfitTriggerPxHuman?.trim() || args.stopLossTriggerPxHuman?.trim());
1565
+ }
1160
1566
  async function buildCoreWriterMultisign(common, data, signatureMeta) {
1161
1567
  const step = coreWriterStep(data);
1162
1568
  return buildEvmMultisignBatch({
@@ -1181,6 +1587,26 @@ async function buildCoreWriterMultisign(common, data, signatureMeta) {
1181
1587
  });
1182
1588
  }
1183
1589
  async function buildEvmMultisignBodyHyperliquidLimitOrderBatch(args) {
1590
+ if (hasHyperliquidBracketTpsl(args)) {
1591
+ if (args.reduceOnly) {
1592
+ throw new Error("reduceOnly cannot be combined with takeProfitTriggerPxHuman or stopLossTriggerPxHuman.");
1593
+ }
1594
+ return buildHyperliquidLimitOrderWithTpslMultisign({
1595
+ keyGen: args.keyGen,
1596
+ chainId: args.chainId,
1597
+ purposeText: args.purposeText,
1598
+ coin: args.coin,
1599
+ marketKind: args.marketKind,
1600
+ dex: args.dex,
1601
+ isBuy: args.isBuy,
1602
+ limitPxHuman: args.limitPxHuman,
1603
+ szHuman: args.szHuman,
1604
+ tif: args.tif,
1605
+ takeProfitTriggerPxHuman: args.takeProfitTriggerPxHuman,
1606
+ stopLossTriggerPxHuman: args.stopLossTriggerPxHuman,
1607
+ tpslExecMode: args.tpslExecMode
1608
+ });
1609
+ }
1184
1610
  const marketKind = args.marketKind ?? "perp";
1185
1611
  const { asset } = await hyperliquidResolveAsset({
1186
1612
  chainId: args.chainId,
@@ -1330,211 +1756,6 @@ async function buildEvmMultisignBodyHyperliquidDelegateOnlyBatch(args) {
1330
1756
  async function buildEvmMultisignBodyHyperliquidUndelegateBatch(args) {
1331
1757
  return buildEvmMultisignBodyHyperliquidDelegateBatch({ ...args, isUndelegate: true });
1332
1758
  }
1333
- var EXCHANGE_DOMAIN = {
1334
- name: "Exchange",
1335
- version: "1",
1336
- chainId: 1337,
1337
- verifyingContract: "0x0000000000000000000000000000000000000000"
1338
- };
1339
- var AGENT_TYPES = {
1340
- Agent: [
1341
- { name: "source", type: "string" },
1342
- { name: "connectionId", type: "bytes32" }
1343
- ]
1344
- };
1345
- function adjustMsgpackValue(value) {
1346
- if (Array.isArray(value)) return value.map(adjustMsgpackValue);
1347
- if (typeof value === "object" && value !== null) {
1348
- const result = {};
1349
- for (const key of Object.keys(value)) {
1350
- const entry = value[key];
1351
- if (entry !== void 0) result[key] = adjustMsgpackValue(entry);
1352
- }
1353
- return result;
1354
- }
1355
- if (typeof value === "number" && Number.isInteger(value) && (value >= 4294967296 || value < -2147483648)) {
1356
- return BigInt(value);
1357
- }
1358
- return value;
1359
- }
1360
- function toUint64Bytes(n) {
1361
- const bytes = new Uint8Array(8);
1362
- new DataView(bytes.buffer).setBigUint64(0, BigInt(n));
1363
- return bytes;
1364
- }
1365
- function concatBytes(...parts) {
1366
- const total = parts.reduce((sum, p) => sum + p.length, 0);
1367
- const out = new Uint8Array(total);
1368
- let offset = 0;
1369
- for (const p of parts) {
1370
- out.set(p, offset);
1371
- offset += p.length;
1372
- }
1373
- return out;
1374
- }
1375
- function hexToBytes(hex) {
1376
- const h = hex.startsWith("0x") ? hex.slice(2) : hex;
1377
- const bytes = new Uint8Array(h.length / 2);
1378
- for (let i = 0; i < bytes.length; i++) {
1379
- bytes[i] = parseInt(h.slice(i * 2, i * 2 + 2), 16);
1380
- }
1381
- return bytes;
1382
- }
1383
- function createHyperliquidL1ActionHash(args) {
1384
- const { action, nonce, vaultAddress, expiresAfter } = args;
1385
- const actionBytes = msgpack.encode(adjustMsgpackValue(action));
1386
- const nonceBytes = toUint64Bytes(nonce);
1387
- const vaultMarker = vaultAddress ? new Uint8Array([1]) : new Uint8Array([0]);
1388
- const vaultBytes = vaultAddress ? hexToBytes(vaultAddress) : new Uint8Array();
1389
- const expiresMarker = expiresAfter !== void 0 ? new Uint8Array([0]) : new Uint8Array();
1390
- const expiresBytes = expiresAfter !== void 0 ? toUint64Bytes(expiresAfter) : new Uint8Array();
1391
- const bytes = concatBytes(actionBytes, nonceBytes, vaultMarker, vaultBytes, expiresMarker, expiresBytes);
1392
- return viem.keccak256(bytes);
1393
- }
1394
- function buildHyperliquidAgentTypedData(args) {
1395
- const connectionId = createHyperliquidL1ActionHash(args);
1396
- const source = args.isTestnet ? "b" : "a";
1397
- return {
1398
- domain: EXCHANGE_DOMAIN,
1399
- types: AGENT_TYPES,
1400
- primaryType: "Agent",
1401
- message: {
1402
- source,
1403
- connectionId
1404
- },
1405
- connectionId,
1406
- nonce: args.nonce,
1407
- action: args.action
1408
- };
1409
- }
1410
- function buildHyperliquidUpdateLeverageAction(args) {
1411
- const leverage = Math.trunc(args.leverage);
1412
- if (!Number.isFinite(leverage) || leverage < 1) {
1413
- throw new Error("leverage must be a positive integer");
1414
- }
1415
- return {
1416
- type: "updateLeverage",
1417
- asset: args.asset,
1418
- isCross: args.isCross !== false,
1419
- leverage
1420
- };
1421
- }
1422
- var EIP712_SIGN_REQUEST_KIND = "eip712";
1423
- function msgHashNo0x(digest) {
1424
- return digest.startsWith("0x") ? digest.slice(2) : digest;
1425
- }
1426
- function eip712SignatureText(domain, primaryType) {
1427
- return JSON.stringify({
1428
- kind: "EIP-712",
1429
- ...typeof domain.name === "string" ? { name: domain.name } : {},
1430
- primaryType
1431
- });
1432
- }
1433
- function jsonStringifyForAudit(value) {
1434
- return JSON.stringify(value, (_, v) => typeof v === "bigint" ? v.toString() : v);
1435
- }
1436
- function eip712MsgRawHex(typedData, delivery) {
1437
- const envelope = {
1438
- version: 1,
1439
- ...typedData,
1440
- delivery
1441
- };
1442
- return viem.stringToHex(jsonStringifyForAudit(envelope));
1443
- }
1444
- function buildEip712MultisignBody(args) {
1445
- const { typedData, delivery } = args;
1446
- const digest = viem.hashTypedData({
1447
- domain: typedData.domain,
1448
- types: typedData.types,
1449
- primaryType: typedData.primaryType,
1450
- message: typedData.message
1451
- });
1452
- const extraJSON = {
1453
- signRequestKind: EIP712_SIGN_REQUEST_KIND,
1454
- eip712: {
1455
- version: 1,
1456
- digest,
1457
- domain: typedData.domain,
1458
- types: typedData.types,
1459
- primaryType: typedData.primaryType,
1460
- message: typedData.message
1461
- },
1462
- delivery
1463
- };
1464
- return finalizeMultisign({
1465
- keyGen: args.keyGen,
1466
- purposeText: args.purposeText,
1467
- purposeSuffix: args.purposeSuffix,
1468
- destinationChainID: args.destinationChainID,
1469
- destinationAddress: args.destinationAddress,
1470
- extraJSON,
1471
- legs: [
1472
- {
1473
- msgHash: msgHashNo0x(digest),
1474
- msgRaw: eip712MsgRawHex(typedData, delivery),
1475
- destinationAddress: args.destinationAddress,
1476
- signatureText: eip712SignatureText(typedData.domain, typedData.primaryType),
1477
- audit: {
1478
- kind: "EIP712",
1479
- primaryType: typedData.primaryType,
1480
- deliveryKind: delivery.kind,
1481
- ...args.audit ?? {}
1482
- },
1483
- feeSnapshot: {}
1484
- }
1485
- ]
1486
- });
1487
- }
1488
-
1489
- // src/protocols/evm/hyperliquid/exchangeMultisign.ts
1490
- var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
1491
- async function buildHyperliquidUpdateLeverageMultisign(args) {
1492
- const marketKind = args.marketKind ?? "perp";
1493
- const { asset } = await hyperliquidResolveAsset({
1494
- chainId: args.chainId,
1495
- coin: args.coin,
1496
- marketKind,
1497
- dex: args.dex
1498
- });
1499
- const action = buildHyperliquidUpdateLeverageAction({
1500
- asset,
1501
- leverage: args.leverage,
1502
- isCross: args.isCross
1503
- });
1504
- const nonce = args.nonce ?? Date.now();
1505
- const isTestnet = args.chainId === 998;
1506
- const typed = buildHyperliquidAgentTypedData({ action, nonce, isTestnet });
1507
- return buildEip712MultisignBody({
1508
- keyGen: args.keyGen,
1509
- purposeText: args.purposeText,
1510
- destinationChainID: String(args.chainId),
1511
- destinationAddress: ZERO_ADDRESS,
1512
- typedData: {
1513
- domain: typed.domain,
1514
- types: typed.types,
1515
- primaryType: typed.primaryType,
1516
- message: typed.message
1517
- },
1518
- delivery: {
1519
- kind: "hyperliquid_exchange",
1520
- chainId: args.chainId,
1521
- isTestnet,
1522
- action,
1523
- nonce
1524
- },
1525
- audit: {
1526
- protocol: "hyperliquid",
1527
- action: "updateLeverage",
1528
- coin: args.coin,
1529
- marketKind,
1530
- asset,
1531
- leverage: action.leverage,
1532
- isCross: action.isCross,
1533
- nonce,
1534
- connectionId: typed.connectionId
1535
- }
1536
- });
1537
- }
1538
1759
  var HYPERLIQUID_BRIDGE_MIN_DEPOSIT_USDC = 5;
1539
1760
  var HYPERLIQUID_BRIDGE_ARBITRUM_MAINNET_CHAIN_ID = 42161;
1540
1761
  var HYPERLIQUID_BRIDGE_ARBITRUM_TESTNET_CHAIN_ID = 421614;
@@ -1731,6 +1952,44 @@ async function buildHyperliquidBridgeWithdrawMultisign(args) {
1731
1952
  });
1732
1953
  }
1733
1954
 
1955
+ // src/protocols/evm/hyperliquid/pendingClose.ts
1956
+ function parsePositiveSize(value) {
1957
+ if (value == null || !String(value).trim()) return null;
1958
+ const n = Number.parseFloat(String(value).trim());
1959
+ if (!Number.isFinite(n) || n <= 0) return null;
1960
+ return n;
1961
+ }
1962
+ function hyperliquidOrderClosesPosition(position, orderSide) {
1963
+ const side = String(orderSide).trim().toUpperCase();
1964
+ return position.isLong ? side === "A" : side === "B";
1965
+ }
1966
+ function hyperliquidOrderCountsAsPendingClose(order) {
1967
+ return Boolean(order.reduceOnly) || Boolean(order.isTrigger);
1968
+ }
1969
+ function hyperliquidPendingCloseForPosition(args) {
1970
+ const positionSize = parsePositiveSize(args.position.size);
1971
+ if (positionSize == null) {
1972
+ return { pendingCloseSz: 0, pendingClosePct: 0 };
1973
+ }
1974
+ let pendingCloseSz = 0;
1975
+ for (const order of args.orders) {
1976
+ if (order.coin !== args.position.coin) continue;
1977
+ if (!hyperliquidOrderClosesPosition(args.position, order.side)) continue;
1978
+ if (!hyperliquidOrderCountsAsPendingClose(order)) continue;
1979
+ const sz = parsePositiveSize(order.sz);
1980
+ if (sz != null) pendingCloseSz += sz;
1981
+ }
1982
+ const pendingClosePct = Math.min(100, pendingCloseSz / positionSize * 100);
1983
+ return { pendingCloseSz, pendingClosePct };
1984
+ }
1985
+ function hyperliquidPendingCloseByCoin(args) {
1986
+ const out = /* @__PURE__ */ new Map();
1987
+ for (const position of args.positions) {
1988
+ out.set(position.key, hyperliquidPendingCloseForPosition({ position, orders: args.orders }));
1989
+ }
1990
+ return out;
1991
+ }
1992
+
1734
1993
  // src/protocols/evm/hyperliquid/index.ts
1735
1994
  var HYPERLIQUID_PROTOCOL_ID = "hyperliquid";
1736
1995
  var hyperliquidProtocolModule = {
@@ -1750,7 +2009,7 @@ var hyperliquidProtocolModule = {
1750
2009
  id: "hyperliquid.limitOrder",
1751
2010
  protocolId: HYPERLIQUID_PROTOCOL_ID,
1752
2011
  chainCategory: "evm",
1753
- description: "Place a Hyperliquid limit/IoC order via HyperEVM CoreWriter",
2012
+ description: "Place a Hyperliquid limit/IoC order via CoreWriter, or L1 normalTpsl bracket when TP/SL triggers are set",
1754
2013
  commonParams: ["keyGen", "purposeText", "useCustomGas"],
1755
2014
  params: {
1756
2015
  coin: { type: "string", required: true, description: "Market coin e.g. BTC" },
@@ -1759,7 +2018,10 @@ var hyperliquidProtocolModule = {
1759
2018
  szHuman: { type: "string", required: true, description: "Order size in coin units" },
1760
2019
  marketKind: { type: "string", required: false, description: "perp (default) or spot" },
1761
2020
  tif: { type: "string", required: false, description: "gtc, ioc, or alo" },
1762
- dex: { type: "string", required: false, description: "HIP-3 dex name when applicable" }
2021
+ dex: { type: "string", required: false, description: "HIP-3 dex name when applicable" },
2022
+ takeProfitTriggerPxHuman: { type: "string", required: false, description: "TP trigger \u2014 enables L1 bracket with SL" },
2023
+ stopLossTriggerPxHuman: { type: "string", required: false, description: "SL trigger \u2014 enables L1 bracket with TP" },
2024
+ tpslExecMode: { type: "string", required: false, description: "limit_at_trigger (default) or market" }
1763
2025
  }
1764
2026
  },
1765
2027
  {
@@ -1944,6 +2206,11 @@ exports.buildEvmMultisignBodyHyperliquidVaultDepositBatch = buildEvmMultisignBod
1944
2206
  exports.buildEvmMultisignBodyHyperliquidVaultWithdrawBatch = buildEvmMultisignBodyHyperliquidVaultWithdrawBatch;
1945
2207
  exports.buildHyperliquidAgentTypedData = buildHyperliquidAgentTypedData;
1946
2208
  exports.buildHyperliquidBridgeWithdrawMultisign = buildHyperliquidBridgeWithdrawMultisign;
2209
+ exports.buildHyperliquidLimitOrderWire = buildHyperliquidLimitOrderWire;
2210
+ exports.buildHyperliquidLimitOrderWithTpslMultisign = buildHyperliquidLimitOrderWithTpslMultisign;
2211
+ exports.buildHyperliquidNormalTpslOrderWires = buildHyperliquidNormalTpslOrderWires;
2212
+ exports.buildHyperliquidOrderAction = buildHyperliquidOrderAction;
2213
+ exports.buildHyperliquidTriggerOrderWire = buildHyperliquidTriggerOrderWire;
1947
2214
  exports.buildHyperliquidUpdateLeverageAction = buildHyperliquidUpdateLeverageAction;
1948
2215
  exports.buildHyperliquidUpdateLeverageMultisign = buildHyperliquidUpdateLeverageMultisign;
1949
2216
  exports.buildHyperliquidWithdraw3Action = buildHyperliquidWithdraw3Action;
@@ -1964,6 +2231,7 @@ exports.hyperliquidFetchClearinghouseState = hyperliquidFetchClearinghouseState;
1964
2231
  exports.hyperliquidFetchDelegations = hyperliquidFetchDelegations;
1965
2232
  exports.hyperliquidFetchDelegationsForExecutor = hyperliquidFetchDelegationsForExecutor;
1966
2233
  exports.hyperliquidFetchDexList = hyperliquidFetchDexList;
2234
+ exports.hyperliquidFetchFrontendOpenOrders = hyperliquidFetchFrontendOpenOrders;
1967
2235
  exports.hyperliquidFetchMarketSnapshot = hyperliquidFetchMarketSnapshot;
1968
2236
  exports.hyperliquidFetchMarketSnapshotSummary = hyperliquidFetchMarketSnapshotSummary;
1969
2237
  exports.hyperliquidFetchMarketsSummary = hyperliquidFetchMarketsSummary;
@@ -1989,9 +2257,15 @@ exports.hyperliquidFetchUserVaultEquities = hyperliquidFetchUserVaultEquities;
1989
2257
  exports.hyperliquidFetchUserVaultEquitiesSummary = hyperliquidFetchUserVaultEquitiesSummary;
1990
2258
  exports.hyperliquidFetchVaultCatalogSummary = hyperliquidFetchVaultCatalogSummary;
1991
2259
  exports.hyperliquidFetchVaultSummaries = hyperliquidFetchVaultSummaries;
2260
+ exports.hyperliquidFloatToWire = hyperliquidFloatToWire;
1992
2261
  exports.hyperliquidInferDexFromCoin = hyperliquidInferDexFromCoin;
1993
2262
  exports.hyperliquidIsSpotAssetId = hyperliquidIsSpotAssetId;
2263
+ exports.hyperliquidL1TifFromKey = hyperliquidL1TifFromKey;
1994
2264
  exports.hyperliquidMarketSymbol = hyperliquidMarketSymbol;
2265
+ exports.hyperliquidOrderClosesPosition = hyperliquidOrderClosesPosition;
2266
+ exports.hyperliquidOrderCountsAsPendingClose = hyperliquidOrderCountsAsPendingClose;
2267
+ exports.hyperliquidPendingCloseByCoin = hyperliquidPendingCloseByCoin;
2268
+ exports.hyperliquidPendingCloseForPosition = hyperliquidPendingCloseForPosition;
1995
2269
  exports.hyperliquidProtocolModule = hyperliquidProtocolModule;
1996
2270
  exports.hyperliquidResolveAsset = hyperliquidResolveAsset;
1997
2271
  exports.hyperliquidResolveOhlcvWindow = hyperliquidResolveOhlcvWindow;
@@ -2006,5 +2280,6 @@ exports.isHyperliquidBridgeArbitrumChainSupported = isHyperliquidBridgeArbitrumC
2006
2280
  exports.isHyperliquidBridgeArbitrumUsdcRow = isHyperliquidBridgeArbitrumUsdcRow;
2007
2281
  exports.isHyperliquidChainSupported = isHyperliquidChainSupported;
2008
2282
  exports.isHyperliquidHyperEvmUsdcRow = isHyperliquidHyperEvmUsdcRow;
2283
+ exports.validateHyperliquidTpslGeometry = validateHyperliquidTpslGeometry;
2009
2284
  //# sourceMappingURL=index.cjs.map
2010
2285
  //# sourceMappingURL=index.cjs.map