@continuumdao/ctm-mpc-defi 0.2.26 → 0.2.28

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 (38) hide show
  1. package/dist/agent/catalog.cjs +681 -46
  2. package/dist/agent/catalog.cjs.map +1 -1
  3. package/dist/agent/catalog.d.ts +1209 -21
  4. package/dist/agent/catalog.js +668 -47
  5. package/dist/agent/catalog.js.map +1 -1
  6. package/dist/agent/skills/morpho/SKILL.md +38 -6
  7. package/dist/agent/skills/uniswap-v4/SKILL.md +15 -0
  8. package/dist/core/index.cjs +19 -0
  9. package/dist/core/index.cjs.map +1 -1
  10. package/dist/core/index.d.ts +8 -1
  11. package/dist/core/index.js +17 -1
  12. package/dist/core/index.js.map +1 -1
  13. package/dist/index.cjs +363 -22
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.d.ts +1 -1
  16. package/dist/index.js +361 -23
  17. package/dist/index.js.map +1 -1
  18. package/dist/protocols/evm/aave-v4/index.cjs.map +1 -1
  19. package/dist/protocols/evm/aave-v4/index.js.map +1 -1
  20. package/dist/protocols/evm/euler-v2/index.cjs.map +1 -1
  21. package/dist/protocols/evm/euler-v2/index.js.map +1 -1
  22. package/dist/protocols/evm/maple/index.cjs.map +1 -1
  23. package/dist/protocols/evm/maple/index.js.map +1 -1
  24. package/dist/protocols/evm/morpho/index.cjs +1153 -142
  25. package/dist/protocols/evm/morpho/index.cjs.map +1 -1
  26. package/dist/protocols/evm/morpho/index.d.ts +314 -8
  27. package/dist/protocols/evm/morpho/index.js +1131 -144
  28. package/dist/protocols/evm/morpho/index.js.map +1 -1
  29. package/dist/protocols/evm/permit2/index.cjs.map +1 -1
  30. package/dist/protocols/evm/permit2/index.js.map +1 -1
  31. package/dist/protocols/evm/sky/index.cjs.map +1 -1
  32. package/dist/protocols/evm/sky/index.js.map +1 -1
  33. package/dist/protocols/evm/uniswap-v4/index.cjs +863 -25
  34. package/dist/protocols/evm/uniswap-v4/index.cjs.map +1 -1
  35. package/dist/protocols/evm/uniswap-v4/index.d.ts +266 -9
  36. package/dist/protocols/evm/uniswap-v4/index.js +834 -27
  37. package/dist/protocols/evm/uniswap-v4/index.js.map +1 -1
  38. package/package.json +2 -1
@@ -1,4 +1,4 @@
1
- import { parseAbi, parseAbiParameters, parseAbiItem, getAddress, zeroAddress, formatUnits, parseUnits, createPublicClient, http, defineChain, encodeFunctionData, keccak256, encodeAbiParameters, decodeEventLog, decodeFunctionData, parseGwei, serializeTransaction, erc20Abi, hashTypedData, stringToHex } from 'viem';
1
+ import { parseAbi, parseAbiParameters, parseAbiItem, getAddress, createPublicClient, http, defineChain, zeroAddress, formatUnits, parseUnits, encodeFunctionData, keccak256, encodeAbiParameters, decodeEventLog, decodeFunctionData, parseGwei, serializeTransaction, erc20Abi, hashTypedData, stringToHex } from 'viem';
2
2
  import { nodeFetchWithReadAuth, fetchChainFeeParams, gasLimitFromEstimateAndChainConfig, gweiToDecimalString, proposalTxParamsToFeeSnapshot, alignEip1559FeesWithLatestBase, getClientIdFromKeyGenResult } from '@continuumdao/continuum-node-sdk';
3
3
 
4
4
  // src/core/registry.ts
@@ -70,11 +70,23 @@ var UNIVERSAL_ROUTER_SPENDER = {
70
70
  /** Robinhood Chain mainnet — Universal Router v2.1.1 (Trade API / interface) */
71
71
  4663: "0x8876789976decbfcbbbe364623c63652db8c0904"
72
72
  };
73
+ var UNIVERSAL_ROUTER_V2_2_SPENDER = {
74
+ 1: "0xCb640A86855f1A828c27241bA364348de28abe66",
75
+ 11155111: "0xB0C89059d7190EDb17eFF19829cc009cEe923916"
76
+ };
73
77
  var UNIVERSAL_ROUTER_VERSION_BY_CHAIN = {
74
78
  /** Robinhood has UR 2.1.1 only in the supported-chains table (no 2.0 Trade API column). */
75
79
  4663: "2.1.1"
76
80
  };
77
- function getUniswapUniversalRouterVersion(chainId) {
81
+ var UNISWAP_UNIVERSAL_ROUTER_VERSION_DEFAULT = "2.0";
82
+ var UNISWAP_UNIVERSAL_ROUTER_VERSION_PERMISSIONED = "2.2.0";
83
+ function getUniswapUniversalRouterVersion(chainId, opts) {
84
+ if (opts?.permissioned) {
85
+ const v22 = UNIVERSAL_ROUTER_V2_2_SPENDER[chainId];
86
+ if (typeof v22 === "string" && v22.startsWith("0x")) {
87
+ return UNISWAP_UNIVERSAL_ROUTER_VERSION_PERMISSIONED;
88
+ }
89
+ }
78
90
  const v = UNIVERSAL_ROUTER_VERSION_BY_CHAIN[chainId];
79
91
  return typeof v === "string" && v.trim() ? v.trim() : UNISWAP_UNIVERSAL_ROUTER_VERSION_DEFAULT;
80
92
  }
@@ -85,7 +97,11 @@ function isUniswapV4ChainSupported(chainId) {
85
97
  const a = UNIVERSAL_ROUTER_SPENDER[n];
86
98
  return typeof a === "string" && a.startsWith("0x");
87
99
  }
88
- function getUniswapUniversalRouterSpenderOrThrow(chainId) {
100
+ function getUniswapUniversalRouterSpenderOrThrow(chainId, opts) {
101
+ if (opts?.permissioned) {
102
+ const raw22 = UNIVERSAL_ROUTER_V2_2_SPENDER[chainId];
103
+ if (raw22 && raw22.startsWith("0x")) return getAddress(raw22);
104
+ }
89
105
  const raw = UNIVERSAL_ROUTER_SPENDER[chainId];
90
106
  if (!raw || !raw.startsWith("0x")) {
91
107
  throw new Error(
@@ -94,12 +110,16 @@ function getUniswapUniversalRouterSpenderOrThrow(chainId) {
94
110
  }
95
111
  return getAddress(raw);
96
112
  }
113
+ function tryGetUniswapUniversalRouterV22(chainId) {
114
+ const raw = UNIVERSAL_ROUTER_V2_2_SPENDER[chainId];
115
+ if (!raw || !raw.startsWith("0x")) return null;
116
+ return getAddress(raw);
117
+ }
97
118
  var MAX_UINT160 = (1n << 160n) - 1n;
98
119
  var MAX_UINT48 = (1n << 48n) - 1n;
99
120
  var UNISWAP_UNIVERSAL_ROUTER_DEFAULT_GAS_UNITS = 1500000n;
100
121
  var UNISWAP_TRADE_BASE_DEFAULT = "https://trade-api.gateway.uniswap.org/v1";
101
122
  var UNISWAP_LP_API_BASE_DEFAULT = "https://api.uniswap.org";
102
- var UNISWAP_UNIVERSAL_ROUTER_VERSION_DEFAULT = "2.0";
103
123
  var UNISWAP_SWAP_DEFAULT_EXPIRY_MINUTES = 30;
104
124
  var UNISWAP_SWAP_DEFAULT_DEADLINE_SEC_OFFSET = UNISWAP_SWAP_DEFAULT_EXPIRY_MINUTES * 60;
105
125
  var UNISWAP_LP_DEFAULT_EXPIRY_MINUTES = 30;
@@ -118,6 +138,18 @@ var POSITION_MANAGER_BY_CHAIN = {
118
138
  /** Robinhood Chain mainnet */
119
139
  4663: "0x58daec3116aae6D93017bAAea7749052E8a04fA7"
120
140
  };
141
+ var PERMISSIONED_POSITION_MANAGER_BY_CHAIN = {
142
+ 1: "0x89628C9B4CE81951a9BC1F36F0688Fad6A6ee248",
143
+ 11155111: "0x68fC145BB20b388965bED184Df5ef912215bb3C7"
144
+ };
145
+ var PERMISSIONED_HOOKS_BY_CHAIN = {
146
+ 1: "0x69603ab16110Eb0bB5f5E9C8019749eE41A128C0",
147
+ 11155111: "0x8B0E8d467af81D9F5B49165e104a2fe1b98328C0"
148
+ };
149
+ var PERMISSIONS_ADAPTER_FACTORY_BY_CHAIN = {
150
+ 1: "0x38f9Ab57FBE2704EbB727cB20e33201aF0E5F961",
151
+ 11155111: "0xEe258C31574fb59660C23534E76AF6497c2e5683"
152
+ };
121
153
  var ROBINHOOD_CHAIN_ID = 4663;
122
154
  var ROBINHOOD_WETH_ADDRESS = "0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73";
123
155
  function getUniswapV4PositionManagerOrThrow(chainId) {
@@ -136,6 +168,76 @@ function tryGetUniswapV4PositionManager(chainId) {
136
168
  return null;
137
169
  }
138
170
  }
171
+ function getUniswapV4PermissionedPositionManagerOrThrow(chainId) {
172
+ const raw = PERMISSIONED_POSITION_MANAGER_BY_CHAIN[chainId];
173
+ if (!raw || !raw.startsWith("0x") || raw.length !== 42) {
174
+ throw new Error(
175
+ `No Uniswap V4 Permissioned PositionManager is configured for chainId ${chainId}.`
176
+ );
177
+ }
178
+ return getAddress(raw);
179
+ }
180
+ function tryGetUniswapV4PermissionedPositionManager(chainId) {
181
+ try {
182
+ return getUniswapV4PermissionedPositionManagerOrThrow(chainId);
183
+ } catch {
184
+ return null;
185
+ }
186
+ }
187
+ function getUniswapV4PermissionedHooksOrThrow(chainId) {
188
+ const raw = PERMISSIONED_HOOKS_BY_CHAIN[chainId];
189
+ if (!raw || !raw.startsWith("0x") || raw.length !== 42) {
190
+ throw new Error(`No Uniswap V4 PermissionedHooks is configured for chainId ${chainId}.`);
191
+ }
192
+ return getAddress(raw);
193
+ }
194
+ function tryGetUniswapV4PermissionedHooks(chainId) {
195
+ try {
196
+ return getUniswapV4PermissionedHooksOrThrow(chainId);
197
+ } catch {
198
+ return null;
199
+ }
200
+ }
201
+ function getUniswapV4PermissionsAdapterFactoryOrThrow(chainId) {
202
+ const raw = PERMISSIONS_ADAPTER_FACTORY_BY_CHAIN[chainId];
203
+ if (!raw || !raw.startsWith("0x") || raw.length !== 42) {
204
+ throw new Error(
205
+ `No Uniswap V4 PermissionsAdapterFactory is configured for chainId ${chainId}.`
206
+ );
207
+ }
208
+ return getAddress(raw);
209
+ }
210
+ function tryGetUniswapV4PermissionsAdapterFactory(chainId) {
211
+ try {
212
+ return getUniswapV4PermissionsAdapterFactoryOrThrow(chainId);
213
+ } catch {
214
+ return null;
215
+ }
216
+ }
217
+ function isUniswapV4PermissionedPositionManager(chainId, address) {
218
+ if (!address?.toString().trim()) return false;
219
+ const perm = tryGetUniswapV4PermissionedPositionManager(chainId);
220
+ if (!perm) return false;
221
+ try {
222
+ return getAddress(address) === perm;
223
+ } catch {
224
+ return false;
225
+ }
226
+ }
227
+ function isUniswapV4AnyPositionManager(chainId, address) {
228
+ if (!address?.toString().trim()) return false;
229
+ try {
230
+ const a = getAddress(address);
231
+ const std = tryGetUniswapV4PositionManager(chainId);
232
+ const perm = tryGetUniswapV4PermissionedPositionManager(chainId);
233
+ return std != null && a === std || perm != null && a === perm;
234
+ } catch {
235
+ return false;
236
+ }
237
+ }
238
+ function resolveUniswapV4PositionManager(chainId, kind = "standard") {
239
+ return kind === "permissioned" ? getUniswapV4PermissionedPositionManagerOrThrow(chainId) : getUniswapV4PositionManagerOrThrow(chainId);
240
+ }
139
241
  var POSITION_MANAGER_DEPLOY_BLOCK_BY_CHAIN = {
140
242
  /** Ethereum mainnet — Uniswap v4 launch (Jan 2025). */
141
243
  1: 22938741n
@@ -151,6 +253,231 @@ var UNISWAP_V4_LP_DECREASE_DEFAULT_GAS_UNITS = 1200000n;
151
253
  var UNISWAP_V4_LP_COLLECT_DEFAULT_GAS_UNITS = 900000n;
152
254
  var UNISWAP_V4_LP_ERC20_APPROVE_FALLBACK = 100000n;
153
255
  var UNISWAP_V4_LP_WETH_DEPOSIT_FALLBACK = 120000n;
256
+ var UNISWAP_V4_LP_PERMIT2_APPROVE_FALLBACK = 100000n;
257
+ var UNISWAP_V4_PERMISSION_FLAG_SWAP = 1;
258
+ var UNISWAP_V4_PERMISSION_FLAG_LIQUIDITY = 2;
259
+ var permissionsAdapterAbi = parseAbi([
260
+ "function isAllowed(address account, uint8 permission) view returns (bool)",
261
+ "function PERMISSIONED_TOKEN() view returns (address)"
262
+ ]);
263
+ var factoryAbi = parseAbi([
264
+ "function verifiedPermissionsAdapterOf(address permissionsAdapter) view returns (address)"
265
+ ]);
266
+ function normalizeTokenList(tokens) {
267
+ const out = [];
268
+ const seen = /* @__PURE__ */ new Set();
269
+ for (const raw of tokens) {
270
+ const t = (raw ?? "").toString().trim();
271
+ if (!t) continue;
272
+ if (isUniswapNativeTokenAddress(t)) continue;
273
+ let addr;
274
+ try {
275
+ addr = getAddress(t);
276
+ } catch {
277
+ continue;
278
+ }
279
+ if (addr === zeroAddress) continue;
280
+ const key = addr.toLowerCase();
281
+ if (seen.has(key)) continue;
282
+ seen.add(key);
283
+ out.push(addr);
284
+ if (out.length >= 2) break;
285
+ }
286
+ return out;
287
+ }
288
+ function parsePermissionRow(raw) {
289
+ const tokenRaw = (raw.token ?? raw.address ?? "").toString().trim();
290
+ if (!tokenRaw) return null;
291
+ let token;
292
+ try {
293
+ token = getAddress(tokenRaw);
294
+ } catch {
295
+ return null;
296
+ }
297
+ const isPermissioned = Boolean(raw.isPermissioned);
298
+ const isAllowlisted = isPermissioned ? Boolean(raw.isAllowlisted) : true;
299
+ let adapterTokenAddress;
300
+ const adapterRaw = (raw.adapterTokenAddress ?? "").toString().trim();
301
+ if (adapterRaw) {
302
+ try {
303
+ adapterTokenAddress = getAddress(adapterRaw);
304
+ } catch {
305
+ }
306
+ }
307
+ const kycUrl = typeof raw.kycUrl === "string" && raw.kycUrl.trim() ? raw.kycUrl.trim() : void 0;
308
+ const issuer = typeof raw.issuer === "string" && raw.issuer.trim() ? raw.issuer.trim() : void 0;
309
+ return { token, isPermissioned, isAllowlisted, adapterTokenAddress, kycUrl, issuer };
310
+ }
311
+ async function uniswapV4CheckPermissions(args) {
312
+ const apiKey = args.uniswapApiKey?.trim();
313
+ if (!apiKey) throw new Error("uniswapApiKey is required for POST /v1/permissions");
314
+ const walletAddress = getAddress(args.walletAddress.trim());
315
+ const chainId = parseUniswapChainId(args.chainId);
316
+ const tokens = normalizeTokenList(args.tokens);
317
+ if (tokens.length === 0) {
318
+ return {
319
+ results: [],
320
+ anyPermissioned: false,
321
+ allAllowlisted: true,
322
+ requiresUniversalRouterV22: false
323
+ };
324
+ }
325
+ const base = (args.baseUrl?.trim() || UNISWAP_TRADE_BASE_DEFAULT).replace(/\/$/, "");
326
+ const url = `${base}/permissions`;
327
+ const fetchFn = args.fetchImpl ?? globalThis.fetch;
328
+ const res = await fetchFn(url, {
329
+ method: "POST",
330
+ headers: {
331
+ "Content-Type": "application/json",
332
+ "User-Agent": "ctm-mpc-defi uniswapPermissions/1.0 (TS)",
333
+ "x-api-key": apiKey
334
+ },
335
+ body: JSON.stringify({
336
+ walletAddress,
337
+ tokens,
338
+ chainId
339
+ }),
340
+ signal: args.signal
341
+ });
342
+ const text = await res.text();
343
+ if (!res.ok) {
344
+ throw new Error(
345
+ `Uniswap POST /permissions failed: ${messageFromUniswapHttpResponseBody(text, res.status, res.statusText)}`
346
+ );
347
+ }
348
+ let parsed;
349
+ try {
350
+ parsed = JSON.parse(text.replace(/^\uFEFF/, ""));
351
+ } catch {
352
+ throw new Error(
353
+ `Uniswap POST /permissions: ${messageFromUniswapHttpResponseBody(text, res.status, res.statusText)}`
354
+ );
355
+ }
356
+ const rawResults = Array.isArray(parsed.results) ? parsed.results : [];
357
+ const results = [];
358
+ for (const row of rawResults) {
359
+ if (!row || typeof row !== "object" || Array.isArray(row)) continue;
360
+ const parsedRow = parsePermissionRow(row);
361
+ if (parsedRow) results.push(parsedRow);
362
+ }
363
+ for (const token of tokens) {
364
+ if (!results.some((r) => r.token === token)) {
365
+ results.push({ token, isPermissioned: false, isAllowlisted: true });
366
+ }
367
+ }
368
+ const anyPermissioned = results.some((r) => r.isPermissioned);
369
+ const allAllowlisted = results.every((r) => !r.isPermissioned || r.isAllowlisted);
370
+ return {
371
+ requestId: typeof parsed.requestId === "string" ? parsed.requestId : void 0,
372
+ results,
373
+ anyPermissioned,
374
+ allAllowlisted,
375
+ requiresUniversalRouterV22: anyPermissioned
376
+ };
377
+ }
378
+ var UniswapV4PermissionDeniedError = class extends Error {
379
+ code = "UNISWAP_V4_PERMISSION_DENIED";
380
+ permissions;
381
+ blocked;
382
+ constructor(permissions) {
383
+ const blocked = permissions.results.filter((r) => r.isPermissioned && !r.isAllowlisted);
384
+ const issuer = blocked.find((b) => b.issuer)?.issuer;
385
+ const kycUrl = blocked.find((b) => b.kycUrl)?.kycUrl;
386
+ const parts = [
387
+ "Wallet is not allowlisted for one or more permissioned Uniswap V4 tokens.",
388
+ issuer ? `Issuer: ${issuer}.` : null,
389
+ kycUrl ? `Complete KYC at: ${kycUrl}` : "Open the issuer KYC URL from check_permissions."
390
+ ].filter(Boolean);
391
+ super(parts.join(" "));
392
+ this.name = "UniswapV4PermissionDeniedError";
393
+ this.permissions = permissions;
394
+ this.blocked = blocked;
395
+ }
396
+ };
397
+ function assertUniswapV4PermissionsAllowlisted(permissions) {
398
+ if (!permissions.allAllowlisted) {
399
+ throw new UniswapV4PermissionDeniedError(permissions);
400
+ }
401
+ }
402
+ async function readUniswapV4OnChainPermissionFlags(args) {
403
+ const factory = tryGetUniswapV4PermissionsAdapterFactory(args.chainId);
404
+ if (!factory) return [];
405
+ const client = args.publicClient ?? createPublicClient({
406
+ chain: defineChain({
407
+ id: args.chainId,
408
+ name: `uniswap-perm-${args.chainId}`,
409
+ nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 },
410
+ rpcUrls: { default: { http: [args.rpcUrl] } }
411
+ }),
412
+ transport: http(args.rpcUrl)
413
+ });
414
+ const wallet = getAddress(args.walletAddress);
415
+ const out = [];
416
+ for (const raw of args.currencyOrAdapterAddresses) {
417
+ let address;
418
+ try {
419
+ address = getAddress(raw);
420
+ } catch {
421
+ continue;
422
+ }
423
+ if (address === zeroAddress) continue;
424
+ let underlying;
425
+ try {
426
+ underlying = getAddress(
427
+ await client.readContract({
428
+ address: factory,
429
+ abi: factoryAbi,
430
+ functionName: "verifiedPermissionsAdapterOf",
431
+ args: [address]
432
+ })
433
+ );
434
+ } catch {
435
+ out.push({
436
+ address,
437
+ isVerifiedAdapter: false,
438
+ swapAllowed: true,
439
+ liquidityAllowed: true
440
+ });
441
+ continue;
442
+ }
443
+ if (underlying === zeroAddress) {
444
+ out.push({
445
+ address,
446
+ isVerifiedAdapter: false,
447
+ swapAllowed: true,
448
+ liquidityAllowed: true
449
+ });
450
+ continue;
451
+ }
452
+ const [swapAllowed, liquidityAllowed] = await Promise.all([
453
+ client.readContract({
454
+ address,
455
+ abi: permissionsAdapterAbi,
456
+ functionName: "isAllowed",
457
+ args: [wallet, UNISWAP_V4_PERMISSION_FLAG_SWAP]
458
+ }),
459
+ client.readContract({
460
+ address,
461
+ abi: permissionsAdapterAbi,
462
+ functionName: "isAllowed",
463
+ args: [wallet, UNISWAP_V4_PERMISSION_FLAG_LIQUIDITY]
464
+ })
465
+ ]);
466
+ out.push({
467
+ address,
468
+ isVerifiedAdapter: true,
469
+ underlyingToken: underlying,
470
+ swapAllowed: Boolean(swapAllowed),
471
+ liquidityAllowed: Boolean(liquidityAllowed)
472
+ });
473
+ }
474
+ return out;
475
+ }
476
+ async function uniswapV4CheckPermissionsMcp(args) {
477
+ return uniswapV4CheckPermissions(args);
478
+ }
479
+
480
+ // src/protocols/evm/uniswap-v4/quote.ts
154
481
  var DEFAULT_TRADE_BASE = "https://trade-api.gateway.uniswap.org/v1";
155
482
  var UNISWAP_QUOTE_HEADERS_BASE = {
156
483
  "Content-Type": "application/json",
@@ -400,7 +727,25 @@ async function uniswapTradeQuote(args) {
400
727
  const base = args.baseUrl && args.baseUrl.trim() ? args.baseUrl.trim().replace(/\/$/, "") : DEFAULT_TRADE_BASE;
401
728
  const quoteUrl = `${base}/quote`;
402
729
  const chainIdForRouter = parseUniswapChainId(resolveInputChainId(args));
403
- const urv = args.universalRouterVersion && args.universalRouterVersion.trim() || getUniswapUniversalRouterVersion(chainIdForRouter);
730
+ let permissions;
731
+ const shouldCheckPermissions = args.forcePermissionedRouter !== true && args.skipPermissionCheck !== true && args.checkPermissions !== false;
732
+ if (shouldCheckPermissions) {
733
+ try {
734
+ permissions = await uniswapV4CheckPermissions({
735
+ walletAddress: swapper,
736
+ tokens: [args.tokenIn, args.tokenOut],
737
+ chainId: chainIdForRouter,
738
+ uniswapApiKey: apiKey,
739
+ baseUrl: base,
740
+ signal: args.signal,
741
+ fetchImpl: args.fetchImpl
742
+ });
743
+ } catch {
744
+ permissions = void 0;
745
+ }
746
+ }
747
+ const permissionedRouter = args.forcePermissionedRouter === true || Boolean(permissions?.requiresUniversalRouterV22);
748
+ const urv = args.universalRouterVersion && args.universalRouterVersion.trim() || getUniswapUniversalRouterVersion(chainIdForRouter, { permissioned: permissionedRouter });
404
749
  const body = buildUniswapQuoteRequestBody({ ...args, swapper });
405
750
  const nativeIn = isUniswapNativeTokenAddress(args.tokenIn);
406
751
  const nativeOut = isUniswapNativeTokenAddress(args.tokenOut);
@@ -429,13 +774,27 @@ async function uniswapTradeQuote(args) {
429
774
  }
430
775
  const forParse = text.replace(/^\uFEFF/, "");
431
776
  try {
432
- return JSON.parse(forParse);
777
+ const parsed = JSON.parse(forParse);
778
+ if (permissionedRouter || urv === UNISWAP_UNIVERSAL_ROUTER_VERSION_PERMISSIONED) {
779
+ parsed._continuumPermissioned = true;
780
+ parsed._continuumUniversalRouterVersion = urv;
781
+ }
782
+ if (permissions) {
783
+ parsed._continuumPermissions = permissions;
784
+ }
785
+ return parsed;
433
786
  } catch {
434
787
  throw new Error(
435
788
  `Trade API: ${messageFromUniswapHttpResponseBody(text, res.status, res.statusText)}`
436
789
  );
437
790
  }
438
791
  }
792
+ function isUniswapStoredQuotePermissioned(stored) {
793
+ if (!stored) return false;
794
+ if (stored._continuumPermissioned === true) return true;
795
+ const v = stored._continuumUniversalRouterVersion;
796
+ return typeof v === "string" && v.trim() === UNISWAP_UNIVERSAL_ROUTER_VERSION_PERMISSIONED;
797
+ }
439
798
  function uniswapQuoteToJsonQuoteOneLine(quote) {
440
799
  return JSON.stringify(quote);
441
800
  }
@@ -989,7 +1348,9 @@ async function uniswapCreateSwap(args) {
989
1348
  quote: classic,
990
1349
  deadline
991
1350
  };
992
- const urv = (args.universalRouterVersion ?? "").trim() || getUniswapUniversalRouterVersion(resolveChainIdFromStoredUniswapQuote(args.fullQuoteFromPermit));
1351
+ const chainIdForRouter = resolveChainIdFromStoredUniswapQuote(args.fullQuoteFromPermit);
1352
+ const permissioned = isUniswapStoredQuotePermissioned(args.fullQuoteFromPermit);
1353
+ const urv = (args.universalRouterVersion ?? "").trim() || getUniswapUniversalRouterVersion(chainIdForRouter, { permissioned });
993
1354
  const fn = args.fetchImpl ?? globalThis.fetch;
994
1355
  const nativeIn = isUniswapFullQuoteResponseNativeIn(args.fullQuoteFromPermit);
995
1356
  const nativeOut = isUniswapFullQuoteResponseNativeOut(args.fullQuoteFromPermit);
@@ -1117,8 +1478,8 @@ function applySlippagePercentToApproveWei(baseWei, slippagePercent) {
1117
1478
  if (bps <= 0) return baseWei;
1118
1479
  return (baseWei * BigInt(1e4 + bps) + 9999n) / 10000n;
1119
1480
  }
1120
- function permit2SpenderAndApproveWeiFromSwapCalldata(dataHex, tokenIn, quoteInputWei, chainId) {
1121
- const canonical = getUniswapUniversalRouterSpenderOrThrow(chainId);
1481
+ function permit2SpenderAndApproveWeiFromSwapCalldata(dataHex, tokenIn, quoteInputWei, chainId, permissioned = false) {
1482
+ const canonical = getUniswapUniversalRouterSpenderOrThrow(chainId, { permissioned });
1122
1483
  try {
1123
1484
  const d = decodeFunctionData({ abi: uniswapDispatchExecuteAbi, data: dataHex });
1124
1485
  if (d.functionName !== "execute") {
@@ -1254,6 +1615,27 @@ async function buildEvmMultisignBodyUniswapV4SkipPermit2Batch(args) {
1254
1615
  "Could not read a positive input amount from the quote. Refresh the quote and ensure the Trade API returned classic quote.input.amount."
1255
1616
  );
1256
1617
  }
1618
+ const permissioned = isUniswapStoredQuotePermissioned(args.fullQuoteSnapshot);
1619
+ if (args.skipPermissionCheck !== true) {
1620
+ const cached = args.fullQuoteSnapshot._continuumPermissions;
1621
+ if (cached && typeof cached === "object" && cached.allAllowlisted === false) {
1622
+ assertUniswapV4PermissionsAllowlisted({
1623
+ results: cached.results ?? [],
1624
+ anyPermissioned: Boolean(cached.anyPermissioned),
1625
+ allAllowlisted: false,
1626
+ requiresUniversalRouterV22: Boolean(cached.requiresUniversalRouterV22)
1627
+ });
1628
+ } else if (args.uniswapApiKey?.trim() && (permissioned || args.tokenOut)) {
1629
+ const tokens = [args.tokenIn, args.tokenOut].filter(Boolean);
1630
+ const permissions = await uniswapV4CheckPermissions({
1631
+ walletAddress: args.executorAddress,
1632
+ tokens,
1633
+ chainId: args.chainId,
1634
+ uniswapApiKey: args.uniswapApiKey.trim()
1635
+ });
1636
+ assertUniswapV4PermissionsAllowlisted(permissions);
1637
+ }
1638
+ }
1257
1639
  if (tokenIn === zeroAddress) {
1258
1640
  return buildEvmMultisignBodyUniswapV4NativeInOnly(args, quoteInputWei);
1259
1641
  }
@@ -1264,12 +1646,15 @@ async function buildEvmMultisignBodyUniswapV4SkipPermit2Batch(args) {
1264
1646
  const d = (args.swap.data ?? "0x").toString().trim();
1265
1647
  return d.startsWith("0x") ? d : `0x${d}`;
1266
1648
  })();
1267
- const canonicalUniversalRouter = getUniswapUniversalRouterSpenderOrThrow(args.chainId);
1649
+ const canonicalUniversalRouter = getUniswapUniversalRouterSpenderOrThrow(args.chainId, {
1650
+ permissioned
1651
+ });
1268
1652
  const { permit2Spender, approveWei: baseApproveWei, calldataAmountWei } = permit2SpenderAndApproveWeiFromSwapCalldata(
1269
1653
  dataHex,
1270
1654
  tokenIn,
1271
1655
  quoteInputWei,
1272
- args.chainId
1656
+ args.chainId,
1657
+ permissioned
1273
1658
  );
1274
1659
  const approveAmountWei = applySlippagePercentToApproveWei(baseApproveWei, args.slippagePercent);
1275
1660
  const usePermit2Triple = toRouter.toLowerCase() === permit2Spender.toLowerCase();
@@ -2319,6 +2704,9 @@ var erc20AllowanceAbi2 = parseAbi([
2319
2704
  "function allowance(address owner, address spender) view returns (uint256)",
2320
2705
  "function decimals() view returns (uint8)"
2321
2706
  ]);
2707
+ var permit2ApproveAbi = parseAbi([
2708
+ "function approve(address token, address spender, uint160 amount, uint48 expiration)"
2709
+ ]);
2322
2710
  function parseOptionalGasLimitString2(raw) {
2323
2711
  if (raw == null) return null;
2324
2712
  const s = String(raw).trim();
@@ -2442,7 +2830,9 @@ async function buildEvmMultisignBodyUniswapV4LiquidityBatchInternal(args) {
2442
2830
  const dataHex = dataHexFromTx(tx);
2443
2831
  const valueWei = parseTxValueWei(tx);
2444
2832
  const executor = getAddress(args.executorAddress);
2445
- const spender = to;
2833
+ const positionManagerKind = args.positionManagerKind === "permissioned" || args.positionManagerKind === "standard" ? args.positionManagerKind : isUniswapV4PermissionedPositionManager(args.chainId, to) ? "permissioned" : "standard";
2834
+ const usePermit2 = args.usePermit2Approvals === true || args.usePermit2Approvals !== false && positionManagerKind === "permissioned";
2835
+ const erc20Spender = usePermit2 ? PERMIT2_ADDRESS : to;
2446
2836
  const chain = defineChain({
2447
2837
  id: args.chainId,
2448
2838
  name: `uniswap-v4-lp-${args.chainId}`,
@@ -2450,15 +2840,21 @@ async function buildEvmMultisignBodyUniswapV4LiquidityBatchInternal(args) {
2450
2840
  rpcUrls: { default: { http: [args.rpcUrl] } }
2451
2841
  });
2452
2842
  const publicClient = createPublicClient({ chain, transport: http(args.rpcUrl) });
2453
- const approveTargets = await resolveApproveTargets({
2843
+ const needsTokenApproves = args.action === "mint" || args.action === "increase";
2844
+ const approveTargets = needsTokenApproves ? await resolveApproveTargets({
2454
2845
  publicClient,
2455
2846
  executor,
2456
- spender,
2847
+ spender: erc20Spender,
2457
2848
  token0: parsed.token0,
2458
2849
  token1: parsed.token1,
2459
2850
  nativeWrapped: args.nativeWrapped
2460
- });
2851
+ }) : [];
2461
2852
  const steps = [];
2853
+ let permit2Expiration48 = 0n;
2854
+ if (usePermit2 && needsTokenApproves) {
2855
+ permit2Expiration48 = BigInt(Math.floor(Date.now() / 1e3) + UNISWAP_LP_DEFAULT_DEADLINE_SEC_OFFSET);
2856
+ if (permit2Expiration48 > MAX_UINT48) permit2Expiration48 = MAX_UINT48;
2857
+ }
2462
2858
  for (const target of approveTargets) {
2463
2859
  if (target.kind === "weth_deposit") {
2464
2860
  steps.push({
@@ -2471,13 +2867,17 @@ async function buildEvmMultisignBodyUniswapV4LiquidityBatchInternal(args) {
2471
2867
  address: target.token,
2472
2868
  abi: erc20AllowanceAbi2,
2473
2869
  functionName: "allowance",
2474
- args: [executor, spender]
2870
+ args: [executor, erc20Spender]
2475
2871
  });
2476
2872
  if (wethAllowance < target.amount) {
2477
- if (wethAllowance > 0n) {
2873
+ if (wethAllowance > 0n && !usePermit2) {
2478
2874
  steps.push({
2479
2875
  to: target.token,
2480
- data: encodeFunctionData({ abi: erc20Abi, functionName: "approve", args: [spender, 0n] }),
2876
+ data: encodeFunctionData({
2877
+ abi: erc20Abi,
2878
+ functionName: "approve",
2879
+ args: [erc20Spender, 0n]
2880
+ }),
2481
2881
  value: 0n,
2482
2882
  fallbackGas: UNISWAP_V4_LP_ERC20_APPROVE_FALLBACK
2483
2883
  });
@@ -2487,7 +2887,7 @@ async function buildEvmMultisignBodyUniswapV4LiquidityBatchInternal(args) {
2487
2887
  data: encodeFunctionData({
2488
2888
  abi: erc20Abi,
2489
2889
  functionName: "approve",
2490
- args: [spender, target.amount]
2890
+ args: [erc20Spender, target.amount]
2491
2891
  }),
2492
2892
  value: 0n,
2493
2893
  fallbackGas: UNISWAP_V4_LP_ERC20_APPROVE_FALLBACK
@@ -2499,13 +2899,66 @@ async function buildEvmMultisignBodyUniswapV4LiquidityBatchInternal(args) {
2499
2899
  data: encodeFunctionData({
2500
2900
  abi: erc20Abi,
2501
2901
  functionName: "approve",
2502
- args: [spender, target.amount]
2902
+ args: [erc20Spender, target.amount]
2503
2903
  }),
2504
2904
  value: 0n,
2505
2905
  fallbackGas: UNISWAP_V4_LP_ERC20_APPROVE_FALLBACK
2506
2906
  });
2507
2907
  }
2508
2908
  }
2909
+ if (usePermit2 && needsTokenApproves) {
2910
+ const pairs = [parsed.token0, parsed.token1].filter(Boolean);
2911
+ for (const row of pairs) {
2912
+ const amt = BigInt(row.amount);
2913
+ if (amt <= 0n) continue;
2914
+ let token;
2915
+ if (isNativeUniswapLpTokenAddress(row.tokenAddress)) {
2916
+ if (!args.nativeWrapped) {
2917
+ throw new Error("nativeWrapped is required when LP uses native ETH (0x0) token.");
2918
+ }
2919
+ token = getAddress(args.nativeWrapped);
2920
+ if (!approveTargets.some((a) => a.token === token && a.kind === "weth_deposit")) {
2921
+ steps.push({
2922
+ to: token,
2923
+ data: encodeFunctionData({ abi: wethDepositAbi, functionName: "deposit" }),
2924
+ value: amt,
2925
+ fallbackGas: UNISWAP_V4_LP_WETH_DEPOSIT_FALLBACK
2926
+ });
2927
+ const wethAllowance = await publicClient.readContract({
2928
+ address: token,
2929
+ abi: erc20AllowanceAbi2,
2930
+ functionName: "allowance",
2931
+ args: [executor, PERMIT2_ADDRESS]
2932
+ });
2933
+ if (wethAllowance < amt) {
2934
+ steps.push({
2935
+ to: token,
2936
+ data: encodeFunctionData({
2937
+ abi: erc20Abi,
2938
+ functionName: "approve",
2939
+ args: [PERMIT2_ADDRESS, amt]
2940
+ }),
2941
+ value: 0n,
2942
+ fallbackGas: UNISWAP_V4_LP_ERC20_APPROVE_FALLBACK
2943
+ });
2944
+ }
2945
+ }
2946
+ } else {
2947
+ token = getAddress(row.tokenAddress);
2948
+ }
2949
+ const amount160 = amt > MAX_UINT160 ? MAX_UINT160 : amt;
2950
+ steps.push({
2951
+ to: PERMIT2_ADDRESS,
2952
+ data: encodeFunctionData({
2953
+ abi: permit2ApproveAbi,
2954
+ functionName: "approve",
2955
+ args: [token, to, amount160, Number(permit2Expiration48)]
2956
+ }),
2957
+ value: 0n,
2958
+ fallbackGas: UNISWAP_V4_LP_PERMIT2_APPROVE_FALLBACK
2959
+ });
2960
+ }
2961
+ }
2509
2962
  const lpFallbackGas = defaultGasForAction(args.action);
2510
2963
  const fromTradeApi = parseOptionalGasLimitString2(tx.gasLimit) ?? parseOptionalGasLimitString2(tx.gas);
2511
2964
  steps.push({
@@ -2517,6 +2970,7 @@ async function buildEvmMultisignBodyUniswapV4LiquidityBatchInternal(args) {
2517
2970
  const actionLabel = args.action === "mint" ? "mint liquidity" : args.action === "increase" ? "increase liquidity" : args.action === "decrease" ? "decrease liquidity" : "collect fees";
2518
2971
  const dataNo0x = dataHex.startsWith("0x") ? dataHex.slice(2) : dataHex;
2519
2972
  const lpIndex = steps.length - 1;
2973
+ const purposeSuffix = usePermit2 ? `Uniswap V4 permissioned: ${steps.length}-tx batch \u2014 ${actionLabel} (ERC-20\u2192Permit2, Permit2\u2192PosM, Position Manager).` : `Uniswap V4: ${steps.length}-tx batch \u2014 ${actionLabel} (classic ERC-20 approve + Position Manager).`;
2520
2974
  return buildEvmMultisignBatch({
2521
2975
  context: {
2522
2976
  chainCategory: "evm",
@@ -2530,7 +2984,7 @@ async function buildEvmMultisignBodyUniswapV4LiquidityBatchInternal(args) {
2530
2984
  customGasChainDetails: args.customGasChainDetails
2531
2985
  },
2532
2986
  steps,
2533
- purposeSuffix: `Uniswap V4: ${steps.length}-tx batch \u2014 ${actionLabel} (classic ERC-20 approve + Position Manager).`,
2987
+ purposeSuffix,
2534
2988
  firstMsgRawNo0x: dataNo0x,
2535
2989
  destinationAddress: to,
2536
2990
  buildBatchMeta: ({ index }) => {
@@ -2540,13 +2994,17 @@ async function buildEvmMultisignBodyUniswapV4LiquidityBatchInternal(args) {
2540
2994
  kind: "UniswapV4Liquidity",
2541
2995
  action: args.action,
2542
2996
  step: index,
2543
- lpTx: isLpStep
2997
+ lpTx: isLpStep,
2998
+ positionManagerKind,
2999
+ usePermit2
2544
3000
  }),
2545
3001
  ...isLpStep ? {
2546
3002
  evm: { type: "uniswap_v4_liquidity_tx", version: 1, chainId: String(args.chainId) },
2547
3003
  uniswapV4Liquidity: {
2548
3004
  action: args.action,
2549
- skipPermit2Batch: true,
3005
+ skipPermit2Batch: !usePermit2,
3006
+ usePermit2Approvals: usePermit2,
3007
+ positionManagerKind,
2550
3008
  nftTokenId: args.nftTokenId != null ? String(args.nftTokenId) : void 0,
2551
3009
  poolReference: args.poolReference,
2552
3010
  lpResponseSnapshot: args.lpResponse,
@@ -2579,6 +3037,260 @@ async function buildEvmMultisignBodyUniswapV4DecreaseLiquidityBatch(args) {
2579
3037
  async function buildEvmMultisignBodyUniswapV4CollectFeesBatch(args) {
2580
3038
  return buildEvmMultisignBodyUniswapV4LiquidityBatchInternal({ ...args, action: "collect" });
2581
3039
  }
3040
+ var PERMISSIONED_LP_PRESETS = [
3041
+ // No public launch-partner presets hard-coded yet — use custom existingPool with hooks.
3042
+ ];
3043
+ function buildUniswapV4PermissionedLpPoolRow(args) {
3044
+ const chainId = parseUniswapChainId(args.chainId);
3045
+ const hooks = (args.hooks?.trim() ? getAddress(args.hooks.trim()) : tryGetUniswapV4PermissionedHooks(chainId)) ?? (() => {
3046
+ throw new Error(`No PermissionedHooks for chainId ${chainId}; pass hooks explicitly.`);
3047
+ })();
3048
+ const positionManager = tryGetUniswapV4PermissionedPositionManager(chainId);
3049
+ if (!positionManager) {
3050
+ throw new Error(`No Permissioned PositionManager for chainId ${chainId}.`);
3051
+ }
3052
+ const adapter = getAddress(args.adapterAddress);
3053
+ const other = getAddress(args.otherCurrencyAddress);
3054
+ const sorted = sortUniswapV4PoolCurrencies(adapter, other);
3055
+ const poolReference = computeUniswapV4PoolReference({
3056
+ token0Address: sorted.currency0,
3057
+ token1Address: sorted.currency1,
3058
+ fee: args.fee,
3059
+ tickSpacing: args.tickSpacing,
3060
+ hooks
3061
+ });
3062
+ return {
3063
+ presetId: args.presetId,
3064
+ pairSlug: args.pairSlug,
3065
+ pairLabel: args.pairLabel,
3066
+ fee: args.fee,
3067
+ feeLabel: args.feeLabel,
3068
+ tickSpacing: args.tickSpacing,
3069
+ token0Symbol: sorted.currency0 === adapter ? args.adapterSymbol ?? "v4PT" : args.otherSymbol ?? "TOKEN",
3070
+ token1Symbol: sorted.currency1 === adapter ? args.adapterSymbol ?? "v4PT" : args.otherSymbol ?? "TOKEN",
3071
+ token0Address: sorted.currency0,
3072
+ token1Address: sorted.currency1,
3073
+ poolReference,
3074
+ hooks,
3075
+ nativeWrapped: args.nativeWrapped ? getAddress(args.nativeWrapped) : void 0,
3076
+ usesNativeEth: Boolean(args.usesNativeEth),
3077
+ positionManagerKind: "permissioned",
3078
+ positionManager,
3079
+ underlyingPermissionedToken: args.underlyingPermissionedToken ? getAddress(args.underlyingPermissionedToken) : void 0,
3080
+ adapterAddress: adapter,
3081
+ issuer: args.issuer
3082
+ };
3083
+ }
3084
+ function listUniswapV4PermissionedLpPools(args) {
3085
+ const chainId = parseUniswapChainId(args.chainId);
3086
+ const positionManager = tryGetUniswapV4PermissionedPositionManager(chainId);
3087
+ const hooks = tryGetUniswapV4PermissionedHooks(chainId);
3088
+ if (!positionManager || !hooks) {
3089
+ return {
3090
+ chainId,
3091
+ chainLabel: `chain ${chainId}`,
3092
+ pools: [],
3093
+ positionManagerKind: "permissioned",
3094
+ notes: "No Permissioned PositionManager / PermissionedHooks configured for this chain. Ethereum mainnet (1) and Sepolia (11155111) are supported. Pass custom existingPool with adapter currency + hooks."
3095
+ };
3096
+ }
3097
+ let pools = PERMISSIONED_LP_PRESETS.filter(
3098
+ (p) => p.chainId === chainId
3099
+ ).map(
3100
+ (p) => buildUniswapV4PermissionedLpPoolRow({
3101
+ chainId,
3102
+ presetId: p.presetId,
3103
+ pairSlug: p.pairSlug,
3104
+ pairLabel: p.pairLabel,
3105
+ fee: p.fee,
3106
+ feeLabel: p.feeLabel,
3107
+ tickSpacing: p.tickSpacing,
3108
+ adapterAddress: p.adapterAddress,
3109
+ otherCurrencyAddress: p.otherCurrency,
3110
+ adapterSymbol: p.adapterSymbol,
3111
+ otherSymbol: p.otherSymbol,
3112
+ underlyingPermissionedToken: p.underlyingPermissionedToken,
3113
+ usesNativeEth: p.usesNativeEth,
3114
+ nativeWrapped: p.nativeWrapped,
3115
+ issuer: p.issuer,
3116
+ hooks
3117
+ })
3118
+ );
3119
+ const pairFilter = args.pair?.trim().toLowerCase();
3120
+ if (pairFilter) {
3121
+ pools = pools.filter(
3122
+ (row) => row.pairSlug.includes(pairFilter) || row.pairLabel.toLowerCase().includes(pairFilter) || row.presetId.includes(pairFilter)
3123
+ );
3124
+ }
3125
+ const chainLabel = PERMISSIONED_LP_PRESETS.find((p) => p.chainId === chainId)?.chainLabel ?? (chainId === 1 ? "Ethereum" : chainId === 11155111 ? "Sepolia" : `chain ${chainId}`);
3126
+ return {
3127
+ chainId,
3128
+ chainLabel,
3129
+ pools,
3130
+ positionManagerKind: "permissioned",
3131
+ notes: `Permissioned LP uses Permissioned Position Manager (UNI-V4-PERM-POSM) and PermissionedHooks. Pool currencies use the Permissions Adapter address, not the underlying token. Requires LIQUIDITY_ALLOWED on the wallet. Curated presets may be empty \u2014 pass existingPool with adapter + hooks + fee/tickSpacing. positionManager=${positionManager} hooks=${hooks}`
3132
+ };
3133
+ }
3134
+ function resolveUniswapV4PermissionedLpPoolPreset(args) {
3135
+ const listed = listUniswapV4PermissionedLpPools({ chainId: args.chainId });
3136
+ const preset = args.presetId.trim().toLowerCase();
3137
+ const row = listed.pools.find((p) => p.presetId.toLowerCase() === preset);
3138
+ if (!row) {
3139
+ throw new Error(
3140
+ `Unknown permissioned LP pool preset "${args.presetId}" on chainId ${listed.chainId}. Call ctm_uniswap_v4_list_lp_pools with permissioned=true, or pass custom existingPool.`
3141
+ );
3142
+ }
3143
+ return row;
3144
+ }
3145
+ function uniswapV4ListLpPools(args) {
3146
+ if (args.permissioned) {
3147
+ return listUniswapV4PermissionedLpPools(args);
3148
+ }
3149
+ const std = listUniswapV4StandardLpPools(args);
3150
+ return {
3151
+ ...std,
3152
+ positionManagerKind: "standard"
3153
+ };
3154
+ }
3155
+ function buildUniswapV4KycApplyLink(args) {
3156
+ const walletAddress = getAddress(args.walletAddress.trim());
3157
+ const chainId = parseUniswapChainId(args.chainId);
3158
+ const kycUrl = args.kycUrl.trim();
3159
+ if (!kycUrl) throw new Error("kycUrl is required");
3160
+ let token;
3161
+ let adapterTokenAddress;
3162
+ if (args.token?.trim()) {
3163
+ try {
3164
+ token = getAddress(args.token.trim());
3165
+ } catch {
3166
+ }
3167
+ }
3168
+ if (args.adapterTokenAddress?.trim()) {
3169
+ try {
3170
+ adapterTokenAddress = getAddress(args.adapterTokenAddress.trim());
3171
+ } catch {
3172
+ }
3173
+ }
3174
+ let applyUrl = kycUrl;
3175
+ try {
3176
+ const u = new URL(kycUrl);
3177
+ if (!u.searchParams.has("wallet") && !u.searchParams.has("address")) {
3178
+ u.searchParams.set("wallet", walletAddress);
3179
+ u.searchParams.set("address", walletAddress);
3180
+ }
3181
+ if (!u.searchParams.has("chainId")) u.searchParams.set("chainId", String(chainId));
3182
+ if (token && !u.searchParams.has("token")) u.searchParams.set("token", token);
3183
+ applyUrl = u.toString();
3184
+ } catch {
3185
+ applyUrl = kycUrl;
3186
+ }
3187
+ return {
3188
+ walletAddress,
3189
+ chainId,
3190
+ issuer: args.issuer?.trim() || void 0,
3191
+ kycUrl,
3192
+ applyUrl,
3193
+ token,
3194
+ adapterTokenAddress
3195
+ };
3196
+ }
3197
+ function pickUniswapV4KycTarget(results) {
3198
+ return results.find((r) => r.isPermissioned && !r.isAllowlisted && r.kycUrl) ?? results.find((r) => r.isPermissioned && r.kycUrl) ?? null;
3199
+ }
3200
+ function uniswapV4KycApplyLinkMcp(args) {
3201
+ return buildUniswapV4KycApplyLink(args);
3202
+ }
3203
+ var ALLOWLIST_FINALIZE_FALLBACK_GAS = 250000n;
3204
+ async function buildEvmMultisignBodyUniswapV4PermissionedAllowlistFinalize(args) {
3205
+ const to = getAddress(args.to.trim());
3206
+ let dataHex = (args.data ?? "0x").toString().trim();
3207
+ if (!dataHex.startsWith("0x")) dataHex = `0x${dataHex}`;
3208
+ if (dataHex.length < 10) {
3209
+ throw new Error("allowlist finalize `data` must be non-empty ABI-encoded calldata");
3210
+ }
3211
+ let value = 0n;
3212
+ if (args.valueWei != null && String(args.valueWei).trim() !== "") {
3213
+ try {
3214
+ value = BigInt(String(args.valueWei).trim());
3215
+ } catch {
3216
+ value = 0n;
3217
+ }
3218
+ }
3219
+ const steps = [
3220
+ {
3221
+ to,
3222
+ data: dataHex,
3223
+ value,
3224
+ fallbackGas: ALLOWLIST_FINALIZE_FALLBACK_GAS
3225
+ }
3226
+ ];
3227
+ const dataNo0x = dataHex.slice(2);
3228
+ const issuerLabel = args.issuer?.trim() || "issuer";
3229
+ return buildEvmMultisignBatch({
3230
+ context: {
3231
+ chainCategory: "evm",
3232
+ keyGen: args.keyGen,
3233
+ purposeText: args.purposeText,
3234
+ chainId: args.chainId,
3235
+ rpcUrl: args.rpcUrl,
3236
+ executorAddress: args.executorAddress,
3237
+ chainDetail: args.chainDetail,
3238
+ useCustomGas: args.useCustomGas,
3239
+ customGasChainDetails: args.customGasChainDetails
3240
+ },
3241
+ steps,
3242
+ purposeSuffix: `Uniswap V4 permissioned: 1-tx allowlist finalize (${issuerLabel}).`,
3243
+ firstMsgRawNo0x: dataNo0x,
3244
+ destinationAddress: to,
3245
+ buildBatchMeta: () => ({
3246
+ signatureText: JSON.stringify({
3247
+ kind: "UniswapV4PermissionedAllowlist",
3248
+ issuer: args.issuer,
3249
+ entityId: args.entityId != null ? String(args.entityId) : void 0
3250
+ }),
3251
+ evm: {
3252
+ type: "uniswap_v4_permissioned_allowlist",
3253
+ version: 1,
3254
+ chainId: String(args.chainId)
3255
+ },
3256
+ uniswapV4PermissionedAllowlist: {
3257
+ to,
3258
+ dataNibbles: dataNo0x.length,
3259
+ issuer: args.issuer,
3260
+ entityId: args.entityId != null ? String(args.entityId) : void 0,
3261
+ tokenAddress: args.tokenAddress,
3262
+ originalPurpose: args.purposeText
3263
+ }
3264
+ })
3265
+ });
3266
+ }
3267
+ function isUniswapV4PermissionedAllowlistEvmSignRequest(detail) {
3268
+ if (!detail) return false;
3269
+ const raw = detail.ExtraJSON ?? detail.extraJSON;
3270
+ let ex = null;
3271
+ if (raw && typeof raw === "object" && !Array.isArray(raw)) ex = raw;
3272
+ else if (typeof raw === "string" && raw.trim()) {
3273
+ try {
3274
+ const p = JSON.parse(raw);
3275
+ if (p && typeof p === "object" && !Array.isArray(p)) ex = p;
3276
+ } catch {
3277
+ return false;
3278
+ }
3279
+ }
3280
+ if (!ex) return false;
3281
+ const bm = ex.batchMeta;
3282
+ if (Array.isArray(bm) && bm[0] && typeof bm[0] === "object" && !Array.isArray(bm[0])) {
3283
+ const evm0 = bm[0].evm;
3284
+ if (evm0 && typeof evm0 === "object" && !Array.isArray(evm0)) {
3285
+ if (String(evm0.type ?? "") === "uniswap_v4_permissioned_allowlist") {
3286
+ return true;
3287
+ }
3288
+ }
3289
+ }
3290
+ const evm = ex.evm;
3291
+ if (!evm || typeof evm !== "object" || Array.isArray(evm)) return false;
3292
+ return String(evm.type ?? "") === "uniswap_v4_permissioned_allowlist";
3293
+ }
2582
3294
 
2583
3295
  // src/protocols/evm/uniswap-v4/support.ts
2584
3296
  function computeUniswapV4Session(args) {
@@ -2597,7 +3309,12 @@ function computeUniswapV4Session(args) {
2597
3309
  chainId: chainIdNum,
2598
3310
  rpcUrl,
2599
3311
  chainSupported,
2600
- universalRouter
3312
+ universalRouter,
3313
+ universalRouterV22: tryGetUniswapUniversalRouterV22(chainIdNum) ?? void 0,
3314
+ positionManager: tryGetUniswapV4PositionManager(chainIdNum) ?? void 0,
3315
+ permissionedPositionManager: tryGetUniswapV4PermissionedPositionManager(chainIdNum) ?? void 0,
3316
+ permissionedHooks: tryGetUniswapV4PermissionedHooks(chainIdNum) ?? void 0,
3317
+ permissionsAdapterFactory: tryGetUniswapV4PermissionsAdapterFactory(chainIdNum) ?? void 0
2601
3318
  };
2602
3319
  }
2603
3320
 
@@ -2888,6 +3605,28 @@ async function fetchUniswapV4PoolMeta(args) {
2888
3605
  );
2889
3606
  return data.pool ?? null;
2890
3607
  }
3608
+ var LATEST_SWAP_GQL = `
3609
+ query UniswapV4LatestSwap($pool: String!) {
3610
+ swaps(
3611
+ where: { pool: $pool }
3612
+ orderBy: timestamp
3613
+ orderDirection: desc
3614
+ first: 1
3615
+ ) {
3616
+ token0Price
3617
+ sqrtPriceX96
3618
+ }
3619
+ }`;
3620
+ async function fetchUniswapV4LatestSwap(args) {
3621
+ const pool = normalizePoolId(args.poolReference);
3622
+ const data = await postUniswapV4SubgraphGql(
3623
+ args.chainId,
3624
+ LATEST_SWAP_GQL,
3625
+ { pool },
3626
+ args.theGraphApiKey
3627
+ );
3628
+ return data.swaps?.[0] ?? null;
3629
+ }
2891
3630
 
2892
3631
  // src/protocols/evm/uniswap-v4/bitqueryApiKey.ts
2893
3632
  var BITQUERY_API_KEY_ENV = "BITQUERY_API_KEY";
@@ -3176,7 +3915,7 @@ function parseDecimal(raw) {
3176
3915
  const n = Number(raw);
3177
3916
  return Number.isFinite(n) && n > 0 ? n : null;
3178
3917
  }
3179
- function priceFromSwapRow(row) {
3918
+ function priceFromUniswapV4SwapRow(row) {
3180
3919
  const fromToken0 = parseDecimal(row.token0Price);
3181
3920
  if (fromToken0 != null) return fromToken0;
3182
3921
  const sqrt = row.sqrtPriceX96?.trim();
@@ -3198,7 +3937,7 @@ function bucketUniswapV4SwapsIntoCandles(args) {
3198
3937
  const buckets = /* @__PURE__ */ new Map();
3199
3938
  for (const swap of args.swaps) {
3200
3939
  const ts = Number(swap.timestamp);
3201
- const price = priceFromSwapRow(swap);
3940
+ const price = priceFromUniswapV4SwapRow(swap);
3202
3941
  if (!Number.isFinite(ts) || price == null) continue;
3203
3942
  const bucket = bucketStartSec(Math.floor(ts), args.bucketSec);
3204
3943
  const vol = parseDecimal(swap.amountUSD) ?? 0;
@@ -3539,6 +4278,74 @@ async function uniswapV4FetchOhlcv(args) {
3539
4278
  };
3540
4279
  }
3541
4280
 
4281
+ // src/protocols/evm/uniswap-v4/livePrice.ts
4282
+ function applyPriceQuote(price, quote) {
4283
+ if (!Number.isFinite(price) || price <= 0) return null;
4284
+ if (quote === "token1PerToken0") {
4285
+ const inverted = 1 / price;
4286
+ return Number.isFinite(inverted) && inverted > 0 ? inverted : null;
4287
+ }
4288
+ return price;
4289
+ }
4290
+ function bitqueryFilterFromPoolReference(poolReference) {
4291
+ const ref = poolReference.trim();
4292
+ if (!ref) return null;
4293
+ if (ref.startsWith("symbol:")) {
4294
+ return { kind: "symbol", symbol: ref.slice("symbol:".length).trim() };
4295
+ }
4296
+ if (ref.startsWith("0x")) {
4297
+ return { kind: "address", address: ref };
4298
+ }
4299
+ return null;
4300
+ }
4301
+ async function fetchUniswapV4BitqueryLatestClose(args) {
4302
+ const filter = bitqueryFilterFromPoolReference(args.poolReference);
4303
+ if (!filter) return null;
4304
+ const apiKey = resolveBitqueryApiKey(args.bitqueryApiKey);
4305
+ if (!apiKey) return null;
4306
+ const interval = args.interval?.trim() || "15m";
4307
+ const endTimeMs = Date.now();
4308
+ const startTimeMs = endTimeMs - 6 * 3600 * 1e3;
4309
+ const { candles } = await fetchRobinhoodBitqueryOhlcv({
4310
+ filter,
4311
+ interval,
4312
+ startTimeMs,
4313
+ endTimeMs,
4314
+ apiKey,
4315
+ limit: 5
4316
+ });
4317
+ if (candles.length === 0) return null;
4318
+ const last = candles[candles.length - 1];
4319
+ const close = Number(last.close);
4320
+ return Number.isFinite(close) && close > 0 ? close : null;
4321
+ }
4322
+ async function fetchUniswapV4ChartLivePrice(args) {
4323
+ const chainId = Math.floor(Number(args.chainId));
4324
+ if (!Number.isFinite(chainId) || chainId <= 0) return null;
4325
+ const poolReference = args.poolReference.trim();
4326
+ if (!poolReference) return null;
4327
+ const dataSource = String(args.dataSource ?? "").trim().toLowerCase();
4328
+ if (dataSource === "bitquery" || isRobinhoodOhlcvChain(chainId)) {
4329
+ return fetchUniswapV4BitqueryLatestClose({
4330
+ poolReference,
4331
+ interval: args.interval,
4332
+ bitqueryApiKey: args.bitqueryApiKey
4333
+ });
4334
+ }
4335
+ if (!uniswapV4SubgraphSupportedChainIds().includes(chainId)) {
4336
+ return null;
4337
+ }
4338
+ const row = await fetchUniswapV4LatestSwap({
4339
+ chainId,
4340
+ poolReference,
4341
+ theGraphApiKey: resolveTheGraphApiKey(args.theGraphApiKey)
4342
+ });
4343
+ if (!row) return null;
4344
+ const raw = priceFromUniswapV4SwapRow(row);
4345
+ if (raw == null) return null;
4346
+ return applyPriceQuote(raw, args.priceQuote);
4347
+ }
4348
+
3542
4349
  // src/protocols/evm/uniswap-v4/limitOrder.ts
3543
4350
  function trimAddr3(a) {
3544
4351
  return a.trim();
@@ -4032,6 +4839,6 @@ var uniswapV4 = {
4032
4839
  isChainSupported: isUniswapV4ChainSupported
4033
4840
  };
4034
4841
 
4035
- export { BITQUERY_API_KEY_DOCS_URL, BITQUERY_API_KEY_ENV, BITQUERY_API_KEY_SIGNUP_URL, BITQUERY_GRAPHQL_URL, DEFAULT_LIMIT_ORDER_QUOTE_PATH, DEFAULT_ORDER_SUBMIT_PATH, DEFAULT_UNISWAPX_ORDER_BASE, MAX_UINT160, MAX_UINT48, PERMIT2_ADDRESS, ROBINHOOD_CHAIN_ID, ROBINHOOD_WETH_ADDRESS, THE_GRAPH_API_KEY_DOCS_URL, THE_GRAPH_API_KEY_ENV, THE_GRAPH_API_KEY_SIGNUP_URL, UNISWAP_LIMIT_ORDER_CHAIN_ID, UNISWAP_LP_API_BASE_DEFAULT, UNISWAP_LP_DEFAULT_DEADLINE_SEC_OFFSET, UNISWAP_LP_DEFAULT_EXPIRY_MINUTES, UNISWAP_LP_DEFAULT_SLIPPAGE_PERCENT, UNISWAP_SWAP_DEFAULT_DEADLINE_SEC_OFFSET, UNISWAP_SWAP_DEFAULT_EXPIRY_MINUTES, UNISWAP_TRADE_BASE_DEFAULT, UNISWAP_UNIVERSAL_ROUTER_DEFAULT_GAS_UNITS, UNISWAP_UNIVERSAL_ROUTER_VERSION_DEFAULT, UNISWAP_V4_LP_COLLECT_DEFAULT_GAS_UNITS, UNISWAP_V4_LP_DECREASE_DEFAULT_GAS_UNITS, UNISWAP_V4_LP_ERC20_APPROVE_FALLBACK, UNISWAP_V4_LP_INCREASE_DEFAULT_GAS_UNITS, UNISWAP_V4_LP_LOG_CHUNK_SIZE_DEFAULT, UNISWAP_V4_LP_LOG_CHUNK_SIZE_MIN, UNISWAP_V4_LP_MINT_DEFAULT_GAS_UNITS, UNISWAP_V4_LP_POOL_LOOKUP_HINT, UNISWAP_V4_LP_POSITION_REGISTRY_HINT, UNISWAP_V4_LP_WETH_DEPOSIT_FALLBACK, UNISWAP_V4_OHLCV_INTERVALS, UNISWAP_V4_PROTOCOL_ID, UNISWAP_V4_SUBGRAPH_ID_BY_CHAIN_ID, aggregateOhlcvCandles, applySlippagePercentToApproveWei, assertUniswapLimitOrderChain, assertUniswapV4OhlcvInterval, bitqueryApiKeyVariablesHint, bitqueryAuthErrorMessage, buildEvmMultisignBodyUniswapV4CollectFeesBatch, buildEvmMultisignBodyUniswapV4DecreaseLiquidityBatch, buildEvmMultisignBodyUniswapV4IncreaseLiquidityBatch, buildEvmMultisignBodyUniswapV4LimitOrderBatch, buildEvmMultisignBodyUniswapV4LimitOrderBatchFromMcp, buildEvmMultisignBodyUniswapV4MintLiquidityBatch, buildEvmMultisignBodyUniswapV4SkipPermit2Batch, buildLimitOrderQuoteRequestBody, buildUniswapQuoteRequestBody, buildUniswapV4PurposePrefill, buildUniswapXLimitOrderSubmitBody, computeUniswapV4PoolReference, computeUniswapV4Session, createSwap, currencyFilterLabel, errorMessageFromUniswapJsonBody, extractPermitDataFromLimitQuote, extractUniswapLpTokenAmounts, extractUniswapLpTransaction, fetchEthereumAddressForKeyGen, fetchRobinhoodBitqueryOhlcv, fetchUniswapV4PoolDayDatas, fetchUniswapV4PoolHourDatas, fetchUniswapV4PoolMeta, fetchUniswapV4Swaps, fetchUniswapXLimitOrders, formatUniswapAmountFieldFromWei, formatUniswapLpAmountHuman, formatUniswapPercentForUi, formatUniswapQuoteForDisplay, formatUniswapV4PositionNotFoundError, getClassicQuoteFromStoredUniswapResponse, getUniswapUniversalRouterSpenderOrThrow, getUniswapUniversalRouterVersion, getUniswapV4PositionManagerDeployBlock, getUniswapV4PositionManagerOrThrow, isBitqueryAuthOrRateLimitError, isEthGetLogsBlockRangeTooLargeError, isNativeUniswapLpTokenAddress, isRobinhoodOhlcvChain, isTheGraphRateLimitOrAuthError, isUniswapFullQuoteResponseNativeIn, isUniswapFullQuoteResponseNativeOut, isUniswapLimitOrderChainSupported, isUniswapNativeTokenAddress, isUniswapTokenInAddressNative, isUniswapV4ChainSupported, isUniswapV4LiquidityEvmSignRequest, isUniswapV4SwapEvmSignRequest, listUniswapV4PositionsForWallet, listUniswapV4StandardLpPools, mapBitqueryOhlcvRowsToCandles, messageFromUniswapHttpResponseBody, parseUniswapChainId, parseUniswapLpApiSnapshot, parseUniswapQuoteClassicInOut, parseUniswapQuoteSlippageInfo, parseUniswapV4ScanFromDateYmd, permitDataToEip712Payload, quoteSwap, readUniswapV4PositionInfoRaw, requireBitqueryApiKey, resolveBitqueryApiKey, resolveBlockAtOrAfterUnixTime, resolveChainIdFromStoredUniswapQuote, resolveInputChainId, resolveRobinhoodChartCurrency, resolveRouterSwapGasUnitsFromSignRequest, resolveTheGraphApiKey, resolveUniswapV4LpExistingPoolFromKey, resolveUniswapV4LpPoolPreset, resolveUniswapV4OhlcvDataTier, resolveUniswapV4OhlcvPool, resolveUniswapV4PositionScanFromDate, sortUniswapV4PoolCurrencies, submitUniswapXLimitOrder, swapExactInput, swapFromQuote, swapTransactionDeadlineUnixFromExpiryMinutes, theGraphApiKeyVariablesHint, theGraphRateLimitErrorMessage, tryGetUniswapV4PositionManager, uniswapCreateSwap, uniswapFetchLimitOrdersMcp, uniswapLimitOrderQuote, uniswapLpClaimFees, uniswapLpCreatePosition, uniswapLpDecreasePosition, uniswapLpIncreasePosition, uniswapLpTxFieldForAction, uniswapQuoteToJsonQuoteOneLine, uniswapTradeQuote, uniswapV4, uniswapV4FetchOhlcv, uniswapV4ListPositionsForMcp, uniswapV4ListPositionsFromRegistryForMcp, uniswapV4ListPositionsRegistryMcpPlaceholder, uniswapV4ListStandardLpPools, uniswapV4OhlcvIntervalToBucketSec, uniswapV4OhlcvSupportedChainIds, uniswapV4PositionMintedTokenIdsFromReceipt, uniswapV4ProtocolModule, uniswapV4RegisterPositionFromMintTxPlaceholder, uniswapV4RegisterPositionNftPlaceholder, uniswapV4SubgraphIdForChain, uniswapV4SubgraphSupportedChainIds, uniswapV4SubgraphUrlForChain };
4842
+ export { BITQUERY_API_KEY_DOCS_URL, BITQUERY_API_KEY_ENV, BITQUERY_API_KEY_SIGNUP_URL, BITQUERY_GRAPHQL_URL, DEFAULT_LIMIT_ORDER_QUOTE_PATH, DEFAULT_ORDER_SUBMIT_PATH, DEFAULT_UNISWAPX_ORDER_BASE, MAX_UINT160, MAX_UINT48, PERMIT2_ADDRESS, ROBINHOOD_CHAIN_ID, ROBINHOOD_WETH_ADDRESS, THE_GRAPH_API_KEY_DOCS_URL, THE_GRAPH_API_KEY_ENV, THE_GRAPH_API_KEY_SIGNUP_URL, UNISWAP_LIMIT_ORDER_CHAIN_ID, UNISWAP_LP_API_BASE_DEFAULT, UNISWAP_LP_DEFAULT_DEADLINE_SEC_OFFSET, UNISWAP_LP_DEFAULT_EXPIRY_MINUTES, UNISWAP_LP_DEFAULT_SLIPPAGE_PERCENT, UNISWAP_SWAP_DEFAULT_DEADLINE_SEC_OFFSET, UNISWAP_SWAP_DEFAULT_EXPIRY_MINUTES, UNISWAP_TRADE_BASE_DEFAULT, UNISWAP_UNIVERSAL_ROUTER_DEFAULT_GAS_UNITS, UNISWAP_UNIVERSAL_ROUTER_VERSION_DEFAULT, UNISWAP_UNIVERSAL_ROUTER_VERSION_PERMISSIONED, UNISWAP_V4_LP_COLLECT_DEFAULT_GAS_UNITS, UNISWAP_V4_LP_DECREASE_DEFAULT_GAS_UNITS, UNISWAP_V4_LP_ERC20_APPROVE_FALLBACK, UNISWAP_V4_LP_INCREASE_DEFAULT_GAS_UNITS, UNISWAP_V4_LP_LOG_CHUNK_SIZE_DEFAULT, UNISWAP_V4_LP_LOG_CHUNK_SIZE_MIN, UNISWAP_V4_LP_MINT_DEFAULT_GAS_UNITS, UNISWAP_V4_LP_PERMIT2_APPROVE_FALLBACK, UNISWAP_V4_LP_POOL_LOOKUP_HINT, UNISWAP_V4_LP_POSITION_REGISTRY_HINT, UNISWAP_V4_LP_WETH_DEPOSIT_FALLBACK, UNISWAP_V4_OHLCV_INTERVALS, UNISWAP_V4_PERMISSION_FLAG_LIQUIDITY, UNISWAP_V4_PERMISSION_FLAG_SWAP, UNISWAP_V4_PROTOCOL_ID, UNISWAP_V4_SUBGRAPH_ID_BY_CHAIN_ID, UniswapV4PermissionDeniedError, aggregateOhlcvCandles, applySlippagePercentToApproveWei, assertUniswapLimitOrderChain, assertUniswapV4OhlcvInterval, assertUniswapV4PermissionsAllowlisted, bitqueryApiKeyVariablesHint, bitqueryAuthErrorMessage, buildEvmMultisignBodyUniswapV4CollectFeesBatch, buildEvmMultisignBodyUniswapV4DecreaseLiquidityBatch, buildEvmMultisignBodyUniswapV4IncreaseLiquidityBatch, buildEvmMultisignBodyUniswapV4LimitOrderBatch, buildEvmMultisignBodyUniswapV4LimitOrderBatchFromMcp, buildEvmMultisignBodyUniswapV4MintLiquidityBatch, buildEvmMultisignBodyUniswapV4PermissionedAllowlistFinalize, buildEvmMultisignBodyUniswapV4SkipPermit2Batch, buildLimitOrderQuoteRequestBody, buildUniswapQuoteRequestBody, buildUniswapV4KycApplyLink, buildUniswapV4PermissionedLpPoolRow, buildUniswapV4PurposePrefill, buildUniswapXLimitOrderSubmitBody, computeUniswapV4PoolReference, computeUniswapV4Session, createSwap, currencyFilterLabel, errorMessageFromUniswapJsonBody, extractPermitDataFromLimitQuote, extractUniswapLpTokenAmounts, extractUniswapLpTransaction, fetchEthereumAddressForKeyGen, fetchRobinhoodBitqueryOhlcv, fetchUniswapV4ChartLivePrice, fetchUniswapV4LatestSwap, fetchUniswapV4PoolDayDatas, fetchUniswapV4PoolHourDatas, fetchUniswapV4PoolMeta, fetchUniswapV4Swaps, fetchUniswapXLimitOrders, formatUniswapAmountFieldFromWei, formatUniswapLpAmountHuman, formatUniswapPercentForUi, formatUniswapQuoteForDisplay, formatUniswapV4PositionNotFoundError, getClassicQuoteFromStoredUniswapResponse, getUniswapUniversalRouterSpenderOrThrow, getUniswapUniversalRouterVersion, getUniswapV4PermissionedHooksOrThrow, getUniswapV4PermissionedPositionManagerOrThrow, getUniswapV4PermissionsAdapterFactoryOrThrow, getUniswapV4PositionManagerDeployBlock, getUniswapV4PositionManagerOrThrow, isBitqueryAuthOrRateLimitError, isEthGetLogsBlockRangeTooLargeError, isNativeUniswapLpTokenAddress, isRobinhoodOhlcvChain, isTheGraphRateLimitOrAuthError, isUniswapFullQuoteResponseNativeIn, isUniswapFullQuoteResponseNativeOut, isUniswapLimitOrderChainSupported, isUniswapNativeTokenAddress, isUniswapStoredQuotePermissioned, isUniswapTokenInAddressNative, isUniswapV4AnyPositionManager, isUniswapV4ChainSupported, isUniswapV4LiquidityEvmSignRequest, isUniswapV4PermissionedAllowlistEvmSignRequest, isUniswapV4PermissionedPositionManager, isUniswapV4SwapEvmSignRequest, listUniswapV4PermissionedLpPools, listUniswapV4PositionsForWallet, listUniswapV4StandardLpPools, mapBitqueryOhlcvRowsToCandles, messageFromUniswapHttpResponseBody, parseUniswapChainId, parseUniswapLpApiSnapshot, parseUniswapQuoteClassicInOut, parseUniswapQuoteSlippageInfo, parseUniswapV4ScanFromDateYmd, permitDataToEip712Payload, pickUniswapV4KycTarget, quoteSwap, readUniswapV4OnChainPermissionFlags, readUniswapV4PositionInfoRaw, requireBitqueryApiKey, resolveBitqueryApiKey, resolveBlockAtOrAfterUnixTime, resolveChainIdFromStoredUniswapQuote, resolveInputChainId, resolveRobinhoodChartCurrency, resolveRouterSwapGasUnitsFromSignRequest, resolveTheGraphApiKey, resolveUniswapV4LpExistingPoolFromKey, resolveUniswapV4LpPoolPreset, resolveUniswapV4OhlcvDataTier, resolveUniswapV4OhlcvPool, resolveUniswapV4PermissionedLpPoolPreset, resolveUniswapV4PositionManager, resolveUniswapV4PositionScanFromDate, sortUniswapV4PoolCurrencies, submitUniswapXLimitOrder, swapExactInput, swapFromQuote, swapTransactionDeadlineUnixFromExpiryMinutes, theGraphApiKeyVariablesHint, theGraphRateLimitErrorMessage, tryGetUniswapUniversalRouterV22, tryGetUniswapV4PermissionedHooks, tryGetUniswapV4PermissionedPositionManager, tryGetUniswapV4PermissionsAdapterFactory, tryGetUniswapV4PositionManager, uniswapCreateSwap, uniswapFetchLimitOrdersMcp, uniswapLimitOrderQuote, uniswapLpClaimFees, uniswapLpCreatePosition, uniswapLpDecreasePosition, uniswapLpIncreasePosition, uniswapLpTxFieldForAction, uniswapQuoteToJsonQuoteOneLine, uniswapTradeQuote, uniswapV4, uniswapV4CheckPermissions, uniswapV4CheckPermissionsMcp, uniswapV4FetchOhlcv, uniswapV4KycApplyLinkMcp, uniswapV4ListLpPools, uniswapV4ListPositionsForMcp, uniswapV4ListPositionsFromRegistryForMcp, uniswapV4ListPositionsRegistryMcpPlaceholder, uniswapV4ListStandardLpPools, uniswapV4OhlcvIntervalToBucketSec, uniswapV4OhlcvSupportedChainIds, uniswapV4PositionMintedTokenIdsFromReceipt, uniswapV4ProtocolModule, uniswapV4RegisterPositionFromMintTxPlaceholder, uniswapV4RegisterPositionNftPlaceholder, uniswapV4SubgraphIdForChain, uniswapV4SubgraphSupportedChainIds, uniswapV4SubgraphUrlForChain };
4036
4843
  //# sourceMappingURL=index.js.map
4037
4844
  //# sourceMappingURL=index.js.map