{"version":3,"sources":["../../src/multicall.ts"],"sourcesContent":["import { encodeFunctionData, decodeFunctionResult } from \"viem\";\n\n/**\n * Multicall3 contract address.\n * Same address on all EVM chains via CREATE2 deployment.\n *\n * @see https://github.com/mds1/multicall\n */\nexport const MULTICALL3_ADDRESS = \"0xcA11bde05977b3631167028862bE2a173976CA11\" as const;\n\n/** Multicall3 getEthBalance ABI for querying native token balance. */\nexport const multicall3GetEthBalanceAbi = [\n  {\n    name: \"getEthBalance\",\n    inputs: [{ name: \"addr\", type: \"address\" }],\n    outputs: [{ name: \"balance\", type: \"uint256\" }],\n    stateMutability: \"view\",\n    type: \"function\",\n  },\n] as const;\n\n/** Multicall3 tryAggregate ABI for batching calls. */\nconst multicall3ABI = [\n  {\n    inputs: [\n      { name: \"requireSuccess\", type: \"bool\" },\n      {\n        name: \"calls\",\n        type: \"tuple[]\",\n        components: [\n          { name: \"target\", type: \"address\" },\n          { name: \"callData\", type: \"bytes\" },\n        ],\n      },\n    ],\n    name: \"tryAggregate\",\n    outputs: [\n      {\n        name: \"returnData\",\n        type: \"tuple[]\",\n        components: [\n          { name: \"success\", type: \"bool\" },\n          { name: \"returnData\", type: \"bytes\" },\n        ],\n      },\n    ],\n    stateMutability: \"payable\",\n    type: \"function\",\n  },\n] as const;\n\nexport type ContractCall = {\n  address: `0x${string}`;\n  abi: readonly unknown[];\n  functionName: string;\n  args?: readonly unknown[];\n};\n\nexport type RawContractCall = {\n  address: `0x${string}`;\n  callData: `0x${string}`;\n};\n\nexport type MulticallSuccess = { status: \"success\"; result: unknown };\nexport type MulticallFailure = { status: \"failure\"; error: Error };\nexport type MulticallResult = MulticallSuccess | MulticallFailure;\n\n/**\n * Batches contract calls via Multicall3 `tryAggregate(false, ...)`.\n *\n * Accepts a mix of typed ContractCall (ABI-encoded + decoded) and\n * RawContractCall (pre-encoded calldata, no decoding) entries.\n * Raw calls are useful for the EIP-6492 factory deployment case\n * where calldata is pre-encoded with no ABI available.\n */\ntype ReadContractFn = (args: {\n  address: `0x${string}`;\n  abi: readonly unknown[];\n  functionName: string;\n  args?: readonly unknown[];\n}) => Promise<unknown>;\n\n/**\n * Executes multiple contract read calls in a single RPC round-trip using Multicall3.\n *\n * @param readContract - Function that performs a single contract read (e.g. viem readContract)\n * @param calls - Array of contract calls to batch (ContractCall or RawContractCall)\n * @returns A promise that resolves to an array of decoded results, one per call\n */\nexport async function multicall(\n  readContract: ReadContractFn,\n  calls: ReadonlyArray<ContractCall | RawContractCall>,\n): Promise<MulticallResult[]> {\n  const aggregateCalls = calls.map(call => {\n    if (\"callData\" in call) {\n      return { target: call.address, callData: call.callData };\n    }\n    const callData = encodeFunctionData({\n      abi: call.abi,\n      functionName: call.functionName,\n      args: call.args as unknown[],\n    });\n    return { target: call.address, callData };\n  });\n\n  const rawResults = (await readContract({\n    address: MULTICALL3_ADDRESS,\n    abi: multicall3ABI,\n    functionName: \"tryAggregate\",\n    args: [false, aggregateCalls],\n  })) as { success: boolean; returnData: `0x${string}` }[];\n\n  return rawResults.map((raw, i) => {\n    if (!raw.success) {\n      return {\n        status: \"failure\" as const,\n        error: new Error(`multicall: call reverted (returnData: ${raw.returnData})`),\n      };\n    }\n\n    const call = calls[i];\n    if (\"callData\" in call) {\n      return { status: \"success\" as const, result: undefined };\n    }\n\n    try {\n      const decoded = decodeFunctionResult({\n        abi: call.abi,\n        functionName: call.functionName,\n        data: raw.returnData,\n      });\n      return { status: \"success\" as const, result: decoded };\n    } catch (err) {\n      return {\n        status: \"failure\" as const,\n        error: err instanceof Error ? err : new Error(String(err)),\n      };\n    }\n  });\n}\n"],"mappings":";AAAA,SAAS,oBAAoB,4BAA4B;AAQlD,IAAM,qBAAqB;AAclC,IAAM,gBAAgB;AAAA,EACpB;AAAA,IACE,QAAQ;AAAA,MACN,EAAE,MAAM,kBAAkB,MAAM,OAAO;AAAA,MACvC;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,YAAY;AAAA,UACV,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,UAClC,EAAE,MAAM,YAAY,MAAM,QAAQ;AAAA,QACpC;AAAA,MACF;AAAA,IACF;AAAA,IACA,MAAM;AAAA,IACN,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,YAAY;AAAA,UACV,EAAE,MAAM,WAAW,MAAM,OAAO;AAAA,UAChC,EAAE,MAAM,cAAc,MAAM,QAAQ;AAAA,QACtC;AAAA,MACF;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,IACjB,MAAM;AAAA,EACR;AACF;AAwCA,eAAsB,UACpB,cACA,OAC4B;AAC5B,QAAM,iBAAiB,MAAM,IAAI,UAAQ;AACvC,QAAI,cAAc,MAAM;AACtB,aAAO,EAAE,QAAQ,KAAK,SAAS,UAAU,KAAK,SAAS;AAAA,IACzD;AACA,UAAM,WAAW,mBAAmB;AAAA,MAClC,KAAK,KAAK;AAAA,MACV,cAAc,KAAK;AAAA,MACnB,MAAM,KAAK;AAAA,IACb,CAAC;AACD,WAAO,EAAE,QAAQ,KAAK,SAAS,SAAS;AAAA,EAC1C,CAAC;AAED,QAAM,aAAc,MAAM,aAAa;AAAA,IACrC,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,OAAO,cAAc;AAAA,EAC9B,CAAC;AAED,SAAO,WAAW,IAAI,CAAC,KAAK,MAAM;AAChC,QAAI,CAAC,IAAI,SAAS;AAChB,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,OAAO,IAAI,MAAM,yCAAyC,IAAI,UAAU,GAAG;AAAA,MAC7E;AAAA,IACF;AAEA,UAAM,OAAO,MAAM,CAAC;AACpB,QAAI,cAAc,MAAM;AACtB,aAAO,EAAE,QAAQ,WAAoB,QAAQ,OAAU;AAAA,IACzD;AAEA,QAAI;AACF,YAAM,UAAU,qBAAqB;AAAA,QACnC,KAAK,KAAK;AAAA,QACV,cAAc,KAAK;AAAA,QACnB,MAAM,IAAI;AAAA,MACZ,CAAC;AACD,aAAO,EAAE,QAAQ,WAAoB,QAAQ,QAAQ;AAAA,IACvD,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,OAAO,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC;AAAA,MAC3D;AAAA,IACF;AAAA,EACF,CAAC;AACH;","names":[]}