{"version":3,"sources":["../../src/sdk/common/ERC4337Utils.ts"],"sourcesContent":["import { Buffer } from 'buffer';\nimport { concat, decodeAbiParameters, encodeAbiParameters, Hex, keccak256, pad, parseAbiParameters, toHex } from 'viem';\nimport { hexlifyValue } from './utils/hexlify';\nimport { BaseAccountUserOperationStruct } from '../types/user-operation-types';\nimport { BigNumber, BigNumberish } from '../types/bignumber';\nimport { BytesLike } from '../types';\n\nexport interface UserOperation {\n  sender: string\n  nonce: BigNumberish\n  factory?: string\n  factoryData?: BytesLike\n  callData: BytesLike\n  callGasLimit: BigNumberish\n  verificationGasLimit: BigNumberish\n  preVerificationGas: BigNumberish\n  maxFeePerGas: BigNumberish\n  maxPriorityFeePerGas: BigNumberish\n  paymaster?: string\n  paymasterVerificationGasLimit?: BigNumberish\n  paymasterPostOpGasLimit?: BigNumberish\n  paymasterData?: BytesLike\n  signature: BytesLike\n}\n\n// reverse \"Deferrable\" or \"PromiseOrValue\" fields\nexport type NotPromise<T> = {\n  [P in keyof T]: Exclude<T[P], Promise<any>>\n}\n\n// TODO - test this on sepolia\n/**\n * pack the userOperation\n * @param op\n * @param forSignature \"true\" if the hash is needed to calculate the getUserOpHash()\n *  \"false\" to pack entire UserOp, for calculating the calldata cost of putting it on-chain.\n */\nexport function packUserOp(op1: UserOperation | NotPromise<BaseAccountUserOperationStruct>, forSignature = true): string {\n  let op: NotPromise<BaseAccountUserOperationStruct>;\n  if ('callGasLimit' in op1) {\n    op = packUserOpData(op1)\n  } else {\n    op = op1\n  }\n\n  if (forSignature) {\n\n    const packedUserOp = encodeAbiParameters(\n      parseAbiParameters('address, uint256, bytes32, bytes32, bytes32, uint256, bytes32, bytes32'),\n      [op.sender as Hex,\n      BigInt(op.nonce as Hex),\n      keccak256(op.initCode as Hex),\n      keccak256(op.callData as Hex),\n      op.accountGasLimits.toString() as Hex,\n      BigInt(op.preVerificationGas as Hex),\n      op.gasFees.toString() as Hex,\n      keccak256(op.paymasterAndData as Hex)]\n    );\n\n    return packedUserOp;\n  } else {\n    // for the purpose of calculating gas cost encode also signature (and no keccak of bytes)\n    const packedUserOp = encodeAbiParameters(\n      parseAbiParameters('address, uint256, bytes, bytes, bytes32, uint256, bytes32, bytes, bytes'),\n      [op.sender as Hex,\n      BigInt(op.nonce as Hex),\n      op.initCode as Hex,\n      op.callData as Hex,\n      op.accountGasLimits.toString() as Hex,\n      BigInt(op.preVerificationGas as Hex),\n      op.gasFees.toString() as Hex,\n      op.paymasterAndData as Hex,\n      op.signature as Hex]\n    );\n\n    return packedUserOp;\n  }\n}\n\nexport function packUint(high128: BigNumberish, low128: BigNumberish): string {\n  return pad(BigNumber.from(high128).shl(128).add(low128).toHexString() as Hex, { size: 32 })\n}\n\n// TODO - test this on sepolia\nexport function packPaymasterData(paymaster: string, paymasterVerificationGasLimit: BigNumberish, postOpGasLimit: BigNumberish, paymasterData?: BytesLike): BytesLike {\n  const paymasterAndData = paymasterData ? paymasterData : '0x';\n  return concat([\n    paymaster as Hex,\n    packUint(paymasterVerificationGasLimit, postOpGasLimit) as Hex,\n    paymasterAndData as Hex\n  ])\n}\n\n// TODO - test this on sepolia\nexport function packUserOpData(op: any): NotPromise<BaseAccountUserOperationStruct> {\n  let paymasterAndData: BytesLike\n  if (op.paymaster == null) {\n    paymasterAndData = '0x'\n  } else {\n    if (op.paymasterVerificationGasLimit == null || op.paymasterPostOpGasLimit == null) {\n      throw new Error('paymaster with no gas limits')\n    }\n    paymasterAndData = packPaymasterData(op.paymaster, op.paymasterVerificationGasLimit, op.paymasterPostOpGasLimit, op.paymasterData)\n  }\n\n  return {\n    sender: op.sender,\n    nonce: BigNumber.from(op.nonce).toHexString(),\n    initCode: op.factory == null ? '0x' : concat([op.factory, op.factoryData ?? '']),\n    callData: op.callData,\n    accountGasLimits: packUint(op.verificationGasLimit, op.callGasLimit),\n    preVerificationGas: BigNumber.from(op.preVerificationGas).toHexString(),\n    gasFees: packUint(op.maxPriorityFeePerGas, op.maxFeePerGas),\n    paymasterAndData,\n    signature: op.signature\n  }\n}\n\n/**\n * calculate the userOpHash of a given userOperation.\n * The userOpHash is a hash of all UserOperation fields, except the \"signature\" field.\n * The entryPoint uses this value in the emitted UserOperationEvent.\n * A wallet may use this value as the hash to sign (the SampleWallet uses this method)\n * @param op\n * @param entryPoint\n * @param chainId\n */\nexport function getUserOpHash(op: UserOperation, entryPoint: string, chainId: number): string {\n  const userOpHash = keccak256(packUserOp(op, true) as Hex);\n  //const enc = defaultAbiCoder.encode(['bytes32', 'address', 'uint256'], [userOpHash, entryPoint, chainId]);\n  const enc = encodeAbiParameters(parseAbiParameters('bytes32, address, uint256'), [userOpHash, entryPoint as Hex, BigInt(chainId)]);\n  return keccak256(enc as Hex);\n}\n\nconst ErrorSig = keccak256(Buffer.from('Error(string)')).slice(0, 10); // 0x08c379a0\nconst FailedOpSig = keccak256(Buffer.from('FailedOp(uint256,string)')).slice(0, 10); // 0x220266b6\n\ninterface DecodedError {\n  message: string;\n  opIndex?: number;\n}\n\n/**\n * decode bytes thrown by revert as Error(message) or FailedOp(opIndex,paymaster,message)\n */\n// TODO-Test decodeErrorReason\nexport function decodeErrorReason(error: string): DecodedError | undefined {\n  if (error.startsWith(ErrorSig)) {\n    const [message] = decodeAbiParameters(parseAbiParameters('string'), '0x' + error.substring(10) as Hex);\n    return { message };\n  } else if (error.startsWith(FailedOpSig)) {\n    const [opIndexBigInt, message] =  decodeAbiParameters(parseAbiParameters('uint256, string'), '0x' + error.substring(10) as Hex);\n    const formattedMessage = `FailedOp: ${message as string}`;\n    return {\n      message: formattedMessage,\n      opIndex: Number(opIndexBigInt),\n    };\n  }\n}\n\n/**\n * update thrown Error object with our custom FailedOp message, and re-throw it.\n * updated both \"message\" and inner encoded \"data\"\n * tested on geth, hardhat-node\n * usage: entryPoint.handleOps().catch(decodeError)\n */\nexport function rethrowError(e: any): any {\n  let error = e;\n  let parent = e;\n  if (error?.error != null) {\n    error = error.error;\n  }\n  while (error?.data != null) {\n    parent = error;\n    error = error.data;\n  }\n  const decoded = typeof error === 'string' && error.length > 2 ? decodeErrorReason(error) : undefined;\n  if (decoded != null) {\n    e.message = decoded.message;\n\n    if (decoded.opIndex != null) {\n      // helper for chai: convert our FailedOp error into \"Error(msg)\"\n      const errorWithMsg = concat([ErrorSig as Hex, encodeAbiParameters(parseAbiParameters('string'), [decoded.message]) as Hex]);\n      // modify in-place the error object:\n      parent.data = errorWithMsg;\n    }\n  }\n  throw e;\n}\n\n/**\n * hexlify all members of object, recursively\n * @param obj\n */\nexport function deepHexlify(obj: any): any {\n  if (typeof obj === 'function') {\n    return undefined;\n  }\n  if (obj == null || typeof obj === 'string' || typeof obj === 'boolean') {\n    return obj;\n  } else if (obj._isBigNumber != null || typeof obj !== 'object') {\n    const hexlified = hexlifyValue(obj).replace(/^0x0/, '0x');\n    return hexlified;\n  }\n  if (Array.isArray(obj)) {\n    return obj.map((member) => deepHexlify(member));\n  }\n  return Object.keys(obj).reduce(\n    (set, key) => ({\n      ...set,\n      [key]: deepHexlify(obj[key]),\n    }),\n    {},\n  );\n}\n\n// resolve all property and hexlify.\n// (UserOpMethodHandler receives data from the network, so we need to pack our generated values)\nexport function resolveHexlify(a: any): any {\n  return deepHexlify(a);\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA,SAAS,cAAc;AAqChB,SAAS,WAAW,KAAiE,eAAe,MAAc;AACvH,MAAI;AACJ,MAAI,kBAAkB,KAAK;AACzB,SAAK,eAAe,GAAG;AAAA,EACzB,OAAO;AACL,SAAK;AAAA,EACP;AAEA,MAAI,cAAc;AAEhB,UAAM,eAAe;AAAA,MACnB,mBAAmB,wEAAwE;AAAA,MAC3F;AAAA,QAAC,GAAG;AAAA,QACJ,OAAO,GAAG,KAAY;AAAA,QACtB,UAAU,GAAG,QAAe;AAAA,QAC5B,UAAU,GAAG,QAAe;AAAA,QAC5B,GAAG,iBAAiB,SAAS;AAAA,QAC7B,OAAO,GAAG,kBAAyB;AAAA,QACnC,GAAG,QAAQ,SAAS;AAAA,QACpB,UAAU,GAAG,gBAAuB;AAAA,MAAC;AAAA,IACvC;AAEA,WAAO;AAAA,EACT,OAAO;AAEL,UAAM,eAAe;AAAA,MACnB,mBAAmB,yEAAyE;AAAA,MAC5F;AAAA,QAAC,GAAG;AAAA,QACJ,OAAO,GAAG,KAAY;AAAA,QACtB,GAAG;AAAA,QACH,GAAG;AAAA,QACH,GAAG,iBAAiB,SAAS;AAAA,QAC7B,OAAO,GAAG,kBAAyB;AAAA,QACnC,GAAG,QAAQ,SAAS;AAAA,QACpB,GAAG;AAAA,QACH,GAAG;AAAA,MAAgB;AAAA,IACrB;AAEA,WAAO;AAAA,EACT;AACF;AAEO,SAAS,SAAS,SAAuB,QAA8B;AAC5E,SAAO,IAAI,UAAU,KAAK,OAAO,EAAE,IAAI,GAAG,EAAE,IAAI,MAAM,EAAE,YAAY,GAAU,EAAE,MAAM,GAAG,CAAC;AAC5F;AAGO,SAAS,kBAAkB,WAAmB,+BAA6C,gBAA8B,eAAsC;AACpK,QAAM,mBAAmB,gBAAgB,gBAAgB;AACzD,SAAO,OAAO;AAAA,IACZ;AAAA,IACA,SAAS,+BAA+B,cAAc;AAAA,IACtD;AAAA,EACF,CAAC;AACH;AAGO,SAAS,eAAe,IAAqD;AAClF,MAAI;AACJ,MAAI,GAAG,aAAa,MAAM;AACxB,uBAAmB;AAAA,EACrB,OAAO;AACL,QAAI,GAAG,iCAAiC,QAAQ,GAAG,2BAA2B,MAAM;AAClF,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAChD;AACA,uBAAmB,kBAAkB,GAAG,WAAW,GAAG,+BAA+B,GAAG,yBAAyB,GAAG,aAAa;AAAA,EACnI;AAEA,SAAO;AAAA,IACL,QAAQ,GAAG;AAAA,IACX,OAAO,UAAU,KAAK,GAAG,KAAK,EAAE,YAAY;AAAA,IAC5C,UAAU,GAAG,WAAW,OAAO,OAAO,OAAO,CAAC,GAAG,SAAS,GAAG,eAAe,EAAE,CAAC;AAAA,IAC/E,UAAU,GAAG;AAAA,IACb,kBAAkB,SAAS,GAAG,sBAAsB,GAAG,YAAY;AAAA,IACnE,oBAAoB,UAAU,KAAK,GAAG,kBAAkB,EAAE,YAAY;AAAA,IACtE,SAAS,SAAS,GAAG,sBAAsB,GAAG,YAAY;AAAA,IAC1D;AAAA,IACA,WAAW,GAAG;AAAA,EAChB;AACF;AAWO,SAAS,cAAc,IAAmB,YAAoB,SAAyB;AAC5F,QAAM,aAAa,UAAU,WAAW,IAAI,IAAI,CAAQ;AAExD,QAAM,MAAM,oBAAoB,mBAAmB,2BAA2B,GAAG,CAAC,YAAY,YAAmB,OAAO,OAAO,CAAC,CAAC;AACjI,SAAO,UAAU,GAAU;AAC7B;AAEA,IAAM,WAAW,UAAU,OAAO,KAAK,eAAe,CAAC,EAAE,MAAM,GAAG,EAAE;AACpE,IAAM,cAAc,UAAU,OAAO,KAAK,0BAA0B,CAAC,EAAE,MAAM,GAAG,EAAE;AAW3E,SAAS,kBAAkB,OAAyC;AACzE,MAAI,MAAM,WAAW,QAAQ,GAAG;AAC9B,UAAM,CAAC,OAAO,IAAI,oBAAoB,mBAAmB,QAAQ,GAAG,OAAO,MAAM,UAAU,EAAE,CAAQ;AACrG,WAAO,EAAE,QAAQ;AAAA,EACnB,WAAW,MAAM,WAAW,WAAW,GAAG;AACxC,UAAM,CAAC,eAAe,OAAO,IAAK,oBAAoB,mBAAmB,iBAAiB,GAAG,OAAO,MAAM,UAAU,EAAE,CAAQ;AAC9H,UAAM,mBAAmB,aAAa,OAAiB;AACvD,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAS,OAAO,aAAa;AAAA,IAC/B;AAAA,EACF;AACF;AAQO,SAAS,aAAa,GAAa;AACxC,MAAI,QAAQ;AACZ,MAAI,SAAS;AACb,MAAI,OAAO,SAAS,MAAM;AACxB,YAAQ,MAAM;AAAA,EAChB;AACA,SAAO,OAAO,QAAQ,MAAM;AAC1B,aAAS;AACT,YAAQ,MAAM;AAAA,EAChB;AACA,QAAM,UAAU,OAAO,UAAU,YAAY,MAAM,SAAS,IAAI,kBAAkB,KAAK,IAAI;AAC3F,MAAI,WAAW,MAAM;AACnB,MAAE,UAAU,QAAQ;AAEpB,QAAI,QAAQ,WAAW,MAAM;AAE3B,YAAM,eAAe,OAAO,CAAC,UAAiB,oBAAoB,mBAAmB,QAAQ,GAAG,CAAC,QAAQ,OAAO,CAAC,CAAQ,CAAC;AAE1H,aAAO,OAAO;AAAA,IAChB;AAAA,EACF;AACA,QAAM;AACR;AAMO,SAAS,YAAY,KAAe;AACzC,MAAI,OAAO,QAAQ,YAAY;AAC7B,WAAO;AAAA,EACT;AACA,MAAI,OAAO,QAAQ,OAAO,QAAQ,YAAY,OAAO,QAAQ,WAAW;AACtE,WAAO;AAAA,EACT,WAAW,IAAI,gBAAgB,QAAQ,OAAO,QAAQ,UAAU;AAC9D,UAAM,YAAY,aAAa,GAAG,EAAE,QAAQ,QAAQ,IAAI;AACxD,WAAO;AAAA,EACT;AACA,MAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,WAAO,IAAI,IAAI,CAAC,WAAW,YAAY,MAAM,CAAC;AAAA,EAChD;AACA,SAAO,OAAO,KAAK,GAAG,EAAE;AAAA,IACtB,CAAC,KAAK,SAAS;AAAA,MACb,GAAG;AAAA,MACH,CAAC,GAAG,GAAG,YAAY,IAAI,GAAG,CAAC;AAAA,IAC7B;AAAA,IACA,CAAC;AAAA,EACH;AACF;AAIO,SAAS,eAAe,GAAa;AAC1C,SAAO,YAAY,CAAC;AACtB;","names":[]}