{"version":3,"sources":["../../src/sdk/base/EtherspotWalletAPI.ts","../../src/sdk/sdk.ts","../../src/sdk/index.ts","../../src/sdk/base/BaseAccountAPI.ts"],"sourcesContent":["import { bootstrapAbi, CALL_TYPE, entryPointAbi, EXEC_TYPE, factoryAbi, getExecuteMode } from '../common';\nimport { encodeFunctionData, parseAbi, encodeAbiParameters, parseAbiParameters, type WalletClient, type PublicClient, toBytes, concat, getAddress, pad, toHex, isBytes, Account, Hex } from 'viem';\nimport { accountAbi } from '../common';\nimport { BigNumber, BigNumberish } from '../types/bignumber';\nimport { BaseAccountAPI, BaseApiParams } from './BaseAccountAPI';\nimport { BootstrapConfig, makeBootstrapConfig, _makeBootstrapConfig } from './Bootstrap';\nimport { Networks, DEFAULT_MULTIPLE_OWNER_ECDSA_VALIDATOR_ADDRESS } from '../network/constants';\n\nconst ADDRESS_ZERO = getAddress(\"0x0000000000000000000000000000000000000000\");\n\n/**\n * constructor params, added no top of base params:\n * @param owner the signer object for the account owner\n * @param factoryAddress address of contract \"factory\" to deploy new contracts (not needed if account already deployed)\n * @param index nonce value used when creating multiple accounts for the same owner\n */\nexport interface EtherspotWalletApiParams extends BaseApiParams {\n  factoryAddress?: string;\n  index?: number;\n  chainId: number;\n  etherspotWalletAddress?: string;\n}\n\n/**\n * An implementation of the BaseAccountAPI using the EtherspotWallet contract.\n * - contract deployer gets \"entrypoint\", \"owner\" addresses and \"index\" nonce\n * - owner signs requests using normal \"Ethereum Signed Message\" (ether's signer.signMessage())\n * - nonce method is \"nonce()\"\n * - execute method is \"execFromEntryPoint()\"\n */\nexport class EtherspotWalletAPI extends BaseAccountAPI {\n  index: number;\n  accountAddress?: string;\n  bootstrapAddress?: string;\n  multipleOwnerECDSAValidatorAddress?: string;\n  eoaAddress: Hex;\n\n  constructor(params: EtherspotWalletApiParams) {\n    super(params);\n    this.index = params.index ?? 0;\n    this.multipleOwnerECDSAValidatorAddress = Networks[params.chainId]?.contracts?.multipleOwnerECDSAValidator ?? DEFAULT_MULTIPLE_OWNER_ECDSA_VALIDATOR_ADDRESS;\n  }\n\n  getEOAAddress(): Hex {\n    return this.externalViemAccount.address\n  }\n\n  /**\n * return the value to put into the \"initCode\" field, if the account is not yet deployed.\n * this value holds the \"factory\" address, followed by this account's information\n */\n  async getAccountInitCode(): Promise<string> {\n    if (this.factoryAddress == null || this.factoryAddress == '') {\n      throw new Error('no factory to get initCode');\n    }\n\n    const initCode = await this.getInitCodeData();\n    const salt = pad(toHex(this.index), { size: 32 });\n\n    const functionData = encodeFunctionData({\n      functionName: 'createAccount',\n      abi: parseAbi(factoryAbi),\n      args: [\n        salt,\n        initCode,\n      ],\n    })\n\n    return concat([\n      this.factoryAddress as Hex,\n      functionData,\n    ]);\n  }\n\n  async getInitCodeData(): Promise<string> {\n    const validators: BootstrapConfig[] = makeBootstrapConfig(this.multipleOwnerECDSAValidatorAddress, '0x');\n    const executors: BootstrapConfig[] = makeBootstrapConfig(ADDRESS_ZERO, '0x');\n    const hook: BootstrapConfig = _makeBootstrapConfig(ADDRESS_ZERO, '0x');\n    const fallbacks: BootstrapConfig[] = makeBootstrapConfig(ADDRESS_ZERO, '0x');\n\n    const initMSAData = encodeFunctionData({\n      functionName: 'initMSA',\n      abi: parseAbi(bootstrapAbi),\n      args: [validators, executors, hook, fallbacks],\n    });\n    const eoaAddress = await this.getEOAAddress();\n\n    const initCode = encodeAbiParameters(\n      parseAbiParameters('address, address, bytes'),\n      [eoaAddress, this.bootstrapAddress as Hex, initMSAData]\n    )\n\n    return initCode;\n  }\n\n  async getNonce(key: BigNumber = BigNumber.from(0)): Promise<BigNumber> {\n    const etherspotWalletAddress = await this.getEtherspotWalletAddress();\n    const dummyKey = key.eq(0)\n      ? getAddress(this.multipleOwnerECDSAValidatorAddress) + \"00000000\"\n      : getAddress(key.toHexString()) + \"00000000\";\n\n    const nonceResponse = await this.publicClient.readContract({\n      address: this.entryPointAddress as Hex,\n      abi: parseAbi(entryPointAbi),\n      functionName: 'getNonce',\n      args: [etherspotWalletAddress, BigInt(dummyKey)]\n    });\n    return nonceResponse as BigNumber;\n  }\n\n\n  /**\n   * encode a method call from entryPoint to our contract\n   * @param target\n   * @param value\n   * @param data\n   */\n  async encodeExecute(target: string, value: BigNumberish, data: string): Promise<string> {\n    const executeMode = getExecuteMode({\n      callType: CALL_TYPE.SINGLE,\n      execType: EXEC_TYPE.DEFAULT\n    });\n\n    // Assuming toHex is a function that accepts string | number | bigint | boolean | Uint8Array\n    // Convert BigNumberish to a string if it's a BigNumber\n    // Convert BigNumberish or Bytes to a compatible type\n    let valueToProcess: string | number | bigint | boolean | Uint8Array;\n\n    if (BigNumber.isBigNumber(value)) {\n      valueToProcess = value.toString(); // Convert BigNumber to string\n    } else if (isBytes(value)) {\n      valueToProcess = new Uint8Array(value); // Convert Bytes to Uint8Array\n    } else {\n      // Here, TypeScript is unsure about the type of `value`\n      // You need to ensure `value` is of a type compatible with `valueToProcess`\n      // If `value` can only be string, number, bigint, boolean, or Uint8Array, this assignment is safe\n      // If `value` can be of other types (like Bytes), you need an explicit conversion or handling here\n      // For example, if there's a chance `value` is still `Bytes`, you could handle it like so:\n      if (typeof value === 'object' && value !== null && 'length' in value) {\n        // Assuming this condition is sufficient to identify Bytes-like objects\n        // Convert it to Uint8Array\n        valueToProcess = new Uint8Array(Object.values(value));\n      } else {\n        valueToProcess = value as string | number | bigint | boolean | Uint8Array;\n      }\n    }\n\n    const calldata = concat([\n      target as Hex,\n      pad(toHex(valueToProcess), { size: 32 }) as Hex,\n      data as Hex\n    ]);\n\n    return encodeFunctionData({\n      functionName: 'execute',\n      abi: parseAbi(accountAbi),\n      args: [executeMode, calldata],\n    });\n  }\n\n  async encodeBatch(targets: string[], values: BigNumberish[], datas: string[]): Promise<string> {\n\n    const executeMode = getExecuteMode({\n      callType: CALL_TYPE.BATCH,\n      execType: EXEC_TYPE.DEFAULT\n    });\n\n    const result = targets.map((target, index) => ({\n      target: target as Hex,\n      value: values[index],\n      callData: datas[index] as Hex\n    }));\n\n    const convertedResult = result.map(item => ({\n      ...item,\n      // Convert `value` from BigNumberish to bigint\n      value: typeof item.value === 'bigint' ? item.value : BigInt(item.value.toString()),\n    }));\n\n    //TODO-Test-LibraryFix identify the syntax for viem to pass array of tuple\n    // const calldata = ethers.utils.defaultAbiCoder.encode(\n    //   [\"tuple(address target,uint256 value,bytes callData)[]\"],\n    //   [result]\n    // );\n\n    const calldata = encodeAbiParameters(\n      parseAbiParameters('(address target,uint256 value,bytes callData)[]'),\n      [convertedResult]\n    )\n\n    return encodeFunctionData({\n      functionName: 'execute',\n      abi: parseAbi(accountAbi),\n      args: [executeMode, calldata],\n    });\n  }\n\n}\n","import { Networks } from './network/constants';\nimport { Account, formatEther, http, type PublicClient } from 'viem';\nimport { getPublicClient, getViemAddress } from './common/utils/viem-utils';\nimport { BigNumber, BigNumberish } from './types/bignumber';\nimport { ErrorHandler } from './error-handler/errorHandler.service';\nimport { EtherspotBundler } from './bundler/providers/EtherspotBundler';\nimport { Factory, PaymasterApi, SdkOptions } from \"./interfaces\";\nimport { HttpRpcClient } from \"./base/HttpRpcClient\";\nimport { getGasFee, UserOperation } from \"./common\";\nimport { TransactionDetailsForUserOp, TransactionGasInfoForUserOp } from './base/TransactionDetailsForUserOp';\nimport { EtherspotWalletAPI } from \"./base/EtherspotWalletAPI\";\nimport { VerifyingPaymasterAPI } from \"./base/VerifyingPaymasterAPI\";\nimport { BatchUserOpsRequest, UserOpsRequest } from './common/interfaces';\nimport { isAValidSessionKey } from './session-keys/validate-session-key';\nimport { signUserOpWithSessionKey } from './session-keys/sign-userop';\nimport { getOnchainSessionKeyData, isSessionKeyLiveOnChain } from './session-keys/erc20-sessionkey-onchain';\nimport { SessionKeyOnChainData } from './types';\nimport { isModuleInstalled, MODULE_TYPE } from './session-keys/module-query';\n\n/**\n * RemoteSigner-Sdk\n *\n * @category RemoteSigner-Sdk\n */\nexport class RemoteSignerSdk {\n  externalViemAccount: Account;\n  etherspotWalletAddress: string;\n  chainId: number;\n  index: number;\n  apiKey: string;\n  sessionKey: string;\n  factoryUsed: string;\n  providerUrl: string;\n  publicClient: PublicClient;\n  etherspotWallet: EtherspotWalletAPI;\n  bundler: HttpRpcClient;\n  erc20SessionKeyValidator: string;\n\n  private userOpsBatch: BatchUserOpsRequest = { to: [], data: [], value: [] };\n\n  private constructor(externalViemAccount: Account, sdkOptions: SdkOptions) {\n    const { index, etherspotWalletAddress, chainId, apiKey, sessionKey, rpcProviderUrl } = sdkOptions;\n\n    if (!externalViemAccount) throw new Error('EOAAddress - ViemAccount object is required');\n    this.externalViemAccount = externalViemAccount;\n\n    if (!etherspotWalletAddress) throw new Error('etherspotWalletAddress is required');\n    this.etherspotWalletAddress = etherspotWalletAddress;\n\n    if (!chainId || chainId <= 0) throw new Error('chainId is required');\n\n    if (!Networks[chainId]) {\n      throw new Error('ChainId not found in the Networks');\n    }\n\n    this.chainId = chainId;\n\n    this.index = index ?? 0;\n\n    if (!apiKey) throw new Error('apiKey is required');\n    this.apiKey = apiKey;\n\n    if (!sessionKey) throw new Error('sessionKey is required');\n    this.sessionKey = sessionKey;\n\n    if (!sdkOptions.bundlerProvider) {\n      sdkOptions.bundlerProvider = new EtherspotBundler(chainId);\n    }\n\n    this.factoryUsed = sdkOptions.factoryWallet ?? Factory.ETHERSPOT;\n    let viemClientUrl = '';\n\n    if (rpcProviderUrl) {\n      viemClientUrl = rpcProviderUrl;\n    } else {\n      viemClientUrl = sdkOptions.bundlerProvider.url;\n    }\n\n    this.providerUrl = viemClientUrl;\n\n    this.publicClient = getPublicClient({\n      chainId: chainId,\n      transport: http(viemClientUrl)\n    }) as PublicClient;\n\n    let entryPointAddress = Networks[chainId].contracts.entryPoint;\n    if (Networks[chainId].contracts.walletFactory == '') throw new Error('The selected factory is not deployed in the selected chain_id');\n    let walletFactoryAddress = Networks[chainId].contracts.walletFactory;\n\n    if (sdkOptions.entryPointAddress) entryPointAddress = sdkOptions.entryPointAddress;\n    if (sdkOptions.walletFactoryAddress) walletFactoryAddress = sdkOptions.walletFactoryAddress;\n\n    if (entryPointAddress == '') throw new Error('entryPointAddress not set on the given chain_id');\n    if (walletFactoryAddress == '') throw new Error('walletFactoryAddress not set on the given chain_id');\n    this.etherspotWallet = new EtherspotWalletAPI({\n      sdkOptions,\n      entryPointAddress,\n      factoryAddress: walletFactoryAddress,\n      etherspotWalletAddress: etherspotWalletAddress,\n      externalViemAccount: this.externalViemAccount,\n      publicClient: this.publicClient,\n      index: this.index,\n      chainId: this.chainId,\n    });\n    this.bundler = new HttpRpcClient(sdkOptions.bundlerProvider.url, entryPointAddress, chainId, this.publicClient);\n  }\n\n  private async initialize(sdkOptions: SdkOptions): Promise<void> {\n\n    const isPhantom = await this.etherspotWallet.checkAccountPhantom();\n    if (isPhantom) {\n      throw new Error(`EtherspotWallet: ${this.etherspotWalletAddress} is not deployed/initialized on chain: ${this.chainId}`);\n    }\n\n    const erc20SessionKeyValidator = await this.getERC20SessionKeyValidator();\n    const isModuleInstalledIndicator = await isModuleInstalled(\n      this.publicClient,\n      this.etherspotWalletAddress,\n      MODULE_TYPE.VALIDATOR,\n      erc20SessionKeyValidator);\n\n    if(!isModuleInstalledIndicator) {\n      throw new Error(`Module: ${erc20SessionKeyValidator} is not installed on etherspotWalletAddress: ${this.etherspotWalletAddress} on chainId: ${Networks[this.chainId].chain.name}`);\n    } \n\n    const sessionKeyExists = await isAValidSessionKey(this.publicClient, erc20SessionKeyValidator, this.etherspotWalletAddress, this.chainId, this.apiKey, this.sessionKey);\n\n    if (!sessionKeyExists) {\n      throw new Error(`Sessionkey: ${sdkOptions.sessionKey} is invalid for etherspotWalletAddress: ${this.etherspotWalletAddress} and apiKey: ${this.apiKey} on chainId: ${Networks[this.chainId].chain.name}`);\n    }\n  }\n\n  private async getERC20SessionKeyValidator(): Promise<string> {\n    if (this.erc20SessionKeyValidator) {\n      return this.erc20SessionKeyValidator;\n    }\n\n    this.erc20SessionKeyValidator = Networks[this.chainId]?.contracts?.erc20SessionKeyValidator;\n\n    if (!this.erc20SessionKeyValidator) {\n      throw new Error('erc20SessionKeyValidator not found in the Networks for chainId: `' + this.chainId + '`');\n    }\n\n    return this.erc20SessionKeyValidator;\n  }\n\n  static async create(externalViemAccount: Account, sdkOptions: SdkOptions): Promise<RemoteSignerSdk> {\n    const instance = new RemoteSignerSdk(externalViemAccount, sdkOptions);\n    await instance.initialize(sdkOptions);\n    return instance;\n  }\n\n  getPublicClient(): PublicClient {\n    return this.publicClient;\n  }\n\n  getProviderUrl(): string {\n    return this.providerUrl;\n  }\n\n  async validateSessionKey(): Promise<boolean> {\n    const sessionKeyValidator = await this.getERC20SessionKeyValidator();\n    return isAValidSessionKey(\n      this.publicClient,\n      sessionKeyValidator,\n      this.etherspotWalletAddress,\n      this.chainId,\n      this.apiKey,\n      this.sessionKey);\n  }\n\n  async isSessionKeyLiveOnChain(): Promise<boolean> {\n    const sessionKeyValidator = await this.getERC20SessionKeyValidator();\n    return isSessionKeyLiveOnChain(\n      this.etherspotWalletAddress,\n      this.publicClient,\n      sessionKeyValidator,\n      this.sessionKey);\n  }\n\n  async getSessionKeyOnChainData(): Promise<SessionKeyOnChainData> {\n    const sessionKeyValidator = await this.getERC20SessionKeyValidator();\n    return getOnchainSessionKeyData(\n      this.etherspotWalletAddress,\n      this.publicClient,\n      sessionKeyValidator,\n      this.sessionKey);\n  }\n\n  async signUserOp(userOp: UserOperation): Promise<UserOperation> {\n\n    if (!this.etherspotWallet.etherspotWalletAddress) {\n      throw new ErrorHandler('EtherspotWalletAddress not found', 500);\n    }\n\n    const sessionSignedUserOp = await signUserOpWithSessionKey(\n      this.etherspotWallet.etherspotWalletAddress,\n      this.chainId,\n      this.apiKey,\n      this.sessionKey,\n      userOp\n    );\n\n    return sessionSignedUserOp;\n  }\n\n  async getCounterFactualAddress(): Promise<string> {\n    return this.etherspotWallet.getEtherspotWalletAddress();\n  }\n\n  async estimate(params: {\n    paymasterDetails?: PaymasterApi,\n    gasDetails?: TransactionGasInfoForUserOp,\n    callGasLimit?: BigNumberish,\n    nonceKey?: BigNumber\n  } = { nonceKey: BigNumber.from(0) }): Promise<any> {\n    const { paymasterDetails, gasDetails, callGasLimit, nonceKey } = params;\n    const dummySignature = \"0xfffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c\";\n\n    if (this.userOpsBatch.to.length < 1) {\n      throw new ErrorHandler('cannot sign empty transaction batch', 1);\n    }\n\n    if (paymasterDetails?.url) {\n      const paymasterAPI = new VerifyingPaymasterAPI(paymasterDetails.url, this.etherspotWallet.entryPointAddress, paymasterDetails.context ?? {})\n      this.etherspotWallet.setPaymasterApi(paymasterAPI)\n    } else this.etherspotWallet.setPaymasterApi(null);\n\n    const tx: TransactionDetailsForUserOp = {\n      target: this.userOpsBatch.to,\n      values: this.userOpsBatch.value,\n      data: this.userOpsBatch.data,\n      dummySignature: dummySignature,\n      ...gasDetails,\n    }\n\n    const gasInfo = await this.getGasFee();\n\n    const partialtx = await this.etherspotWallet.createUnsignedUserOp({\n      ...tx,\n      maxFeePerGas: gasInfo.maxFeePerGas,\n      maxPriorityFeePerGas: gasInfo.maxPriorityFeePerGas,\n    }, nonceKey);\n\n    if (callGasLimit) {\n      partialtx.callGasLimit = BigNumber.from(callGasLimit).toHexString();\n    }\n\n    const bundlerGasEstimate = await this.bundler.getVerificationGasInfo(partialtx);\n\n    // if user has specified the gas prices then use them\n    if (gasDetails?.maxFeePerGas && gasDetails?.maxPriorityFeePerGas) {\n      partialtx.maxFeePerGas = gasDetails.maxFeePerGas;\n      partialtx.maxPriorityFeePerGas = gasDetails.maxPriorityFeePerGas;\n    }\n    // if estimation has gas prices use them, otherwise fetch them in a separate call\n    else if (bundlerGasEstimate.maxFeePerGas && bundlerGasEstimate.maxPriorityFeePerGas) {\n      partialtx.maxFeePerGas = bundlerGasEstimate.maxFeePerGas;\n      partialtx.maxPriorityFeePerGas = bundlerGasEstimate.maxPriorityFeePerGas;\n    } else {\n      const gas = await this.getGasFee();\n      partialtx.maxFeePerGas = gas.maxFeePerGas;\n      partialtx.maxPriorityFeePerGas = gas.maxPriorityFeePerGas;\n    }\n\n    if (bundlerGasEstimate.preVerificationGas) {\n      partialtx.preVerificationGas = BigNumber.from(bundlerGasEstimate.preVerificationGas);\n      partialtx.verificationGasLimit = BigNumber.from(bundlerGasEstimate.verificationGasLimit ?? bundlerGasEstimate.verificationGas);\n      const expectedCallGasLimit = BigNumber.from(bundlerGasEstimate.callGasLimit);\n      if (!callGasLimit)\n        partialtx.callGasLimit = expectedCallGasLimit;\n      else if (BigNumber.from(callGasLimit).lt(expectedCallGasLimit))\n        throw new ErrorHandler(`CallGasLimit is too low. Expected atleast ${expectedCallGasLimit.toString()}`);\n    }\n\n    return partialtx;\n\n  }\n\n  async send(signedUserOp: any) {\n    return this.bundler.sendUserOpToBundler(signedUserOp);\n  }\n\n  async getGasFee() {\n    const version = await this.bundler.getBundlerVersion();\n    if (version && version.includes('skandha'))\n      return this.bundler.getSkandhaGasPrice();\n    return getGasFee(this.publicClient);\n  }\n\n  async getNativeBalance() {\n    const balance = await this.publicClient.getBalance({ address: getViemAddress(this.etherspotWallet.accountAddress) });\n    return formatEther(balance);\n  }\n\n  async getUserOpReceipt(userOpHash: string) {\n    //return this.bundler.getUserOpsReceipt(userOpHash);\n    return await this.etherspotWallet.getUserOpReceipt(userOpHash);\n  }\n\n  async getUserOpHash(userOp: UserOperation) {\n    return this.etherspotWallet.getUserOpHash(userOp);\n  }\n\n  async addUserOpsToBatch(\n    tx: UserOpsRequest,\n  ): Promise<BatchUserOpsRequest> {\n    if (!tx.data && !tx.value) throw new ErrorHandler('Data and Value both cannot be empty', 1);\n    this.userOpsBatch.to.push(tx.to);\n    this.userOpsBatch.value.push(tx.value ?? BigNumber.from(0));\n    this.userOpsBatch.data.push(tx.data ?? '0x');\n    return this.userOpsBatch;\n  }\n\n  async clearUserOpsFromBatch(): Promise<void> {\n    this.userOpsBatch.to = [];\n    this.userOpsBatch.data = [];\n    this.userOpsBatch.value = [];\n  }\n\n  async totalGasEstimated(userOp: UserOperation): Promise<BigNumber> {\n    const callGasLimit = BigNumber.from(await userOp.callGasLimit);\n    const verificationGasLimit = BigNumber.from(await userOp.verificationGasLimit);\n    const preVerificationGas = BigNumber.from(await userOp.preVerificationGas);\n    return callGasLimit.add(verificationGasLimit).add(preVerificationGas);\n  }\n}\n","import { RemoteSignerSdk } from './sdk';\n\nexport * from './dto';\nexport * from './interfaces';\nexport * from './network';\nexport * from './bundler';\nexport * from './common';\nexport * from './error-handler';\nexport * from './session-keys';\nexport * from './remote-signer';\nexport * from './types';\n\nexport { RemoteSignerSdk };\nexport default RemoteSignerSdk;","import { TransactionDetailsForUserOp } from './TransactionDetailsForUserOp';\nimport { PaymasterAPI } from './PaymasterAPI';\nimport { getUserOpHash, NotPromise, packUserOp, UserOperation } from '../common';\nimport { calcPreVerificationGas, GasOverheads } from './calcPreVerificationGas';\nimport { Factory, SdkOptions, SignMessageDto, validateDto } from '../';\nimport { PaymasterResponse } from './VerifyingPaymasterAPI';\nimport { Account, Hex, parseAbi, parseAbiItem, PublicClient, TypedDataParameter, WalletClient } from 'viem';\nimport { entryPointAbi } from '../common/abis';\nimport { resolveProperties, Result } from '../common/utils';\nimport { BaseAccountUserOperationStruct, FeeData } from '../types/user-operation-types';\nimport { BigNumber, BigNumberish } from '../types/bignumber';\n\nexport interface BaseApiParams {\n  entryPointAddress: string;\n  etherspotWalletAddress?: string;\n  overheads?: Partial<GasOverheads>;\n  factoryAddress?: string;\n  sdkOptions?: SdkOptions;\n  walletClient?: WalletClient;\n  publicClient?: PublicClient;\n  externalViemAccount?: Account;\n}\n\nexport interface UserOpResult {\n  transactionHash: string;\n  success: boolean;\n}\n\n/**\n * Base class for all Smart Wallet ERC-4337 Clients to implement.\n * Subclass should inherit 5 methods to support a specific wallet contract:\n *\n * - getAccountInitCode - return the value to put into the \"initCode\" field, if the account is not yet deployed. should create the account instance using a factory contract.\n * - getNonce - return current account's nonce value\n * - encodeExecute - encode the call from entryPoint through our account to the target contract.\n * - signUserOpHash - sign the hash of a UserOp.\n *\n * The user can use the following APIs:\n * - createUnsignedUserOp - given \"target\" and \"calldata\", fill userOp to perform that operation from the account.\n * - createSignedUserOp - helper to call the above createUnsignedUserOp, and then extract the userOpHash and sign it\n */\nexport abstract class BaseAccountAPI {\n  private senderAddress!: string;\n  private isPhantom = true;\n\n  overheads?: Partial<GasOverheads>;\n  entryPointAddress: string;\n  etherspotWalletAddress?: string;\n  paymasterAPI?: PaymasterAPI;\n  factoryUsed: Factory;\n  factoryAddress?: string;\n  externalViemAccount: Account;\n  walletClient: WalletClient;\n  publicClient: PublicClient;\n\n  /**\n   * base constructor.\n   * subclass SHOULD add parameters that define the owner (signer) of this wallet\n   */\n  constructor(params: BaseApiParams) {\n\n    const sdkOptions = params.sdkOptions;\n\n    const {\n      chainId, //\n      rpcProviderUrl,\n      factoryWallet,\n      bundlerProvider,\n    } = sdkOptions;\n\n    this.factoryUsed = factoryWallet;\n\n    // super();\n    this.overheads = params.overheads;\n    this.entryPointAddress = params.entryPointAddress;\n    this.externalViemAccount = params.externalViemAccount;\n    this.etherspotWalletAddress = params.etherspotWalletAddress;\n    this.factoryAddress = params.factoryAddress;\n    this.walletClient = params.walletClient;\n    this.publicClient = params.publicClient;\n  }\n\n  // sdk\n\n  // wallet\n\n  /**\n   * signs message\n   * @param dto\n   * @return Promise<string>\n   */\n  async signMessage(dto: SignMessageDto): Promise<string> {\n    const { message } = await validateDto(dto, SignMessageDto);\n\n    await this.require({\n      network: false,\n    });\n\n    return this.walletClient.signMessage(\n      {\n        account: this.externalViemAccount,\n        message: message as Hex\n      });\n  }\n\n  async setPaymasterApi(paymaster: PaymasterAPI | null) {\n    this.paymasterAPI = paymaster;\n  }\n\n\n  // private\n\n\n  async require(\n    options: {\n      network?: boolean;\n      wallet?: boolean;\n    } = {},\n  ): Promise<void> {\n    options = {\n      network: true,\n      wallet: true,\n      ...options,\n    };\n  }\n\n  async init(): Promise<this> {\n    // check EntryPoint is deployed at given address\n    if ((await this.publicClient.getCode({ address: this.entryPointAddress as Hex })) === '0x') {\n      throw new Error(`entryPoint not deployed at ${this.entryPointAddress}`);\n    }\n\n    await this.getEtherspotWalletAddress();\n    return this;\n  }\n\n  /**\n   * return the value to put into the \"initCode\" field, if the contract is not yet deployed.\n   * this value holds the \"factory\" address, followed by this account's information\n   */\n  protected abstract getAccountInitCode(): Promise<string>;\n\n  /**\n   * return current account's nonce.\n   */\n  protected abstract getNonce(key?: BigNumber): Promise<BigNumber>;\n\n  /**\n   * encode the call from entryPoint through our account to the target contract.\n   * @param target\n   * @param value\n   * @param data\n   */\n  protected abstract encodeExecute(target: string, value: BigNumberish, data: string): Promise<string>;\n\n  protected abstract encodeBatch(targets: string[], values: BigNumberish[], datas: string[]): Promise<string>;\n\n  /**\n   * check if the contract is already deployed.\n   */\n  async checkAccountPhantom(): Promise<boolean> {\n    if (!this.isPhantom) {\n      // already deployed. no need to check anymore.\n      return this.isPhantom;\n    }\n    const etherspotWalletAddress = await this.getEtherspotWalletAddress();\n    const senderAddressCode = await this.publicClient.getCode({ address: etherspotWalletAddress as Hex })\n    if (!senderAddressCode || senderAddressCode === '0x' || senderAddressCode.length <= 2) {\n      this.isPhantom = true;\n    } else {\n      this.isPhantom = false;\n    }\n\n    return this.isPhantom;\n  }\n\n  /**\n   * calculate the account address even before it is deployed\n   */\n  async getCounterFactualAddress(): Promise<string> {\n    const initCode = await this.getAccountInitCode();\n    // use entryPoint to query account address (factory can provide a helper method to do the same, but\n    // this method attempts to be generic\n    try {\n      //await this.entryPointView.callStatic.getSenderAddress(initCode);\n      await this.publicClient.simulateContract({\n        address: this.entryPointAddress as Hex,\n        abi: parseAbi(entryPointAbi),\n        functionName: 'getSenderAddress',\n        args: [initCode]\n      });\n\n\n    } catch (e: any) {\n      return e.errorArgs.sender;\n    }\n    throw new Error('must handle revert');\n  }\n\n  /**\n   * return initCode value to into the UserOp.\n   * (either deployment code, or empty hex if contract already deployed)\n   */\n  async getInitCode(): Promise<string> {\n    if (await this.checkAccountPhantom()) {\n      return await this.getAccountInitCode();\n    }\n    return '0x';\n  }\n\n  /**\n   * return maximum gas used for verification.\n   * NOTE: createUnsignedUserOp will add to this value the cost of creation, if the contract is not yet created.\n   */\n  async getVerificationGasLimit(): Promise<BigNumberish> {\n    return 100000;\n  }\n\n  /**\n   * should cover cost of putting calldata on-chain, and some overhead.\n   * actual overhead depends on the expected bundle size\n   */\n  async getPreVerificationGas(userOp: Partial<BaseAccountUserOperationStruct>): Promise<number> {\n    const p = await resolveProperties(userOp);\n    return calcPreVerificationGas(p, this.overheads);\n  }\n\n  /**\n   * ABI-encode a user operation. used for calldata cost estimation\n   */\n  packUserOp(userOp: NotPromise<BaseAccountUserOperationStruct>): string {\n    return packUserOp(userOp, false);\n  }\n\n  async encodeUserOpCallDataAndGasLimit(\n    detailsForUserOp: TransactionDetailsForUserOp,\n  ): Promise<{ callData: string; callGasLimit: BigNumber }> {\n    function parseNumber(a: any): BigNumber | null {\n      if (a == null || a === '') return null;\n      return BigNumber.from(a.toString());\n    }\n\n    const value = parseNumber(detailsForUserOp.value) ?? BigNumber.from(0);\n    let callData: string;\n    const data = detailsForUserOp.data;\n    let target = detailsForUserOp.target;\n    if (typeof data === 'string') {\n      if (typeof target !== 'string') {\n        throw new Error('must have target address if data is single value');\n      }\n      callData = await this.encodeExecute(target, value, data);\n    } else {\n      if (typeof target === 'string') {\n        target = Array(data.length).fill(target);\n      }\n      callData = await this.encodeBatch(target, detailsForUserOp.values, data);\n    }\n\n    const callGasLimit =\n      parseNumber(detailsForUserOp.gasLimit) ?? BigNumber.from(35000)\n\n    return {\n      callData,\n      callGasLimit,\n    };\n  }\n\n  /**\n   * return userOpHash for signing.\n   * This value matches entryPoint.getUserOpHash (calculated off-chain, to avoid a view call)\n   * @param userOp userOperation, (signature field ignored)\n   */\n  async getUserOpHash(userOp: UserOperation): Promise<string> {\n    const op = await resolveProperties(userOp);\n    const chainId = await this.publicClient.getChainId();\n    return getUserOpHash(op, this.entryPointAddress, chainId);\n  }\n\n  /**\n   * return the account's address.\n   * this value is valid even before deploying the contract.\n   */\n  async getEtherspotWalletAddress(): Promise<string> {\n    if (this.senderAddress == null) {\n      if (this.etherspotWalletAddress != null) {\n        this.senderAddress = this.etherspotWalletAddress;\n      } else {\n        this.senderAddress = await this.getCounterFactualAddress();\n      }\n    }\n    return this.senderAddress;\n  }\n\n  async estimateCreationGas(initCode?: string): Promise<BigNumberish> {\n    if (initCode == null || initCode === '0x') return 0;\n    const deployerAddress = initCode.substring(0, 42);\n    const deployerCallData = '0x' + initCode.substring(42);\n    const estimatedGas = await this.publicClient.estimateGas({\n      account: this.externalViemAccount,\n      to: deployerAddress,\n      data: deployerCallData,\n    });\n\n    return estimatedGas ? estimatedGas : 0;\n  }\n\n  async getViemFeeData(): Promise<FeeData> {\n    const block = await this.publicClient.getBlock();\n    const gasPrice = await this.publicClient.getGasPrice();\n    const gasPriceInDecimals = BigNumber.from(gasPrice);\n\n    let lastBaseFeePerGas = null, maxFeePerGas = null, maxPriorityFeePerGas = null;\n\n    if (block && block.baseFeePerGas) {\n      // We may want to compute this more accurately in the future,\n      // using the formula \"check if the base fee is correct\".\n      // See: https://eips.ethereum.org/EIPS/eip-1559\n      lastBaseFeePerGas = block.baseFeePerGas;\n      const baseFeePerGasAsBigNumber = BigNumber.from(block.baseFeePerGas);\n      maxPriorityFeePerGas = BigNumber.from(\"1500000000\");\n      maxFeePerGas = baseFeePerGasAsBigNumber.mul(2).add(maxPriorityFeePerGas);\n    }\n\n    return { lastBaseFeePerGas, maxFeePerGas, maxPriorityFeePerGas, gasPrice: gasPriceInDecimals };\n  }\n\n  /**\n   * create a UserOperation, filling all details (except signature)\n   * - if account is not yet created, add initCode to deploy it.\n   * - if gas or nonce are missing, read them from the chain (note that we can't fill gaslimit before the account is created)\n   * @param info\n   */\n  async createUnsignedUserOp(info: TransactionDetailsForUserOp, key = BigNumber.from(0)): Promise<any> {\n    const { callData, callGasLimit } = await this.encodeUserOpCallDataAndGasLimit(info);\n    const factoryData = await this.getInitCode();\n    const initGas = await this.estimateCreationGas(factoryData);\n    const verificationGasLimit = BigNumber.from(await this.getVerificationGasLimit()).add(initGas);\n\n    let { maxFeePerGas, maxPriorityFeePerGas } = info;\n    if (maxFeePerGas == null || maxPriorityFeePerGas == null) {\n      let feeData: any = {};\n      try {\n        feeData = await this.getViemFeeData();\n      } catch (err) {\n        console.warn(\n          \"getGas: eth_maxPriorityFeePerGas failed, falling back to legacy gas price.\"\n        );\n        const gas = await this.publicClient.getGasPrice();\n\n        feeData = { maxFeePerGas: gas, maxPriorityFeePerGas: gas };\n      }\n      if (maxFeePerGas == null) {\n        maxFeePerGas = feeData.maxFeePerGas ?? undefined;\n      }\n      if (maxPriorityFeePerGas == null) {\n        maxPriorityFeePerGas = feeData.maxPriorityFeePerGas ?? undefined;\n      }\n    }\n    let partialUserOp: any;\n    if (factoryData !== '0x') {\n      partialUserOp = {\n        sender: await this.getEtherspotWalletAddress(),\n        nonce: await this.getNonce(key),\n        factory: this.factoryAddress,\n        factoryData: '0x' + factoryData.substring(42),\n        callData,\n        callGasLimit,\n        verificationGasLimit,\n        maxFeePerGas,\n        maxPriorityFeePerGas,\n      };\n    } else {\n      partialUserOp = {\n        sender: await this.getEtherspotWalletAddress(),\n        nonce: await this.getNonce(key),\n        factoryData: '0x' + factoryData.substring(42),\n        callData,\n        callGasLimit,\n        verificationGasLimit,\n        maxFeePerGas,\n        maxPriorityFeePerGas,\n      };\n    }\n\n    let paymasterData: PaymasterResponse | undefined = null;\n    if (this.paymasterAPI != null) {\n      // fill (partial) preVerificationGas (all except the cost of the generated paymasterData)\n      const userOpForPm = {\n        ...partialUserOp,\n        preVerificationGas: this.getPreVerificationGas(partialUserOp),\n      };\n      paymasterData = (await this.paymasterAPI.getPaymasterData(userOpForPm));\n      partialUserOp.verificationGasLimit = paymasterData.result.verificationGasLimit;\n      partialUserOp.preVerificationGas = paymasterData.result.preVerificationGas;\n      partialUserOp.callGasLimit = paymasterData.result.callGasLimit;\n      partialUserOp.paymaster = paymasterData.result.paymaster;\n      partialUserOp.paymasterVerificationGasLimit = paymasterData.result.paymasterVerificationGasLimit;\n      partialUserOp.paymasterPostOpGasLimit = paymasterData.result.paymasterPostOpGasLimit;\n    }\n    partialUserOp.paymasterData = paymasterData ? paymasterData.result.paymasterData : '0x';\n    return {\n      ...partialUserOp,\n      preVerificationGas: this.getPreVerificationGas(partialUserOp),\n      signature: info.dummySignature ?? '0x',\n    };\n  }\n\n  /**\n   * get the transaction that has this userOpHash mined, or null if not found\n   * @param userOpHash returned by sendUserOpToBundler (or by getUserOpHash..)\n   * @param timeout stop waiting after this timeout\n   * @param interval time to wait between polls.\n   * @return the transactionHash this userOp was mined, or null if not found.\n   */\n  async getUserOpReceipt(userOpHash: string, timeout = 30000, interval = 5000): Promise<string | null> {\n    const endtime = Date.now() + timeout;\n    while (Date.now() < endtime) {\n      const filter = await this.publicClient.createEventFilter({\n        address: this.entryPointAddress as Hex,\n        args: {\n          userOpHash: userOpHash as Hex,\n        },\n        event: parseAbiItem('event UserOperationEvent(bytes32 indexed userOpHash,address indexed sender,address indexed paymaster,uint256 nonce,bool success,uint256 actualGasCost,uint256 actualGasUsed)'),\n      })\n\n      const logs = await this.publicClient.getFilterLogs({ filter })\n\n      if (logs && logs.length > 0) {\n        return logs[0].transactionHash;\n      }\n\n      await new Promise((resolve) => setTimeout(resolve, interval));\n    }\n\n    return null;\n  }\n\n  // TODO fix signTypedData\n  async signTypedData(domain: any, types: TypedDataParameter[], message: any) {\n\n    // Step 1: Initialize an empty object for the transformed types\n    const typesObject: { [key: string]: TypedDataParameter[] } = {};\n\n    // Step 2: Iterate over the types array to transform it into the required format\n    types.forEach((type) => {\n      if (!typesObject[type.type]) {\n        // Step 3a: If the type does not exist, create it with the current item as the first element\n        typesObject[type.type] = [type];\n      } else {\n        // Step 3b: If the type exists, append the current item to its array\n        typesObject[type.type].push(type);\n      }\n    });\n\n    return await this.walletClient.signTypedData({\n      domain,\n      types: typesObject,\n      primaryType: 'UserOperation',\n      account: this.externalViemAccount,\n      message\n    });\n    //return this.services.walletService.signTypedData(types, message, this.accountAddress);\n  }\n}\n"],"mappings":"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","names":[]}