1
1
import { ERC4337EthersSigner } from "@thirdweb-dev/wallets/dist/declarations/src/evm/connectors/smart-wallet/lib/erc4337-signer" ;
2
+ import { providers } from "ethers" ;
2
3
import {
3
4
defineChain ,
4
5
eth_getBlockByNumber ,
@@ -39,118 +40,140 @@ export const updateMinedUserOps = async () => {
39
40
}
40
41
41
42
const promises = userOps . map ( async ( userOp ) => {
42
- if (
43
- ! userOp . sentAt ||
44
- ! userOp . signerAddress ||
45
- ! userOp . accountAddress ||
46
- ! userOp . userOpHash
47
- ) {
48
- return ;
49
- }
50
-
51
- const sdk = await getSdk ( {
52
- chainId : parseInt ( userOp . chainId ) ,
53
- walletAddress : userOp . signerAddress ,
54
- accountAddress : userOp . accountAddress ,
55
- } ) ;
56
- const signer = sdk . getSigner ( ) as ERC4337EthersSigner ;
43
+ try {
44
+ if (
45
+ ! userOp . sentAt ||
46
+ ! userOp . signerAddress ||
47
+ ! userOp . accountAddress ||
48
+ ! userOp . userOpHash
49
+ ) {
50
+ return ;
51
+ }
57
52
58
- // Get userOp receipt.
59
- // If no receipt, try again later (or cancel userOps after 1 hour).
60
- // Else the transaction call was submitted to mempool.
61
- const userOpReceipt = await signer . smartAccountAPI . getUserOpReceipt (
62
- signer . httpRpcClient ,
63
- userOp . userOpHash ,
64
- 3_000 , // 3 seconds
65
- ) ;
66
- if ( ! userOpReceipt ) {
67
- if ( msSince ( userOp . sentAt ) > CANCEL_DEADLINE_MS ) {
68
- await updateTx ( {
69
- pgtx,
53
+ const sdk = await getSdk ( {
54
+ chainId : parseInt ( userOp . chainId ) ,
55
+ walletAddress : userOp . signerAddress ,
56
+ accountAddress : userOp . accountAddress ,
57
+ } ) ;
58
+ const signer = sdk . getSigner ( ) as ERC4337EthersSigner ;
59
+ let userOpReceipt : providers . TransactionReceipt | undefined ;
60
+ try {
61
+ // Get userOp receipt.
62
+ // If no receipt, try again later (or cancel userOps after 1 hour).
63
+ // Else the transaction call was submitted to mempool.
64
+ userOpReceipt = await signer . smartAccountAPI . getUserOpReceipt (
65
+ signer . httpRpcClient ,
66
+ userOp . userOpHash ,
67
+ 3_000 , // 3 seconds
68
+ ) ;
69
+ } catch ( error ) {
70
+ // do-nothing
71
+ logger ( {
72
+ service : "worker" ,
73
+ level : "error" ,
70
74
queueId : userOp . id ,
71
- data : {
72
- status : TransactionStatus . Errored ,
73
- errorMessage : "Transaction timed out." ,
74
- } ,
75
+ message : "Failed to get receipt for UserOp" ,
76
+ error,
75
77
} ) ;
76
78
}
77
- return ;
78
- }
79
79
80
- const chain = defineChain ( parseInt ( userOp . chainId ) ) ;
81
- const rpcRequest = getRpcClient ( {
82
- client : thirdwebClient ,
83
- chain,
84
- } ) ;
80
+ if ( ! userOpReceipt ) {
81
+ if ( msSince ( userOp . sentAt ) > CANCEL_DEADLINE_MS ) {
82
+ await updateTx ( {
83
+ pgtx,
84
+ queueId : userOp . id ,
85
+ data : {
86
+ status : TransactionStatus . Errored ,
87
+ errorMessage : "Transaction timed out." ,
88
+ } ,
89
+ } ) ;
90
+ }
91
+ return ;
92
+ }
93
+
94
+ const chain = defineChain ( parseInt ( userOp . chainId ) ) ;
95
+ const rpcRequest = getRpcClient ( {
96
+ client : thirdwebClient ,
97
+ chain,
98
+ } ) ;
85
99
86
- // Get the transaction receipt.
87
- // If no receipt, try again later.
88
- // Else the transaction call was confirmed onchain.
89
- const transaction = await eth_getTransactionByHash ( rpcRequest , {
90
- hash : userOpReceipt . transactionHash as `0x${string } `,
91
- } ) ;
92
- const transactionReceipt = await eth_getTransactionReceipt (
93
- rpcRequest ,
94
- { hash : transaction . hash } ,
95
- ) ;
96
- if ( ! transactionReceipt ) {
100
+ // Get the transaction receipt.
97
101
// If no receipt, try again later.
98
- return ;
99
- }
102
+ // Else the transaction call was confirmed onchain.
103
+ const transaction = await eth_getTransactionByHash ( rpcRequest , {
104
+ hash : userOpReceipt . transactionHash as `0x${string } `,
105
+ } ) ;
106
+ const transactionReceipt = await eth_getTransactionReceipt (
107
+ rpcRequest ,
108
+ { hash : transaction . hash } ,
109
+ ) ;
110
+ if ( ! transactionReceipt ) {
111
+ // If no receipt, try again later.
112
+ return ;
113
+ }
100
114
101
- let minedAt = new Date ( ) ;
102
- try {
103
- const block = await eth_getBlockByNumber ( rpcRequest , {
104
- blockNumber : transactionReceipt . blockNumber ,
105
- includeTransactions : false ,
115
+ let minedAt = new Date ( ) ;
116
+ try {
117
+ const block = await eth_getBlockByNumber ( rpcRequest , {
118
+ blockNumber : transactionReceipt . blockNumber ,
119
+ includeTransactions : false ,
120
+ } ) ;
121
+ minedAt = new Date ( Number ( block . timestamp ) * 1000 ) ;
122
+ } catch ( e ) { }
123
+
124
+ // Update the userOp transaction as mined.
125
+ await updateTx ( {
126
+ pgtx,
127
+ queueId : userOp . id ,
128
+ data : {
129
+ status : TransactionStatus . Mined ,
130
+ minedAt,
131
+ blockNumber : Number ( transactionReceipt . blockNumber ) ,
132
+ onChainTxStatus : toTransactionStatus ( transactionReceipt . status ) ,
133
+ transactionHash : transactionReceipt . transactionHash ,
134
+ transactionType : toTransactionType ( transaction . type ) ,
135
+ gasLimit : userOp . gasLimit ?? undefined ,
136
+ maxFeePerGas : transaction . maxFeePerGas ?. toString ( ) ,
137
+ maxPriorityFeePerGas :
138
+ transaction . maxPriorityFeePerGas ?. toString ( ) ,
139
+ gasPrice : transaction . gasPrice ?. toString ( ) ,
140
+ } ,
106
141
} ) ;
107
- minedAt = new Date ( Number ( block . timestamp ) * 1000 ) ;
108
- } catch ( e ) { }
109
142
110
- // Update the userOp transaction as mined.
111
- await updateTx ( {
112
- pgtx,
113
- queueId : userOp . id ,
114
- data : {
143
+ logger ( {
144
+ service : "worker" ,
145
+ level : "info" ,
146
+ queueId : userOp . id ,
147
+ message : "Updated with receipt" ,
148
+ } ) ;
149
+ sendWebhookForQueueIds . push ( {
150
+ queueId : userOp . id ,
115
151
status : TransactionStatus . Mined ,
116
- minedAt,
117
- blockNumber : Number ( transactionReceipt . blockNumber ) ,
118
- onChainTxStatus : toTransactionStatus ( transactionReceipt . status ) ,
119
- transactionHash : transactionReceipt . transactionHash ,
120
- transactionType : toTransactionType ( transaction . type ) ,
121
- gasLimit : userOp . gasLimit ?? undefined ,
122
- maxFeePerGas : transaction . maxFeePerGas ?. toString ( ) ,
123
- maxPriorityFeePerGas :
124
- transaction . maxPriorityFeePerGas ?. toString ( ) ,
125
- gasPrice : transaction . gasPrice ?. toString ( ) ,
126
- } ,
127
- } ) ;
128
-
129
- logger ( {
130
- service : "worker" ,
131
- level : "info" ,
132
- queueId : userOp . id ,
133
- message : "Updated with receipt" ,
134
- } ) ;
135
- sendWebhookForQueueIds . push ( {
136
- queueId : userOp . id ,
137
- status : TransactionStatus . Mined ,
138
- } ) ;
139
- reportUsageForQueueIds . push ( {
140
- input : {
141
- fromAddress : userOp . fromAddress ?? undefined ,
142
- toAddress : userOp . toAddress ?? undefined ,
143
- value : userOp . value ?? undefined ,
144
- chainId : userOp . chainId ,
145
- userOpHash : userOp . userOpHash ?? undefined ,
146
- onChainTxStatus : toTransactionStatus ( transactionReceipt . status ) ,
147
- functionName : userOp . functionName ?? undefined ,
148
- extension : userOp . extension ?? undefined ,
149
- provider : signer . httpRpcClient . bundlerUrl ,
150
- msSinceSend : msSince ( userOp . sentAt ! ) ,
151
- } ,
152
- action : UsageEventTxActionEnum . MineTx ,
153
- } ) ;
152
+ } ) ;
153
+ reportUsageForQueueIds . push ( {
154
+ input : {
155
+ fromAddress : userOp . fromAddress ?? undefined ,
156
+ toAddress : userOp . toAddress ?? undefined ,
157
+ value : userOp . value ?? undefined ,
158
+ chainId : userOp . chainId ,
159
+ userOpHash : userOp . userOpHash ?? undefined ,
160
+ onChainTxStatus : toTransactionStatus ( transactionReceipt . status ) ,
161
+ functionName : userOp . functionName ?? undefined ,
162
+ extension : userOp . extension ?? undefined ,
163
+ provider : signer . httpRpcClient . bundlerUrl ,
164
+ msSinceSend : msSince ( userOp . sentAt ! ) ,
165
+ } ,
166
+ action : UsageEventTxActionEnum . MineTx ,
167
+ } ) ;
168
+ } catch ( err ) {
169
+ logger ( {
170
+ service : "worker" ,
171
+ level : "error" ,
172
+ queueId : userOp . id ,
173
+ message : "Failed to update receipt for UserOp " ,
174
+ error : err ,
175
+ } ) ;
176
+ }
154
177
} ) ;
155
178
156
179
await Promise . all ( promises ) ;
@@ -166,7 +189,7 @@ export const updateMinedUserOps = async () => {
166
189
logger ( {
167
190
service : "worker" ,
168
191
level : "error" ,
169
- message : "Failed to update receipts" ,
192
+ message : "Failed to batch update receipts" ,
170
193
error : err ,
171
194
} ) ;
172
195
}
0 commit comments