1
1
import {
2
+ ComputeBudgetProgram ,
2
3
Connection ,
3
4
Keypair ,
4
5
SendOptions ,
@@ -15,6 +16,9 @@ import { SolanaChains } from '../types';
15
16
import { SolanaUnsignedTransaction } from '../unsignedTransaction' ;
16
17
import { logTxDetails } from './debug' ;
17
18
19
+ // Number of blocks to wait before considering a transaction expired
20
+ const SOLANA_EXPIRED_BLOCKHEIGHT = 150 ;
21
+
18
22
export class SolanaSendSigner <
19
23
N extends Network ,
20
24
C extends SolanaChains = 'Solana' ,
@@ -26,6 +30,7 @@ export class SolanaSendSigner<
26
30
private _keypair : Keypair ,
27
31
private _debug : boolean = false ,
28
32
private _sendOpts ?: SendOptions ,
33
+ private _priotifyFeeAmount ?: bigint ,
29
34
) {
30
35
this . _sendOpts = this . _sendOpts ?? {
31
36
preflightCommitment : this . _rpc . commitment ,
@@ -42,6 +47,7 @@ export class SolanaSendSigner<
42
47
43
48
// Handles retrying a Transaction if the error is deemed to be
44
49
// recoverable. Currently handles:
50
+ // - Transaction expired
45
51
// - Blockhash not found
46
52
// - Not enough bytes (storage account not seen yet)
47
53
private retryable ( e : any ) : boolean {
@@ -75,7 +81,6 @@ export class SolanaSendSigner<
75
81
async signAndSend ( tx : UnsignedTransaction [ ] ) : Promise < any [ ] > {
76
82
let { blockhash, lastValidBlockHeight } = await SolanaPlatform . latestBlock (
77
83
this . _rpc ,
78
- 'finalized' ,
79
84
) ;
80
85
81
86
const txids : string [ ] = [ ] ;
@@ -86,6 +91,13 @@ export class SolanaSendSigner<
86
91
} = txn as SolanaUnsignedTransaction < N , C > ;
87
92
console . log ( `Signing: ${ description } for ${ this . address ( ) } ` ) ;
88
93
94
+ if ( this . _priotifyFeeAmount )
95
+ transaction . add (
96
+ ComputeBudgetProgram . setComputeUnitPrice ( {
97
+ microLamports : this . _priotifyFeeAmount ,
98
+ } ) ,
99
+ ) ;
100
+
89
101
if ( this . _debug ) logTxDetails ( transaction ) ;
90
102
91
103
// Try to send the transaction up to 5 times
@@ -103,9 +115,22 @@ export class SolanaSendSigner<
103
115
} catch ( e ) {
104
116
if ( ! this . retryable ( e ) ) throw e ;
105
117
106
- // If it is retryable, we should grab a new block hash
107
- ( { blockhash, lastValidBlockHeight } =
108
- await SolanaPlatform . latestBlock ( this . _rpc , 'finalized' ) ) ;
118
+ // If it is retryable, we need to grab a new block hash
119
+ const {
120
+ blockhash : newBlockhash ,
121
+ lastValidBlockHeight : newBlockHeight ,
122
+ } = await SolanaPlatform . latestBlock ( this . _rpc ) ;
123
+
124
+ // But we should _not_ submit if the blockhash hasnt expired
125
+ if (
126
+ newBlockHeight - lastValidBlockHeight <
127
+ SOLANA_EXPIRED_BLOCKHEIGHT
128
+ ) {
129
+ throw e ;
130
+ }
131
+
132
+ lastValidBlockHeight = newBlockHeight ;
133
+ blockhash = newBlockhash ;
109
134
}
110
135
}
111
136
}
0 commit comments