opentool 0.15.1 → 0.17.0

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.
@@ -582,37 +582,6 @@ async function signUserPortfolioMargin(args) {
582
582
  });
583
583
  return splitSignature(signatureHex);
584
584
  }
585
- async function signUserDexAbstraction(args) {
586
- const { wallet, action } = args;
587
- const domain = {
588
- name: "HyperliquidSignTransaction",
589
- version: "1",
590
- chainId: Number.parseInt(action.signatureChainId, 16),
591
- verifyingContract: ZERO_ADDRESS
592
- };
593
- const message = {
594
- hyperliquidChain: action.hyperliquidChain,
595
- user: action.user,
596
- enabled: action.enabled,
597
- nonce: BigInt(action.nonce)
598
- };
599
- const types = {
600
- "HyperliquidTransaction:UserDexAbstraction": [
601
- { name: "hyperliquidChain", type: "string" },
602
- { name: "user", type: "address" },
603
- { name: "enabled", type: "bool" },
604
- { name: "nonce", type: "uint64" }
605
- ]
606
- };
607
- const signatureHex = await wallet.walletClient.signTypedData({
608
- account: wallet.account,
609
- domain,
610
- types,
611
- primaryType: "HyperliquidTransaction:UserDexAbstraction",
612
- message
613
- });
614
- return splitSignature(signatureHex);
615
- }
616
585
  async function signUserSetAbstraction(args) {
617
586
  const { wallet, action } = args;
618
587
  const domain = {
@@ -1027,17 +996,6 @@ var HyperliquidExchangeClient = class {
1027
996
  ...params
1028
997
  });
1029
998
  }
1030
- setDexAbstraction(params) {
1031
- const base = {
1032
- wallet: this.wallet,
1033
- enabled: params.enabled,
1034
- environment: this.environment,
1035
- vaultAddress: this.vaultAddress,
1036
- expiresAfter: this.expiresAfter,
1037
- nonceSource: this.nonceSource
1038
- };
1039
- return setHyperliquidDexAbstraction(params.user ? { ...base, user: params.user } : base);
1040
- }
1041
999
  setAccountAbstractionMode(params) {
1042
1000
  const base = {
1043
1001
  wallet: this.wallet,
@@ -1103,46 +1061,6 @@ async function setHyperliquidPortfolioMargin(options) {
1103
1061
  }
1104
1062
  return postExchange(env, body);
1105
1063
  }
1106
- async function setHyperliquidDexAbstraction(options) {
1107
- const env = options.environment ?? "mainnet";
1108
- if (!options.wallet?.account || !options.wallet.walletClient) {
1109
- throw new Error("Wallet with signing capability is required for dex abstraction.");
1110
- }
1111
- const nonce = resolveRequiredExchangeNonce({
1112
- nonce: options.nonce,
1113
- nonceSource: options.nonceSource,
1114
- walletNonceProvider: options.walletNonceProvider,
1115
- wallet: options.wallet,
1116
- action: "Hyperliquid dex abstraction"
1117
- });
1118
- const signatureChainId = getSignatureChainId(env);
1119
- const hyperliquidChain = HL_CHAIN_LABEL[env];
1120
- const user = normalizeAddress(options.user ?? options.wallet.address);
1121
- const action = {
1122
- type: "userDexAbstraction",
1123
- enabled: Boolean(options.enabled),
1124
- hyperliquidChain,
1125
- signatureChainId,
1126
- user,
1127
- nonce
1128
- };
1129
- const signature = await signUserDexAbstraction({
1130
- wallet: options.wallet,
1131
- action
1132
- });
1133
- const body = {
1134
- action,
1135
- nonce,
1136
- signature
1137
- };
1138
- if (options.vaultAddress) {
1139
- body.vaultAddress = normalizeAddress(options.vaultAddress);
1140
- }
1141
- if (typeof options.expiresAfter === "number") {
1142
- body.expiresAfter = options.expiresAfter;
1143
- }
1144
- return postExchange(env, body);
1145
- }
1146
1064
  async function setHyperliquidAccountAbstractionMode(options) {
1147
1065
  const env = options.environment ?? "mainnet";
1148
1066
  if (!options.wallet?.account || !options.wallet.walletClient) {
@@ -1574,99 +1492,365 @@ async function postExchange(env, body) {
1574
1492
  }
1575
1493
  return json;
1576
1494
  }
1577
- function resolveRequiredNonce(params) {
1578
- if (typeof params.nonce === "number") {
1579
- return params.nonce;
1580
- }
1581
- const resolved = params.nonceSource?.() ?? params.wallet?.nonceSource?.();
1582
- if (resolved === void 0) {
1583
- throw new Error(`${params.action} requires an explicit nonce or wallet nonce source.`);
1584
- }
1585
- return resolved;
1495
+
1496
+ // src/adapters/hyperliquid/symbols.ts
1497
+ var UNKNOWN_SYMBOL2 = "UNKNOWN";
1498
+ function extractHyperliquidDex(symbol) {
1499
+ const idx = symbol.indexOf(":");
1500
+ if (idx <= 0) return null;
1501
+ const dex = symbol.slice(0, idx).trim().toLowerCase();
1502
+ return dex || null;
1586
1503
  }
1587
- function assertPositiveDecimalInput(value, label) {
1588
- if (typeof value === "number") {
1589
- if (!Number.isFinite(value) || value <= 0) {
1590
- throw new Error(`${label} must be a positive number.`);
1591
- }
1592
- return;
1593
- }
1594
- if (typeof value === "bigint") {
1595
- if (value <= 0n) {
1596
- throw new Error(`${label} must be positive.`);
1597
- }
1598
- return;
1599
- }
1504
+ function parseHyperliquidSymbol(value) {
1505
+ if (!value) return null;
1600
1506
  const trimmed = value.trim();
1601
- if (!trimmed.length) {
1602
- throw new Error(`${label} must be a non-empty string.`);
1507
+ if (!trimmed) return null;
1508
+ if (trimmed.startsWith("@")) {
1509
+ return {
1510
+ raw: trimmed,
1511
+ kind: "spotIndex",
1512
+ normalized: trimmed,
1513
+ routeTicker: trimmed,
1514
+ displaySymbol: trimmed,
1515
+ base: null,
1516
+ quote: null,
1517
+ pair: null,
1518
+ dex: null,
1519
+ leverageMode: "cross"
1520
+ };
1603
1521
  }
1604
- if (!/^(?:\d+\.?\d*|\.\d+)$/.test(trimmed)) {
1605
- throw new Error(`${label} must be a positive decimal string.`);
1522
+ const dex = extractHyperliquidDex(trimmed);
1523
+ const pair = resolveHyperliquidPair(trimmed);
1524
+ const base = normalizeHyperliquidBaseSymbol(trimmed);
1525
+ if (dex) {
1526
+ if (!base) return null;
1527
+ return {
1528
+ raw: trimmed,
1529
+ kind: "perp",
1530
+ normalized: `${dex}:${base}`,
1531
+ routeTicker: `${dex}:${base}`,
1532
+ displaySymbol: `${dex.toUpperCase()}:${base}-USDC`,
1533
+ base,
1534
+ quote: null,
1535
+ pair: null,
1536
+ dex,
1537
+ leverageMode: "isolated"
1538
+ };
1606
1539
  }
1607
- const numeric = Number(trimmed);
1608
- if (!Number.isFinite(numeric) || numeric <= 0) {
1609
- throw new Error(`${label} must be positive.`);
1540
+ if (pair) {
1541
+ const [pairBase, pairQuote] = pair.split("/");
1542
+ return {
1543
+ raw: trimmed,
1544
+ kind: "spot",
1545
+ normalized: pair,
1546
+ routeTicker: pair.replace("/", "-"),
1547
+ displaySymbol: pair.replace("/", "-"),
1548
+ base: pairBase ?? null,
1549
+ quote: pairQuote ?? null,
1550
+ pair,
1551
+ dex: null,
1552
+ leverageMode: "cross"
1553
+ };
1610
1554
  }
1555
+ if (!base) return null;
1556
+ return {
1557
+ raw: trimmed,
1558
+ kind: "perp",
1559
+ normalized: base,
1560
+ routeTicker: base,
1561
+ displaySymbol: `${base}-USDC`,
1562
+ base,
1563
+ quote: null,
1564
+ pair: null,
1565
+ dex: null,
1566
+ leverageMode: "cross"
1567
+ };
1611
1568
  }
1612
- function normalizePositiveDecimalString(raw, label) {
1613
- const trimmed = raw.trim();
1614
- if (!trimmed.length) {
1615
- throw new Error(`${label} must be a non-empty decimal string.`);
1616
- }
1617
- if (!/^(?:\d+\.?\d*|\.\d+)$/.test(trimmed)) {
1618
- throw new Error(`${label} must be a positive decimal string.`);
1619
- }
1620
- const normalized = trimmed.replace(/^0+(?=\d)/, "").replace(/(\.\d*?)0+$/, "$1").replace(/\.$/, "");
1621
- const numeric = Number(normalized);
1622
- if (!Number.isFinite(numeric) || numeric <= 0) {
1623
- throw new Error(`${label} must be positive.`);
1569
+ function normalizeSpotTokenName2(value) {
1570
+ const raw = (value ?? "").trim();
1571
+ if (!raw) return "";
1572
+ if (raw.endsWith("0") && raw.length > 1) {
1573
+ return raw.slice(0, -1);
1624
1574
  }
1575
+ return raw;
1576
+ }
1577
+ function canonicalizeHyperliquidTokenCase(value) {
1578
+ const trimmed = value.trim();
1579
+ if (!trimmed) return "";
1580
+ return trimmed === trimmed.toLowerCase() ? trimmed.toUpperCase() : trimmed;
1581
+ }
1582
+ function normalizeHyperliquidBaseSymbol(value) {
1583
+ if (!value) return null;
1584
+ const trimmed = value.trim();
1585
+ if (!trimmed) return null;
1586
+ const withoutDex = trimmed.includes(":") ? trimmed.split(":").slice(1).join(":") : trimmed;
1587
+ const base = withoutDex.split("-")[0] ?? withoutDex;
1588
+ const baseNoPair = base.split("/")[0] ?? base;
1589
+ const normalized = canonicalizeHyperliquidTokenCase(baseNoPair);
1590
+ if (!normalized || normalized === UNKNOWN_SYMBOL2) return null;
1625
1591
  return normalized;
1626
1592
  }
1627
- async function placeHyperliquidOrder(options) {
1628
- const {
1629
- wallet,
1630
- orders,
1631
- grouping = "na",
1632
- environment,
1633
- vaultAddress,
1634
- expiresAfter,
1635
- nonce
1636
- } = options;
1637
- if (!wallet?.account || !wallet.walletClient) {
1638
- throw new Error("Hyperliquid order signing requires a wallet with signing capabilities.");
1593
+ function normalizeHyperliquidMetaSymbol(symbol) {
1594
+ const trimmed = symbol.trim();
1595
+ const noDex = trimmed.includes(":") ? trimmed.split(":").slice(1).join(":") : trimmed;
1596
+ const noPair = noDex.split("-")[0] ?? noDex;
1597
+ return (noPair.split("/")[0] ?? noPair).trim();
1598
+ }
1599
+ function resolveHyperliquidPair(value) {
1600
+ if (!value) return null;
1601
+ const trimmed = value.trim();
1602
+ if (!trimmed) return null;
1603
+ const withoutDex = trimmed.includes(":") ? trimmed.split(":").slice(1).join(":") : trimmed;
1604
+ if (withoutDex.includes("/")) {
1605
+ const [base, ...rest] = withoutDex.split("/");
1606
+ const quote = rest.join("/").trim();
1607
+ if (!base || !quote) return null;
1608
+ return `${canonicalizeHyperliquidTokenCase(base)}/${canonicalizeHyperliquidTokenCase(quote)}`;
1639
1609
  }
1640
- if (!orders.length) {
1641
- throw new Error("At least one order is required.");
1610
+ if (withoutDex.includes("-")) {
1611
+ const [base, ...rest] = withoutDex.split("-");
1612
+ const quote = rest.join("-").trim();
1613
+ if (!base || !quote) return null;
1614
+ return `${canonicalizeHyperliquidTokenCase(base)}/${canonicalizeHyperliquidTokenCase(quote)}`;
1642
1615
  }
1643
- const inferredEnvironment = environment ?? "mainnet";
1644
- const resolvedBaseUrl = API_BASES[inferredEnvironment];
1645
- const preparedOrders = await Promise.all(
1646
- orders.map(async (intent) => {
1647
- assertPositiveDecimalInput(intent.price, "price");
1648
- assertPositiveDecimalInput(intent.size, "size");
1649
- if (intent.trigger) {
1650
- assertPositiveDecimalInput(intent.trigger.triggerPx, "triggerPx");
1651
- }
1652
- const assetIndex = await resolveHyperliquidAssetIndex({
1653
- symbol: intent.symbol,
1654
- baseUrl: resolvedBaseUrl,
1655
- environment: inferredEnvironment,
1656
- fetcher: (...args) => fetch(...args)
1657
- });
1658
- const order = {
1659
- a: assetIndex,
1660
- b: intent.side === "buy",
1661
- p: toApiDecimal(intent.price),
1662
- s: toApiDecimal(intent.size),
1663
- r: intent.reduceOnly ?? false,
1664
- t: intent.trigger ? {
1665
- trigger: {
1666
- isMarket: Boolean(intent.trigger.isMarket),
1667
- triggerPx: toApiDecimal(intent.trigger.triggerPx),
1668
- tpsl: intent.trigger.tpsl
1669
- }
1616
+ return null;
1617
+ }
1618
+ function resolveHyperliquidLeverageMode(symbol) {
1619
+ return symbol.includes(":") ? "isolated" : "cross";
1620
+ }
1621
+ function resolveHyperliquidProfileChain(environment) {
1622
+ return environment === "testnet" ? "hyperliquid-testnet" : "hyperliquid";
1623
+ }
1624
+ function buildHyperliquidProfileAssets(params) {
1625
+ const chain = resolveHyperliquidProfileChain(params.environment);
1626
+ return params.assets.map((asset) => {
1627
+ const symbols = asset.assetSymbols.map((symbol) => normalizeHyperliquidBaseSymbol(symbol)).filter((symbol) => Boolean(symbol));
1628
+ if (symbols.length === 0) return null;
1629
+ const explicitPair = typeof asset.pair === "string" ? resolveHyperliquidPair(asset.pair) : null;
1630
+ const derivedPair = symbols.length === 1 ? resolveHyperliquidPair(asset.assetSymbols[0] ?? symbols[0]) : null;
1631
+ const pair = explicitPair ?? derivedPair ?? void 0;
1632
+ const leverage = typeof asset.leverage === "number" && Number.isFinite(asset.leverage) && asset.leverage > 0 ? asset.leverage : void 0;
1633
+ const walletAddress = typeof asset.walletAddress === "string" && asset.walletAddress.trim().length > 0 ? asset.walletAddress.trim() : void 0;
1634
+ return {
1635
+ venue: "hyperliquid",
1636
+ chain,
1637
+ assetSymbols: symbols,
1638
+ ...pair ? { pair } : {},
1639
+ ...leverage ? { leverage } : {},
1640
+ ...walletAddress ? { walletAddress } : {}
1641
+ };
1642
+ }).filter((asset) => asset !== null);
1643
+ }
1644
+ function parseSpotPairSymbol(symbol) {
1645
+ const trimmed = symbol.trim();
1646
+ if (!trimmed.includes("/")) return null;
1647
+ const [rawBase, rawQuote] = trimmed.split("/");
1648
+ const base = rawBase?.trim().toUpperCase() ?? "";
1649
+ const quote = rawQuote?.trim().toUpperCase() ?? "";
1650
+ if (!base || !quote) return null;
1651
+ return { base, quote };
1652
+ }
1653
+ function isHyperliquidSpotSymbol(symbol) {
1654
+ const trimmed = symbol.trim();
1655
+ if (!trimmed) return false;
1656
+ if (trimmed.startsWith("@") || trimmed.includes("/")) return true;
1657
+ if (trimmed.includes(":")) return false;
1658
+ return resolveHyperliquidPair(trimmed) !== null;
1659
+ }
1660
+ function resolveHyperliquidMarketDataCoin(value) {
1661
+ if (!value) return null;
1662
+ const trimmed = value.trim();
1663
+ if (!trimmed) return null;
1664
+ if (trimmed.startsWith("@")) return trimmed;
1665
+ const pair = resolveHyperliquidPair(trimmed);
1666
+ if (pair && !extractHyperliquidDex(trimmed)) {
1667
+ return pair;
1668
+ }
1669
+ return trimmed;
1670
+ }
1671
+ function supportsHyperliquidBuilderFee(params) {
1672
+ if (!isHyperliquidSpotSymbol(params.symbol)) {
1673
+ return true;
1674
+ }
1675
+ return params.side === "sell";
1676
+ }
1677
+ function resolveSpotMidCandidates(baseSymbol) {
1678
+ const base = baseSymbol.trim().toUpperCase();
1679
+ if (!base) return [];
1680
+ const candidates = [base];
1681
+ if (base.startsWith("U") && base.length > 1) {
1682
+ candidates.push(base.slice(1));
1683
+ }
1684
+ return Array.from(new Set(candidates));
1685
+ }
1686
+ function resolveSpotTokenCandidates(value) {
1687
+ const normalized = normalizeSpotTokenName2(value).toUpperCase();
1688
+ if (!normalized) return [];
1689
+ const candidates = [normalized];
1690
+ if (normalized.startsWith("U") && normalized.length > 1) {
1691
+ candidates.push(normalized.slice(1));
1692
+ }
1693
+ return Array.from(new Set(candidates));
1694
+ }
1695
+ function resolveHyperliquidOrderSymbol(value) {
1696
+ if (!value) return null;
1697
+ const trimmed = value.trim();
1698
+ if (!trimmed) return null;
1699
+ if (trimmed.startsWith("@")) return trimmed;
1700
+ if (trimmed.includes(":")) {
1701
+ const [rawDex, ...restParts] = trimmed.split(":");
1702
+ const dex = rawDex.trim().toLowerCase();
1703
+ const rest = restParts.join(":");
1704
+ const normalizedBase = normalizeHyperliquidBaseSymbol(rest);
1705
+ if (!dex || !normalizedBase || normalizedBase === UNKNOWN_SYMBOL2) {
1706
+ return null;
1707
+ }
1708
+ return `${dex}:${normalizedBase}`;
1709
+ }
1710
+ const pair = resolveHyperliquidPair(trimmed);
1711
+ if (pair) return pair;
1712
+ return normalizeHyperliquidBaseSymbol(trimmed);
1713
+ }
1714
+ function resolveHyperliquidSymbol(asset, override) {
1715
+ const raw = override && override.trim().length > 0 ? override.trim() : asset.trim();
1716
+ if (!raw) return raw;
1717
+ if (raw.startsWith("@")) return raw;
1718
+ if (raw.includes(":")) {
1719
+ const [dexRaw, ...restParts] = raw.split(":");
1720
+ const dex = dexRaw.trim().toLowerCase();
1721
+ const rest = restParts.join(":");
1722
+ const normalizedBase = normalizeHyperliquidBaseSymbol(rest) ?? canonicalizeHyperliquidTokenCase(rest);
1723
+ if (!dex) return normalizedBase;
1724
+ return `${dex}:${normalizedBase}`;
1725
+ }
1726
+ if (raw.includes("/")) {
1727
+ return resolveHyperliquidPair(raw) ?? raw;
1728
+ }
1729
+ if (raw.includes("-")) {
1730
+ return resolveHyperliquidPair(raw) ?? raw;
1731
+ }
1732
+ return normalizeHyperliquidBaseSymbol(raw) ?? canonicalizeHyperliquidTokenCase(raw);
1733
+ }
1734
+ function resolveHyperliquidPerpSymbol(asset) {
1735
+ const raw = asset.trim();
1736
+ if (!raw) return raw;
1737
+ const dex = extractHyperliquidDex(raw);
1738
+ const base = normalizeHyperliquidBaseSymbol(raw) ?? raw.toUpperCase();
1739
+ return dex ? `${dex}:${base}` : base;
1740
+ }
1741
+ function resolveHyperliquidSpotSymbol(asset, defaultQuote = "USDC") {
1742
+ const quote = defaultQuote.trim().toUpperCase() || "USDC";
1743
+ const raw = asset.trim().toUpperCase();
1744
+ if (!raw) {
1745
+ return { symbol: raw, base: raw, quote };
1746
+ }
1747
+ const pair = resolveHyperliquidPair(raw);
1748
+ if (pair) {
1749
+ const [base2, pairQuote] = pair.split("/");
1750
+ return {
1751
+ symbol: pair,
1752
+ base: base2?.trim() ?? raw,
1753
+ quote: pairQuote?.trim() ?? quote
1754
+ };
1755
+ }
1756
+ const base = normalizeHyperliquidBaseSymbol(raw) ?? raw;
1757
+ return { symbol: `${base}/${quote}`, base, quote };
1758
+ }
1759
+
1760
+ // src/adapters/hyperliquid/actions.ts
1761
+ function resolveRequiredNonce(params) {
1762
+ if (typeof params.nonce === "number") {
1763
+ return params.nonce;
1764
+ }
1765
+ const resolved = params.nonceSource?.() ?? params.wallet?.nonceSource?.();
1766
+ if (resolved === void 0) {
1767
+ throw new Error(`${params.action} requires an explicit nonce or wallet nonce source.`);
1768
+ }
1769
+ return resolved;
1770
+ }
1771
+ function assertPositiveDecimalInput(value, label) {
1772
+ if (typeof value === "number") {
1773
+ if (!Number.isFinite(value) || value <= 0) {
1774
+ throw new Error(`${label} must be a positive number.`);
1775
+ }
1776
+ return;
1777
+ }
1778
+ if (typeof value === "bigint") {
1779
+ if (value <= 0n) {
1780
+ throw new Error(`${label} must be positive.`);
1781
+ }
1782
+ return;
1783
+ }
1784
+ const trimmed = value.trim();
1785
+ if (!trimmed.length) {
1786
+ throw new Error(`${label} must be a non-empty string.`);
1787
+ }
1788
+ if (!/^(?:\d+\.?\d*|\.\d+)$/.test(trimmed)) {
1789
+ throw new Error(`${label} must be a positive decimal string.`);
1790
+ }
1791
+ const numeric = Number(trimmed);
1792
+ if (!Number.isFinite(numeric) || numeric <= 0) {
1793
+ throw new Error(`${label} must be positive.`);
1794
+ }
1795
+ }
1796
+ function normalizePositiveDecimalString(raw, label) {
1797
+ const trimmed = raw.trim();
1798
+ if (!trimmed.length) {
1799
+ throw new Error(`${label} must be a non-empty decimal string.`);
1800
+ }
1801
+ if (!/^(?:\d+\.?\d*|\.\d+)$/.test(trimmed)) {
1802
+ throw new Error(`${label} must be a positive decimal string.`);
1803
+ }
1804
+ const normalized = trimmed.replace(/^0+(?=\d)/, "").replace(/(\.\d*?)0+$/, "$1").replace(/\.$/, "");
1805
+ const numeric = Number(normalized);
1806
+ if (!Number.isFinite(numeric) || numeric <= 0) {
1807
+ throw new Error(`${label} must be positive.`);
1808
+ }
1809
+ return normalized;
1810
+ }
1811
+ async function placeHyperliquidOrder(options) {
1812
+ const {
1813
+ wallet,
1814
+ orders,
1815
+ grouping = "na",
1816
+ environment,
1817
+ vaultAddress,
1818
+ expiresAfter,
1819
+ nonce
1820
+ } = options;
1821
+ if (!wallet?.account || !wallet.walletClient) {
1822
+ throw new Error("Hyperliquid order signing requires a wallet with signing capabilities.");
1823
+ }
1824
+ if (!orders.length) {
1825
+ throw new Error("At least one order is required.");
1826
+ }
1827
+ const inferredEnvironment = environment ?? "mainnet";
1828
+ const resolvedBaseUrl = API_BASES[inferredEnvironment];
1829
+ const preparedOrders = await Promise.all(
1830
+ orders.map(async (intent) => {
1831
+ assertPositiveDecimalInput(intent.price, "price");
1832
+ assertPositiveDecimalInput(intent.size, "size");
1833
+ if (intent.trigger) {
1834
+ assertPositiveDecimalInput(intent.trigger.triggerPx, "triggerPx");
1835
+ }
1836
+ const assetIndex = await resolveHyperliquidAssetIndex({
1837
+ symbol: intent.symbol,
1838
+ baseUrl: resolvedBaseUrl,
1839
+ environment: inferredEnvironment,
1840
+ fetcher: (...args) => fetch(...args)
1841
+ });
1842
+ const order = {
1843
+ a: assetIndex,
1844
+ b: intent.side === "buy",
1845
+ p: toApiDecimal(intent.price),
1846
+ s: toApiDecimal(intent.size),
1847
+ r: intent.reduceOnly ?? false,
1848
+ t: intent.trigger ? {
1849
+ trigger: {
1850
+ isMarket: Boolean(intent.trigger.isMarket),
1851
+ triggerPx: toApiDecimal(intent.trigger.triggerPx),
1852
+ tpsl: intent.trigger.tpsl
1853
+ }
1670
1854
  } : {
1671
1855
  limit: {
1672
1856
  tif: intent.tif ?? "Ioc"
@@ -1680,12 +1864,14 @@ async function placeHyperliquidOrder(options) {
1680
1864
  const action = {
1681
1865
  type: "order",
1682
1866
  orders: preparedOrders,
1683
- grouping,
1684
- builder: {
1867
+ grouping
1868
+ };
1869
+ if (orders.every((intent) => supportsHyperliquidBuilderFee(intent))) {
1870
+ action.builder = {
1685
1871
  b: normalizeAddress(BUILDER_CODE.address),
1686
1872
  f: BUILDER_CODE.fee
1687
- }
1688
- };
1873
+ };
1874
+ }
1689
1875
  const effectiveNonce = resolveRequiredNonce({
1690
1876
  nonce,
1691
1877
  nonceSource: options.nonceSource,
@@ -1951,264 +2137,6 @@ async function getHyperliquidMaxBuilderFee(params) {
1951
2137
  function createHyperliquidActionHash(params) {
1952
2138
  return createL1ActionHash(params);
1953
2139
  }
1954
-
1955
- // src/adapters/hyperliquid/symbols.ts
1956
- var UNKNOWN_SYMBOL2 = "UNKNOWN";
1957
- function extractHyperliquidDex(symbol) {
1958
- const idx = symbol.indexOf(":");
1959
- if (idx <= 0) return null;
1960
- const dex = symbol.slice(0, idx).trim().toLowerCase();
1961
- return dex || null;
1962
- }
1963
- function parseHyperliquidSymbol(value) {
1964
- if (!value) return null;
1965
- const trimmed = value.trim();
1966
- if (!trimmed) return null;
1967
- if (trimmed.startsWith("@")) {
1968
- return {
1969
- raw: trimmed,
1970
- kind: "spotIndex",
1971
- normalized: trimmed,
1972
- routeTicker: trimmed,
1973
- displaySymbol: trimmed,
1974
- base: null,
1975
- quote: null,
1976
- pair: null,
1977
- dex: null,
1978
- leverageMode: "cross"
1979
- };
1980
- }
1981
- const dex = extractHyperliquidDex(trimmed);
1982
- const pair = resolveHyperliquidPair(trimmed);
1983
- const base = normalizeHyperliquidBaseSymbol(trimmed);
1984
- if (dex) {
1985
- if (!base) return null;
1986
- return {
1987
- raw: trimmed,
1988
- kind: "perp",
1989
- normalized: `${dex}:${base}`,
1990
- routeTicker: `${dex}:${base}`,
1991
- displaySymbol: `${dex.toUpperCase()}:${base}-USDC`,
1992
- base,
1993
- quote: null,
1994
- pair: null,
1995
- dex,
1996
- leverageMode: "isolated"
1997
- };
1998
- }
1999
- if (pair) {
2000
- const [pairBase, pairQuote] = pair.split("/");
2001
- return {
2002
- raw: trimmed,
2003
- kind: "spot",
2004
- normalized: pair,
2005
- routeTicker: pair.replace("/", "-"),
2006
- displaySymbol: pair.replace("/", "-"),
2007
- base: pairBase ?? null,
2008
- quote: pairQuote ?? null,
2009
- pair,
2010
- dex: null,
2011
- leverageMode: "cross"
2012
- };
2013
- }
2014
- if (!base) return null;
2015
- return {
2016
- raw: trimmed,
2017
- kind: "perp",
2018
- normalized: base,
2019
- routeTicker: base,
2020
- displaySymbol: `${base}-USDC`,
2021
- base,
2022
- quote: null,
2023
- pair: null,
2024
- dex: null,
2025
- leverageMode: "cross"
2026
- };
2027
- }
2028
- function normalizeSpotTokenName2(value) {
2029
- const raw = (value ?? "").trim();
2030
- if (!raw) return "";
2031
- if (raw.endsWith("0") && raw.length > 1) {
2032
- return raw.slice(0, -1);
2033
- }
2034
- return raw;
2035
- }
2036
- function normalizeHyperliquidBaseSymbol(value) {
2037
- if (!value) return null;
2038
- const trimmed = value.trim();
2039
- if (!trimmed) return null;
2040
- const withoutDex = trimmed.includes(":") ? trimmed.split(":").slice(1).join(":") : trimmed;
2041
- const base = withoutDex.split("-")[0] ?? withoutDex;
2042
- const baseNoPair = base.split("/")[0] ?? base;
2043
- const normalized = baseNoPair.trim().toUpperCase();
2044
- if (!normalized || normalized === UNKNOWN_SYMBOL2) return null;
2045
- return normalized;
2046
- }
2047
- function normalizeHyperliquidMetaSymbol(symbol) {
2048
- const trimmed = symbol.trim();
2049
- const noDex = trimmed.includes(":") ? trimmed.split(":").slice(1).join(":") : trimmed;
2050
- const noPair = noDex.split("-")[0] ?? noDex;
2051
- return (noPair.split("/")[0] ?? noPair).trim();
2052
- }
2053
- function resolveHyperliquidPair(value) {
2054
- if (!value) return null;
2055
- const trimmed = value.trim();
2056
- if (!trimmed) return null;
2057
- const withoutDex = trimmed.includes(":") ? trimmed.split(":").slice(1).join(":") : trimmed;
2058
- if (withoutDex.includes("/")) {
2059
- return withoutDex.toUpperCase();
2060
- }
2061
- if (withoutDex.includes("-")) {
2062
- const [base, ...rest] = withoutDex.split("-");
2063
- const quote = rest.join("-").trim();
2064
- if (!base || !quote) return null;
2065
- return `${base.toUpperCase()}/${quote.toUpperCase()}`;
2066
- }
2067
- return null;
2068
- }
2069
- function resolveHyperliquidLeverageMode(symbol) {
2070
- return symbol.includes(":") ? "isolated" : "cross";
2071
- }
2072
- function resolveHyperliquidProfileChain(environment) {
2073
- return environment === "testnet" ? "hyperliquid-testnet" : "hyperliquid";
2074
- }
2075
- function buildHyperliquidProfileAssets(params) {
2076
- const chain = resolveHyperliquidProfileChain(params.environment);
2077
- return params.assets.map((asset) => {
2078
- const symbols = asset.assetSymbols.map((symbol) => normalizeHyperliquidBaseSymbol(symbol)).filter((symbol) => Boolean(symbol));
2079
- if (symbols.length === 0) return null;
2080
- const explicitPair = typeof asset.pair === "string" ? resolveHyperliquidPair(asset.pair) : null;
2081
- const derivedPair = symbols.length === 1 ? resolveHyperliquidPair(asset.assetSymbols[0] ?? symbols[0]) : null;
2082
- const pair = explicitPair ?? derivedPair ?? void 0;
2083
- const leverage = typeof asset.leverage === "number" && Number.isFinite(asset.leverage) && asset.leverage > 0 ? asset.leverage : void 0;
2084
- const walletAddress = typeof asset.walletAddress === "string" && asset.walletAddress.trim().length > 0 ? asset.walletAddress.trim() : void 0;
2085
- return {
2086
- venue: "hyperliquid",
2087
- chain,
2088
- assetSymbols: symbols,
2089
- ...pair ? { pair } : {},
2090
- ...leverage ? { leverage } : {},
2091
- ...walletAddress ? { walletAddress } : {}
2092
- };
2093
- }).filter((asset) => asset !== null);
2094
- }
2095
- function parseSpotPairSymbol(symbol) {
2096
- const trimmed = symbol.trim();
2097
- if (!trimmed.includes("/")) return null;
2098
- const [rawBase, rawQuote] = trimmed.split("/");
2099
- const base = rawBase?.trim().toUpperCase() ?? "";
2100
- const quote = rawQuote?.trim().toUpperCase() ?? "";
2101
- if (!base || !quote) return null;
2102
- return { base, quote };
2103
- }
2104
- function isHyperliquidSpotSymbol(symbol) {
2105
- const trimmed = symbol.trim();
2106
- if (!trimmed) return false;
2107
- if (trimmed.startsWith("@") || trimmed.includes("/")) return true;
2108
- if (trimmed.includes(":")) return false;
2109
- return resolveHyperliquidPair(trimmed) !== null;
2110
- }
2111
- function resolveHyperliquidMarketDataCoin(value) {
2112
- if (!value) return null;
2113
- const trimmed = value.trim();
2114
- if (!trimmed) return null;
2115
- if (trimmed.startsWith("@")) return trimmed;
2116
- const pair = resolveHyperliquidPair(trimmed);
2117
- if (pair && !extractHyperliquidDex(trimmed)) {
2118
- return pair;
2119
- }
2120
- return trimmed;
2121
- }
2122
- function resolveSpotMidCandidates(baseSymbol) {
2123
- const base = baseSymbol.trim().toUpperCase();
2124
- if (!base) return [];
2125
- const candidates = [base];
2126
- if (base.startsWith("U") && base.length > 1) {
2127
- candidates.push(base.slice(1));
2128
- }
2129
- return Array.from(new Set(candidates));
2130
- }
2131
- function resolveSpotTokenCandidates(value) {
2132
- const normalized = normalizeSpotTokenName2(value).toUpperCase();
2133
- if (!normalized) return [];
2134
- const candidates = [normalized];
2135
- if (normalized.startsWith("U") && normalized.length > 1) {
2136
- candidates.push(normalized.slice(1));
2137
- }
2138
- return Array.from(new Set(candidates));
2139
- }
2140
- function resolveHyperliquidOrderSymbol(value) {
2141
- if (!value) return null;
2142
- const trimmed = value.trim();
2143
- if (!trimmed) return null;
2144
- if (trimmed.startsWith("@")) return trimmed;
2145
- if (trimmed.includes(":")) {
2146
- const [rawDex, ...restParts] = trimmed.split(":");
2147
- const dex = rawDex.trim().toLowerCase();
2148
- const rest = restParts.join(":");
2149
- const base = rest.split("/")[0]?.split("-")[0] ?? rest;
2150
- const normalizedBase = base.trim().toUpperCase();
2151
- if (!dex || !normalizedBase || normalizedBase === UNKNOWN_SYMBOL2) {
2152
- return null;
2153
- }
2154
- return `${dex}:${normalizedBase}`;
2155
- }
2156
- const pair = resolveHyperliquidPair(trimmed);
2157
- if (pair) return pair;
2158
- return normalizeHyperliquidBaseSymbol(trimmed);
2159
- }
2160
- function resolveHyperliquidSymbol(asset, override) {
2161
- const raw = override && override.trim().length > 0 ? override.trim() : asset.trim();
2162
- if (!raw) return raw;
2163
- if (raw.startsWith("@")) return raw;
2164
- if (raw.includes(":")) {
2165
- const [dexRaw, ...restParts] = raw.split(":");
2166
- const dex = dexRaw.trim().toLowerCase();
2167
- const rest = restParts.join(":");
2168
- const base2 = rest.split("/")[0]?.split("-")[0] ?? rest;
2169
- const normalizedBase = base2.trim().toUpperCase();
2170
- if (!dex) return normalizedBase;
2171
- return `${dex}:${normalizedBase}`;
2172
- }
2173
- if (raw.includes("/")) {
2174
- return raw.toUpperCase();
2175
- }
2176
- if (raw.includes("-")) {
2177
- const [base2, ...rest] = raw.split("-");
2178
- const quote = rest.join("-").trim();
2179
- if (base2 && quote) {
2180
- return `${base2.toUpperCase()}/${quote.toUpperCase()}`;
2181
- }
2182
- }
2183
- const base = raw.split("-")[0] ?? raw;
2184
- const baseNoPair = base.split("/")[0] ?? base;
2185
- return baseNoPair.trim().toUpperCase();
2186
- }
2187
- function resolveHyperliquidPerpSymbol(asset) {
2188
- const raw = asset.trim();
2189
- if (!raw) return raw;
2190
- const dex = extractHyperliquidDex(raw);
2191
- const base = normalizeHyperliquidBaseSymbol(raw) ?? raw.toUpperCase();
2192
- return dex ? `${dex}:${base}` : base;
2193
- }
2194
- function resolveHyperliquidSpotSymbol(asset, defaultQuote = "USDC") {
2195
- const quote = defaultQuote.trim().toUpperCase() || "USDC";
2196
- const raw = asset.trim().toUpperCase();
2197
- if (!raw) {
2198
- return { symbol: raw, base: raw, quote };
2199
- }
2200
- const pair = resolveHyperliquidPair(raw);
2201
- if (pair) {
2202
- const [base2, pairQuote] = pair.split("/");
2203
- return {
2204
- symbol: pair,
2205
- base: base2?.trim() ?? raw,
2206
- quote: pairQuote?.trim() ?? quote
2207
- };
2208
- }
2209
- const base = normalizeHyperliquidBaseSymbol(raw) ?? raw;
2210
- return { symbol: `${base}/${quote}`, base, quote };
2211
- }
2212
2140
  function gcd(a, b) {
2213
2141
  let left = a < 0n ? -a : a;
2214
2142
  let right = b < 0n ? -b : b;
@@ -2773,6 +2701,6 @@ function estimateHyperliquidLiquidationPrice(params) {
2773
2701
  return liquidationPrice;
2774
2702
  }
2775
2703
 
2776
- export { DEFAULT_HYPERLIQUID_MARKET_SLIPPAGE_BPS, DEFAULT_HYPERLIQUID_TPSL_MARKET_SLIPPAGE_BPS, HyperliquidApiError, HyperliquidBuilderApprovalError, HyperliquidExchangeClient, HyperliquidGuardError, HyperliquidInfoClient, HyperliquidTermsError, approveHyperliquidBuilderFee, batchModifyHyperliquidOrders, buildHyperliquidMarketIdentity, buildHyperliquidProfileAssets, cancelAllHyperliquidOrders, cancelHyperliquidOrders, cancelHyperliquidOrdersByCloid, cancelHyperliquidTwapOrder, computeHyperliquidMarketIocLimitPrice, createHyperliquidActionHash, createHyperliquidSubAccount, createMonotonicNonceFactory, depositToHyperliquidBridge, estimateHyperliquidLiquidationPrice, extractHyperliquidDex, fetchHyperliquidAssetCtxs, fetchHyperliquidClearinghouseState, fetchHyperliquidFrontendOpenOrders, fetchHyperliquidHistoricalOrders, fetchHyperliquidMeta, fetchHyperliquidMetaAndAssetCtxs, fetchHyperliquidOpenOrders, fetchHyperliquidOrderStatus, fetchHyperliquidPreTransferCheck, fetchHyperliquidSizeDecimals, fetchHyperliquidSpotAssetCtxs, fetchHyperliquidSpotClearinghouseState, fetchHyperliquidSpotMeta, fetchHyperliquidSpotMetaAndAssetCtxs, fetchHyperliquidTickSize, fetchHyperliquidUserFills, fetchHyperliquidUserFillsByTime, fetchHyperliquidUserRateLimit, formatHyperliquidMarketablePrice, formatHyperliquidPrice, formatHyperliquidSize, getHyperliquidMaxBuilderFee, isHyperliquidSpotSymbol, modifyHyperliquidOrder, normalizeHyperliquidBaseSymbol, normalizeHyperliquidMetaSymbol, normalizeSpotTokenName2 as normalizeSpotTokenName, parseHyperliquidSymbol, parseSpotPairSymbol, placeHyperliquidOrder, placeHyperliquidOrderWithTpSl, placeHyperliquidPositionTpSl, placeHyperliquidTwapOrder, reserveHyperliquidRequestWeight, resolveHyperliquidAbstractionFromMode, resolveHyperliquidLeverageMode, resolveHyperliquidMarketDataCoin, resolveHyperliquidOrderSymbol, resolveHyperliquidPair, resolveHyperliquidPerpSymbol, resolveHyperliquidProfileChain, resolveHyperliquidSpotSymbol, resolveHyperliquidSymbol, resolveSpotMidCandidates, resolveSpotTokenCandidates, scheduleHyperliquidCancel, sendHyperliquidSpot, setHyperliquidAccountAbstractionMode, setHyperliquidDexAbstraction, setHyperliquidPortfolioMargin, transferHyperliquidSubAccount, updateHyperliquidIsolatedMargin, updateHyperliquidLeverage, withdrawFromHyperliquid };
2704
+ export { DEFAULT_HYPERLIQUID_MARKET_SLIPPAGE_BPS, DEFAULT_HYPERLIQUID_TPSL_MARKET_SLIPPAGE_BPS, HyperliquidApiError, HyperliquidBuilderApprovalError, HyperliquidExchangeClient, HyperliquidGuardError, HyperliquidInfoClient, HyperliquidTermsError, approveHyperliquidBuilderFee, batchModifyHyperliquidOrders, buildHyperliquidMarketIdentity, buildHyperliquidProfileAssets, cancelAllHyperliquidOrders, cancelHyperliquidOrders, cancelHyperliquidOrdersByCloid, cancelHyperliquidTwapOrder, computeHyperliquidMarketIocLimitPrice, createHyperliquidActionHash, createHyperliquidSubAccount, createMonotonicNonceFactory, depositToHyperliquidBridge, estimateHyperliquidLiquidationPrice, extractHyperliquidDex, fetchHyperliquidAssetCtxs, fetchHyperliquidClearinghouseState, fetchHyperliquidFrontendOpenOrders, fetchHyperliquidHistoricalOrders, fetchHyperliquidMeta, fetchHyperliquidMetaAndAssetCtxs, fetchHyperliquidOpenOrders, fetchHyperliquidOrderStatus, fetchHyperliquidPreTransferCheck, fetchHyperliquidSizeDecimals, fetchHyperliquidSpotAssetCtxs, fetchHyperliquidSpotClearinghouseState, fetchHyperliquidSpotMeta, fetchHyperliquidSpotMetaAndAssetCtxs, fetchHyperliquidTickSize, fetchHyperliquidUserFills, fetchHyperliquidUserFillsByTime, fetchHyperliquidUserRateLimit, formatHyperliquidMarketablePrice, formatHyperliquidPrice, formatHyperliquidSize, getHyperliquidMaxBuilderFee, isHyperliquidSpotSymbol, modifyHyperliquidOrder, normalizeHyperliquidBaseSymbol, normalizeHyperliquidMetaSymbol, normalizeSpotTokenName2 as normalizeSpotTokenName, parseHyperliquidSymbol, parseSpotPairSymbol, placeHyperliquidOrder, placeHyperliquidOrderWithTpSl, placeHyperliquidPositionTpSl, placeHyperliquidTwapOrder, reserveHyperliquidRequestWeight, resolveHyperliquidAbstractionFromMode, resolveHyperliquidLeverageMode, resolveHyperliquidMarketDataCoin, resolveHyperliquidOrderSymbol, resolveHyperliquidPair, resolveHyperliquidPerpSymbol, resolveHyperliquidProfileChain, resolveHyperliquidSpotSymbol, resolveHyperliquidSymbol, resolveSpotMidCandidates, resolveSpotTokenCandidates, scheduleHyperliquidCancel, sendHyperliquidSpot, setHyperliquidAccountAbstractionMode, setHyperliquidPortfolioMargin, supportsHyperliquidBuilderFee, transferHyperliquidSubAccount, updateHyperliquidIsolatedMargin, updateHyperliquidLeverage, withdrawFromHyperliquid };
2777
2705
  //# sourceMappingURL=browser.js.map
2778
2706
  //# sourceMappingURL=browser.js.map