22/* eslint-disable no-continue */
33/* eslint-disable no-constant-condition */
44
5- import { Contract , Interface , toBeHex } from 'ethers'
5+ import { Interface , toBeHex } from 'ethers'
66
77import AmbireAccount from '../../../contracts/compiled/AmbireAccount.json'
8- import entryPointAbi from '../../../contracts/compiled/EntryPoint.json'
98import { EIP7702Auth } from '../../consts/7702'
10- import { ERC_4337_ENTRYPOINT } from '../../consts/deploy'
119import { AccountOnchainState } from '../../interfaces/account'
1210import { Network } from '../../interfaces/network'
1311import { RPCProvider } from '../../interfaces/provider'
@@ -20,8 +18,10 @@ import { AccountOp, getSignableCalls } from '../accountOp/accountOp'
2018import { SubmittedAccountOp } from '../accountOp/submittedAccountOp'
2119import { AccountOpStatus } from '../accountOp/types'
2220import { PaymasterEstimationData } from '../erc7677/types'
21+ import { DecodedError } from '../errorDecoder/types'
2322import { getHumanReadableEstimationError } from '../errorHumanizer'
2423import { TokenResult } from '../portfolio'
24+ import { fetchNonce } from '../userOperation/fetchEntryPointNonce'
2525import { UserOperation } from '../userOperation/types'
2626import { getSigForCalculations , getUserOperation } from '../userOperation/userOperation'
2727import { estimateWithRetries } from './estimateWithRetries'
@@ -119,7 +119,12 @@ async function estimate(
119119
120120 const nonFatalErrors : Error [ ] = [ ]
121121 const estimateErrorCallback = ( e : Error ) => {
122- const decodedError = bundler . decodeBundlerError ( e )
122+ let decodedError : Error | DecodedError = e
123+ try {
124+ decodedError = bundler . decodeBundlerError ( e )
125+ } catch ( err ) {
126+ // failed to decode the error, move on with the original one
127+ }
123128
124129 // if the bundler estimation fails, add a nonFatalError so we can react to
125130 // it on the FE. The BE at a later stage decides if this error is actually fatal
@@ -202,6 +207,7 @@ export async function bundlerEstimate(
202207 }
203208
204209 const flags : EstimationFlags = { }
210+ flags . invalid4337NonceCounter = 0
205211 while ( true ) {
206212 // estimate
207213 const estimations = await estimate (
@@ -235,14 +241,20 @@ export async function bundlerEstimate(
235241 estimations . nonFatalErrors . find ( ( err ) => err . cause === '4337_INVALID_NONCE' )
236242 ) {
237243 flags . has4337NonceDiscrepancy = true
244+ flags . invalid4337NonceCounter += 1
245+
246+ // prevent infinite loops in the event of a terrible rpc malfunction
247+ if ( flags . invalid4337NonceCounter >= 3 ) {
248+ return estimations . nonFatalErrors . find ( ( err ) => err . cause === '4337_INVALID_NONCE' ) !
249+ }
238250
239251 // wait a bit to allow the state to sync
240252 await wait ( 2000 )
241- const ep = new Contract ( ERC_4337_ENTRYPOINT , entryPointAbi , provider )
242- const accountNonce = await ep
243- . getNonce ( account . addr , 0 , { blockTag : 'pending' } )
244- . catch ( ( ) => null )
245- if ( ! accountNonce ) continue
253+ const accountNonce = await fetchNonce ( account , provider )
254+ if ( accountNonce === null || accountNonce === 0n ) {
255+ // RPC serious malfunction
256+ return estimations . nonFatalErrors . find ( ( err ) => err . cause === '4337_INVALID_NONCE' ) !
257+ }
246258
247259 if ( network . chainId === 1n && BigInt ( userOp . nonce ) === BigInt ( accountNonce ) ) {
248260 return estimations . nonFatalErrors . find ( ( err ) => err . cause === '4337_INVALID_NONCE' ) !
0 commit comments