1
- import { TransactionResponse } from "@ethersproject/abstract-provider" ;
2
1
import { getDefaultGasOverrides } from "@thirdweb-dev/sdk" ;
3
2
import { StatusCodes } from "http-status-codes" ;
4
3
import { getTxById } from "../../db/transactions/getTxById" ;
@@ -25,10 +24,6 @@ export const cancelTransactionAndUpdate = async ({
25
24
} ;
26
25
}
27
26
28
- let message = "" ;
29
- let error = null ;
30
- let transferTransactionResult : TransactionResponse | null = null ;
31
-
32
27
if ( txData . signerAddress && txData . accountAddress ) {
33
28
switch ( txData . status ) {
34
29
case TransactionStatus . Errored :
@@ -62,25 +57,44 @@ export const cancelTransactionAndUpdate = async ({
62
57
status : TransactionStatus . Cancelled ,
63
58
} ,
64
59
} ) ;
65
- message = "Transaction cancelled on-database successfully." ;
66
- break ;
60
+ return {
61
+ message : "Transaction cancelled on-database successfully." ,
62
+ } ;
67
63
}
68
64
} else {
69
65
switch ( txData . status ) {
70
- case TransactionStatus . Errored :
71
- error = createCustomError (
66
+ case TransactionStatus . Errored : {
67
+ if ( ! txData . chainId || ! txData . fromAddress ) {
68
+ throw new Error ( "Invalid transaction state to cancel." ) ;
69
+ }
70
+ if ( txData . nonce ) {
71
+ const { transactionHash, error } = await sendNullTransaction ( {
72
+ chainId : parseInt ( txData . chainId ) ,
73
+ walletAddress : txData . fromAddress ,
74
+ nonce : txData . nonce ,
75
+ } ) ;
76
+ if ( error ) {
77
+ return { message : error } ;
78
+ }
79
+
80
+ return {
81
+ message : "Transaction cancelled successfully." ,
82
+ transactionHash,
83
+ } ;
84
+ }
85
+
86
+ throw createCustomError (
72
87
`Transaction has already errored: ${ txData . errorMessage } ` ,
73
88
StatusCodes . BAD_REQUEST ,
74
89
"TransactionErrored" ,
75
90
) ;
76
- break ;
91
+ }
77
92
case TransactionStatus . Cancelled :
78
- error = createCustomError (
93
+ throw createCustomError (
79
94
"Transaction is already cancelled." ,
80
95
StatusCodes . BAD_REQUEST ,
81
96
"TransactionAlreadyCancelled" ,
82
97
) ;
83
- break ;
84
98
case TransactionStatus . Queued :
85
99
await updateTx ( {
86
100
queueId,
@@ -89,40 +103,28 @@ export const cancelTransactionAndUpdate = async ({
89
103
status : TransactionStatus . Cancelled ,
90
104
} ,
91
105
} ) ;
92
- message = "Transaction cancelled successfully." ;
93
- break ;
106
+ return {
107
+ message : "Transaction cancelled successfully." ,
108
+ } ;
94
109
case TransactionStatus . Mined :
95
- error = createCustomError (
110
+ throw createCustomError (
96
111
"Transaction already mined." ,
97
112
StatusCodes . BAD_REQUEST ,
98
113
"TransactionAlreadyMined" ,
99
114
) ;
100
- break ;
101
115
case TransactionStatus . Sent : {
102
- const sdk = await getSdk ( {
103
- chainId : parseInt ( txData . chainId ! ) ,
104
- walletAddress : txData . fromAddress ! ,
105
- } ) ;
106
-
107
- const txReceipt = await sdk
108
- . getProvider ( )
109
- . getTransactionReceipt ( txData . transactionHash ! ) ;
110
- if ( txReceipt ) {
111
- message = "Transaction already mined." ;
112
- break ;
116
+ if ( ! txData . chainId || ! txData . fromAddress || ! txData . nonce ) {
117
+ throw new Error ( "Invalid transaction state to cancel." ) ;
113
118
}
114
119
115
- const gasOverrides = await getDefaultGasOverrides ( sdk . getProvider ( ) ) ;
116
- transferTransactionResult = await sdk . wallet . sendRawTransaction ( {
117
- to : txData . fromAddress ! ,
118
- from : txData . fromAddress ! ,
119
- data : "0x" ,
120
- value : "0x00" ,
121
- nonce : txData . nonce ! ,
122
- ...multiplyGasOverrides ( gasOverrides , 2 ) ,
120
+ const { transactionHash, error } = await sendNullTransaction ( {
121
+ chainId : parseInt ( txData . chainId ) ,
122
+ walletAddress : txData . fromAddress ,
123
+ nonce : txData . nonce ,
123
124
} ) ;
124
-
125
- message = "Transaction cancelled successfully." ;
125
+ if ( error ) {
126
+ return { message : error } ;
127
+ }
126
128
127
129
await updateTx ( {
128
130
queueId,
@@ -131,19 +133,51 @@ export const cancelTransactionAndUpdate = async ({
131
133
status : TransactionStatus . Cancelled ,
132
134
} ,
133
135
} ) ;
134
- break ;
136
+ return {
137
+ message : "Transaction cancelled successfully." ,
138
+ transactionHash,
139
+ } ;
135
140
}
136
- default :
137
- break ;
138
141
}
139
142
}
140
143
141
- if ( error ) {
142
- throw error ;
144
+ throw new Error ( "Unhandled cancellation state." ) ;
145
+ } ;
146
+
147
+ const sendNullTransaction = async ( args : {
148
+ chainId : number ;
149
+ walletAddress : string ;
150
+ nonce : number ;
151
+ transactionHash ?: string ;
152
+ } ) : Promise < {
153
+ transactionHash ?: string ;
154
+ error ?: string ;
155
+ } > => {
156
+ const { chainId, walletAddress, nonce, transactionHash } = args ;
157
+
158
+ const sdk = await getSdk ( { chainId, walletAddress } ) ;
159
+ const provider = sdk . getProvider ( ) ;
160
+
161
+ // Skip if the tx is already mined.
162
+ if ( transactionHash ) {
163
+ const txReceipt = await provider . getTransactionReceipt ( transactionHash ) ;
164
+ if ( txReceipt ) {
165
+ return { error : "Transaction already mined." } ;
166
+ }
143
167
}
144
168
145
- return {
146
- message,
147
- transactionHash : transferTransactionResult ?. hash ,
148
- } ;
169
+ try {
170
+ const gasOverrides = await getDefaultGasOverrides ( provider ) ;
171
+ const { hash } = await sdk . wallet . sendRawTransaction ( {
172
+ to : walletAddress ,
173
+ from : walletAddress ,
174
+ data : "0x" ,
175
+ value : "0" ,
176
+ nonce,
177
+ ...multiplyGasOverrides ( gasOverrides , 2 ) ,
178
+ } ) ;
179
+ return { transactionHash : hash } ;
180
+ } catch ( e : any ) {
181
+ return { error : e . toString ( ) } ;
182
+ }
149
183
} ;
0 commit comments