@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
package/dist/index.d.ts CHANGED
@@ -1,9 +1,10 @@
1
- export { C as ChainCategory, a as ChainSupportContext, E as EvmTokenKind, K as KeyGenSubset, b as KeyGenSubsetForPermit, M as MultisignBuildResult, c as MultisignCommonArgs, N as NearTokenKind, P as ParamDoc, d as ProtocolActionDescriptor, e as ProtocolModule, S as SolanaTokenKind, T as TokenRef } from './types-BfjWdw1j.js';
1
+ export { C as ChainCategory, a as ChainSupportContext, E as EvmTokenKind, K as KeyGenSubset, b as KeyGenSubsetForPermit, M as MultisignBuildResult, c as MultisignCommonArgs, N as NearTokenKind, P as ParamDoc, d as ProtocolActionDescriptor, e as ProtocolModule, S as SolanaTokenKind, T as TokenRef } from './types-PZrvtjv8.js';
2
2
  export { getClientIdFromKeyGenResult as firstClientIdFromKeyGen } from '@continuumdao/continuum-node-sdk';
3
- export { BuildEip712MultisignBodyArgs, EIP712_SIGN_REQUEST_KIND, Eip712MultisignDelivery, Eip712TypedDataField, Eip712TypedDataPayload, buildEip712MultisignBody, getAaveGraphqlProxyUrl, getCoingeckoProxyUrl, getEulerGraphqlProxyUrl, getMapleGraphqlProxyUrl, getMorphoGraphqlProxyUrl, mergePurposeText, postJsonViaOptionalProxy, setAaveGraphqlProxyUrl, setCoingeckoProxyUrl, setEulerGraphqlProxyUrl, setMapleGraphqlProxyUrl, setMorphoGraphqlProxyUrl } from './core/index.js';
4
- export { C as ChainCategoryBuildInput, a as ChainCategoryModule, M as MultisignLeg, c as coreChainCategoryModule, f as finalizeMultisign } from './envelope-CpBUh9eP.js';
5
- export { g as getActionsByChainCategory, a as getProtocolModule, b as getProtocolModules, r as registerProtocolModule } from './registry-Bv5o37_w.js';
6
- export { E as EvmChainDetail, a as EvmProtocolContext, b as EvmTxStep, i as isEvmNativeToken, m as matchEvmTokenKind } from './types-DUeNJLr9.js';
3
+ export { DEFAULT_DEFI_MULTISIGN_EXPIRY_SECONDS, DEFI_PROTOCOLS_WITH_30MIN_EXPIRY, defiMultisignExpiryUnixSeconds, getAaveGraphqlProxyUrl, getCoingeckoProxyUrl, getEulerGraphqlProxyUrl, getMapleGraphqlProxyUrl, getMorphoGraphqlProxyUrl, mergePurposeText, postJsonViaOptionalProxy, setAaveGraphqlProxyUrl, setCoingeckoProxyUrl, setEulerGraphqlProxyUrl, setMapleGraphqlProxyUrl, setMorphoGraphqlProxyUrl } from './core/index.js';
4
+ export { C as ChainCategoryBuildInput, a as ChainCategoryModule, M as MultisignLeg, c as coreChainCategoryModule, f as finalizeMultisign } from './envelope-C_bfuKab.js';
5
+ export { g as getActionsByChainCategory, a as getProtocolModule, b as getProtocolModules, r as registerProtocolModule } from './registry-DxDSPQ-p.js';
6
+ export { B as BuildEip712MultisignBodyArgs, E as EIP712_SIGN_REQUEST_KIND, a as Eip712MultisignDelivery, b as Eip712TypedDataField, c as Eip712TypedDataPayload, d as buildEip712MultisignBody } from './eip712Multisign-xhXpUYp3.js';
7
+ export { E as EvmChainDetail, a as EvmProtocolContext, b as EvmTxStep, i as isEvmNativeToken, m as matchEvmTokenKind } from './types-RZWOTm8c.js';
7
8
  export { COINGECKO_PLATFORM_BY_CHAIN_ID, ConditionalApproveStep, EvmBatchMetaBuilder, EvmBuildBatchArgs, approveStepsToEvmTxSteps, buildConditionalErc20ApproveSteps, buildEvmMultisignBatch, coingeckoPlatformForChainId, evmChainCategoryModule, normalizeCurveRouterAmountString, normalizeHumanDecimalAmount, parseEvmChainIdToNumber, publicClientForRpc, resolveErc20Decimals, routerSwapGasLimitFromEstimate } from './chains/evm/index.js';
8
9
  export { SOLANA_CHAIN_CATEGORY, solanaChainCategoryModule } from './chains/solana/index.js';
9
10
  export { NEAR_CHAIN_CATEGORY, nearChainCategoryModule } from './chains/near/index.js';
package/dist/index.js CHANGED
@@ -60,6 +60,9 @@ function finalizeMultisign(input) {
60
60
  bodyForSign.value = valueWei.toString();
61
61
  }
62
62
  if (clientId) bodyForSign.clientId = clientId;
63
+ if (input.expiryDate != null && input.expiryDate > 0) {
64
+ bodyForSign.expiryDate = Math.floor(input.expiryDate);
65
+ }
63
66
  return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) };
64
67
  }
65
68
  var coreChainCategoryModule = {
@@ -197,6 +200,7 @@ function buildEip712MultisignBody(args) {
197
200
  destinationChainID: args.destinationChainID,
198
201
  destinationAddress: args.destinationAddress,
199
202
  extraJSON,
203
+ expiryDate: args.expiryDate,
200
204
  legs: [
201
205
  {
202
206
  msgHash: msgHashNo0x(digest),
@@ -214,6 +218,24 @@ function buildEip712MultisignBody(args) {
214
218
  ]
215
219
  });
216
220
  }
221
+
222
+ // src/core/expiry.ts
223
+ var DEFAULT_DEFI_MULTISIGN_EXPIRY_SECONDS = 30 * 60;
224
+ var DEFI_PROTOCOLS_WITH_30MIN_EXPIRY = /* @__PURE__ */ new Set([
225
+ "uniswap-v4",
226
+ "gmx",
227
+ "hyperliquid",
228
+ "curve-dao"
229
+ ]);
230
+ function defiMultisignExpiryUnixSeconds(protocolId, explicitExpiryDate) {
231
+ if (typeof explicitExpiryDate === "number" && Number.isFinite(explicitExpiryDate) && explicitExpiryDate > 0) {
232
+ return Math.floor(explicitExpiryDate);
233
+ }
234
+ if (protocolId && DEFI_PROTOCOLS_WITH_30MIN_EXPIRY.has(protocolId)) {
235
+ return Math.floor(Date.now() / 1e3) + DEFAULT_DEFI_MULTISIGN_EXPIRY_SECONDS;
236
+ }
237
+ return void 0;
238
+ }
217
239
  function isEvmNativeToken(address) {
218
240
  try {
219
241
  return getAddress(address) === zeroAddress;
@@ -389,7 +411,8 @@ async function buildEvmMultisignBatch(args) {
389
411
  destinationChainID: String(chainId),
390
412
  destinationAddress: args.destinationAddress ?? steps[0].to,
391
413
  legs,
392
- extraJSON: Object.keys(extraJSON).length > 0 ? extraJSON : void 0
414
+ extraJSON: Object.keys(extraJSON).length > 0 ? extraJSON : void 0,
415
+ expiryDate: context.expiryDate
393
416
  });
394
417
  const pv = args.payableValueWei;
395
418
  if (pv != null && pv > 0n) {
@@ -592,8 +615,18 @@ var UNIVERSAL_ROUTER_SPENDER = {
592
615
  143: "0x0d97dc33264bfc1c226207428a79b26757fb9dc3",
593
616
  59144: "0x661e93cca42afacb172121ef892830ca3b70f08d",
594
617
  4217: "0x1febb76be10aaf3a1402f04e8e835f2c382f7914",
595
- 196: "0x5507749f2c558bb3e162c6e90c314c092e7372ff"
618
+ 196: "0x5507749f2c558bb3e162c6e90c314c092e7372ff",
619
+ /** Robinhood Chain mainnet — Universal Router v2.1.1 (Trade API / interface) */
620
+ 4663: "0x8876789976decbfcbbbe364623c63652db8c0904"
621
+ };
622
+ var UNIVERSAL_ROUTER_VERSION_BY_CHAIN = {
623
+ /** Robinhood has UR 2.1.1 only in the supported-chains table (no 2.0 Trade API column). */
624
+ 4663: "2.1.1"
596
625
  };
626
+ function getUniswapUniversalRouterVersion(chainId) {
627
+ const v = UNIVERSAL_ROUTER_VERSION_BY_CHAIN[chainId];
628
+ return typeof v === "string" && v.trim() ? v.trim() : UNISWAP_UNIVERSAL_ROUTER_VERSION_DEFAULT;
629
+ }
597
630
  function isUniswapV4ChainSupported(chainId) {
598
631
  if (chainId == null) return false;
599
632
  const n = parseEvmChainIdToNumber(chainId);
@@ -628,7 +661,9 @@ var POSITION_MANAGER_BY_CHAIN = {
628
661
  11155111: "0x4B2C77d209D3405F41a037Ec6c77F7F5b8e2ca80",
629
662
  130: "0x0d97dc33264bfc1c226207428a79b26757fb9dc3",
630
663
  1868: "0x0e2850543f69f678257266e0907ff9a58b3f13de",
631
- 59144: "0x661e93cca42afacb172121ef892830ca3b70f08d"
664
+ 59144: "0x661e93cca42afacb172121ef892830ca3b70f08d",
665
+ /** Robinhood Chain mainnet */
666
+ 4663: "0x58daec3116aae6D93017bAAea7749052E8a04fA7"
632
667
  };
633
668
  function getUniswapV4PositionManagerOrThrow(chainId) {
634
669
  const raw = POSITION_MANAGER_BY_CHAIN[chainId];
@@ -675,8 +710,8 @@ function parseUniswapChainId(value) {
675
710
  function trimAddr(a) {
676
711
  return a.trim();
677
712
  }
678
- function isUniswapTokenInAddressNative(tokenIn) {
679
- const t = (tokenIn ?? "").toString().trim();
713
+ function isUniswapNativeTokenAddress(token) {
714
+ const t = (token ?? "").toString().trim();
680
715
  if (!t) return false;
681
716
  try {
682
717
  return getAddress(t) === zeroAddress;
@@ -691,7 +726,16 @@ function isUniswapFullQuoteResponseNativeIn(stored) {
691
726
  const input = q.input;
692
727
  if (!input) return false;
693
728
  const raw = (input.address ?? input.token ?? "").toString().trim();
694
- return isUniswapTokenInAddressNative(raw);
729
+ return isUniswapNativeTokenAddress(raw);
730
+ }
731
+ function isUniswapFullQuoteResponseNativeOut(stored) {
732
+ if (!stored) return false;
733
+ const q = stored.quote;
734
+ if (!q || typeof q !== "object" || Array.isArray(q)) return false;
735
+ const output = q.output;
736
+ if (!output) return false;
737
+ const raw = (output.address ?? output.token ?? "").toString().trim();
738
+ return isUniswapNativeTokenAddress(raw);
695
739
  }
696
740
  async function fetchEthereumAddressForKeyGen(managementNodeUrl, keyGenId, readAuth = { bearerOnGet: true, jwt: null }, init) {
697
741
  const base = managementNodeUrl.trim().replace(/\/$/, "");
@@ -753,6 +797,31 @@ function buildUniswapQuoteRequestBody(args) {
753
797
  }
754
798
  return body;
755
799
  }
800
+ function resolveChainIdFromStoredUniswapQuote(stored) {
801
+ if (!stored) return 0;
802
+ const top = stored;
803
+ for (const key of ["tokenInChainId", "chainId"]) {
804
+ const raw = top[key];
805
+ if (raw != null && String(raw).trim() !== "") {
806
+ try {
807
+ return parseUniswapChainId(raw);
808
+ } catch {
809
+ }
810
+ }
811
+ }
812
+ const q = top.quote;
813
+ if (q && typeof q === "object" && !Array.isArray(q)) {
814
+ const input = q.input;
815
+ const chain = input?.chainId;
816
+ if (chain != null && String(chain).trim() !== "") {
817
+ try {
818
+ return parseUniswapChainId(chain);
819
+ } catch {
820
+ }
821
+ }
822
+ }
823
+ return 0;
824
+ }
756
825
  function errorMessageFromUniswapJsonBody(value) {
757
826
  if (value == null) return null;
758
827
  if (typeof value === "string") {
@@ -865,16 +934,18 @@ async function uniswapTradeQuote(args) {
865
934
  }
866
935
  const base = args.baseUrl && args.baseUrl.trim() ? args.baseUrl.trim().replace(/\/$/, "") : DEFAULT_TRADE_BASE;
867
936
  const quoteUrl = `${base}/quote`;
868
- const urv = args.universalRouterVersion && args.universalRouterVersion.trim() || "2.0";
937
+ const chainIdForRouter = parseUniswapChainId(resolveInputChainId(args));
938
+ const urv = args.universalRouterVersion && args.universalRouterVersion.trim() || getUniswapUniversalRouterVersion(chainIdForRouter);
869
939
  const body = buildUniswapQuoteRequestBody({ ...args, swapper });
870
- const nativeIn = isUniswapTokenInAddressNative(args.tokenIn);
940
+ const nativeIn = isUniswapNativeTokenAddress(args.tokenIn);
941
+ const nativeOut = isUniswapNativeTokenAddress(args.tokenOut);
871
942
  const headers = {
872
943
  ...UNISWAP_QUOTE_HEADERS_BASE,
873
944
  "x-api-key": apiKey,
874
945
  "x-universal-router-version": urv,
875
946
  "x-permit2-disabled": args.permit2Disabled === true ? "true" : "false",
876
- /** Native (0x0) as token in: Trade API needs this for classic routes and payable /swap. */
877
- "x-erc20eth-enabled": nativeIn ? "true" : "false"
947
+ /** Native (0x0) in or out: enables ERC20↔ETH routes (incl. UniswapX on Robinhood). */
948
+ "x-erc20eth-enabled": nativeIn || nativeOut ? "true" : "false"
878
949
  };
879
950
  const fetchFn = args.fetchImpl ?? globalThis.fetch;
880
951
  const res = await fetchFn(quoteUrl, {
@@ -885,7 +956,11 @@ async function uniswapTradeQuote(args) {
885
956
  });
886
957
  const text = await res.text();
887
958
  if (!res.ok) {
888
- throw new Error(messageFromUniswapHttpResponseBody(text, res.status, res.statusText));
959
+ let msg = messageFromUniswapHttpResponseBody(text, res.status, res.statusText);
960
+ if (res.status === 404 && chainIdForRouter === 4663) {
961
+ msg += " On Robinhood Chain, confirm USDG is 0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168, use Native ETH or WETH (0x0Bd7\u2026) as output, and try at least ~$300 notional (UniswapX minimum).";
962
+ }
963
+ throw new Error(msg);
889
964
  }
890
965
  const forParse = text.replace(/^\uFEFF/, "");
891
966
  try {
@@ -992,16 +1067,17 @@ async function uniswapCreateSwap(args) {
992
1067
  quote: classic,
993
1068
  deadline
994
1069
  };
995
- const urv = (args.universalRouterVersion ?? UNISWAP_UNIVERSAL_ROUTER_VERSION_DEFAULT).trim() || "2.0";
1070
+ const urv = (args.universalRouterVersion ?? "").trim() || getUniswapUniversalRouterVersion(resolveChainIdFromStoredUniswapQuote(args.fullQuoteFromPermit));
996
1071
  const fn = args.fetchImpl ?? globalThis.fetch;
997
1072
  const nativeIn = isUniswapFullQuoteResponseNativeIn(args.fullQuoteFromPermit);
1073
+ const nativeOut = isUniswapFullQuoteResponseNativeOut(args.fullQuoteFromPermit);
998
1074
  const res = await fn(url, {
999
1075
  method: "POST",
1000
1076
  headers: {
1001
1077
  "Content-Type": "application/json",
1002
1078
  "x-api-key": args.uniswapApiKey.trim(),
1003
1079
  "x-universal-router-version": urv,
1004
- "x-erc20eth-enabled": nativeIn ? "true" : "false",
1080
+ "x-erc20eth-enabled": nativeIn || nativeOut ? "true" : "false",
1005
1081
  "x-permit2-disabled": "true"
1006
1082
  },
1007
1083
  body: JSON.stringify(body)
@@ -2201,6 +2277,270 @@ async function swapExactInput(args) {
2201
2277
  return swapFromQuote({ ...args, swap });
2202
2278
  }
2203
2279
 
2280
+ // src/protocols/evm/uniswap-v4/limitOrder.ts
2281
+ function trimAddr3(a) {
2282
+ return a.trim();
2283
+ }
2284
+ var UNISWAP_LIMIT_ORDER_CHAIN_ID = 1;
2285
+ var DEFAULT_UNISWAPX_ORDER_BASE = "https://api.uniswap.org/v2";
2286
+ var DEFAULT_LIMIT_ORDER_QUOTE_PATH = "/limit_order_quote";
2287
+ var UNISWAP_QUOTE_HEADERS_BASE2 = {
2288
+ "Content-Type": "application/json",
2289
+ "User-Agent": "ctm-mpc-defi uniswapLimitOrderQuote/1.0 (TS)"
2290
+ };
2291
+ function isUniswapLimitOrderChainSupported(chainId) {
2292
+ return parseUniswapChainId(chainId) === UNISWAP_LIMIT_ORDER_CHAIN_ID;
2293
+ }
2294
+ function assertUniswapLimitOrderChain(chainId) {
2295
+ if (!isUniswapLimitOrderChainSupported(chainId)) {
2296
+ throw new Error(
2297
+ `UniswapX limit orders are only supported on Ethereum mainnet (chainId ${UNISWAP_LIMIT_ORDER_CHAIN_ID}). Got ${chainId}. Use market swap on this chain or wait for UniswapX limit support.`
2298
+ );
2299
+ }
2300
+ }
2301
+ function inferPrimaryTypeFromPermitTypes(types) {
2302
+ for (const key of Object.keys(types)) {
2303
+ if (key !== "EIP712Domain") {
2304
+ return key;
2305
+ }
2306
+ }
2307
+ throw new Error("permitData.types missing primaryType (no non-EIP712Domain entry)");
2308
+ }
2309
+ function permitDataToEip712Payload(permitData) {
2310
+ const domain = permitData.domain;
2311
+ const types = permitData.types;
2312
+ const message = permitData.values ?? permitData.message;
2313
+ if (domain == null || typeof domain !== "object" || Array.isArray(domain)) {
2314
+ throw new Error("limit order quote: permitData.domain missing");
2315
+ }
2316
+ if (types == null || typeof types !== "object" || Array.isArray(types)) {
2317
+ throw new Error("limit order quote: permitData.types missing");
2318
+ }
2319
+ if (message == null || typeof message !== "object" || Array.isArray(message)) {
2320
+ throw new Error("limit order quote: permitData.values (message) missing");
2321
+ }
2322
+ const primaryType = typeof permitData.primaryType === "string" && permitData.primaryType.trim() ? permitData.primaryType.trim() : inferPrimaryTypeFromPermitTypes(
2323
+ types
2324
+ );
2325
+ return {
2326
+ domain,
2327
+ types,
2328
+ primaryType,
2329
+ message
2330
+ };
2331
+ }
2332
+ function extractPermitDataFromLimitQuote(quoteResponse) {
2333
+ const permitData = quoteResponse.permitData;
2334
+ if (permitData == null) return null;
2335
+ if (typeof permitData !== "object" || Array.isArray(permitData)) {
2336
+ throw new Error("limit order quote: permitData is not an object");
2337
+ }
2338
+ return permitData;
2339
+ }
2340
+ function buildLimitOrderQuoteRequestBody(args) {
2341
+ const base = buildUniswapQuoteRequestBody({
2342
+ type: args.type,
2343
+ amount: args.amount,
2344
+ tokenIn: args.tokenIn,
2345
+ tokenOut: args.tokenOut,
2346
+ chainId: args.chainId,
2347
+ tokenInChainId: args.tokenInChainId,
2348
+ tokenOutChainId: args.tokenOutChainId,
2349
+ swapper: args.swapper
2350
+ });
2351
+ assertUniswapLimitOrderChain(base.tokenInChainId);
2352
+ return {
2353
+ ...base,
2354
+ limitPrice: String(args.limitPrice).trim(),
2355
+ orderDeadline: args.orderDeadline
2356
+ };
2357
+ }
2358
+ async function uniswapLimitOrderQuote(args) {
2359
+ const apiKey = (args.uniswapApiKey || "").trim();
2360
+ if (!apiKey) {
2361
+ throw new Error("uniswapApiKey (x-api-key) is required");
2362
+ }
2363
+ let swapper;
2364
+ if ((args.swapper || "").trim()) {
2365
+ swapper = trimAddr3(args.swapper);
2366
+ } else {
2367
+ const keyGen = (args.keyGen || "").trim();
2368
+ if (!keyGen) {
2369
+ throw new Error("keyGen is required when swapper is not provided");
2370
+ }
2371
+ const mpc = (args.managementNodeUrl || "").trim();
2372
+ if (!mpc) {
2373
+ throw new Error("managementNodeUrl is required when swapper is not provided (to resolve keyGen)");
2374
+ }
2375
+ swapper = await fetchEthereumAddressForKeyGen(
2376
+ mpc,
2377
+ keyGen,
2378
+ args.nodeReadAuth ?? { bearerOnGet: true, jwt: null }
2379
+ );
2380
+ }
2381
+ const chainIdForGuard = parseUniswapChainId(resolveInputChainId(args));
2382
+ assertUniswapLimitOrderChain(chainIdForGuard);
2383
+ const base = args.baseUrl && args.baseUrl.trim() ? args.baseUrl.trim().replace(/\/$/, "") : "https://trade-api.gateway.uniswap.org/v1";
2384
+ const quoteUrl = `${base}${DEFAULT_LIMIT_ORDER_QUOTE_PATH}`;
2385
+ const body = buildLimitOrderQuoteRequestBody({ ...args, swapper });
2386
+ const headers = {
2387
+ ...UNISWAP_QUOTE_HEADERS_BASE2,
2388
+ "x-api-key": apiKey
2389
+ };
2390
+ const fetchFn = args.fetchImpl ?? globalThis.fetch;
2391
+ const res = await fetchFn(quoteUrl, {
2392
+ method: "POST",
2393
+ headers,
2394
+ body: JSON.stringify(body),
2395
+ signal: args.signal
2396
+ });
2397
+ const text = await res.text();
2398
+ if (!res.ok) {
2399
+ throw new Error(messageFromUniswapHttpResponseBody(text, res.status, res.statusText));
2400
+ }
2401
+ const forParse = text.replace(/^\uFEFF/, "");
2402
+ try {
2403
+ return JSON.parse(forParse);
2404
+ } catch {
2405
+ throw new Error(
2406
+ `Limit order quote: ${messageFromUniswapHttpResponseBody(text, res.status, res.statusText)}`
2407
+ );
2408
+ }
2409
+ }
2410
+ function buildUniswapXLimitOrderSubmitBody(args) {
2411
+ const quote = args.quoteResponse.quote;
2412
+ if (quote == null || typeof quote !== "object" || Array.isArray(quote)) {
2413
+ throw new Error("limit order submit: quoteResponse.quote missing");
2414
+ }
2415
+ const routing = typeof args.quoteResponse.routing === "string" && args.quoteResponse.routing.trim() ? args.quoteResponse.routing.trim() : "LIMIT_ORDER";
2416
+ const chainId = args.quoteResponse.chainId ?? quote.chainId ?? UNISWAP_LIMIT_ORDER_CHAIN_ID;
2417
+ const quoteId = typeof args.quoteResponse.quoteId === "string" ? args.quoteResponse.quoteId : void 0;
2418
+ const requestId = typeof args.quoteResponse.requestId === "string" ? args.quoteResponse.requestId : void 0;
2419
+ return {
2420
+ signature: args.signatureHex.startsWith("0x") ? args.signatureHex : `0x${args.signatureHex}`,
2421
+ quote,
2422
+ chainId: parseUniswapChainId(chainId),
2423
+ orderType: "Limit",
2424
+ routing,
2425
+ ...quoteId ? { quoteId } : {},
2426
+ ...requestId ? { requestId } : {}
2427
+ };
2428
+ }
2429
+ async function fetchUniswapXLimitOrders(args) {
2430
+ const chainId = args.chainId ?? UNISWAP_LIMIT_ORDER_CHAIN_ID;
2431
+ assertUniswapLimitOrderChain(chainId);
2432
+ const base = args.baseUrl && args.baseUrl.trim() ? args.baseUrl.trim().replace(/\/$/, "") : DEFAULT_UNISWAPX_ORDER_BASE;
2433
+ const params = new URLSearchParams({
2434
+ chainId: String(chainId),
2435
+ swapper: trimAddr3(args.swapper)
2436
+ });
2437
+ if (args.limit != null && args.limit > 0) {
2438
+ params.set("limit", String(Math.floor(args.limit)));
2439
+ }
2440
+ const url = `${base}/limit-orders?${params.toString()}`;
2441
+ const headers = {
2442
+ Accept: "application/json",
2443
+ "User-Agent": "ctm-mpc-defi uniswapLimitOrdersList/1.0 (TS)"
2444
+ };
2445
+ const apiKey = (args.uniswapApiKey || "").trim();
2446
+ if (apiKey) {
2447
+ headers["x-api-key"] = apiKey;
2448
+ }
2449
+ const fetchFn = args.fetchImpl ?? globalThis.fetch;
2450
+ const res = await fetchFn(url, { method: "GET", headers });
2451
+ const text = await res.text();
2452
+ if (!res.ok) {
2453
+ const parsed = (() => {
2454
+ try {
2455
+ return JSON.parse(text);
2456
+ } catch {
2457
+ return null;
2458
+ }
2459
+ })();
2460
+ const msg = errorMessageFromUniswapJsonBody(parsed) ?? (text.trim() || res.statusText);
2461
+ throw new Error(`List limit orders HTTP ${res.status}: ${msg}`);
2462
+ }
2463
+ return JSON.parse(text.replace(/^\uFEFF/, ""));
2464
+ }
2465
+ async function uniswapFetchLimitOrdersMcp(args) {
2466
+ let swapper;
2467
+ if ((args.swapper || "").trim()) {
2468
+ swapper = trimAddr3(args.swapper);
2469
+ } else {
2470
+ const keyGen = (args.keyGen || "").trim();
2471
+ if (!keyGen) {
2472
+ throw new Error("swapper or keyGen is required");
2473
+ }
2474
+ const mpc = (args.managementNodeUrl || "").trim();
2475
+ if (!mpc) {
2476
+ throw new Error("managementNodeUrl is required when swapper is not provided");
2477
+ }
2478
+ swapper = await fetchEthereumAddressForKeyGen(
2479
+ mpc,
2480
+ keyGen,
2481
+ args.nodeReadAuth ?? { bearerOnGet: true, jwt: null }
2482
+ );
2483
+ }
2484
+ return fetchUniswapXLimitOrders({
2485
+ swapper,
2486
+ chainId: args.chainId,
2487
+ uniswapApiKey: args.uniswapApiKey,
2488
+ limit: args.limit,
2489
+ baseUrl: args.baseUrl,
2490
+ fetchImpl: args.fetchImpl
2491
+ });
2492
+ }
2493
+ async function buildEvmMultisignBodyUniswapV4LimitOrderBatch(args) {
2494
+ assertUniswapLimitOrderChain(args.chainId);
2495
+ const permitRaw = extractPermitDataFromLimitQuote(args.fullLimitQuote);
2496
+ if (!permitRaw) {
2497
+ throw new Error(
2498
+ "Limit order quote has no permitData \u2014 cannot build EIP-712 sign request. Re-quote or confirm mainnet limit order support for this pair."
2499
+ );
2500
+ }
2501
+ const typedData = permitDataToEip712Payload(permitRaw);
2502
+ const submitTemplate = buildUniswapXLimitOrderSubmitBody({
2503
+ quoteResponse: args.fullLimitQuote,
2504
+ signatureHex: "0x"
2505
+ });
2506
+ return buildEip712MultisignBody({
2507
+ keyGen: args.keyGen,
2508
+ purposeText: args.purposeText,
2509
+ destinationChainID: String(UNISWAP_LIMIT_ORDER_CHAIN_ID),
2510
+ destinationAddress: PERMIT2_ADDRESS,
2511
+ typedData,
2512
+ delivery: {
2513
+ kind: "uniswapx_limit_order",
2514
+ chainId: UNISWAP_LIMIT_ORDER_CHAIN_ID,
2515
+ swapper: getAddress(args.swapper),
2516
+ submitBodyTemplate: submitTemplate,
2517
+ quoteResponse: args.fullLimitQuote,
2518
+ uniswapApiKey: args.uniswapApiKey,
2519
+ tradeApiBaseUrl: args.tradeApiBaseUrl ?? "https://trade-api.gateway.uniswap.org/v1"
2520
+ },
2521
+ audit: {
2522
+ protocol: "uniswap-v4",
2523
+ action: "limitOrder",
2524
+ routing: args.fullLimitQuote.routing ?? "LIMIT_ORDER",
2525
+ orderType: "Limit",
2526
+ primaryType: typedData.primaryType
2527
+ },
2528
+ expiryDate: args.expiryDate
2529
+ });
2530
+ }
2531
+ async function buildEvmMultisignBodyUniswapV4LimitOrderBatchFromMcp(args) {
2532
+ return buildEvmMultisignBodyUniswapV4LimitOrderBatch({
2533
+ keyGen: args.keyGen,
2534
+ chainId: args.chainId,
2535
+ purposeText: args.purposeText,
2536
+ fullLimitQuote: args.fullLimitQuote,
2537
+ swapper: getAddress(args.executorAddress),
2538
+ uniswapApiKey: args.uniswapApiKey,
2539
+ tradeApiBaseUrl: args.tradeApiBaseUrl,
2540
+ expiryDate: args.expiryDate
2541
+ });
2542
+ }
2543
+
2204
2544
  // src/protocols/evm/uniswap-v4/index.ts
2205
2545
  var UNISWAP_V4_PROTOCOL_ID = "uniswap-v4";
2206
2546
  var uniswapV4ProtocolModule = {
@@ -2247,6 +2587,17 @@ var uniswapV4ProtocolModule = {
2247
2587
  type: { type: "EXACT_INPUT | EXACT_OUTPUT", required: true, description: "Trade type" }
2248
2588
  }
2249
2589
  },
2590
+ {
2591
+ id: "uniswap-v4.limit-order",
2592
+ protocolId: UNISWAP_V4_PROTOCOL_ID,
2593
+ chainCategory: "evm",
2594
+ description: "Place UniswapX limit order via EIP-712 sign + POST /order (Ethereum mainnet only)",
2595
+ commonParams: ["keyGen", "purposeText"],
2596
+ params: {
2597
+ fullLimitQuote: { type: "object", required: true, description: "Full limit order quote from Trade API" },
2598
+ uniswapApiKey: { type: "string", required: true, description: "Uniswap Trade API key" }
2599
+ }
2600
+ },
2250
2601
  {
2251
2602
  id: "uniswap-v4.mint-liquidity",
2252
2603
  protocolId: UNISWAP_V4_PROTOCOL_ID,
@@ -2302,6 +2653,10 @@ var uniswapV4 = {
2302
2653
  swapExactInput,
2303
2654
  swapFromQuote,
2304
2655
  buildSwapMultisignBody: buildEvmMultisignBodyUniswapV4SkipPermit2Batch,
2656
+ limitOrderQuote: uniswapLimitOrderQuote,
2657
+ buildLimitOrderMultisignBody: buildEvmMultisignBodyUniswapV4LimitOrderBatchFromMcp,
2658
+ fetchLimitOrders: fetchUniswapXLimitOrders,
2659
+ fetchLimitOrdersMcp: uniswapFetchLimitOrdersMcp,
2305
2660
  quote: uniswapTradeQuote,
2306
2661
  createLiquidityPosition: uniswapLpCreatePosition,
2307
2662
  increaseLiquidityPosition: uniswapLpIncreasePosition,
@@ -2682,6 +3037,6 @@ var curveDao = {
2682
3037
  registerProtocolModule(uniswapV4ProtocolModule);
2683
3038
  registerProtocolModule(curveDaoProtocolModule);
2684
3039
 
2685
- export { COINGECKO_PLATFORM_BY_CHAIN_ID, EIP712_SIGN_REQUEST_KIND, NEAR_CHAIN_CATEGORY, SOLANA_CHAIN_CATEGORY, approveStepsToEvmTxSteps, buildConditionalErc20ApproveSteps, buildEip712MultisignBody, buildEvmMultisignBatch, coingeckoPlatformForChainId, coreChainCategoryModule, curveDao, curveDaoProtocolModule, evmChainCategoryModule, finalizeMultisign, getAaveGraphqlProxyUrl, getActionsByChainCategory, getCoingeckoProxyUrl, getEulerGraphqlProxyUrl, getMapleGraphqlProxyUrl, getMorphoGraphqlProxyUrl, getProtocolModule, getProtocolModules, isEvmNativeToken, matchEvmTokenKind, mergePurposeText, nearChainCategoryModule, normalizeCurveRouterAmountString, normalizeHumanDecimalAmount, parseEvmChainIdToNumber, postJsonViaOptionalProxy, publicClientForRpc, registerProtocolModule, resolveErc20Decimals, routerSwapGasLimitFromEstimate, setAaveGraphqlProxyUrl, setCoingeckoProxyUrl, setEulerGraphqlProxyUrl, setMapleGraphqlProxyUrl, setMorphoGraphqlProxyUrl, solanaChainCategoryModule, uniswapV4, uniswapV4ProtocolModule };
3040
+ export { COINGECKO_PLATFORM_BY_CHAIN_ID, DEFAULT_DEFI_MULTISIGN_EXPIRY_SECONDS, DEFI_PROTOCOLS_WITH_30MIN_EXPIRY, EIP712_SIGN_REQUEST_KIND, NEAR_CHAIN_CATEGORY, SOLANA_CHAIN_CATEGORY, approveStepsToEvmTxSteps, buildConditionalErc20ApproveSteps, buildEip712MultisignBody, buildEvmMultisignBatch, coingeckoPlatformForChainId, coreChainCategoryModule, curveDao, curveDaoProtocolModule, defiMultisignExpiryUnixSeconds, evmChainCategoryModule, finalizeMultisign, getAaveGraphqlProxyUrl, getActionsByChainCategory, getCoingeckoProxyUrl, getEulerGraphqlProxyUrl, getMapleGraphqlProxyUrl, getMorphoGraphqlProxyUrl, getProtocolModule, getProtocolModules, isEvmNativeToken, matchEvmTokenKind, mergePurposeText, nearChainCategoryModule, normalizeCurveRouterAmountString, normalizeHumanDecimalAmount, parseEvmChainIdToNumber, postJsonViaOptionalProxy, publicClientForRpc, registerProtocolModule, resolveErc20Decimals, routerSwapGasLimitFromEstimate, setAaveGraphqlProxyUrl, setCoingeckoProxyUrl, setEulerGraphqlProxyUrl, setMapleGraphqlProxyUrl, setMorphoGraphqlProxyUrl, solanaChainCategoryModule, uniswapV4, uniswapV4ProtocolModule };
2686
3041
  //# sourceMappingURL=index.js.map
2687
3042
  //# sourceMappingURL=index.js.map