@continuumdao/ctm-mpc-defi 0.2.3 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/catalog.cjs +451 -31
- package/dist/agent/catalog.cjs.map +1 -1
- package/dist/agent/catalog.d.ts +938 -1
- package/dist/agent/catalog.js +432 -32
- package/dist/agent/catalog.js.map +1 -1
- package/dist/agent/skills/aave-v4/SKILL.md +120 -14
- package/dist/agent/skills/curve-dao/SKILL.md +125 -6
- package/dist/agent/skills/uniswap-v4/SKILL.md +195 -11
- package/dist/index.cjs +757 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +758 -5
- package/dist/index.js.map +1 -1
- package/dist/protocols/evm/curve-dao/index.cjs +15 -2
- package/dist/protocols/evm/curve-dao/index.cjs.map +1 -1
- package/dist/protocols/evm/curve-dao/index.js +15 -2
- package/dist/protocols/evm/curve-dao/index.js.map +1 -1
- package/dist/protocols/evm/uniswap-v4/index.cjs +1231 -1
- package/dist/protocols/evm/uniswap-v4/index.cjs.map +1 -1
- package/dist/protocols/evm/uniswap-v4/index.d.ts +366 -4
- package/dist/protocols/evm/uniswap-v4/index.js +1182 -3
- package/dist/protocols/evm/uniswap-v4/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/purpose.ts","../src/core/envelope.ts","../src/core/registry.ts","../src/core/defiProxy.ts","../src/chains/evm/types.ts","../src/chains/evm/routerSwapGas.ts","../src/chains/evm/buildBatch.ts","../src/chains/evm/chainIdParse.ts","../src/chains/evm/normalizeAmount.ts","../src/chains/evm/coingecko.ts","../src/chains/solana/types.ts","../src/chains/solana/index.ts","../src/chains/near/types.ts","../src/chains/near/index.ts","../src/protocols/evm/uniswap-v4/constants.ts","../src/protocols/evm/uniswap-v4/quote.ts","../src/protocols/evm/uniswap-v4/swapMultisign.ts","../src/protocols/evm/uniswap-v4/swap.ts","../src/protocols/evm/uniswap-v4/index.ts","../src/protocols/evm/curve-dao/support.ts","../src/protocols/evm/curve-dao/swapDestinations.ts","../src/protocols/evm/curve-dao/apiSession.ts","../src/protocols/evm/curve-dao/executeHelpers.ts","../src/protocols/evm/curve-dao/multisign.ts","../src/protocols/evm/curve-dao/index.ts","../src/index.ts"],"names":["getClientIdFromKeyGenResult","r","getAddress","zeroAddress","gasLimitFromEstimateAndChainConfig","defineChain","createPublicClient","http","fetchChainFeeParams","parseGwei","gweiToDecimalString","serializeTransaction","proposalTxParamsToFeeSnapshot","alignEip1559FeesWithLatestBase","keccak256","parseUnits","formatUnits","nodeFetchWithReadAuth","res","text","parsed","decodeFunctionData","encodeFunctionData","erc20Abi","isAddress","session","ETH_PLACEHOLDER","parseAbi"],"mappings":"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","file":"index.cjs","sourcesContent":["/** Merge user purpose text with an optional batch / protocol suffix. */\nexport function mergePurposeText(purposeText: string, purposeSuffix?: string): string {\n const t = purposeText.trim()\n const suffix = (purposeSuffix ?? '').trim()\n if (!suffix) return t\n return t ? `${t}\\n\\n${suffix}` : suffix\n}\n","import type { ChainCategory, MultisignBuildResult, KeyGenSubset } from './types.js'\nimport { getClientIdFromKeyGenResult } from '@continuumdao/continuum-node-sdk'\nimport { mergePurposeText } from './purpose.js'\n\nexport interface MultisignLeg {\n msgHash: string\n msgRaw: string\n destinationAddress: string\n signatureText: string\n audit: Record<string, unknown>\n feeSnapshot: Record<string, unknown>\n proposalTxParams?: Record<string, unknown>\n /** Payable value wei string for first leg only when relevant */\n valueWei?: bigint\n}\n\nexport interface ChainCategoryBuildInput {\n keyGen: KeyGenSubset\n purposeText: string\n purposeSuffix?: string\n destinationChainID: string\n legs: MultisignLeg[]\n extraJSON?: Record<string, unknown>\n /** Top-level destination address (first leg destination if omitted) */\n destinationAddress?: string\n}\n\nexport interface ChainCategoryModule {\n category: ChainCategory\n finalizeMultisign(input: ChainCategoryBuildInput): MultisignBuildResult\n}\n\n/**\n * Assemble mpc-auth `bodyForSign` from category-built legs.\n * Supports single-tx and batch (messageHashes / messageRawBatch / proposalTxParams).\n */\nexport function finalizeMultisign(input: ChainCategoryBuildInput): MultisignBuildResult {\n const { keyGen, destinationChainID, legs } = input\n if (legs.length === 0) {\n throw new Error('finalizeMultisign requires at least one leg')\n }\n\n const ph = (keyGen.pubkeyhex ?? '').trim()\n if (!ph) throw new Error('keyGen pubKey (pubkeyhex) is required')\n\n const keyList = keyGen.keylist ?? []\n const clientId = getClientIdFromKeyGenResult(keyGen)\n const first = legs[0]!\n\n const messageHashes = legs.map((l) => l.msgHash)\n const messageRawBatch = legs.map((l) => l.msgRaw)\n const batchMeta = legs.map((l) => ({\n destinationAddress: l.destinationAddress,\n signatureText: l.signatureText,\n ...l.audit,\n }))\n\n const proposalTxParams = legs\n .map((l) => l.proposalTxParams)\n .filter((p): p is Record<string, unknown> => p != null && typeof p === 'object')\n\n const extraPayload: Record<string, unknown> = {\n batchMeta,\n ...(input.extraJSON ?? {}),\n }\n const extraJSON = JSON.stringify(extraPayload)\n\n const bodyForSign: Record<string, unknown> = {\n keyList,\n pubKey: ph,\n msgHash: messageHashes[0],\n msgRaw: first.msgRaw,\n destinationChainID,\n destinationAddress: input.destinationAddress ?? first.destinationAddress,\n extraJSON,\n signatureText: first.signatureText,\n purpose: mergePurposeText(input.purposeText, input.purposeSuffix),\n ...first.feeSnapshot,\n }\n\n if (legs.length > 1) {\n bodyForSign.messageHashes = messageHashes\n bodyForSign.messageRawBatch = messageRawBatch\n }\n\n if (proposalTxParams.length > 0) {\n bodyForSign.proposalTxParams = proposalTxParams\n }\n\n const valueWei = first.valueWei\n if (valueWei != null && valueWei > 0n) {\n bodyForSign.value = valueWei.toString()\n }\n\n if (clientId) bodyForSign.clientId = clientId\n\n return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) }\n}\n\nexport const coreChainCategoryModule: ChainCategoryModule = {\n category: 'evm',\n finalizeMultisign,\n}\n","import type { ProtocolModule } from './types.js'\n\nconst modules: ProtocolModule[] = []\n\nexport function registerProtocolModule(mod: ProtocolModule): void {\n const existing = modules.findIndex((m) => m.id === mod.id)\n if (existing >= 0) {\n modules[existing] = mod\n } else {\n modules.push(mod)\n }\n}\n\nexport function getProtocolModules(): readonly ProtocolModule[] {\n return modules\n}\n\nexport function getProtocolModule(id: string): ProtocolModule | undefined {\n return modules.find((m) => m.id === id)\n}\n\nexport function getActionsByChainCategory(category: string): ProtocolModule['actions'] {\n return modules.filter((m) => m.chainCategory === category).flatMap((m) => m.actions)\n}\n","/**\n * Optional browser → Next.js API proxy paths for DeFi upstream calls.\n * Set once from continuumdao-node-app client bootstrap.\n */\n\nlet aaveGraphqlProxyUrl: string | undefined\nlet eulerGraphqlProxyUrl: string | undefined\nlet mapleGraphqlProxyUrl: string | undefined\nlet coingeckoProxyUrl: string | undefined\n\nexport function setAaveGraphqlProxyUrl(url: string | undefined): void {\n aaveGraphqlProxyUrl = url?.trim() || undefined\n}\n\nexport function getAaveGraphqlProxyUrl(): string | undefined {\n return aaveGraphqlProxyUrl\n}\n\nexport function setEulerGraphqlProxyUrl(url: string | undefined): void {\n eulerGraphqlProxyUrl = url?.trim() || undefined\n}\n\nexport function getEulerGraphqlProxyUrl(): string | undefined {\n return eulerGraphqlProxyUrl\n}\n\nexport function setMapleGraphqlProxyUrl(url: string | undefined): void {\n mapleGraphqlProxyUrl = url?.trim() || undefined\n}\n\nexport function getMapleGraphqlProxyUrl(): string | undefined {\n return mapleGraphqlProxyUrl\n}\n\nexport function setCoingeckoProxyUrl(url: string | undefined): void {\n coingeckoProxyUrl = url?.trim() || undefined\n}\n\nexport function getCoingeckoProxyUrl(): string | undefined {\n return coingeckoProxyUrl\n}\n\nexport async function postJsonViaOptionalProxy<T>(args: {\n directUrl: string\n body: unknown\n proxyUrl?: string\n proxyEnvelope?: unknown\n}): Promise<T> {\n const proxy = args.proxyUrl?.trim()\n if (proxy) {\n const r = await fetch(proxy, {\n method: 'POST',\n headers: {'content-type': 'application/json'},\n body: JSON.stringify(args.proxyEnvelope ?? args.body),\n })\n if (!r.ok) {\n const t = await r.text().catch(() => '')\n throw new Error(t ? `Proxy HTTP ${r.status}: ${t.slice(0, 200)}` : `Proxy HTTP ${r.status}`)\n }\n return (await r.json()) as T\n }\n const r = await fetch(args.directUrl, {\n method: 'POST',\n headers: {'content-type': 'application/json'},\n body: JSON.stringify(args.body),\n })\n if (!r.ok) {\n const t = await r.text().catch(() => '')\n throw new Error(t ? `HTTP ${r.status}: ${t.slice(0, 200)}` : `HTTP ${r.status}`)\n }\n return (await r.json()) as T\n}\n","import type { EvmTokenKind, MultisignCommonArgs } from '../../core/types.js'\nimport { getAddress, zeroAddress, type Address } from 'viem'\n\nexport type EvmChainDetail = {\n legacy?: boolean\n gasLimit?: number\n gasMultiplier?: number\n gasPrice?: number\n baseFee?: number\n priorityFee?: number\n baseFeeMultiplier?: number\n}\n\nexport interface EvmProtocolContext extends MultisignCommonArgs {\n chainCategory: 'evm'\n chainId: number\n rpcUrl: string\n executorAddress: Address\n chainDetail: EvmChainDetail\n useCustomGas: boolean\n customGasChainDetails?: Record<string, unknown> | null\n}\n\nexport type EvmTxStep = {\n to: Address\n data: `0x${string}`\n value: bigint\n /** Fallback when estimateGas reverts */\n fallbackGas?: bigint\n /** When set, use routerSwapGasLimitFromEstimate instead of plain estimate */\n routerSwap?: boolean\n}\n\nexport function isEvmNativeToken(address: string): boolean {\n try {\n return getAddress(address as `0x${string}`) === zeroAddress\n } catch {\n return address.toLowerCase() === zeroAddress\n }\n}\n\nexport function matchEvmTokenKind(\n kind: EvmTokenKind,\n address: string,\n): boolean {\n if (kind === 'native') return isEvmNativeToken(address)\n if (kind === 'erc20' || kind === 'ctmerc20' || kind === 'ctmrwa1') {\n return !isEvmNativeToken(address)\n }\n return true\n}\n","import { gasLimitFromEstimateAndChainConfig } from '@continuumdao/continuum-node-sdk'\n\n/** Curve router swap gas: chain cap when set, else 12/10 estimate bump. */\nexport function routerSwapGasLimitFromEstimate(\n estimatedGas: bigint,\n chainGasLimit?: number | null,\n): bigint {\n if (chainGasLimit != null && Number.isFinite(chainGasLimit) && chainGasLimit > 0) {\n return gasLimitFromEstimateAndChainConfig(estimatedGas, chainGasLimit)\n }\n return (estimatedGas * 12n + 9n) / 10n\n}\n","import {\n keccak256,\n createPublicClient,\n defineChain,\n http,\n serializeTransaction,\n getAddress,\n parseGwei,\n type Address,\n type PublicClient,\n} from 'viem'\nimport type { MultisignBuildResult } from '../../core/types.js'\nimport { finalizeMultisign, type MultisignLeg } from '../../core/envelope.js'\nimport type { KeyGenSubset } from '../../core/types.js'\nimport {\n fetchChainFeeParams,\n alignEip1559FeesWithLatestBase,\n gweiToDecimalString,\n gasLimitFromEstimateAndChainConfig,\n proposalTxParamsToFeeSnapshot,\n type ProposalTxParams,\n} from '@continuumdao/continuum-node-sdk'\nimport { routerSwapGasLimitFromEstimate } from './routerSwapGas.js'\nimport type { EvmProtocolContext, EvmTxStep } from './types.js'\n\nexport type EvmBatchMetaBuilder = (args: {\n step: EvmTxStep\n index: number\n gasLimit: bigint\n}) => Record<string, unknown>\n\nexport type EvmBuildBatchArgs = {\n context: EvmProtocolContext\n steps: EvmTxStep[]\n purposeSuffix?: string\n buildBatchMeta: EvmBatchMetaBuilder\n /** First leg msgRaw without 0x prefix; defaults to first step calldata */\n firstMsgRawNo0x?: string\n destinationAddress?: Address\n /** Top-level `value` on bodyForSign when the payable amount is not on the first leg */\n payableValueWei?: bigint\n resolveGasLimit?: (args: {\n step: EvmTxStep\n index: number\n estimatedGas: bigint\n publicClient: PublicClient\n }) => Promise<bigint> | bigint\n /** Override default `estimateGas` (e.g. trade-API gas, skip post-approve deposit estimate). */\n estimateGasForStep?: (args: {\n step: EvmTxStep\n index: number\n publicClient: PublicClient\n executor: Address\n }) => Promise<bigint> | bigint\n}\n\n/**\n * Build unsigned EVM txs, estimate gas, serialize, hash — then assemble mpc-auth body via core envelope.\n */\nexport async function buildEvmMultisignBatch(args: EvmBuildBatchArgs): Promise<MultisignBuildResult> {\n const { context, steps } = args\n const {\n chainId,\n rpcUrl,\n executorAddress,\n chainDetail,\n useCustomGas,\n customGasChainDetails,\n keyGen,\n purposeText,\n } = context\n\n if (steps.length === 0) throw new Error('buildEvmMultisignBatch requires at least one step')\n\n const ch = defineChain({\n id: chainId,\n name: 'Destination',\n nativeCurrency: { decimals: 18, name: 'Ether', symbol: 'ETH' },\n rpcUrls: { default: { http: [rpcUrl] } },\n })\n const publicClient = createPublicClient({ chain: ch, transport: http(rpcUrl) })\n\n const feeParams = await fetchChainFeeParams(rpcUrl, chainId)\n const legacy = Boolean(chainDetail?.legacy) || !feeParams.isEip1559\n const latestBaseFeeWei = !legacy\n ? ((await publicClient.getBlock({ blockTag: 'latest' })).baseFeePerGas ?? 0n)\n : 0n\n\n const gasLimitConfig =\n useCustomGas && chainDetail?.gasLimit != null ? Number(chainDetail.gasLimit) : undefined\n const chainGasLimitRouter =\n chainDetail?.gasLimit != null &&\n Number.isFinite(Number(chainDetail.gasLimit)) &&\n Number(chainDetail.gasLimit) > 0\n ? Number(chainDetail.gasLimit)\n : undefined\n const gasFeeMultiplier =\n useCustomGas && chainDetail?.gasMultiplier != null ? Number(chainDetail.gasMultiplier) : undefined\n\n const executor = getAddress(executorAddress)\n const baseNonce = await publicClient.getTransactionCount({ address: executor, blockTag: 'pending' })\n\n const legs: MultisignLeg[] = []\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]!\n const currentNonce = baseNonce + i\n\n let estimatedGas: bigint\n if (args.estimateGasForStep) {\n estimatedGas = await args.estimateGasForStep({ step, index: i, publicClient, executor })\n } else {\n try {\n estimatedGas = await publicClient.estimateGas({\n to: step.to,\n data: step.data,\n value: step.value,\n account: executor,\n })\n } catch {\n estimatedGas = step.fallbackGas ?? 100_000n\n }\n }\n\n let gasLimitI: bigint\n if (args.resolveGasLimit) {\n gasLimitI = await args.resolveGasLimit({ step, index: i, estimatedGas, publicClient })\n } else if (step.routerSwap) {\n gasLimitI = routerSwapGasLimitFromEstimate(estimatedGas, chainGasLimitRouter)\n } else {\n gasLimitI = useCustomGas\n ? gasLimitFromEstimateAndChainConfig(estimatedGas, gasLimitConfig)\n : estimatedGas\n }\n\n let proposalTxParams: ProposalTxParams\n let feeSnapshot: Record<string, unknown>\n let serialized: `0x${string}`\n\n if (legacy) {\n let gasPriceWei = await publicClient.getGasPrice()\n if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {\n gasPriceWei = (gasPriceWei * BigInt(100 + gasFeeMultiplier)) / 100n\n }\n if (useCustomGas && chainDetail?.gasPrice != null && chainDetail.gasPrice > 0) {\n const configured = parseGwei(gweiToDecimalString(Number(chainDetail.gasPrice)))\n if (configured > gasPriceWei) gasPriceWei = configured\n }\n serialized = serializeTransaction({\n type: 'legacy',\n to: step.to,\n data: step.data,\n value: step.value,\n gas: gasLimitI,\n gasPrice: gasPriceWei,\n nonce: currentNonce,\n chainId,\n })\n proposalTxParams = {\n nonce: currentNonce,\n gasLimit: gasLimitI.toString(),\n txType: 'legacy',\n gasPrice: gasPriceWei.toString(),\n }\n feeSnapshot = proposalTxParamsToFeeSnapshot(proposalTxParams)\n } else {\n const fetchedBase = feeParams.baseFeeGwei ?? 0\n const fetchedPriority = feeParams.priorityFeeGwei ?? 0\n const configuredBase =\n useCustomGas && chainDetail?.baseFee != null ? Number(chainDetail.baseFee) : 0\n const configuredPriority =\n useCustomGas && chainDetail?.priorityFee != null ? Number(chainDetail.priorityFee) : 0\n const effectiveBaseFeeGwei = Math.max(fetchedBase, configuredBase)\n const effectivePriorityFeeGwei = Math.max(fetchedPriority, configuredPriority)\n const baseFeeMultiplierPct =\n useCustomGas && chainDetail?.baseFeeMultiplier != null\n ? Math.max(100, Number(chainDetail.baseFeeMultiplier))\n : 100\n const baseComponentGwei = (effectiveBaseFeeGwei * baseFeeMultiplierPct) / 100\n const maxFeePerGasGwei = baseComponentGwei + effectivePriorityFeeGwei\n let maxPriorityFeePerGas =\n effectivePriorityFeeGwei > 0\n ? parseGwei(gweiToDecimalString(effectivePriorityFeeGwei))\n : parseGwei('1')\n let maxFeePerGas = parseGwei(gweiToDecimalString(maxFeePerGasGwei))\n if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {\n maxPriorityFeePerGas = (maxPriorityFeePerGas * BigInt(100 + gasFeeMultiplier)) / 100n\n maxFeePerGas = (maxFeePerGas * BigInt(100 + gasFeeMultiplier)) / 100n\n }\n ;({ maxFeePerGas, maxPriorityFeePerGas } = alignEip1559FeesWithLatestBase(\n maxFeePerGas,\n maxPriorityFeePerGas,\n latestBaseFeeWei,\n ))\n serialized = serializeTransaction({\n type: 'eip1559',\n to: step.to,\n data: step.data,\n value: step.value,\n gas: gasLimitI,\n maxFeePerGas,\n maxPriorityFeePerGas,\n nonce: currentNonce,\n chainId,\n })\n proposalTxParams = {\n nonce: currentNonce,\n gasLimit: gasLimitI.toString(),\n txType: 'eip1559',\n maxFeePerGas: maxFeePerGas.toString(),\n maxPriorityFeePerGas: maxPriorityFeePerGas.toString(),\n }\n feeSnapshot = i === 0 ? proposalTxParamsToFeeSnapshot(proposalTxParams) : {}\n }\n\n const h = keccak256(serialized)\n const msgHash = h.startsWith('0x') ? h.slice(2) : h\n\n const batchMetaExtra = args.buildBatchMeta({ step, index: i, gasLimit: gasLimitI })\n\n legs.push({\n msgHash,\n msgRaw: i === 0 && args.firstMsgRawNo0x != null ? args.firstMsgRawNo0x : serialized,\n destinationAddress: step.to,\n signatureText:\n typeof batchMetaExtra.signatureText === 'string'\n ? batchMetaExtra.signatureText\n : JSON.stringify(batchMetaExtra.signatureText ?? {}),\n audit: batchMetaExtra,\n feeSnapshot: i === 0 ? feeSnapshot : {},\n proposalTxParams,\n valueWei: i === 0 ? step.value : undefined,\n })\n\n if (i === 0 && args.firstMsgRawNo0x != null) {\n legs[0]!.msgRaw = args.firstMsgRawNo0x\n }\n }\n\n const extraJSON: Record<string, unknown> = {}\n if (useCustomGas && customGasChainDetails && Object.keys(customGasChainDetails).length > 0) {\n extraJSON.customGasChainDetails = customGasChainDetails\n }\n\n const result = finalizeMultisign({\n keyGen: keyGen as KeyGenSubset,\n purposeText,\n purposeSuffix: args.purposeSuffix,\n destinationChainID: String(chainId),\n destinationAddress: args.destinationAddress ?? steps[0]!.to,\n legs,\n extraJSON: Object.keys(extraJSON).length > 0 ? extraJSON : undefined,\n })\n const pv = args.payableValueWei\n if (pv != null && pv > 0n) {\n result.bodyForSign.value = pv.toString()\n }\n return result\n}\n\nexport const evmChainCategoryModule = {\n category: 'evm' as const,\n finalizeMultisign,\n buildEvmMultisignBatch,\n}\n","/** Parse chain id for comparisons (decimal, 0x hex, CAIP-2 eip155:N, bigint). */\nexport function parseEvmChainIdToNumber(chainId: string | number | bigint | null | undefined): number {\n if (chainId == null) return Number.NaN\n if (typeof chainId === 'bigint') {\n const n = Number(chainId)\n return Number.isSafeInteger(n) && n >= 0 ? n : Number.NaN\n }\n if (typeof chainId === 'number') {\n return Number.isInteger(chainId) && chainId >= 0 ? chainId : Number.NaN\n }\n const t = String(chainId).trim()\n if (!t) return Number.NaN\n const low = t.toLowerCase()\n if (low.startsWith('eip155:')) {\n const rest = t.slice('eip155:'.length).trim()\n const n = Number.parseInt(rest, 10)\n return Number.isNaN(n) || n < 0 ? Number.NaN : n\n }\n if (low.startsWith('0x')) {\n return Number.parseInt(t, 16)\n }\n return Number.parseInt(t, 10)\n}\n","import { formatUnits, parseUnits } from 'viem'\n\n/**\n * Canonical human decimal string for a token amount (truncate to token decimals via wei round-trip).\n * Used by Curve router and multisign dialogs across protocols.\n */\nexport function normalizeHumanDecimalAmount(raw: string, tokenDecimals: number): string {\n const t = raw.trim().replace(/,/g, '')\n if (!t) return ''\n if (!Number.isInteger(tokenDecimals) || tokenDecimals < 0 || tokenDecimals > 18) {\n throw new Error('Invalid token decimals for amount normalization.')\n }\n const wei = parseUnits(t, tokenDecimals)\n return formatUnits(wei, tokenDecimals)\n}\n\n/** @deprecated Prefer normalizeHumanDecimalAmount; kept for Curve router parity. */\nexport const normalizeCurveRouterAmountString = normalizeHumanDecimalAmount\n","/** CoinGecko asset platform id by mainnet chainId (contract price endpoint). */\nexport const COINGECKO_PLATFORM_BY_CHAIN_ID: Record<string, string> = {\n '1': 'ethereum',\n '56': 'binance-smart-chain',\n '137': 'polygon-pos',\n '42161': 'arbitrum-one',\n '10': 'optimistic-ethereum',\n '43114': 'avalanche',\n '8453': 'base',\n '324': 'zk-sync-era',\n '42220': 'celo',\n '250': 'fantom',\n '100': 'gnosis',\n '204': 'op-bnb',\n '534352': 'scroll',\n '5000': 'mantle',\n '169': 'manta-pacific',\n '1116': 'core',\n '30': 'rootstock',\n '288': 'boba',\n '1088': 'metis-andromeda',\n '34443': 'mode',\n '80084': 'berachain',\n '146': 'sonic',\n '60808': 'bob-network',\n '80094': 'berachain',\n '130': 'unichain',\n '57073': 'ink',\n '999': 'hyperevm',\n '239': 'tac',\n '9745': 'plasma',\n '1923': 'swellchain',\n '59144': 'linea',\n '81457': 'blast',\n '7777777': 'zora',\n}\n\nexport function coingeckoPlatformForChainId(chainId: string | number): string | undefined {\n return COINGECKO_PLATFORM_BY_CHAIN_ID[String(chainId).trim()]\n}\n","/** Solana signing defaults — mirrors app NonEvmChainDetailRow.signingDefaults. */\nexport type SolanaSigningDefaults = {\n commitment?: 'confirmed' | 'finalized'\n computeUnitLimit?: number\n priorityFeeMicroLamports?: number\n}\n\nexport type SolanaChainDetail = {\n chainType: 'solana'\n chainId: string\n chainName: string\n rpcGateway: string\n endpointKind: 'json-rpc'\n testnet: boolean\n nativeSymbol: string\n nativeDecimals: number\n signingDefaults?: SolanaSigningDefaults\n}\n\nexport interface SolanaProtocolContext {\n chainCategory: 'solana'\n chainId: string\n rpcGateway: string\n executorAddress: string\n chainDetail: SolanaChainDetail\n useCustomFees: boolean\n keyGen: import('../../core/types.js').KeyGenSubset\n purposeText: string\n}\n\nexport class NotImplementedError extends Error {\n constructor(feature: string) {\n super(`${feature} is not implemented yet for chain category solana`)\n this.name = 'NotImplementedError'\n }\n}\n\nexport async function buildSolanaMultisignBatch(): Promise<never> {\n throw new NotImplementedError('buildSolanaMultisignBatch')\n}\n\nexport const solanaChainCategoryModule = {\n category: 'solana' as const,\n}\n","export * from './types.js'\n\nexport const SOLANA_CHAIN_CATEGORY = 'solana' as const\n","export type NearSigningDefaults = {\n gasPriceYocto?: string\n}\n\nexport type NearChainDetail = {\n chainType: 'near'\n chainId: string\n chainName: string\n rpcGateway: string\n endpointKind: 'json-rpc'\n testnet: boolean\n nativeSymbol: string\n nativeDecimals: number\n signingDefaults?: NearSigningDefaults\n}\n\nexport interface NearProtocolContext {\n chainCategory: 'near'\n chainId: string\n rpcGateway: string\n executorAddress: string\n chainDetail: NearChainDetail\n useCustomFees: boolean\n keyGen: import('../../core/types.js').KeyGenSubset\n purposeText: string\n}\n\nexport class NotImplementedError extends Error {\n constructor(feature: string) {\n super(`${feature} is not implemented yet for chain category near`)\n this.name = 'NotImplementedError'\n }\n}\n\nexport async function buildNearMultisignBatch(): Promise<never> {\n throw new NotImplementedError('buildNearMultisignBatch')\n}\n\nexport const nearChainCategoryModule = {\n category: 'near' as const,\n}\n","export * from './types.js'\n\nexport const NEAR_CHAIN_CATEGORY = 'near' as const\n","import { getAddress, type Address } from 'viem'\nimport { parseEvmChainIdToNumber } from '../../../chains/evm/chainIdParse.js'\n\n/** Canonical Uniswap token-allowance contract on most EVM chains. */\nexport const PERMIT2_ADDRESS: Address = '0x000000000022D473030F116dDEE9F6B43aC78BA3'\n\nconst UNIVERSAL_ROUTER_SPENDER: Partial<Record<number, string>> = {\n 1: '0x66a9893cc07d91d95644aedd05d03f95e1dba8af',\n 5: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',\n 11155111: '0x3a9d48ab9751398bbfa63ad67599bb04e4bdf98b',\n 137: '0x1095692a6237d83c6a72f3f5efedb9a670c49223',\n 80001: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',\n 10: '0x851116d9223fabed8e56c0e6b8ad0c31d98b3507',\n 420: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',\n 42161: '0xa51afafe0263b40edaef0df8781ea9aa03e381a3',\n 421613: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',\n 42220: '0xcb695bc5D3Aa22cAD1E6DF07801b061a05A0233A',\n 44787: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',\n 56: '0x1906c1d672b88cd1b9ac7593301ca990f94eae07',\n 43114: '0x94b75331ae8d42c1b61065089b7d48fe14aa73b7',\n 84531: '0xd0872d928672ae2ff74bdb2f5130ac12229cafaf',\n 8453: '0x6fF5693b99212da76ad316178a184ab56d299b43',\n 81457: '0xeabbcb3e8e415306207ef514f660a3f820025be3',\n 7777777: '0x3315ef7ca28db74abadc6c44570efdf06b04b020',\n 324: '0x28731BCC616B5f51dD52CF2e4dF0E78dD1136C06',\n 480: '0x8ac7bee993bb44dab564ea4bc9ea67bf9eb5e743',\n 1301: '0xf70536b3bcc1bd1a972dc186a2cf84cc6da6be5d',\n 130: '0xef740bf23acae26f6492b10de645d6b98dc8eaf3',\n 10143: '0x3ae6d8a282d67893e17aa70ebffb33ee5aa65893',\n 84532: '0x492e6456d9528771018deb9e87ef7750ef184104',\n 1868: '0x0e2850543f69f678257266e0907ff9a58b3f13de',\n 143: '0x0d97dc33264bfc1c226207428a79b26757fb9dc3',\n 59144: '0x661e93cca42afacb172121ef892830ca3b70f08d',\n 4217: '0x1febb76be10aaf3a1402f04e8e835f2c382f7914',\n 196: '0x5507749f2c558bb3e162c6e90c314c092e7372ff',\n}\n\nexport function isUniswapV4ChainSupported(chainId: string | number | bigint | null | undefined): boolean {\n if (chainId == null) return false\n const n = parseEvmChainIdToNumber(chainId)\n if (Number.isNaN(n) || n < 0) return false\n const a = UNIVERSAL_ROUTER_SPENDER[n]\n return typeof a === 'string' && a.startsWith('0x')\n}\n\nexport function getUniswapUniversalRouterSpenderOrThrow(chainId: number): Address {\n const raw = UNIVERSAL_ROUTER_SPENDER[chainId]\n if (!raw || !raw.startsWith('0x')) {\n throw new Error(\n `No Uniswap Universal Router (spender) is configured for chainId ${chainId}. Add this chain to uniswap-v4/constants or use a chain supported by the Uniswap SDK.`,\n )\n }\n return getAddress(raw)\n}\n\nexport const MAX_UINT160 = (1n << 160n) - 1n\nexport const MAX_UINT48 = (1n << 48n) - 1n\n\nexport const UNISWAP_UNIVERSAL_ROUTER_DEFAULT_GAS_UNITS = 1_500_000n\nexport const UNISWAP_TRADE_BASE_DEFAULT = 'https://trade-api.gateway.uniswap.org/v1'\nexport const UNISWAP_UNIVERSAL_ROUTER_VERSION_DEFAULT = '2.0'\nexport const UNISWAP_SWAP_DEFAULT_EXPIRY_MINUTES = 30\nexport const UNISWAP_SWAP_DEFAULT_DEADLINE_SEC_OFFSET = UNISWAP_SWAP_DEFAULT_EXPIRY_MINUTES * 60\n","import { formatUnits, parseUnits, getAddress, zeroAddress } from 'viem'\nimport {\n nodeFetchWithReadAuth,\n type NodeReadAuth,\n} from '@continuumdao/continuum-node-sdk'\n\n/** POST /v1/quote `type` (same as `uniswap_trade_quote.py` `--type`). */\nexport type UniswapQuoteTradeType = 'EXACT_INPUT' | 'EXACT_OUTPUT'\n\nconst DEFAULT_TRADE_BASE = 'https://trade-api.gateway.uniswap.org/v1'\n\nconst UNISWAP_QUOTE_HEADERS_BASE: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'User-Agent': 'ctm-mpc-defi uniswapTradeQuote/1.0 (TS)',\n}\n\n/** Parse chain id like Python: decimal or 0x hex. */\nexport function parseUniswapChainId(value: string | number): number {\n if (typeof value === 'number') {\n if (!Number.isInteger(value) || value < 0) {\n throw new TypeError('chainId number must be a non-negative integer')\n }\n return value\n }\n const t = value.trim()\n if (t.toLowerCase().startsWith('0x')) {\n return Number.parseInt(t, 16)\n }\n return Number.parseInt(t, 10)\n}\n\nfunction trimAddr(a: string): string {\n return a.trim()\n}\n\n/** `tokenIn` is the EVM address `0x0` used by the Trade API for the chain’s native (gas) token. */\nexport function isUniswapTokenInAddressNative(tokenIn: string | undefined | null): boolean {\n const t = (tokenIn ?? '').toString().trim()\n if (!t) return false\n try {\n return getAddress(t as `0x${string}`) === zeroAddress\n } catch {\n return t.toLowerCase() === '0x0000000000000000000000000000000000000000'\n }\n}\n\n/** `fullQuote` / stored quote response: top-level or nested has `quote.input` with a native or ERC-20 address. */\nexport function isUniswapFullQuoteResponseNativeIn(\n stored: Record<string, unknown> | null | undefined,\n): boolean {\n if (!stored) return false\n const q = (stored as { quote?: unknown }).quote\n if (!q || typeof q !== 'object' || Array.isArray(q)) return false\n const input = (q as Record<string, unknown>).input as Record<string, unknown> | undefined\n if (!input) return false\n const raw = (input.address ?? (input as { token?: string }).token ?? '').toString().trim()\n return isUniswapTokenInAddressNative(raw)\n}\n\n/**\n * GET /getKeyGenResultById and return `ethereumaddress` (swapper), same as\n * `uniswap_mpc_helpers.resolve_owner_from_keygen` in mpc-config.\n */\nexport async function fetchEthereumAddressForKeyGen(\n managementNodeUrl: string,\n keyGenId: string,\n readAuth: NodeReadAuth = { bearerOnGet: true, jwt: null },\n init?: RequestInit\n): Promise<string> {\n const base = managementNodeUrl.trim().replace(/\\/$/, '')\n if (!base) {\n throw new Error('managementNodeUrl is required to resolve keyGen')\n }\n const id = (keyGenId || '').trim()\n if (!id) {\n throw new Error('keyGen is required')\n }\n const url = `${base}/getKeyGenResultById?id=${encodeURIComponent(id)}`\n const res = await nodeFetchWithReadAuth(url, { ...init, method: 'GET', cache: 'no-store' }, readAuth)\n if (!res.ok) {\n const t = await res.text().catch(() => '')\n throw new Error(\n `getKeyGenResultById HTTP ${res.status}: ${t || res.statusText}`.trim()\n )\n }\n const raw = (await res.json()) as {\n Data?: { ethereumaddress?: string; [k: string]: unknown }\n data?: { ethereumaddress?: string; [k: string]: unknown }\n }\n const d = raw.Data ?? raw.data\n const eth = d?.ethereumaddress\n if (typeof eth !== 'string' || !eth.trim()) {\n throw new Error('getKeyGenResultById: ethereumaddress missing for this keyGen')\n }\n return eth.trim()\n}\n\nexport interface UniswapTradeQuoteParams {\n amount: string\n tokenIn: string\n tokenOut: string\n uniswapApiKey: string\n /**\n * KeyGen id — used to resolve `swapper` from GET /getKeyGenResultById unless `swapper` is set.\n * Required unless `swapper` is set.\n */\n keyGen?: string\n type: UniswapQuoteTradeType\n /**\n * Slippage as percent, e.g. `0.5` for 0.5%. If omitted, the body uses\n * `autoSlippage: \"DEFAULT\"` (same as the Python script when `--slippage` is not set).\n */\n slippage?: number | string\n /**\n * Chain id for the input side (`tokenInChainId` in the HTTP body; Python `--chain-id`).\n * You may set **`chainId` or `tokenInChainId`** (same meaning); if both are set, `chainId` wins.\n * Same-chain quote: set one chain here and omit `tokenOutChainId` (or set both to the same id).\n */\n chainId?: string | number\n /**\n * Same as `chainId` (input chain). If `chainId` is omitted, this must be set.\n */\n tokenInChainId?: string | number\n /**\n * Output chain id; defaults to the input chain when omitted (Python: empty `--token-out-chain-id`).\n */\n tokenOutChainId?: string | number\n /**\n * When `true`, sends `x-permit2-disabled: true` (Uniswap’s header for classic ERC-20 allowance; no permitData in the response).\n * Omit or set `false` for the default Trade API routing (default).\n */\n permit2Disabled?: boolean\n /**\n * MPC wallet (swapper) address. If omitted, `managementNodeUrl` is used with `keyGen`\n * to call GET /getKeyGenResultById.\n */\n swapper?: `0x${string}` | string\n /**\n * Management node base URL (MPC), required when `swapper` is not provided.\n */\n managementNodeUrl?: string\n /** For Browser HTTPS: Bearer on GET to /getKeyGenResultById. */\n nodeReadAuth?: NodeReadAuth\n /** Trade API base without `/quote` (default: Uniswap gateway v1). */\n baseUrl?: string\n /** `x-universal-router-version` (default `2.0`, aligned with Python / v4). */\n universalRouterVersion?: string\n signal?: AbortSignal\n /** Override for tests. */\n fetchImpl?: typeof fetch\n}\n\n/**\n * Build the same JSON body as `uniswap_trade_quote.py` (minus `swapper`, which you must set).\n */\n/**\n * `tokenInChainId` in the HTTP body (Python `--chain-id`).\n * Order: `chainId`, then `tokenInChainId`, else if only `tokenOutChainId` is set use it\n * (same in/out, e.g. same-chain with a single id).\n */\nfunction resolveInputChainId(\n p: Pick<UniswapTradeQuoteParams, 'chainId' | 'tokenInChainId' | 'tokenOutChainId'>\n): string | number {\n if (p.chainId !== undefined && p.chainId !== null && String(p.chainId).trim() !== '') {\n return p.chainId\n }\n if (p.tokenInChainId !== undefined && p.tokenInChainId !== null && String(p.tokenInChainId).trim() !== '') {\n return p.tokenInChainId\n }\n if (p.tokenOutChainId !== undefined && p.tokenOutChainId !== null && String(p.tokenOutChainId).trim() !== '') {\n return p.tokenOutChainId\n }\n throw new Error('Set chainId, tokenInChainId, or tokenOutChainId (same-chain) for the input side')\n}\n\nexport function buildUniswapQuoteRequestBody(\n args: Pick<\n UniswapTradeQuoteParams,\n | 'type'\n | 'amount'\n | 'tokenIn'\n | 'tokenOut'\n | 'slippage'\n | 'chainId'\n | 'tokenInChainId'\n | 'tokenOutChainId'\n > & { swapper: string }\n): Record<string, unknown> {\n const cIn = parseUniswapChainId(resolveInputChainId(args))\n const cOut =\n args.tokenOutChainId !== undefined && args.tokenOutChainId !== null && String(args.tokenOutChainId).trim() !== ''\n ? parseUniswapChainId(args.tokenOutChainId)\n : cIn\n const body: Record<string, unknown> = {\n type: args.type,\n amount: String(args.amount).trim(),\n tokenInChainId: cIn,\n tokenOutChainId: cOut,\n tokenIn: trimAddr(args.tokenIn),\n tokenOut: trimAddr(args.tokenOut),\n swapper: trimAddr(args.swapper),\n }\n if (args.slippage !== undefined && args.slippage !== null && String(args.slippage).trim() !== '') {\n const s =\n typeof args.slippage === 'number' ? args.slippage : Number.parseFloat(String(args.slippage).trim())\n if (Number.isNaN(s)) {\n throw new TypeError('slippage must be a number or a numeric string')\n }\n body.slippageTolerance = s\n } else {\n body.autoSlippage = 'DEFAULT'\n }\n return body\n}\n\n/**\n * Pull a user-facing string from Uniswap / generic JSON error bodies.\n */\nexport function errorMessageFromUniswapJsonBody(value: unknown): string | null {\n if (value == null) return null\n if (typeof value === 'string') {\n const t = value.trim()\n return t || null\n }\n if (typeof value !== 'object') return null\n if (Array.isArray(value)) {\n if (value.length === 0) return null\n return errorMessageFromUniswapJsonBody(value[0])\n }\n const o = value as Record<string, unknown>\n /** Uniswap Trade API, e.g. 404: `{ errorCode, detail, requestId }` */\n if (typeof o.detail === 'string' && o.detail.trim()) {\n const base = o.detail.trim()\n const code = typeof o.errorCode === 'string' && o.errorCode.trim() ? o.errorCode.trim() : ''\n const req = typeof o.requestId === 'string' && o.requestId.trim() ? o.requestId.trim() : ''\n if (code) {\n return req ? `${base} (${code}) [${req}]` : `${base} (${code})`\n }\n return req ? `${base} [${req}]` : base\n }\n if (typeof o.errorCode === 'string' && o.errorCode.trim()) {\n return o.errorCode.trim()\n }\n for (const k of ['message', 'detail', 'description', 'title', 'reason']) {\n const v = o[k]\n if (typeof v === 'string' && v.trim()) return v.trim()\n }\n if (typeof o.error === 'string' && o.error.trim()) return o.error.trim()\n if (o.error != null && typeof o.error === 'object') {\n const inner = errorMessageFromUniswapJsonBody(o.error)\n if (inner) return inner\n }\n if (Array.isArray(o.errors) && o.errors.length > 0) {\n const inner = errorMessageFromUniswapJsonBody(o.errors[0])\n if (inner) return inner\n }\n if (typeof o.code === 'string' && o.code.trim()) return o.code.trim()\n return null\n}\n\nfunction bodyLooksLikeHtml(t: string): boolean {\n const s = t.slice(0, 256).trimStart()\n return s.startsWith('<!') || s.toLowerCase().startsWith('<html')\n}\n\nfunction titleFromHtml(t: string): string | null {\n const m = t.match(/<title[^>]*>([^<]+)<\\/title>/i)\n if (!m?.[1]) return null\n const s = m[1].replace(/\\s+/g, ' ').trim()\n return s || null\n}\n\n/**\n * User-facing string from an HTTP body: JSON `message` / `error` / `detail` first,\n * else a short plain-text / HTML page title, not the raw document (avoids huge HTML in UI).\n */\nexport function messageFromUniswapHttpResponseBody(\n text: string,\n status: number,\n statusText = ''\n): string {\n const raw = (text ?? '').trim()\n const st = (statusText ?? '').trim()\n if (!raw) {\n if (status > 0) {\n return st ? `HTTP ${status} (${st})` : `HTTP ${status}`\n }\n return 'Empty response'\n }\n if (bodyLooksLikeHtml(raw)) {\n const title = titleFromHtml(raw)\n if (title) {\n return status > 0 ? `HTTP ${status}: ${title}` : title\n }\n return status > 0\n ? 'HTTP ' +\n String(status) +\n ': response was not JSON (HTML or error page). Check API key, token pair, and network.'\n : 'Response was not JSON (HTML or error page).'\n }\n const forParse = raw.replace(/^\\uFEFF/, '')\n try {\n const j = JSON.parse(forParse) as unknown\n if (j && typeof j === 'object') {\n const msg = errorMessageFromUniswapJsonBody(j)\n if (msg) {\n if (status >= 400) {\n return st ? `${msg} (HTTP ${status} ${st})` : `${msg} (HTTP ${status})`\n }\n return msg\n }\n }\n } catch {\n /* not JSON */\n }\n const oneLine = raw.replace(/\\s+/g, ' ').trim()\n const short = oneLine.length > 500 ? `${oneLine.slice(0, 500)}…` : oneLine\n if (status > 0) {\n return st && !short ? `HTTP ${status} (${st})` : st ? `HTTP ${status}: ${short} (${st})` : `HTTP ${status}: ${short}`\n }\n return short\n}\n\n/**\n * `POST` Uniswap Trade API `/v1/quote` — TypeScript version of\n * `mpc-config/recipes/uniswapV4/uniswap_trade_quote.py` (core HTTP call + KeyGen → swapper).\n *\n * CORS: calling the Trade API from a browser may be blocked. Prefer a server / route\n * handler, or use this in Node. KeyGen resolution uses a GET to your management node\n * and follows the same read-auth pattern as the app.\n */\nexport async function uniswapTradeQuote(\n args: UniswapTradeQuoteParams\n): Promise<Record<string, unknown>> {\n const apiKey = (args.uniswapApiKey || '').trim()\n if (!apiKey) {\n throw new Error('uniswapApiKey (x-api-key) is required')\n }\n const keyGen = (args.keyGen || '').trim()\n\n let swapper: string\n if ((args.swapper || '').trim()) {\n swapper = trimAddr(args.swapper as string)\n } else {\n if (!keyGen) {\n throw new Error('keyGen is required when swapper is not provided')\n }\n const mpc = (args.managementNodeUrl || '').trim()\n if (!mpc) {\n throw new Error('managementNodeUrl is required when swapper is not provided (to resolve keyGen)')\n }\n swapper = await fetchEthereumAddressForKeyGen(\n mpc,\n keyGen,\n args.nodeReadAuth ?? { bearerOnGet: true, jwt: null }\n )\n }\n\n const base =\n (args.baseUrl && args.baseUrl.trim()) ? args.baseUrl.trim().replace(/\\/$/, '') : DEFAULT_TRADE_BASE\n const quoteUrl = `${base}/quote`\n const urv = (args.universalRouterVersion && args.universalRouterVersion.trim()) || '2.0'\n\n const body = buildUniswapQuoteRequestBody({ ...args, swapper })\n const nativeIn = isUniswapTokenInAddressNative(args.tokenIn)\n const headers: Record<string, string> = {\n ...UNISWAP_QUOTE_HEADERS_BASE,\n 'x-api-key': apiKey,\n 'x-universal-router-version': urv,\n 'x-permit2-disabled': args.permit2Disabled === true ? 'true' : 'false',\n /** Native (0x0) as token in: Trade API needs this for classic routes and payable /swap. */\n 'x-erc20eth-enabled': nativeIn ? 'true' : 'false',\n }\n\n const fetchFn = args.fetchImpl ?? globalThis.fetch\n const res = await fetchFn(quoteUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: args.signal,\n })\n const text = await res.text()\n if (!res.ok) {\n throw new Error(messageFromUniswapHttpResponseBody(text, res.status, res.statusText))\n }\n const forParse = text.replace(/^\\uFEFF/, '')\n try {\n return JSON.parse(forParse) as Record<string, unknown>\n } catch {\n throw new Error(\n `Trade API: ${messageFromUniswapHttpResponseBody(text, res.status, res.statusText)}`\n )\n }\n}\n\n/**\n * Single-line JSON for mpc-config `uniswap_trade_swap.py --quote-json` (compact quote body).\n */\nexport function uniswapQuoteToJsonQuoteOneLine(quote: Record<string, unknown>): string {\n return JSON.stringify(quote)\n}\n\n/**\n * `quote.input.amount` / `quote.output.amount` as bigints, if present (classic response).\n */\nexport function parseUniswapQuoteClassicInOut(\n res: Record<string, unknown>\n): { inputWei: bigint; outputWei: bigint } | null {\n const inner = res.quote\n if (!inner || typeof inner !== 'object' || Array.isArray(inner)) return null\n const q = inner as Record<string, unknown>\n const input = q.input as { amount?: string } | undefined\n const output = q.output as { amount?: string } | undefined\n const inAm = input?.amount\n const outAm = output?.amount\n if (typeof inAm !== 'string' || !inAm || typeof outAm !== 'string' || !outAm) return null\n try {\n return { inputWei: BigInt(inAm), outputWei: BigInt(outAm) }\n } catch {\n return null\n }\n}\n\n/**\n * Fields from Uniswap Trade API `200` `quote` (e.g. {@link https://api-docs.uniswap.org/api-reference/swapping/quote} `ClassicQuote`):\n * - `slippage` — slippage tolerance (percent) used for the quote\n * - `priceImpact` — “impact the trade has on the market price of the pool, between 0-100 percent”\n */\nexport function parseUniswapQuoteSlippageInfo(res: Record<string, unknown>): {\n slippageTolerancePercent: number | null\n priceImpactPercent: number | null\n} {\n const inner = res.quote\n if (!inner || typeof inner !== 'object' || Array.isArray(inner)) {\n return { slippageTolerancePercent: null, priceImpactPercent: null }\n }\n const q = inner as Record<string, unknown>\n const sRaw = q.slippage ?? q.slippageTolerance\n let slippageTolerancePercent: number | null = null\n if (typeof sRaw === 'number' && Number.isFinite(sRaw)) {\n slippageTolerancePercent = sRaw\n } else if (typeof sRaw === 'string' && sRaw.trim()) {\n const p = Number.parseFloat(sRaw.trim().replace(/,/g, ''))\n if (Number.isFinite(p)) slippageTolerancePercent = p\n }\n const piRaw = q.priceImpact\n let priceImpactPercent: number | null = null\n if (typeof piRaw === 'number' && Number.isFinite(piRaw)) {\n priceImpactPercent = piRaw\n } else if (typeof piRaw === 'string' && piRaw.trim()) {\n const p = Number.parseFloat(piRaw.trim().replace(/,/g, ''))\n if (Number.isFinite(p)) priceImpactPercent = p\n }\n return { slippageTolerancePercent, priceImpactPercent }\n}\n\n/** Compact percent for UI (e.g. 0.5, 1.2345). */\nexport function formatUniswapPercentForUi(n: number): string {\n if (!Number.isFinite(n)) return '—'\n const t = n.toFixed(4).replace(/\\.?0+$/, '')\n return t || '0'\n}\n\n/** Human string for a modal amount field, trimmed of trailing fraction zeros. */\nexport function formatUniswapAmountFieldFromWei(wei: bigint, decimals: number): string {\n const s = formatUnits(wei, decimals)\n if (!s.includes('.')) return s\n const t = s.replace(/0+$/, '')\n return t.endsWith('.') ? t.slice(0, -1) : t\n}\n\n/**\n * One-line prefill for multi-sign \"purpose\" (user may append context below in the same field).\n */\nexport function buildUniswapV4PurposePrefill(args: {\n tradeType: UniswapQuoteTradeType\n tokenInSymbol: string\n tokenOutSymbol: string\n tokenInDecimals: number\n tokenOutDecimals: number\n amountInput: string\n quote: Record<string, unknown> | null\n slippageInput: string\n chainName: string\n chainId: number\n}): string {\n const symIn = (args.tokenInSymbol || '').trim() || 'token in'\n const symOut = (args.tokenOutSymbol || '').trim() || 'token out'\n const rawS = String(args.slippageInput || '0.5').trim().replace(/,/g, '')\n const parsedSlip = Number.parseFloat(rawS)\n const slip = Number.isFinite(parsedSlip) ? parsedSlip : 0.5\n const slipText = (Math.round(slip * 100) / 100).toString()\n const p = args.quote != null ? parseUniswapQuoteClassicInOut(args.quote) : null\n let inPart = '…'\n let outPart = '…'\n if (p) {\n inPart = `${formatUniswapAmountFieldFromWei(p.inputWei, args.tokenInDecimals)} ${symIn}`.replace(/\\s+/g, ' ').trim()\n outPart = `${formatUniswapAmountFieldFromWei(p.outputWei, args.tokenOutDecimals)} ${symOut}`.replace(/\\s+/g, ' ').trim()\n } else if (args.tradeType === 'EXACT_INPUT' && args.amountInput.trim()) {\n try {\n const w = parseUnits(args.amountInput.trim(), args.tokenInDecimals)\n inPart = `${formatUniswapAmountFieldFromWei(w, args.tokenInDecimals)} ${symIn}`.replace(/\\s+/g, ' ').trim()\n outPart = `… ${symOut}`\n } catch {\n /* keep … */\n }\n }\n const cname = (args.chainName || '').trim() || 'chain'\n return `Swap ${inPart} for ${outPart} with a slippage of ${slipText}% on ${cname} (chainId ${args.chainId})`\n}\n\n/**\n * Human-readable lines from a Trade API `/quote` 200 JSON body.\n * Classic quotes expose `quote.input` / `quote.output` with `amount` (base units as string).\n */\nexport function formatUniswapQuoteForDisplay(\n res: Record<string, unknown>,\n args: {\n tradeType: UniswapQuoteTradeType\n tokenInDecimals: number\n tokenOutDecimals: number\n tokenInSymbol: string\n tokenOutSymbol: string\n }\n): { title: string; lines: string[]; rawJson: string } {\n const { tradeType, tokenInDecimals, tokenOutDecimals, tokenInSymbol, tokenOutSymbol } = args\n const rawJson = JSON.stringify(res, null, 2)\n const routing = typeof res.routing === 'string' ? res.routing : undefined\n const requestId = typeof res.requestId === 'string' ? res.requestId : undefined\n\n const inner = res.quote\n if (inner && typeof inner === 'object' && !Array.isArray(inner)) {\n const q = inner as Record<string, unknown>\n const input = q.input as { amount?: string; token?: string } | undefined\n const output = q.output as { amount?: string; token?: string } | undefined\n const inAm = input?.amount\n const outAm = output?.amount\n if (typeof inAm === 'string' && inAm && typeof outAm === 'string' && outAm) {\n try {\n const inH = formatUnits(BigInt(inAm), tokenInDecimals)\n const outH = formatUnits(BigInt(outAm), tokenOutDecimals)\n const title =\n tradeType === 'EXACT_INPUT'\n ? `≈ ${outH} ${tokenOutSymbol} for ${inH} ${tokenInSymbol} (est.)`\n : `≈ ${inH} ${tokenInSymbol} for ${outH} ${tokenOutSymbol} (est.)`\n const lines: string[] = [\n `Input: ${inH} ${tokenInSymbol} (${inAm} wei)`,\n `Output: ${outH} ${tokenOutSymbol} (${outAm} wei)`,\n ]\n if (routing) lines.push(`Route: ${routing}`)\n if (requestId) lines.push(`Request: ${requestId.slice(0, 24)}…`)\n return { title, lines, rawJson }\n } catch {\n // non-classic or bigint parse error\n }\n }\n }\n\n const lines: string[] = ['(Could not parse classic input/output; see raw JSON below.)']\n if (routing) lines.push(`Route: ${routing}`)\n if (requestId) lines.push(`Request: ${requestId}`)\n return { title: 'Quote received', lines, rawJson }\n}\n","import {\n getAddress,\n encodeFunctionData,\n decodeFunctionData,\n erc20Abi,\n zeroAddress,\n type Address,\n type PublicClient,\n} from 'viem'\nimport { type KeyGenSubsetForPermit } from '../../../core/types.js'\nimport { buildEvmMultisignBatch } from '../../../chains/evm/buildBatch.js'\nimport type { EvmTxStep } from '../../../chains/evm/types.js'\nimport {\n PERMIT2_ADDRESS,\n getUniswapUniversalRouterSpenderOrThrow,\n MAX_UINT160,\n MAX_UINT48,\n UNISWAP_TRADE_BASE_DEFAULT,\n UNISWAP_UNIVERSAL_ROUTER_VERSION_DEFAULT,\n UNISWAP_SWAP_DEFAULT_EXPIRY_MINUTES,\n UNISWAP_SWAP_DEFAULT_DEADLINE_SEC_OFFSET,\n UNISWAP_UNIVERSAL_ROUTER_DEFAULT_GAS_UNITS,\n} from './constants.js'\nimport {\n isUniswapFullQuoteResponseNativeIn,\n messageFromUniswapHttpResponseBody,\n parseUniswapQuoteClassicInOut,\n} from './quote.js'\n\n/** Parse `gasLimit` from Trade API or chain config (decimal or 0x hex). */\nfunction parseOptionalGasLimitString(raw: string | number | undefined): bigint | null {\n if (raw == null) return null\n const s = String(raw).trim()\n if (!s) return null\n try {\n if (/^0x[0-9a-fA-F]+$/.test(s)) return BigInt(s)\n return BigInt(s)\n } catch {\n return null\n }\n}\n\nfunction parseExtraJsonObject(\n detail: Record<string, unknown> | null | undefined\n): Record<string, unknown> | null {\n if (!detail) return null\n const raw = detail.ExtraJSON ?? detail.extraJSON\n if (raw == null) return null\n if (typeof raw === 'object' && !Array.isArray(raw)) return raw as Record<string, unknown>\n if (typeof raw === 'string' && raw.trim()) {\n try {\n const p = JSON.parse(raw) as unknown\n if (p && typeof p === 'object' && !Array.isArray(p)) return p as Record<string, unknown>\n } catch {\n return null\n }\n }\n return null\n}\n\nfunction uniswapV4EvmTypeFromBatchMeta(\n ex: Record<string, unknown> | null,\n batchIndex: number\n): boolean {\n if (!ex) return false\n const bm = ex.batchMeta\n if (!Array.isArray(bm) || !bm[batchIndex] || typeof bm[batchIndex] !== 'object' || Array.isArray(bm[batchIndex])) {\n return false\n }\n const evm0 = (bm[batchIndex] as Record<string, unknown>).evm\n if (!evm0 || typeof evm0 !== 'object' || Array.isArray(evm0)) return false\n return String((evm0 as Record<string, unknown>).type ?? '') === 'uniswap_v4_swap_tx'\n}\n\nfunction uniswapV4AuditFromDetail(\n ex: Record<string, unknown> | null,\n batchIndex?: number\n): Record<string, unknown> | undefined {\n if (!ex) return undefined\n const index = batchIndex != null && batchIndex >= 0 ? batchIndex : 0\n const bm = ex.batchMeta\n if (Array.isArray(bm) && bm[index] && typeof bm[index] === 'object' && !Array.isArray(bm[index])) {\n const nested = (bm[index] as Record<string, unknown>).uniswapV4\n if (nested && typeof nested === 'object' && !Array.isArray(nested)) {\n return nested as Record<string, unknown>\n }\n }\n const root = ex.uniswapV4\n if (root && typeof root === 'object' && !Array.isArray(root)) return root as Record<string, unknown>\n return undefined\n}\n\n/**\n * When `batchIndex` is set, check `batchMeta[i].evm`. Without `batchIndex`, also check `batchMeta[0]`\n * (native ETH-in single-tx requests store evm only under batchMeta, not top-level extraJSON.evm).\n */\nexport function isUniswapV4SwapEvmSignRequest(\n detail: Record<string, unknown> | null | undefined,\n batchIndex?: number\n): boolean {\n const ex = parseExtraJsonObject(detail)\n if (batchIndex != null && batchIndex >= 0) {\n if (uniswapV4EvmTypeFromBatchMeta(ex, batchIndex)) return true\n } else if (uniswapV4EvmTypeFromBatchMeta(ex, 0)) {\n return true\n }\n const evm = ex?.evm\n if (!evm || typeof evm !== 'object' || Array.isArray(evm)) return false\n return String((evm as Record<string, unknown>).type ?? '') === 'uniswap_v4_swap_tx'\n}\n\n/**\n * Gas units for Get Sig without `eth_estimateGas` (same calldata often reverts on estimate).\n * Order: proposal row[i] (or [0] / single `txParams`) / ExtraJSON uniswapV4 (audit, quote).\n * Pass `batchIndex` when the sign request is a multi-tx batch.\n */\nexport function resolveRouterSwapGasUnitsFromSignRequest(\n detail: Record<string, unknown> | null | undefined,\n batchIndex?: number\n): bigint | null {\n if (!detail) return null\n const propBatch = (detail.proposal_tx_params ??\n detail.proposalTxParams ??\n detail.ProposalTxParams) as unknown\n const index = batchIndex != null && batchIndex >= 0 ? batchIndex : 0\n if (Array.isArray(propBatch) && propBatch.length > index) {\n const row = propBatch[index]\n if (row && typeof row === 'object' && !Array.isArray(row)) {\n const r = row as Record<string, unknown>\n const gl = parseOptionalGasLimitString(\n (r.gas_limit ?? r.gasLimit ?? r.GasLimit) as string | number | undefined\n )\n if (gl != null && gl > 0n) return gl\n }\n }\n if (batchIndex == null || batchIndex === 0) {\n const tp = (detail.txParams ?? detail.TxParams) as Record<string, unknown> | undefined\n if (tp && typeof tp === 'object') {\n const gl = parseOptionalGasLimitString(\n (tp.gasLimit ?? tp.GasLimit ?? tp.txGasLimit) as string | number | undefined\n )\n if (gl != null && gl > 0n) return gl\n }\n }\n const ex = parseExtraJsonObject(detail)\n const u4 = uniswapV4AuditFromDetail(ex, batchIndex)\n if (u4) {\n const uc = u4.uniswapCreateSwap as Record<string, unknown> | undefined\n const gb = (uc?.gasBuildSwap ?? uc?.gasBuild) as Record<string, unknown> | undefined\n const base = parseOptionalGasLimitString(gb?.baseGasUnits as string | number | undefined)\n if (base != null && base > 0n) return base\n const snap = u4.fullQuoteFromPermitSnapshot as Record<string, unknown> | undefined\n const quote = snap?.quote as Record<string, unknown> | undefined\n const gue = parseOptionalGasLimitString(quote?.gasUseEstimate as string | number | undefined)\n if (gue != null && gue > 0n) return gue\n }\n return null\n}\n\n/**\n * Uniswap POST /swap `swap.gasLimit` is derived from the route; prefer it so we don't rely on\n * `eth_estimateGas`, which often reverts for Universal Router bundles (RPC simulation quirks).\n * When we must fall back, use a generous floor (L2s; adjust via chain `gasLimit` in app config).\n */\n/** Public for Get Sig when `eth_estimateGas` reverts on Universal Router calldata. */\nexport { UNISWAP_UNIVERSAL_ROUTER_DEFAULT_GAS_UNITS } from './constants.js'\nconst DEFAULT_UNIVERSAL_ROUTER_GAS_FALLBACK = UNISWAP_UNIVERSAL_ROUTER_DEFAULT_GAS_UNITS\n\nexport {\n UNISWAP_TRADE_BASE_DEFAULT,\n UNISWAP_UNIVERSAL_ROUTER_VERSION_DEFAULT,\n UNISWAP_SWAP_DEFAULT_EXPIRY_MINUTES,\n UNISWAP_SWAP_DEFAULT_DEADLINE_SEC_OFFSET,\n} from './constants.js'\n\n/** `deadline` = `now` + `expiryMinutes * 60` (seconds). */\nexport function swapTransactionDeadlineUnixFromExpiryMinutes(\n expiryMinutes: number,\n nowSec: number = Math.floor(Date.now() / 1000)\n): number {\n const m = Number.isFinite(expiryMinutes) && expiryMinutes > 0 ? expiryMinutes : UNISWAP_SWAP_DEFAULT_EXPIRY_MINUTES\n return nowSec + Math.floor(m * 60)\n}\n\nfunction swapDeadlineUnixSeconds(args: { swapTransactionDeadlineUnix?: number }): number {\n const now = Math.floor(Date.now() / 1000)\n if (\n args.swapTransactionDeadlineUnix != null &&\n Number.isFinite(args.swapTransactionDeadlineUnix) &&\n args.swapTransactionDeadlineUnix > now\n ) {\n return Math.floor(args.swapTransactionDeadlineUnix)\n }\n return swapTransactionDeadlineUnixFromExpiryMinutes(UNISWAP_SWAP_DEFAULT_EXPIRY_MINUTES, now)\n}\n\n/** The stored `uniswapTradeQuote` is the full `POST /quote` JSON; `/swap` wants the **inner** classic quote. */\nexport function getClassicQuoteFromStoredUniswapResponse(stored: Record<string, unknown> | null | undefined): unknown {\n if (!stored) return null\n const q = (stored as Record<string, unknown>).quote\n return q != null && typeof q === 'object' ? q : null\n}\n\ntype TransactionRequest = {\n to: string\n from?: string\n data: string\n value: string\n /** Trade API or eth-style field name */\n gasLimit?: string\n gas?: string\n chainId?: number\n}\n\ntype CreateSwapResponse = {\n requestId?: string\n swap: TransactionRequest\n gasFee?: string\n}\n\n/**\n * `POST /v1/swap` — builds swap calldata (Universal Router) from a quote fetched with classic-allowance header `x-permit2-disabled: true`.\n * @see https://api-docs.uniswap.org/api-reference/swapping/swap\n */\nexport async function uniswapCreateSwap(\n args: {\n uniswapApiKey: string\n baseUrl?: string\n /** Full `POST /quote` JSON (must include classic `quote`). */\n fullQuoteFromPermit: Record<string, unknown>\n universalRouterVersion?: string\n fetchImpl?: typeof fetch\n /**\n * In the browser, direct `POST` to `trade-api.gateway.uniswap.org` is blocked by CORS.\n * When true (default in browser), the request goes to same-origin `POST /api/uniswap/swap` which proxies server-side. Set `false` to force a direct call (e.g. tests, Node scripts).\n */\n useServerProxy?: boolean\n /**\n * Universal Router swap deadline (unix seconds). Defaults to now + {@link UNISWAP_SWAP_DEFAULT_DEADLINE_SEC_OFFSET}.\n * Omitting this caused short API defaults and `TransactionDeadlinePassed` after MPC delay.\n */\n swapTransactionDeadlineUnix?: number\n }\n): Promise<CreateSwapResponse> {\n const deadline = swapDeadlineUnixSeconds(args)\n const useProxy = (args.useServerProxy !== false) && typeof globalThis !== 'undefined' && typeof (globalThis as { window?: unknown }).window !== 'undefined'\n if (useProxy) {\n const proxyPayload: Record<string, unknown> = {\n uniswapApiKey: args.uniswapApiKey,\n fullQuoteFromPermit: args.fullQuoteFromPermit,\n universalRouterVersion: args.universalRouterVersion,\n baseUrl: args.baseUrl,\n swapTransactionDeadlineUnix: deadline,\n }\n const res = await (args.fetchImpl ?? globalThis.fetch)('/api/uniswap/swap', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(proxyPayload),\n credentials: 'same-origin',\n })\n const text = await res.text()\n if (!res.ok) {\n let errMsg = res.statusText\n try {\n const j = JSON.parse(text) as { error?: string }\n if (j && typeof j.error === 'string' && j.error.trim()) errMsg = j.error.trim()\n } catch {\n if (text.trim()) errMsg = text.slice(0, 500)\n }\n throw new Error(`Uniswap swap proxy failed: ${errMsg}`)\n }\n const parsed = JSON.parse(text) as CreateSwapResponse\n if (!parsed?.swap || typeof parsed.swap !== 'object') {\n throw new Error('Uniswap /swap (proxy): missing `swap` in response.')\n }\n return parsed\n }\n const base = (args.baseUrl ?? UNISWAP_TRADE_BASE_DEFAULT).replace(/\\/$/, '')\n const url = `${base}/swap`\n const classic = getClassicQuoteFromStoredUniswapResponse(args.fullQuoteFromPermit) as Record<string, unknown> | null\n if (!classic) {\n throw new Error('Stored Uniswap quote is missing a classic `quote` object; cannot build swap calldata.')\n }\n const body: Record<string, unknown> = {\n quote: classic,\n deadline,\n }\n const urv = (args.universalRouterVersion ?? UNISWAP_UNIVERSAL_ROUTER_VERSION_DEFAULT).trim() || '2.0'\n const fn = args.fetchImpl ?? globalThis.fetch\n const nativeIn = isUniswapFullQuoteResponseNativeIn(args.fullQuoteFromPermit)\n const res = await fn(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': args.uniswapApiKey.trim(),\n 'x-universal-router-version': urv,\n 'x-erc20eth-enabled': nativeIn ? 'true' : 'false',\n 'x-permit2-disabled': 'true',\n },\n body: JSON.stringify(body),\n })\n const text = await res.text()\n if (!res.ok) {\n throw new Error(\n `Uniswap POST /swap failed: ${messageFromUniswapHttpResponseBody(text, res.status, res.statusText)}`\n )\n }\n const parsed = JSON.parse(text) as CreateSwapResponse\n if (!parsed?.swap || typeof parsed.swap !== 'object') {\n throw new Error('Uniswap /swap: missing `swap` in response.')\n }\n return parsed\n}\n\ntype ChainRow = {\n legacy?: boolean\n gasLimit?: number\n gasMultiplier?: number\n gasPrice?: number\n baseFee?: number\n priorityFee?: number\n baseFeeMultiplier?: number\n}\n\nasync function estimateUniswapRouterSwapGas(args: {\n publicClient: PublicClient\n executor: Address\n to: Address\n data: `0x${string}`\n value: bigint\n swapRecord: Record<string, unknown>\n useCustomGas: boolean\n chainDetail: ChainRow\n}): Promise<{\n baseGasUnits: bigint\n source: 'tradeApi' | 'rpcEstimate' | 'estimateFailedFallback'\n estimateGasError?: string\n}> {\n const fromTradeApi =\n parseOptionalGasLimitString(args.swapRecord.gasLimit as string | number | undefined) ??\n parseOptionalGasLimitString(args.swapRecord.gas as string | number | undefined)\n if (fromTradeApi != null && fromTradeApi > 0n) {\n return { baseGasUnits: fromTradeApi, source: 'tradeApi' }\n }\n try {\n const est = await args.publicClient.estimateGas({\n to: args.to,\n data: args.data,\n value: args.value,\n account: args.executor,\n })\n return { baseGasUnits: est, source: 'rpcEstimate' }\n } catch (e) {\n const estimateGasError = e instanceof Error ? e.message : String(e)\n const minRouterGas = 500_000n\n if (args.useCustomGas) {\n const cfg =\n args.chainDetail?.gasLimit != null\n ? parseOptionalGasLimitString(String(args.chainDetail.gasLimit))\n : null\n if (cfg != null && cfg >= minRouterGas) {\n return { baseGasUnits: cfg, source: 'estimateFailedFallback', estimateGasError }\n }\n }\n return {\n baseGasUnits: DEFAULT_UNIVERSAL_ROUTER_GAS_FALLBACK,\n source: 'estimateFailedFallback',\n estimateGasError,\n }\n }\n}\n\nconst permit2ApproveRouterAbi = [\n {\n name: 'approve',\n type: 'function',\n stateMutability: 'nonpayable',\n inputs: [\n { name: 'token', type: 'address' },\n { name: 'spender', type: 'address' },\n { name: 'amount', type: 'uint160' },\n { name: 'expiration', type: 'uint48' },\n ],\n outputs: [],\n },\n] as const\n\n/**\n * Trade `POST /swap` often returns calldata for `execute(router, token, amount, commands, inputs, deadline)` (dispatcher\n * entry). The **router** argument is the allowance-hub **spender**; the **amount** can exceed `quote.input.amount` (slippage /\n * route). We must approve at least that amount and the correct spender.\n */\nconst uniswapDispatchExecuteAbi = [\n {\n name: 'execute',\n type: 'function',\n stateMutability: 'payable',\n inputs: [\n { name: 'router', type: 'address' },\n { name: 'token', type: 'address' },\n { name: 'amount', type: 'uint256' },\n { name: 'commands', type: 'bytes' },\n { name: 'inputs', type: 'bytes[]' },\n { name: 'deadline', type: 'uint256' },\n ],\n outputs: [],\n },\n] as const\n\n/** Parse payable `value` wei from Trade API `swap` (string hex/decimal, `Value`, or finite JSON number). */\nfunction parseSwapTxValueWei(swap: Record<string, unknown>): bigint {\n const raw = swap.value ?? swap.Value\n if (raw == null || raw === '') return 0n\n if (typeof raw === 'bigint') return raw > 0n ? raw : 0n\n if (typeof raw === 'number' && Number.isFinite(raw)) {\n try {\n return BigInt(Math.max(0, Math.trunc(raw)))\n } catch {\n return 0n\n }\n }\n const s = String(raw).trim()\n if (!s) return 0n\n try {\n if (/^0x[0-9a-fA-F]+$/.test(s)) return BigInt(s)\n return BigInt(s.replace(/^0x/i, ''))\n } catch {\n return 0n\n }\n}\n\n/**\n * Native ETH–in payable amount: prefer `swap.value` from POST /swap; if missing/zero, use dispatcher\n * `execute(..., amount, ...)` from calldata (Trade API sometimes omits top-level `value`); else classic quote input wei.\n */\nfunction nativeEthInPayableValueWei(args: {\n swap: TransactionRequest\n dataHex: `0x${string}`\n quoteInputWei: bigint\n}): bigint {\n const fromApi = parseSwapTxValueWei(args.swap as Record<string, unknown>)\n if (fromApi > 0n) return fromApi\n try {\n const d = decodeFunctionData({ abi: uniswapDispatchExecuteAbi, data: args.dataHex })\n if (d.functionName === 'execute') {\n const rawAmt = d.args[2]\n const amount = typeof rawAmt === 'bigint' ? rawAmt : BigInt(String(rawAmt))\n if (amount > 0n) return amount\n }\n } catch {\n /* calldata is not dispatcher `execute` */\n }\n return args.quoteInputWei > 0n ? args.quoteInputWei : 0n\n}\n\n/**\n * Apply UI slippage % on top of the base approve amount (EXACT_OUTPUT only at call sites; basis points, ceil wei).\n * Example: 0.5% → multiply by 1.005 (10050/10000). `undefined` / non‑positive leaves `baseWei` unchanged.\n */\nexport function applySlippagePercentToApproveWei(baseWei: bigint, slippagePercent: number | undefined): bigint {\n if (baseWei <= 0n) return baseWei\n const s = slippagePercent == null ? NaN : Number(slippagePercent)\n if (!Number.isFinite(s) || s <= 0) return baseWei\n const bps = Math.min(100_000, Math.round(s * 100))\n if (bps <= 0) return baseWei\n return (baseWei * BigInt(10_000 + bps) + 9_999n) / 10_000n\n}\n\nfunction permit2SpenderAndApproveWeiFromSwapCalldata(\n dataHex: `0x${string}`,\n tokenIn: Address,\n quoteInputWei: bigint,\n chainId: number\n): { permit2Spender: Address; approveWei: bigint; calldataAmountWei: bigint | null } {\n const canonical = getUniswapUniversalRouterSpenderOrThrow(chainId)\n try {\n const d = decodeFunctionData({ abi: uniswapDispatchExecuteAbi, data: dataHex })\n if (d.functionName !== 'execute') {\n return { permit2Spender: canonical, approveWei: quoteInputWei, calldataAmountWei: null }\n }\n const router = getAddress(d.args[0] as Address)\n const token = getAddress(d.args[1] as Address)\n const rawAmt = d.args[2]\n const amount = typeof rawAmt === 'bigint' ? rawAmt : BigInt(String(rawAmt))\n if (token.toLowerCase() !== tokenIn.toLowerCase()) {\n throw new Error(\n `Swap calldata token ${token} does not match token in ${tokenIn}. Refresh quote and /swap.`\n )\n }\n const calldataAmountWei = amount > 0n ? amount : null\n let approveWei = quoteInputWei\n if (calldataAmountWei != null && calldataAmountWei > approveWei) {\n approveWei = calldataAmountWei\n }\n return { permit2Spender: router, approveWei, calldataAmountWei }\n } catch (e) {\n if (e instanceof Error && e.message.includes('does not match token')) throw e\n return { permit2Spender: canonical, approveWei: quoteInputWei, calldataAmountWei: null }\n }\n}\n\ntype UniswapV4SkipPermit2BatchArg = {\n keyGen: KeyGenSubsetForPermit\n chainId: number\n rpcUrl: string\n chainDetail: ChainRow\n useCustomGas: boolean\n customGasChainDetails?: Record<string, unknown> | null\n /** `0x0` = native (ETH) in; otherwise ERC-20. */\n tokenIn: Address\n executorAddress: Address\n swap: TransactionRequest\n createSwapResponse: { requestId?: string; gasFee?: string; swap: TransactionRequest }\n fullQuoteSnapshot: Record<string, unknown>\n purposeText: string\n swapDeadlineUnix: number\n slippagePercent?: number\n}\n\n/**\n * **Native (ETH) input** — a single **payable** swap tx from `POST /swap` (`swap.value` > 0). No `approve` (no ERC-20 for token in).\n */\nasync function buildEvmMultisignBodyUniswapV4NativeInOnly(\n args: UniswapV4SkipPermit2BatchArg,\n quoteInputWei: bigint,\n): Promise<{ bodyForSign: Record<string, unknown>; messageToSign: string }> {\n const toRouter = getAddress(\n (args.swap.to ?? '').trim().startsWith('0x') ? (args.swap.to.trim() as `0x${string}`) : `0x${args.swap.to.trim()}`,\n )\n const dataHex = (() => {\n const d = (args.swap.data ?? '0x').toString().trim()\n return d.startsWith('0x') ? d : `0x${d}`\n })() as `0x${string}`\n\n const valueWei = nativeEthInPayableValueWei({\n swap: args.swap,\n dataHex,\n quoteInputWei,\n })\n if (valueWei <= 0n) {\n throw new Error(\n 'Native (ETH) in swap: could not determine payable value (no `swap.value`, no `execute` amount in calldata, and quote input is zero). Refresh the quote and request /swap again.',\n )\n }\n\n const swapRecord = args.swap as Record<string, unknown>\n let gasBuildSource: 'tradeApi' | 'rpcEstimate' | 'estimateFailedFallback' = 'rpcEstimate'\n let estimateGasError: string | undefined\n let swapBaseGasUnits = DEFAULT_UNIVERSAL_ROUTER_GAS_FALLBACK\n\n const dataNo0x = dataHex.startsWith('0x') ? dataHex.slice(2) : dataHex\n const purposeSuffix =\n 'Uniswap V4: 1-tx batch — native gas token in (no ERC-20 approve) — single payable swap (Trade /swap).'\n\n return buildEvmMultisignBatch({\n context: {\n chainCategory: 'evm',\n keyGen: args.keyGen,\n purposeText: args.purposeText,\n chainId: args.chainId,\n rpcUrl: args.rpcUrl,\n executorAddress: args.executorAddress,\n chainDetail: args.chainDetail,\n useCustomGas: args.useCustomGas,\n customGasChainDetails: args.customGasChainDetails,\n },\n steps: [\n {\n to: toRouter,\n data: dataHex,\n value: valueWei,\n routerSwap: true,\n fallbackGas: DEFAULT_UNIVERSAL_ROUTER_GAS_FALLBACK,\n },\n ],\n purposeSuffix,\n firstMsgRawNo0x: dataNo0x,\n destinationAddress: toRouter,\n estimateGasForStep: async ({ publicClient, executor }) => {\n const r = await estimateUniswapRouterSwapGas({\n publicClient,\n executor,\n to: toRouter,\n data: dataHex,\n value: valueWei,\n swapRecord,\n useCustomGas: args.useCustomGas,\n chainDetail: args.chainDetail,\n })\n gasBuildSource = r.source\n estimateGasError = r.estimateGasError\n swapBaseGasUnits = r.baseGasUnits\n return r.baseGasUnits\n },\n buildBatchMeta: () => ({\n signatureText: JSON.stringify({\n kind: 'UniswapV4',\n name: 'UniversalRouter (payable, native in)',\n note: 'Single tx from Trade POST /swap; no ERC-20 approve. Calldata in messageHashes[0] / messageRawBatch[0].',\n }),\n evm: { type: 'uniswap_v4_swap_tx', version: 1, chainId: String(args.chainId) },\n uniswapV4: {\n skipPermit2Batch: true,\n inputKind: 'native_eth',\n noErc20Approve: true,\n quoteInputWei: quoteInputWei.toString(),\n swapValueWei: valueWei.toString(),\n uniswapCreateSwap: {\n requestId: args.createSwapResponse.requestId,\n gasFee: args.createSwapResponse.gasFee,\n gasBuildSwap: {\n useCustomGas: args.useCustomGas,\n source: gasBuildSource,\n baseGasUnits: swapBaseGasUnits.toString(),\n ...(estimateGasError != null && estimateGasError !== '' ? { estimateGasError } : {}),\n },\n swap: {\n to: args.createSwapResponse.swap.to,\n value: args.createSwapResponse.swap.value,\n dataNibbles: (() => {\n const t = (args.createSwapResponse.swap.data ?? '').toString().trim()\n return t.startsWith('0x') ? t.length - 2 : t.length\n })(),\n },\n },\n fullQuoteFromPermitSnapshot: args.fullQuoteSnapshot,\n originalPurpose: args.purposeText,\n },\n }),\n })\n}\n\n/**\n * **Classic ERC-20 allowance** batch (on-chain approvals only), two shapes:\n *\n * - **`swap.to` == inner `router` (calldata arg)** — Universal Router is the tx target; tokens move via the **allowance hub**:\n * `ERC20→hub`, hub `approve(router)`, swap (3 txs).\n *\n * - **`swap.to` ≠ inner `router`** — Trade uses a **dispatcher** that calls `ERC20.transferFrom` with **`msg.sender` = `swap.to`**.\n * Approving only the hub is insufficient (`cast run` shows `transfer amount exceeds allowance`). Path:\n * `ERC20.approve(swap.to)`, swap (2 txs).\n *\n * Approved amount: `max(quote.input, calldata amount)`; with **EXACT_OUTPUT** trades, multiply by `(1 + slippage%)` from the quote modal (input can grow vs the quoted figure).\n */\nexport async function buildEvmMultisignBodyUniswapV4SkipPermit2Batch(\n args: UniswapV4SkipPermit2BatchArg,\n): Promise<{ bodyForSign: Record<string, unknown>; messageToSign: string }> {\n const tokenIn = getAddress(args.tokenIn)\n const parsedInOut = parseUniswapQuoteClassicInOut(args.fullQuoteSnapshot)\n const quoteInputWei = parsedInOut?.inputWei\n if (quoteInputWei == null || quoteInputWei <= 0n) {\n throw new Error(\n 'Could not read a positive input amount from the quote. Refresh the quote and ensure the Trade API returned classic quote.input.amount.',\n )\n }\n\n if (tokenIn === zeroAddress) {\n return buildEvmMultisignBodyUniswapV4NativeInOnly(args, quoteInputWei)\n }\n\n const toRouter = getAddress(\n (args.swap.to ?? '').trim().startsWith('0x') ? (args.swap.to.trim() as `0x${string}`) : `0x${args.swap.to.trim()}`,\n )\n const dataHex = (() => {\n const d = (args.swap.data ?? '0x').toString().trim()\n return d.startsWith('0x') ? d : `0x${d}`\n })() as `0x${string}`\n\n const canonicalUniversalRouter = getUniswapUniversalRouterSpenderOrThrow(args.chainId)\n const { permit2Spender, approveWei: baseApproveWei, calldataAmountWei } = permit2SpenderAndApproveWeiFromSwapCalldata(\n dataHex,\n tokenIn,\n quoteInputWei,\n args.chainId,\n )\n const approveAmountWei = applySlippagePercentToApproveWei(baseApproveWei, args.slippagePercent)\n const usePermit2Triple = toRouter.toLowerCase() === permit2Spender.toLowerCase()\n if (usePermit2Triple && approveAmountWei > MAX_UINT160) {\n throw new Error('Approved transfer amount exceeds allowance-hub uint160 max; reduce trade size.')\n }\n\n let expiration48 = 0n\n if (usePermit2Triple) {\n const deadlineSec = Math.floor(Number(args.swapDeadlineUnix))\n if (!Number.isFinite(deadlineSec) || deadlineSec <= 0) {\n throw new Error('Invalid swapDeadlineUnix for allowance-hub approve expiration.')\n }\n expiration48 = BigInt(deadlineSec)\n if (expiration48 > MAX_UINT48) expiration48 = MAX_UINT48\n }\n\n const erc20ApproveSpender: Address = usePermit2Triple ? PERMIT2_ADDRESS : toRouter\n const approveData = encodeFunctionData({\n abi: erc20Abi,\n functionName: 'approve',\n args: [erc20ApproveSpender, approveAmountWei],\n }) as `0x${string}`\n const valueWei = (() => {\n const v = args.swap.value\n if (v == null || v === '') return 0n\n try {\n return BigInt(String(v).replace(/^0x/i, ''))\n } catch {\n return 0n\n }\n })()\n\n const swapRecord = args.swap as Record<string, unknown>\n const swapMsgIndex = usePermit2Triple ? 2 : 1\n let gasBuildSource: 'tradeApi' | 'rpcEstimate' | 'estimateFailedFallback' = 'rpcEstimate'\n let estimateGasError: string | undefined\n let swapBaseGasUnits = DEFAULT_UNIVERSAL_ROUTER_GAS_FALLBACK\n\n const steps: EvmTxStep[] = [\n { to: tokenIn, data: approveData, value: 0n, fallbackGas: 100_000n },\n ]\n if (usePermit2Triple) {\n const permit2ApproveData = encodeFunctionData({\n abi: permit2ApproveRouterAbi,\n functionName: 'approve',\n args: [tokenIn, permit2Spender, approveAmountWei, Number(expiration48)],\n }) as `0x${string}`\n steps.push({ to: PERMIT2_ADDRESS, data: permit2ApproveData, value: 0n, fallbackGas: 100_000n })\n }\n steps.push({\n to: toRouter,\n data: dataHex,\n value: valueWei,\n routerSwap: true,\n fallbackGas: DEFAULT_UNIVERSAL_ROUTER_GAS_FALLBACK,\n })\n\n const swapStepIndex = steps.length - 1\n const approveMsgRawNo0x = approveData.startsWith('0x') ? approveData.slice(2) : approveData\n const purposeSuffix = usePermit2Triple\n ? 'Uniswap V4: 3-tx batch (classic allowance) — (1) ERC-20 approve allowance hub, (2) hub approve(Universal Router), (3) swap (Trade /swap).'\n : 'Uniswap V4: 2-tx batch (classic allowance, dispatcher) — (1) ERC-20 approve swap.to (dispatcher pulls tokens), (2) swap (Trade /swap).'\n\n const buildSwapAudit = (): Record<string, unknown> => ({\n skipPermit2Batch: true,\n approvalPath: usePermit2Triple ? 'permit2_triple' : 'dispatcher',\n approveAmount: {\n baseWeiBeforeSlippage: baseApproveWei.toString(),\n finalWei: approveAmountWei.toString(),\n slippagePercent: args.slippagePercent,\n quoteInputWei: quoteInputWei.toString(),\n ...(calldataAmountWei != null ? { swapCalldataAmountWei: calldataAmountWei.toString() } : {}),\n },\n uniswapCreateSwap: {\n requestId: args.createSwapResponse.requestId,\n gasFee: args.createSwapResponse.gasFee,\n gasBuildSwap: {\n useCustomGas: args.useCustomGas,\n source: gasBuildSource,\n baseGasUnits: swapBaseGasUnits.toString(),\n ...(estimateGasError != null && estimateGasError !== '' ? { estimateGasError } : {}),\n },\n swap: {\n to: args.createSwapResponse.swap.to,\n value: args.createSwapResponse.swap.value,\n dataNibbles: (() => {\n const d = args.createSwapResponse.swap.data ?? ''\n const t = d.toString().trim()\n return t.startsWith('0x') ? t.length - 2 : t.length\n })(),\n },\n },\n fullQuoteFromPermitSnapshot: args.fullQuoteSnapshot,\n originalPurpose: args.purposeText,\n innerRouterFromCalldata: permit2Spender,\n swapToEqualsInnerRouter: usePermit2Triple,\n ...(usePermit2Triple\n ? {\n permit2Erc20Approve: {\n token: tokenIn,\n spender: PERMIT2_ADDRESS,\n amountWei: approveAmountWei.toString(),\n note: 'ERC-20 → allowance hub before hub approve(router).',\n },\n permit2ApproveUniversalRouter: {\n permit2: PERMIT2_ADDRESS,\n token: tokenIn,\n spender: permit2Spender,\n canonicalUniversalRouterFromAppMap: canonicalUniversalRouter,\n spenderMatchesCanonicalMap: permit2Spender.toLowerCase() === canonicalUniversalRouter.toLowerCase(),\n amountWei: approveAmountWei.toString(),\n expiration: expiration48.toString(),\n note: 'Allowance-hub spender must match the router in swap calldata.',\n },\n }\n : {\n erc20ApproveDispatcher: {\n token: tokenIn,\n spender: toRouter,\n amountWei: approveAmountWei.toString(),\n note:\n 'Dispatcher pulls via ERC20.transferFrom(user, universalRouter, amount); allowance must be on swap.to (see cast trace TRANSFER_FROM_FAILED when only the hub is approved).',\n },\n }),\n })\n\n return buildEvmMultisignBatch({\n context: {\n chainCategory: 'evm',\n keyGen: args.keyGen,\n purposeText: args.purposeText,\n chainId: args.chainId,\n rpcUrl: args.rpcUrl,\n executorAddress: args.executorAddress,\n chainDetail: args.chainDetail,\n useCustomGas: args.useCustomGas,\n customGasChainDetails: args.customGasChainDetails,\n },\n steps,\n purposeSuffix,\n firstMsgRawNo0x: approveMsgRawNo0x,\n destinationAddress: tokenIn,\n payableValueWei: valueWei > 0n ? valueWei : undefined,\n estimateGasForStep: async ({ step, index, publicClient, executor }) => {\n if (index !== swapStepIndex) {\n return publicClient.estimateGas({\n to: step.to,\n data: step.data,\n value: step.value,\n account: executor,\n })\n }\n const r = await estimateUniswapRouterSwapGas({\n publicClient,\n executor,\n to: toRouter,\n data: dataHex,\n value: valueWei,\n swapRecord,\n useCustomGas: args.useCustomGas,\n chainDetail: args.chainDetail,\n })\n gasBuildSource = r.source\n estimateGasError = r.estimateGasError\n swapBaseGasUnits = r.baseGasUnits\n return r.baseGasUnits\n },\n buildBatchMeta: ({ index }) => {\n if (index === 0) {\n return {\n signatureText: JSON.stringify({\n kind: 'UniswapV4',\n name: 'ERC20.approve',\n to: usePermit2Triple ? 'allowance hub' : 'dispatcher(swap.to)',\n function: 'approve(address spender, uint256 amount)',\n spender: erc20ApproveSpender,\n amountWei: approveAmountWei.toString(),\n }),\n evm: {\n type: usePermit2Triple ? 'uniswap_v4_skip_permit2_approve' : 'uniswap_v4_skip_permit2_dispatcher_approve',\n version: 1,\n chainId: String(args.chainId),\n ...(usePermit2Triple ? { permit2: PERMIT2_ADDRESS } : { dispatcher: toRouter }),\n },\n }\n }\n if (usePermit2Triple && index === 1) {\n return {\n signatureText: JSON.stringify({\n kind: 'UniswapV4',\n name: 'AllowanceHub.approve',\n function: 'approve(address token, address spender, uint160 amount, uint48 expiration)',\n token: tokenIn,\n spender: permit2Spender,\n amountWei: approveAmountWei.toString(),\n expiration: expiration48.toString(),\n }),\n evm: {\n type: 'uniswap_v4_skip_permit2_permit2_approve',\n version: 1,\n chainId: String(args.chainId),\n permit2: PERMIT2_ADDRESS,\n permit2Spender,\n },\n }\n }\n return {\n signatureText: JSON.stringify({\n kind: 'UniswapV4',\n name: 'UniversalRouter.execute',\n note: `Calldata from Trade API POST /swap; signed tx hash in messageHashes[${swapMsgIndex}].`,\n }),\n evm: { type: 'uniswap_v4_swap_tx', version: 1, chainId: String(args.chainId) },\n uniswapV4: buildSwapAudit(),\n }\n },\n })\n}\n","import type { Address } from 'viem'\nimport type { EvmChainDetail } from '../../../chains/evm/types.js'\nimport type { KeyGenSubsetForPermit } from '../../../core/types.js'\nimport type { UniswapQuoteTradeType } from './quote.js'\nimport { uniswapTradeQuote } from './quote.js'\nimport { uniswapCreateSwap, buildEvmMultisignBodyUniswapV4SkipPermit2Batch } from './swapMultisign.js'\nimport { swapTransactionDeadlineUnixFromExpiryMinutes } from './swapMultisign.js'\n\nexport type SwapExactInputArgs = {\n keyGen: KeyGenSubsetForPermit\n purposeText: string\n chainId: number\n rpcUrl: string\n executorAddress: Address\n chainDetail: EvmChainDetail\n useCustomGas: boolean\n customGasChainDetails?: Record<string, unknown> | null\n tokenIn: Address\n uniswapApiKey: string\n fullQuote: Record<string, unknown>\n slippagePercent?: number\n swapTransactionDeadlineUnix?: number\n baseUrl?: string\n}\n\n/** Quote then build swap multisign body for EXACT_INPUT (caller must have fetched quote first for EXACT_OUTPUT). */\nexport async function swapFromQuote(args: SwapExactInputArgs & { swap: Awaited<ReturnType<typeof uniswapCreateSwap>> }) {\n const deadline =\n args.swapTransactionDeadlineUnix ??\n swapTransactionDeadlineUnixFromExpiryMinutes(30)\n return buildEvmMultisignBodyUniswapV4SkipPermit2Batch({\n keyGen: args.keyGen,\n chainId: args.chainId,\n rpcUrl: args.rpcUrl,\n chainDetail: args.chainDetail,\n useCustomGas: args.useCustomGas,\n customGasChainDetails: args.customGasChainDetails,\n tokenIn: args.tokenIn,\n executorAddress: args.executorAddress,\n swap: args.swap.swap,\n createSwapResponse: args.swap,\n fullQuoteSnapshot: args.fullQuote,\n purposeText: args.purposeText,\n swapDeadlineUnix: deadline,\n slippagePercent: args.slippagePercent,\n })\n}\n\nexport async function quoteSwap(\n args: Parameters<typeof uniswapTradeQuote>[0],\n): Promise<Record<string, unknown>> {\n return uniswapTradeQuote(args)\n}\n\nexport async function createSwap(\n args: Parameters<typeof uniswapCreateSwap>[0],\n): Promise<Awaited<ReturnType<typeof uniswapCreateSwap>>> {\n return uniswapCreateSwap(args)\n}\n\nexport async function swapExactInput(\n args: SwapExactInputArgs & {\n tradeType?: UniswapQuoteTradeType\n },\n) {\n const swap = await uniswapCreateSwap({\n uniswapApiKey: args.uniswapApiKey,\n fullQuoteFromPermit: args.fullQuote,\n baseUrl: args.baseUrl,\n swapTransactionDeadlineUnix: args.swapTransactionDeadlineUnix,\n useServerProxy: false,\n })\n return swapFromQuote({ ...args, swap })\n}\n","import type { ProtocolModule } from '../../../core/types.js'\nimport { registerProtocolModule } from '../../../core/registry.js'\nimport { isUniswapV4ChainSupported } from './constants.js'\n\nexport * from './constants.js'\nexport * from './quote.js'\nexport * from './swapMultisign.js'\nexport * from './purpose.js'\nexport * from './support.js'\nexport * from './swap.js'\n\nexport {\n isUniswapV4SwapEvmSignRequest,\n resolveRouterSwapGasUnitsFromSignRequest,\n} from './swapMultisign.js'\n\nexport const UNISWAP_V4_PROTOCOL_ID = 'uniswap-v4'\n\nexport const uniswapV4ProtocolModule: ProtocolModule = {\n id: UNISWAP_V4_PROTOCOL_ID,\n chainCategory: 'evm',\n isChainSupported(ctx) {\n if (ctx.chainCategory !== 'evm') return false\n return isUniswapV4ChainSupported(ctx.chainId)\n },\n isTokenSupported(token) {\n if (token.category !== 'evm') return false\n return token.kind === 'native' || token.kind === 'erc20'\n },\n actions: [\n {\n id: 'uniswap-v4.swap-exact-input',\n protocolId: UNISWAP_V4_PROTOCOL_ID,\n chainCategory: 'evm',\n description: 'Swap ERC-20 or native token via Uniswap V4 Universal Router (classic allowance path)',\n commonParams: ['keyGen', 'purposeText', 'useCustomGas'],\n params: {\n tokenIn: { type: 'address', required: true, description: 'Input token (0x0 for native)' },\n tokenOut: { type: 'address', required: true, description: 'Output token address' },\n amount: { type: 'string', required: true, description: 'Human or wei amount per trade type' },\n slippagePercent: { type: 'number', required: true, description: 'Slippage tolerance percent' },\n swapTransactionDeadlineUnix: {\n type: 'number',\n required: false,\n description: 'On-chain swap deadline (unix seconds)',\n },\n uniswapApiKey: { type: 'string', required: true, description: 'Uniswap Trade API key' },\n },\n },\n {\n id: 'uniswap-v4.quote',\n protocolId: UNISWAP_V4_PROTOCOL_ID,\n chainCategory: 'evm',\n description: 'Fetch Uniswap Trade API quote',\n commonParams: ['keyGen'],\n params: {\n tokenIn: { type: 'address', required: true, description: 'Input token' },\n tokenOut: { type: 'address', required: true, description: 'Output token' },\n amount: { type: 'string', required: true, description: 'Amount for quote' },\n type: { type: 'EXACT_INPUT | EXACT_OUTPUT', required: true, description: 'Trade type' },\n },\n },\n ],\n}\n\nregisterProtocolModule(uniswapV4ProtocolModule)\n\nimport { uniswapTradeQuote } from './quote.js'\nimport { buildEvmMultisignBodyUniswapV4SkipPermit2Batch } from './swapMultisign.js'\nimport { swapExactInput as swapExactInputFn, quoteSwap, createSwap, swapFromQuote } from './swap.js'\n\nexport const uniswapV4 = {\n quoteSwap,\n createSwap,\n swapExactInput: swapExactInputFn,\n swapFromQuote,\n buildSwapMultisignBody: buildEvmMultisignBodyUniswapV4SkipPermit2Batch,\n quote: uniswapTradeQuote,\n isChainSupported: isUniswapV4ChainSupported,\n}\n","import { parseEvmChainIdToNumber } from '../../../chains/evm/chainIdParse.js'\n\nconst CURVE_FULL_NETWORK_CONSTANTS_CHAIN_IDS: ReadonlySet<number> = new Set([\n 1, 10, 56, 100, 137, 146, 196, 250, 252, 324, 999, 1284, 2222, 5000, 8453, 42161, 42220, 43114, 1313161554,\n])\n\nexport function isCurveApiChainSupported(chainId: string | number | bigint | null | undefined): boolean {\n const n = parseEvmChainIdToNumber(chainId)\n if (Number.isNaN(n) || n < 0) return false\n return CURVE_FULL_NETWORK_CONSTANTS_CHAIN_IDS.has(n)\n}\n\nexport { isCurveApiChainSupported as isCurveDaoChainSupported }\n","import { getAddress, isAddress } from 'viem'\nimport { normalizeHumanDecimalAmount } from '../../../chains/evm/normalizeAmount.js'\n\nexport const CURVE_NATIVE_PLACEHOLDER = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'\n\nconst ETH_PLACEHOLDER = CURVE_NATIVE_PLACEHOLDER\n\nfunction normalizeAddr(a: string): string {\n return a.toLowerCase()\n}\n\n/** Map token in list to the address shape Curve uses in pool graphs (native → 0xeeee…). */\nexport function toCurveTokenKey(tokenInAddress: string, wrappedNative: string | undefined): string {\n if (!isAddress(tokenInAddress)) return normalizeAddr(tokenInAddress)\n try {\n const a = getAddress(tokenInAddress)\n if (wrappedNative && a.toLowerCase() === wrappedNative.toLowerCase()) {\n return ETH_PLACEHOLDER\n }\n return a.toLowerCase()\n } catch {\n return normalizeAddr(tokenInAddress)\n }\n}\n\n/**\n * Router / `getBestRouteAndOutput` expect the same coin id as the pool graph: wrapped native\n * is represented as `0xeeee…`, not the WETH (etc.) contract. Without this, route discovery can\n * return an empty route while BFS (which uses `toCurveTokenKey`) still finds a path.\n */\nexport function toCurveRouterTokenId(tokenAddress: string, wrappedNative: string | undefined): string {\n const t = (tokenAddress ?? '').trim().toLowerCase()\n if (t === ETH_PLACEHOLDER) return ETH_PLACEHOLDER\n if (!isAddress((tokenAddress ?? '').trim())) return normalizeAddr((tokenAddress ?? '').trim())\n try {\n const a = getAddress((tokenAddress ?? '').trim())\n if (wrappedNative && a.toLowerCase() === wrappedNative.toLowerCase()) {\n return ETH_PLACEHOLDER\n }\n /** Lowercase matches pool graph keys and `@curvefi/api`’s `DECIMALS` lookups. */\n return a.toLowerCase()\n } catch {\n return normalizeAddr((tokenAddress ?? '').trim())\n }\n}\n\n/**\n * Turn the user’s decimal string into a canonical form using **this chain’s** token-in decimals\n * (from the asset row). `@curvefi/api` uses the same for `parseUnits` when building routes; an\n * over-long fraction (e.g. 1e-8 on USDC) can make internal calls fail and yield an empty route / 0.0.\n */\nexport function normalizeCurveRouterAmountString(raw: string, tokenInDecimals: number): string {\n return normalizeHumanDecimalAmount(raw, tokenInDecimals)\n}\n\nfunction addEdge(adj: Map<string, Set<string>>, a: string, b: string) {\n if (a === b) return\n if (!adj.has(a)) adj.set(a, new Set())\n if (!adj.has(b)) adj.set(b, new Set())\n adj.get(a)!.add(b)\n adj.get(b)!.add(a)\n}\n\n/**\n * Build graph from the same pool list the Curve router uses (`getPool` / `getPoolList` on the\n * public `@curvefi/api` instance; `getPoolsData` is internal).\n */\nexport function buildCurveLiquidityGraphFromApi(curve: {\n getPoolList: () => string[]\n getPool: (id: string) => {\n underlyingCoinAddresses: string[] | undefined\n wrappedCoinAddresses: string[] | undefined\n }\n}): Map<string, Set<string>> {\n const adj = new Map<string, Set<string>>()\n for (const id of curve.getPoolList()) {\n try {\n const pool = curve.getPool(id)\n const w = (pool.wrappedCoinAddresses ?? []).map(normalizeAddr)\n const u = (pool.underlyingCoinAddresses ?? []).map(normalizeAddr)\n const all = [...new Set([...w, ...u])]\n for (let i = 0; i < all.length; i++) {\n for (let j = i + 1; j < all.length; j++) {\n addEdge(adj, all[i], all[j])\n }\n }\n } catch {\n /* pool constructor can throw for stale ids */\n }\n }\n return adj\n}\n\n/**\n * Add bidirectional edge between the SDK's native placeholder coin and WETH, when the chain uses\n * wrapped native in pools (mirrors the Curve dialog graph).\n */\nexport function addNativeWethBridge(adj: Map<string, Set<string>>, wrappedNative: string | undefined) {\n if (!wrappedNative) return\n const w = wrappedNative.toLowerCase()\n const a = ETH_PLACEHOLDER\n const b = w\n if (a === b) return\n if (!adj.has(a)) adj.set(a, new Set())\n if (!adj.has(b)) adj.set(b, new Set())\n adj.get(a)!.add(b)\n adj.get(b)!.add(a)\n}\n\n/** True when the token key appears in the graph with at least one swap neighbor. */\nexport function isCurveTokenKeySwappable(\n swappableNodeKeys: ReadonlySet<string>,\n graphTokenKey: string,\n): boolean {\n return swappableNodeKeys.has(graphTokenKey)\n}\n\n/**\n * All token keys in `adj` that have at least one pool neighbor (candidates to start a path from).\n */\nexport function swappableCurveGraphNodeKeys(adj: Map<string, Set<string>>): Set<string> {\n const out = new Set<string>()\n for (const [k, neigh] of adj) {\n if (neigh.size > 0) out.add(k)\n }\n return out\n}\n\n/**\n * All tokens in the same connected component as `start` (excluding `start`), for router discovery.\n */\nexport function bfsCurveSwapDestinations(adj: Map<string, Set<string>>, start: string): Set<string> {\n const s = normalizeAddr(start)\n const visited = new Set<string>([s])\n const q: string[] = [s]\n while (q.length) {\n const n = q.shift()!\n for (const nxt of adj.get(n) ?? []) {\n if (!visited.has(nxt)) {\n visited.add(nxt)\n q.push(nxt)\n }\n }\n }\n visited.delete(s)\n return visited\n}\n\nexport type CurveDestToken = {\n address: string\n symbol: string\n name: string\n /** From Curve `getCoinsData` (on-chain), when available. */\n decimals: number | null\n}\n","import {\n addNativeWethBridge,\n buildCurveLiquidityGraphFromApi,\n swappableCurveGraphNodeKeys,\n} from './swapDestinations.js'\n\nconst CURVE_SESSION_CACHE_TTL_MS = 5 * 60 * 1000\nconst curveSessionCache = new Map<string, { session: CurveFullSession; expiresAt: number }>()\n\n/** Live `@curvefi/api` instance with pools already fetched, plus the routing graph. */\nexport type CurveFullSession = {\n /** Same reference used for getCoinsData / router; pools already loaded. */\n curve: any\n adj: Map<string, Set<string>>\n swappableNodeKeys: ReadonlySet<string>\n wrappedNative: string | undefined\n}\n\n/**\n * Fetches all factory pools in parallel (best-effort; failures are ignored per factory,\n * same as the Curve dialog).\n */\nexport async function fetchAllCurvePools(curve: {\n factory?: { fetchPools: () => Promise<unknown> }\n crvUSDFactory?: { fetchPools: () => Promise<unknown> }\n EYWAFactory?: { fetchPools: () => Promise<unknown> }\n cryptoFactory?: { fetchPools: () => Promise<unknown> }\n twocryptoFactory?: { fetchPools: () => Promise<unknown> }\n tricryptoFactory?: { fetchPools: () => Promise<unknown> }\n stableNgFactory?: { fetchPools: () => Promise<unknown> }\n}): Promise<void> {\n const run = (p: Promise<unknown>) => p.catch(() => undefined)\n const tasks: Promise<unknown>[] = []\n for (const key of [\n 'factory',\n 'crvUSDFactory',\n 'EYWAFactory',\n 'cryptoFactory',\n 'twocryptoFactory',\n 'tricryptoFactory',\n 'stableNgFactory',\n ] as const) {\n const f = curve[key]\n if (f?.fetchPools) {\n tasks.push(run(f.fetchPools()))\n }\n }\n await Promise.all(tasks)\n}\n\n/**\n * One init + `fetchAllCurvePools` + graph build. Reuse this session for the asset list and the\n * Curve dialog to avoid duplicating the Curve API work.\n */\nexport async function loadFullCurveSessionForRpc(rpcUrl: string): Promise<CurveFullSession> {\n const url = (rpcUrl ?? '').trim()\n if (!url) {\n throw new Error('rpcUrl is required.')\n }\n const cached = curveSessionCache.get(url)\n if (cached && cached.expiresAt > Date.now()) {\n return cached.session\n }\n try {\n const { default: curve } = await import('@curvefi/api')\n await curve.init('JsonRpc', { url }, {})\n const wrapped = (curve.getNetworkConstants() as { NATIVE_COIN?: { wrappedAddress?: string } })\n .NATIVE_COIN?.wrappedAddress\n if (!curve.hasRouter || !curve.hasRouter()) {\n const session: CurveFullSession = {\n curve,\n adj: new Map(),\n swappableNodeKeys: new Set<string>(),\n wrappedNative: wrapped,\n }\n curveSessionCache.set(url, { session, expiresAt: Date.now() + CURVE_SESSION_CACHE_TTL_MS })\n return session\n }\n await fetchAllCurvePools(curve)\n const adj = buildCurveLiquidityGraphFromApi(curve)\n addNativeWethBridge(adj, wrapped)\n const session: CurveFullSession = {\n curve,\n adj,\n swappableNodeKeys: swappableCurveGraphNodeKeys(adj),\n wrappedNative: wrapped,\n }\n curveSessionCache.set(url, { session, expiresAt: Date.now() + CURVE_SESSION_CACHE_TTL_MS })\n return session\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e)\n throw new Error(`Curve session init failed for RPC: ${msg}`)\n }\n}\n\nexport type CurveSessionSnapshot = {\n wrappedNative: string | undefined\n swappableNodeKeys: string[]\n routerReady: boolean\n adj: Record<string, string[]>\n}\n\n/** JSON-safe Curve session for browser clients (via Next.js API route). */\nexport async function loadCurveSessionSnapshotForRpc(\n rpcUrl: string,\n): Promise<CurveSessionSnapshot> {\n const session = await loadFullCurveSessionForRpc(rpcUrl)\n const adj: Record<string, string[]> = {}\n for (const [key, neighbors] of session.adj) {\n adj[key] = [...neighbors]\n }\n return {\n wrappedNative: session.wrappedNative,\n swappableNodeKeys: [...session.swappableNodeKeys],\n routerReady: Boolean(session.curve?.hasRouter?.() && session.curve.hasRouter()),\n adj,\n }\n}\n\nexport type CurveCoinDataRow = {\n address: string\n name?: string\n symbol?: string\n decimals?: number | null\n}\n\n/** On-chain token metadata via `@curvefi/api` `getCoinsData` (server-side). */\nexport async function fetchCurveCoinsDataForRpc(\n rpcUrl: string,\n addresses: string[],\n): Promise<CurveCoinDataRow[]> {\n const session = await loadFullCurveSessionForRpc(rpcUrl)\n if (!session.curve?.getCoinsData) {\n throw new Error('Curve getCoinsData is not available for this RPC session.')\n }\n const coins = await session.curve.getCoinsData(addresses)\n return addresses.map((addr, i) => {\n const c = coins[i] as { name?: string; symbol?: string; decimals?: number } | undefined\n const dec = c?.decimals\n const decimals =\n typeof dec === 'number' && Number.isInteger(dec) && dec >= 0 && dec <= 18 ? dec : null\n return {\n address: addr,\n name: (c?.name && String(c.name).trim()) || '—',\n symbol: (c?.symbol && String(c.symbol).trim()) || addr.slice(0, 6),\n decimals,\n }\n })\n}\n\n","import type { ProposalTxParams } from '@continuumdao/continuum-node-sdk'\nexport type { ProposalTxParams }\n\nfunction parseOptionalGasLimitString(raw: string | number | undefined): bigint | null {\n if (raw == null) return null\n const s = String(raw).trim()\n if (!s) return null\n try {\n if (/^0x[0-9a-fA-F]+$/.test(s)) return BigInt(s)\n return BigInt(s)\n } catch {\n return null\n }\n}\n\nfunction parseExtraJsonObject(detail: Record<string, unknown> | null | undefined): Record<string, unknown> | null {\n if (!detail) return null\n const raw = detail.ExtraJSON ?? detail.extraJSON\n if (raw == null) return null\n if (typeof raw === 'object' && !Array.isArray(raw)) return raw as Record<string, unknown>\n if (typeof raw === 'string' && raw.trim()) {\n try {\n const p = JSON.parse(raw) as unknown\n if (p && typeof p === 'object' && !Array.isArray(p)) return p as Record<string, unknown>\n } catch {\n return null\n }\n }\n return null\n}\n\nexport const CURVE_ROUTER_EXCHANGE_DEFAULT_GAS_UNITS = 1_200_000n\n\nexport function isCurveDaoSwapEvmSignRequest(\n detail: Record<string, unknown> | null | undefined,\n batchIndex?: number,\n): boolean {\n const ex = parseExtraJsonObject(detail)\n if (batchIndex != null && batchIndex >= 0 && ex) {\n const bm = ex.batchMeta\n if (Array.isArray(bm) && bm[batchIndex] && typeof bm[batchIndex] === 'object' && !Array.isArray(bm[batchIndex])) {\n const evm0 = (bm[batchIndex] as Record<string, unknown>).evm\n if (evm0 && typeof evm0 === 'object' && !Array.isArray(evm0)) {\n if (String((evm0 as Record<string, unknown>).type ?? '') === 'curve_dao_router_exchange') return true\n }\n }\n }\n const evm = ex?.evm\n if (!evm || typeof evm !== 'object' || Array.isArray(evm)) return false\n return String((evm as Record<string, unknown>).type ?? '') === 'curve_dao_router_exchange'\n}\n\nexport function isCurveDaoErc20ApproveEvmSignRequest(\n detail: Record<string, unknown> | null | undefined,\n batchIndex?: number,\n): boolean {\n const ex = parseExtraJsonObject(detail)\n const index = batchIndex != null && batchIndex >= 0 ? batchIndex : 0\n const bm = ex?.batchMeta\n if (Array.isArray(bm) && bm[index] && typeof bm[index] === 'object' && !Array.isArray(bm[index])) {\n const evm0 = (bm[index] as Record<string, unknown>).evm\n if (evm0 && typeof evm0 === 'object' && !Array.isArray(evm0)) {\n const t = String((evm0 as Record<string, unknown>).type ?? '')\n return t === 'curve_dao_erc20_approve'\n }\n }\n return false\n}\n\nexport function resolveCurveDaoRouterGasUnitsFromSignRequest(\n detail: Record<string, unknown> | null | undefined,\n batchIndex?: number,\n): bigint | null {\n if (!detail) return null\n const propBatch = (detail.proposal_tx_params ??\n detail.proposalTxParams ??\n detail.ProposalTxParams) as unknown\n const index = batchIndex != null && batchIndex >= 0 ? batchIndex : 0\n if (Array.isArray(propBatch) && propBatch.length > index) {\n const row = propBatch[index]\n if (row && typeof row === 'object' && !Array.isArray(row)) {\n const r = row as Record<string, unknown>\n const gl = parseOptionalGasLimitString(\n (r.gas_limit ?? r.gasLimit ?? r.GasLimit) as string | number | undefined,\n )\n if (gl != null && gl > 0n) return gl\n }\n }\n const ex = parseExtraJsonObject(detail)\n const bm = ex?.batchMeta\n if (Array.isArray(bm)) {\n for (const item of bm) {\n if (!item || typeof item !== 'object' || Array.isArray(item)) continue\n const cd = (item as Record<string, unknown>).curveDao as Record<string, unknown> | undefined\n const gb = cd?.gasBuildExchange as Record<string, unknown> | undefined\n const base = parseOptionalGasLimitString(gb?.baseGasUnits as string | number | undefined)\n if (base != null && base > 0n) return base\n }\n }\n return null\n}\n","import {\n type Address,\n createPublicClient,\n defineChain,\n encodeFunctionData,\n getAddress,\n http,\n parseAbi,\n parseUnits,\n} from 'viem'\nimport type { KeyGenSubsetForPermit } from '../../../core/types.js'\nimport type { EvmChainDetail, EvmTxStep } from '../../../chains/evm/types.js'\nimport { buildEvmMultisignBatch } from '../../../chains/evm/buildBatch.js'\nimport { loadFullCurveSessionForRpc } from './apiSession.js'\nimport { toCurveRouterTokenId } from './swapDestinations.js'\nimport { CURVE_ROUTER_EXCHANGE_DEFAULT_GAS_UNITS } from './executeHelpers.js'\nimport { routerSwapGasLimitFromEstimate } from '../../../chains/evm/routerSwapGas.js'\n\nconst ETH_PLACEHOLDER = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' as const\n\ntype CurveStepKind = 'approve' | 'exchange'\ntype CurveStep = EvmTxStep & { kind: CurveStepKind; routerSwap?: boolean; fallbackGas?: bigint }\n\nfunction txToViemStep(tx: {\n to?: string | null\n data?: string | null\n value?: string | bigint | number | null\n}): { to: Address; data: `0x${string}`; value: bigint } {\n if (!tx.to) throw new Error('Transaction missing `to`')\n const to = getAddress((tx.to ?? '').trim() as `0x${string}`)\n const raw = (tx.data ?? '0x').toString()\n const data = (raw.startsWith('0x') ? raw : `0x${raw}`) as `0x${string}`\n let value = 0n\n if (tx.value != null) {\n if (typeof tx.value === 'bigint') value = tx.value\n else value = BigInt(String(tx.value))\n }\n return { to, data, value }\n}\n\n/**\n * Build `POST /multiSignRequest` body: optional ERC-20 approve(s) to the Curve router, then\n * `CurveRouterNG.exchange` via `@curvefi/api` `router.populateSwap`.\n */\nexport async function buildEvmMultisignBodyCurveDaoBatch(args: {\n keyGen: KeyGenSubsetForPermit\n chainId: number\n rpcUrl: string\n chainDetail: EvmChainDetail\n useCustomGas: boolean\n customGasChainDetails?: Record<string, unknown> | null\n tokenIn: Address\n tokenOut: string\n amountHuman: string\n slippagePercent: number\n executorAddress: Address\n purposeText: string\n}) {\n const tokenIn = getAddress(args.tokenIn)\n const executor = getAddress(args.executorAddress)\n\n const session = await loadFullCurveSessionForRpc(args.rpcUrl)\n if (!session?.curve?.router?.populateSwap) {\n throw new Error('Curve router is not available (load session failed or chain has no router).')\n }\n const { curve, wrappedNative } = session\n const wn = wrappedNative as string | undefined\n const tokenInId = toCurveRouterTokenId(tokenIn, wn)\n const outTrim = (args.tokenOut ?? '').trim()\n const tokenOutId = toCurveRouterTokenId(\n outTrim.toLowerCase() === ETH_PLACEHOLDER ? ETH_PLACEHOLDER : getAddress(outTrim),\n wn,\n )\n const isNativeIn = tokenInId.toLowerCase() === ETH_PLACEHOLDER\n const slip = args.slippagePercent\n if (!Number.isFinite(slip) || slip <= 0 || slip >= 100) {\n throw new Error('Slippage must be between 0 and 100 (exclusive).')\n }\n\n const swapPop = await curve.router.populateSwap(tokenInId, tokenOutId, args.amountHuman, slip)\n const swapBase = txToViemStep(swapPop as Parameters<typeof txToViemStep>[0])\n const rawTo = (swapPop as { to?: string | null })?.to\n if (rawTo == null || String(rawTo).trim() === '') {\n throw new Error('Curve populateSwap did not return a destination address (router).')\n }\n const routerAddr = getAddress(String(rawTo).trim() as `0x${string}`)\n\n const ch = defineChain({\n id: args.chainId,\n name: 'Destination',\n nativeCurrency: { decimals: 18, name: 'Ether', symbol: 'ETH' },\n rpcUrls: { default: { http: [args.rpcUrl] } },\n })\n const publicClient = createPublicClient({ chain: ch, transport: http(args.rpcUrl) })\n\n const erc20AllowanceAbi = parseAbi([\n 'function allowance(address owner, address spender) view returns (uint256)',\n 'function decimals() view returns (uint8)',\n ])\n const erc20ApproveAbi = parseAbi(['function approve(address spender, uint256 amount) returns (bool)'])\n\n const steps: CurveStep[] = []\n\n if (!isNativeIn) {\n const decimalsN = await publicClient.readContract({\n address: tokenIn,\n abi: erc20AllowanceAbi,\n functionName: 'decimals',\n })\n const amountWei = parseUnits(args.amountHuman, Number(decimalsN))\n const currentAllowance = await publicClient.readContract({\n address: tokenIn,\n abi: erc20AllowanceAbi,\n functionName: 'allowance',\n args: [executor, routerAddr],\n })\n if (currentAllowance < amountWei) {\n if (currentAllowance > 0n) {\n const dataReset = encodeFunctionData({\n abi: erc20ApproveAbi,\n functionName: 'approve',\n args: [routerAddr, 0n],\n })\n steps.push({ to: tokenIn, data: dataReset, value: 0n, kind: 'approve', fallbackGas: 80_000n })\n }\n const dataApprove = encodeFunctionData({\n abi: erc20ApproveAbi,\n functionName: 'approve',\n args: [routerAddr, amountWei],\n })\n steps.push({ to: tokenIn, data: dataApprove, value: 0n, kind: 'approve', fallbackGas: 80_000n })\n }\n }\n\n steps.push({\n ...swapBase,\n kind: 'exchange',\n routerSwap: true,\n fallbackGas: CURVE_ROUTER_EXCHANGE_DEFAULT_GAS_UNITS,\n })\n\n const chainGasLimitRouter =\n args.chainDetail?.gasLimit != null &&\n Number.isFinite(Number(args.chainDetail.gasLimit)) &&\n Number(args.chainDetail.gasLimit) > 0\n ? Number(args.chainDetail.gasLimit)\n : undefined\n\n const gasLimitByIndex = new Map<number, bigint>()\n const n = steps.length\n const purposeSuffix =\n n === 1\n ? 'Curve (DAO): 1-tx — CurveRouterNG.exchange (native in or allowance already set).'\n : `Curve (DAO): ${n}-tx batch — ERC-20 approve Curve router, then CurveRouterNG.exchange.`\n\n const firstDataNo0x = steps[0]!.data.startsWith('0x') ? steps[0]!.data.slice(2) : steps[0]!.data\n const payableValueWei = steps.filter((s) => s.kind === 'exchange').reduce((a, s) => a + s.value, 0n)\n\n return buildEvmMultisignBatch({\n context: {\n chainCategory: 'evm',\n keyGen: args.keyGen,\n purposeText: args.purposeText,\n chainId: args.chainId,\n rpcUrl: args.rpcUrl,\n executorAddress: executor,\n chainDetail: args.chainDetail,\n useCustomGas: args.useCustomGas,\n customGasChainDetails: args.customGasChainDetails,\n },\n steps,\n purposeSuffix,\n firstMsgRawNo0x: firstDataNo0x,\n destinationAddress: steps[0]!.to,\n payableValueWei: payableValueWei > 0n ? payableValueWei : undefined,\n resolveGasLimit: async ({ step, index, estimatedGas }) => {\n const s = step as CurveStep\n let gasLimitI: bigint\n if (s.kind === 'exchange') {\n gasLimitI = routerSwapGasLimitFromEstimate(estimatedGas, chainGasLimitRouter)\n } else {\n gasLimitI = estimatedGas\n }\n gasLimitByIndex.set(index, gasLimitI)\n return gasLimitI\n },\n buildBatchMeta: ({ step, index, gasLimit }) => {\n const s = step as CurveStep\n const gl = gasLimitByIndex.get(index) ?? gasLimit\n if (s.kind === 'approve') {\n return {\n signatureText: JSON.stringify({\n kind: 'CurveDao',\n name: 'ERC20.approve',\n to: 'Curve router',\n function: 'approve(address spender, uint256 amount)',\n spender: routerAddr,\n amountHuman: args.amountHuman,\n note: 'Allowance approved for this swap amount only (not unlimited).',\n }),\n evm: { type: 'curve_dao_erc20_approve', version: 1, chainId: String(args.chainId) },\n }\n }\n return {\n signatureText: JSON.stringify({\n kind: 'CurveDao',\n name: 'CurveRouterNG.exchange',\n note: 'Calldata from @curvefi/api `router.populateSwap` (same on-chain as router `exchange`).',\n }),\n evm: { type: 'curve_dao_router_exchange', version: 1, chainId: String(args.chainId) },\n curveDao: {\n slippagePercent: slip,\n amountHuman: args.amountHuman,\n tokenIn: tokenInId,\n tokenOut: tokenOutId,\n isNativeIn,\n gasBuildExchange: { baseGasUnits: gl.toString() },\n },\n }\n },\n })\n}\n","import type { ProtocolModule } from '../../../core/types.js'\nimport { registerProtocolModule } from '../../../core/registry.js'\nimport { isCurveApiChainSupported } from './support.js'\n\nexport * from './support.js'\nexport * from './swapDestinations.js'\nexport * from './apiSession.js'\nexport * from './purpose.js'\nexport * from './executeHelpers.js'\nexport * from './multisign.js'\nexport * from './quote.js'\nexport * from './quoteDisplay.js'\n\nexport const CURVE_DAO_PROTOCOL_ID = 'curve-dao'\n\nexport const curveDaoProtocolModule: ProtocolModule = {\n id: CURVE_DAO_PROTOCOL_ID,\n chainCategory: 'evm',\n isChainSupported(ctx) {\n if (ctx.chainCategory !== 'evm') return false\n return isCurveApiChainSupported(ctx.chainId)\n },\n isTokenSupported(token) {\n if (token.category !== 'evm') return false\n return token.kind === 'native' || token.kind === 'erc20'\n },\n actions: [\n {\n id: 'curve-dao.quote',\n protocolId: CURVE_DAO_PROTOCOL_ID,\n chainCategory: 'evm',\n description: 'Quote swap via Curve Router NG (getBestRouteAndOutput)',\n commonParams: [],\n params: {\n chainId: { type: 'number', required: true, description: 'EVM chain id' },\n tokenIn: { type: 'address', required: true, description: 'Token in or native placeholder' },\n tokenOut: { type: 'address', required: true, description: 'Token out or native placeholder' },\n amountHuman: { type: 'string', required: true, description: 'Human-readable input amount' },\n },\n },\n {\n id: 'curve-dao.swap',\n protocolId: CURVE_DAO_PROTOCOL_ID,\n chainCategory: 'evm',\n description: 'Swap via Curve Router NG (optional ERC-20 approve batch)',\n commonParams: ['keyGen', 'purposeText', 'useCustomGas'],\n params: {\n tokenIn: { type: 'address', required: true, description: 'ERC-20 token in (native uses WETH path in UI)' },\n tokenOut: { type: 'address', required: true, description: 'Output token or 0xeeee… native placeholder' },\n amountHuman: { type: 'string', required: true, description: 'Human-readable input amount' },\n slippagePercent: { type: 'number', required: true, description: 'Slippage percent (0–100 exclusive)' },\n },\n },\n ],\n}\n\nregisterProtocolModule(curveDaoProtocolModule)\n\nimport { buildEvmMultisignBodyCurveDaoBatch } from './multisign.js'\nimport { loadFullCurveSessionForRpc } from './apiSession.js'\n\nexport const curveDao = {\n buildSwapMultisignBody: buildEvmMultisignBodyCurveDaoBatch,\n isChainSupported: isCurveApiChainSupported,\n loadSession: loadFullCurveSessionForRpc,\n}\n","export * from './core/index.js'\nexport * from './chains/evm/index.js'\nexport { solanaChainCategoryModule, SOLANA_CHAIN_CATEGORY } from './chains/solana/index.js'\nexport { nearChainCategoryModule, NEAR_CHAIN_CATEGORY } from './chains/near/index.js'\nexport { uniswapV4ProtocolModule, uniswapV4 } from './protocols/evm/uniswap-v4/index.js'\nexport { curveDaoProtocolModule, curveDao } from './protocols/evm/curve-dao/index.js'\nimport { registerProtocolModule } from './core/registry.js'\nimport { uniswapV4ProtocolModule } from './protocols/evm/uniswap-v4/index.js'\nimport { curveDaoProtocolModule } from './protocols/evm/curve-dao/index.js'\n\nregisterProtocolModule(uniswapV4ProtocolModule)\nregisterProtocolModule(curveDaoProtocolModule)\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/purpose.ts","../src/core/envelope.ts","../src/core/registry.ts","../src/core/defiProxy.ts","../src/chains/evm/types.ts","../src/chains/evm/routerSwapGas.ts","../src/chains/evm/buildBatch.ts","../src/chains/evm/chainIdParse.ts","../src/chains/evm/normalizeAmount.ts","../src/chains/evm/coingecko.ts","../src/chains/solana/types.ts","../src/chains/solana/index.ts","../src/chains/near/types.ts","../src/chains/near/index.ts","../src/protocols/evm/uniswap-v4/constants.ts","../src/protocols/evm/uniswap-v4/quote.ts","../src/protocols/evm/uniswap-v4/swapMultisign.ts","../src/protocols/evm/uniswap-v4/knownLpPools.ts","../src/protocols/evm/uniswap-v4/liquidityApi.ts","../src/protocols/evm/uniswap-v4/liquidityQuote.ts","../src/protocols/evm/uniswap-v4/positions.ts","../src/protocols/evm/uniswap-v4/liquidityMultisign.ts","../src/protocols/evm/uniswap-v4/swap.ts","../src/protocols/evm/uniswap-v4/index.ts","../src/protocols/evm/curve-dao/support.ts","../src/protocols/evm/curve-dao/swapDestinations.ts","../src/protocols/evm/curve-dao/apiSession.ts","../src/protocols/evm/curve-dao/executeHelpers.ts","../src/protocols/evm/curve-dao/multisign.ts","../src/protocols/evm/curve-dao/index.ts","../src/index.ts"],"names":["getClientIdFromKeyGenResult","r","getAddress","zeroAddress","gasLimitFromEstimateAndChainConfig","defineChain","createPublicClient","http","fetchChainFeeParams","parseGwei","gweiToDecimalString","serializeTransaction","proposalTxParamsToFeeSnapshot","alignEip1559FeesWithLatestBase","keccak256","parseUnits","formatUnits","nodeFetchWithReadAuth","res","text","parsed","decodeFunctionData","encodeFunctionData","erc20Abi","trimAddr","fn","base","parseAbi","parseAbiItem","parseOptionalGasLimitString","isAddress","session","ETH_PLACEHOLDER","erc20AllowanceAbi"],"mappings":"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","file":"index.cjs","sourcesContent":["/** Merge user purpose text with an optional batch / protocol suffix. */\nexport function mergePurposeText(purposeText: string, purposeSuffix?: string): string {\n const t = purposeText.trim()\n const suffix = (purposeSuffix ?? '').trim()\n if (!suffix) return t\n return t ? `${t}\\n\\n${suffix}` : suffix\n}\n","import type { ChainCategory, MultisignBuildResult, KeyGenSubset } from './types.js'\nimport { getClientIdFromKeyGenResult } from '@continuumdao/continuum-node-sdk'\nimport { mergePurposeText } from './purpose.js'\n\nexport interface MultisignLeg {\n msgHash: string\n msgRaw: string\n destinationAddress: string\n signatureText: string\n audit: Record<string, unknown>\n feeSnapshot: Record<string, unknown>\n proposalTxParams?: Record<string, unknown>\n /** Payable value wei string for first leg only when relevant */\n valueWei?: bigint\n}\n\nexport interface ChainCategoryBuildInput {\n keyGen: KeyGenSubset\n purposeText: string\n purposeSuffix?: string\n destinationChainID: string\n legs: MultisignLeg[]\n extraJSON?: Record<string, unknown>\n /** Top-level destination address (first leg destination if omitted) */\n destinationAddress?: string\n}\n\nexport interface ChainCategoryModule {\n category: ChainCategory\n finalizeMultisign(input: ChainCategoryBuildInput): MultisignBuildResult\n}\n\n/**\n * Assemble mpc-auth `bodyForSign` from category-built legs.\n * Supports single-tx and batch (messageHashes / messageRawBatch / proposalTxParams).\n */\nexport function finalizeMultisign(input: ChainCategoryBuildInput): MultisignBuildResult {\n const { keyGen, destinationChainID, legs } = input\n if (legs.length === 0) {\n throw new Error('finalizeMultisign requires at least one leg')\n }\n\n const ph = (keyGen.pubkeyhex ?? '').trim()\n if (!ph) throw new Error('keyGen pubKey (pubkeyhex) is required')\n\n const keyList = keyGen.keylist ?? []\n const clientId = getClientIdFromKeyGenResult(keyGen)\n const first = legs[0]!\n\n const messageHashes = legs.map((l) => l.msgHash)\n const messageRawBatch = legs.map((l) => l.msgRaw)\n const batchMeta = legs.map((l) => ({\n destinationAddress: l.destinationAddress,\n signatureText: l.signatureText,\n ...l.audit,\n }))\n\n const proposalTxParams = legs\n .map((l) => l.proposalTxParams)\n .filter((p): p is Record<string, unknown> => p != null && typeof p === 'object')\n\n const extraPayload: Record<string, unknown> = {\n batchMeta,\n ...(input.extraJSON ?? {}),\n }\n const extraJSON = JSON.stringify(extraPayload)\n\n const bodyForSign: Record<string, unknown> = {\n keyList,\n pubKey: ph,\n msgHash: messageHashes[0],\n msgRaw: first.msgRaw,\n destinationChainID,\n destinationAddress: input.destinationAddress ?? first.destinationAddress,\n extraJSON,\n signatureText: first.signatureText,\n purpose: mergePurposeText(input.purposeText, input.purposeSuffix),\n ...first.feeSnapshot,\n }\n\n if (legs.length > 1) {\n bodyForSign.messageHashes = messageHashes\n bodyForSign.messageRawBatch = messageRawBatch\n }\n\n if (proposalTxParams.length > 0) {\n bodyForSign.proposalTxParams = proposalTxParams\n }\n\n const valueWei = first.valueWei\n if (valueWei != null && valueWei > 0n) {\n bodyForSign.value = valueWei.toString()\n }\n\n if (clientId) bodyForSign.clientId = clientId\n\n return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) }\n}\n\nexport const coreChainCategoryModule: ChainCategoryModule = {\n category: 'evm',\n finalizeMultisign,\n}\n","import type { ProtocolModule } from './types.js'\n\nconst modules: ProtocolModule[] = []\n\nexport function registerProtocolModule(mod: ProtocolModule): void {\n const existing = modules.findIndex((m) => m.id === mod.id)\n if (existing >= 0) {\n modules[existing] = mod\n } else {\n modules.push(mod)\n }\n}\n\nexport function getProtocolModules(): readonly ProtocolModule[] {\n return modules\n}\n\nexport function getProtocolModule(id: string): ProtocolModule | undefined {\n return modules.find((m) => m.id === id)\n}\n\nexport function getActionsByChainCategory(category: string): ProtocolModule['actions'] {\n return modules.filter((m) => m.chainCategory === category).flatMap((m) => m.actions)\n}\n","/**\n * Optional browser → Next.js API proxy paths for DeFi upstream calls.\n * Set once from continuumdao-node-app client bootstrap.\n */\n\nlet aaveGraphqlProxyUrl: string | undefined\nlet eulerGraphqlProxyUrl: string | undefined\nlet mapleGraphqlProxyUrl: string | undefined\nlet coingeckoProxyUrl: string | undefined\n\nexport function setAaveGraphqlProxyUrl(url: string | undefined): void {\n aaveGraphqlProxyUrl = url?.trim() || undefined\n}\n\nexport function getAaveGraphqlProxyUrl(): string | undefined {\n return aaveGraphqlProxyUrl\n}\n\nexport function setEulerGraphqlProxyUrl(url: string | undefined): void {\n eulerGraphqlProxyUrl = url?.trim() || undefined\n}\n\nexport function getEulerGraphqlProxyUrl(): string | undefined {\n return eulerGraphqlProxyUrl\n}\n\nexport function setMapleGraphqlProxyUrl(url: string | undefined): void {\n mapleGraphqlProxyUrl = url?.trim() || undefined\n}\n\nexport function getMapleGraphqlProxyUrl(): string | undefined {\n return mapleGraphqlProxyUrl\n}\n\nexport function setCoingeckoProxyUrl(url: string | undefined): void {\n coingeckoProxyUrl = url?.trim() || undefined\n}\n\nexport function getCoingeckoProxyUrl(): string | undefined {\n return coingeckoProxyUrl\n}\n\nexport async function postJsonViaOptionalProxy<T>(args: {\n directUrl: string\n body: unknown\n proxyUrl?: string\n proxyEnvelope?: unknown\n}): Promise<T> {\n const proxy = args.proxyUrl?.trim()\n if (proxy) {\n const r = await fetch(proxy, {\n method: 'POST',\n headers: {'content-type': 'application/json'},\n body: JSON.stringify(args.proxyEnvelope ?? args.body),\n })\n if (!r.ok) {\n const t = await r.text().catch(() => '')\n throw new Error(t ? `Proxy HTTP ${r.status}: ${t.slice(0, 200)}` : `Proxy HTTP ${r.status}`)\n }\n return (await r.json()) as T\n }\n const r = await fetch(args.directUrl, {\n method: 'POST',\n headers: {'content-type': 'application/json'},\n body: JSON.stringify(args.body),\n })\n if (!r.ok) {\n const t = await r.text().catch(() => '')\n throw new Error(t ? `HTTP ${r.status}: ${t.slice(0, 200)}` : `HTTP ${r.status}`)\n }\n return (await r.json()) as T\n}\n","import type { EvmTokenKind, MultisignCommonArgs } from '../../core/types.js'\nimport { getAddress, zeroAddress, type Address } from 'viem'\n\nexport type EvmChainDetail = {\n legacy?: boolean\n gasLimit?: number\n gasMultiplier?: number\n gasPrice?: number\n baseFee?: number\n priorityFee?: number\n baseFeeMultiplier?: number\n}\n\nexport interface EvmProtocolContext extends MultisignCommonArgs {\n chainCategory: 'evm'\n chainId: number\n rpcUrl: string\n executorAddress: Address\n chainDetail: EvmChainDetail\n useCustomGas: boolean\n customGasChainDetails?: Record<string, unknown> | null\n}\n\nexport type EvmTxStep = {\n to: Address\n data: `0x${string}`\n value: bigint\n /** Fallback when estimateGas reverts */\n fallbackGas?: bigint\n /** When set, use routerSwapGasLimitFromEstimate instead of plain estimate */\n routerSwap?: boolean\n}\n\nexport function isEvmNativeToken(address: string): boolean {\n try {\n return getAddress(address as `0x${string}`) === zeroAddress\n } catch {\n return address.toLowerCase() === zeroAddress\n }\n}\n\nexport function matchEvmTokenKind(\n kind: EvmTokenKind,\n address: string,\n): boolean {\n if (kind === 'native') return isEvmNativeToken(address)\n if (kind === 'erc20' || kind === 'ctmerc20' || kind === 'ctmrwa1') {\n return !isEvmNativeToken(address)\n }\n return true\n}\n","import { gasLimitFromEstimateAndChainConfig } from '@continuumdao/continuum-node-sdk'\n\n/** Curve router swap gas: chain cap when set, else 12/10 estimate bump. */\nexport function routerSwapGasLimitFromEstimate(\n estimatedGas: bigint,\n chainGasLimit?: number | null,\n): bigint {\n if (chainGasLimit != null && Number.isFinite(chainGasLimit) && chainGasLimit > 0) {\n return gasLimitFromEstimateAndChainConfig(estimatedGas, chainGasLimit)\n }\n return (estimatedGas * 12n + 9n) / 10n\n}\n","import {\n keccak256,\n createPublicClient,\n defineChain,\n http,\n serializeTransaction,\n getAddress,\n parseGwei,\n type Address,\n type PublicClient,\n} from 'viem'\nimport type { MultisignBuildResult } from '../../core/types.js'\nimport { finalizeMultisign, type MultisignLeg } from '../../core/envelope.js'\nimport type { KeyGenSubset } from '../../core/types.js'\nimport {\n fetchChainFeeParams,\n alignEip1559FeesWithLatestBase,\n gweiToDecimalString,\n gasLimitFromEstimateAndChainConfig,\n proposalTxParamsToFeeSnapshot,\n type ProposalTxParams,\n} from '@continuumdao/continuum-node-sdk'\nimport { routerSwapGasLimitFromEstimate } from './routerSwapGas.js'\nimport type { EvmProtocolContext, EvmTxStep } from './types.js'\n\nexport type EvmBatchMetaBuilder = (args: {\n step: EvmTxStep\n index: number\n gasLimit: bigint\n}) => Record<string, unknown>\n\nexport type EvmBuildBatchArgs = {\n context: EvmProtocolContext\n steps: EvmTxStep[]\n purposeSuffix?: string\n buildBatchMeta: EvmBatchMetaBuilder\n /** First leg msgRaw without 0x prefix; defaults to first step calldata */\n firstMsgRawNo0x?: string\n destinationAddress?: Address\n /** Top-level `value` on bodyForSign when the payable amount is not on the first leg */\n payableValueWei?: bigint\n resolveGasLimit?: (args: {\n step: EvmTxStep\n index: number\n estimatedGas: bigint\n publicClient: PublicClient\n }) => Promise<bigint> | bigint\n /** Override default `estimateGas` (e.g. trade-API gas, skip post-approve deposit estimate). */\n estimateGasForStep?: (args: {\n step: EvmTxStep\n index: number\n publicClient: PublicClient\n executor: Address\n }) => Promise<bigint> | bigint\n}\n\n/**\n * Build unsigned EVM txs, estimate gas, serialize, hash — then assemble mpc-auth body via core envelope.\n */\nexport async function buildEvmMultisignBatch(args: EvmBuildBatchArgs): Promise<MultisignBuildResult> {\n const { context, steps } = args\n const {\n chainId,\n rpcUrl,\n executorAddress,\n chainDetail,\n useCustomGas,\n customGasChainDetails,\n keyGen,\n purposeText,\n } = context\n\n if (steps.length === 0) throw new Error('buildEvmMultisignBatch requires at least one step')\n\n const ch = defineChain({\n id: chainId,\n name: 'Destination',\n nativeCurrency: { decimals: 18, name: 'Ether', symbol: 'ETH' },\n rpcUrls: { default: { http: [rpcUrl] } },\n })\n const publicClient = createPublicClient({ chain: ch, transport: http(rpcUrl) })\n\n const feeParams = await fetchChainFeeParams(rpcUrl, chainId)\n const legacy = Boolean(chainDetail?.legacy) || !feeParams.isEip1559\n const latestBaseFeeWei = !legacy\n ? ((await publicClient.getBlock({ blockTag: 'latest' })).baseFeePerGas ?? 0n)\n : 0n\n\n const gasLimitConfig =\n useCustomGas && chainDetail?.gasLimit != null ? Number(chainDetail.gasLimit) : undefined\n const chainGasLimitRouter =\n chainDetail?.gasLimit != null &&\n Number.isFinite(Number(chainDetail.gasLimit)) &&\n Number(chainDetail.gasLimit) > 0\n ? Number(chainDetail.gasLimit)\n : undefined\n const gasFeeMultiplier =\n useCustomGas && chainDetail?.gasMultiplier != null ? Number(chainDetail.gasMultiplier) : undefined\n\n const executor = getAddress(executorAddress)\n const baseNonce = await publicClient.getTransactionCount({ address: executor, blockTag: 'pending' })\n\n const legs: MultisignLeg[] = []\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]!\n const currentNonce = baseNonce + i\n\n let estimatedGas: bigint\n if (args.estimateGasForStep) {\n estimatedGas = await args.estimateGasForStep({ step, index: i, publicClient, executor })\n } else {\n try {\n estimatedGas = await publicClient.estimateGas({\n to: step.to,\n data: step.data,\n value: step.value,\n account: executor,\n })\n } catch {\n estimatedGas = step.fallbackGas ?? 100_000n\n }\n }\n\n let gasLimitI: bigint\n if (args.resolveGasLimit) {\n gasLimitI = await args.resolveGasLimit({ step, index: i, estimatedGas, publicClient })\n } else if (step.routerSwap) {\n gasLimitI = routerSwapGasLimitFromEstimate(estimatedGas, chainGasLimitRouter)\n } else {\n gasLimitI = useCustomGas\n ? gasLimitFromEstimateAndChainConfig(estimatedGas, gasLimitConfig)\n : estimatedGas\n }\n\n let proposalTxParams: ProposalTxParams\n let feeSnapshot: Record<string, unknown>\n let serialized: `0x${string}`\n\n if (legacy) {\n let gasPriceWei = await publicClient.getGasPrice()\n if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {\n gasPriceWei = (gasPriceWei * BigInt(100 + gasFeeMultiplier)) / 100n\n }\n if (useCustomGas && chainDetail?.gasPrice != null && chainDetail.gasPrice > 0) {\n const configured = parseGwei(gweiToDecimalString(Number(chainDetail.gasPrice)))\n if (configured > gasPriceWei) gasPriceWei = configured\n }\n serialized = serializeTransaction({\n type: 'legacy',\n to: step.to,\n data: step.data,\n value: step.value,\n gas: gasLimitI,\n gasPrice: gasPriceWei,\n nonce: currentNonce,\n chainId,\n })\n proposalTxParams = {\n nonce: currentNonce,\n gasLimit: gasLimitI.toString(),\n txType: 'legacy',\n gasPrice: gasPriceWei.toString(),\n }\n feeSnapshot = proposalTxParamsToFeeSnapshot(proposalTxParams)\n } else {\n const fetchedBase = feeParams.baseFeeGwei ?? 0\n const fetchedPriority = feeParams.priorityFeeGwei ?? 0\n const configuredBase =\n useCustomGas && chainDetail?.baseFee != null ? Number(chainDetail.baseFee) : 0\n const configuredPriority =\n useCustomGas && chainDetail?.priorityFee != null ? Number(chainDetail.priorityFee) : 0\n const effectiveBaseFeeGwei = Math.max(fetchedBase, configuredBase)\n const effectivePriorityFeeGwei = Math.max(fetchedPriority, configuredPriority)\n const baseFeeMultiplierPct =\n useCustomGas && chainDetail?.baseFeeMultiplier != null\n ? Math.max(100, Number(chainDetail.baseFeeMultiplier))\n : 100\n const baseComponentGwei = (effectiveBaseFeeGwei * baseFeeMultiplierPct) / 100\n const maxFeePerGasGwei = baseComponentGwei + effectivePriorityFeeGwei\n let maxPriorityFeePerGas =\n effectivePriorityFeeGwei > 0\n ? parseGwei(gweiToDecimalString(effectivePriorityFeeGwei))\n : parseGwei('1')\n let maxFeePerGas = parseGwei(gweiToDecimalString(maxFeePerGasGwei))\n if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {\n maxPriorityFeePerGas = (maxPriorityFeePerGas * BigInt(100 + gasFeeMultiplier)) / 100n\n maxFeePerGas = (maxFeePerGas * BigInt(100 + gasFeeMultiplier)) / 100n\n }\n ;({ maxFeePerGas, maxPriorityFeePerGas } = alignEip1559FeesWithLatestBase(\n maxFeePerGas,\n maxPriorityFeePerGas,\n latestBaseFeeWei,\n ))\n serialized = serializeTransaction({\n type: 'eip1559',\n to: step.to,\n data: step.data,\n value: step.value,\n gas: gasLimitI,\n maxFeePerGas,\n maxPriorityFeePerGas,\n nonce: currentNonce,\n chainId,\n })\n proposalTxParams = {\n nonce: currentNonce,\n gasLimit: gasLimitI.toString(),\n txType: 'eip1559',\n maxFeePerGas: maxFeePerGas.toString(),\n maxPriorityFeePerGas: maxPriorityFeePerGas.toString(),\n }\n feeSnapshot = i === 0 ? proposalTxParamsToFeeSnapshot(proposalTxParams) : {}\n }\n\n const h = keccak256(serialized)\n const msgHash = h.startsWith('0x') ? h.slice(2) : h\n\n const batchMetaExtra = args.buildBatchMeta({ step, index: i, gasLimit: gasLimitI })\n\n legs.push({\n msgHash,\n msgRaw: i === 0 && args.firstMsgRawNo0x != null ? args.firstMsgRawNo0x : serialized,\n destinationAddress: step.to,\n signatureText:\n typeof batchMetaExtra.signatureText === 'string'\n ? batchMetaExtra.signatureText\n : JSON.stringify(batchMetaExtra.signatureText ?? {}),\n audit: batchMetaExtra,\n feeSnapshot: i === 0 ? feeSnapshot : {},\n proposalTxParams,\n valueWei: i === 0 ? step.value : undefined,\n })\n\n if (i === 0 && args.firstMsgRawNo0x != null) {\n legs[0]!.msgRaw = args.firstMsgRawNo0x\n }\n }\n\n const extraJSON: Record<string, unknown> = {}\n if (useCustomGas && customGasChainDetails && Object.keys(customGasChainDetails).length > 0) {\n extraJSON.customGasChainDetails = customGasChainDetails\n }\n\n const result = finalizeMultisign({\n keyGen: keyGen as KeyGenSubset,\n purposeText,\n purposeSuffix: args.purposeSuffix,\n destinationChainID: String(chainId),\n destinationAddress: args.destinationAddress ?? steps[0]!.to,\n legs,\n extraJSON: Object.keys(extraJSON).length > 0 ? extraJSON : undefined,\n })\n const pv = args.payableValueWei\n if (pv != null && pv > 0n) {\n result.bodyForSign.value = pv.toString()\n }\n return result\n}\n\nexport const evmChainCategoryModule = {\n category: 'evm' as const,\n finalizeMultisign,\n buildEvmMultisignBatch,\n}\n","/** Parse chain id for comparisons (decimal, 0x hex, CAIP-2 eip155:N, bigint). */\nexport function parseEvmChainIdToNumber(chainId: string | number | bigint | null | undefined): number {\n if (chainId == null) return Number.NaN\n if (typeof chainId === 'bigint') {\n const n = Number(chainId)\n return Number.isSafeInteger(n) && n >= 0 ? n : Number.NaN\n }\n if (typeof chainId === 'number') {\n return Number.isInteger(chainId) && chainId >= 0 ? chainId : Number.NaN\n }\n const t = String(chainId).trim()\n if (!t) return Number.NaN\n const low = t.toLowerCase()\n if (low.startsWith('eip155:')) {\n const rest = t.slice('eip155:'.length).trim()\n const n = Number.parseInt(rest, 10)\n return Number.isNaN(n) || n < 0 ? Number.NaN : n\n }\n if (low.startsWith('0x')) {\n return Number.parseInt(t, 16)\n }\n return Number.parseInt(t, 10)\n}\n","import { formatUnits, parseUnits } from 'viem'\n\n/**\n * Canonical human decimal string for a token amount (truncate to token decimals via wei round-trip).\n * Used by Curve router and multisign dialogs across protocols.\n */\nexport function normalizeHumanDecimalAmount(raw: string, tokenDecimals: number): string {\n const t = raw.trim().replace(/,/g, '')\n if (!t) return ''\n if (!Number.isInteger(tokenDecimals) || tokenDecimals < 0 || tokenDecimals > 18) {\n throw new Error('Invalid token decimals for amount normalization.')\n }\n const wei = parseUnits(t, tokenDecimals)\n return formatUnits(wei, tokenDecimals)\n}\n\n/** @deprecated Prefer normalizeHumanDecimalAmount; kept for Curve router parity. */\nexport const normalizeCurveRouterAmountString = normalizeHumanDecimalAmount\n","/** CoinGecko asset platform id by mainnet chainId (contract price endpoint). */\nexport const COINGECKO_PLATFORM_BY_CHAIN_ID: Record<string, string> = {\n '1': 'ethereum',\n '56': 'binance-smart-chain',\n '137': 'polygon-pos',\n '42161': 'arbitrum-one',\n '10': 'optimistic-ethereum',\n '43114': 'avalanche',\n '8453': 'base',\n '324': 'zk-sync-era',\n '42220': 'celo',\n '250': 'fantom',\n '100': 'gnosis',\n '204': 'op-bnb',\n '534352': 'scroll',\n '5000': 'mantle',\n '169': 'manta-pacific',\n '1116': 'core',\n '30': 'rootstock',\n '288': 'boba',\n '1088': 'metis-andromeda',\n '34443': 'mode',\n '80084': 'berachain',\n '146': 'sonic',\n '60808': 'bob-network',\n '80094': 'berachain',\n '130': 'unichain',\n '57073': 'ink',\n '999': 'hyperevm',\n '239': 'tac',\n '9745': 'plasma',\n '1923': 'swellchain',\n '59144': 'linea',\n '81457': 'blast',\n '7777777': 'zora',\n}\n\nexport function coingeckoPlatformForChainId(chainId: string | number): string | undefined {\n return COINGECKO_PLATFORM_BY_CHAIN_ID[String(chainId).trim()]\n}\n","/** Solana signing defaults — mirrors app NonEvmChainDetailRow.signingDefaults. */\nexport type SolanaSigningDefaults = {\n commitment?: 'confirmed' | 'finalized'\n computeUnitLimit?: number\n priorityFeeMicroLamports?: number\n}\n\nexport type SolanaChainDetail = {\n chainType: 'solana'\n chainId: string\n chainName: string\n rpcGateway: string\n endpointKind: 'json-rpc'\n testnet: boolean\n nativeSymbol: string\n nativeDecimals: number\n signingDefaults?: SolanaSigningDefaults\n}\n\nexport interface SolanaProtocolContext {\n chainCategory: 'solana'\n chainId: string\n rpcGateway: string\n executorAddress: string\n chainDetail: SolanaChainDetail\n useCustomFees: boolean\n keyGen: import('../../core/types.js').KeyGenSubset\n purposeText: string\n}\n\nexport class NotImplementedError extends Error {\n constructor(feature: string) {\n super(`${feature} is not implemented yet for chain category solana`)\n this.name = 'NotImplementedError'\n }\n}\n\nexport async function buildSolanaMultisignBatch(): Promise<never> {\n throw new NotImplementedError('buildSolanaMultisignBatch')\n}\n\nexport const solanaChainCategoryModule = {\n category: 'solana' as const,\n}\n","export * from './types.js'\n\nexport const SOLANA_CHAIN_CATEGORY = 'solana' as const\n","export type NearSigningDefaults = {\n gasPriceYocto?: string\n}\n\nexport type NearChainDetail = {\n chainType: 'near'\n chainId: string\n chainName: string\n rpcGateway: string\n endpointKind: 'json-rpc'\n testnet: boolean\n nativeSymbol: string\n nativeDecimals: number\n signingDefaults?: NearSigningDefaults\n}\n\nexport interface NearProtocolContext {\n chainCategory: 'near'\n chainId: string\n rpcGateway: string\n executorAddress: string\n chainDetail: NearChainDetail\n useCustomFees: boolean\n keyGen: import('../../core/types.js').KeyGenSubset\n purposeText: string\n}\n\nexport class NotImplementedError extends Error {\n constructor(feature: string) {\n super(`${feature} is not implemented yet for chain category near`)\n this.name = 'NotImplementedError'\n }\n}\n\nexport async function buildNearMultisignBatch(): Promise<never> {\n throw new NotImplementedError('buildNearMultisignBatch')\n}\n\nexport const nearChainCategoryModule = {\n category: 'near' as const,\n}\n","export * from './types.js'\n\nexport const NEAR_CHAIN_CATEGORY = 'near' as const\n","import { getAddress, type Address } from 'viem'\nimport { parseEvmChainIdToNumber } from '../../../chains/evm/chainIdParse.js'\n\n/** Canonical Uniswap token-allowance contract on most EVM chains. */\nexport const PERMIT2_ADDRESS: Address = '0x000000000022D473030F116dDEE9F6B43aC78BA3'\n\nconst UNIVERSAL_ROUTER_SPENDER: Partial<Record<number, string>> = {\n 1: '0x66a9893cc07d91d95644aedd05d03f95e1dba8af',\n 5: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',\n 11155111: '0x3a9d48ab9751398bbfa63ad67599bb04e4bdf98b',\n 137: '0x1095692a6237d83c6a72f3f5efedb9a670c49223',\n 80001: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',\n 10: '0x851116d9223fabed8e56c0e6b8ad0c31d98b3507',\n 420: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',\n 42161: '0xa51afafe0263b40edaef0df8781ea9aa03e381a3',\n 421613: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',\n 42220: '0xcb695bc5D3Aa22cAD1E6DF07801b061a05A0233A',\n 44787: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',\n 56: '0x1906c1d672b88cd1b9ac7593301ca990f94eae07',\n 43114: '0x94b75331ae8d42c1b61065089b7d48fe14aa73b7',\n 84531: '0xd0872d928672ae2ff74bdb2f5130ac12229cafaf',\n 8453: '0x6fF5693b99212da76ad316178a184ab56d299b43',\n 81457: '0xeabbcb3e8e415306207ef514f660a3f820025be3',\n 7777777: '0x3315ef7ca28db74abadc6c44570efdf06b04b020',\n 324: '0x28731BCC616B5f51dD52CF2e4dF0E78dD1136C06',\n 480: '0x8ac7bee993bb44dab564ea4bc9ea67bf9eb5e743',\n 1301: '0xf70536b3bcc1bd1a972dc186a2cf84cc6da6be5d',\n 130: '0xef740bf23acae26f6492b10de645d6b98dc8eaf3',\n 10143: '0x3ae6d8a282d67893e17aa70ebffb33ee5aa65893',\n 84532: '0x492e6456d9528771018deb9e87ef7750ef184104',\n 1868: '0x0e2850543f69f678257266e0907ff9a58b3f13de',\n 143: '0x0d97dc33264bfc1c226207428a79b26757fb9dc3',\n 59144: '0x661e93cca42afacb172121ef892830ca3b70f08d',\n 4217: '0x1febb76be10aaf3a1402f04e8e835f2c382f7914',\n 196: '0x5507749f2c558bb3e162c6e90c314c092e7372ff',\n}\n\nexport function isUniswapV4ChainSupported(chainId: string | number | bigint | null | undefined): boolean {\n if (chainId == null) return false\n const n = parseEvmChainIdToNumber(chainId)\n if (Number.isNaN(n) || n < 0) return false\n const a = UNIVERSAL_ROUTER_SPENDER[n]\n return typeof a === 'string' && a.startsWith('0x')\n}\n\nexport function getUniswapUniversalRouterSpenderOrThrow(chainId: number): Address {\n const raw = UNIVERSAL_ROUTER_SPENDER[chainId]\n if (!raw || !raw.startsWith('0x')) {\n throw new Error(\n `No Uniswap Universal Router (spender) is configured for chainId ${chainId}. Add this chain to uniswap-v4/constants or use a chain supported by the Uniswap SDK.`,\n )\n }\n return getAddress(raw)\n}\n\nexport const MAX_UINT160 = (1n << 160n) - 1n\nexport const MAX_UINT48 = (1n << 48n) - 1n\n\nexport const UNISWAP_UNIVERSAL_ROUTER_DEFAULT_GAS_UNITS = 1_500_000n\nexport const UNISWAP_TRADE_BASE_DEFAULT = 'https://trade-api.gateway.uniswap.org/v1'\n/** Alternate LP API host (integration guide); trade-api `/v1/lp/*` is primary. */\nexport const UNISWAP_LP_API_BASE_DEFAULT = 'https://api.uniswap.org'\nexport const UNISWAP_UNIVERSAL_ROUTER_VERSION_DEFAULT = '2.0'\nexport const UNISWAP_SWAP_DEFAULT_EXPIRY_MINUTES = 30\nexport const UNISWAP_SWAP_DEFAULT_DEADLINE_SEC_OFFSET = UNISWAP_SWAP_DEFAULT_EXPIRY_MINUTES * 60\nexport const UNISWAP_LP_DEFAULT_EXPIRY_MINUTES = 30\nexport const UNISWAP_LP_DEFAULT_DEADLINE_SEC_OFFSET = UNISWAP_LP_DEFAULT_EXPIRY_MINUTES * 60\nexport const UNISWAP_LP_DEFAULT_SLIPPAGE_PERCENT = 0.5\n\n/** Position Manager (v4 periphery) per chain — for NFT position reads. */\nconst POSITION_MANAGER_BY_CHAIN: Partial<Record<number, string>> = {\n 1: '0xbd216513d74c8cf14cf4747e6aaa6420ff64ee9e',\n 10: '0x3c3ea4b57a46241e54610e5f022e5c45859a1017',\n 137: '0x1ec2ebf4f37e7363fdfe3551602425af0b3ceef9',\n 42161: '0xd88f38f930b7952f2db2432cb002e7abbf3dd869',\n 8453: '0x7C5f5A4bBd8fD63184577525326123B519429bDc',\n 11155111: '0x4B2C77d209D3405F41a037Ec6c77F7F5b8e2ca80',\n 130: '0x0d97dc33264bfc1c226207428a79b26757fb9dc3',\n 1868: '0x0e2850543f69f678257266e0907ff9a58b3f13de',\n 59144: '0x661e93cca42afacb172121ef892830ca3b70f08d',\n}\n\nexport function getUniswapV4PositionManagerOrThrow(chainId: number): Address {\n const raw = POSITION_MANAGER_BY_CHAIN[chainId]\n if (!raw || !raw.startsWith('0x') || raw.length !== 42) {\n throw new Error(\n `No Uniswap V4 PositionManager is configured for chainId ${chainId}. Add this chain to uniswap-v4/constants or pass position manager from LP API response.`,\n )\n }\n return getAddress(raw)\n}\n\nexport function tryGetUniswapV4PositionManager(chainId: number): Address | null {\n try {\n return getUniswapV4PositionManagerOrThrow(chainId)\n } catch {\n return null\n }\n}\n\n/**\n * First block where the Position Manager existed (for narrowing `eth_getLogs` scans).\n * Source: https://docs.uniswap.org/contracts/v4/deployments\n */\nconst POSITION_MANAGER_DEPLOY_BLOCK_BY_CHAIN: Partial<Record<number, bigint>> = {\n /** Ethereum mainnet — Uniswap v4 launch (Jan 2025). */\n 1: 22_938_741n,\n}\n\n/** Default `eth_getLogs` span — many free RPCs cap at 250 blocks (e.g. Nodies). */\nexport const UNISWAP_V4_LP_LOG_CHUNK_SIZE_DEFAULT = 200n\nexport const UNISWAP_V4_LP_LOG_CHUNK_SIZE_MIN = 10n\n\nexport function getUniswapV4PositionManagerDeployBlock(chainId: number): bigint | undefined {\n return POSITION_MANAGER_DEPLOY_BLOCK_BY_CHAIN[chainId]\n}\n\nexport const UNISWAP_V4_LP_MINT_DEFAULT_GAS_UNITS = 1_800_000n\nexport const UNISWAP_V4_LP_INCREASE_DEFAULT_GAS_UNITS = 1_500_000n\nexport const UNISWAP_V4_LP_DECREASE_DEFAULT_GAS_UNITS = 1_200_000n\nexport const UNISWAP_V4_LP_COLLECT_DEFAULT_GAS_UNITS = 900_000n\nexport const UNISWAP_V4_LP_ERC20_APPROVE_FALLBACK = 100_000n\nexport const UNISWAP_V4_LP_WETH_DEPOSIT_FALLBACK = 120_000n\n","import { formatUnits, parseUnits, getAddress, zeroAddress } from 'viem'\nimport {\n nodeFetchWithReadAuth,\n type NodeReadAuth,\n} from '@continuumdao/continuum-node-sdk'\n\n/** POST /v1/quote `type` (same as `uniswap_trade_quote.py` `--type`). */\nexport type UniswapQuoteTradeType = 'EXACT_INPUT' | 'EXACT_OUTPUT'\n\nconst DEFAULT_TRADE_BASE = 'https://trade-api.gateway.uniswap.org/v1'\n\nconst UNISWAP_QUOTE_HEADERS_BASE: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'User-Agent': 'ctm-mpc-defi uniswapTradeQuote/1.0 (TS)',\n}\n\n/** Parse chain id like Python: decimal or 0x hex. */\nexport function parseUniswapChainId(value: string | number): number {\n if (typeof value === 'number') {\n if (!Number.isInteger(value) || value < 0) {\n throw new TypeError('chainId number must be a non-negative integer')\n }\n return value\n }\n const t = value.trim()\n if (t.toLowerCase().startsWith('0x')) {\n return Number.parseInt(t, 16)\n }\n return Number.parseInt(t, 10)\n}\n\nfunction trimAddr(a: string): string {\n return a.trim()\n}\n\n/** `tokenIn` is the EVM address `0x0` used by the Trade API for the chain’s native (gas) token. */\nexport function isUniswapTokenInAddressNative(tokenIn: string | undefined | null): boolean {\n const t = (tokenIn ?? '').toString().trim()\n if (!t) return false\n try {\n return getAddress(t as `0x${string}`) === zeroAddress\n } catch {\n return t.toLowerCase() === '0x0000000000000000000000000000000000000000'\n }\n}\n\n/** `fullQuote` / stored quote response: top-level or nested has `quote.input` with a native or ERC-20 address. */\nexport function isUniswapFullQuoteResponseNativeIn(\n stored: Record<string, unknown> | null | undefined,\n): boolean {\n if (!stored) return false\n const q = (stored as { quote?: unknown }).quote\n if (!q || typeof q !== 'object' || Array.isArray(q)) return false\n const input = (q as Record<string, unknown>).input as Record<string, unknown> | undefined\n if (!input) return false\n const raw = (input.address ?? (input as { token?: string }).token ?? '').toString().trim()\n return isUniswapTokenInAddressNative(raw)\n}\n\n/**\n * GET /getKeyGenResultById and return `ethereumaddress` (swapper), same as\n * `uniswap_mpc_helpers.resolve_owner_from_keygen` in mpc-config.\n */\nexport async function fetchEthereumAddressForKeyGen(\n managementNodeUrl: string,\n keyGenId: string,\n readAuth: NodeReadAuth = { bearerOnGet: true, jwt: null },\n init?: RequestInit\n): Promise<string> {\n const base = managementNodeUrl.trim().replace(/\\/$/, '')\n if (!base) {\n throw new Error('managementNodeUrl is required to resolve keyGen')\n }\n const id = (keyGenId || '').trim()\n if (!id) {\n throw new Error('keyGen is required')\n }\n const url = `${base}/getKeyGenResultById?id=${encodeURIComponent(id)}`\n const res = await nodeFetchWithReadAuth(url, { ...init, method: 'GET', cache: 'no-store' }, readAuth)\n if (!res.ok) {\n const t = await res.text().catch(() => '')\n throw new Error(\n `getKeyGenResultById HTTP ${res.status}: ${t || res.statusText}`.trim()\n )\n }\n const raw = (await res.json()) as {\n Data?: { ethereumaddress?: string; [k: string]: unknown }\n data?: { ethereumaddress?: string; [k: string]: unknown }\n }\n const d = raw.Data ?? raw.data\n const eth = d?.ethereumaddress\n if (typeof eth !== 'string' || !eth.trim()) {\n throw new Error('getKeyGenResultById: ethereumaddress missing for this keyGen')\n }\n return eth.trim()\n}\n\nexport interface UniswapTradeQuoteParams {\n amount: string\n tokenIn: string\n tokenOut: string\n uniswapApiKey: string\n /**\n * KeyGen id — used to resolve `swapper` from GET /getKeyGenResultById unless `swapper` is set.\n * Required unless `swapper` is set.\n */\n keyGen?: string\n type: UniswapQuoteTradeType\n /**\n * Slippage as percent, e.g. `0.5` for 0.5%. If omitted, the body uses\n * `autoSlippage: \"DEFAULT\"` (same as the Python script when `--slippage` is not set).\n */\n slippage?: number | string\n /**\n * Chain id for the input side (`tokenInChainId` in the HTTP body; Python `--chain-id`).\n * You may set **`chainId` or `tokenInChainId`** (same meaning); if both are set, `chainId` wins.\n * Same-chain quote: set one chain here and omit `tokenOutChainId` (or set both to the same id).\n */\n chainId?: string | number\n /**\n * Same as `chainId` (input chain). If `chainId` is omitted, this must be set.\n */\n tokenInChainId?: string | number\n /**\n * Output chain id; defaults to the input chain when omitted (Python: empty `--token-out-chain-id`).\n */\n tokenOutChainId?: string | number\n /**\n * When `true`, sends `x-permit2-disabled: true` (Uniswap’s header for classic ERC-20 allowance; no permitData in the response).\n * Omit or set `false` for the default Trade API routing (default).\n */\n permit2Disabled?: boolean\n /**\n * MPC wallet (swapper) address. If omitted, `managementNodeUrl` is used with `keyGen`\n * to call GET /getKeyGenResultById.\n */\n swapper?: `0x${string}` | string\n /**\n * Management node base URL (MPC), required when `swapper` is not provided.\n */\n managementNodeUrl?: string\n /** For Browser HTTPS: Bearer on GET to /getKeyGenResultById. */\n nodeReadAuth?: NodeReadAuth\n /** Trade API base without `/quote` (default: Uniswap gateway v1). */\n baseUrl?: string\n /** `x-universal-router-version` (default `2.0`, aligned with Python / v4). */\n universalRouterVersion?: string\n signal?: AbortSignal\n /** Override for tests. */\n fetchImpl?: typeof fetch\n}\n\n/**\n * Build the same JSON body as `uniswap_trade_quote.py` (minus `swapper`, which you must set).\n */\n/**\n * `tokenInChainId` in the HTTP body (Python `--chain-id`).\n * Order: `chainId`, then `tokenInChainId`, else if only `tokenOutChainId` is set use it\n * (same in/out, e.g. same-chain with a single id).\n */\nfunction resolveInputChainId(\n p: Pick<UniswapTradeQuoteParams, 'chainId' | 'tokenInChainId' | 'tokenOutChainId'>\n): string | number {\n if (p.chainId !== undefined && p.chainId !== null && String(p.chainId).trim() !== '') {\n return p.chainId\n }\n if (p.tokenInChainId !== undefined && p.tokenInChainId !== null && String(p.tokenInChainId).trim() !== '') {\n return p.tokenInChainId\n }\n if (p.tokenOutChainId !== undefined && p.tokenOutChainId !== null && String(p.tokenOutChainId).trim() !== '') {\n return p.tokenOutChainId\n }\n throw new Error('Set chainId, tokenInChainId, or tokenOutChainId (same-chain) for the input side')\n}\n\nexport function buildUniswapQuoteRequestBody(\n args: Pick<\n UniswapTradeQuoteParams,\n | 'type'\n | 'amount'\n | 'tokenIn'\n | 'tokenOut'\n | 'slippage'\n | 'chainId'\n | 'tokenInChainId'\n | 'tokenOutChainId'\n > & { swapper: string }\n): Record<string, unknown> {\n const cIn = parseUniswapChainId(resolveInputChainId(args))\n const cOut =\n args.tokenOutChainId !== undefined && args.tokenOutChainId !== null && String(args.tokenOutChainId).trim() !== ''\n ? parseUniswapChainId(args.tokenOutChainId)\n : cIn\n const body: Record<string, unknown> = {\n type: args.type,\n amount: String(args.amount).trim(),\n tokenInChainId: cIn,\n tokenOutChainId: cOut,\n tokenIn: trimAddr(args.tokenIn),\n tokenOut: trimAddr(args.tokenOut),\n swapper: trimAddr(args.swapper),\n }\n if (args.slippage !== undefined && args.slippage !== null && String(args.slippage).trim() !== '') {\n const s =\n typeof args.slippage === 'number' ? args.slippage : Number.parseFloat(String(args.slippage).trim())\n if (Number.isNaN(s)) {\n throw new TypeError('slippage must be a number or a numeric string')\n }\n body.slippageTolerance = s\n } else {\n body.autoSlippage = 'DEFAULT'\n }\n return body\n}\n\n/**\n * Pull a user-facing string from Uniswap / generic JSON error bodies.\n */\nexport function errorMessageFromUniswapJsonBody(value: unknown): string | null {\n if (value == null) return null\n if (typeof value === 'string') {\n const t = value.trim()\n return t || null\n }\n if (typeof value !== 'object') return null\n if (Array.isArray(value)) {\n if (value.length === 0) return null\n return errorMessageFromUniswapJsonBody(value[0])\n }\n const o = value as Record<string, unknown>\n /** Uniswap Trade API, e.g. 404: `{ errorCode, detail, requestId }` */\n if (typeof o.detail === 'string' && o.detail.trim()) {\n const base = o.detail.trim()\n const code = typeof o.errorCode === 'string' && o.errorCode.trim() ? o.errorCode.trim() : ''\n const req = typeof o.requestId === 'string' && o.requestId.trim() ? o.requestId.trim() : ''\n if (code) {\n return req ? `${base} (${code}) [${req}]` : `${base} (${code})`\n }\n return req ? `${base} [${req}]` : base\n }\n if (typeof o.errorCode === 'string' && o.errorCode.trim()) {\n return o.errorCode.trim()\n }\n for (const k of ['message', 'detail', 'description', 'title', 'reason']) {\n const v = o[k]\n if (typeof v === 'string' && v.trim()) return v.trim()\n }\n if (typeof o.error === 'string' && o.error.trim()) return o.error.trim()\n if (o.error != null && typeof o.error === 'object') {\n const inner = errorMessageFromUniswapJsonBody(o.error)\n if (inner) return inner\n }\n if (Array.isArray(o.errors) && o.errors.length > 0) {\n const inner = errorMessageFromUniswapJsonBody(o.errors[0])\n if (inner) return inner\n }\n if (typeof o.code === 'string' && o.code.trim()) return o.code.trim()\n return null\n}\n\nfunction bodyLooksLikeHtml(t: string): boolean {\n const s = t.slice(0, 256).trimStart()\n return s.startsWith('<!') || s.toLowerCase().startsWith('<html')\n}\n\nfunction titleFromHtml(t: string): string | null {\n const m = t.match(/<title[^>]*>([^<]+)<\\/title>/i)\n if (!m?.[1]) return null\n const s = m[1].replace(/\\s+/g, ' ').trim()\n return s || null\n}\n\n/**\n * User-facing string from an HTTP body: JSON `message` / `error` / `detail` first,\n * else a short plain-text / HTML page title, not the raw document (avoids huge HTML in UI).\n */\nexport function messageFromUniswapHttpResponseBody(\n text: string,\n status: number,\n statusText = ''\n): string {\n const raw = (text ?? '').trim()\n const st = (statusText ?? '').trim()\n if (!raw) {\n if (status > 0) {\n return st ? `HTTP ${status} (${st})` : `HTTP ${status}`\n }\n return 'Empty response'\n }\n if (bodyLooksLikeHtml(raw)) {\n const title = titleFromHtml(raw)\n if (title) {\n return status > 0 ? `HTTP ${status}: ${title}` : title\n }\n return status > 0\n ? 'HTTP ' +\n String(status) +\n ': response was not JSON (HTML or error page). Check API key, token pair, and network.'\n : 'Response was not JSON (HTML or error page).'\n }\n const forParse = raw.replace(/^\\uFEFF/, '')\n try {\n const j = JSON.parse(forParse) as unknown\n if (j && typeof j === 'object') {\n const msg = errorMessageFromUniswapJsonBody(j)\n if (msg) {\n if (status >= 400) {\n return st ? `${msg} (HTTP ${status} ${st})` : `${msg} (HTTP ${status})`\n }\n return msg\n }\n }\n } catch {\n /* not JSON */\n }\n const oneLine = raw.replace(/\\s+/g, ' ').trim()\n const short = oneLine.length > 500 ? `${oneLine.slice(0, 500)}…` : oneLine\n if (status > 0) {\n return st && !short ? `HTTP ${status} (${st})` : st ? `HTTP ${status}: ${short} (${st})` : `HTTP ${status}: ${short}`\n }\n return short\n}\n\n/**\n * `POST` Uniswap Trade API `/v1/quote` — TypeScript version of\n * `mpc-config/recipes/uniswapV4/uniswap_trade_quote.py` (core HTTP call + KeyGen → swapper).\n *\n * CORS: calling the Trade API from a browser may be blocked. Prefer a server / route\n * handler, or use this in Node. KeyGen resolution uses a GET to your management node\n * and follows the same read-auth pattern as the app.\n */\nexport async function uniswapTradeQuote(\n args: UniswapTradeQuoteParams\n): Promise<Record<string, unknown>> {\n const apiKey = (args.uniswapApiKey || '').trim()\n if (!apiKey) {\n throw new Error('uniswapApiKey (x-api-key) is required')\n }\n const keyGen = (args.keyGen || '').trim()\n\n let swapper: string\n if ((args.swapper || '').trim()) {\n swapper = trimAddr(args.swapper as string)\n } else {\n if (!keyGen) {\n throw new Error('keyGen is required when swapper is not provided')\n }\n const mpc = (args.managementNodeUrl || '').trim()\n if (!mpc) {\n throw new Error('managementNodeUrl is required when swapper is not provided (to resolve keyGen)')\n }\n swapper = await fetchEthereumAddressForKeyGen(\n mpc,\n keyGen,\n args.nodeReadAuth ?? { bearerOnGet: true, jwt: null }\n )\n }\n\n const base =\n (args.baseUrl && args.baseUrl.trim()) ? args.baseUrl.trim().replace(/\\/$/, '') : DEFAULT_TRADE_BASE\n const quoteUrl = `${base}/quote`\n const urv = (args.universalRouterVersion && args.universalRouterVersion.trim()) || '2.0'\n\n const body = buildUniswapQuoteRequestBody({ ...args, swapper })\n const nativeIn = isUniswapTokenInAddressNative(args.tokenIn)\n const headers: Record<string, string> = {\n ...UNISWAP_QUOTE_HEADERS_BASE,\n 'x-api-key': apiKey,\n 'x-universal-router-version': urv,\n 'x-permit2-disabled': args.permit2Disabled === true ? 'true' : 'false',\n /** Native (0x0) as token in: Trade API needs this for classic routes and payable /swap. */\n 'x-erc20eth-enabled': nativeIn ? 'true' : 'false',\n }\n\n const fetchFn = args.fetchImpl ?? globalThis.fetch\n const res = await fetchFn(quoteUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: args.signal,\n })\n const text = await res.text()\n if (!res.ok) {\n throw new Error(messageFromUniswapHttpResponseBody(text, res.status, res.statusText))\n }\n const forParse = text.replace(/^\\uFEFF/, '')\n try {\n return JSON.parse(forParse) as Record<string, unknown>\n } catch {\n throw new Error(\n `Trade API: ${messageFromUniswapHttpResponseBody(text, res.status, res.statusText)}`\n )\n }\n}\n\n/**\n * Single-line JSON for mpc-config `uniswap_trade_swap.py --quote-json` (compact quote body).\n */\nexport function uniswapQuoteToJsonQuoteOneLine(quote: Record<string, unknown>): string {\n return JSON.stringify(quote)\n}\n\n/**\n * `quote.input.amount` / `quote.output.amount` as bigints, if present (classic response).\n */\nexport function parseUniswapQuoteClassicInOut(\n res: Record<string, unknown>\n): { inputWei: bigint; outputWei: bigint } | null {\n const inner = res.quote\n if (!inner || typeof inner !== 'object' || Array.isArray(inner)) return null\n const q = inner as Record<string, unknown>\n const input = q.input as { amount?: string } | undefined\n const output = q.output as { amount?: string } | undefined\n const inAm = input?.amount\n let outAm = output?.amount\n if (typeof outAm !== 'string' || !outAm) {\n const agg = q.aggregatedOutputs\n if (Array.isArray(agg) && agg.length > 0) {\n const first = agg[0] as { amount?: string } | undefined\n if (typeof first?.amount === 'string' && first.amount) {\n outAm = first.amount\n }\n }\n }\n if (typeof inAm !== 'string' || !inAm || typeof outAm !== 'string' || !outAm) return null\n try {\n return { inputWei: BigInt(inAm), outputWei: BigInt(outAm) }\n } catch {\n return null\n }\n}\n\n/**\n * Fields from Uniswap Trade API `200` `quote` (e.g. {@link https://api-docs.uniswap.org/api-reference/swapping/quote} `ClassicQuote`):\n * - `slippage` — slippage tolerance (percent) used for the quote\n * - `priceImpact` — “impact the trade has on the market price of the pool, between 0-100 percent”\n */\nexport function parseUniswapQuoteSlippageInfo(res: Record<string, unknown>): {\n slippageTolerancePercent: number | null\n priceImpactPercent: number | null\n} {\n const inner = res.quote\n if (!inner || typeof inner !== 'object' || Array.isArray(inner)) {\n return { slippageTolerancePercent: null, priceImpactPercent: null }\n }\n const q = inner as Record<string, unknown>\n const sRaw = q.slippage ?? q.slippageTolerance\n let slippageTolerancePercent: number | null = null\n if (typeof sRaw === 'number' && Number.isFinite(sRaw)) {\n slippageTolerancePercent = sRaw\n } else if (typeof sRaw === 'string' && sRaw.trim()) {\n const p = Number.parseFloat(sRaw.trim().replace(/,/g, ''))\n if (Number.isFinite(p)) slippageTolerancePercent = p\n }\n const piRaw = q.priceImpact\n let priceImpactPercent: number | null = null\n if (typeof piRaw === 'number' && Number.isFinite(piRaw)) {\n priceImpactPercent = piRaw\n } else if (typeof piRaw === 'string' && piRaw.trim()) {\n const p = Number.parseFloat(piRaw.trim().replace(/,/g, ''))\n if (Number.isFinite(p)) priceImpactPercent = p\n }\n return { slippageTolerancePercent, priceImpactPercent }\n}\n\n/** Compact percent for UI (e.g. 0.5, 1.2345). */\nexport function formatUniswapPercentForUi(n: number): string {\n if (!Number.isFinite(n)) return '—'\n const t = n.toFixed(4).replace(/\\.?0+$/, '')\n return t || '0'\n}\n\n/** Human string for a modal amount field, trimmed of trailing fraction zeros. */\nexport function formatUniswapAmountFieldFromWei(wei: bigint, decimals: number): string {\n const s = formatUnits(wei, decimals)\n if (!s.includes('.')) return s\n const t = s.replace(/0+$/, '')\n return t.endsWith('.') ? t.slice(0, -1) : t\n}\n\n/**\n * One-line prefill for multi-sign \"purpose\" (user may append context below in the same field).\n */\nexport function buildUniswapV4PurposePrefill(args: {\n tradeType: UniswapQuoteTradeType\n tokenInSymbol: string\n tokenOutSymbol: string\n tokenInDecimals: number\n tokenOutDecimals: number\n amountInput: string\n quote: Record<string, unknown> | null\n slippageInput: string\n chainName: string\n chainId: number\n}): string {\n const symIn = (args.tokenInSymbol || '').trim() || 'token in'\n const symOut = (args.tokenOutSymbol || '').trim() || 'token out'\n const rawS = String(args.slippageInput || '0.5').trim().replace(/,/g, '')\n const parsedSlip = Number.parseFloat(rawS)\n const slip = Number.isFinite(parsedSlip) ? parsedSlip : 0.5\n const slipText = (Math.round(slip * 100) / 100).toString()\n const p = args.quote != null ? parseUniswapQuoteClassicInOut(args.quote) : null\n let inPart = '…'\n let outPart = '…'\n if (p) {\n inPart = `${formatUniswapAmountFieldFromWei(p.inputWei, args.tokenInDecimals)} ${symIn}`.replace(/\\s+/g, ' ').trim()\n outPart = `${formatUniswapAmountFieldFromWei(p.outputWei, args.tokenOutDecimals)} ${symOut}`.replace(/\\s+/g, ' ').trim()\n } else if (args.tradeType === 'EXACT_INPUT' && args.amountInput.trim()) {\n try {\n const w = parseUnits(args.amountInput.trim(), args.tokenInDecimals)\n inPart = `${formatUniswapAmountFieldFromWei(w, args.tokenInDecimals)} ${symIn}`.replace(/\\s+/g, ' ').trim()\n outPart = `… ${symOut}`\n } catch {\n /* keep … */\n }\n }\n const cname = (args.chainName || '').trim() || 'chain'\n return `Swap ${inPart} for ${outPart} with a slippage of ${slipText}% on ${cname} (chainId ${args.chainId})`\n}\n\n/**\n * Human-readable lines from a Trade API `/quote` 200 JSON body.\n * Classic quotes expose `quote.input` / `quote.output` with `amount` (base units as string).\n */\nexport function formatUniswapQuoteForDisplay(\n res: Record<string, unknown>,\n args: {\n tradeType: UniswapQuoteTradeType\n tokenInDecimals: number\n tokenOutDecimals: number\n tokenInSymbol: string\n tokenOutSymbol: string\n }\n): { title: string; lines: string[]; rawJson: string } {\n const { tradeType, tokenInDecimals, tokenOutDecimals, tokenInSymbol, tokenOutSymbol } = args\n const rawJson = JSON.stringify(res, null, 2)\n const routing = typeof res.routing === 'string' ? res.routing : undefined\n const requestId = typeof res.requestId === 'string' ? res.requestId : undefined\n\n const inner = res.quote\n if (inner && typeof inner === 'object' && !Array.isArray(inner)) {\n const q = inner as Record<string, unknown>\n const input = q.input as { amount?: string; token?: string } | undefined\n const output = q.output as { amount?: string; token?: string } | undefined\n const inAm = input?.amount\n const outAm = output?.amount\n if (typeof inAm === 'string' && inAm && typeof outAm === 'string' && outAm) {\n try {\n const inH = formatUnits(BigInt(inAm), tokenInDecimals)\n const outH = formatUnits(BigInt(outAm), tokenOutDecimals)\n const title =\n tradeType === 'EXACT_INPUT'\n ? `≈ ${outH} ${tokenOutSymbol} for ${inH} ${tokenInSymbol} (est.)`\n : `≈ ${inH} ${tokenInSymbol} for ${outH} ${tokenOutSymbol} (est.)`\n const lines: string[] = [\n `Input: ${inH} ${tokenInSymbol} (${inAm} wei)`,\n `Output: ${outH} ${tokenOutSymbol} (${outAm} wei)`,\n ]\n if (routing) lines.push(`Route: ${routing}`)\n if (requestId) lines.push(`Request: ${requestId.slice(0, 24)}…`)\n return { title, lines, rawJson }\n } catch {\n // non-classic or bigint parse error\n }\n }\n }\n\n const lines: string[] = ['(Could not parse classic input/output; see raw JSON below.)']\n if (routing) lines.push(`Route: ${routing}`)\n if (requestId) lines.push(`Request: ${requestId}`)\n return { title: 'Quote received', lines, rawJson }\n}\n","import {\n getAddress,\n encodeFunctionData,\n decodeFunctionData,\n erc20Abi,\n zeroAddress,\n type Address,\n type PublicClient,\n} from 'viem'\nimport { type KeyGenSubsetForPermit } from '../../../core/types.js'\nimport { buildEvmMultisignBatch } from '../../../chains/evm/buildBatch.js'\nimport type { EvmTxStep } from '../../../chains/evm/types.js'\nimport {\n PERMIT2_ADDRESS,\n getUniswapUniversalRouterSpenderOrThrow,\n MAX_UINT160,\n MAX_UINT48,\n UNISWAP_TRADE_BASE_DEFAULT,\n UNISWAP_UNIVERSAL_ROUTER_VERSION_DEFAULT,\n UNISWAP_SWAP_DEFAULT_EXPIRY_MINUTES,\n UNISWAP_SWAP_DEFAULT_DEADLINE_SEC_OFFSET,\n UNISWAP_UNIVERSAL_ROUTER_DEFAULT_GAS_UNITS,\n} from './constants.js'\nimport {\n isUniswapFullQuoteResponseNativeIn,\n messageFromUniswapHttpResponseBody,\n parseUniswapQuoteClassicInOut,\n} from './quote.js'\n\n/** Parse `gasLimit` from Trade API or chain config (decimal or 0x hex). */\nfunction parseOptionalGasLimitString(raw: string | number | undefined): bigint | null {\n if (raw == null) return null\n const s = String(raw).trim()\n if (!s) return null\n try {\n if (/^0x[0-9a-fA-F]+$/.test(s)) return BigInt(s)\n return BigInt(s)\n } catch {\n return null\n }\n}\n\nfunction parseExtraJsonObject(\n detail: Record<string, unknown> | null | undefined\n): Record<string, unknown> | null {\n if (!detail) return null\n const raw = detail.ExtraJSON ?? detail.extraJSON\n if (raw == null) return null\n if (typeof raw === 'object' && !Array.isArray(raw)) return raw as Record<string, unknown>\n if (typeof raw === 'string' && raw.trim()) {\n try {\n const p = JSON.parse(raw) as unknown\n if (p && typeof p === 'object' && !Array.isArray(p)) return p as Record<string, unknown>\n } catch {\n return null\n }\n }\n return null\n}\n\nfunction uniswapV4EvmTypeFromBatchMeta(\n ex: Record<string, unknown> | null,\n batchIndex: number\n): boolean {\n if (!ex) return false\n const bm = ex.batchMeta\n if (!Array.isArray(bm) || !bm[batchIndex] || typeof bm[batchIndex] !== 'object' || Array.isArray(bm[batchIndex])) {\n return false\n }\n const evm0 = (bm[batchIndex] as Record<string, unknown>).evm\n if (!evm0 || typeof evm0 !== 'object' || Array.isArray(evm0)) return false\n return String((evm0 as Record<string, unknown>).type ?? '') === 'uniswap_v4_swap_tx'\n}\n\nfunction uniswapV4AuditFromDetail(\n ex: Record<string, unknown> | null,\n batchIndex?: number\n): Record<string, unknown> | undefined {\n if (!ex) return undefined\n const index = batchIndex != null && batchIndex >= 0 ? batchIndex : 0\n const bm = ex.batchMeta\n if (Array.isArray(bm) && bm[index] && typeof bm[index] === 'object' && !Array.isArray(bm[index])) {\n const nested = (bm[index] as Record<string, unknown>).uniswapV4\n if (nested && typeof nested === 'object' && !Array.isArray(nested)) {\n return nested as Record<string, unknown>\n }\n }\n const root = ex.uniswapV4\n if (root && typeof root === 'object' && !Array.isArray(root)) return root as Record<string, unknown>\n return undefined\n}\n\n/**\n * When `batchIndex` is set, check `batchMeta[i].evm`. Without `batchIndex`, also check `batchMeta[0]`\n * (native ETH-in single-tx requests store evm only under batchMeta, not top-level extraJSON.evm).\n */\nexport function isUniswapV4SwapEvmSignRequest(\n detail: Record<string, unknown> | null | undefined,\n batchIndex?: number\n): boolean {\n const ex = parseExtraJsonObject(detail)\n if (batchIndex != null && batchIndex >= 0) {\n if (uniswapV4EvmTypeFromBatchMeta(ex, batchIndex)) return true\n } else if (uniswapV4EvmTypeFromBatchMeta(ex, 0)) {\n return true\n }\n const evm = ex?.evm\n if (!evm || typeof evm !== 'object' || Array.isArray(evm)) return false\n return String((evm as Record<string, unknown>).type ?? '') === 'uniswap_v4_swap_tx'\n}\n\n/**\n * Gas units for Get Sig without `eth_estimateGas` (same calldata often reverts on estimate).\n * Order: proposal row[i] (or [0] / single `txParams`) / ExtraJSON uniswapV4 (audit, quote).\n * Pass `batchIndex` when the sign request is a multi-tx batch.\n */\nexport function resolveRouterSwapGasUnitsFromSignRequest(\n detail: Record<string, unknown> | null | undefined,\n batchIndex?: number\n): bigint | null {\n if (!detail) return null\n const propBatch = (detail.proposal_tx_params ??\n detail.proposalTxParams ??\n detail.ProposalTxParams) as unknown\n const index = batchIndex != null && batchIndex >= 0 ? batchIndex : 0\n if (Array.isArray(propBatch) && propBatch.length > index) {\n const row = propBatch[index]\n if (row && typeof row === 'object' && !Array.isArray(row)) {\n const r = row as Record<string, unknown>\n const gl = parseOptionalGasLimitString(\n (r.gas_limit ?? r.gasLimit ?? r.GasLimit) as string | number | undefined\n )\n if (gl != null && gl > 0n) return gl\n }\n }\n if (batchIndex == null || batchIndex === 0) {\n const tp = (detail.txParams ?? detail.TxParams) as Record<string, unknown> | undefined\n if (tp && typeof tp === 'object') {\n const gl = parseOptionalGasLimitString(\n (tp.gasLimit ?? tp.GasLimit ?? tp.txGasLimit) as string | number | undefined\n )\n if (gl != null && gl > 0n) return gl\n }\n }\n const ex = parseExtraJsonObject(detail)\n const u4 = uniswapV4AuditFromDetail(ex, batchIndex)\n if (u4) {\n const uc = u4.uniswapCreateSwap as Record<string, unknown> | undefined\n const gb = (uc?.gasBuildSwap ?? uc?.gasBuild) as Record<string, unknown> | undefined\n const base = parseOptionalGasLimitString(gb?.baseGasUnits as string | number | undefined)\n if (base != null && base > 0n) return base\n const snap = u4.fullQuoteFromPermitSnapshot as Record<string, unknown> | undefined\n const quote = snap?.quote as Record<string, unknown> | undefined\n const gue = parseOptionalGasLimitString(quote?.gasUseEstimate as string | number | undefined)\n if (gue != null && gue > 0n) return gue\n }\n return null\n}\n\n/**\n * Uniswap POST /swap `swap.gasLimit` is derived from the route; prefer it so we don't rely on\n * `eth_estimateGas`, which often reverts for Universal Router bundles (RPC simulation quirks).\n * When we must fall back, use a generous floor (L2s; adjust via chain `gasLimit` in app config).\n */\n/** Public for Get Sig when `eth_estimateGas` reverts on Universal Router calldata. */\nexport { UNISWAP_UNIVERSAL_ROUTER_DEFAULT_GAS_UNITS } from './constants.js'\nconst DEFAULT_UNIVERSAL_ROUTER_GAS_FALLBACK = UNISWAP_UNIVERSAL_ROUTER_DEFAULT_GAS_UNITS\n\nexport {\n UNISWAP_TRADE_BASE_DEFAULT,\n UNISWAP_UNIVERSAL_ROUTER_VERSION_DEFAULT,\n UNISWAP_SWAP_DEFAULT_EXPIRY_MINUTES,\n UNISWAP_SWAP_DEFAULT_DEADLINE_SEC_OFFSET,\n} from './constants.js'\n\n/** `deadline` = `now` + `expiryMinutes * 60` (seconds). */\nexport function swapTransactionDeadlineUnixFromExpiryMinutes(\n expiryMinutes: number,\n nowSec: number = Math.floor(Date.now() / 1000)\n): number {\n const m = Number.isFinite(expiryMinutes) && expiryMinutes > 0 ? expiryMinutes : UNISWAP_SWAP_DEFAULT_EXPIRY_MINUTES\n return nowSec + Math.floor(m * 60)\n}\n\nfunction swapDeadlineUnixSeconds(args: { swapTransactionDeadlineUnix?: number }): number {\n const now = Math.floor(Date.now() / 1000)\n if (\n args.swapTransactionDeadlineUnix != null &&\n Number.isFinite(args.swapTransactionDeadlineUnix) &&\n args.swapTransactionDeadlineUnix > now\n ) {\n return Math.floor(args.swapTransactionDeadlineUnix)\n }\n return swapTransactionDeadlineUnixFromExpiryMinutes(UNISWAP_SWAP_DEFAULT_EXPIRY_MINUTES, now)\n}\n\n/** The stored `uniswapTradeQuote` is the full `POST /quote` JSON; `/swap` wants the **inner** classic quote. */\nexport function getClassicQuoteFromStoredUniswapResponse(stored: Record<string, unknown> | null | undefined): unknown {\n if (!stored) return null\n const q = (stored as Record<string, unknown>).quote\n return q != null && typeof q === 'object' ? q : null\n}\n\ntype TransactionRequest = {\n to: string\n from?: string\n data: string\n value: string\n /** Trade API or eth-style field name */\n gasLimit?: string\n gas?: string\n chainId?: number\n}\n\ntype CreateSwapResponse = {\n requestId?: string\n swap: TransactionRequest\n gasFee?: string\n}\n\n/**\n * `POST /v1/swap` — builds swap calldata (Universal Router) from a quote fetched with classic-allowance header `x-permit2-disabled: true`.\n * @see https://api-docs.uniswap.org/api-reference/swapping/swap\n */\nexport async function uniswapCreateSwap(\n args: {\n uniswapApiKey: string\n baseUrl?: string\n /** Full `POST /quote` JSON (must include classic `quote`). */\n fullQuoteFromPermit: Record<string, unknown>\n universalRouterVersion?: string\n fetchImpl?: typeof fetch\n /**\n * In the browser, direct `POST` to `trade-api.gateway.uniswap.org` is blocked by CORS.\n * When true (default in browser), the request goes to same-origin `POST /api/uniswap/swap` which proxies server-side. Set `false` to force a direct call (e.g. tests, Node scripts).\n */\n useServerProxy?: boolean\n /**\n * Universal Router swap deadline (unix seconds). Defaults to now + {@link UNISWAP_SWAP_DEFAULT_DEADLINE_SEC_OFFSET}.\n * Omitting this caused short API defaults and `TransactionDeadlinePassed` after MPC delay.\n */\n swapTransactionDeadlineUnix?: number\n }\n): Promise<CreateSwapResponse> {\n const deadline = swapDeadlineUnixSeconds(args)\n const useProxy = (args.useServerProxy !== false) && typeof globalThis !== 'undefined' && typeof (globalThis as { window?: unknown }).window !== 'undefined'\n if (useProxy) {\n const proxyPayload: Record<string, unknown> = {\n uniswapApiKey: args.uniswapApiKey,\n fullQuoteFromPermit: args.fullQuoteFromPermit,\n universalRouterVersion: args.universalRouterVersion,\n baseUrl: args.baseUrl,\n swapTransactionDeadlineUnix: deadline,\n }\n const res = await (args.fetchImpl ?? globalThis.fetch)('/api/uniswap/swap', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(proxyPayload),\n credentials: 'same-origin',\n })\n const text = await res.text()\n if (!res.ok) {\n let errMsg = res.statusText\n try {\n const j = JSON.parse(text) as { error?: string }\n if (j && typeof j.error === 'string' && j.error.trim()) errMsg = j.error.trim()\n } catch {\n if (text.trim()) errMsg = text.slice(0, 500)\n }\n throw new Error(`Uniswap swap proxy failed: ${errMsg}`)\n }\n const parsed = JSON.parse(text) as CreateSwapResponse\n if (!parsed?.swap || typeof parsed.swap !== 'object') {\n throw new Error('Uniswap /swap (proxy): missing `swap` in response.')\n }\n return parsed\n }\n const base = (args.baseUrl ?? UNISWAP_TRADE_BASE_DEFAULT).replace(/\\/$/, '')\n const url = `${base}/swap`\n const classic = getClassicQuoteFromStoredUniswapResponse(args.fullQuoteFromPermit) as Record<string, unknown> | null\n if (!classic) {\n throw new Error('Stored Uniswap quote is missing a classic `quote` object; cannot build swap calldata.')\n }\n const body: Record<string, unknown> = {\n quote: classic,\n deadline,\n }\n const urv = (args.universalRouterVersion ?? UNISWAP_UNIVERSAL_ROUTER_VERSION_DEFAULT).trim() || '2.0'\n const fn = args.fetchImpl ?? globalThis.fetch\n const nativeIn = isUniswapFullQuoteResponseNativeIn(args.fullQuoteFromPermit)\n const res = await fn(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': args.uniswapApiKey.trim(),\n 'x-universal-router-version': urv,\n 'x-erc20eth-enabled': nativeIn ? 'true' : 'false',\n 'x-permit2-disabled': 'true',\n },\n body: JSON.stringify(body),\n })\n const text = await res.text()\n if (!res.ok) {\n throw new Error(\n `Uniswap POST /swap failed: ${messageFromUniswapHttpResponseBody(text, res.status, res.statusText)}`\n )\n }\n const parsed = JSON.parse(text) as CreateSwapResponse\n if (!parsed?.swap || typeof parsed.swap !== 'object') {\n throw new Error('Uniswap /swap: missing `swap` in response.')\n }\n return parsed\n}\n\ntype ChainRow = {\n legacy?: boolean\n gasLimit?: number\n gasMultiplier?: number\n gasPrice?: number\n baseFee?: number\n priorityFee?: number\n baseFeeMultiplier?: number\n}\n\nasync function estimateUniswapRouterSwapGas(args: {\n publicClient: PublicClient\n executor: Address\n to: Address\n data: `0x${string}`\n value: bigint\n swapRecord: Record<string, unknown>\n useCustomGas: boolean\n chainDetail: ChainRow\n}): Promise<{\n baseGasUnits: bigint\n source: 'tradeApi' | 'rpcEstimate' | 'estimateFailedFallback'\n estimateGasError?: string\n}> {\n const fromTradeApi =\n parseOptionalGasLimitString(args.swapRecord.gasLimit as string | number | undefined) ??\n parseOptionalGasLimitString(args.swapRecord.gas as string | number | undefined)\n if (fromTradeApi != null && fromTradeApi > 0n) {\n return { baseGasUnits: fromTradeApi, source: 'tradeApi' }\n }\n try {\n const est = await args.publicClient.estimateGas({\n to: args.to,\n data: args.data,\n value: args.value,\n account: args.executor,\n })\n return { baseGasUnits: est, source: 'rpcEstimate' }\n } catch (e) {\n const estimateGasError = e instanceof Error ? e.message : String(e)\n const minRouterGas = 500_000n\n if (args.useCustomGas) {\n const cfg =\n args.chainDetail?.gasLimit != null\n ? parseOptionalGasLimitString(String(args.chainDetail.gasLimit))\n : null\n if (cfg != null && cfg >= minRouterGas) {\n return { baseGasUnits: cfg, source: 'estimateFailedFallback', estimateGasError }\n }\n }\n return {\n baseGasUnits: DEFAULT_UNIVERSAL_ROUTER_GAS_FALLBACK,\n source: 'estimateFailedFallback',\n estimateGasError,\n }\n }\n}\n\nconst permit2ApproveRouterAbi = [\n {\n name: 'approve',\n type: 'function',\n stateMutability: 'nonpayable',\n inputs: [\n { name: 'token', type: 'address' },\n { name: 'spender', type: 'address' },\n { name: 'amount', type: 'uint160' },\n { name: 'expiration', type: 'uint48' },\n ],\n outputs: [],\n },\n] as const\n\n/**\n * Trade `POST /swap` often returns calldata for `execute(router, token, amount, commands, inputs, deadline)` (dispatcher\n * entry). The **router** argument is the allowance-hub **spender**; the **amount** can exceed `quote.input.amount` (slippage /\n * route). We must approve at least that amount and the correct spender.\n */\nconst uniswapDispatchExecuteAbi = [\n {\n name: 'execute',\n type: 'function',\n stateMutability: 'payable',\n inputs: [\n { name: 'router', type: 'address' },\n { name: 'token', type: 'address' },\n { name: 'amount', type: 'uint256' },\n { name: 'commands', type: 'bytes' },\n { name: 'inputs', type: 'bytes[]' },\n { name: 'deadline', type: 'uint256' },\n ],\n outputs: [],\n },\n] as const\n\n/** Parse payable `value` wei from Trade API `swap` (string hex/decimal, `Value`, or finite JSON number). */\nfunction parseSwapTxValueWei(swap: Record<string, unknown>): bigint {\n const raw = swap.value ?? swap.Value\n if (raw == null || raw === '') return 0n\n if (typeof raw === 'bigint') return raw > 0n ? raw : 0n\n if (typeof raw === 'number' && Number.isFinite(raw)) {\n try {\n return BigInt(Math.max(0, Math.trunc(raw)))\n } catch {\n return 0n\n }\n }\n const s = String(raw).trim()\n if (!s) return 0n\n try {\n if (/^0x[0-9a-fA-F]+$/.test(s)) return BigInt(s)\n return BigInt(s.replace(/^0x/i, ''))\n } catch {\n return 0n\n }\n}\n\n/**\n * Native ETH–in payable amount: prefer `swap.value` from POST /swap; if missing/zero, use dispatcher\n * `execute(..., amount, ...)` from calldata (Trade API sometimes omits top-level `value`); else classic quote input wei.\n */\nfunction nativeEthInPayableValueWei(args: {\n swap: TransactionRequest\n dataHex: `0x${string}`\n quoteInputWei: bigint\n}): bigint {\n const fromApi = parseSwapTxValueWei(args.swap as Record<string, unknown>)\n if (fromApi > 0n) return fromApi\n try {\n const d = decodeFunctionData({ abi: uniswapDispatchExecuteAbi, data: args.dataHex })\n if (d.functionName === 'execute') {\n const rawAmt = d.args[2]\n const amount = typeof rawAmt === 'bigint' ? rawAmt : BigInt(String(rawAmt))\n if (amount > 0n) return amount\n }\n } catch {\n /* calldata is not dispatcher `execute` */\n }\n return args.quoteInputWei > 0n ? args.quoteInputWei : 0n\n}\n\n/**\n * Apply UI slippage % on top of the base approve amount (EXACT_OUTPUT only at call sites; basis points, ceil wei).\n * Example: 0.5% → multiply by 1.005 (10050/10000). `undefined` / non‑positive leaves `baseWei` unchanged.\n */\nexport function applySlippagePercentToApproveWei(baseWei: bigint, slippagePercent: number | undefined): bigint {\n if (baseWei <= 0n) return baseWei\n const s = slippagePercent == null ? NaN : Number(slippagePercent)\n if (!Number.isFinite(s) || s <= 0) return baseWei\n const bps = Math.min(100_000, Math.round(s * 100))\n if (bps <= 0) return baseWei\n return (baseWei * BigInt(10_000 + bps) + 9_999n) / 10_000n\n}\n\nfunction permit2SpenderAndApproveWeiFromSwapCalldata(\n dataHex: `0x${string}`,\n tokenIn: Address,\n quoteInputWei: bigint,\n chainId: number\n): { permit2Spender: Address; approveWei: bigint; calldataAmountWei: bigint | null } {\n const canonical = getUniswapUniversalRouterSpenderOrThrow(chainId)\n try {\n const d = decodeFunctionData({ abi: uniswapDispatchExecuteAbi, data: dataHex })\n if (d.functionName !== 'execute') {\n return { permit2Spender: canonical, approveWei: quoteInputWei, calldataAmountWei: null }\n }\n const router = getAddress(d.args[0] as Address)\n const token = getAddress(d.args[1] as Address)\n const rawAmt = d.args[2]\n const amount = typeof rawAmt === 'bigint' ? rawAmt : BigInt(String(rawAmt))\n if (token.toLowerCase() !== tokenIn.toLowerCase()) {\n throw new Error(\n `Swap calldata token ${token} does not match token in ${tokenIn}. Refresh quote and /swap.`\n )\n }\n const calldataAmountWei = amount > 0n ? amount : null\n let approveWei = quoteInputWei\n if (calldataAmountWei != null && calldataAmountWei > approveWei) {\n approveWei = calldataAmountWei\n }\n return { permit2Spender: router, approveWei, calldataAmountWei }\n } catch (e) {\n if (e instanceof Error && e.message.includes('does not match token')) throw e\n return { permit2Spender: canonical, approveWei: quoteInputWei, calldataAmountWei: null }\n }\n}\n\ntype UniswapV4SkipPermit2BatchArg = {\n keyGen: KeyGenSubsetForPermit\n chainId: number\n rpcUrl: string\n chainDetail: ChainRow\n useCustomGas: boolean\n customGasChainDetails?: Record<string, unknown> | null\n /** `0x0` = native (ETH) in; otherwise ERC-20. */\n tokenIn: Address\n executorAddress: Address\n swap: TransactionRequest\n createSwapResponse: { requestId?: string; gasFee?: string; swap: TransactionRequest }\n fullQuoteSnapshot: Record<string, unknown>\n purposeText: string\n swapDeadlineUnix: number\n slippagePercent?: number\n}\n\n/**\n * **Native (ETH) input** — a single **payable** swap tx from `POST /swap` (`swap.value` > 0). No `approve` (no ERC-20 for token in).\n */\nasync function buildEvmMultisignBodyUniswapV4NativeInOnly(\n args: UniswapV4SkipPermit2BatchArg,\n quoteInputWei: bigint,\n): Promise<{ bodyForSign: Record<string, unknown>; messageToSign: string }> {\n const toRouter = getAddress(\n (args.swap.to ?? '').trim().startsWith('0x') ? (args.swap.to.trim() as `0x${string}`) : `0x${args.swap.to.trim()}`,\n )\n const dataHex = (() => {\n const d = (args.swap.data ?? '0x').toString().trim()\n return d.startsWith('0x') ? d : `0x${d}`\n })() as `0x${string}`\n\n const valueWei = nativeEthInPayableValueWei({\n swap: args.swap,\n dataHex,\n quoteInputWei,\n })\n if (valueWei <= 0n) {\n throw new Error(\n 'Native (ETH) in swap: could not determine payable value (no `swap.value`, no `execute` amount in calldata, and quote input is zero). Refresh the quote and request /swap again.',\n )\n }\n\n const swapRecord = args.swap as Record<string, unknown>\n let gasBuildSource: 'tradeApi' | 'rpcEstimate' | 'estimateFailedFallback' = 'rpcEstimate'\n let estimateGasError: string | undefined\n let swapBaseGasUnits = DEFAULT_UNIVERSAL_ROUTER_GAS_FALLBACK\n\n const dataNo0x = dataHex.startsWith('0x') ? dataHex.slice(2) : dataHex\n const purposeSuffix =\n 'Uniswap V4: 1-tx batch — native gas token in (no ERC-20 approve) — single payable swap (Trade /swap).'\n\n return buildEvmMultisignBatch({\n context: {\n chainCategory: 'evm',\n keyGen: args.keyGen,\n purposeText: args.purposeText,\n chainId: args.chainId,\n rpcUrl: args.rpcUrl,\n executorAddress: args.executorAddress,\n chainDetail: args.chainDetail,\n useCustomGas: args.useCustomGas,\n customGasChainDetails: args.customGasChainDetails,\n },\n steps: [\n {\n to: toRouter,\n data: dataHex,\n value: valueWei,\n routerSwap: true,\n fallbackGas: DEFAULT_UNIVERSAL_ROUTER_GAS_FALLBACK,\n },\n ],\n purposeSuffix,\n firstMsgRawNo0x: dataNo0x,\n destinationAddress: toRouter,\n estimateGasForStep: async ({ publicClient, executor }) => {\n const r = await estimateUniswapRouterSwapGas({\n publicClient,\n executor,\n to: toRouter,\n data: dataHex,\n value: valueWei,\n swapRecord,\n useCustomGas: args.useCustomGas,\n chainDetail: args.chainDetail,\n })\n gasBuildSource = r.source\n estimateGasError = r.estimateGasError\n swapBaseGasUnits = r.baseGasUnits\n return r.baseGasUnits\n },\n buildBatchMeta: () => ({\n signatureText: JSON.stringify({\n kind: 'UniswapV4',\n name: 'UniversalRouter (payable, native in)',\n note: 'Single tx from Trade POST /swap; no ERC-20 approve. Calldata in messageHashes[0] / messageRawBatch[0].',\n }),\n evm: { type: 'uniswap_v4_swap_tx', version: 1, chainId: String(args.chainId) },\n uniswapV4: {\n skipPermit2Batch: true,\n inputKind: 'native_eth',\n noErc20Approve: true,\n quoteInputWei: quoteInputWei.toString(),\n swapValueWei: valueWei.toString(),\n uniswapCreateSwap: {\n requestId: args.createSwapResponse.requestId,\n gasFee: args.createSwapResponse.gasFee,\n gasBuildSwap: {\n useCustomGas: args.useCustomGas,\n source: gasBuildSource,\n baseGasUnits: swapBaseGasUnits.toString(),\n ...(estimateGasError != null && estimateGasError !== '' ? { estimateGasError } : {}),\n },\n swap: {\n to: args.createSwapResponse.swap.to,\n value: args.createSwapResponse.swap.value,\n dataNibbles: (() => {\n const t = (args.createSwapResponse.swap.data ?? '').toString().trim()\n return t.startsWith('0x') ? t.length - 2 : t.length\n })(),\n },\n },\n fullQuoteFromPermitSnapshot: args.fullQuoteSnapshot,\n originalPurpose: args.purposeText,\n },\n }),\n })\n}\n\n/**\n * **Classic ERC-20 allowance** batch (on-chain approvals only), two shapes:\n *\n * - **`swap.to` == inner `router` (calldata arg)** — Universal Router is the tx target; tokens move via the **allowance hub**:\n * `ERC20→hub`, hub `approve(router)`, swap (3 txs).\n *\n * - **`swap.to` ≠ inner `router`** — Trade uses a **dispatcher** that calls `ERC20.transferFrom` with **`msg.sender` = `swap.to`**.\n * Approving only the hub is insufficient (`cast run` shows `transfer amount exceeds allowance`). Path:\n * `ERC20.approve(swap.to)`, swap (2 txs).\n *\n * Approved amount: `max(quote.input, calldata amount)`; with **EXACT_OUTPUT** trades, multiply by `(1 + slippage%)` from the quote modal (input can grow vs the quoted figure).\n */\nexport async function buildEvmMultisignBodyUniswapV4SkipPermit2Batch(\n args: UniswapV4SkipPermit2BatchArg,\n): Promise<{ bodyForSign: Record<string, unknown>; messageToSign: string }> {\n const tokenIn = getAddress(args.tokenIn)\n const parsedInOut = parseUniswapQuoteClassicInOut(args.fullQuoteSnapshot)\n const quoteInputWei = parsedInOut?.inputWei\n if (quoteInputWei == null || quoteInputWei <= 0n) {\n throw new Error(\n 'Could not read a positive input amount from the quote. Refresh the quote and ensure the Trade API returned classic quote.input.amount.',\n )\n }\n\n if (tokenIn === zeroAddress) {\n return buildEvmMultisignBodyUniswapV4NativeInOnly(args, quoteInputWei)\n }\n\n const toRouter = getAddress(\n (args.swap.to ?? '').trim().startsWith('0x') ? (args.swap.to.trim() as `0x${string}`) : `0x${args.swap.to.trim()}`,\n )\n const dataHex = (() => {\n const d = (args.swap.data ?? '0x').toString().trim()\n return d.startsWith('0x') ? d : `0x${d}`\n })() as `0x${string}`\n\n const canonicalUniversalRouter = getUniswapUniversalRouterSpenderOrThrow(args.chainId)\n const { permit2Spender, approveWei: baseApproveWei, calldataAmountWei } = permit2SpenderAndApproveWeiFromSwapCalldata(\n dataHex,\n tokenIn,\n quoteInputWei,\n args.chainId,\n )\n const approveAmountWei = applySlippagePercentToApproveWei(baseApproveWei, args.slippagePercent)\n const usePermit2Triple = toRouter.toLowerCase() === permit2Spender.toLowerCase()\n if (usePermit2Triple && approveAmountWei > MAX_UINT160) {\n throw new Error('Approved transfer amount exceeds allowance-hub uint160 max; reduce trade size.')\n }\n\n let expiration48 = 0n\n if (usePermit2Triple) {\n const deadlineSec = Math.floor(Number(args.swapDeadlineUnix))\n if (!Number.isFinite(deadlineSec) || deadlineSec <= 0) {\n throw new Error('Invalid swapDeadlineUnix for allowance-hub approve expiration.')\n }\n expiration48 = BigInt(deadlineSec)\n if (expiration48 > MAX_UINT48) expiration48 = MAX_UINT48\n }\n\n const erc20ApproveSpender: Address = usePermit2Triple ? PERMIT2_ADDRESS : toRouter\n const approveData = encodeFunctionData({\n abi: erc20Abi,\n functionName: 'approve',\n args: [erc20ApproveSpender, approveAmountWei],\n }) as `0x${string}`\n const valueWei = (() => {\n const v = args.swap.value\n if (v == null || v === '') return 0n\n try {\n return BigInt(String(v).replace(/^0x/i, ''))\n } catch {\n return 0n\n }\n })()\n\n const swapRecord = args.swap as Record<string, unknown>\n const swapMsgIndex = usePermit2Triple ? 2 : 1\n let gasBuildSource: 'tradeApi' | 'rpcEstimate' | 'estimateFailedFallback' = 'rpcEstimate'\n let estimateGasError: string | undefined\n let swapBaseGasUnits = DEFAULT_UNIVERSAL_ROUTER_GAS_FALLBACK\n\n const steps: EvmTxStep[] = [\n { to: tokenIn, data: approveData, value: 0n, fallbackGas: 100_000n },\n ]\n if (usePermit2Triple) {\n const permit2ApproveData = encodeFunctionData({\n abi: permit2ApproveRouterAbi,\n functionName: 'approve',\n args: [tokenIn, permit2Spender, approveAmountWei, Number(expiration48)],\n }) as `0x${string}`\n steps.push({ to: PERMIT2_ADDRESS, data: permit2ApproveData, value: 0n, fallbackGas: 100_000n })\n }\n steps.push({\n to: toRouter,\n data: dataHex,\n value: valueWei,\n routerSwap: true,\n fallbackGas: DEFAULT_UNIVERSAL_ROUTER_GAS_FALLBACK,\n })\n\n const swapStepIndex = steps.length - 1\n const approveMsgRawNo0x = approveData.startsWith('0x') ? approveData.slice(2) : approveData\n const purposeSuffix = usePermit2Triple\n ? 'Uniswap V4: 3-tx batch (classic allowance) — (1) ERC-20 approve allowance hub, (2) hub approve(Universal Router), (3) swap (Trade /swap).'\n : 'Uniswap V4: 2-tx batch (classic allowance, dispatcher) — (1) ERC-20 approve swap.to (dispatcher pulls tokens), (2) swap (Trade /swap).'\n\n const buildSwapAudit = (): Record<string, unknown> => ({\n skipPermit2Batch: true,\n approvalPath: usePermit2Triple ? 'permit2_triple' : 'dispatcher',\n approveAmount: {\n baseWeiBeforeSlippage: baseApproveWei.toString(),\n finalWei: approveAmountWei.toString(),\n slippagePercent: args.slippagePercent,\n quoteInputWei: quoteInputWei.toString(),\n ...(calldataAmountWei != null ? { swapCalldataAmountWei: calldataAmountWei.toString() } : {}),\n },\n uniswapCreateSwap: {\n requestId: args.createSwapResponse.requestId,\n gasFee: args.createSwapResponse.gasFee,\n gasBuildSwap: {\n useCustomGas: args.useCustomGas,\n source: gasBuildSource,\n baseGasUnits: swapBaseGasUnits.toString(),\n ...(estimateGasError != null && estimateGasError !== '' ? { estimateGasError } : {}),\n },\n swap: {\n to: args.createSwapResponse.swap.to,\n value: args.createSwapResponse.swap.value,\n dataNibbles: (() => {\n const d = args.createSwapResponse.swap.data ?? ''\n const t = d.toString().trim()\n return t.startsWith('0x') ? t.length - 2 : t.length\n })(),\n },\n },\n fullQuoteFromPermitSnapshot: args.fullQuoteSnapshot,\n originalPurpose: args.purposeText,\n innerRouterFromCalldata: permit2Spender,\n swapToEqualsInnerRouter: usePermit2Triple,\n ...(usePermit2Triple\n ? {\n permit2Erc20Approve: {\n token: tokenIn,\n spender: PERMIT2_ADDRESS,\n amountWei: approveAmountWei.toString(),\n note: 'ERC-20 → allowance hub before hub approve(router).',\n },\n permit2ApproveUniversalRouter: {\n permit2: PERMIT2_ADDRESS,\n token: tokenIn,\n spender: permit2Spender,\n canonicalUniversalRouterFromAppMap: canonicalUniversalRouter,\n spenderMatchesCanonicalMap: permit2Spender.toLowerCase() === canonicalUniversalRouter.toLowerCase(),\n amountWei: approveAmountWei.toString(),\n expiration: expiration48.toString(),\n note: 'Allowance-hub spender must match the router in swap calldata.',\n },\n }\n : {\n erc20ApproveDispatcher: {\n token: tokenIn,\n spender: toRouter,\n amountWei: approveAmountWei.toString(),\n note:\n 'Dispatcher pulls via ERC20.transferFrom(user, universalRouter, amount); allowance must be on swap.to (see cast trace TRANSFER_FROM_FAILED when only the hub is approved).',\n },\n }),\n })\n\n return buildEvmMultisignBatch({\n context: {\n chainCategory: 'evm',\n keyGen: args.keyGen,\n purposeText: args.purposeText,\n chainId: args.chainId,\n rpcUrl: args.rpcUrl,\n executorAddress: args.executorAddress,\n chainDetail: args.chainDetail,\n useCustomGas: args.useCustomGas,\n customGasChainDetails: args.customGasChainDetails,\n },\n steps,\n purposeSuffix,\n firstMsgRawNo0x: approveMsgRawNo0x,\n destinationAddress: tokenIn,\n payableValueWei: valueWei > 0n ? valueWei : undefined,\n estimateGasForStep: async ({ step, index, publicClient, executor }) => {\n if (index !== swapStepIndex) {\n return publicClient.estimateGas({\n to: step.to,\n data: step.data,\n value: step.value,\n account: executor,\n })\n }\n const r = await estimateUniswapRouterSwapGas({\n publicClient,\n executor,\n to: toRouter,\n data: dataHex,\n value: valueWei,\n swapRecord,\n useCustomGas: args.useCustomGas,\n chainDetail: args.chainDetail,\n })\n gasBuildSource = r.source\n estimateGasError = r.estimateGasError\n swapBaseGasUnits = r.baseGasUnits\n return r.baseGasUnits\n },\n buildBatchMeta: ({ index }) => {\n if (index === 0) {\n return {\n signatureText: JSON.stringify({\n kind: 'UniswapV4',\n name: 'ERC20.approve',\n to: usePermit2Triple ? 'allowance hub' : 'dispatcher(swap.to)',\n function: 'approve(address spender, uint256 amount)',\n spender: erc20ApproveSpender,\n amountWei: approveAmountWei.toString(),\n }),\n evm: {\n type: usePermit2Triple ? 'uniswap_v4_skip_permit2_approve' : 'uniswap_v4_skip_permit2_dispatcher_approve',\n version: 1,\n chainId: String(args.chainId),\n ...(usePermit2Triple ? { permit2: PERMIT2_ADDRESS } : { dispatcher: toRouter }),\n },\n }\n }\n if (usePermit2Triple && index === 1) {\n return {\n signatureText: JSON.stringify({\n kind: 'UniswapV4',\n name: 'AllowanceHub.approve',\n function: 'approve(address token, address spender, uint160 amount, uint48 expiration)',\n token: tokenIn,\n spender: permit2Spender,\n amountWei: approveAmountWei.toString(),\n expiration: expiration48.toString(),\n }),\n evm: {\n type: 'uniswap_v4_skip_permit2_permit2_approve',\n version: 1,\n chainId: String(args.chainId),\n permit2: PERMIT2_ADDRESS,\n permit2Spender,\n },\n }\n }\n return {\n signatureText: JSON.stringify({\n kind: 'UniswapV4',\n name: 'UniversalRouter.execute',\n note: `Calldata from Trade API POST /swap; signed tx hash in messageHashes[${swapMsgIndex}].`,\n }),\n evm: { type: 'uniswap_v4_swap_tx', version: 1, chainId: String(args.chainId) },\n uniswapV4: buildSwapAudit(),\n }\n },\n })\n}\n","import { getAddress, type Address } from 'viem'\nimport { isUniswapV4ChainSupported } from './constants.js'\nimport { parseUniswapChainId } from './quote.js'\nimport { computeUniswapV4PoolReference, sortUniswapV4PoolCurrencies } from './poolId.js'\n\nconst ZERO_HOOKS = '0x0000000000000000000000000000000000000000' as Address\n\nexport const UNISWAP_V4_LP_POOL_LOOKUP_HINT =\n 'Pool may not be initialized on this chain. Call ctm_uniswap_v4_list_lp_pools for other presets, pass a custom existingPool.poolReference, or use newPool to initialize a pool.'\n\ntype ChainTokenRow = {\n symbol: string\n address: Address\n /** True when the LP pair uses native ETH (`0x0`) instead of wrapped native. */\n native?: boolean\n}\n\ntype ChainLpConfig = {\n chainId: number\n chainLabel: string\n nativeWrapped: Address\n tokens: Record<string, ChainTokenRow>\n pairs: Array<{\n slug: string\n label: string\n token0Key: string\n token1Key: string\n tiers: Array<{ fee: number; feeLabel: string; tickSpacing: number }>\n }>\n}\n\nconst FEE_TIERS = [\n { fee: 500, feeLabel: '0.05%', tickSpacing: 10 },\n { fee: 3000, feeLabel: '0.3%', tickSpacing: 60 },\n { fee: 10000, feeLabel: '1%', tickSpacing: 200 },\n] as const\n\nconst CHAIN_LP_CONFIGS: ChainLpConfig[] = [\n {\n chainId: 1,\n chainLabel: 'Ethereum',\n nativeWrapped: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',\n tokens: {\n eth: { symbol: 'ETH', address: '0x0000000000000000000000000000000000000000', native: true },\n usdc: { symbol: 'USDC', address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' },\n usdt: { symbol: 'USDT', address: '0xdAC17F958D2ee523a2206206994597C13D831ec7' },\n wbtc: { symbol: 'WBTC', address: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599' },\n },\n pairs: [\n { slug: 'eth-usdc', label: 'ETH/USDC', token0Key: 'eth', token1Key: 'usdc', tiers: [...FEE_TIERS] },\n { slug: 'eth-usdt', label: 'ETH/USDT', token0Key: 'eth', token1Key: 'usdt', tiers: [...FEE_TIERS] },\n { slug: 'eth-wbtc', label: 'ETH/WBTC', token0Key: 'eth', token1Key: 'wbtc', tiers: [...FEE_TIERS] },\n ],\n },\n {\n chainId: 8453,\n chainLabel: 'Base',\n nativeWrapped: '0x4200000000000000000000000000000000000006',\n tokens: {\n eth: { symbol: 'ETH', address: '0x0000000000000000000000000000000000000000', native: true },\n usdc: { symbol: 'USDC', address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' },\n },\n pairs: [\n { slug: 'eth-usdc', label: 'ETH/USDC', token0Key: 'eth', token1Key: 'usdc', tiers: [...FEE_TIERS] },\n ],\n },\n {\n chainId: 42161,\n chainLabel: 'Arbitrum',\n nativeWrapped: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1',\n tokens: {\n eth: { symbol: 'ETH', address: '0x0000000000000000000000000000000000000000', native: true },\n usdc: { symbol: 'USDC', address: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831' },\n },\n pairs: [\n { slug: 'eth-usdc', label: 'ETH/USDC', token0Key: 'eth', token1Key: 'usdc', tiers: [...FEE_TIERS] },\n ],\n },\n {\n chainId: 10,\n chainLabel: 'Optimism',\n nativeWrapped: '0x4200000000000000000000000000000000000006',\n tokens: {\n eth: { symbol: 'ETH', address: '0x0000000000000000000000000000000000000000', native: true },\n usdc: { symbol: 'USDC', address: '0x0b2C639c533813f4Aa9D7837CAa646c993D1B7926' },\n },\n pairs: [\n { slug: 'eth-usdc', label: 'ETH/USDC', token0Key: 'eth', token1Key: 'usdc', tiers: [...FEE_TIERS] },\n ],\n },\n {\n chainId: 137,\n chainLabel: 'Polygon',\n nativeWrapped: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619',\n tokens: {\n eth: { symbol: 'ETH', address: '0x0000000000000000000000000000000000000000', native: true },\n usdc: { symbol: 'USDC', address: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359' },\n },\n pairs: [\n { slug: 'eth-usdc', label: 'ETH/USDC', token0Key: 'eth', token1Key: 'usdc', tiers: [...FEE_TIERS] },\n ],\n },\n]\n\nexport type UniswapV4StandardLpPoolRow = {\n presetId: string\n pairSlug: string\n pairLabel: string\n fee: number\n feeLabel: string\n tickSpacing: number\n token0Symbol: string\n token1Symbol: string\n token0Address: Address\n token1Address: Address\n poolReference: `0x${string}`\n hooks: Address\n nativeWrapped?: Address\n usesNativeEth: boolean\n}\n\nfunction buildPresetId(pairSlug: string, feeLabel: string): string {\n const feeSlug = feeLabel.replace('%', '').replace('.', '-')\n return `${pairSlug}-${feeSlug}`\n}\n\nfunction buildPoolRows(config: ChainLpConfig): UniswapV4StandardLpPoolRow[] {\n const rows: UniswapV4StandardLpPoolRow[] = []\n for (const pair of config.pairs) {\n const token0 = config.tokens[pair.token0Key]\n const token1 = config.tokens[pair.token1Key]\n if (!token0 || !token1) continue\n for (const tier of pair.tiers) {\n const poolReference = computeUniswapV4PoolReference({\n token0Address: token0.address,\n token1Address: token1.address,\n fee: tier.fee,\n tickSpacing: tier.tickSpacing,\n hooks: ZERO_HOOKS,\n })\n const usesNativeEth = Boolean(token0.native || token1.native)\n rows.push({\n presetId: buildPresetId(pair.slug, tier.feeLabel),\n pairSlug: pair.slug,\n pairLabel: pair.label,\n fee: tier.fee,\n feeLabel: tier.feeLabel,\n tickSpacing: tier.tickSpacing,\n token0Symbol: token0.symbol,\n token1Symbol: token1.symbol,\n token0Address: getAddress(token0.address),\n token1Address: getAddress(token1.address),\n poolReference,\n hooks: ZERO_HOOKS,\n nativeWrapped: usesNativeEth ? getAddress(config.nativeWrapped) : undefined,\n usesNativeEth,\n })\n }\n }\n return rows\n}\n\nfunction chainConfigOrThrow(chainId: number): ChainLpConfig {\n const config = CHAIN_LP_CONFIGS.find((row) => row.chainId === chainId)\n if (!config) {\n throw new Error(\n `No standard Uniswap V4 LP pool catalog for chainId ${chainId}. Supported catalog chains: ${CHAIN_LP_CONFIGS.map((c) => c.chainId).join(', ')}.`,\n )\n }\n if (!isUniswapV4ChainSupported(chainId)) {\n throw new Error(`chainId ${chainId} is not supported for Uniswap V4 MCP tools.`)\n }\n return config\n}\n\nexport function listUniswapV4StandardLpPools(args: {\n chainId: number | string\n pair?: string\n}): {\n chainId: number\n chainLabel: string\n pools: UniswapV4StandardLpPoolRow[]\n notes: string\n} {\n const chainId = parseUniswapChainId(args.chainId)\n const config = chainConfigOrThrow(chainId)\n let pools = buildPoolRows(config)\n const pairFilter = args.pair?.trim().toLowerCase()\n if (pairFilter) {\n pools = pools.filter(\n (row) =>\n row.pairSlug.includes(pairFilter) ||\n row.pairLabel.toLowerCase().includes(pairFilter) ||\n row.presetId.includes(pairFilter),\n )\n }\n return {\n chainId,\n chainLabel: config.chainLabel,\n pools,\n notes:\n 'poolReference is derived from token addresses, fee, tickSpacing, and hooks (no-hook pools). ' +\n 'Pass presetId to ctm_uniswap_v4_lp_create_position as poolPreset, or copy existingPool fields. ' +\n 'If LP create fails, the pool may not exist on-chain — try another preset, pass poolReference manually, or use newPool.',\n }\n}\n\nexport function resolveUniswapV4LpPoolPreset(args: {\n chainId: number | string\n presetId: string\n}): UniswapV4StandardLpPoolRow {\n const chainId = parseUniswapChainId(args.chainId)\n const preset = args.presetId.trim().toLowerCase()\n const row = buildPoolRows(chainConfigOrThrow(chainId)).find(\n (pool) => pool.presetId.toLowerCase() === preset,\n )\n if (!row) {\n throw new Error(\n `Unknown LP pool preset \"${args.presetId}\" on chainId ${chainId}. Call ctm_uniswap_v4_list_lp_pools to list standard presets.`,\n )\n }\n return row\n}\n\nexport function resolveUniswapV4LpExistingPoolFromKey(args: {\n token0Address: string\n token1Address: string\n fee: number\n tickSpacing: number\n hooks?: string\n poolReference?: string\n}): {\n token0Address: Address\n token1Address: Address\n poolReference: `0x${string}`\n} {\n const poolReference =\n args.poolReference?.trim() ||\n computeUniswapV4PoolReference({\n token0Address: args.token0Address,\n token1Address: args.token1Address,\n fee: args.fee,\n tickSpacing: args.tickSpacing,\n hooks: args.hooks,\n })\n const sorted = sortTokensForExistingPool(args.token0Address, args.token1Address)\n return {\n token0Address: sorted.token0Address,\n token1Address: sorted.token1Address,\n poolReference: poolReference as `0x${string}`,\n }\n}\n\nfunction sortTokensForExistingPool(\n token0Address: string,\n token1Address: string,\n): { token0Address: Address; token1Address: Address } {\n const sorted = sortUniswapV4PoolCurrencies(token0Address, token1Address)\n return { token0Address: sorted.currency0, token1Address: sorted.currency1 }\n}\n\nexport function uniswapV4ListStandardLpPools(args: {\n chainId: number | string\n pair?: string\n}): ReturnType<typeof listUniswapV4StandardLpPools> {\n return listUniswapV4StandardLpPools(args)\n}\n","import {\n UNISWAP_LP_API_BASE_DEFAULT,\n UNISWAP_LP_DEFAULT_DEADLINE_SEC_OFFSET,\n UNISWAP_LP_DEFAULT_SLIPPAGE_PERCENT,\n UNISWAP_TRADE_BASE_DEFAULT,\n} from './constants.js'\nimport { UNISWAP_V4_LP_POOL_LOOKUP_HINT } from './knownLpPools.js'\nimport { messageFromUniswapHttpResponseBody } from './quote.js'\n\nexport type UniswapLpProtocol = 'V4'\n\nexport type UniswapLpTransactionRequest = {\n to: string\n from?: string\n data: string\n value: string\n chainId?: number\n gasLimit?: string\n gasPrice?: string\n maxFeePerGas?: string\n maxPriorityFeePerGas?: string\n}\n\nexport type UniswapLpTokenAmount = {\n tokenAddress: string\n amount: string\n}\n\nexport type UniswapLpExistingPool = {\n token0Address: string\n token1Address: string\n /** V4 pool id (bytes32 hex); V3 pool contract address. */\n poolReference: string\n}\n\nexport type UniswapLpNewPool = {\n token0Address: string\n token1Address: string\n fee: number\n tickSpacing: number\n hooks?: string\n initialPrice: string\n}\n\nexport type UniswapLpIndependentToken = {\n tokenAddress: string\n amount: string\n}\n\nexport type UniswapLpPriceBounds = {\n minPrice: string\n maxPrice: string\n}\n\nexport type UniswapLpTickBounds = {\n tickLower: number\n tickUpper: number\n}\n\nconst LP_HEADERS_BASE: Record<string, string> = {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'User-Agent': 'ctm-mpc-defi uniswapLpApi/1.0 (TS)',\n}\n\nfunction trimAddr(a: string): string {\n return a.trim()\n}\n\nfunction lpDeadlineUnix(nowSec: number = Math.floor(Date.now() / 1000)): number {\n return nowSec + UNISWAP_LP_DEFAULT_DEADLINE_SEC_OFFSET\n}\n\nfunction resolveLpBaseUrl(baseUrl?: string): string {\n const raw = (baseUrl ?? UNISWAP_TRADE_BASE_DEFAULT).replace(/\\/$/, '')\n return raw\n}\n\nfunction resolveLpPath(baseUrl: string, action: 'create' | 'increase' | 'decrease' | 'claim' | 'approve'): string {\n const normalized = baseUrl.replace(/\\/$/, '')\n if (normalized.includes('api.uniswap.org')) {\n return `${normalized}/lp/${action}`\n }\n return `${normalized}/lp/${action}`\n}\n\nasync function postUniswapLpApi(args: {\n uniswapApiKey: string\n path: 'create' | 'increase' | 'decrease' | 'claim' | 'approve'\n body: Record<string, unknown>\n baseUrl?: string\n fetchImpl?: typeof fetch\n useServerProxy?: boolean\n proxyPath?: string\n}): Promise<Record<string, unknown>> {\n const useProxy =\n (args.useServerProxy !== false) &&\n typeof globalThis !== 'undefined' &&\n typeof (globalThis as { window?: unknown }).window !== 'undefined'\n\n if (useProxy && args.proxyPath) {\n const fn = args.fetchImpl ?? globalThis.fetch\n const res = await fn(args.proxyPath, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n uniswapApiKey: args.uniswapApiKey,\n baseUrl: args.baseUrl,\n body: args.body,\n }),\n credentials: 'same-origin',\n })\n const text = await res.text()\n if (!res.ok) {\n let errMsg = res.statusText\n try {\n const j = JSON.parse(text) as { error?: string }\n if (j?.error?.trim()) errMsg = j.error.trim()\n } catch {\n if (text.trim()) errMsg = text.slice(0, 500)\n }\n throw new Error(`Uniswap LP proxy failed: ${errMsg}`)\n }\n return JSON.parse(text) as Record<string, unknown>\n }\n\n const base = resolveLpBaseUrl(args.baseUrl)\n const url = resolveLpPath(base, args.path)\n const fn = args.fetchImpl ?? globalThis.fetch\n const res = await fn(url, {\n method: 'POST',\n headers: {\n ...LP_HEADERS_BASE,\n 'x-api-key': args.uniswapApiKey.trim(),\n },\n body: JSON.stringify(args.body),\n })\n const text = await res.text()\n if (!res.ok) {\n const base = messageFromUniswapHttpResponseBody(text, res.status, res.statusText)\n const hint =\n args.path === 'create' && args.body.existingPool\n ? ` ${UNISWAP_V4_LP_POOL_LOOKUP_HINT}`\n : ''\n throw new Error(`Uniswap LP POST /${args.path} failed: ${base}${hint}`)\n }\n return JSON.parse(text) as Record<string, unknown>\n}\n\nexport function extractUniswapLpTransaction(\n response: Record<string, unknown>,\n field: 'create' | 'increase' | 'decrease' | 'claim',\n): UniswapLpTransactionRequest {\n const tx = response[field]\n if (!tx || typeof tx !== 'object' || Array.isArray(tx)) {\n throw new Error(`Uniswap LP response missing \\`${field}\\` transaction object.`)\n }\n const o = tx as Record<string, unknown>\n const to = String(o.to ?? '').trim()\n const data = String(o.data ?? '').trim()\n if (!to.startsWith('0x') || !data.startsWith('0x') || data === '0x') {\n throw new Error(`Uniswap LP \\`${field}\\` transaction has invalid to/data.`)\n }\n return {\n to,\n from: o.from != null ? String(o.from) : undefined,\n data,\n value: String(o.value ?? '0'),\n chainId: typeof o.chainId === 'number' ? o.chainId : undefined,\n gasLimit: o.gasLimit != null ? String(o.gasLimit) : undefined,\n gasPrice: o.gasPrice != null ? String(o.gasPrice) : undefined,\n maxFeePerGas: o.maxFeePerGas != null ? String(o.maxFeePerGas) : undefined,\n maxPriorityFeePerGas:\n o.maxPriorityFeePerGas != null ? String(o.maxPriorityFeePerGas) : undefined,\n }\n}\n\nexport function extractUniswapLpTokenAmounts(\n response: Record<string, unknown>,\n): { token0?: UniswapLpTokenAmount; token1?: UniswapLpTokenAmount } {\n const read = (key: 'token0' | 'token1'): UniswapLpTokenAmount | undefined => {\n const raw = response[key]\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return undefined\n const o = raw as Record<string, unknown>\n const tokenAddress = String(o.tokenAddress ?? o.token ?? '').trim()\n const amount = String(o.amount ?? '').trim()\n if (!tokenAddress.startsWith('0x') || !amount) return undefined\n return { tokenAddress, amount }\n }\n return { token0: read('token0'), token1: read('token1') }\n}\n\nexport async function uniswapLpCreatePosition(args: {\n uniswapApiKey: string\n walletAddress: string\n chainId: number\n existingPool?: UniswapLpExistingPool\n newPool?: UniswapLpNewPool\n independentToken: UniswapLpIndependentToken\n priceBounds?: UniswapLpPriceBounds\n tickBounds?: UniswapLpTickBounds\n slippageTolerance?: number\n deadline?: number\n simulateTransaction?: boolean\n batchPermitData?: Record<string, unknown>\n signature?: string\n baseUrl?: string\n fetchImpl?: typeof fetch\n useServerProxy?: boolean\n}): Promise<Record<string, unknown>> {\n const body: Record<string, unknown> = {\n protocol: 'V4',\n walletAddress: trimAddr(args.walletAddress),\n chainId: args.chainId,\n independentToken: {\n tokenAddress: trimAddr(args.independentToken.tokenAddress),\n amount: String(args.independentToken.amount).trim(),\n },\n slippageTolerance: args.slippageTolerance ?? UNISWAP_LP_DEFAULT_SLIPPAGE_PERCENT,\n deadline: args.deadline ?? lpDeadlineUnix(),\n simulateTransaction: args.simulateTransaction ?? false,\n }\n if (args.existingPool) {\n body.existingPool = {\n token0Address: trimAddr(args.existingPool.token0Address),\n token1Address: trimAddr(args.existingPool.token1Address),\n poolReference: trimAddr(args.existingPool.poolReference),\n }\n }\n if (args.newPool) {\n body.newPool = {\n token0Address: trimAddr(args.newPool.token0Address),\n token1Address: trimAddr(args.newPool.token1Address),\n fee: args.newPool.fee,\n tickSpacing: args.newPool.tickSpacing,\n initialPrice: String(args.newPool.initialPrice).trim(),\n ...(args.newPool.hooks ? { hooks: trimAddr(args.newPool.hooks) } : {}),\n }\n }\n if (!args.existingPool && !args.newPool) {\n throw new Error('Provide existingPool or newPool for LP create.')\n }\n if (args.priceBounds) {\n body.priceBounds = {\n minPrice: String(args.priceBounds.minPrice).trim(),\n maxPrice: String(args.priceBounds.maxPrice).trim(),\n }\n }\n if (args.tickBounds) {\n body.tickBounds = {\n tickLower: args.tickBounds.tickLower,\n tickUpper: args.tickBounds.tickUpper,\n }\n }\n if (!args.priceBounds && !args.tickBounds) {\n throw new Error('Provide priceBounds or tickBounds for LP create.')\n }\n if (args.batchPermitData) body.batchPermitData = args.batchPermitData\n if (args.signature) body.signature = args.signature\n\n return postUniswapLpApi({\n uniswapApiKey: args.uniswapApiKey,\n path: 'create',\n body,\n baseUrl: args.baseUrl,\n fetchImpl: args.fetchImpl,\n useServerProxy: args.useServerProxy,\n proxyPath: '/api/uniswap/liquidity/create',\n })\n}\n\nexport async function uniswapLpIncreasePosition(args: {\n uniswapApiKey: string\n walletAddress: string\n chainId: number\n token0Address: string\n token1Address: string\n nftTokenId: string | number\n independentToken: UniswapLpIndependentToken\n slippageTolerance?: number\n deadline?: number\n simulateTransaction?: boolean\n v4BatchPermitData?: Record<string, unknown>\n signature?: string\n baseUrl?: string\n fetchImpl?: typeof fetch\n useServerProxy?: boolean\n}): Promise<Record<string, unknown>> {\n const body: Record<string, unknown> = {\n protocol: 'V4',\n walletAddress: trimAddr(args.walletAddress),\n chainId: args.chainId,\n token0Address: trimAddr(args.token0Address),\n token1Address: trimAddr(args.token1Address),\n nftTokenId: String(args.nftTokenId),\n independentToken: {\n tokenAddress: trimAddr(args.independentToken.tokenAddress),\n amount: String(args.independentToken.amount).trim(),\n },\n slippageTolerance: args.slippageTolerance ?? UNISWAP_LP_DEFAULT_SLIPPAGE_PERCENT,\n deadline: args.deadline ?? lpDeadlineUnix(),\n simulateTransaction: args.simulateTransaction ?? false,\n }\n if (args.v4BatchPermitData) body.v4BatchPermitData = args.v4BatchPermitData\n if (args.signature) body.signature = args.signature\n\n return postUniswapLpApi({\n uniswapApiKey: args.uniswapApiKey,\n path: 'increase',\n body,\n baseUrl: args.baseUrl,\n fetchImpl: args.fetchImpl,\n useServerProxy: args.useServerProxy,\n proxyPath: '/api/uniswap/liquidity/increase',\n })\n}\n\nexport async function uniswapLpDecreasePosition(args: {\n uniswapApiKey: string\n walletAddress: string\n chainId: number\n token0Address: string\n token1Address: string\n nftTokenId: string | number\n liquidityPercentageToDecrease: number\n slippageTolerance?: number\n deadline?: number\n simulateTransaction?: boolean\n baseUrl?: string\n fetchImpl?: typeof fetch\n useServerProxy?: boolean\n}): Promise<Record<string, unknown>> {\n const pct = Math.trunc(args.liquidityPercentageToDecrease)\n if (!Number.isFinite(pct) || pct < 1 || pct > 100) {\n throw new Error('liquidityPercentageToDecrease must be an integer from 1 to 100.')\n }\n const body: Record<string, unknown> = {\n protocol: 'V4',\n walletAddress: trimAddr(args.walletAddress),\n chainId: args.chainId,\n token0Address: trimAddr(args.token0Address),\n token1Address: trimAddr(args.token1Address),\n nftTokenId: String(args.nftTokenId),\n liquidityPercentageToDecrease: pct,\n slippageTolerance: args.slippageTolerance ?? UNISWAP_LP_DEFAULT_SLIPPAGE_PERCENT,\n deadline: args.deadline ?? lpDeadlineUnix(),\n simulateTransaction: args.simulateTransaction ?? false,\n }\n\n return postUniswapLpApi({\n uniswapApiKey: args.uniswapApiKey,\n path: 'decrease',\n body,\n baseUrl: args.baseUrl,\n fetchImpl: args.fetchImpl,\n useServerProxy: args.useServerProxy,\n proxyPath: '/api/uniswap/liquidity/decrease',\n })\n}\n\nexport async function uniswapLpClaimFees(args: {\n uniswapApiKey: string\n walletAddress: string\n chainId: number\n tokenId: string | number\n simulateTransaction?: boolean\n baseUrl?: string\n fetchImpl?: typeof fetch\n useServerProxy?: boolean\n}): Promise<Record<string, unknown>> {\n const body: Record<string, unknown> = {\n protocol: 'V4',\n walletAddress: trimAddr(args.walletAddress),\n chainId: args.chainId,\n tokenId: String(args.tokenId),\n simulateTransaction: args.simulateTransaction ?? false,\n }\n\n return postUniswapLpApi({\n uniswapApiKey: args.uniswapApiKey,\n path: 'claim',\n body,\n baseUrl: args.baseUrl,\n fetchImpl: args.fetchImpl,\n useServerProxy: args.useServerProxy,\n proxyPath: '/api/uniswap/liquidity/claim',\n })\n}\n\nexport { UNISWAP_LP_API_BASE_DEFAULT, UNISWAP_TRADE_BASE_DEFAULT }\n","import { formatUnits } from 'viem'\nimport type { UniswapLpTokenAmount, UniswapLpTransactionRequest } from './liquidityApi.js'\nimport { extractUniswapLpTokenAmounts, extractUniswapLpTransaction } from './liquidityApi.js'\n\nexport type UniswapLpAction = 'mint' | 'increase' | 'decrease' | 'collect'\n\nconst TX_FIELD_BY_ACTION: Record<UniswapLpAction, 'create' | 'increase' | 'decrease' | 'claim'> = {\n mint: 'create',\n increase: 'increase',\n decrease: 'decrease',\n collect: 'claim',\n}\n\nexport function uniswapLpTxFieldForAction(action: UniswapLpAction): 'create' | 'increase' | 'decrease' | 'claim' {\n return TX_FIELD_BY_ACTION[action]\n}\n\nexport function parseUniswapLpApiSnapshot(args: {\n action: UniswapLpAction\n lpResponse: Record<string, unknown>\n}): {\n transaction: UniswapLpTransactionRequest\n token0?: UniswapLpTokenAmount\n token1?: UniswapLpTokenAmount\n tickLower?: number\n tickUpper?: number\n minPrice?: string\n maxPrice?: string\n} {\n const field = TX_FIELD_BY_ACTION[args.action]\n const transaction = extractUniswapLpTransaction(args.lpResponse, field)\n const amounts = extractUniswapLpTokenAmounts(args.lpResponse)\n const tickLower =\n typeof args.lpResponse.tickLower === 'number' ? args.lpResponse.tickLower : undefined\n const tickUpper =\n typeof args.lpResponse.tickUpper === 'number' ? args.lpResponse.tickUpper : undefined\n const minPrice =\n typeof args.lpResponse.minPrice === 'string' ? args.lpResponse.minPrice : undefined\n const maxPrice =\n typeof args.lpResponse.maxPrice === 'string' ? args.lpResponse.maxPrice : undefined\n return {\n transaction,\n token0: amounts.token0,\n token1: amounts.token1,\n tickLower,\n tickUpper,\n minPrice,\n maxPrice,\n }\n}\n\nexport function formatUniswapLpAmountHuman(amountWei: string, decimals: number): string {\n try {\n return formatUnits(BigInt(amountWei), decimals)\n } catch {\n return amountWei\n }\n}\n","import {\n createPublicClient,\n decodeEventLog,\n defineChain,\n getAddress,\n http,\n parseAbi,\n parseAbiItem,\n type Address,\n type TransactionReceipt,\n zeroAddress,\n} from 'viem'\nimport {\n getUniswapV4PositionManagerDeployBlock,\n getUniswapV4PositionManagerOrThrow,\n UNISWAP_V4_LP_LOG_CHUNK_SIZE_DEFAULT,\n UNISWAP_V4_LP_LOG_CHUNK_SIZE_MIN,\n} from './constants.js'\n\nconst erc721BalanceAbi = parseAbi([\n 'function balanceOf(address owner) view returns (uint256)',\n 'function ownerOf(uint256 tokenId) view returns (address)',\n])\n\nconst positionInfoAbi = parseAbi([\n 'function positionInfo(uint256 tokenId) view returns (uint256 info)',\n])\n\nexport type UniswapV4PositionRow = {\n tokenId: string\n positionManager: Address\n owner: Address\n name?: string\n symbol?: string\n}\n\n/** Shown when LP tools cannot resolve a position NFT from the node token registry. */\nexport const UNISWAP_V4_LP_POSITION_REGISTRY_HINT =\n 'Add the position NFT to the node token registry (tokenType ERC721: Uniswap V4 Position Manager contract + tokenId). ' +\n 'MCP: call ctm_uniswap_v4_register_position_nft (by tokenId) or ctm_uniswap_v4_register_position_from_mint_tx (after mint execute). ' +\n 'Or use add_to_token_registry. In the Continuum app: Add Token (ERC721), or Manage liquidity → Refresh positions (blockchain scan).'\n\nexport function formatUniswapV4PositionNotFoundError(args: {\n tokenId: string\n chainId: number | string\n}): string {\n return (\n `Uniswap V4 position #${args.tokenId} is not in the node token registry for chain ${args.chainId}. ` +\n UNISWAP_V4_LP_POSITION_REGISTRY_HINT\n )\n}\n\nconst positionManagerTransferEvent = parseAbiItem(\n 'event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)',\n)\n\n/** Minted position NFT ids from a successful Position Manager mint receipt. */\nexport function uniswapV4PositionMintedTokenIdsFromReceipt(\n receipt: TransactionReceipt,\n positionManager: Address,\n owner: Address,\n): bigint[] {\n const pm = getAddress(positionManager)\n const wallet = getAddress(owner)\n const ids: bigint[] = []\n for (const log of receipt.logs) {\n try {\n if (getAddress(log.address) !== pm) continue\n const decoded = decodeEventLog({\n abi: [positionManagerTransferEvent],\n data: log.data,\n topics: log.topics,\n })\n if (decoded.eventName !== 'Transfer') continue\n const from = decoded.args.from\n const to = decoded.args.to\n const tokenId = decoded.args.tokenId\n if (from === zeroAddress && getAddress(to) === wallet) {\n ids.push(tokenId)\n }\n } catch {\n /* unrelated log */\n }\n }\n return ids\n}\n\nexport type UniswapV4RegistryErc721Row = {\n contractAddress: string\n tokenId: string\n name?: string\n symbol?: string\n}\n\n/** List positions from saved ERC721 tokens (Position Manager contract on this chain). */\nexport function uniswapV4ListPositionsFromRegistryForMcp(args: {\n chainId: number | string\n walletAddress: Address | string\n erc721Tokens: UniswapV4RegistryErc721Row[]\n positionManagerAddress?: Address | string\n}): { positions: UniswapV4PositionRow[]; source: 'token_registry' } {\n const chainId =\n typeof args.chainId === 'number' ? args.chainId : Number.parseInt(String(args.chainId), 10)\n if (!Number.isFinite(chainId) || chainId <= 0) {\n throw new Error('chainId must be a positive integer')\n }\n const wallet = getAddress(args.walletAddress)\n const pm = getAddress(\n args.positionManagerAddress\n ? String(args.positionManagerAddress)\n : getUniswapV4PositionManagerOrThrow(chainId),\n )\n const pmLower = pm.toLowerCase()\n const positions: UniswapV4PositionRow[] = []\n for (const row of args.erc721Tokens) {\n const addr = (row.contractAddress ?? '').trim()\n const tokenId = (row.tokenId ?? '').trim()\n if (!addr || !tokenId) continue\n try {\n if (getAddress(addr as `0x${string}`).toLowerCase() !== pmLower) continue\n } catch {\n continue\n }\n positions.push({\n tokenId,\n positionManager: pm,\n owner: wallet,\n name: row.name,\n symbol: row.symbol,\n })\n }\n positions.sort((a, b) => (BigInt(a.tokenId) < BigInt(b.tokenId) ? -1 : 1))\n return { positions, source: 'token_registry' }\n}\n\nfunction throwIfScanAborted(signal?: AbortSignal): void {\n if (signal?.aborted) {\n throw new DOMException('Position scan aborted.', 'AbortError')\n }\n}\n\nexport type UniswapV4PositionScanProgress = {\n latestBlock: string\n scanFromBlock: string\n scanningFromBlock: string\n scanningToBlock: string\n foundCount: number\n targetCount: number\n}\n\nconst TRANSFER_EVENT = {\n type: 'event',\n name: 'Transfer',\n inputs: [\n { indexed: true, name: 'from', type: 'address' },\n { indexed: true, name: 'to', type: 'address' },\n { indexed: true, name: 'tokenId', type: 'uint256' },\n ],\n} as const\n\n/** True when the RPC rejects `eth_getLogs` because the block span is too large. */\nexport function isEthGetLogsBlockRangeTooLargeError(err: unknown): boolean {\n const msg = (err instanceof Error ? err.message : String(err)).toLowerCase()\n return (\n msg.includes('block range too large') ||\n msg.includes('maximum allowed') ||\n msg.includes('query returned more than') ||\n msg.includes('exceed maximum block range') ||\n msg.includes('block range is too large')\n )\n}\n\ntype TransferLog = {\n args: {\n from?: Address\n to?: Address\n tokenId?: bigint\n }\n}\n\nasync function getTransferLogsForWalletInRange(args: {\n client: ReturnType<typeof createPublicClient>\n positionManager: Address\n wallet: Address\n fromBlock: bigint\n toBlock: bigint\n chunkSize: bigint\n}): Promise<TransferLog[]> {\n const { client, positionManager, wallet, fromBlock, toBlock } = args\n let chunkSize =\n args.chunkSize < UNISWAP_V4_LP_LOG_CHUNK_SIZE_MIN\n ? UNISWAP_V4_LP_LOG_CHUNK_SIZE_MIN\n : args.chunkSize\n\n const out: TransferLog[] = []\n let from = fromBlock\n\n while (from <= toBlock) {\n let to = from + chunkSize - 1n > toBlock ? toBlock : from + chunkSize - 1n\n\n for (;;) {\n try {\n const [toLogs, fromLogs] = await Promise.all([\n client.getLogs({\n address: positionManager,\n event: TRANSFER_EVENT,\n args: { to: wallet },\n fromBlock: from,\n toBlock: to,\n }),\n client.getLogs({\n address: positionManager,\n event: TRANSFER_EVENT,\n args: { from: wallet },\n fromBlock: from,\n toBlock: to,\n }),\n ])\n out.push(...(toLogs as TransferLog[]), ...(fromLogs as TransferLog[]))\n from = to + 1n\n break\n } catch (err) {\n if (!isEthGetLogsBlockRangeTooLargeError(err) || chunkSize <= UNISWAP_V4_LP_LOG_CHUNK_SIZE_MIN) {\n throw err\n }\n chunkSize = chunkSize / 2n\n if (chunkSize < UNISWAP_V4_LP_LOG_CHUNK_SIZE_MIN) {\n chunkSize = UNISWAP_V4_LP_LOG_CHUNK_SIZE_MIN\n }\n to = from + chunkSize - 1n > toBlock ? toBlock : from + chunkSize - 1n\n }\n }\n }\n\n return out\n}\n\n/** Parse `YYYY-MM-DD` as UTC midnight. */\nexport function parseUniswapV4ScanFromDateYmd(fromDate: string): number {\n const trimmed = fromDate.trim()\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(trimmed)) {\n throw new Error('fromDate must be YYYY-MM-DD')\n }\n const ms = Date.parse(`${trimmed}T00:00:00.000Z`)\n if (!Number.isFinite(ms)) {\n throw new Error(`Invalid fromDate: ${fromDate}`)\n }\n return Math.floor(ms / 1000)\n}\n\n/** Smallest block whose timestamp is >= `unixTime` (binary search). */\nexport async function resolveBlockAtOrAfterUnixTime(\n client: ReturnType<typeof createPublicClient>,\n unixTime: number,\n bounds: { minBlock: bigint; maxBlock: bigint },\n): Promise<bigint> {\n let lo = bounds.minBlock\n let hi = bounds.maxBlock\n let ans = hi\n while (lo <= hi) {\n const mid = (lo + hi) / 2n\n const block = await client.getBlock({ blockNumber: mid })\n const ts = Number(block.timestamp)\n if (ts >= unixTime) {\n ans = mid\n if (mid === 0n) break\n hi = mid - 1n\n } else {\n lo = mid + 1n\n }\n }\n return ans\n}\n\n/** Map a calendar date to the first block to scan from (never before Position Manager deploy). */\nexport async function resolveUniswapV4PositionScanFromDate(args: {\n chainId: number\n rpcUrl: string\n fromDate: string\n}): Promise<bigint> {\n const unixTime = parseUniswapV4ScanFromDateYmd(args.fromDate)\n const chain = defineChain({\n id: args.chainId,\n name: `uniswap-v4-${args.chainId}`,\n nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },\n rpcUrls: { default: { http: [args.rpcUrl] } },\n })\n const client = createPublicClient({ chain, transport: http(args.rpcUrl) })\n const latest = await client.getBlockNumber()\n const deploy = getUniswapV4PositionManagerDeployBlock(args.chainId) ?? 0n\n const resolved = await resolveBlockAtOrAfterUnixTime(client, unixTime, {\n minBlock: deploy,\n maxBlock: latest,\n })\n return resolved < deploy ? deploy : resolved\n}\n\nfunction defaultScanFromBlock(args: {\n chainId: number\n latest: bigint\n fromBlock?: bigint\n maxBlocksToScan: bigint\n}): bigint {\n if (args.fromBlock != null) return args.fromBlock\n const deploy = getUniswapV4PositionManagerDeployBlock(args.chainId)\n if (deploy != null) return deploy\n return args.latest > args.maxBlocksToScan ? args.latest - args.maxBlocksToScan : 0n\n}\n\n/**\n * List v4 position NFT tokenIds owned by `walletAddress` via Position Manager Transfer logs.\n * Uses small `eth_getLogs` chunks (default 200 blocks) and scans backward so wallets with\n * few positions finish without walking full chain history.\n */\nexport async function listUniswapV4PositionsForWallet(args: {\n chainId: number\n rpcUrl: string\n walletAddress: Address | string\n positionManagerAddress?: Address | string\n fromBlock?: bigint\n maxBlocksToScan?: bigint\n chunkSize?: bigint\n onProgress?: (progress: UniswapV4PositionScanProgress) => void\n signal?: AbortSignal\n}): Promise<UniswapV4PositionRow[]> {\n throwIfScanAborted(args.signal)\n const wallet = getAddress(args.walletAddress)\n const pm = getAddress(\n args.positionManagerAddress\n ? String(args.positionManagerAddress)\n : getUniswapV4PositionManagerOrThrow(args.chainId),\n )\n const chain = defineChain({\n id: args.chainId,\n name: `uniswap-v4-${args.chainId}`,\n nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },\n rpcUrls: { default: { http: [args.rpcUrl] } },\n })\n const client = createPublicClient({ chain, transport: http(args.rpcUrl) })\n const latest = await client.getBlockNumber()\n const maxScan = args.maxBlocksToScan ?? 500_000n\n const chunkSize = args.chunkSize ?? UNISWAP_V4_LP_LOG_CHUNK_SIZE_DEFAULT\n const scanFrom = defaultScanFromBlock({\n chainId: args.chainId,\n latest,\n fromBlock: args.fromBlock,\n maxBlocksToScan: maxScan,\n })\n\n const balance = await client.readContract({\n address: pm,\n abi: erc721BalanceAbi,\n functionName: 'balanceOf',\n args: [wallet],\n })\n const targetCount = Number(balance)\n const emitProgress = (scanningFromBlock: bigint, scanningToBlock: bigint, foundCount: number) => {\n args.onProgress?.({\n latestBlock: latest.toString(),\n scanFromBlock: scanFrom.toString(),\n scanningFromBlock: scanningFromBlock.toString(),\n scanningToBlock: scanningToBlock.toString(),\n foundCount,\n targetCount,\n })\n }\n\n if (balance === 0n) {\n emitProgress(latest, latest, 0)\n return []\n }\n\n const candidates = new Set<string>()\n const verified = new Map<string, UniswapV4PositionRow>()\n let toBlock = latest\n\n while (toBlock >= scanFrom && verified.size < targetCount) {\n throwIfScanAborted(args.signal)\n let fromBlock = toBlock >= chunkSize - 1n ? toBlock - chunkSize + 1n : 0n\n if (fromBlock < scanFrom) fromBlock = scanFrom\n\n emitProgress(fromBlock, toBlock, verified.size)\n\n const logs = await getTransferLogsForWalletInRange({\n client,\n positionManager: pm,\n wallet,\n fromBlock,\n toBlock,\n chunkSize,\n })\n\n for (const log of logs) {\n const tokenId = log.args.tokenId?.toString()\n if (!tokenId) continue\n const to = log.args.to != null ? getAddress(log.args.to) : null\n const from = log.args.from != null ? getAddress(log.args.from) : null\n if (to === wallet) candidates.add(tokenId)\n if (from === wallet) candidates.delete(tokenId)\n }\n\n for (const tokenId of candidates) {\n if (verified.has(tokenId)) continue\n try {\n const owner = await client.readContract({\n address: pm,\n abi: erc721BalanceAbi,\n functionName: 'ownerOf',\n args: [BigInt(tokenId)],\n })\n if (getAddress(owner) !== wallet) continue\n verified.set(tokenId, { tokenId, positionManager: pm, owner: wallet })\n if (verified.size >= targetCount) break\n } catch {\n /* transferred away since log scan */\n }\n }\n\n if (verified.size >= targetCount) break\n if (fromBlock <= scanFrom) break\n toBlock = fromBlock - 1n\n }\n\n const out = [...verified.values()]\n out.sort((a, b) => (BigInt(a.tokenId) < BigInt(b.tokenId) ? -1 : 1))\n return out\n}\n\nexport async function readUniswapV4PositionInfoRaw(args: {\n chainId: number\n rpcUrl: string\n tokenId: string | number\n positionManagerAddress?: Address | string\n}): Promise<{ info: bigint; positionManager: Address }> {\n const pm = getAddress(\n args.positionManagerAddress\n ? String(args.positionManagerAddress)\n : getUniswapV4PositionManagerOrThrow(args.chainId),\n )\n const chain = defineChain({\n id: args.chainId,\n name: `uniswap-v4-${args.chainId}`,\n nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },\n rpcUrls: { default: { http: [args.rpcUrl] } },\n })\n const client = createPublicClient({ chain, transport: http(args.rpcUrl) })\n const info = await client.readContract({\n address: pm,\n abi: positionInfoAbi,\n functionName: 'positionInfo',\n args: [BigInt(args.tokenId)],\n })\n return { info, positionManager: pm }\n}\n\n/** MCP handler for `ctm_uniswap_v4_lp_list_positions`. */\nexport async function uniswapV4ListPositionsForMcp(args: {\n chainId: number | string\n rpcUrl: string\n walletAddress: string\n positionManagerAddress?: string\n fromBlock?: string | number\n onProgress?: (progress: UniswapV4PositionScanProgress) => void\n signal?: AbortSignal\n}): Promise<{ positions: UniswapV4PositionRow[] }> {\n const chainId =\n typeof args.chainId === 'number' ? args.chainId : Number.parseInt(String(args.chainId), 10)\n if (!Number.isFinite(chainId) || chainId <= 0) {\n throw new Error('chainId must be a positive integer')\n }\n const fromBlock =\n args.fromBlock != null && String(args.fromBlock).trim() !== ''\n ? BigInt(String(args.fromBlock).trim())\n : undefined\n const positions = await listUniswapV4PositionsForWallet({\n chainId,\n rpcUrl: args.rpcUrl,\n walletAddress: args.walletAddress,\n positionManagerAddress: args.positionManagerAddress,\n fromBlock,\n onProgress: args.onProgress,\n signal: args.signal,\n })\n return { positions }\n}\n\n/** Stub — continuum-node-sdk MCP server lists positions from token registry. */\nexport function uniswapV4ListPositionsRegistryMcpPlaceholder(): never {\n throw new Error(\n 'ctm_uniswap_v4_lp_list_positions must run via continuum-node-sdk MCP (token registry, no RPC scan).',\n )\n}\n\n/** Stub — continuum-node-sdk MCP server implements registration (management POST). */\nexport function uniswapV4RegisterPositionNftPlaceholder(): never {\n throw new Error(\n 'ctm_uniswap_v4_register_position_nft must run via continuum-node-sdk MCP (management-signed addToken).',\n )\n}\n\n/** Stub — continuum-node-sdk MCP server implements registration from mint receipt. */\nexport function uniswapV4RegisterPositionFromMintTxPlaceholder(): never {\n throw new Error(\n 'ctm_uniswap_v4_register_position_from_mint_tx must run via continuum-node-sdk MCP (management-signed addToken).',\n )\n}\n\nexport function isNativeUniswapLpTokenAddress(token: string): boolean {\n try {\n return getAddress(token as `0x${string}`) === zeroAddress\n } catch {\n return token.toLowerCase() === zeroAddress.toLowerCase()\n }\n}\n","import {\n createPublicClient,\n defineChain,\n encodeFunctionData,\n erc20Abi,\n getAddress,\n http,\n parseAbi,\n type Address,\n type PublicClient,\n} from 'viem'\nimport { type KeyGenSubsetForPermit } from '../../../core/types.js'\nimport { buildEvmMultisignBatch } from '../../../chains/evm/buildBatch.js'\nimport type { EvmTxStep } from '../../../chains/evm/types.js'\nimport {\n UNISWAP_V4_LP_COLLECT_DEFAULT_GAS_UNITS,\n UNISWAP_V4_LP_DECREASE_DEFAULT_GAS_UNITS,\n UNISWAP_V4_LP_ERC20_APPROVE_FALLBACK,\n UNISWAP_V4_LP_INCREASE_DEFAULT_GAS_UNITS,\n UNISWAP_V4_LP_MINT_DEFAULT_GAS_UNITS,\n UNISWAP_V4_LP_WETH_DEPOSIT_FALLBACK,\n} from './constants.js'\nimport type { UniswapLpTransactionRequest } from './liquidityApi.js'\nimport { parseUniswapLpApiSnapshot, type UniswapLpAction } from './liquidityQuote.js'\nimport { isNativeUniswapLpTokenAddress } from './positions.js'\n\ntype ChainRow = {\n legacy?: boolean\n gasLimit?: number\n gasMultiplier?: number\n gasPrice?: number\n baseFee?: number\n priorityFee?: number\n baseFeeMultiplier?: number\n}\n\nconst wethDepositAbi = parseAbi(['function deposit() payable'])\nconst erc20AllowanceAbi = parseAbi([\n 'function allowance(address owner, address spender) view returns (uint256)',\n 'function decimals() view returns (uint8)',\n])\n\nfunction parseOptionalGasLimitString(raw: string | number | undefined): bigint | null {\n if (raw == null) return null\n const s = String(raw).trim()\n if (!s) return null\n try {\n if (/^0x[0-9a-fA-F]+$/.test(s)) return BigInt(s)\n return BigInt(s)\n } catch {\n return null\n }\n}\n\nfunction parseTxValueWei(tx: UniswapLpTransactionRequest): bigint {\n const raw = tx.value ?? '0'\n try {\n if (typeof raw === 'string' && /^0x[0-9a-fA-F]+$/.test(raw.trim())) return BigInt(raw.trim())\n return BigInt(String(raw).trim() || '0')\n } catch {\n return 0n\n }\n}\n\nfunction dataHexFromTx(tx: UniswapLpTransactionRequest): `0x${string}` {\n const d = (tx.data ?? '0x').toString().trim()\n return (d.startsWith('0x') ? d : `0x${d}`) as `0x${string}`\n}\n\nfunction parseExtraJsonObject(\n detail: Record<string, unknown> | null | undefined,\n): Record<string, unknown> | null {\n if (!detail) return null\n const raw = detail.ExtraJSON ?? detail.extraJSON\n if (raw == null) return null\n if (typeof raw === 'object' && !Array.isArray(raw)) return raw as Record<string, unknown>\n if (typeof raw === 'string' && raw.trim()) {\n try {\n const p = JSON.parse(raw) as unknown\n if (p && typeof p === 'object' && !Array.isArray(p)) return p as Record<string, unknown>\n } catch {\n return null\n }\n }\n return null\n}\n\nfunction uniswapV4LiquidityEvmTypeFromBatchMeta(\n ex: Record<string, unknown> | null,\n batchIndex: number,\n): boolean {\n if (!ex) return false\n const bm = ex.batchMeta\n if (!Array.isArray(bm) || !bm[batchIndex] || typeof bm[batchIndex] !== 'object' || Array.isArray(bm[batchIndex])) {\n return false\n }\n const evm0 = (bm[batchIndex] as Record<string, unknown>).evm\n if (!evm0 || typeof evm0 !== 'object' || Array.isArray(evm0)) return false\n return String((evm0 as Record<string, unknown>).type ?? '') === 'uniswap_v4_liquidity_tx'\n}\n\nexport function isUniswapV4LiquidityEvmSignRequest(\n detail: Record<string, unknown> | null | undefined,\n batchIndex?: number,\n): boolean {\n const ex = parseExtraJsonObject(detail)\n if (batchIndex != null && batchIndex >= 0) {\n if (uniswapV4LiquidityEvmTypeFromBatchMeta(ex, batchIndex)) return true\n } else if (uniswapV4LiquidityEvmTypeFromBatchMeta(ex, 0)) {\n return true\n }\n const evm = ex?.evm\n if (!evm || typeof evm !== 'object' || Array.isArray(evm)) return false\n return String((evm as Record<string, unknown>).type ?? '') === 'uniswap_v4_liquidity_tx'\n}\n\nfunction defaultGasForAction(action: UniswapLpAction): bigint {\n switch (action) {\n case 'mint':\n return UNISWAP_V4_LP_MINT_DEFAULT_GAS_UNITS\n case 'increase':\n return UNISWAP_V4_LP_INCREASE_DEFAULT_GAS_UNITS\n case 'decrease':\n return UNISWAP_V4_LP_DECREASE_DEFAULT_GAS_UNITS\n case 'collect':\n return UNISWAP_V4_LP_COLLECT_DEFAULT_GAS_UNITS\n default:\n return UNISWAP_V4_LP_MINT_DEFAULT_GAS_UNITS\n }\n}\n\ntype LiquidityMultisignCommon = {\n keyGen: KeyGenSubsetForPermit\n chainId: number\n rpcUrl: string\n chainDetail: ChainRow\n useCustomGas: boolean\n customGasChainDetails?: Record<string, unknown> | null\n executorAddress: Address\n purposeText: string\n lpResponse: Record<string, unknown>\n action: UniswapLpAction\n /** Wrapped native token when pool uses native ETH as currency0/1. */\n nativeWrapped?: Address\n nftTokenId?: string | number\n poolReference?: string\n}\n\nasync function resolveApproveTargets(args: {\n publicClient: PublicClient\n executor: Address\n spender: Address\n token0?: { tokenAddress: string; amount: string }\n token1?: { tokenAddress: string; amount: string }\n nativeWrapped?: Address\n}): Promise<\n Array<{ token: Address; amount: bigint; kind: 'approve' | 'weth_deposit' }>\n> {\n const out: Array<{ token: Address; amount: bigint; kind: 'approve' | 'weth_deposit' }> = []\n const pairs = [args.token0, args.token1].filter(Boolean) as Array<{\n tokenAddress: string\n amount: string\n }>\n\n for (const row of pairs) {\n const amt = BigInt(row.amount)\n if (amt <= 0n) continue\n if (isNativeUniswapLpTokenAddress(row.tokenAddress)) {\n if (!args.nativeWrapped) {\n throw new Error('nativeWrapped is required when LP uses native ETH (0x0) token.')\n }\n out.push({ token: getAddress(args.nativeWrapped), amount: amt, kind: 'weth_deposit' })\n continue\n }\n out.push({ token: getAddress(row.tokenAddress), amount: amt, kind: 'approve' })\n }\n\n const deduped: typeof out = []\n for (const row of out) {\n const existing = deduped.find((d) => d.token === row.token && d.kind === row.kind)\n if (existing) {\n if (row.amount > existing.amount) existing.amount = row.amount\n } else {\n deduped.push({ ...row })\n }\n }\n\n const steps: typeof out = []\n for (const row of deduped) {\n if (row.kind === 'weth_deposit') {\n steps.push(row)\n continue\n }\n const allowance = await args.publicClient.readContract({\n address: row.token,\n abi: erc20AllowanceAbi,\n functionName: 'allowance',\n args: [args.executor, args.spender],\n })\n if (allowance < row.amount) {\n steps.push(row)\n }\n }\n return steps\n}\n\nasync function buildEvmMultisignBodyUniswapV4LiquidityBatchInternal(\n args: LiquidityMultisignCommon,\n): Promise<{ bodyForSign: Record<string, unknown>; messageToSign: string }> {\n const parsed = parseUniswapLpApiSnapshot({ action: args.action, lpResponse: args.lpResponse })\n const tx = parsed.transaction\n const to = getAddress(tx.to)\n const dataHex = dataHexFromTx(tx)\n const valueWei = parseTxValueWei(tx)\n const executor = getAddress(args.executorAddress)\n const spender = to\n\n const chain = defineChain({\n id: args.chainId,\n name: `uniswap-v4-lp-${args.chainId}`,\n nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },\n rpcUrls: { default: { http: [args.rpcUrl] } },\n })\n const publicClient = createPublicClient({ chain, transport: http(args.rpcUrl) })\n\n const approveTargets = await resolveApproveTargets({\n publicClient,\n executor,\n spender,\n token0: parsed.token0,\n token1: parsed.token1,\n nativeWrapped: args.nativeWrapped,\n })\n\n const steps: EvmTxStep[] = []\n for (const target of approveTargets) {\n if (target.kind === 'weth_deposit') {\n steps.push({\n to: target.token,\n data: encodeFunctionData({ abi: wethDepositAbi, functionName: 'deposit' }),\n value: target.amount,\n fallbackGas: UNISWAP_V4_LP_WETH_DEPOSIT_FALLBACK,\n })\n steps.push({\n to: target.token,\n data: encodeFunctionData({\n abi: erc20Abi,\n functionName: 'approve',\n args: [spender, target.amount],\n }),\n value: 0n,\n fallbackGas: UNISWAP_V4_LP_ERC20_APPROVE_FALLBACK,\n })\n } else {\n steps.push({\n to: target.token,\n data: encodeFunctionData({\n abi: erc20Abi,\n functionName: 'approve',\n args: [spender, target.amount],\n }),\n value: 0n,\n fallbackGas: UNISWAP_V4_LP_ERC20_APPROVE_FALLBACK,\n })\n }\n }\n\n const lpFallbackGas = defaultGasForAction(args.action)\n const fromTradeApi =\n parseOptionalGasLimitString(tx.gasLimit) ?? parseOptionalGasLimitString((tx as { gas?: string }).gas)\n steps.push({\n to,\n data: dataHex,\n value: valueWei,\n fallbackGas: fromTradeApi != null && fromTradeApi > 0n ? fromTradeApi : lpFallbackGas,\n })\n\n const actionLabel =\n args.action === 'mint'\n ? 'mint liquidity'\n : args.action === 'increase'\n ? 'increase liquidity'\n : args.action === 'decrease'\n ? 'decrease liquidity'\n : 'collect fees'\n\n const dataNo0x = dataHex.startsWith('0x') ? dataHex.slice(2) : dataHex\n const lpIndex = steps.length - 1\n\n return buildEvmMultisignBatch({\n context: {\n chainCategory: 'evm',\n keyGen: args.keyGen,\n purposeText: args.purposeText,\n chainId: args.chainId,\n rpcUrl: args.rpcUrl,\n executorAddress: args.executorAddress,\n chainDetail: args.chainDetail,\n useCustomGas: args.useCustomGas,\n customGasChainDetails: args.customGasChainDetails,\n },\n steps,\n purposeSuffix: `Uniswap V4: ${steps.length}-tx batch — ${actionLabel} (classic ERC-20 approve + Position Manager).`,\n firstMsgRawNo0x: dataNo0x,\n destinationAddress: to,\n buildBatchMeta: ({ index }) => {\n const isLpStep = index === lpIndex\n return {\n signatureText: JSON.stringify({\n kind: 'UniswapV4Liquidity',\n action: args.action,\n step: index,\n lpTx: isLpStep,\n }),\n ...(isLpStep\n ? {\n evm: { type: 'uniswap_v4_liquidity_tx', version: 1, chainId: String(args.chainId) },\n uniswapV4Liquidity: {\n action: args.action,\n skipPermit2Batch: true,\n nftTokenId: args.nftTokenId != null ? String(args.nftTokenId) : undefined,\n poolReference: args.poolReference,\n lpResponseSnapshot: args.lpResponse,\n token0: parsed.token0,\n token1: parsed.token1,\n tickLower: parsed.tickLower,\n tickUpper: parsed.tickUpper,\n transaction: {\n to: tx.to,\n value: tx.value,\n dataNibbles: dataNo0x.length,\n gasLimit: tx.gasLimit,\n },\n originalPurpose: args.purposeText,\n },\n }\n : {}),\n }\n },\n })\n}\n\nexport async function buildEvmMultisignBodyUniswapV4MintLiquidityBatch(\n args: Omit<LiquidityMultisignCommon, 'action' | 'nftTokenId'> & { poolReference?: string },\n): Promise<{ bodyForSign: Record<string, unknown>; messageToSign: string }> {\n return buildEvmMultisignBodyUniswapV4LiquidityBatchInternal({ ...args, action: 'mint' })\n}\n\nexport async function buildEvmMultisignBodyUniswapV4IncreaseLiquidityBatch(\n args: Omit<LiquidityMultisignCommon, 'action'> & { nftTokenId: string | number },\n): Promise<{ bodyForSign: Record<string, unknown>; messageToSign: string }> {\n return buildEvmMultisignBodyUniswapV4LiquidityBatchInternal({ ...args, action: 'increase' })\n}\n\nexport async function buildEvmMultisignBodyUniswapV4DecreaseLiquidityBatch(\n args: Omit<LiquidityMultisignCommon, 'action'> & { nftTokenId: string | number },\n): Promise<{ bodyForSign: Record<string, unknown>; messageToSign: string }> {\n return buildEvmMultisignBodyUniswapV4LiquidityBatchInternal({ ...args, action: 'decrease' })\n}\n\nexport async function buildEvmMultisignBodyUniswapV4CollectFeesBatch(\n args: Omit<LiquidityMultisignCommon, 'action'> & { nftTokenId: string | number },\n): Promise<{ bodyForSign: Record<string, unknown>; messageToSign: string }> {\n return buildEvmMultisignBodyUniswapV4LiquidityBatchInternal({ ...args, action: 'collect' })\n}\n\nexport {\n UNISWAP_V4_LP_MINT_DEFAULT_GAS_UNITS,\n UNISWAP_V4_LP_INCREASE_DEFAULT_GAS_UNITS,\n UNISWAP_V4_LP_DECREASE_DEFAULT_GAS_UNITS,\n UNISWAP_V4_LP_COLLECT_DEFAULT_GAS_UNITS,\n}\n","import type { Address } from 'viem'\nimport type { EvmChainDetail } from '../../../chains/evm/types.js'\nimport type { KeyGenSubsetForPermit } from '../../../core/types.js'\nimport type { UniswapQuoteTradeType } from './quote.js'\nimport { uniswapTradeQuote } from './quote.js'\nimport { uniswapCreateSwap, buildEvmMultisignBodyUniswapV4SkipPermit2Batch } from './swapMultisign.js'\nimport { swapTransactionDeadlineUnixFromExpiryMinutes } from './swapMultisign.js'\n\nexport type SwapExactInputArgs = {\n keyGen: KeyGenSubsetForPermit\n purposeText: string\n chainId: number\n rpcUrl: string\n executorAddress: Address\n chainDetail: EvmChainDetail\n useCustomGas: boolean\n customGasChainDetails?: Record<string, unknown> | null\n tokenIn: Address\n uniswapApiKey: string\n fullQuote: Record<string, unknown>\n slippagePercent?: number\n swapTransactionDeadlineUnix?: number\n baseUrl?: string\n}\n\n/** Quote then build swap multisign body for EXACT_INPUT (caller must have fetched quote first for EXACT_OUTPUT). */\nexport async function swapFromQuote(args: SwapExactInputArgs & { swap: Awaited<ReturnType<typeof uniswapCreateSwap>> }) {\n const deadline =\n args.swapTransactionDeadlineUnix ??\n swapTransactionDeadlineUnixFromExpiryMinutes(30)\n return buildEvmMultisignBodyUniswapV4SkipPermit2Batch({\n keyGen: args.keyGen,\n chainId: args.chainId,\n rpcUrl: args.rpcUrl,\n chainDetail: args.chainDetail,\n useCustomGas: args.useCustomGas,\n customGasChainDetails: args.customGasChainDetails,\n tokenIn: args.tokenIn,\n executorAddress: args.executorAddress,\n swap: args.swap.swap,\n createSwapResponse: args.swap,\n fullQuoteSnapshot: args.fullQuote,\n purposeText: args.purposeText,\n swapDeadlineUnix: deadline,\n slippagePercent: args.slippagePercent,\n })\n}\n\nexport async function quoteSwap(\n args: Parameters<typeof uniswapTradeQuote>[0],\n): Promise<Record<string, unknown>> {\n return uniswapTradeQuote(args)\n}\n\nexport async function createSwap(\n args: Parameters<typeof uniswapCreateSwap>[0],\n): Promise<Awaited<ReturnType<typeof uniswapCreateSwap>>> {\n return uniswapCreateSwap(args)\n}\n\nexport async function swapExactInput(\n args: SwapExactInputArgs & {\n tradeType?: UniswapQuoteTradeType\n },\n) {\n const swap = await uniswapCreateSwap({\n uniswapApiKey: args.uniswapApiKey,\n fullQuoteFromPermit: args.fullQuote,\n baseUrl: args.baseUrl,\n swapTransactionDeadlineUnix: args.swapTransactionDeadlineUnix,\n useServerProxy: false,\n })\n return swapFromQuote({ ...args, swap })\n}\n","import type { ProtocolModule } from '../../../core/types.js'\nimport { registerProtocolModule } from '../../../core/registry.js'\nimport { isUniswapV4ChainSupported } from './constants.js'\n\nexport * from './constants.js'\nexport * from './quote.js'\nexport * from './swapMultisign.js'\nexport * from './liquidityApi.js'\nexport * from './liquidityQuote.js'\nexport * from './liquidityMultisign.js'\nexport * from './positions.js'\nexport * from './poolId.js'\nexport * from './knownLpPools.js'\nexport * from './purpose.js'\nexport * from './support.js'\nexport * from './swap.js'\n\nexport {\n isUniswapV4SwapEvmSignRequest,\n resolveRouterSwapGasUnitsFromSignRequest,\n} from './swapMultisign.js'\n\nexport { isUniswapV4LiquidityEvmSignRequest } from './liquidityMultisign.js'\n\nexport const UNISWAP_V4_PROTOCOL_ID = 'uniswap-v4'\n\nexport const uniswapV4ProtocolModule: ProtocolModule = {\n id: UNISWAP_V4_PROTOCOL_ID,\n chainCategory: 'evm',\n isChainSupported(ctx) {\n if (ctx.chainCategory !== 'evm') return false\n return isUniswapV4ChainSupported(ctx.chainId)\n },\n isTokenSupported(token) {\n if (token.category !== 'evm') return false\n return token.kind === 'native' || token.kind === 'erc20'\n },\n actions: [\n {\n id: 'uniswap-v4.swap-exact-input',\n protocolId: UNISWAP_V4_PROTOCOL_ID,\n chainCategory: 'evm',\n description: 'Swap ERC-20 or native token via Uniswap V4 Universal Router (classic allowance path)',\n commonParams: ['keyGen', 'purposeText', 'useCustomGas'],\n params: {\n tokenIn: { type: 'address', required: true, description: 'Input token (0x0 for native)' },\n tokenOut: { type: 'address', required: true, description: 'Output token address' },\n amount: { type: 'string', required: true, description: 'Human or wei amount per trade type' },\n slippagePercent: { type: 'number', required: true, description: 'Slippage tolerance percent' },\n swapTransactionDeadlineUnix: {\n type: 'number',\n required: false,\n description: 'On-chain swap deadline (unix seconds)',\n },\n uniswapApiKey: { type: 'string', required: true, description: 'Uniswap Trade API key' },\n },\n },\n {\n id: 'uniswap-v4.quote',\n protocolId: UNISWAP_V4_PROTOCOL_ID,\n chainCategory: 'evm',\n description: 'Fetch Uniswap Trade API quote',\n commonParams: ['keyGen'],\n params: {\n tokenIn: { type: 'address', required: true, description: 'Input token' },\n tokenOut: { type: 'address', required: true, description: 'Output token' },\n amount: { type: 'string', required: true, description: 'Amount for quote' },\n type: { type: 'EXACT_INPUT | EXACT_OUTPUT', required: true, description: 'Trade type' },\n },\n },\n {\n id: 'uniswap-v4.mint-liquidity',\n protocolId: UNISWAP_V4_PROTOCOL_ID,\n chainCategory: 'evm',\n description: 'Mint a new Uniswap V4 concentrated liquidity position (Position Manager NFT)',\n commonParams: ['keyGen', 'purposeText', 'useCustomGas'],\n params: {\n lpResponse: { type: 'object', required: true, description: 'Full LP API create response' },\n nativeWrapped: { type: 'address', required: false, description: 'WETH when pool uses native ETH' },\n poolReference: { type: 'string', required: false, description: 'V4 pool id' },\n uniswapApiKey: { type: 'string', required: true, description: 'Uniswap API key' },\n },\n },\n {\n id: 'uniswap-v4.increase-liquidity',\n protocolId: UNISWAP_V4_PROTOCOL_ID,\n chainCategory: 'evm',\n description: 'Increase liquidity on an existing Uniswap V4 position NFT',\n commonParams: ['keyGen', 'purposeText', 'useCustomGas'],\n params: {\n nftTokenId: { type: 'string', required: true, description: 'Position NFT token id' },\n lpResponse: { type: 'object', required: true, description: 'Full LP API increase response' },\n },\n },\n {\n id: 'uniswap-v4.decrease-liquidity',\n protocolId: UNISWAP_V4_PROTOCOL_ID,\n chainCategory: 'evm',\n description: 'Decrease liquidity on an existing Uniswap V4 position NFT',\n commonParams: ['keyGen', 'purposeText', 'useCustomGas'],\n params: {\n nftTokenId: { type: 'string', required: true, description: 'Position NFT token id' },\n lpResponse: { type: 'object', required: true, description: 'Full LP API decrease response' },\n },\n },\n {\n id: 'uniswap-v4.collect-fees',\n protocolId: UNISWAP_V4_PROTOCOL_ID,\n chainCategory: 'evm',\n description: 'Collect accrued fees from a Uniswap V4 position NFT',\n commonParams: ['keyGen', 'purposeText', 'useCustomGas'],\n params: {\n nftTokenId: { type: 'string', required: true, description: 'Position NFT token id' },\n lpResponse: { type: 'object', required: true, description: 'Full LP API claim response' },\n },\n },\n ],\n}\n\nregisterProtocolModule(uniswapV4ProtocolModule)\n\nimport { uniswapTradeQuote } from './quote.js'\nimport { buildEvmMultisignBodyUniswapV4SkipPermit2Batch } from './swapMultisign.js'\nimport { swapExactInput as swapExactInputFn, quoteSwap, createSwap, swapFromQuote } from './swap.js'\nimport {\n uniswapLpClaimFees,\n uniswapLpCreatePosition,\n uniswapLpDecreasePosition,\n uniswapLpIncreasePosition,\n} from './liquidityApi.js'\nimport {\n buildEvmMultisignBodyUniswapV4CollectFeesBatch,\n buildEvmMultisignBodyUniswapV4DecreaseLiquidityBatch,\n buildEvmMultisignBodyUniswapV4IncreaseLiquidityBatch,\n buildEvmMultisignBodyUniswapV4MintLiquidityBatch,\n} from './liquidityMultisign.js'\nimport { listUniswapV4PositionsForWallet } from './positions.js'\n\nexport const uniswapV4 = {\n quoteSwap,\n createSwap,\n swapExactInput: swapExactInputFn,\n swapFromQuote,\n buildSwapMultisignBody: buildEvmMultisignBodyUniswapV4SkipPermit2Batch,\n quote: uniswapTradeQuote,\n createLiquidityPosition: uniswapLpCreatePosition,\n increaseLiquidityPosition: uniswapLpIncreasePosition,\n decreaseLiquidityPosition: uniswapLpDecreasePosition,\n claimLiquidityFees: uniswapLpClaimFees,\n buildMintLiquidityMultisignBody: buildEvmMultisignBodyUniswapV4MintLiquidityBatch,\n buildIncreaseLiquidityMultisignBody: buildEvmMultisignBodyUniswapV4IncreaseLiquidityBatch,\n buildDecreaseLiquidityMultisignBody: buildEvmMultisignBodyUniswapV4DecreaseLiquidityBatch,\n buildCollectFeesMultisignBody: buildEvmMultisignBodyUniswapV4CollectFeesBatch,\n listPositions: listUniswapV4PositionsForWallet,\n isChainSupported: isUniswapV4ChainSupported,\n}\n","import { parseEvmChainIdToNumber } from '../../../chains/evm/chainIdParse.js'\n\nconst CURVE_FULL_NETWORK_CONSTANTS_CHAIN_IDS: ReadonlySet<number> = new Set([\n 1, 10, 56, 100, 137, 146, 196, 250, 252, 324, 999, 1284, 2222, 5000, 8453, 42161, 42220, 43114, 1313161554,\n])\n\nexport function isCurveApiChainSupported(chainId: string | number | bigint | null | undefined): boolean {\n const n = parseEvmChainIdToNumber(chainId)\n if (Number.isNaN(n) || n < 0) return false\n return CURVE_FULL_NETWORK_CONSTANTS_CHAIN_IDS.has(n)\n}\n\nexport { isCurveApiChainSupported as isCurveDaoChainSupported }\n","import { getAddress, isAddress } from 'viem'\nimport { normalizeHumanDecimalAmount } from '../../../chains/evm/normalizeAmount.js'\n\nexport const CURVE_NATIVE_PLACEHOLDER = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'\n\nconst ETH_PLACEHOLDER = CURVE_NATIVE_PLACEHOLDER\n\nfunction normalizeAddr(a: string): string {\n return a.toLowerCase()\n}\n\n/** Map token in list to the address shape Curve uses in pool graphs (native → 0xeeee…). */\nexport function toCurveTokenKey(tokenInAddress: string, wrappedNative: string | undefined): string {\n if (!isAddress(tokenInAddress)) return normalizeAddr(tokenInAddress)\n try {\n const a = getAddress(tokenInAddress)\n if (wrappedNative && a.toLowerCase() === wrappedNative.toLowerCase()) {\n return ETH_PLACEHOLDER\n }\n return a.toLowerCase()\n } catch {\n return normalizeAddr(tokenInAddress)\n }\n}\n\n/**\n * Router / `getBestRouteAndOutput` expect the same coin id as the pool graph: wrapped native\n * is represented as `0xeeee…`, not the WETH (etc.) contract. Without this, route discovery can\n * return an empty route while BFS (which uses `toCurveTokenKey`) still finds a path.\n */\nexport function toCurveRouterTokenId(tokenAddress: string, wrappedNative: string | undefined): string {\n const t = (tokenAddress ?? '').trim().toLowerCase()\n if (t === ETH_PLACEHOLDER) return ETH_PLACEHOLDER\n if (!isAddress((tokenAddress ?? '').trim())) return normalizeAddr((tokenAddress ?? '').trim())\n try {\n const a = getAddress((tokenAddress ?? '').trim())\n if (wrappedNative && a.toLowerCase() === wrappedNative.toLowerCase()) {\n return ETH_PLACEHOLDER\n }\n /** Lowercase matches pool graph keys and `@curvefi/api`’s `DECIMALS` lookups. */\n return a.toLowerCase()\n } catch {\n return normalizeAddr((tokenAddress ?? '').trim())\n }\n}\n\n/**\n * Turn the user’s decimal string into a canonical form using **this chain’s** token-in decimals\n * (from the asset row). `@curvefi/api` uses the same for `parseUnits` when building routes; an\n * over-long fraction (e.g. 1e-8 on USDC) can make internal calls fail and yield an empty route / 0.0.\n */\nexport function normalizeCurveRouterAmountString(raw: string, tokenInDecimals: number): string {\n return normalizeHumanDecimalAmount(raw, tokenInDecimals)\n}\n\nfunction addEdge(adj: Map<string, Set<string>>, a: string, b: string) {\n if (a === b) return\n if (!adj.has(a)) adj.set(a, new Set())\n if (!adj.has(b)) adj.set(b, new Set())\n adj.get(a)!.add(b)\n adj.get(b)!.add(a)\n}\n\n/**\n * Build graph from the same pool list the Curve router uses (`getPool` / `getPoolList` on the\n * public `@curvefi/api` instance; `getPoolsData` is internal).\n */\nexport function buildCurveLiquidityGraphFromApi(curve: {\n getPoolList: () => string[]\n getPool: (id: string) => {\n underlyingCoinAddresses: string[] | undefined\n wrappedCoinAddresses: string[] | undefined\n }\n}): Map<string, Set<string>> {\n const adj = new Map<string, Set<string>>()\n for (const id of curve.getPoolList()) {\n try {\n const pool = curve.getPool(id)\n const w = (pool.wrappedCoinAddresses ?? []).map(normalizeAddr)\n const u = (pool.underlyingCoinAddresses ?? []).map(normalizeAddr)\n const all = [...new Set([...w, ...u])]\n for (let i = 0; i < all.length; i++) {\n for (let j = i + 1; j < all.length; j++) {\n addEdge(adj, all[i], all[j])\n }\n }\n } catch {\n /* pool constructor can throw for stale ids */\n }\n }\n return adj\n}\n\n/**\n * Add bidirectional edge between the SDK's native placeholder coin and WETH, when the chain uses\n * wrapped native in pools (mirrors the Curve dialog graph).\n */\nexport function addNativeWethBridge(adj: Map<string, Set<string>>, wrappedNative: string | undefined) {\n if (!wrappedNative) return\n const w = wrappedNative.toLowerCase()\n const a = ETH_PLACEHOLDER\n const b = w\n if (a === b) return\n if (!adj.has(a)) adj.set(a, new Set())\n if (!adj.has(b)) adj.set(b, new Set())\n adj.get(a)!.add(b)\n adj.get(b)!.add(a)\n}\n\n/** True when the token key appears in the graph with at least one swap neighbor. */\nexport function isCurveTokenKeySwappable(\n swappableNodeKeys: ReadonlySet<string>,\n graphTokenKey: string,\n): boolean {\n return swappableNodeKeys.has(graphTokenKey)\n}\n\n/**\n * All token keys in `adj` that have at least one pool neighbor (candidates to start a path from).\n */\nexport function swappableCurveGraphNodeKeys(adj: Map<string, Set<string>>): Set<string> {\n const out = new Set<string>()\n for (const [k, neigh] of adj) {\n if (neigh.size > 0) out.add(k)\n }\n return out\n}\n\n/**\n * All tokens in the same connected component as `start` (excluding `start`), for router discovery.\n */\nexport function bfsCurveSwapDestinations(adj: Map<string, Set<string>>, start: string): Set<string> {\n const s = normalizeAddr(start)\n const visited = new Set<string>([s])\n const q: string[] = [s]\n while (q.length) {\n const n = q.shift()!\n for (const nxt of adj.get(n) ?? []) {\n if (!visited.has(nxt)) {\n visited.add(nxt)\n q.push(nxt)\n }\n }\n }\n visited.delete(s)\n return visited\n}\n\nexport type CurveDestToken = {\n address: string\n symbol: string\n name: string\n /** From Curve `getCoinsData` (on-chain), when available. */\n decimals: number | null\n}\n","import {\n addNativeWethBridge,\n buildCurveLiquidityGraphFromApi,\n swappableCurveGraphNodeKeys,\n} from './swapDestinations.js'\n\nconst CURVE_SESSION_CACHE_TTL_MS = 5 * 60 * 1000\nconst curveSessionCache = new Map<string, { session: CurveFullSession; expiresAt: number }>()\n\n/** Live `@curvefi/api` instance with pools already fetched, plus the routing graph. */\nexport type CurveFullSession = {\n /** Same reference used for getCoinsData / router; pools already loaded. */\n curve: any\n adj: Map<string, Set<string>>\n swappableNodeKeys: ReadonlySet<string>\n wrappedNative: string | undefined\n}\n\n/**\n * Fetches all factory pools in parallel (best-effort; failures are ignored per factory,\n * same as the Curve dialog).\n */\nexport async function fetchAllCurvePools(curve: {\n factory?: { fetchPools: () => Promise<unknown> }\n crvUSDFactory?: { fetchPools: () => Promise<unknown> }\n EYWAFactory?: { fetchPools: () => Promise<unknown> }\n cryptoFactory?: { fetchPools: () => Promise<unknown> }\n twocryptoFactory?: { fetchPools: () => Promise<unknown> }\n tricryptoFactory?: { fetchPools: () => Promise<unknown> }\n stableNgFactory?: { fetchPools: () => Promise<unknown> }\n}): Promise<void> {\n const run = (p: Promise<unknown>) => p.catch(() => undefined)\n const tasks: Promise<unknown>[] = []\n for (const key of [\n 'factory',\n 'crvUSDFactory',\n 'EYWAFactory',\n 'cryptoFactory',\n 'twocryptoFactory',\n 'tricryptoFactory',\n 'stableNgFactory',\n ] as const) {\n const f = curve[key]\n if (f?.fetchPools) {\n tasks.push(run(f.fetchPools()))\n }\n }\n await Promise.all(tasks)\n}\n\n/**\n * One init + `fetchAllCurvePools` + graph build. Reuse this session for the asset list and the\n * Curve dialog to avoid duplicating the Curve API work.\n */\nexport async function loadFullCurveSessionForRpc(rpcUrl: string): Promise<CurveFullSession> {\n const url = (rpcUrl ?? '').trim()\n if (!url) {\n throw new Error('rpcUrl is required.')\n }\n const cached = curveSessionCache.get(url)\n if (cached && cached.expiresAt > Date.now()) {\n return cached.session\n }\n try {\n const { default: curve } = await import('@curvefi/api')\n await curve.init('JsonRpc', { url }, {})\n const wrapped = (curve.getNetworkConstants() as { NATIVE_COIN?: { wrappedAddress?: string } })\n .NATIVE_COIN?.wrappedAddress\n if (!curve.hasRouter || !curve.hasRouter()) {\n const session: CurveFullSession = {\n curve,\n adj: new Map(),\n swappableNodeKeys: new Set<string>(),\n wrappedNative: wrapped,\n }\n curveSessionCache.set(url, { session, expiresAt: Date.now() + CURVE_SESSION_CACHE_TTL_MS })\n return session\n }\n await fetchAllCurvePools(curve)\n const adj = buildCurveLiquidityGraphFromApi(curve)\n addNativeWethBridge(adj, wrapped)\n const session: CurveFullSession = {\n curve,\n adj,\n swappableNodeKeys: swappableCurveGraphNodeKeys(adj),\n wrappedNative: wrapped,\n }\n curveSessionCache.set(url, { session, expiresAt: Date.now() + CURVE_SESSION_CACHE_TTL_MS })\n return session\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e)\n throw new Error(`Curve session init failed for RPC: ${msg}`)\n }\n}\n\nexport type CurveSessionSnapshot = {\n wrappedNative: string | undefined\n swappableNodeKeys: string[]\n routerReady: boolean\n adj: Record<string, string[]>\n}\n\n/** JSON-safe Curve session for browser clients (via Next.js API route). */\nexport async function loadCurveSessionSnapshotForRpc(\n rpcUrl: string,\n): Promise<CurveSessionSnapshot> {\n const session = await loadFullCurveSessionForRpc(rpcUrl)\n if (!session) {\n throw new Error('Failed to load Curve session for this RPC.')\n }\n const adjMap = session.adj\n if (!adjMap) {\n throw new Error('Curve session has no pool graph for this RPC.')\n }\n const adj: Record<string, string[]> = {}\n for (const [key, neighbors] of adjMap) {\n adj[key] = [...neighbors]\n }\n return {\n wrappedNative: session.wrappedNative,\n swappableNodeKeys: [...session.swappableNodeKeys],\n routerReady: Boolean(session.curve?.hasRouter?.() && session.curve.hasRouter()),\n adj,\n }\n}\n\nexport type CurveCoinDataRow = {\n address: string\n name?: string\n symbol?: string\n decimals?: number | null\n}\n\n/** On-chain token metadata via `@curvefi/api` `getCoinsData` (server-side). */\nexport async function fetchCurveCoinsDataForRpc(\n rpcUrl: string,\n addresses: string[],\n): Promise<CurveCoinDataRow[]> {\n const session = await loadFullCurveSessionForRpc(rpcUrl)\n if (!session.curve?.getCoinsData) {\n throw new Error('Curve getCoinsData is not available for this RPC session.')\n }\n const coins = await session.curve.getCoinsData(addresses)\n return addresses.map((addr, i) => {\n const c = coins[i] as { name?: string; symbol?: string; decimals?: number } | undefined\n const dec = c?.decimals\n const decimals =\n typeof dec === 'number' && Number.isInteger(dec) && dec >= 0 && dec <= 18 ? dec : null\n return {\n address: addr,\n name: (c?.name && String(c.name).trim()) || '—',\n symbol: (c?.symbol && String(c.symbol).trim()) || addr.slice(0, 6),\n decimals,\n }\n })\n}\n\n","import type { ProposalTxParams } from '@continuumdao/continuum-node-sdk'\nexport type { ProposalTxParams }\n\nfunction parseOptionalGasLimitString(raw: string | number | undefined): bigint | null {\n if (raw == null) return null\n const s = String(raw).trim()\n if (!s) return null\n try {\n if (/^0x[0-9a-fA-F]+$/.test(s)) return BigInt(s)\n return BigInt(s)\n } catch {\n return null\n }\n}\n\nfunction parseExtraJsonObject(detail: Record<string, unknown> | null | undefined): Record<string, unknown> | null {\n if (!detail) return null\n const raw = detail.ExtraJSON ?? detail.extraJSON\n if (raw == null) return null\n if (typeof raw === 'object' && !Array.isArray(raw)) return raw as Record<string, unknown>\n if (typeof raw === 'string' && raw.trim()) {\n try {\n const p = JSON.parse(raw) as unknown\n if (p && typeof p === 'object' && !Array.isArray(p)) return p as Record<string, unknown>\n } catch {\n return null\n }\n }\n return null\n}\n\nexport const CURVE_ROUTER_EXCHANGE_DEFAULT_GAS_UNITS = 1_200_000n\n\nexport function isCurveDaoSwapEvmSignRequest(\n detail: Record<string, unknown> | null | undefined,\n batchIndex?: number,\n): boolean {\n const ex = parseExtraJsonObject(detail)\n if (batchIndex != null && batchIndex >= 0 && ex) {\n const bm = ex.batchMeta\n if (Array.isArray(bm) && bm[batchIndex] && typeof bm[batchIndex] === 'object' && !Array.isArray(bm[batchIndex])) {\n const evm0 = (bm[batchIndex] as Record<string, unknown>).evm\n if (evm0 && typeof evm0 === 'object' && !Array.isArray(evm0)) {\n if (String((evm0 as Record<string, unknown>).type ?? '') === 'curve_dao_router_exchange') return true\n }\n }\n }\n const evm = ex?.evm\n if (!evm || typeof evm !== 'object' || Array.isArray(evm)) return false\n return String((evm as Record<string, unknown>).type ?? '') === 'curve_dao_router_exchange'\n}\n\nexport function isCurveDaoErc20ApproveEvmSignRequest(\n detail: Record<string, unknown> | null | undefined,\n batchIndex?: number,\n): boolean {\n const ex = parseExtraJsonObject(detail)\n const index = batchIndex != null && batchIndex >= 0 ? batchIndex : 0\n const bm = ex?.batchMeta\n if (Array.isArray(bm) && bm[index] && typeof bm[index] === 'object' && !Array.isArray(bm[index])) {\n const evm0 = (bm[index] as Record<string, unknown>).evm\n if (evm0 && typeof evm0 === 'object' && !Array.isArray(evm0)) {\n const t = String((evm0 as Record<string, unknown>).type ?? '')\n return t === 'curve_dao_erc20_approve'\n }\n }\n return false\n}\n\nexport function resolveCurveDaoRouterGasUnitsFromSignRequest(\n detail: Record<string, unknown> | null | undefined,\n batchIndex?: number,\n): bigint | null {\n if (!detail) return null\n const propBatch = (detail.proposal_tx_params ??\n detail.proposalTxParams ??\n detail.ProposalTxParams) as unknown\n const index = batchIndex != null && batchIndex >= 0 ? batchIndex : 0\n if (Array.isArray(propBatch) && propBatch.length > index) {\n const row = propBatch[index]\n if (row && typeof row === 'object' && !Array.isArray(row)) {\n const r = row as Record<string, unknown>\n const gl = parseOptionalGasLimitString(\n (r.gas_limit ?? r.gasLimit ?? r.GasLimit) as string | number | undefined,\n )\n if (gl != null && gl > 0n) return gl\n }\n }\n const ex = parseExtraJsonObject(detail)\n const bm = ex?.batchMeta\n if (Array.isArray(bm)) {\n for (const item of bm) {\n if (!item || typeof item !== 'object' || Array.isArray(item)) continue\n const cd = (item as Record<string, unknown>).curveDao as Record<string, unknown> | undefined\n const gb = cd?.gasBuildExchange as Record<string, unknown> | undefined\n const base = parseOptionalGasLimitString(gb?.baseGasUnits as string | number | undefined)\n if (base != null && base > 0n) return base\n }\n }\n return null\n}\n","import {\n type Address,\n createPublicClient,\n defineChain,\n encodeFunctionData,\n getAddress,\n http,\n parseAbi,\n parseUnits,\n} from 'viem'\nimport type { KeyGenSubsetForPermit } from '../../../core/types.js'\nimport type { EvmChainDetail, EvmTxStep } from '../../../chains/evm/types.js'\nimport { buildEvmMultisignBatch } from '../../../chains/evm/buildBatch.js'\nimport { loadFullCurveSessionForRpc } from './apiSession.js'\nimport { toCurveRouterTokenId } from './swapDestinations.js'\nimport { CURVE_ROUTER_EXCHANGE_DEFAULT_GAS_UNITS } from './executeHelpers.js'\nimport { routerSwapGasLimitFromEstimate } from '../../../chains/evm/routerSwapGas.js'\n\nconst ETH_PLACEHOLDER = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' as const\n\ntype CurveStepKind = 'approve' | 'exchange'\ntype CurveStep = EvmTxStep & { kind: CurveStepKind; routerSwap?: boolean; fallbackGas?: bigint }\n\nfunction txToViemStep(tx: {\n to?: string | null\n data?: string | null\n value?: string | bigint | number | null\n}): { to: Address; data: `0x${string}`; value: bigint } {\n if (!tx.to) throw new Error('Transaction missing `to`')\n const to = getAddress((tx.to ?? '').trim() as `0x${string}`)\n const raw = (tx.data ?? '0x').toString()\n const data = (raw.startsWith('0x') ? raw : `0x${raw}`) as `0x${string}`\n let value = 0n\n if (tx.value != null) {\n if (typeof tx.value === 'bigint') value = tx.value\n else value = BigInt(String(tx.value))\n }\n return { to, data, value }\n}\n\n/**\n * Build `POST /multiSignRequest` body: optional ERC-20 approve(s) to the Curve router, then\n * `CurveRouterNG.exchange` via `@curvefi/api` `router.populateSwap`.\n */\nexport async function buildEvmMultisignBodyCurveDaoBatch(args: {\n keyGen: KeyGenSubsetForPermit\n chainId: number\n rpcUrl: string\n chainDetail: EvmChainDetail\n useCustomGas: boolean\n customGasChainDetails?: Record<string, unknown> | null\n tokenIn: Address\n tokenOut: string\n amountHuman: string\n slippagePercent: number\n executorAddress: Address\n purposeText: string\n}) {\n const tokenIn = getAddress(args.tokenIn)\n const executor = getAddress(args.executorAddress)\n\n const session = await loadFullCurveSessionForRpc(args.rpcUrl)\n if (!session?.curve?.router?.populateSwap) {\n throw new Error('Curve router is not available (load session failed or chain has no router).')\n }\n const { curve, wrappedNative } = session\n const wn = wrappedNative as string | undefined\n const tokenInId = toCurveRouterTokenId(tokenIn, wn)\n const outTrim = (args.tokenOut ?? '').trim()\n const tokenOutId = toCurveRouterTokenId(\n outTrim.toLowerCase() === ETH_PLACEHOLDER ? ETH_PLACEHOLDER : getAddress(outTrim),\n wn,\n )\n const isNativeIn = tokenInId.toLowerCase() === ETH_PLACEHOLDER\n const slip = args.slippagePercent\n if (!Number.isFinite(slip) || slip <= 0 || slip >= 100) {\n throw new Error('Slippage must be between 0 and 100 (exclusive).')\n }\n\n const swapPop = await curve.router.populateSwap(tokenInId, tokenOutId, args.amountHuman, slip)\n const swapBase = txToViemStep(swapPop as Parameters<typeof txToViemStep>[0])\n const rawTo = (swapPop as { to?: string | null })?.to\n if (rawTo == null || String(rawTo).trim() === '') {\n throw new Error('Curve populateSwap did not return a destination address (router).')\n }\n const routerAddr = getAddress(String(rawTo).trim() as `0x${string}`)\n\n const ch = defineChain({\n id: args.chainId,\n name: 'Destination',\n nativeCurrency: { decimals: 18, name: 'Ether', symbol: 'ETH' },\n rpcUrls: { default: { http: [args.rpcUrl] } },\n })\n const publicClient = createPublicClient({ chain: ch, transport: http(args.rpcUrl) })\n\n const erc20AllowanceAbi = parseAbi([\n 'function allowance(address owner, address spender) view returns (uint256)',\n 'function decimals() view returns (uint8)',\n ])\n const erc20ApproveAbi = parseAbi(['function approve(address spender, uint256 amount) returns (bool)'])\n\n const steps: CurveStep[] = []\n\n if (!isNativeIn) {\n const decimalsN = await publicClient.readContract({\n address: tokenIn,\n abi: erc20AllowanceAbi,\n functionName: 'decimals',\n })\n const amountWei = parseUnits(args.amountHuman, Number(decimalsN))\n const currentAllowance = await publicClient.readContract({\n address: tokenIn,\n abi: erc20AllowanceAbi,\n functionName: 'allowance',\n args: [executor, routerAddr],\n })\n if (currentAllowance < amountWei) {\n if (currentAllowance > 0n) {\n const dataReset = encodeFunctionData({\n abi: erc20ApproveAbi,\n functionName: 'approve',\n args: [routerAddr, 0n],\n })\n steps.push({ to: tokenIn, data: dataReset, value: 0n, kind: 'approve', fallbackGas: 80_000n })\n }\n const dataApprove = encodeFunctionData({\n abi: erc20ApproveAbi,\n functionName: 'approve',\n args: [routerAddr, amountWei],\n })\n steps.push({ to: tokenIn, data: dataApprove, value: 0n, kind: 'approve', fallbackGas: 80_000n })\n }\n }\n\n steps.push({\n ...swapBase,\n kind: 'exchange',\n routerSwap: true,\n fallbackGas: CURVE_ROUTER_EXCHANGE_DEFAULT_GAS_UNITS,\n })\n\n const chainGasLimitRouter =\n args.chainDetail?.gasLimit != null &&\n Number.isFinite(Number(args.chainDetail.gasLimit)) &&\n Number(args.chainDetail.gasLimit) > 0\n ? Number(args.chainDetail.gasLimit)\n : undefined\n\n const gasLimitByIndex = new Map<number, bigint>()\n const n = steps.length\n const purposeSuffix =\n n === 1\n ? 'Curve (DAO): 1-tx — CurveRouterNG.exchange (native in or allowance already set).'\n : `Curve (DAO): ${n}-tx batch — ERC-20 approve Curve router, then CurveRouterNG.exchange.`\n\n const firstDataNo0x = steps[0]!.data.startsWith('0x') ? steps[0]!.data.slice(2) : steps[0]!.data\n const payableValueWei = steps.filter((s) => s.kind === 'exchange').reduce((a, s) => a + s.value, 0n)\n\n return buildEvmMultisignBatch({\n context: {\n chainCategory: 'evm',\n keyGen: args.keyGen,\n purposeText: args.purposeText,\n chainId: args.chainId,\n rpcUrl: args.rpcUrl,\n executorAddress: executor,\n chainDetail: args.chainDetail,\n useCustomGas: args.useCustomGas,\n customGasChainDetails: args.customGasChainDetails,\n },\n steps,\n purposeSuffix,\n firstMsgRawNo0x: firstDataNo0x,\n destinationAddress: steps[0]!.to,\n payableValueWei: payableValueWei > 0n ? payableValueWei : undefined,\n resolveGasLimit: async ({ step, index, estimatedGas }) => {\n const s = step as CurveStep\n let gasLimitI: bigint\n if (s.kind === 'exchange') {\n gasLimitI = routerSwapGasLimitFromEstimate(estimatedGas, chainGasLimitRouter)\n } else {\n gasLimitI = estimatedGas\n }\n gasLimitByIndex.set(index, gasLimitI)\n return gasLimitI\n },\n buildBatchMeta: ({ step, index, gasLimit }) => {\n const s = step as CurveStep\n const gl = gasLimitByIndex.get(index) ?? gasLimit\n if (s.kind === 'approve') {\n return {\n signatureText: JSON.stringify({\n kind: 'CurveDao',\n name: 'ERC20.approve',\n to: 'Curve router',\n function: 'approve(address spender, uint256 amount)',\n spender: routerAddr,\n amountHuman: args.amountHuman,\n note: 'Allowance approved for this swap amount only (not unlimited).',\n }),\n evm: { type: 'curve_dao_erc20_approve', version: 1, chainId: String(args.chainId) },\n }\n }\n return {\n signatureText: JSON.stringify({\n kind: 'CurveDao',\n name: 'CurveRouterNG.exchange',\n note: 'Calldata from @curvefi/api `router.populateSwap` (same on-chain as router `exchange`).',\n }),\n evm: { type: 'curve_dao_router_exchange', version: 1, chainId: String(args.chainId) },\n curveDao: {\n slippagePercent: slip,\n amountHuman: args.amountHuman,\n tokenIn: tokenInId,\n tokenOut: tokenOutId,\n isNativeIn,\n gasBuildExchange: { baseGasUnits: gl.toString() },\n },\n }\n },\n })\n}\n","import type { ProtocolModule } from '../../../core/types.js'\nimport { registerProtocolModule } from '../../../core/registry.js'\nimport { isCurveApiChainSupported } from './support.js'\n\nexport * from './support.js'\nexport * from './swapDestinations.js'\nexport * from './apiSession.js'\nexport * from './purpose.js'\nexport * from './executeHelpers.js'\nexport * from './multisign.js'\nexport * from './quote.js'\nexport * from './quoteDisplay.js'\n\nexport const CURVE_DAO_PROTOCOL_ID = 'curve-dao'\n\nexport const curveDaoProtocolModule: ProtocolModule = {\n id: CURVE_DAO_PROTOCOL_ID,\n chainCategory: 'evm',\n isChainSupported(ctx) {\n if (ctx.chainCategory !== 'evm') return false\n return isCurveApiChainSupported(ctx.chainId)\n },\n isTokenSupported(token) {\n if (token.category !== 'evm') return false\n return token.kind === 'native' || token.kind === 'erc20'\n },\n actions: [\n {\n id: 'curve-dao.quote',\n protocolId: CURVE_DAO_PROTOCOL_ID,\n chainCategory: 'evm',\n description: 'Quote swap via Curve Router NG (getBestRouteAndOutput)',\n commonParams: [],\n params: {\n chainId: { type: 'number', required: true, description: 'EVM chain id' },\n tokenIn: { type: 'address', required: true, description: 'Token in or native placeholder' },\n tokenOut: { type: 'address', required: true, description: 'Token out or native placeholder' },\n amountHuman: { type: 'string', required: true, description: 'Human-readable input amount' },\n },\n },\n {\n id: 'curve-dao.swap',\n protocolId: CURVE_DAO_PROTOCOL_ID,\n chainCategory: 'evm',\n description: 'Swap via Curve Router NG (optional ERC-20 approve batch)',\n commonParams: ['keyGen', 'purposeText', 'useCustomGas'],\n params: {\n tokenIn: { type: 'address', required: true, description: 'ERC-20 token in (native uses WETH path in UI)' },\n tokenOut: { type: 'address', required: true, description: 'Output token or 0xeeee… native placeholder' },\n amountHuman: { type: 'string', required: true, description: 'Human-readable input amount' },\n slippagePercent: { type: 'number', required: true, description: 'Slippage percent (0–100 exclusive)' },\n },\n },\n ],\n}\n\nregisterProtocolModule(curveDaoProtocolModule)\n\nimport { buildEvmMultisignBodyCurveDaoBatch } from './multisign.js'\nimport { loadFullCurveSessionForRpc } from './apiSession.js'\n\nexport const curveDao = {\n buildSwapMultisignBody: buildEvmMultisignBodyCurveDaoBatch,\n isChainSupported: isCurveApiChainSupported,\n loadSession: loadFullCurveSessionForRpc,\n}\n","export * from './core/index.js'\nexport * from './chains/evm/index.js'\nexport { solanaChainCategoryModule, SOLANA_CHAIN_CATEGORY } from './chains/solana/index.js'\nexport { nearChainCategoryModule, NEAR_CHAIN_CATEGORY } from './chains/near/index.js'\nexport { uniswapV4ProtocolModule, uniswapV4 } from './protocols/evm/uniswap-v4/index.js'\nexport { curveDaoProtocolModule, curveDao } from './protocols/evm/curve-dao/index.js'\nimport { registerProtocolModule } from './core/registry.js'\nimport { uniswapV4ProtocolModule } from './protocols/evm/uniswap-v4/index.js'\nimport { curveDaoProtocolModule } from './protocols/evm/curve-dao/index.js'\n\nregisterProtocolModule(uniswapV4ProtocolModule)\nregisterProtocolModule(curveDaoProtocolModule)\n"]}
|