@massalabs/gossip-sdk 0.0.2-dev.20260217151032 → 0.0.2-dev.20260218140635
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/messageProtocol/rest.d.ts +1 -0
- package/dist/api/messageProtocol/rest.js +10 -0
- package/dist/api/messageProtocol/types.d.ts +4 -0
- package/dist/gossip.d.ts +2 -0
- package/dist/gossip.js +2 -0
- package/dist/services/announcement.d.ts +8 -2
- package/dist/services/announcement.js +32 -15
- package/package.json +1 -1
|
@@ -15,6 +15,7 @@ export declare class RestMessageProtocol implements IMessageProtocol {
|
|
|
15
15
|
sendMessage(message: EncryptedMessage): Promise<void>;
|
|
16
16
|
sendAnnouncement(announcement: Uint8Array): Promise<string>;
|
|
17
17
|
fetchAnnouncements(limit?: number, cursor?: string): Promise<BulletinItem[]>;
|
|
18
|
+
fetchBulletinCounter(): Promise<string>;
|
|
18
19
|
fetchPublicKeyByUserId(userId: Uint8Array): Promise<string>;
|
|
19
20
|
postPublicKey(base64PublicKeys: string): Promise<string>;
|
|
20
21
|
private makeRequest;
|
|
@@ -91,6 +91,16 @@ export class RestMessageProtocol {
|
|
|
91
91
|
data: decodeFromBase64(item.data),
|
|
92
92
|
}));
|
|
93
93
|
}
|
|
94
|
+
async fetchBulletinCounter() {
|
|
95
|
+
const url = `${this.baseUrl}${BULLETIN_ENDPOINT}/counter`;
|
|
96
|
+
const response = await this.makeRequest(url, {
|
|
97
|
+
method: 'GET',
|
|
98
|
+
});
|
|
99
|
+
if (!response.success || !response.data) {
|
|
100
|
+
throw new Error(response.error || 'Failed to fetch bulletin counter');
|
|
101
|
+
}
|
|
102
|
+
return response.data.counter;
|
|
103
|
+
}
|
|
94
104
|
async fetchPublicKeyByUserId(userId) {
|
|
95
105
|
const response = await this.makeRequest(`${this.baseUrl}/auth/retrieve`, {
|
|
96
106
|
method: 'POST',
|
|
@@ -40,6 +40,10 @@ export interface IMessageProtocol {
|
|
|
40
40
|
* @param cursor - Optional cursor (counter) to fetch announcements after this value
|
|
41
41
|
*/
|
|
42
42
|
fetchAnnouncements(limit?: number, cursor?: string): Promise<BulletinItem[]>;
|
|
43
|
+
/**
|
|
44
|
+
* Fetch the latest bulletin counter from the API without downloading announcement data.
|
|
45
|
+
*/
|
|
46
|
+
fetchBulletinCounter(): Promise<string>;
|
|
43
47
|
/**
|
|
44
48
|
* Fetch public key by userId hash (base64 string)
|
|
45
49
|
* @param userId - Decoded userId bytes
|
package/dist/gossip.d.ts
CHANGED
|
@@ -196,6 +196,8 @@ interface DiscussionServiceAPI {
|
|
|
196
196
|
interface AnnouncementServiceAPI {
|
|
197
197
|
/** Fetch and process announcements from the protocol */
|
|
198
198
|
fetch(): Promise<AnnouncementReceptionResult>;
|
|
199
|
+
/** Skip historical announcements for a new account. Call after profile creation. */
|
|
200
|
+
skipHistorical(): Promise<void>;
|
|
199
201
|
}
|
|
200
202
|
interface ContactsAPI {
|
|
201
203
|
/** List all contacts for the owner */
|
package/dist/gossip.js
CHANGED
|
@@ -230,6 +230,7 @@ class GossipSdk {
|
|
|
230
230
|
this._refresh = new RefreshService(db, this._message, this._discussion, this._announcement, session, this.eventEmitter);
|
|
231
231
|
// Publish gossip ID so the user is discoverable (fire-and-forget — don't block login)
|
|
232
232
|
this._auth.ensurePublicKeyPublished(session.ourPk, session.userIdEncoded).catch(err => console.warn('[GossipSdk] Failed to publish public key:', err));
|
|
233
|
+
// Update SDK state to reflect the newly opened session.
|
|
233
234
|
this.state = {
|
|
234
235
|
status: SdkStatus.SESSION_OPEN,
|
|
235
236
|
messageProtocol: this.state.messageProtocol,
|
|
@@ -304,6 +305,7 @@ class GossipSdk {
|
|
|
304
305
|
await this._refresh?.stateUpdate();
|
|
305
306
|
return result;
|
|
306
307
|
},
|
|
308
|
+
skipHistorical: () => this._announcement.skipHistoricalAnnouncements(),
|
|
307
309
|
};
|
|
308
310
|
this._contactsAPI = {
|
|
309
311
|
list: ownerUserId => getContacts(ownerUserId, db),
|
|
@@ -35,10 +35,16 @@ export declare class AnnouncementService {
|
|
|
35
35
|
fetchAndProcessAnnouncements(): Promise<AnnouncementReceptionResult>;
|
|
36
36
|
/**
|
|
37
37
|
* Persist lastBulletinCounter for the current user.
|
|
38
|
-
*
|
|
39
|
-
*
|
|
38
|
+
* Only updates an existing profile row — never creates a partial one,
|
|
39
|
+
* since a row without `security`/`session` would crash downstream code.
|
|
40
40
|
*/
|
|
41
41
|
private _upsertLastBulletinCounter;
|
|
42
|
+
/**
|
|
43
|
+
* Fetch the latest bulletin counter from the API and persist it so that
|
|
44
|
+
* historical announcements (undecryptable by a new account) are skipped.
|
|
45
|
+
* No-op if a counter already exists or if the profile hasn't been created yet.
|
|
46
|
+
*/
|
|
47
|
+
skipHistoricalAnnouncements(): Promise<void>;
|
|
42
48
|
private _fetchAnnouncements;
|
|
43
49
|
private _generateTemporaryContactName;
|
|
44
50
|
private _processIncomingAnnouncement;
|
|
@@ -267,30 +267,47 @@ export class AnnouncementService {
|
|
|
267
267
|
}
|
|
268
268
|
/**
|
|
269
269
|
* Persist lastBulletinCounter for the current user.
|
|
270
|
-
*
|
|
271
|
-
*
|
|
270
|
+
* Only updates an existing profile row — never creates a partial one,
|
|
271
|
+
* since a row without `security`/`session` would crash downstream code.
|
|
272
272
|
*/
|
|
273
273
|
async _upsertLastBulletinCounter(nextCounter) {
|
|
274
274
|
const userId = this.session.userIdEncoded;
|
|
275
275
|
const existing = await this.db.userProfile.get(userId);
|
|
276
|
-
if (existing) {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
});
|
|
276
|
+
if (!existing) {
|
|
277
|
+
logger
|
|
278
|
+
.forMethod('_upsertLastBulletinCounter')
|
|
279
|
+
.debug('no profile row yet — skipping counter write');
|
|
281
280
|
return;
|
|
282
281
|
}
|
|
283
|
-
|
|
284
|
-
await this.db.userProfile.put({
|
|
285
|
-
userId,
|
|
286
|
-
username: '',
|
|
287
|
-
status: 'offline',
|
|
288
|
-
lastSeen: new Date(),
|
|
289
|
-
createdAt: new Date(),
|
|
290
|
-
updatedAt: new Date(),
|
|
282
|
+
await this.db.userProfile.update(userId, {
|
|
291
283
|
lastBulletinCounter: nextCounter,
|
|
284
|
+
updatedAt: new Date(),
|
|
292
285
|
});
|
|
293
286
|
}
|
|
287
|
+
/**
|
|
288
|
+
* Fetch the latest bulletin counter from the API and persist it so that
|
|
289
|
+
* historical announcements (undecryptable by a new account) are skipped.
|
|
290
|
+
* No-op if a counter already exists or if the profile hasn't been created yet.
|
|
291
|
+
*/
|
|
292
|
+
async skipHistoricalAnnouncements() {
|
|
293
|
+
const log = logger.forMethod('skipHistoricalAnnouncements');
|
|
294
|
+
const existing = await this.db.userProfile.get(this.session.userIdEncoded);
|
|
295
|
+
if (!existing) {
|
|
296
|
+
log.debug('no profile row yet — skipping');
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
if (existing.lastBulletinCounter !== undefined)
|
|
300
|
+
return;
|
|
301
|
+
try {
|
|
302
|
+
const counter = await this.messageProtocol.fetchBulletinCounter();
|
|
303
|
+
await this._upsertLastBulletinCounter(counter);
|
|
304
|
+
log.info('set initial bulletin counter for new account', { counter });
|
|
305
|
+
}
|
|
306
|
+
catch (err) {
|
|
307
|
+
// Non-critical — on failure the first fetch starts from the beginning.
|
|
308
|
+
log.warn('failed to initialize bulletin counter', { err });
|
|
309
|
+
}
|
|
310
|
+
}
|
|
294
311
|
async _fetchAnnouncements(cursor, limit) {
|
|
295
312
|
const fetchLimit = limit ?? this.config.announcements.fetchLimit;
|
|
296
313
|
const log = logger.forMethod('_fetchAnnouncements');
|
package/package.json
CHANGED