@@ -23,6 +23,7 @@ import {
23
23
import {
24
24
clusterApiUrl ,
25
25
Commitment ,
26
+ ComputeBudgetProgram ,
26
27
Connection ,
27
28
Keypair ,
28
29
PublicKey ,
@@ -77,6 +78,9 @@ import {
77
78
const SOLANA_SEQ_LOG = 'Program log: Sequence: ' ;
78
79
const SOLANA_CHAIN_NAME = MAINNET_CONFIG . chains . solana ! . key ;
79
80
81
+ // Add priority fee according to 75th percentile of recent fees paid
82
+ const SOLANA_FEE_PERCENTILE = 0.75 ;
83
+
80
84
const SOLANA_MAINNET_EMMITER_ID =
81
85
'ec7372995d5cc8732397fb0ad35c0121e0eaa90d26f828a534cab54391b3a4f5' ;
82
86
const SOLANA_TESTNET_EMITTER_ID =
@@ -273,7 +277,15 @@ export class SolanaContext<
273
277
payerPublicKey ,
274
278
tokenPublicKey ,
275
279
) ;
276
- const transaction = new Transaction ( ) . add ( createAccountInst ) ;
280
+ const transaction = new Transaction ( ) ;
281
+ transaction . add (
282
+ ...( await this . determineComputeBudget ( [
283
+ tokenPublicKey ,
284
+ associatedPublicKey ,
285
+ ] ) ) ,
286
+ ) ;
287
+ transaction . add ( createAccountInst ) ;
288
+
277
289
const { blockhash } = await this . connection . getLatestBlockhash ( commitment ) ;
278
290
transaction . recentBlockhash = blockhash ;
279
291
transaction . feePayer = payerPublicKey ;
@@ -387,6 +399,8 @@ export class SolanaContext<
387
399
388
400
const { blockhash } = await this . connection . getLatestBlockhash ( commitment ) ;
389
401
const transaction = new Transaction ( ) ;
402
+ transaction . add ( ...( await this . determineComputeBudget ( [ NATIVE_MINT ] ) ) ) ;
403
+
390
404
transaction . recentBlockhash = blockhash ;
391
405
transaction . feePayer = payerPublicKey ;
392
406
transaction . add (
@@ -517,10 +531,14 @@ export class SolanaContext<
517
531
recipientAddress ,
518
532
recipientChainId ,
519
533
) ;
520
- const transaction = new Transaction ( ) . add (
521
- approvalIx ,
522
- tokenBridgeTransferIx ,
534
+ const transaction = new Transaction ( ) ;
535
+ transaction . add (
536
+ ...( await this . determineComputeBudget ( [
537
+ new PublicKey ( fromAddress ) ,
538
+ new PublicKey ( mintAddress ) ,
539
+ ] ) ) ,
523
540
) ;
541
+ transaction . add ( approvalIx , tokenBridgeTransferIx ) ;
524
542
const { blockhash } = await this . connection . getLatestBlockhash ( commitment ) ;
525
543
transaction . recentBlockhash = blockhash ;
526
544
transaction . feePayer = new PublicKey ( senderAddress ) ;
@@ -936,6 +954,7 @@ export class SolanaContext<
936
954
parsed . tokenAddress ,
937
955
) ;
938
956
const transaction = new Transaction ( ) ;
957
+ transaction . add ( ...( await this . determineComputeBudget ( [ mint ] ) ) ) ;
939
958
const recipientTokenAccount = getAssociatedTokenAddressSync (
940
959
mint ,
941
960
recipient ,
@@ -1047,15 +1066,21 @@ export class SolanaContext<
1047
1066
const recipientChainId = this . context . toChainId ( recipientChain ) ;
1048
1067
const nonce = createNonce ( ) . readUint32LE ( ) ;
1049
1068
const transaction = new Transaction ( ) ;
1050
- let transferIx : TransactionInstruction ;
1069
+
1051
1070
if ( token === NATIVE || token . chain === SOLANA_CHAIN_NAME ) {
1052
1071
const mint = token === NATIVE ? NATIVE_MINT : token . address ;
1053
1072
const wrapToken = token === NATIVE ;
1073
+
1074
+ let writableAddresses : PublicKey [ ] = [ NATIVE_MINT ] ;
1075
+
1054
1076
if ( wrapToken ) {
1055
1077
const ata = getAssociatedTokenAddressSync (
1056
1078
NATIVE_MINT ,
1057
1079
new PublicKey ( senderAddress ) ,
1058
1080
) ;
1081
+
1082
+ writableAddresses . push ( ata ) ;
1083
+
1059
1084
try {
1060
1085
await getAccount ( this . connection , ata ) ;
1061
1086
} catch ( e : any ) {
@@ -1073,37 +1098,49 @@ export class SolanaContext<
1073
1098
}
1074
1099
}
1075
1100
}
1076
- transferIx = await createTransferNativeTokensWithRelayInstruction (
1077
- this . connection ,
1078
- relayer ,
1079
- senderAddress ,
1080
- token_bridge ,
1081
- core ,
1082
- mint ,
1083
- BigInt ( amount ) ,
1084
- BigInt ( toNativeToken ) ,
1085
- formattedRecipient ,
1086
- recipientChainId ,
1087
- nonce ,
1088
- wrapToken ,
1101
+
1102
+ transaction . add (
1103
+ ...( await this . determineComputeBudget ( writableAddresses ) ) ,
1104
+ ) ;
1105
+ transaction . add (
1106
+ await createTransferNativeTokensWithRelayInstruction (
1107
+ this . connection ,
1108
+ relayer ,
1109
+ senderAddress ,
1110
+ token_bridge ,
1111
+ core ,
1112
+ mint ,
1113
+ BigInt ( amount ) ,
1114
+ BigInt ( toNativeToken ) ,
1115
+ formattedRecipient ,
1116
+ recipientChainId ,
1117
+ nonce ,
1118
+ wrapToken ,
1119
+ ) ,
1089
1120
) ;
1090
1121
} else {
1091
1122
const mint = await this . mustGetForeignAsset ( token , sendingChain ) ;
1092
- transferIx = await createTransferWrappedTokensWithRelayInstruction (
1093
- this . connection ,
1094
- relayer ,
1095
- senderAddress ,
1096
- token_bridge ,
1097
- core ,
1098
- mint ,
1099
- BigInt ( amount ) ,
1100
- BigInt ( toNativeToken ) ,
1101
- formattedRecipient ,
1102
- recipientChainId ,
1103
- nonce ,
1123
+
1124
+ transaction . add (
1125
+ ...( await this . determineComputeBudget ( [ new PublicKey ( mint ) ] ) ) ,
1126
+ ) ;
1127
+ transaction . add (
1128
+ await createTransferWrappedTokensWithRelayInstruction (
1129
+ this . connection ,
1130
+ relayer ,
1131
+ senderAddress ,
1132
+ token_bridge ,
1133
+ core ,
1134
+ mint ,
1135
+ BigInt ( amount ) ,
1136
+ BigInt ( toNativeToken ) ,
1137
+ formattedRecipient ,
1138
+ recipientChainId ,
1139
+ nonce ,
1140
+ ) ,
1104
1141
) ;
1105
1142
}
1106
- transaction . add ( transferIx ) ;
1143
+
1107
1144
const { blockhash } = await this . connection . getLatestBlockhash ( 'finalized' ) ;
1108
1145
transaction . recentBlockhash = blockhash ;
1109
1146
transaction . feePayer = new PublicKey ( senderAddress ) ;
@@ -1176,4 +1213,38 @@ export class SolanaContext<
1176
1213
chain : 'solana' ,
1177
1214
} ;
1178
1215
}
1216
+
1217
+ async determineComputeBudget (
1218
+ lockedWritableAccounts : PublicKey [ ] = [ ] ,
1219
+ ) : Promise < TransactionInstruction [ ] > {
1220
+ let fee = 100_000 ; // Set fee to 100,000 microlamport by default
1221
+
1222
+ try {
1223
+ const recentFeesResponse =
1224
+ await this . connection ?. getRecentPrioritizationFees ( {
1225
+ lockedWritableAccounts,
1226
+ } ) ;
1227
+
1228
+ if ( recentFeesResponse ) {
1229
+ // Get 75th percentile fee paid in recent slots
1230
+ const recentFees = recentFeesResponse
1231
+ . map ( ( dp ) => dp . prioritizationFee )
1232
+ . sort ( ( a , b ) => a - b ) ;
1233
+ fee = recentFees [ Math . floor ( recentFees . length * SOLANA_FEE_PERCENTILE ) ] ;
1234
+ }
1235
+ } catch ( e ) {
1236
+ console . error ( 'Error fetching Solana recent fees' , e ) ;
1237
+ }
1238
+
1239
+ console . info ( `Setting Solana compute unit price to ${ fee } microLamports` ) ;
1240
+
1241
+ return [
1242
+ ComputeBudgetProgram . setComputeUnitLimit ( {
1243
+ units : 250_000 ,
1244
+ } ) ,
1245
+ ComputeBudgetProgram . setComputeUnitPrice ( {
1246
+ microLamports : fee ,
1247
+ } ) ,
1248
+ ] ;
1249
+ }
1179
1250
}
0 commit comments