@@ -227,12 +227,45 @@ export function mode(): Mode.Mode {
227227 client,
228228 } ) ;
229229
230- const request = await bundlerClient . prepareUserOperation ( { account : smartAccount , calls } ) ;
231- request . signature = await smartAccount . signUserOperation ( request ) ;
232-
233230 const preCalls = ( await PreCalls . get ( { address : smartAccount . address , storage } ) ) ?? [ ] ;
234231 console . log ( "got precalls for" , smartAccount . address , preCalls ) ;
235- PreCalls . clear ( { address : smartAccount . address , storage } ) ;
232+
233+ // If we're estimating with a not-yet-created smart account, we need to
234+ // provide the simulation with a smart account with correct factory args,
235+ // otherwise the simulation fails.
236+ const initialSmartAccount = ( ( ) => {
237+ for ( const preCall of preCalls ) {
238+ if ( preCall . type === "bootstrap" ) {
239+ const eoa = Account . fromPrivateKey ( preCall . eoa . privateKey ) ;
240+ return toCoinbaseSmartAccount ( {
241+ client,
242+ owners : [ eoa ] ,
243+ } ) ;
244+ }
245+ }
246+ } ) ( ) ;
247+
248+ const request = await bundlerClient . prepareUserOperation (
249+ initialSmartAccount
250+ ? {
251+ account : await initialSmartAccount ,
252+ calls,
253+ // exclude factory from default parameters so that we don't
254+ // try to create the smart account again when we execute this
255+ // transaction after bootstrapping
256+ parameters : [
257+ // "factory",
258+ "fees" ,
259+ "gas" ,
260+ "paymaster" ,
261+ "nonce" ,
262+ "signature" ,
263+ "authorization" ,
264+ ] ,
265+ }
266+ : { account : smartAccount , calls } ,
267+ ) ;
268+ request . signature = await smartAccount . signUserOperation ( request ) ;
236269
237270 // TODO: move this to some prepare call helper?
238271 // TODO: can we do precalls + request atomically? they're signed by different accounts
@@ -270,6 +303,9 @@ export function mode(): Mode.Mode {
270303 }
271304 }
272305
306+ // TODO: only clear if precall succeeded?
307+ PreCalls . clear ( { address : smartAccount . address , storage } ) ;
308+
273309 for ( const hash of preCallHashes ) {
274310 const result = await bundlerClient . waitForUserOperationReceipt ( { hash } ) ;
275311 console . log ( "got result" , result ) ;
0 commit comments