@@ -403,6 +403,11 @@ const SignatureStatusResult = pick({
403
403
err : TransactionErrorResult ,
404
404
} ) ;
405
405
406
+ /**
407
+ * Transaction signature received notification
408
+ */
409
+ const SignatureReceivedResult = literal ( 'receivedSignature' ) ;
410
+
406
411
export type Version = {
407
412
'solana-core' : string ;
408
413
'feature-set' ?: number ;
@@ -1009,7 +1014,9 @@ const SlotNotificationResult = pick({
1009
1014
*/
1010
1015
const SignatureNotificationResult = pick ( {
1011
1016
subscription : number ( ) ,
1012
- result : notificationResultAndContext ( SignatureStatusResult ) ,
1017
+ result : notificationResultAndContext (
1018
+ union ( [ SignatureStatusResult , SignatureReceivedResult ] ) ,
1019
+ ) ,
1013
1020
} ) ;
1014
1021
1015
1022
/**
@@ -1456,20 +1463,51 @@ type SlotSubscriptionInfo = {
1456
1463
} ;
1457
1464
1458
1465
/**
1459
- * Callback function for signature notifications
1466
+ * Callback function for signature status notifications
1460
1467
*/
1461
1468
export type SignatureResultCallback = (
1462
1469
signatureResult : SignatureResult ,
1463
1470
context : Context ,
1464
1471
) => void ;
1465
1472
1473
+ /**
1474
+ * Signature status notification with transaction result
1475
+ */
1476
+ export type SignatureStatusNotification = {
1477
+ type : 'status' ;
1478
+ result : SignatureResult ;
1479
+ } ;
1480
+
1481
+ /**
1482
+ * Signature received notification
1483
+ */
1484
+ export type SignatureReceivedNotification = {
1485
+ type : 'received' ;
1486
+ } ;
1487
+
1488
+ /**
1489
+ * Callback function for signature notifications
1490
+ */
1491
+ export type SignatureSubscriptionCallback = (
1492
+ notification : SignatureStatusNotification | SignatureReceivedNotification ,
1493
+ context : Context ,
1494
+ ) => void ;
1495
+
1496
+ /**
1497
+ * Signature subscription options
1498
+ */
1499
+ export type SignatureSubscriptionOptions = {
1500
+ commitment ?: Commitment ;
1501
+ enableReceivedNotification ?: boolean ;
1502
+ } ;
1503
+
1466
1504
/**
1467
1505
* @internal
1468
1506
*/
1469
1507
type SignatureSubscriptionInfo = {
1470
1508
signature : TransactionSignature ; // TransactionSignature as a base 58 string
1471
- callback : SignatureResultCallback ;
1472
- commitment ?: Commitment ;
1509
+ callback : SignatureSubscriptionCallback ;
1510
+ options ?: SignatureSubscriptionOptions ;
1473
1511
subscriptionId : SubscriptionId | null ; // null when there's no current server subscription id
1474
1512
} ;
1475
1513
@@ -2943,11 +2981,9 @@ export class Connection {
2943
2981
2944
2982
for ( let id of signatureKeys ) {
2945
2983
const sub = this . _signatureSubscriptions [ id ] ;
2946
- this . _subscribe (
2947
- sub ,
2948
- 'signatureSubscribe' ,
2949
- this . _buildArgs ( [ sub . signature ] , sub . commitment ) ,
2950
- ) ;
2984
+ const args : any [ ] = [ sub . signature ] ;
2985
+ if ( sub . options ) args . push ( sub . options ) ;
2986
+ this . _subscribe ( sub , 'signatureSubscribe' , args ) ;
2951
2987
}
2952
2988
2953
2989
for ( let id of rootKeys ) {
@@ -3148,11 +3184,26 @@ export class Connection {
3148
3184
const res = create ( notification , SignatureNotificationResult ) ;
3149
3185
for ( const [ id , sub ] of Object . entries ( this . _signatureSubscriptions ) ) {
3150
3186
if ( sub . subscriptionId === res . subscription ) {
3151
- // Signatures subscriptions are auto-removed by the RPC service so
3152
- // no need to explicitly send an unsubscribe message
3153
- delete this . _signatureSubscriptions [ Number ( id ) ] ;
3154
- this . _updateSubscriptions ( ) ;
3155
- sub . callback ( res . result . value , res . result . context ) ;
3187
+ if ( res . result . value === 'receivedSignature' ) {
3188
+ sub . callback (
3189
+ {
3190
+ type : 'received' ,
3191
+ } ,
3192
+ res . result . context ,
3193
+ ) ;
3194
+ } else {
3195
+ // Signatures subscriptions are auto-removed by the RPC service so
3196
+ // no need to explicitly send an unsubscribe message
3197
+ delete this . _signatureSubscriptions [ Number ( id ) ] ;
3198
+ this . _updateSubscriptions ( ) ;
3199
+ sub . callback (
3200
+ {
3201
+ type : 'status' ,
3202
+ result : res . result . value ,
3203
+ } ,
3204
+ res . result . context ,
3205
+ ) ;
3206
+ }
3156
3207
return ;
3157
3208
}
3158
3209
}
@@ -3170,12 +3221,42 @@ export class Connection {
3170
3221
signature : TransactionSignature ,
3171
3222
callback : SignatureResultCallback ,
3172
3223
commitment ?: Commitment ,
3224
+ ) : number {
3225
+ const id = ++ this . _signatureSubscriptionCounter ;
3226
+ this . _signatureSubscriptions [ id ] = {
3227
+ signature,
3228
+ callback : ( notification , context ) => {
3229
+ if ( notification . type === 'status' ) {
3230
+ callback ( notification . result , context ) ;
3231
+ }
3232
+ } ,
3233
+ options : { commitment} ,
3234
+ subscriptionId : null ,
3235
+ } ;
3236
+ this . _updateSubscriptions ( ) ;
3237
+ return id ;
3238
+ }
3239
+
3240
+ /**
3241
+ * Register a callback to be invoked when a transaction is
3242
+ * received and/or processed.
3243
+ *
3244
+ * @param signature Transaction signature string in base 58
3245
+ * @param callback Function to invoke on signature notifications
3246
+ * @param options Enable received notifications and set the commitment
3247
+ * level that signature must reach before notification
3248
+ * @return subscription id
3249
+ */
3250
+ onSignatureWithOptions (
3251
+ signature : TransactionSignature ,
3252
+ callback : SignatureSubscriptionCallback ,
3253
+ options ?: SignatureSubscriptionOptions ,
3173
3254
) : number {
3174
3255
const id = ++ this . _signatureSubscriptionCounter ;
3175
3256
this . _signatureSubscriptions [ id ] = {
3176
3257
signature,
3177
3258
callback,
3178
- commitment ,
3259
+ options ,
3179
3260
subscriptionId : null ,
3180
3261
} ;
3181
3262
this . _updateSubscriptions ( ) ;
0 commit comments