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,
|
err: TransactionErrorResult,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transaction signature received notification
|
||||||
|
*/
|
||||||
|
const SignatureReceivedResult = literal('receivedSignature');
|
||||||
|
|
||||||
export type Version = {
|
export type Version = {
|
||||||
'solana-core': string;
|
'solana-core': string;
|
||||||
'feature-set'?: number;
|
'feature-set'?: number;
|
||||||
|
@ -1009,7 +1014,9 @@ const SlotNotificationResult = pick({
|
||||||
*/
|
*/
|
||||||
const SignatureNotificationResult = pick({
|
const SignatureNotificationResult = pick({
|
||||||
subscription: number(),
|
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 = (
|
export type SignatureResultCallback = (
|
||||||
signatureResult: SignatureResult,
|
signatureResult: SignatureResult,
|
||||||
context: Context,
|
context: Context,
|
||||||
) => void;
|
) => 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
|
* @internal
|
||||||
*/
|
*/
|
||||||
type SignatureSubscriptionInfo = {
|
type SignatureSubscriptionInfo = {
|
||||||
signature: TransactionSignature; // TransactionSignature as a base 58 string
|
signature: TransactionSignature; // TransactionSignature as a base 58 string
|
||||||
callback: SignatureResultCallback;
|
callback: SignatureSubscriptionCallback;
|
||||||
commitment?: Commitment;
|
options?: SignatureSubscriptionOptions;
|
||||||
subscriptionId: SubscriptionId | null; // null when there's no current server subscription id
|
subscriptionId: SubscriptionId | null; // null when there's no current server subscription id
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2943,11 +2981,9 @@ export class Connection {
|
||||||
|
|
||||||
for (let id of signatureKeys) {
|
for (let id of signatureKeys) {
|
||||||
const sub = this._signatureSubscriptions[id];
|
const sub = this._signatureSubscriptions[id];
|
||||||
this._subscribe(
|
const args: any[] = [sub.signature];
|
||||||
sub,
|
if (sub.options) args.push(sub.options);
|
||||||
'signatureSubscribe',
|
this._subscribe(sub, 'signatureSubscribe', args);
|
||||||
this._buildArgs([sub.signature], sub.commitment),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let id of rootKeys) {
|
for (let id of rootKeys) {
|
||||||
|
@ -3148,11 +3184,26 @@ export class Connection {
|
||||||
const res = create(notification, SignatureNotificationResult);
|
const res = create(notification, SignatureNotificationResult);
|
||||||
for (const [id, sub] of Object.entries(this._signatureSubscriptions)) {
|
for (const [id, sub] of Object.entries(this._signatureSubscriptions)) {
|
||||||
if (sub.subscriptionId === res.subscription) {
|
if (sub.subscriptionId === res.subscription) {
|
||||||
// Signatures subscriptions are auto-removed by the RPC service so
|
if (res.result.value === 'receivedSignature') {
|
||||||
// no need to explicitly send an unsubscribe message
|
sub.callback(
|
||||||
delete this._signatureSubscriptions[Number(id)];
|
{
|
||||||
this._updateSubscriptions();
|
type: 'received',
|
||||||
sub.callback(res.result.value, res.result.context);
|
},
|
||||||
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3170,12 +3221,42 @@ export class Connection {
|
||||||
signature: TransactionSignature,
|
signature: TransactionSignature,
|
||||||
callback: SignatureResultCallback,
|
callback: SignatureResultCallback,
|
||||||
commitment?: Commitment,
|
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 {
|
): number {
|
||||||
const id = ++this._signatureSubscriptionCounter;
|
const id = ++this._signatureSubscriptionCounter;
|
||||||
this._signatureSubscriptions[id] = {
|
this._signatureSubscriptions[id] = {
|
||||||
signature,
|
signature,
|
||||||
callback,
|
callback,
|
||||||
commitment,
|
options,
|
||||||
subscriptionId: null,
|
subscriptionId: null,
|
||||||
};
|
};
|
||||||
this._updateSubscriptions();
|
this._updateSubscriptions();
|
||||||
|
|
Loading…
Reference in New Issue