@continuumdao/ctm-mpc-defi 0.2.40 → 0.2.41
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 +38 -5
- package/dist/agent/catalog.cjs.map +1 -1
- package/dist/agent/catalog.js +38 -5
- package/dist/agent/catalog.js.map +1 -1
- package/dist/agent/skills/aave-v4/SKILL.md +1 -1
- package/dist/agent/skills/circle-cctp/SKILL.md +1 -0
- package/dist/agent/skills/morpho/SKILL.md +11 -0
- package/dist/agent/skills/uniswap-v4/SKILL.md +1 -1
- package/dist/chains/evm/index.cjs +1 -0
- package/dist/chains/evm/index.cjs.map +1 -1
- package/dist/chains/evm/index.js +1 -0
- package/dist/chains/evm/index.js.map +1 -1
- package/dist/index.cjs +7 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/protocols/evm/circle-cctp/index.cjs +16 -0
- package/dist/protocols/evm/circle-cctp/index.cjs.map +1 -1
- package/dist/protocols/evm/circle-cctp/index.js +16 -0
- package/dist/protocols/evm/circle-cctp/index.js.map +1 -1
- package/dist/protocols/evm/euler-v2/index.cjs +1 -0
- package/dist/protocols/evm/euler-v2/index.cjs.map +1 -1
- package/dist/protocols/evm/euler-v2/index.js +1 -0
- package/dist/protocols/evm/euler-v2/index.js.map +1 -1
- package/dist/protocols/evm/morpho/index.cjs +21 -2
- package/dist/protocols/evm/morpho/index.cjs.map +1 -1
- package/dist/protocols/evm/morpho/index.d.ts +12 -1
- package/dist/protocols/evm/morpho/index.js +17 -3
- package/dist/protocols/evm/morpho/index.js.map +1 -1
- package/dist/protocols/evm/permit2/index.cjs.map +1 -1
- package/dist/protocols/evm/permit2/index.js.map +1 -1
- package/dist/protocols/evm/uniswap-v4/index.cjs +6 -2
- package/dist/protocols/evm/uniswap-v4/index.cjs.map +1 -1
- package/dist/protocols/evm/uniswap-v4/index.js +6 -2
- package/dist/protocols/evm/uniswap-v4/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/core/purpose.ts","../../../../src/core/envelope.ts","../../../../src/core/eip712Multisign.ts","../../../../src/protocols/evm/uniswap-v4/constants.ts","../../../../src/protocols/evm/permit2/permitSingle.ts"],"names":["getClientIdFromKeyGenResult","stringToHex","hashTypedData","getAddress"],"mappings":"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","file":"index.cjs","sourcesContent":["/** Merge user purpose text with an optional batch / protocol suffix. */\nexport function mergePurposeText(purposeText: string | undefined, 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 /** Unix seconds (UTC) for mpc-auth multiSignRequest expiryDate. */\n expiryDate?: number\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, (_, v) => (typeof v === 'bigint' ? v.toString() : v))\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 if (input.expiryDate != null && input.expiryDate > 0) {\n bodyForSign.expiryDate = Math.floor(input.expiryDate)\n }\n\n return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) }\n}\n\nexport const coreChainCategoryModule: ChainCategoryModule = {\n category: 'evm',\n finalizeMultisign,\n}\n","import { hashTypedData, stringToHex, type TypedDataDomain } from 'viem'\nimport type { KeyGenSubset, MultisignBuildResult } from './types.js'\nimport { finalizeMultisign } from './envelope.js'\n\nexport const EIP712_SIGN_REQUEST_KIND = 'eip712' as const\n\nexport type Eip712TypedDataField = { name: string; type: string }\n\nexport type Eip712TypedDataPayload = {\n domain: TypedDataDomain\n types: Record<string, readonly Eip712TypedDataField[] | Eip712TypedDataField[]>\n primaryType: string\n message: Record<string, unknown>\n}\n\nexport type Eip712MultisignDelivery = Record<string, unknown> & { kind: string }\n\nexport type BuildEip712MultisignLeg = {\n typedData: Eip712TypedDataPayload\n delivery: Eip712MultisignDelivery\n audit?: Record<string, unknown>\n}\n\nexport type BuildEip712MultisignArgs = {\n keyGen: KeyGenSubset\n purposeText: string\n purposeSuffix?: string\n /** Chain id stored on the sign request (protocol context; may differ from EIP-712 domain chainId). */\n destinationChainID: string\n destinationAddress: string\n legs: readonly BuildEip712MultisignLeg[]\n expiryDate?: number\n}\n\nfunction msgHashNo0x(digest: `0x${string}`): string {\n return digest.startsWith('0x') ? digest.slice(2) : digest\n}\n\nfunction eip712SignatureText(domain: TypedDataDomain, primaryType: string): string {\n return JSON.stringify({\n kind: 'EIP-712',\n ...(typeof domain.name === 'string' ? { name: domain.name } : {}),\n primaryType,\n })\n}\n\nfunction jsonStringifyForAudit(value: unknown): string {\n return JSON.stringify(value, (_, v) => (typeof v === 'bigint' ? v.toString() : v))\n}\n\nfunction eip712LegEnvelope(\n typedData: Eip712TypedDataPayload,\n delivery: Eip712MultisignDelivery,\n digest: `0x${string}`,\n): Record<string, unknown> {\n return {\n version: 1,\n digest,\n domain: typedData.domain,\n types: typedData.types,\n primaryType: typedData.primaryType,\n message: typedData.message,\n delivery,\n }\n}\n\nfunction eip712MsgRawHex(envelope: Record<string, unknown>): string {\n return stringToHex(jsonStringifyForAudit(envelope))\n}\n\n/**\n * Build an mpc-auth multiSignRequest body for one or more EIP-712 digests (no EVM tx broadcast).\n * `extraJSON.eip712` is always an array. N=1 uses `msgHash`/`msgRaw`; N>=2 uses `messageHashes`/`messageRawBatch`.\n */\nexport function buildEip712Multisign(args: BuildEip712MultisignArgs): MultisignBuildResult {\n if (args.legs.length < 1) {\n throw new Error('buildEip712Multisign requires at least one leg')\n }\n\n const eip712: Record<string, unknown>[] = []\n const legs = args.legs.map((leg) => {\n const digest = hashTypedData({\n domain: leg.typedData.domain,\n types: leg.typedData.types,\n primaryType: leg.typedData.primaryType,\n message: leg.typedData.message,\n })\n const envelope = eip712LegEnvelope(leg.typedData, leg.delivery, digest)\n eip712.push(envelope)\n return {\n msgHash: msgHashNo0x(digest),\n msgRaw: eip712MsgRawHex(envelope),\n destinationAddress: args.destinationAddress,\n signatureText: eip712SignatureText(leg.typedData.domain, leg.typedData.primaryType),\n audit: {\n kind: 'EIP712',\n primaryType: leg.typedData.primaryType,\n deliveryKind: leg.delivery.kind,\n ...(leg.audit ?? {}),\n },\n feeSnapshot: {},\n }\n })\n\n return finalizeMultisign({\n keyGen: args.keyGen,\n purposeText: args.purposeText,\n purposeSuffix: args.purposeSuffix,\n destinationChainID: args.destinationChainID,\n destinationAddress: args.destinationAddress,\n extraJSON: {\n signRequestKind: EIP712_SIGN_REQUEST_KIND,\n eip712,\n },\n expiryDate: args.expiryDate,\n legs,\n })\n}\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\n/** Standard Universal Router spenders (Trade API default 2.0 / chain-specific). */\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 /** Robinhood Chain mainnet — Universal Router v2.1.1 (Trade API / interface) */\n 4663: '0x8876789976decbfcbbbe364623c63652db8c0904',\n}\n\n/**\n * Universal Router 2.2.0 — required for permissioned / tokenized pool swaps\n * (PermissionedV4Router wrap/unwrap). Source: @uniswap/universal-router-sdk + Uniswap docs.\n */\nconst UNIVERSAL_ROUTER_V2_2_SPENDER: Partial<Record<number, string>> = {\n 1: '0xCb640A86855f1A828c27241bA364348de28abe66',\n 11155111: '0xB0C89059d7190EDb17eFF19829cc009cEe923916',\n}\n\n/** Per-chain Universal Router version for Trade API `x-universal-router-version`. */\nconst UNIVERSAL_ROUTER_VERSION_BY_CHAIN: Partial<Record<number, string>> = {\n /** Robinhood has UR 2.1.1 only in the supported-chains table (no 2.0 Trade API column). */\n 4663: '2.1.1',\n}\n\nexport const UNISWAP_UNIVERSAL_ROUTER_VERSION_DEFAULT = '2.0'\n/** Trade API header value required when any token in the trade is permissioned. */\nexport const UNISWAP_UNIVERSAL_ROUTER_VERSION_PERMISSIONED = '2.2.0'\n\nexport type UniswapUniversalRouterOpts = {\n /** When true, prefer UR 2.2.0 spender/version (permissioned pools). */\n permissioned?: boolean\n}\n\nexport function getUniswapUniversalRouterVersion(\n chainId: number,\n opts?: UniswapUniversalRouterOpts,\n): string {\n if (opts?.permissioned) {\n const v22 = UNIVERSAL_ROUTER_V2_2_SPENDER[chainId]\n if (typeof v22 === 'string' && v22.startsWith('0x')) {\n return UNISWAP_UNIVERSAL_ROUTER_VERSION_PERMISSIONED\n }\n }\n const v = UNIVERSAL_ROUTER_VERSION_BY_CHAIN[chainId]\n return typeof v === 'string' && v.trim() ? v.trim() : UNISWAP_UNIVERSAL_ROUTER_VERSION_DEFAULT\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(\n chainId: number,\n opts?: UniswapUniversalRouterOpts,\n): Address {\n if (opts?.permissioned) {\n const raw22 = UNIVERSAL_ROUTER_V2_2_SPENDER[chainId]\n if (raw22 && raw22.startsWith('0x')) return getAddress(raw22)\n }\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 function tryGetUniswapUniversalRouterV22(chainId: number): Address | null {\n const raw = UNIVERSAL_ROUTER_V2_2_SPENDER[chainId]\n if (!raw || !raw.startsWith('0x')) return null\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_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 /** Robinhood Chain mainnet */\n 4663: '0x58daec3116aae6D93017bAAea7749052E8a04fA7',\n}\n\n/** Permissioned Position Manager (UNI-V4-PERM-POSM) — non-transferable LP NFTs. */\nconst PERMISSIONED_POSITION_MANAGER_BY_CHAIN: Partial<Record<number, string>> = {\n 1: '0x89628C9B4CE81951a9BC1F36F0688Fad6A6ee248',\n 11155111: '0x68fC145BB20b388965bED184Df5ef912215bb3C7',\n}\n\n/** Shared PermissionedHooks address for pool keys. */\nconst PERMISSIONED_HOOKS_BY_CHAIN: Partial<Record<number, string>> = {\n 1: '0x69603ab16110Eb0bB5f5E9C8019749eE41A128C0',\n 11155111: '0x8B0E8d467af81D9F5B49165e104a2fe1b98328C0',\n}\n\n/** PermissionsAdapterFactory — maps adapters ↔ underlying permissioned tokens. */\nconst PERMISSIONS_ADAPTER_FACTORY_BY_CHAIN: Partial<Record<number, string>> = {\n 1: '0x38f9Ab57FBE2704EbB727cB20e33201aF0E5F961',\n 11155111: '0xEe258C31574fb59660C23534E76AF6497c2e5683',\n}\n\n/** Robinhood Chain wrapped native (WETH). */\nexport const ROBINHOOD_CHAIN_ID = 4663\nexport const ROBINHOOD_WETH_ADDRESS = '0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73' as const\n\nexport type UniswapV4PositionManagerKind = 'standard' | 'permissioned'\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\nexport function getUniswapV4PermissionedPositionManagerOrThrow(chainId: number): Address {\n const raw = PERMISSIONED_POSITION_MANAGER_BY_CHAIN[chainId]\n if (!raw || !raw.startsWith('0x') || raw.length !== 42) {\n throw new Error(\n `No Uniswap V4 Permissioned PositionManager is configured for chainId ${chainId}.`,\n )\n }\n return getAddress(raw)\n}\n\nexport function tryGetUniswapV4PermissionedPositionManager(chainId: number): Address | null {\n try {\n return getUniswapV4PermissionedPositionManagerOrThrow(chainId)\n } catch {\n return null\n }\n}\n\nexport function getUniswapV4PermissionedHooksOrThrow(chainId: number): Address {\n const raw = PERMISSIONED_HOOKS_BY_CHAIN[chainId]\n if (!raw || !raw.startsWith('0x') || raw.length !== 42) {\n throw new Error(`No Uniswap V4 PermissionedHooks is configured for chainId ${chainId}.`)\n }\n return getAddress(raw)\n}\n\nexport function tryGetUniswapV4PermissionedHooks(chainId: number): Address | null {\n try {\n return getUniswapV4PermissionedHooksOrThrow(chainId)\n } catch {\n return null\n }\n}\n\nexport function getUniswapV4PermissionsAdapterFactoryOrThrow(chainId: number): Address {\n const raw = PERMISSIONS_ADAPTER_FACTORY_BY_CHAIN[chainId]\n if (!raw || !raw.startsWith('0x') || raw.length !== 42) {\n throw new Error(\n `No Uniswap V4 PermissionsAdapterFactory is configured for chainId ${chainId}.`,\n )\n }\n return getAddress(raw)\n}\n\nexport function tryGetUniswapV4PermissionsAdapterFactory(chainId: number): Address | null {\n try {\n return getUniswapV4PermissionsAdapterFactoryOrThrow(chainId)\n } catch {\n return null\n }\n}\n\nexport function isUniswapV4PermissionedPositionManager(\n chainId: number,\n address: string | Address | null | undefined,\n): boolean {\n if (!address?.toString().trim()) return false\n const perm = tryGetUniswapV4PermissionedPositionManager(chainId)\n if (!perm) return false\n try {\n return getAddress(address as Address) === perm\n } catch {\n return false\n }\n}\n\nexport function isUniswapV4AnyPositionManager(\n chainId: number,\n address: string | Address | null | undefined,\n): boolean {\n if (!address?.toString().trim()) return false\n try {\n const a = getAddress(address as Address)\n const std = tryGetUniswapV4PositionManager(chainId)\n const perm = tryGetUniswapV4PermissionedPositionManager(chainId)\n return (std != null && a === std) || (perm != null && a === perm)\n } catch {\n return false\n }\n}\n\nexport function resolveUniswapV4PositionManager(\n chainId: number,\n kind: UniswapV4PositionManagerKind = 'standard',\n): Address {\n return kind === 'permissioned'\n ? getUniswapV4PermissionedPositionManagerOrThrow(chainId)\n : getUniswapV4PositionManagerOrThrow(chainId)\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\nexport const UNISWAP_V4_LP_PERMIT2_APPROVE_FALLBACK = 100_000n\n\n/** On-chain PermissionFlag bits (IAllowlistChecker / PermissionFlags). */\nexport const UNISWAP_V4_PERMISSION_FLAG_SWAP = 0x0001\nexport const UNISWAP_V4_PERMISSION_FLAG_LIQUIDITY = 0x0002\n","import { getAddress, type Address } from 'viem'\nimport type { KeyGenSubsetForPermit } from '../../../core/types.js'\nimport { buildEip712Multisign } from '../../../core/eip712Multisign.js'\nimport { PERMIT2_ADDRESS } from '../uniswap-v4/constants.js'\n\nexport const PERMIT_SINGLE_TYPES = {\n PermitSingle: [\n { name: 'details', type: 'PermitDetails' },\n { name: 'spender', type: 'address' },\n { name: 'sigDeadline', type: 'uint256' },\n ],\n PermitDetails: [\n { name: 'token', type: 'address' },\n { name: 'amount', type: 'uint160' },\n { name: 'expiration', type: 'uint48' },\n { name: 'nonce', type: 'uint48' },\n ],\n} as const\n\nexport type BuildPermit2PermitSingleMultisignArgs = {\n keyGen: KeyGenSubsetForPermit\n chainId: number\n purposeText: string\n owner: Address\n token: Address\n amount: bigint\n expiration: number\n nonce: number\n spender: Address\n sigDeadline: bigint\n}\n\nexport function buildPermit2PermitSingleMultisign(args: BuildPermit2PermitSingleMultisignArgs) {\n const token = getAddress(args.token)\n const spender = getAddress(args.spender)\n const owner = getAddress(args.owner)\n\n const message = {\n details: {\n token,\n amount: args.amount,\n expiration: args.expiration,\n nonce: args.nonce,\n },\n spender,\n sigDeadline: args.sigDeadline,\n }\n\n const domain = {\n name: 'Permit2',\n chainId: args.chainId,\n verifyingContract: PERMIT2_ADDRESS,\n }\n\n return buildEip712Multisign({\n keyGen: args.keyGen,\n purposeText: args.purposeText,\n destinationChainID: String(args.chainId),\n destinationAddress: PERMIT2_ADDRESS,\n legs: [\n {\n typedData: {\n domain,\n types: PERMIT_SINGLE_TYPES,\n primaryType: 'PermitSingle',\n message,\n },\n delivery: {\n kind: 'permit2_submit',\n chainId: args.chainId,\n permit2: PERMIT2_ADDRESS,\n owner,\n permitSingle: message,\n },\n audit: {\n protocol: 'permit2',\n action: 'permitSingle',\n owner,\n token,\n spender,\n },\n },\n ],\n })\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/core/purpose.ts","../../../../src/core/envelope.ts","../../../../src/core/eip712Multisign.ts","../../../../src/protocols/evm/uniswap-v4/constants.ts","../../../../src/protocols/evm/permit2/permitSingle.ts"],"names":["getClientIdFromKeyGenResult","stringToHex","hashTypedData","getAddress"],"mappings":"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","file":"index.cjs","sourcesContent":["/** Merge user purpose text with an optional batch / protocol suffix. */\nexport function mergePurposeText(purposeText: string | undefined, 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 /** Unix seconds (UTC) for mpc-auth multiSignRequest expiryDate. */\n expiryDate?: number\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, (_, v) => (typeof v === 'bigint' ? v.toString() : v))\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 if (input.expiryDate != null && input.expiryDate > 0) {\n bodyForSign.expiryDate = Math.floor(input.expiryDate)\n }\n\n return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) }\n}\n\nexport const coreChainCategoryModule: ChainCategoryModule = {\n category: 'evm',\n finalizeMultisign,\n}\n","import { hashTypedData, stringToHex, type TypedDataDomain } from 'viem'\nimport type { KeyGenSubset, MultisignBuildResult } from './types.js'\nimport { finalizeMultisign } from './envelope.js'\n\nexport const EIP712_SIGN_REQUEST_KIND = 'eip712' as const\n\nexport type Eip712TypedDataField = { name: string; type: string }\n\nexport type Eip712TypedDataPayload = {\n domain: TypedDataDomain\n types: Record<string, readonly Eip712TypedDataField[] | Eip712TypedDataField[]>\n primaryType: string\n message: Record<string, unknown>\n}\n\nexport type Eip712MultisignDelivery = Record<string, unknown> & { kind: string }\n\nexport type BuildEip712MultisignLeg = {\n typedData: Eip712TypedDataPayload\n delivery: Eip712MultisignDelivery\n audit?: Record<string, unknown>\n}\n\nexport type BuildEip712MultisignArgs = {\n keyGen: KeyGenSubset\n purposeText: string\n purposeSuffix?: string\n /** Chain id stored on the sign request (protocol context; may differ from EIP-712 domain chainId). */\n destinationChainID: string\n destinationAddress: string\n legs: readonly BuildEip712MultisignLeg[]\n expiryDate?: number\n}\n\nfunction msgHashNo0x(digest: `0x${string}`): string {\n return digest.startsWith('0x') ? digest.slice(2) : digest\n}\n\nfunction eip712SignatureText(domain: TypedDataDomain, primaryType: string): string {\n return JSON.stringify({\n kind: 'EIP-712',\n ...(typeof domain.name === 'string' ? { name: domain.name } : {}),\n primaryType,\n })\n}\n\nfunction jsonStringifyForAudit(value: unknown): string {\n return JSON.stringify(value, (_, v) => (typeof v === 'bigint' ? v.toString() : v))\n}\n\nfunction eip712LegEnvelope(\n typedData: Eip712TypedDataPayload,\n delivery: Eip712MultisignDelivery,\n digest: `0x${string}`,\n): Record<string, unknown> {\n return {\n version: 1,\n digest,\n domain: typedData.domain,\n types: typedData.types,\n primaryType: typedData.primaryType,\n message: typedData.message,\n delivery,\n }\n}\n\nfunction eip712MsgRawHex(envelope: Record<string, unknown>): string {\n return stringToHex(jsonStringifyForAudit(envelope))\n}\n\n/**\n * Build an mpc-auth multiSignRequest body for one or more EIP-712 digests (no EVM tx broadcast).\n * `extraJSON.eip712` is always an array. N=1 uses `msgHash`/`msgRaw`; N>=2 uses `messageHashes`/`messageRawBatch`.\n */\nexport function buildEip712Multisign(args: BuildEip712MultisignArgs): MultisignBuildResult {\n if (args.legs.length < 1) {\n throw new Error('buildEip712Multisign requires at least one leg')\n }\n\n const eip712: Record<string, unknown>[] = []\n const legs = args.legs.map((leg) => {\n const digest = hashTypedData({\n domain: leg.typedData.domain,\n types: leg.typedData.types,\n primaryType: leg.typedData.primaryType,\n message: leg.typedData.message,\n })\n const envelope = eip712LegEnvelope(leg.typedData, leg.delivery, digest)\n eip712.push(envelope)\n return {\n msgHash: msgHashNo0x(digest),\n msgRaw: eip712MsgRawHex(envelope),\n destinationAddress: args.destinationAddress,\n signatureText: eip712SignatureText(leg.typedData.domain, leg.typedData.primaryType),\n audit: {\n kind: 'EIP712',\n primaryType: leg.typedData.primaryType,\n deliveryKind: leg.delivery.kind,\n ...(leg.audit ?? {}),\n },\n feeSnapshot: {},\n }\n })\n\n return finalizeMultisign({\n keyGen: args.keyGen,\n purposeText: args.purposeText,\n purposeSuffix: args.purposeSuffix,\n destinationChainID: args.destinationChainID,\n destinationAddress: args.destinationAddress,\n extraJSON: {\n signRequestKind: EIP712_SIGN_REQUEST_KIND,\n eip712,\n },\n expiryDate: args.expiryDate,\n legs,\n })\n}\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\n/** Standard Universal Router spenders (Trade API default 2.0 / chain-specific). */\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 /** Robinhood Chain mainnet — Universal Router v2.1.1 (Trade API / interface) */\n 4663: '0x8876789976decbfcbbbe364623c63652db8c0904',\n /** Circle Arc mainnet — official Uniswap v4 deployments */\n 5042: '0x4fcA4a51Ab4F23A7447b3284fBd7D73289A89Fb1',\n}\n\n/**\n * Universal Router 2.2.0 — required for permissioned / tokenized pool swaps\n * (PermissionedV4Router wrap/unwrap). Source: @uniswap/universal-router-sdk + Uniswap docs.\n */\nconst UNIVERSAL_ROUTER_V2_2_SPENDER: Partial<Record<number, string>> = {\n 1: '0xCb640A86855f1A828c27241bA364348de28abe66',\n 11155111: '0xB0C89059d7190EDb17eFF19829cc009cEe923916',\n}\n\n/** Per-chain Universal Router version for Trade API `x-universal-router-version`. */\nconst UNIVERSAL_ROUTER_VERSION_BY_CHAIN: Partial<Record<number, string>> = {\n /** Robinhood has UR 2.1.1 only in the supported-chains table (no 2.0 Trade API column). */\n 4663: '2.1.1',\n}\n\nexport const UNISWAP_UNIVERSAL_ROUTER_VERSION_DEFAULT = '2.0'\n/** Trade API header value required when any token in the trade is permissioned. */\nexport const UNISWAP_UNIVERSAL_ROUTER_VERSION_PERMISSIONED = '2.2.0'\n\nexport type UniswapUniversalRouterOpts = {\n /** When true, prefer UR 2.2.0 spender/version (permissioned pools). */\n permissioned?: boolean\n}\n\nexport function getUniswapUniversalRouterVersion(\n chainId: number,\n opts?: UniswapUniversalRouterOpts,\n): string {\n if (opts?.permissioned) {\n const v22 = UNIVERSAL_ROUTER_V2_2_SPENDER[chainId]\n if (typeof v22 === 'string' && v22.startsWith('0x')) {\n return UNISWAP_UNIVERSAL_ROUTER_VERSION_PERMISSIONED\n }\n }\n const v = UNIVERSAL_ROUTER_VERSION_BY_CHAIN[chainId]\n return typeof v === 'string' && v.trim() ? v.trim() : UNISWAP_UNIVERSAL_ROUTER_VERSION_DEFAULT\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(\n chainId: number,\n opts?: UniswapUniversalRouterOpts,\n): Address {\n if (opts?.permissioned) {\n const raw22 = UNIVERSAL_ROUTER_V2_2_SPENDER[chainId]\n if (raw22 && raw22.startsWith('0x')) return getAddress(raw22)\n }\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 function tryGetUniswapUniversalRouterV22(chainId: number): Address | null {\n const raw = UNIVERSAL_ROUTER_V2_2_SPENDER[chainId]\n if (!raw || !raw.startsWith('0x')) return null\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_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 /** Robinhood Chain mainnet */\n 4663: '0x58daec3116aae6D93017bAAea7749052E8a04fA7',\n /** Circle Arc mainnet */\n 5042: '0x6049c9a0e26405C0985f9E3685C87d0aE917f82B',\n}\n\n/** Permissioned Position Manager (UNI-V4-PERM-POSM) — non-transferable LP NFTs. */\nconst PERMISSIONED_POSITION_MANAGER_BY_CHAIN: Partial<Record<number, string>> = {\n 1: '0x89628C9B4CE81951a9BC1F36F0688Fad6A6ee248',\n 11155111: '0x68fC145BB20b388965bED184Df5ef912215bb3C7',\n}\n\n/** Shared PermissionedHooks address for pool keys. */\nconst PERMISSIONED_HOOKS_BY_CHAIN: Partial<Record<number, string>> = {\n 1: '0x69603ab16110Eb0bB5f5E9C8019749eE41A128C0',\n 11155111: '0x8B0E8d467af81D9F5B49165e104a2fe1b98328C0',\n}\n\n/** PermissionsAdapterFactory — maps adapters ↔ underlying permissioned tokens. */\nconst PERMISSIONS_ADAPTER_FACTORY_BY_CHAIN: Partial<Record<number, string>> = {\n 1: '0x38f9Ab57FBE2704EbB727cB20e33201aF0E5F961',\n 11155111: '0xEe258C31574fb59660C23534E76AF6497c2e5683',\n}\n\n/** Robinhood Chain wrapped native (WETH). */\nexport const ROBINHOOD_CHAIN_ID = 4663\nexport const ROBINHOOD_WETH_ADDRESS = '0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73' as const\n\nexport type UniswapV4PositionManagerKind = 'standard' | 'permissioned'\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\nexport function getUniswapV4PermissionedPositionManagerOrThrow(chainId: number): Address {\n const raw = PERMISSIONED_POSITION_MANAGER_BY_CHAIN[chainId]\n if (!raw || !raw.startsWith('0x') || raw.length !== 42) {\n throw new Error(\n `No Uniswap V4 Permissioned PositionManager is configured for chainId ${chainId}.`,\n )\n }\n return getAddress(raw)\n}\n\nexport function tryGetUniswapV4PermissionedPositionManager(chainId: number): Address | null {\n try {\n return getUniswapV4PermissionedPositionManagerOrThrow(chainId)\n } catch {\n return null\n }\n}\n\nexport function getUniswapV4PermissionedHooksOrThrow(chainId: number): Address {\n const raw = PERMISSIONED_HOOKS_BY_CHAIN[chainId]\n if (!raw || !raw.startsWith('0x') || raw.length !== 42) {\n throw new Error(`No Uniswap V4 PermissionedHooks is configured for chainId ${chainId}.`)\n }\n return getAddress(raw)\n}\n\nexport function tryGetUniswapV4PermissionedHooks(chainId: number): Address | null {\n try {\n return getUniswapV4PermissionedHooksOrThrow(chainId)\n } catch {\n return null\n }\n}\n\nexport function getUniswapV4PermissionsAdapterFactoryOrThrow(chainId: number): Address {\n const raw = PERMISSIONS_ADAPTER_FACTORY_BY_CHAIN[chainId]\n if (!raw || !raw.startsWith('0x') || raw.length !== 42) {\n throw new Error(\n `No Uniswap V4 PermissionsAdapterFactory is configured for chainId ${chainId}.`,\n )\n }\n return getAddress(raw)\n}\n\nexport function tryGetUniswapV4PermissionsAdapterFactory(chainId: number): Address | null {\n try {\n return getUniswapV4PermissionsAdapterFactoryOrThrow(chainId)\n } catch {\n return null\n }\n}\n\nexport function isUniswapV4PermissionedPositionManager(\n chainId: number,\n address: string | Address | null | undefined,\n): boolean {\n if (!address?.toString().trim()) return false\n const perm = tryGetUniswapV4PermissionedPositionManager(chainId)\n if (!perm) return false\n try {\n return getAddress(address as Address) === perm\n } catch {\n return false\n }\n}\n\nexport function isUniswapV4AnyPositionManager(\n chainId: number,\n address: string | Address | null | undefined,\n): boolean {\n if (!address?.toString().trim()) return false\n try {\n const a = getAddress(address as Address)\n const std = tryGetUniswapV4PositionManager(chainId)\n const perm = tryGetUniswapV4PermissionedPositionManager(chainId)\n return (std != null && a === std) || (perm != null && a === perm)\n } catch {\n return false\n }\n}\n\nexport function resolveUniswapV4PositionManager(\n chainId: number,\n kind: UniswapV4PositionManagerKind = 'standard',\n): Address {\n return kind === 'permissioned'\n ? getUniswapV4PermissionedPositionManagerOrThrow(chainId)\n : getUniswapV4PositionManagerOrThrow(chainId)\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\nexport const UNISWAP_V4_LP_PERMIT2_APPROVE_FALLBACK = 100_000n\n\n/** On-chain PermissionFlag bits (IAllowlistChecker / PermissionFlags). */\nexport const UNISWAP_V4_PERMISSION_FLAG_SWAP = 0x0001\nexport const UNISWAP_V4_PERMISSION_FLAG_LIQUIDITY = 0x0002\n","import { getAddress, type Address } from 'viem'\nimport type { KeyGenSubsetForPermit } from '../../../core/types.js'\nimport { buildEip712Multisign } from '../../../core/eip712Multisign.js'\nimport { PERMIT2_ADDRESS } from '../uniswap-v4/constants.js'\n\nexport const PERMIT_SINGLE_TYPES = {\n PermitSingle: [\n { name: 'details', type: 'PermitDetails' },\n { name: 'spender', type: 'address' },\n { name: 'sigDeadline', type: 'uint256' },\n ],\n PermitDetails: [\n { name: 'token', type: 'address' },\n { name: 'amount', type: 'uint160' },\n { name: 'expiration', type: 'uint48' },\n { name: 'nonce', type: 'uint48' },\n ],\n} as const\n\nexport type BuildPermit2PermitSingleMultisignArgs = {\n keyGen: KeyGenSubsetForPermit\n chainId: number\n purposeText: string\n owner: Address\n token: Address\n amount: bigint\n expiration: number\n nonce: number\n spender: Address\n sigDeadline: bigint\n}\n\nexport function buildPermit2PermitSingleMultisign(args: BuildPermit2PermitSingleMultisignArgs) {\n const token = getAddress(args.token)\n const spender = getAddress(args.spender)\n const owner = getAddress(args.owner)\n\n const message = {\n details: {\n token,\n amount: args.amount,\n expiration: args.expiration,\n nonce: args.nonce,\n },\n spender,\n sigDeadline: args.sigDeadline,\n }\n\n const domain = {\n name: 'Permit2',\n chainId: args.chainId,\n verifyingContract: PERMIT2_ADDRESS,\n }\n\n return buildEip712Multisign({\n keyGen: args.keyGen,\n purposeText: args.purposeText,\n destinationChainID: String(args.chainId),\n destinationAddress: PERMIT2_ADDRESS,\n legs: [\n {\n typedData: {\n domain,\n types: PERMIT_SINGLE_TYPES,\n primaryType: 'PermitSingle',\n message,\n },\n delivery: {\n kind: 'permit2_submit',\n chainId: args.chainId,\n permit2: PERMIT2_ADDRESS,\n owner,\n permitSingle: message,\n },\n audit: {\n protocol: 'permit2',\n action: 'permitSingle',\n owner,\n token,\n spender,\n },\n },\n ],\n })\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/core/purpose.ts","../../../../src/core/envelope.ts","../../../../src/core/eip712Multisign.ts","../../../../src/protocols/evm/uniswap-v4/constants.ts","../../../../src/protocols/evm/permit2/permitSingle.ts"],"names":["getAddress"],"mappings":"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","file":"index.js","sourcesContent":["/** Merge user purpose text with an optional batch / protocol suffix. */\nexport function mergePurposeText(purposeText: string | undefined, 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 /** Unix seconds (UTC) for mpc-auth multiSignRequest expiryDate. */\n expiryDate?: number\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, (_, v) => (typeof v === 'bigint' ? v.toString() : v))\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 if (input.expiryDate != null && input.expiryDate > 0) {\n bodyForSign.expiryDate = Math.floor(input.expiryDate)\n }\n\n return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) }\n}\n\nexport const coreChainCategoryModule: ChainCategoryModule = {\n category: 'evm',\n finalizeMultisign,\n}\n","import { hashTypedData, stringToHex, type TypedDataDomain } from 'viem'\nimport type { KeyGenSubset, MultisignBuildResult } from './types.js'\nimport { finalizeMultisign } from './envelope.js'\n\nexport const EIP712_SIGN_REQUEST_KIND = 'eip712' as const\n\nexport type Eip712TypedDataField = { name: string; type: string }\n\nexport type Eip712TypedDataPayload = {\n domain: TypedDataDomain\n types: Record<string, readonly Eip712TypedDataField[] | Eip712TypedDataField[]>\n primaryType: string\n message: Record<string, unknown>\n}\n\nexport type Eip712MultisignDelivery = Record<string, unknown> & { kind: string }\n\nexport type BuildEip712MultisignLeg = {\n typedData: Eip712TypedDataPayload\n delivery: Eip712MultisignDelivery\n audit?: Record<string, unknown>\n}\n\nexport type BuildEip712MultisignArgs = {\n keyGen: KeyGenSubset\n purposeText: string\n purposeSuffix?: string\n /** Chain id stored on the sign request (protocol context; may differ from EIP-712 domain chainId). */\n destinationChainID: string\n destinationAddress: string\n legs: readonly BuildEip712MultisignLeg[]\n expiryDate?: number\n}\n\nfunction msgHashNo0x(digest: `0x${string}`): string {\n return digest.startsWith('0x') ? digest.slice(2) : digest\n}\n\nfunction eip712SignatureText(domain: TypedDataDomain, primaryType: string): string {\n return JSON.stringify({\n kind: 'EIP-712',\n ...(typeof domain.name === 'string' ? { name: domain.name } : {}),\n primaryType,\n })\n}\n\nfunction jsonStringifyForAudit(value: unknown): string {\n return JSON.stringify(value, (_, v) => (typeof v === 'bigint' ? v.toString() : v))\n}\n\nfunction eip712LegEnvelope(\n typedData: Eip712TypedDataPayload,\n delivery: Eip712MultisignDelivery,\n digest: `0x${string}`,\n): Record<string, unknown> {\n return {\n version: 1,\n digest,\n domain: typedData.domain,\n types: typedData.types,\n primaryType: typedData.primaryType,\n message: typedData.message,\n delivery,\n }\n}\n\nfunction eip712MsgRawHex(envelope: Record<string, unknown>): string {\n return stringToHex(jsonStringifyForAudit(envelope))\n}\n\n/**\n * Build an mpc-auth multiSignRequest body for one or more EIP-712 digests (no EVM tx broadcast).\n * `extraJSON.eip712` is always an array. N=1 uses `msgHash`/`msgRaw`; N>=2 uses `messageHashes`/`messageRawBatch`.\n */\nexport function buildEip712Multisign(args: BuildEip712MultisignArgs): MultisignBuildResult {\n if (args.legs.length < 1) {\n throw new Error('buildEip712Multisign requires at least one leg')\n }\n\n const eip712: Record<string, unknown>[] = []\n const legs = args.legs.map((leg) => {\n const digest = hashTypedData({\n domain: leg.typedData.domain,\n types: leg.typedData.types,\n primaryType: leg.typedData.primaryType,\n message: leg.typedData.message,\n })\n const envelope = eip712LegEnvelope(leg.typedData, leg.delivery, digest)\n eip712.push(envelope)\n return {\n msgHash: msgHashNo0x(digest),\n msgRaw: eip712MsgRawHex(envelope),\n destinationAddress: args.destinationAddress,\n signatureText: eip712SignatureText(leg.typedData.domain, leg.typedData.primaryType),\n audit: {\n kind: 'EIP712',\n primaryType: leg.typedData.primaryType,\n deliveryKind: leg.delivery.kind,\n ...(leg.audit ?? {}),\n },\n feeSnapshot: {},\n }\n })\n\n return finalizeMultisign({\n keyGen: args.keyGen,\n purposeText: args.purposeText,\n purposeSuffix: args.purposeSuffix,\n destinationChainID: args.destinationChainID,\n destinationAddress: args.destinationAddress,\n extraJSON: {\n signRequestKind: EIP712_SIGN_REQUEST_KIND,\n eip712,\n },\n expiryDate: args.expiryDate,\n legs,\n })\n}\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\n/** Standard Universal Router spenders (Trade API default 2.0 / chain-specific). */\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 /** Robinhood Chain mainnet — Universal Router v2.1.1 (Trade API / interface) */\n 4663: '0x8876789976decbfcbbbe364623c63652db8c0904',\n}\n\n/**\n * Universal Router 2.2.0 — required for permissioned / tokenized pool swaps\n * (PermissionedV4Router wrap/unwrap). Source: @uniswap/universal-router-sdk + Uniswap docs.\n */\nconst UNIVERSAL_ROUTER_V2_2_SPENDER: Partial<Record<number, string>> = {\n 1: '0xCb640A86855f1A828c27241bA364348de28abe66',\n 11155111: '0xB0C89059d7190EDb17eFF19829cc009cEe923916',\n}\n\n/** Per-chain Universal Router version for Trade API `x-universal-router-version`. */\nconst UNIVERSAL_ROUTER_VERSION_BY_CHAIN: Partial<Record<number, string>> = {\n /** Robinhood has UR 2.1.1 only in the supported-chains table (no 2.0 Trade API column). */\n 4663: '2.1.1',\n}\n\nexport const UNISWAP_UNIVERSAL_ROUTER_VERSION_DEFAULT = '2.0'\n/** Trade API header value required when any token in the trade is permissioned. */\nexport const UNISWAP_UNIVERSAL_ROUTER_VERSION_PERMISSIONED = '2.2.0'\n\nexport type UniswapUniversalRouterOpts = {\n /** When true, prefer UR 2.2.0 spender/version (permissioned pools). */\n permissioned?: boolean\n}\n\nexport function getUniswapUniversalRouterVersion(\n chainId: number,\n opts?: UniswapUniversalRouterOpts,\n): string {\n if (opts?.permissioned) {\n const v22 = UNIVERSAL_ROUTER_V2_2_SPENDER[chainId]\n if (typeof v22 === 'string' && v22.startsWith('0x')) {\n return UNISWAP_UNIVERSAL_ROUTER_VERSION_PERMISSIONED\n }\n }\n const v = UNIVERSAL_ROUTER_VERSION_BY_CHAIN[chainId]\n return typeof v === 'string' && v.trim() ? v.trim() : UNISWAP_UNIVERSAL_ROUTER_VERSION_DEFAULT\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(\n chainId: number,\n opts?: UniswapUniversalRouterOpts,\n): Address {\n if (opts?.permissioned) {\n const raw22 = UNIVERSAL_ROUTER_V2_2_SPENDER[chainId]\n if (raw22 && raw22.startsWith('0x')) return getAddress(raw22)\n }\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 function tryGetUniswapUniversalRouterV22(chainId: number): Address | null {\n const raw = UNIVERSAL_ROUTER_V2_2_SPENDER[chainId]\n if (!raw || !raw.startsWith('0x')) return null\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_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 /** Robinhood Chain mainnet */\n 4663: '0x58daec3116aae6D93017bAAea7749052E8a04fA7',\n}\n\n/** Permissioned Position Manager (UNI-V4-PERM-POSM) — non-transferable LP NFTs. */\nconst PERMISSIONED_POSITION_MANAGER_BY_CHAIN: Partial<Record<number, string>> = {\n 1: '0x89628C9B4CE81951a9BC1F36F0688Fad6A6ee248',\n 11155111: '0x68fC145BB20b388965bED184Df5ef912215bb3C7',\n}\n\n/** Shared PermissionedHooks address for pool keys. */\nconst PERMISSIONED_HOOKS_BY_CHAIN: Partial<Record<number, string>> = {\n 1: '0x69603ab16110Eb0bB5f5E9C8019749eE41A128C0',\n 11155111: '0x8B0E8d467af81D9F5B49165e104a2fe1b98328C0',\n}\n\n/** PermissionsAdapterFactory — maps adapters ↔ underlying permissioned tokens. */\nconst PERMISSIONS_ADAPTER_FACTORY_BY_CHAIN: Partial<Record<number, string>> = {\n 1: '0x38f9Ab57FBE2704EbB727cB20e33201aF0E5F961',\n 11155111: '0xEe258C31574fb59660C23534E76AF6497c2e5683',\n}\n\n/** Robinhood Chain wrapped native (WETH). */\nexport const ROBINHOOD_CHAIN_ID = 4663\nexport const ROBINHOOD_WETH_ADDRESS = '0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73' as const\n\nexport type UniswapV4PositionManagerKind = 'standard' | 'permissioned'\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\nexport function getUniswapV4PermissionedPositionManagerOrThrow(chainId: number): Address {\n const raw = PERMISSIONED_POSITION_MANAGER_BY_CHAIN[chainId]\n if (!raw || !raw.startsWith('0x') || raw.length !== 42) {\n throw new Error(\n `No Uniswap V4 Permissioned PositionManager is configured for chainId ${chainId}.`,\n )\n }\n return getAddress(raw)\n}\n\nexport function tryGetUniswapV4PermissionedPositionManager(chainId: number): Address | null {\n try {\n return getUniswapV4PermissionedPositionManagerOrThrow(chainId)\n } catch {\n return null\n }\n}\n\nexport function getUniswapV4PermissionedHooksOrThrow(chainId: number): Address {\n const raw = PERMISSIONED_HOOKS_BY_CHAIN[chainId]\n if (!raw || !raw.startsWith('0x') || raw.length !== 42) {\n throw new Error(`No Uniswap V4 PermissionedHooks is configured for chainId ${chainId}.`)\n }\n return getAddress(raw)\n}\n\nexport function tryGetUniswapV4PermissionedHooks(chainId: number): Address | null {\n try {\n return getUniswapV4PermissionedHooksOrThrow(chainId)\n } catch {\n return null\n }\n}\n\nexport function getUniswapV4PermissionsAdapterFactoryOrThrow(chainId: number): Address {\n const raw = PERMISSIONS_ADAPTER_FACTORY_BY_CHAIN[chainId]\n if (!raw || !raw.startsWith('0x') || raw.length !== 42) {\n throw new Error(\n `No Uniswap V4 PermissionsAdapterFactory is configured for chainId ${chainId}.`,\n )\n }\n return getAddress(raw)\n}\n\nexport function tryGetUniswapV4PermissionsAdapterFactory(chainId: number): Address | null {\n try {\n return getUniswapV4PermissionsAdapterFactoryOrThrow(chainId)\n } catch {\n return null\n }\n}\n\nexport function isUniswapV4PermissionedPositionManager(\n chainId: number,\n address: string | Address | null | undefined,\n): boolean {\n if (!address?.toString().trim()) return false\n const perm = tryGetUniswapV4PermissionedPositionManager(chainId)\n if (!perm) return false\n try {\n return getAddress(address as Address) === perm\n } catch {\n return false\n }\n}\n\nexport function isUniswapV4AnyPositionManager(\n chainId: number,\n address: string | Address | null | undefined,\n): boolean {\n if (!address?.toString().trim()) return false\n try {\n const a = getAddress(address as Address)\n const std = tryGetUniswapV4PositionManager(chainId)\n const perm = tryGetUniswapV4PermissionedPositionManager(chainId)\n return (std != null && a === std) || (perm != null && a === perm)\n } catch {\n return false\n }\n}\n\nexport function resolveUniswapV4PositionManager(\n chainId: number,\n kind: UniswapV4PositionManagerKind = 'standard',\n): Address {\n return kind === 'permissioned'\n ? getUniswapV4PermissionedPositionManagerOrThrow(chainId)\n : getUniswapV4PositionManagerOrThrow(chainId)\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\nexport const UNISWAP_V4_LP_PERMIT2_APPROVE_FALLBACK = 100_000n\n\n/** On-chain PermissionFlag bits (IAllowlistChecker / PermissionFlags). */\nexport const UNISWAP_V4_PERMISSION_FLAG_SWAP = 0x0001\nexport const UNISWAP_V4_PERMISSION_FLAG_LIQUIDITY = 0x0002\n","import { getAddress, type Address } from 'viem'\nimport type { KeyGenSubsetForPermit } from '../../../core/types.js'\nimport { buildEip712Multisign } from '../../../core/eip712Multisign.js'\nimport { PERMIT2_ADDRESS } from '../uniswap-v4/constants.js'\n\nexport const PERMIT_SINGLE_TYPES = {\n PermitSingle: [\n { name: 'details', type: 'PermitDetails' },\n { name: 'spender', type: 'address' },\n { name: 'sigDeadline', type: 'uint256' },\n ],\n PermitDetails: [\n { name: 'token', type: 'address' },\n { name: 'amount', type: 'uint160' },\n { name: 'expiration', type: 'uint48' },\n { name: 'nonce', type: 'uint48' },\n ],\n} as const\n\nexport type BuildPermit2PermitSingleMultisignArgs = {\n keyGen: KeyGenSubsetForPermit\n chainId: number\n purposeText: string\n owner: Address\n token: Address\n amount: bigint\n expiration: number\n nonce: number\n spender: Address\n sigDeadline: bigint\n}\n\nexport function buildPermit2PermitSingleMultisign(args: BuildPermit2PermitSingleMultisignArgs) {\n const token = getAddress(args.token)\n const spender = getAddress(args.spender)\n const owner = getAddress(args.owner)\n\n const message = {\n details: {\n token,\n amount: args.amount,\n expiration: args.expiration,\n nonce: args.nonce,\n },\n spender,\n sigDeadline: args.sigDeadline,\n }\n\n const domain = {\n name: 'Permit2',\n chainId: args.chainId,\n verifyingContract: PERMIT2_ADDRESS,\n }\n\n return buildEip712Multisign({\n keyGen: args.keyGen,\n purposeText: args.purposeText,\n destinationChainID: String(args.chainId),\n destinationAddress: PERMIT2_ADDRESS,\n legs: [\n {\n typedData: {\n domain,\n types: PERMIT_SINGLE_TYPES,\n primaryType: 'PermitSingle',\n message,\n },\n delivery: {\n kind: 'permit2_submit',\n chainId: args.chainId,\n permit2: PERMIT2_ADDRESS,\n owner,\n permitSingle: message,\n },\n audit: {\n protocol: 'permit2',\n action: 'permitSingle',\n owner,\n token,\n spender,\n },\n },\n ],\n })\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/core/purpose.ts","../../../../src/core/envelope.ts","../../../../src/core/eip712Multisign.ts","../../../../src/protocols/evm/uniswap-v4/constants.ts","../../../../src/protocols/evm/permit2/permitSingle.ts"],"names":["getAddress"],"mappings":"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","file":"index.js","sourcesContent":["/** Merge user purpose text with an optional batch / protocol suffix. */\nexport function mergePurposeText(purposeText: string | undefined, 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 /** Unix seconds (UTC) for mpc-auth multiSignRequest expiryDate. */\n expiryDate?: number\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, (_, v) => (typeof v === 'bigint' ? v.toString() : v))\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 if (input.expiryDate != null && input.expiryDate > 0) {\n bodyForSign.expiryDate = Math.floor(input.expiryDate)\n }\n\n return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) }\n}\n\nexport const coreChainCategoryModule: ChainCategoryModule = {\n category: 'evm',\n finalizeMultisign,\n}\n","import { hashTypedData, stringToHex, type TypedDataDomain } from 'viem'\nimport type { KeyGenSubset, MultisignBuildResult } from './types.js'\nimport { finalizeMultisign } from './envelope.js'\n\nexport const EIP712_SIGN_REQUEST_KIND = 'eip712' as const\n\nexport type Eip712TypedDataField = { name: string; type: string }\n\nexport type Eip712TypedDataPayload = {\n domain: TypedDataDomain\n types: Record<string, readonly Eip712TypedDataField[] | Eip712TypedDataField[]>\n primaryType: string\n message: Record<string, unknown>\n}\n\nexport type Eip712MultisignDelivery = Record<string, unknown> & { kind: string }\n\nexport type BuildEip712MultisignLeg = {\n typedData: Eip712TypedDataPayload\n delivery: Eip712MultisignDelivery\n audit?: Record<string, unknown>\n}\n\nexport type BuildEip712MultisignArgs = {\n keyGen: KeyGenSubset\n purposeText: string\n purposeSuffix?: string\n /** Chain id stored on the sign request (protocol context; may differ from EIP-712 domain chainId). */\n destinationChainID: string\n destinationAddress: string\n legs: readonly BuildEip712MultisignLeg[]\n expiryDate?: number\n}\n\nfunction msgHashNo0x(digest: `0x${string}`): string {\n return digest.startsWith('0x') ? digest.slice(2) : digest\n}\n\nfunction eip712SignatureText(domain: TypedDataDomain, primaryType: string): string {\n return JSON.stringify({\n kind: 'EIP-712',\n ...(typeof domain.name === 'string' ? { name: domain.name } : {}),\n primaryType,\n })\n}\n\nfunction jsonStringifyForAudit(value: unknown): string {\n return JSON.stringify(value, (_, v) => (typeof v === 'bigint' ? v.toString() : v))\n}\n\nfunction eip712LegEnvelope(\n typedData: Eip712TypedDataPayload,\n delivery: Eip712MultisignDelivery,\n digest: `0x${string}`,\n): Record<string, unknown> {\n return {\n version: 1,\n digest,\n domain: typedData.domain,\n types: typedData.types,\n primaryType: typedData.primaryType,\n message: typedData.message,\n delivery,\n }\n}\n\nfunction eip712MsgRawHex(envelope: Record<string, unknown>): string {\n return stringToHex(jsonStringifyForAudit(envelope))\n}\n\n/**\n * Build an mpc-auth multiSignRequest body for one or more EIP-712 digests (no EVM tx broadcast).\n * `extraJSON.eip712` is always an array. N=1 uses `msgHash`/`msgRaw`; N>=2 uses `messageHashes`/`messageRawBatch`.\n */\nexport function buildEip712Multisign(args: BuildEip712MultisignArgs): MultisignBuildResult {\n if (args.legs.length < 1) {\n throw new Error('buildEip712Multisign requires at least one leg')\n }\n\n const eip712: Record<string, unknown>[] = []\n const legs = args.legs.map((leg) => {\n const digest = hashTypedData({\n domain: leg.typedData.domain,\n types: leg.typedData.types,\n primaryType: leg.typedData.primaryType,\n message: leg.typedData.message,\n })\n const envelope = eip712LegEnvelope(leg.typedData, leg.delivery, digest)\n eip712.push(envelope)\n return {\n msgHash: msgHashNo0x(digest),\n msgRaw: eip712MsgRawHex(envelope),\n destinationAddress: args.destinationAddress,\n signatureText: eip712SignatureText(leg.typedData.domain, leg.typedData.primaryType),\n audit: {\n kind: 'EIP712',\n primaryType: leg.typedData.primaryType,\n deliveryKind: leg.delivery.kind,\n ...(leg.audit ?? {}),\n },\n feeSnapshot: {},\n }\n })\n\n return finalizeMultisign({\n keyGen: args.keyGen,\n purposeText: args.purposeText,\n purposeSuffix: args.purposeSuffix,\n destinationChainID: args.destinationChainID,\n destinationAddress: args.destinationAddress,\n extraJSON: {\n signRequestKind: EIP712_SIGN_REQUEST_KIND,\n eip712,\n },\n expiryDate: args.expiryDate,\n legs,\n })\n}\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\n/** Standard Universal Router spenders (Trade API default 2.0 / chain-specific). */\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 /** Robinhood Chain mainnet — Universal Router v2.1.1 (Trade API / interface) */\n 4663: '0x8876789976decbfcbbbe364623c63652db8c0904',\n /** Circle Arc mainnet — official Uniswap v4 deployments */\n 5042: '0x4fcA4a51Ab4F23A7447b3284fBd7D73289A89Fb1',\n}\n\n/**\n * Universal Router 2.2.0 — required for permissioned / tokenized pool swaps\n * (PermissionedV4Router wrap/unwrap). Source: @uniswap/universal-router-sdk + Uniswap docs.\n */\nconst UNIVERSAL_ROUTER_V2_2_SPENDER: Partial<Record<number, string>> = {\n 1: '0xCb640A86855f1A828c27241bA364348de28abe66',\n 11155111: '0xB0C89059d7190EDb17eFF19829cc009cEe923916',\n}\n\n/** Per-chain Universal Router version for Trade API `x-universal-router-version`. */\nconst UNIVERSAL_ROUTER_VERSION_BY_CHAIN: Partial<Record<number, string>> = {\n /** Robinhood has UR 2.1.1 only in the supported-chains table (no 2.0 Trade API column). */\n 4663: '2.1.1',\n}\n\nexport const UNISWAP_UNIVERSAL_ROUTER_VERSION_DEFAULT = '2.0'\n/** Trade API header value required when any token in the trade is permissioned. */\nexport const UNISWAP_UNIVERSAL_ROUTER_VERSION_PERMISSIONED = '2.2.0'\n\nexport type UniswapUniversalRouterOpts = {\n /** When true, prefer UR 2.2.0 spender/version (permissioned pools). */\n permissioned?: boolean\n}\n\nexport function getUniswapUniversalRouterVersion(\n chainId: number,\n opts?: UniswapUniversalRouterOpts,\n): string {\n if (opts?.permissioned) {\n const v22 = UNIVERSAL_ROUTER_V2_2_SPENDER[chainId]\n if (typeof v22 === 'string' && v22.startsWith('0x')) {\n return UNISWAP_UNIVERSAL_ROUTER_VERSION_PERMISSIONED\n }\n }\n const v = UNIVERSAL_ROUTER_VERSION_BY_CHAIN[chainId]\n return typeof v === 'string' && v.trim() ? v.trim() : UNISWAP_UNIVERSAL_ROUTER_VERSION_DEFAULT\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(\n chainId: number,\n opts?: UniswapUniversalRouterOpts,\n): Address {\n if (opts?.permissioned) {\n const raw22 = UNIVERSAL_ROUTER_V2_2_SPENDER[chainId]\n if (raw22 && raw22.startsWith('0x')) return getAddress(raw22)\n }\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 function tryGetUniswapUniversalRouterV22(chainId: number): Address | null {\n const raw = UNIVERSAL_ROUTER_V2_2_SPENDER[chainId]\n if (!raw || !raw.startsWith('0x')) return null\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_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 /** Robinhood Chain mainnet */\n 4663: '0x58daec3116aae6D93017bAAea7749052E8a04fA7',\n /** Circle Arc mainnet */\n 5042: '0x6049c9a0e26405C0985f9E3685C87d0aE917f82B',\n}\n\n/** Permissioned Position Manager (UNI-V4-PERM-POSM) — non-transferable LP NFTs. */\nconst PERMISSIONED_POSITION_MANAGER_BY_CHAIN: Partial<Record<number, string>> = {\n 1: '0x89628C9B4CE81951a9BC1F36F0688Fad6A6ee248',\n 11155111: '0x68fC145BB20b388965bED184Df5ef912215bb3C7',\n}\n\n/** Shared PermissionedHooks address for pool keys. */\nconst PERMISSIONED_HOOKS_BY_CHAIN: Partial<Record<number, string>> = {\n 1: '0x69603ab16110Eb0bB5f5E9C8019749eE41A128C0',\n 11155111: '0x8B0E8d467af81D9F5B49165e104a2fe1b98328C0',\n}\n\n/** PermissionsAdapterFactory — maps adapters ↔ underlying permissioned tokens. */\nconst PERMISSIONS_ADAPTER_FACTORY_BY_CHAIN: Partial<Record<number, string>> = {\n 1: '0x38f9Ab57FBE2704EbB727cB20e33201aF0E5F961',\n 11155111: '0xEe258C31574fb59660C23534E76AF6497c2e5683',\n}\n\n/** Robinhood Chain wrapped native (WETH). */\nexport const ROBINHOOD_CHAIN_ID = 4663\nexport const ROBINHOOD_WETH_ADDRESS = '0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73' as const\n\nexport type UniswapV4PositionManagerKind = 'standard' | 'permissioned'\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\nexport function getUniswapV4PermissionedPositionManagerOrThrow(chainId: number): Address {\n const raw = PERMISSIONED_POSITION_MANAGER_BY_CHAIN[chainId]\n if (!raw || !raw.startsWith('0x') || raw.length !== 42) {\n throw new Error(\n `No Uniswap V4 Permissioned PositionManager is configured for chainId ${chainId}.`,\n )\n }\n return getAddress(raw)\n}\n\nexport function tryGetUniswapV4PermissionedPositionManager(chainId: number): Address | null {\n try {\n return getUniswapV4PermissionedPositionManagerOrThrow(chainId)\n } catch {\n return null\n }\n}\n\nexport function getUniswapV4PermissionedHooksOrThrow(chainId: number): Address {\n const raw = PERMISSIONED_HOOKS_BY_CHAIN[chainId]\n if (!raw || !raw.startsWith('0x') || raw.length !== 42) {\n throw new Error(`No Uniswap V4 PermissionedHooks is configured for chainId ${chainId}.`)\n }\n return getAddress(raw)\n}\n\nexport function tryGetUniswapV4PermissionedHooks(chainId: number): Address | null {\n try {\n return getUniswapV4PermissionedHooksOrThrow(chainId)\n } catch {\n return null\n }\n}\n\nexport function getUniswapV4PermissionsAdapterFactoryOrThrow(chainId: number): Address {\n const raw = PERMISSIONS_ADAPTER_FACTORY_BY_CHAIN[chainId]\n if (!raw || !raw.startsWith('0x') || raw.length !== 42) {\n throw new Error(\n `No Uniswap V4 PermissionsAdapterFactory is configured for chainId ${chainId}.`,\n )\n }\n return getAddress(raw)\n}\n\nexport function tryGetUniswapV4PermissionsAdapterFactory(chainId: number): Address | null {\n try {\n return getUniswapV4PermissionsAdapterFactoryOrThrow(chainId)\n } catch {\n return null\n }\n}\n\nexport function isUniswapV4PermissionedPositionManager(\n chainId: number,\n address: string | Address | null | undefined,\n): boolean {\n if (!address?.toString().trim()) return false\n const perm = tryGetUniswapV4PermissionedPositionManager(chainId)\n if (!perm) return false\n try {\n return getAddress(address as Address) === perm\n } catch {\n return false\n }\n}\n\nexport function isUniswapV4AnyPositionManager(\n chainId: number,\n address: string | Address | null | undefined,\n): boolean {\n if (!address?.toString().trim()) return false\n try {\n const a = getAddress(address as Address)\n const std = tryGetUniswapV4PositionManager(chainId)\n const perm = tryGetUniswapV4PermissionedPositionManager(chainId)\n return (std != null && a === std) || (perm != null && a === perm)\n } catch {\n return false\n }\n}\n\nexport function resolveUniswapV4PositionManager(\n chainId: number,\n kind: UniswapV4PositionManagerKind = 'standard',\n): Address {\n return kind === 'permissioned'\n ? getUniswapV4PermissionedPositionManagerOrThrow(chainId)\n : getUniswapV4PositionManagerOrThrow(chainId)\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\nexport const UNISWAP_V4_LP_PERMIT2_APPROVE_FALLBACK = 100_000n\n\n/** On-chain PermissionFlag bits (IAllowlistChecker / PermissionFlags). */\nexport const UNISWAP_V4_PERMISSION_FLAG_SWAP = 0x0001\nexport const UNISWAP_V4_PERMISSION_FLAG_LIQUIDITY = 0x0002\n","import { getAddress, type Address } from 'viem'\nimport type { KeyGenSubsetForPermit } from '../../../core/types.js'\nimport { buildEip712Multisign } from '../../../core/eip712Multisign.js'\nimport { PERMIT2_ADDRESS } from '../uniswap-v4/constants.js'\n\nexport const PERMIT_SINGLE_TYPES = {\n PermitSingle: [\n { name: 'details', type: 'PermitDetails' },\n { name: 'spender', type: 'address' },\n { name: 'sigDeadline', type: 'uint256' },\n ],\n PermitDetails: [\n { name: 'token', type: 'address' },\n { name: 'amount', type: 'uint160' },\n { name: 'expiration', type: 'uint48' },\n { name: 'nonce', type: 'uint48' },\n ],\n} as const\n\nexport type BuildPermit2PermitSingleMultisignArgs = {\n keyGen: KeyGenSubsetForPermit\n chainId: number\n purposeText: string\n owner: Address\n token: Address\n amount: bigint\n expiration: number\n nonce: number\n spender: Address\n sigDeadline: bigint\n}\n\nexport function buildPermit2PermitSingleMultisign(args: BuildPermit2PermitSingleMultisignArgs) {\n const token = getAddress(args.token)\n const spender = getAddress(args.spender)\n const owner = getAddress(args.owner)\n\n const message = {\n details: {\n token,\n amount: args.amount,\n expiration: args.expiration,\n nonce: args.nonce,\n },\n spender,\n sigDeadline: args.sigDeadline,\n }\n\n const domain = {\n name: 'Permit2',\n chainId: args.chainId,\n verifyingContract: PERMIT2_ADDRESS,\n }\n\n return buildEip712Multisign({\n keyGen: args.keyGen,\n purposeText: args.purposeText,\n destinationChainID: String(args.chainId),\n destinationAddress: PERMIT2_ADDRESS,\n legs: [\n {\n typedData: {\n domain,\n types: PERMIT_SINGLE_TYPES,\n primaryType: 'PermitSingle',\n message,\n },\n delivery: {\n kind: 'permit2_submit',\n chainId: args.chainId,\n permit2: PERMIT2_ADDRESS,\n owner,\n permitSingle: message,\n },\n audit: {\n protocol: 'permit2',\n action: 'permitSingle',\n owner,\n token,\n spender,\n },\n },\n ],\n })\n}\n"]}
|
|
@@ -70,7 +70,9 @@ var UNIVERSAL_ROUTER_SPENDER = {
|
|
|
70
70
|
4217: "0x1febb76be10aaf3a1402f04e8e835f2c382f7914",
|
|
71
71
|
196: "0x5507749f2c558bb3e162c6e90c314c092e7372ff",
|
|
72
72
|
/** Robinhood Chain mainnet — Universal Router v2.1.1 (Trade API / interface) */
|
|
73
|
-
4663: "0x8876789976decbfcbbbe364623c63652db8c0904"
|
|
73
|
+
4663: "0x8876789976decbfcbbbe364623c63652db8c0904",
|
|
74
|
+
/** Circle Arc mainnet — official Uniswap v4 deployments */
|
|
75
|
+
5042: "0x4fcA4a51Ab4F23A7447b3284fBd7D73289A89Fb1"
|
|
74
76
|
};
|
|
75
77
|
var UNIVERSAL_ROUTER_V2_2_SPENDER = {
|
|
76
78
|
1: "0xCb640A86855f1A828c27241bA364348de28abe66",
|
|
@@ -138,7 +140,9 @@ var POSITION_MANAGER_BY_CHAIN = {
|
|
|
138
140
|
1868: "0x0e2850543f69f678257266e0907ff9a58b3f13de",
|
|
139
141
|
59144: "0x661e93cca42afacb172121ef892830ca3b70f08d",
|
|
140
142
|
/** Robinhood Chain mainnet */
|
|
141
|
-
4663: "0x58daec3116aae6D93017bAAea7749052E8a04fA7"
|
|
143
|
+
4663: "0x58daec3116aae6D93017bAAea7749052E8a04fA7",
|
|
144
|
+
/** Circle Arc mainnet */
|
|
145
|
+
5042: "0x6049c9a0e26405C0985f9E3685C87d0aE917f82B"
|
|
142
146
|
};
|
|
143
147
|
var PERMISSIONED_POSITION_MANAGER_BY_CHAIN = {
|
|
144
148
|
1: "0x89628C9B4CE81951a9BC1F36F0688Fad6A6ee248",
|