1
1
import assert from "node:assert" ;
2
- import { type Job , type Processor , Worker } from "bullmq" ;
2
+ import { DelayedError , type Job , type Processor , Worker } from "bullmq" ;
3
3
import superjson from "superjson" ;
4
4
import {
5
5
type Address ,
@@ -70,7 +70,10 @@ type VersionedUserOp = Awaited<ReturnType<typeof prepareUserOp>>;
70
70
*
71
71
* This worker also handles retried EOA transactions.
72
72
*/
73
- const handler : Processor < string , void , string > = async ( job : Job < string > ) => {
73
+ const handler : Processor < string , void , string > = async (
74
+ job : Job < string > ,
75
+ token ?: string ,
76
+ ) => {
74
77
const { queueId, resendCount } = superjson . parse < SendTransactionData > (
75
78
job . data ,
76
79
) ;
@@ -89,9 +92,9 @@ const handler: Processor<string, void, string> = async (job: Job<string>) => {
89
92
90
93
if ( transaction . status === "queued" ) {
91
94
if ( transaction . isUserOp ) {
92
- resultTransaction = await _sendUserOp ( job , transaction ) ;
95
+ resultTransaction = await _sendUserOp ( job , transaction , token ) ;
93
96
} else {
94
- resultTransaction = await _sendTransaction ( job , transaction ) ;
97
+ resultTransaction = await _sendTransaction ( job , transaction , token ) ;
95
98
}
96
99
} else if ( transaction . status === "sent" ) {
97
100
resultTransaction = await _resendTransaction ( job , transaction , resendCount ) ;
@@ -121,6 +124,7 @@ const handler: Processor<string, void, string> = async (job: Job<string>) => {
121
124
const _sendUserOp = async (
122
125
job : Job ,
123
126
queuedTransaction : QueuedTransaction ,
127
+ token ?: string ,
124
128
) : Promise < SentTransaction | ErroredTransaction | null > => {
125
129
assert ( queuedTransaction . isUserOp ) ;
126
130
@@ -218,7 +222,7 @@ const _sendUserOp = async (
218
222
}
219
223
220
224
// Step 2: Get entrypoint address
221
- let entrypointAddress : string | undefined ;
225
+ let entrypointAddress : Address | undefined ;
222
226
if ( userProvidedEntrypointAddress ) {
223
227
entrypointAddress = queuedTransaction . entrypointAddress ;
224
228
} else {
@@ -298,16 +302,21 @@ const _sendUserOp = async (
298
302
299
303
// Handle if `maxFeePerGas` is overridden.
300
304
// Set it if the transaction will be sent, otherwise delay the job.
301
- if ( overrides ?. maxFeePerGas && unsignedUserOp . maxFeePerGas ) {
305
+ if (
306
+ typeof overrides ?. maxFeePerGas !== "undefined" &&
307
+ unsignedUserOp . maxFeePerGas
308
+ ) {
302
309
if ( overrides . maxFeePerGas > unsignedUserOp . maxFeePerGas ) {
303
310
unsignedUserOp . maxFeePerGas = overrides . maxFeePerGas ;
304
311
} else {
305
312
const retryAt = _minutesFromNow ( 5 ) ;
306
313
job . log (
307
314
`Override gas fee (${ overrides . maxFeePerGas } ) is lower than onchain fee (${ unsignedUserOp . maxFeePerGas } ). Delaying job until ${ retryAt } .` ,
308
315
) ;
309
- await job . moveToDelayed ( retryAt . getTime ( ) ) ;
310
- return null ;
316
+ // token is required to acquire lock for delaying currently processing job: https://docs.bullmq.io/patterns/process-step-jobs#delaying
317
+ await job . moveToDelayed ( retryAt . getTime ( ) , token ) ;
318
+ // throwing delayed error is required to notify bullmq worker not to complete or fail the job
319
+ throw new DelayedError ( "Delaying job due to gas fee override" ) ;
311
320
}
312
321
}
313
322
@@ -374,6 +383,7 @@ const _sendUserOp = async (
374
383
const _sendTransaction = async (
375
384
job : Job ,
376
385
queuedTransaction : QueuedTransaction ,
386
+ token ?: string ,
377
387
) : Promise < SentTransaction | ErroredTransaction | null > => {
378
388
assert ( ! queuedTransaction . isUserOp ) ;
379
389
@@ -463,8 +473,8 @@ const _sendTransaction = async (
463
473
job . log (
464
474
`Override gas fee (${ overrides . maxFeePerGas } ) is lower than onchain fee (${ populatedTransaction . maxFeePerGas } ). Delaying job until ${ retryAt } .` ,
465
475
) ;
466
- await job . moveToDelayed ( retryAt . getTime ( ) ) ;
467
- return null ;
476
+ await job . moveToDelayed ( retryAt . getTime ( ) , token ) ;
477
+ throw new DelayedError ( "Delaying job due to gas fee override" ) ;
468
478
}
469
479
}
470
480
0 commit comments