diff --git a/packages/notify-client/src/client.ts b/packages/notify-client/src/client.ts index e7878aec..28e9fcf5 100644 --- a/packages/notify-client/src/client.ts +++ b/packages/notify-client/src/client.ts @@ -35,6 +35,7 @@ export class NotifyClient extends INotifyClient { public messages: INotifyClient["messages"]; public watchedAccounts: INotifyClient["watchedAccounts"]; public registrationData: INotifyClient["registrationData"]; + public clientStateMaintenance: INotifyClient["clientStateMaintenance"]; public identityKeys: INotifyClient["identityKeys"]; static async init(opts: NotifyClientTypes.ClientOptions) { @@ -95,6 +96,15 @@ export class NotifyClient extends INotifyClient { this.identityKeys = opts.identityKeys ?? new IdentityKeys(this.core, this.keyserverUrl); + + this.clientStateMaintenance = new Store( + this.core, + this.logger, + "clientStateMaintenance", + NOTIFY_CLIENT_STORAGE_PREFIX, + () => "stateMaintenance" + ); + this.engine = new NotifyEngine(this); } @@ -244,6 +254,7 @@ export class NotifyClient extends INotifyClient { await this.registrationData.init(); await this.identityKeys.init(); await this.watchedAccounts.init(); + await this.clientStateMaintenance.init(); await this.engine.init(); this.logger.info(`NotifyClient Initialization Success`); diff --git a/packages/notify-client/src/controllers/engine.ts b/packages/notify-client/src/controllers/engine.ts index 74b8cf6e..94a5e705 100644 --- a/packages/notify-client/src/controllers/engine.ts +++ b/packages/notify-client/src/controllers/engine.ts @@ -1243,6 +1243,20 @@ export class NotifyEngine extends INotifyEngine { | NotifyClientTypes.UpdateResponseJWTClaims >(jwt, act); + const latestSubscriptionSequence = this.client.clientStateMaintenance.length + ? this.client.clientStateMaintenance.get("stateMaintenance") + .latestSubscriptionSequence + : 0; + + const incomingMessageIsOld = latestSubscriptionSequence > claims.seq; + if (incomingMessageIsOld) { + return this.client.subscriptions.getAll(); + } + + await this.client.clientStateMaintenance.set("stateMaintenance", { + latestSubscriptionSequence: claims.seq, + }); + this.client.logger.info("updateSubscriptionsUsingJwt > claims", claims); // Clean up any subscriptions that are no longer valid. diff --git a/packages/notify-client/src/types/client.ts b/packages/notify-client/src/types/client.ts index 685f0b40..2c96f61d 100644 --- a/packages/notify-client/src/types/client.ts +++ b/packages/notify-client/src/types/client.ts @@ -208,6 +208,7 @@ export declare namespace NotifyClientTypes { aud: string; // did:pkh blockchain account that notify subscription is associated with sub: string; // did:pkh of blockchain account that this notify subscription is associated with sbs: NotifyServerSubscription[]; // array of [Notify Server Subscriptions] + seq: number; } interface CommonResponseJWTClaims extends BaseJwtClaims { @@ -220,16 +221,19 @@ export declare namespace NotifyClientTypes { interface SubscriptionResponseJWTClaims extends CommonResponseJWTClaims { act: "notify_subscription_response"; sbs: NotifyServerSubscription[]; // array of [Notify Server Subscriptions] + seq: number; } interface UpdateResponseJWTClaims extends CommonResponseJWTClaims { act: "notify_update_response"; sbs: NotifyServerSubscription[]; // array of [Notify Server Subscriptions] + seq: number; } interface DeleteResponseJWTClaims extends CommonResponseJWTClaims { act: "notify_delete_response"; sbs: NotifyServerSubscription[]; // array of [Notify Server Subscriptions] + seq: number; } interface GetNotificationsResponseClaims extends BaseJwtClaims { @@ -247,6 +251,7 @@ export declare namespace NotifyClientTypes { aud: string; // did:key of client identity key sub: string; // did:key of the public key used for key agreement on the Notify topic sbs: NotifyServerSubscription[]; // array of [Notify Server Subscriptions] + seq: number; } interface NotifySubscriptionsChangedResponseClaims extends BaseJwtClaims { @@ -331,6 +336,13 @@ export abstract class INotifyClient { } >; + public abstract clientStateMaintenance: IStore< + "stateMaintenance", + { + latestSubscriptionSequence: number; + } + >; + public abstract identityKeys: IdentityKeys; public abstract subscriptions: IStore<