feat: add support for signature received notifications (#15946)
* feat: add support for signature received notifications * chore: update type comments
This commit is contained in:
parent
02b81dd05d
commit
f4db9e4275
|
@ -403,6 +403,11 @@ const SignatureStatusResult = pick({
|
|||
err: TransactionErrorResult,
|
||||
});
|
||||
|
||||
/**
|
||||
* Transaction signature received notification
|
||||
*/
|
||||
const SignatureReceivedResult = literal('receivedSignature');
|
||||
|
||||
export type Version = {
|
||||
'solana-core': string;
|
||||
'feature-set'?: number;
|
||||
|
@ -1009,7 +1014,9 @@ const SlotNotificationResult = pick({
|
|||
*/
|
||||
const SignatureNotificationResult = pick({
|
||||
subscription: number(),
|
||||
result: notificationResultAndContext(SignatureStatusResult),
|
||||
result: notificationResultAndContext(
|
||||
union([SignatureStatusResult, SignatureReceivedResult]),
|
||||
),
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -1456,20 +1463,51 @@ type SlotSubscriptionInfo = {
|
|||
};
|
||||
|
||||
/**
|
||||
* Callback function for signature notifications
|
||||
* Callback function for signature status notifications
|
||||
*/
|
||||
export type SignatureResultCallback = (
|
||||
signatureResult: SignatureResult,
|
||||
context: Context,
|
||||
) => void;
|
||||
|
||||
/**
|
||||
* Signature status notification with transaction result
|
||||
*/
|
||||
export type SignatureStatusNotification = {
|
||||
type: 'status';
|
||||
result: SignatureResult;
|
||||
};
|
||||
|
||||
/**
|
||||
* Signature received notification
|
||||
*/
|
||||
export type SignatureReceivedNotification = {
|
||||
type: 'received';
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback function for signature notifications
|
||||
*/
|
||||
export type SignatureSubscriptionCallback = (
|
||||
notification: SignatureStatusNotification | SignatureReceivedNotification,
|
||||
context: Context,
|
||||
) => void;
|
||||
|
||||
/**
|
||||
* Signature subscription options
|
||||
*/
|
||||
export type SignatureSubscriptionOptions = {
|
||||
commitment?: Commitment;
|
||||
enableReceivedNotification?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
type SignatureSubscriptionInfo = {
|
||||
signature: TransactionSignature; // TransactionSignature as a base 58 string
|
||||
callback: SignatureResultCallback;
|
||||
commitment?: Commitment;
|
||||
callback: SignatureSubscriptionCallback;
|
||||
options?: SignatureSubscriptionOptions;
|
||||
subscriptionId: SubscriptionId | null; // null when there's no current server subscription id
|
||||
};
|
||||
|
||||
|
@ -2943,11 +2981,9 @@ export class Connection {
|
|||
|
||||
for (let id of signatureKeys) {
|
||||
const sub = this._signatureSubscriptions[id];
|
||||
this._subscribe(
|
||||
sub,
|
||||
'signatureSubscribe',
|
||||
this._buildArgs([sub.signature], sub.commitment),
|
||||
);
|
||||
const args: any[] = [sub.signature];
|
||||
if (sub.options) args.push(sub.options);
|
||||
this._subscribe(sub, 'signatureSubscribe', args);
|
||||
}
|
||||
|
||||
for (let id of rootKeys) {
|
||||
|
@ -3148,11 +3184,26 @@ export class Connection {
|
|||
const res = create(notification, SignatureNotificationResult);
|
||||
for (const [id, sub] of Object.entries(this._signatureSubscriptions)) {
|
||||
if (sub.subscriptionId === res.subscription) {
|
||||
// Signatures subscriptions are auto-removed by the RPC service so
|
||||
// no need to explicitly send an unsubscribe message
|
||||
delete this._signatureSubscriptions[Number(id)];
|
||||
this._updateSubscriptions();
|
||||
sub.callback(res.result.value, res.result.context);
|
||||
if (res.result.value === 'receivedSignature') {
|
||||
sub.callback(
|
||||
{
|
||||
type: 'received',
|
||||
},
|
||||
res.result.context,
|
||||
);
|
||||
} else {
|
||||
// Signatures subscriptions are auto-removed by the RPC service so
|
||||
// no need to explicitly send an unsubscribe message
|
||||
delete this._signatureSubscriptions[Number(id)];
|
||||
this._updateSubscriptions();
|
||||
sub.callback(
|
||||
{
|
||||
type: 'status',
|
||||
result: res.result.value,
|
||||
},
|
||||
res.result.context,
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -3170,12 +3221,42 @@ export class Connection {
|
|||
signature: TransactionSignature,
|
||||
callback: SignatureResultCallback,
|
||||
commitment?: Commitment,
|
||||
): number {
|
||||
const id = ++this._signatureSubscriptionCounter;
|
||||
this._signatureSubscriptions[id] = {
|
||||
signature,
|
||||
callback: (notification, context) => {
|
||||
if (notification.type === 'status') {
|
||||
callback(notification.result, context);
|
||||
}
|
||||
},
|
||||
options: {commitment},
|
||||
subscriptionId: null,
|
||||
};
|
||||
this._updateSubscriptions();
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to be invoked when a transaction is
|
||||
* received and/or processed.
|
||||
*
|
||||
* @param signature Transaction signature string in base 58
|
||||
* @param callback Function to invoke on signature notifications
|
||||
* @param options Enable received notifications and set the commitment
|
||||
* level that signature must reach before notification
|
||||
* @return subscription id
|
||||
*/
|
||||
onSignatureWithOptions(
|
||||
signature: TransactionSignature,
|
||||
callback: SignatureSubscriptionCallback,
|
||||
options?: SignatureSubscriptionOptions,
|
||||
): number {
|
||||
const id = ++this._signatureSubscriptionCounter;
|
||||
this._signatureSubscriptions[id] = {
|
||||
signature,
|
||||
callback,
|
||||
commitment,
|
||||
options,
|
||||
subscriptionId: null,
|
||||
};
|
||||
this._updateSubscriptions();
|
||||
|
|
Loading…
Reference in New Issue