feat: add support for signature received notifications (#15946)

* feat: add support for signature received notifications

* chore: update type comments
This commit is contained in:
Justin Starry 2021-03-19 09:30:36 +08:00 committed by GitHub
parent 02b81dd05d
commit f4db9e4275
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 96 additions and 15 deletions

View File

@ -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();