11import type { Hex } from 'viem' ;
22
3- import { createPublicClient , http } from 'viem' ;
4- import { entryPoint07Address } from 'viem/account-abstraction' ;
3+ import { http } from 'viem' ;
4+ import { createBundlerClient , entryPoint07Address } from 'viem/account-abstraction' ;
55
66import type {
77 CompleteWithdrawRequest ,
@@ -12,12 +12,9 @@ import type {
1212import { getZerodevBundlerRpcUrl } from './getZerodevBundlerRpcUrl' ;
1313import { getChainForNetwork } from './utils/chainConfig' ;
1414
15- const POLL_INTERVAL_MS = 3000 ;
16- const MAX_POLL_ATTEMPTS = 5 ; // 5 attempts * 3 seconds = 15s max wait
17-
1815/**
1916 * Submits a single signed UserOperation to the ZeroDev bundler and waits for completion.
20- * Uses viem's bundler actions directly instead of kernel client to avoid any modifications .
17+ * Uses viem's bundler client for proper receipt waiting .
2118 */
2219async function submitWithdrawal ( withdrawal : SignedWithdrawal ) : Promise < {
2320 network : string ;
@@ -28,7 +25,7 @@ async function submitWithdrawal(withdrawal: SignedWithdrawal): Promise<{
2825 const { chain, chainId } = getChainForNetwork ( network ) ;
2926 const bundlerUrl = getZerodevBundlerRpcUrl ( chainId ) ;
3027
31- const publicClient = createPublicClient ( {
28+ const bundlerClient = createBundlerClient ( {
3229 chain,
3330 transport : http ( bundlerUrl ) ,
3431 } ) ;
@@ -41,39 +38,19 @@ async function submitWithdrawal(withdrawal: SignedWithdrawal): Promise<{
4138 } ;
4239
4340 // Submit the signed UserOperation to the bundler
44- const userOpHash = ( await publicClient . request ( {
41+ const userOpHash = ( await bundlerClient . request ( {
4542 method : 'eth_sendUserOperation' as any ,
4643 params : [ userOpForRpc , entryPoint07Address ] as any ,
4744 } ) ) as Hex ;
4845
49- // Poll for receipt until confirmed
50- let receipt = null ;
51- for ( let attempt = 0 ; attempt < MAX_POLL_ATTEMPTS ; attempt ++ ) {
52- await new Promise ( ( resolve ) => setTimeout ( resolve , POLL_INTERVAL_MS ) ) ;
53-
54- try {
55- receipt = await publicClient . request ( {
56- method : 'eth_getUserOperationReceipt' as any ,
57- params : [ userOpHash ] as any ,
58- } ) ;
59- if ( receipt ) break ;
60- } catch {
61- // Receipt not available yet, continue polling
62- }
63- }
64-
65- if ( ! receipt ) {
66- const timeoutSeconds = ( MAX_POLL_ATTEMPTS * POLL_INTERVAL_MS ) / 1000 ;
67- throw new Error ( `UserOp ${ userOpHash } not confirmed after ${ timeoutSeconds } seconds` ) ;
68- }
69-
70- // eslint-disable-next-line @typescript-eslint/no-explicit-any
71- const receiptData = receipt as any ;
72- const transactionHash = receiptData . receipt ?. transactionHash || receiptData . transactionHash ;
46+ // Wait for the UserOperation receipt
47+ const receipt = await bundlerClient . waitForUserOperationReceipt ( {
48+ hash : userOpHash ,
49+ } ) ;
7350
7451 return {
7552 network,
76- transactionHash,
53+ transactionHash : receipt . receipt . transactionHash ,
7754 userOpHash,
7855 } ;
7956}
0 commit comments