@continuumdao/ctm-mpc-defi 0.2.40 → 0.2.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/dist/agent/catalog.cjs +50 -6
  2. package/dist/agent/catalog.cjs.map +1 -1
  3. package/dist/agent/catalog.js +50 -6
  4. package/dist/agent/catalog.js.map +1 -1
  5. package/dist/agent/skills/aave-v4/SKILL.md +1 -1
  6. package/dist/agent/skills/circle-cctp/SKILL.md +1 -0
  7. package/dist/agent/skills/morpho/SKILL.md +11 -0
  8. package/dist/agent/skills/uniswap-v4/SKILL.md +1 -1
  9. package/dist/chains/evm/index.cjs +7 -2
  10. package/dist/chains/evm/index.cjs.map +1 -1
  11. package/dist/chains/evm/index.js +8 -3
  12. package/dist/chains/evm/index.js.map +1 -1
  13. package/dist/core/index.cjs +14 -0
  14. package/dist/core/index.cjs.map +1 -1
  15. package/dist/core/index.d.ts +7 -2
  16. package/dist/core/index.js +13 -2
  17. package/dist/core/index.js.map +1 -1
  18. package/dist/index.cjs +52 -8
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.d.ts +1 -1
  21. package/dist/index.js +51 -10
  22. package/dist/index.js.map +1 -1
  23. package/dist/protocols/evm/aave-v4/index.cjs +11 -7
  24. package/dist/protocols/evm/aave-v4/index.cjs.map +1 -1
  25. package/dist/protocols/evm/aave-v4/index.js +12 -8
  26. package/dist/protocols/evm/aave-v4/index.js.map +1 -1
  27. package/dist/protocols/evm/aerodrome/index.cjs +14 -2
  28. package/dist/protocols/evm/aerodrome/index.cjs.map +1 -1
  29. package/dist/protocols/evm/aerodrome/index.js +14 -2
  30. package/dist/protocols/evm/aerodrome/index.js.map +1 -1
  31. package/dist/protocols/evm/arcus/index.cjs +6 -2
  32. package/dist/protocols/evm/arcus/index.cjs.map +1 -1
  33. package/dist/protocols/evm/arcus/index.js +7 -3
  34. package/dist/protocols/evm/arcus/index.js.map +1 -1
  35. package/dist/protocols/evm/circle-cctp/index.cjs +23 -3
  36. package/dist/protocols/evm/circle-cctp/index.cjs.map +1 -1
  37. package/dist/protocols/evm/circle-cctp/index.js +24 -4
  38. package/dist/protocols/evm/circle-cctp/index.js.map +1 -1
  39. package/dist/protocols/evm/compound-v3/index.cjs +9 -3
  40. package/dist/protocols/evm/compound-v3/index.cjs.map +1 -1
  41. package/dist/protocols/evm/compound-v3/index.js +10 -4
  42. package/dist/protocols/evm/compound-v3/index.js.map +1 -1
  43. package/dist/protocols/evm/continuum-dao/index.cjs +11 -5
  44. package/dist/protocols/evm/continuum-dao/index.cjs.map +1 -1
  45. package/dist/protocols/evm/continuum-dao/index.js +12 -6
  46. package/dist/protocols/evm/continuum-dao/index.js.map +1 -1
  47. package/dist/protocols/evm/curve-dao/index.cjs +8 -4
  48. package/dist/protocols/evm/curve-dao/index.cjs.map +1 -1
  49. package/dist/protocols/evm/curve-dao/index.js +9 -5
  50. package/dist/protocols/evm/curve-dao/index.js.map +1 -1
  51. package/dist/protocols/evm/ethena/index.cjs +13 -9
  52. package/dist/protocols/evm/ethena/index.cjs.map +1 -1
  53. package/dist/protocols/evm/ethena/index.js +14 -10
  54. package/dist/protocols/evm/ethena/index.js.map +1 -1
  55. package/dist/protocols/evm/euler-v2/index.cjs +21 -16
  56. package/dist/protocols/evm/euler-v2/index.cjs.map +1 -1
  57. package/dist/protocols/evm/euler-v2/index.js +22 -17
  58. package/dist/protocols/evm/euler-v2/index.js.map +1 -1
  59. package/dist/protocols/evm/gmx/index.cjs +12 -8
  60. package/dist/protocols/evm/gmx/index.cjs.map +1 -1
  61. package/dist/protocols/evm/gmx/index.js +13 -9
  62. package/dist/protocols/evm/gmx/index.js.map +1 -1
  63. package/dist/protocols/evm/hyperliquid/index.cjs +5 -1
  64. package/dist/protocols/evm/hyperliquid/index.cjs.map +1 -1
  65. package/dist/protocols/evm/hyperliquid/index.js +6 -2
  66. package/dist/protocols/evm/hyperliquid/index.js.map +1 -1
  67. package/dist/protocols/evm/lido/index.cjs +7 -3
  68. package/dist/protocols/evm/lido/index.cjs.map +1 -1
  69. package/dist/protocols/evm/lido/index.js +8 -4
  70. package/dist/protocols/evm/lido/index.js.map +1 -1
  71. package/dist/protocols/evm/maple/index.cjs +7 -3
  72. package/dist/protocols/evm/maple/index.cjs.map +1 -1
  73. package/dist/protocols/evm/maple/index.js +8 -4
  74. package/dist/protocols/evm/maple/index.js.map +1 -1
  75. package/dist/protocols/evm/morpho/index.cjs +34 -11
  76. package/dist/protocols/evm/morpho/index.cjs.map +1 -1
  77. package/dist/protocols/evm/morpho/index.d.ts +12 -1
  78. package/dist/protocols/evm/morpho/index.js +31 -13
  79. package/dist/protocols/evm/morpho/index.js.map +1 -1
  80. package/dist/protocols/evm/pendle/index.cjs +9 -3
  81. package/dist/protocols/evm/pendle/index.cjs.map +1 -1
  82. package/dist/protocols/evm/pendle/index.js +10 -4
  83. package/dist/protocols/evm/pendle/index.js.map +1 -1
  84. package/dist/protocols/evm/permit2/index.cjs.map +1 -1
  85. package/dist/protocols/evm/permit2/index.js.map +1 -1
  86. package/dist/protocols/evm/sky/index.cjs +17 -13
  87. package/dist/protocols/evm/sky/index.cjs.map +1 -1
  88. package/dist/protocols/evm/sky/index.js +18 -14
  89. package/dist/protocols/evm/sky/index.js.map +1 -1
  90. package/dist/protocols/evm/uniswap-v4/index.cjs +19 -9
  91. package/dist/protocols/evm/uniswap-v4/index.cjs.map +1 -1
  92. package/dist/protocols/evm/uniswap-v4/index.js +20 -10
  93. package/dist/protocols/evm/uniswap-v4/index.js.map +1 -1
  94. package/dist/protocols/evm/venice/index.cjs +10 -4
  95. package/dist/protocols/evm/venice/index.cjs.map +1 -1
  96. package/dist/protocols/evm/venice/index.js +10 -4
  97. package/dist/protocols/evm/venice/index.js.map +1 -1
  98. 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"]}
@@ -26,6 +26,10 @@ var SKY_LOCKSTAKE_DEFAULT_FARM_REF = 1;
26
26
  var SKY_LOCKSTAKE_UI_COLLATERAL_FACTOR = 0.65;
27
27
  var SKY_TOKEN_DECIMALS = 18;
28
28
  var USDS_DECIMALS = 18;
29
+ function defiEvmTransport(rpcUrl, opts) {
30
+ const url = rpcUrl.trim();
31
+ return viem.http(url, opts);
32
+ }
29
33
 
30
34
  // src/core/purpose.ts
31
35
  function mergePurposeText(purposeText, purposeSuffix) {
@@ -117,7 +121,7 @@ async function buildEvmMultisignBatch(args) {
117
121
  nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
118
122
  rpcUrls: { default: { http: [rpcUrl] } }
119
123
  });
120
- const publicClient = viem.createPublicClient({ chain: ch, transport: viem.http(rpcUrl) });
124
+ const publicClient = viem.createPublicClient({ chain: ch, transport: defiEvmTransport(rpcUrl) });
121
125
  const feeParams = await continuumNodeSdk.fetchChainFeeParams(rpcUrl, chainId);
122
126
  const legacy = Boolean(chainDetail?.legacy) || !feeParams.isEip1559;
123
127
  const latestBaseFeeWei = !legacy ? (await publicClient.getBlock({ blockTag: "latest" })).baseFeePerGas ?? 0n : 0n;
@@ -325,7 +329,7 @@ async function buildSkyLockstakeStakePositionBatch(args) {
325
329
  nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
326
330
  rpcUrls: { default: { http: [rpc] } }
327
331
  });
328
- const publicClient = viem.createPublicClient({ chain: ch, transport: viem.http(rpc) });
332
+ const publicClient = viem.createPublicClient({ chain: ch, transport: defiEvmTransport(rpc) });
329
333
  const executor = viem.getAddress(args.executorAddress);
330
334
  const sky = viem.getAddress(SKY_ETHEREUM_MAINNET);
331
335
  const engine = viem.getAddress(SKY_LOCKSTAKE_ENGINE_MAINNET);
@@ -571,7 +575,7 @@ async function buildSkyLockstakeDrawBatch(args) {
571
575
  nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
572
576
  rpcUrls: { default: { http: [rpc] } }
573
577
  });
574
- const publicClient = viem.createPublicClient({ chain: ch, transport: viem.http(rpc) });
578
+ const publicClient = viem.createPublicClient({ chain: ch, transport: defiEvmTransport(rpc) });
575
579
  const executor = viem.getAddress(args.executorAddress);
576
580
  const engine = viem.getAddress(SKY_LOCKSTAKE_ENGINE_MAINNET);
577
581
  const usds = viem.getAddress(USDS_ETHEREUM_MAINNET);
@@ -636,7 +640,7 @@ async function buildSkyLockstakeGetRewardBatch(args) {
636
640
  nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
637
641
  rpcUrls: { default: { http: [rpc] } }
638
642
  });
639
- const publicClient = viem.createPublicClient({ chain: ch, transport: viem.http(rpc) });
643
+ const publicClient = viem.createPublicClient({ chain: ch, transport: defiEvmTransport(rpc) });
640
644
  const executor = viem.getAddress(args.executorAddress);
641
645
  const engine = viem.getAddress(SKY_LOCKSTAKE_ENGINE_MAINNET);
642
646
  const farm = viem.getAddress(args.farmAddress);
@@ -713,7 +717,7 @@ async function buildSkyLockstakeWipeBatch(args) {
713
717
  nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
714
718
  rpcUrls: { default: { http: [rpc] } }
715
719
  });
716
- const publicClient = viem.createPublicClient({ chain: ch, transport: viem.http(rpc) });
720
+ const publicClient = viem.createPublicClient({ chain: ch, transport: defiEvmTransport(rpc) });
717
721
  const executor = viem.getAddress(args.executorAddress);
718
722
  const engine = viem.getAddress(SKY_LOCKSTAKE_ENGINE_MAINNET);
719
723
  const usds = viem.getAddress(USDS_ETHEREUM_MAINNET);
@@ -867,7 +871,7 @@ async function buildSkyLockstakeCloseBatch(args) {
867
871
  nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
868
872
  rpcUrls: { default: { http: [rpc] } }
869
873
  });
870
- viem.createPublicClient({ chain: ch, transport: viem.http(rpc) });
874
+ viem.createPublicClient({ chain: ch, transport: defiEvmTransport(rpc) });
871
875
  const executor = viem.getAddress(args.executorAddress);
872
876
  const engine = viem.getAddress(SKY_LOCKSTAKE_ENGINE_MAINNET);
873
877
  const usds = viem.getAddress(USDS_ETHEREUM_MAINNET);
@@ -1026,7 +1030,7 @@ async function buildSkySusdsRedeemToUsdsBatch(args) {
1026
1030
  nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
1027
1031
  rpcUrls: { default: { http: [rpc] } }
1028
1032
  });
1029
- const publicClient = viem.createPublicClient({ chain: ch, transport: viem.http(rpc) });
1033
+ const publicClient = viem.createPublicClient({ chain: ch, transport: defiEvmTransport(rpc) });
1030
1034
  const executor = viem.getAddress(args.executorAddress);
1031
1035
  const receiver = viem.getAddress(args.receiver ?? executor);
1032
1036
  const underlying = await publicClient.readContract({
@@ -1101,7 +1105,7 @@ async function buildSkySusdsDepositFromUsdsBatch(args) {
1101
1105
  nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
1102
1106
  rpcUrls: { default: { http: [rpc] } }
1103
1107
  });
1104
- const publicClient = viem.createPublicClient({ chain: ch, transport: viem.http(rpc) });
1108
+ const publicClient = viem.createPublicClient({ chain: ch, transport: defiEvmTransport(rpc) });
1105
1109
  const executor = viem.getAddress(args.executorAddress);
1106
1110
  const underlying = await publicClient.readContract({
1107
1111
  address: vault,
@@ -1231,7 +1235,7 @@ function skyClient(rpcUrl) {
1231
1235
  nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
1232
1236
  rpcUrls: { default: { http: [rpc] } }
1233
1237
  });
1234
- return viem.createPublicClient({ chain: ch, transport: viem.http(rpc) });
1238
+ return viem.createPublicClient({ chain: ch, transport: defiEvmTransport(rpc) });
1235
1239
  }
1236
1240
  function skyUsdsDebtWeiFromUrnArt(art, rate) {
1237
1241
  if (art === 0n || rate === 0n) return 0n;
@@ -1340,7 +1344,7 @@ async function readSusdsVaultShareBalanceWei(args) {
1340
1344
  nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
1341
1345
  rpcUrls: { default: { http: [rpc] } }
1342
1346
  });
1343
- const client = viem.createPublicClient({ chain: ch, transport: viem.http(rpc) });
1347
+ const client = viem.createPublicClient({ chain: ch, transport: defiEvmTransport(rpc) });
1344
1348
  const vault = viem.getAddress(SUSDS_VAULT_ERC4626_MAINNET);
1345
1349
  return client.readContract({
1346
1350
  address: vault,
@@ -1357,7 +1361,7 @@ async function readSusdsVaultDecimals(args) {
1357
1361
  nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
1358
1362
  rpcUrls: { default: { http: [rpc] } }
1359
1363
  });
1360
- const client = viem.createPublicClient({ chain: ch, transport: viem.http(rpc) });
1364
+ const client = viem.createPublicClient({ chain: ch, transport: defiEvmTransport(rpc) });
1361
1365
  const vault = viem.getAddress(SUSDS_VAULT_ERC4626_MAINNET);
1362
1366
  const d = await client.readContract({
1363
1367
  address: vault,
@@ -1375,7 +1379,7 @@ async function readSusdsPreviewRedeemAssetsWei(args) {
1375
1379
  nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
1376
1380
  rpcUrls: { default: { http: [rpc] } }
1377
1381
  });
1378
- const client = viem.createPublicClient({ chain: ch, transport: viem.http(rpc) });
1382
+ const client = viem.createPublicClient({ chain: ch, transport: defiEvmTransport(rpc) });
1379
1383
  const vault = viem.getAddress(SUSDS_VAULT_ERC4626_MAINNET);
1380
1384
  return client.readContract({
1381
1385
  address: vault,
@@ -1413,7 +1417,7 @@ async function skyFetchSusdsRateSummary(args) {
1413
1417
  nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
1414
1418
  rpcUrls: { default: { http: [rpc] } }
1415
1419
  });
1416
- const client = viem.createPublicClient({ chain: ch, transport: viem.http(rpc) });
1420
+ const client = viem.createPublicClient({ chain: ch, transport: defiEvmTransport(rpc) });
1417
1421
  const vault = viem.getAddress(SUSDS_VAULT_ERC4626_MAINNET);
1418
1422
  const [ssr, assets] = await Promise.all([
1419
1423
  client.readContract({ address: vault, abi: susdsRateAbi, functionName: "ssr" }),