import { createBundlerClient, estimateUserOperationGas, getEntryPointVersion } from "permissionless" import type { ENTRYPOINT_ADDRESS_V06_TYPE, EntryPoint, GetEntryPointVersion, UserOperation } from "permissionless/types" import { http, type Transport } from "viem" import { getAction } from "viem/utils" export const getGasParameters = async ({ userOperation, entryPoint, bundlerTransport }: { userOperation: TEntryPoint extends ENTRYPOINT_ADDRESS_V06_TYPE ? UserOperation<"v0.6"> : UserOperation<"v0.7"> entryPoint: TEntryPoint bundlerTransport: Transport }) => { const shouldIncludePimlicoProvider = bundlerTransport({}).config.key === "http" && getEntryPointVersion(entryPoint) === "v0.7" const bundlerClient = createBundlerClient({ transport: (opts) => { let _bundlerTransport = bundlerTransport({ ...opts, retryCount: 0 }) if ( !shouldIncludePimlicoProvider || isProviderSet(_bundlerTransport.value?.url, "ALCHEMY") ) return _bundlerTransport _bundlerTransport = http( setPimlicoAsProvider(_bundlerTransport.value?.url) )({ ...opts, retryCount: 0 }) return _bundlerTransport }, entryPoint }) const gasParameters = await getAction( bundlerClient, estimateUserOperationGas, "estimateUserOperationGas" )({ userOperation: userOperation, entryPoint: entryPoint } as { userOperation: UserOperation> entryPoint: TEntryPoint }) return gasParameters } export const setPimlicoAsProvider = (urlString: string): string => { const url = new URL(urlString) const params = url.searchParams if (params.has("bundlerProvider")) { params.set("bundlerProvider", "PIMLICO") } else if (params.has("paymasterProvider")) { params.set("paymasterProvider", "PIMLICO") } else { params.set("provider", "PIMLICO") } url.search = params.toString() return url.toString() } export const isProviderSet = (urlString: string, provider: string): boolean => { const url = new URL(urlString) const params = url.searchParams const _provider = params.get("provider") ?? params.get("bundlerProvider") ?? params.get("paymasterProvider") if (_provider === provider) return true return false }