@massalabs/gossip-sdk 0.0.2-dev.20260223065033 → 0.0.2-dev.20260223101931
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/README.md +7 -2
- package/dist/gossip.d.ts +3 -14
- package/dist/gossip.js +27 -41
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -33,6 +33,11 @@ await sdk.init();
|
|
|
33
33
|
// 2. Open session (login)
|
|
34
34
|
await sdk.openSession({
|
|
35
35
|
mnemonic: 'word1 word2 word3 ... word12',
|
|
36
|
+
// Optional: for existing session
|
|
37
|
+
// encryptedSession: savedBlob,
|
|
38
|
+
// encryptionKey, // optional - derived from mnemonic if not provided
|
|
39
|
+
// Optional: for persistence
|
|
40
|
+
// onPersist: async (blob, key) => { await saveToStorage(blob, key); },
|
|
36
41
|
});
|
|
37
42
|
|
|
38
43
|
// 3. Use the SDK
|
|
@@ -308,12 +313,12 @@ await sdk.init({
|
|
|
308
313
|
|
|
309
314
|
## Session Persistence
|
|
310
315
|
|
|
311
|
-
For restoring sessions across app restarts:
|
|
316
|
+
For restoring sessions across app restarts, pass `encryptionKey` (optional — derived from mnemonic if omitted) and `onPersist` when opening the session:
|
|
312
317
|
|
|
313
318
|
```typescript
|
|
314
319
|
await sdk.openSession({
|
|
315
320
|
mnemonic,
|
|
316
|
-
encryptionKey,
|
|
321
|
+
encryptionKey, // optional
|
|
317
322
|
onPersist: async (blob, key) => {
|
|
318
323
|
await storage.save({ session: blob });
|
|
319
324
|
},
|
package/dist/gossip.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { type SdkConfig, type DeepPartial } from './config/sdk';
|
|
2
|
-
import { SessionStatus, SessionConfig } from './assets/generated/wasm/gossip_wasm';
|
|
3
2
|
import { EncryptionKey } from './wasm/encryption';
|
|
4
3
|
import { type AnnouncementReceptionResult } from './services/announcement';
|
|
5
4
|
import { DiscussionInitializationResult } from './services/discussion';
|
|
@@ -8,7 +7,7 @@ import { AuthService } from './services/auth';
|
|
|
8
7
|
import type { DeleteContactResult, UpdateContactNameResult } from './utils/contacts';
|
|
9
8
|
import { type ValidationResult } from './utils/validation';
|
|
10
9
|
import { type Contact, type Discussion, type Message } from './db';
|
|
11
|
-
import type
|
|
10
|
+
import { type UserPublicKeys, type SessionConfig, SessionStatus } from './wasm/bindings';
|
|
12
11
|
import { SdkEventType, type SdkEventHandlers } from './core/SdkEventEmitter';
|
|
13
12
|
import { AnnouncementPayload } from './utils/announcementPayload';
|
|
14
13
|
import { Result } from './utils/type';
|
|
@@ -38,12 +37,10 @@ export interface OpenSessionOptions {
|
|
|
38
37
|
mnemonic: string;
|
|
39
38
|
/** Existing encrypted session blob (for restoring session) */
|
|
40
39
|
encryptedSession?: Uint8Array;
|
|
41
|
-
/** Encryption key for decrypting session */
|
|
40
|
+
/** Encryption key for decrypting session and storage. Will be created if not provided. */
|
|
42
41
|
encryptionKey?: EncryptionKey;
|
|
43
42
|
/** Callback when session state changes (for persistence) */
|
|
44
43
|
onPersist?: (encryptedBlob: Uint8Array, encryptionKey: EncryptionKey) => Promise<void>;
|
|
45
|
-
/** Encryption key for persisting session (required if onPersist is provided) */
|
|
46
|
-
persistEncryptionKey?: EncryptionKey;
|
|
47
44
|
/** Custom session configuration (optional, uses defaults if not provided) */
|
|
48
45
|
sessionConfig?: SessionConfig;
|
|
49
46
|
}
|
|
@@ -93,15 +90,7 @@ declare class GossipSdk {
|
|
|
93
90
|
* Get encrypted session blob for persistence.
|
|
94
91
|
* Throws if no session is open.
|
|
95
92
|
*/
|
|
96
|
-
getEncryptedSession(
|
|
97
|
-
/**
|
|
98
|
-
* Configure session persistence after session is opened.
|
|
99
|
-
* Use this when you need to set up persistence after account creation.
|
|
100
|
-
*
|
|
101
|
-
* @param encryptionKey - Key to encrypt session blob
|
|
102
|
-
* @param onPersist - Callback to save encrypted session blob
|
|
103
|
-
*/
|
|
104
|
-
configurePersistence(encryptionKey: EncryptionKey, onPersist: (encryptedBlob: Uint8Array, encryptionKey: EncryptionKey) => Promise<void>): void;
|
|
93
|
+
getEncryptedSession(): Uint8Array;
|
|
105
94
|
/** Auth service (available after init, before session) */
|
|
106
95
|
get auth(): AuthService;
|
|
107
96
|
/** Message service */
|
package/dist/gossip.js
CHANGED
|
@@ -46,6 +46,7 @@ import { defaultSdkConfig, mergeConfig, } from './config/sdk';
|
|
|
46
46
|
import { startWasmInitialization, ensureWasmInitialized } from './wasm/loader';
|
|
47
47
|
import { generateUserKeys } from './wasm/userKeys';
|
|
48
48
|
import { SessionModule } from './wasm/session';
|
|
49
|
+
import { generateEncryptionKeyFromSeed, } from './wasm/encryption';
|
|
49
50
|
import { AnnouncementService, } from './services/announcement';
|
|
50
51
|
import { DiscussionService, } from './services/discussion';
|
|
51
52
|
import { MessageService, rowToMessage, } from './services/message';
|
|
@@ -56,6 +57,7 @@ import { QueueManager } from './utils/queue';
|
|
|
56
57
|
import { encodeUserId, decodeUserId } from './utils/userId';
|
|
57
58
|
import { initDb, getMessageById, getMessagesByOwnerAndContact, getMessagesByStatus, updateMessageById, getDiscussionByOwnerAndContact, getDiscussionsByOwner, getContactsByOwner, getContactByOwnerAndUser, MessageStatus, } from './db';
|
|
58
59
|
import { addContact, updateContactName, deleteContact } from './utils/contacts';
|
|
60
|
+
import { SessionManagerWrapper, } from './wasm/bindings';
|
|
59
61
|
import { SdkEventEmitter, SdkEventType, } from './core/SdkEventEmitter';
|
|
60
62
|
import { SdkPolling } from './core/SdkPolling';
|
|
61
63
|
export { SdkEventType };
|
|
@@ -198,23 +200,23 @@ class GossipSdk {
|
|
|
198
200
|
if (this.state.status === SdkStatus.SESSION_OPEN) {
|
|
199
201
|
throw new Error('Session already open. Call closeSession() first.');
|
|
200
202
|
}
|
|
201
|
-
//
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}
|
|
205
|
-
if (options.encryptionKey && !options.encryptedSession) {
|
|
206
|
-
console.warn('[GossipSdk] encryptionKey provided without encryptedSession - key will be ignored');
|
|
207
|
-
}
|
|
208
|
-
// Validate persistence options
|
|
209
|
-
if (options.onPersist && !options.persistEncryptionKey) {
|
|
210
|
-
throw new Error('persistEncryptionKey is required when onPersist is provided.');
|
|
211
|
-
}
|
|
212
|
-
if (options.persistEncryptionKey && !options.onPersist) {
|
|
213
|
-
console.warn('[GossipSdk] persistEncryptionKey provided without onPersist callback - key will be unused');
|
|
214
|
-
}
|
|
203
|
+
// Derive encryption key from mnemonic when not provided
|
|
204
|
+
const encryptionKey = options.encryptionKey ??
|
|
205
|
+
(await generateEncryptionKeyFromSeed(options.mnemonic, new Uint8Array(32).fill(0)));
|
|
215
206
|
const { messageProtocol } = this.state;
|
|
216
207
|
// Ensure WASM is ready
|
|
217
208
|
await ensureWasmInitialized();
|
|
209
|
+
// Validate that encryptedSession can be decrypted with the provided key
|
|
210
|
+
if (options.encryptedSession) {
|
|
211
|
+
try {
|
|
212
|
+
const sessionManager = SessionManagerWrapper.from_encrypted_blob(options.encryptedSession, encryptionKey);
|
|
213
|
+
// We only create this wrapper for validation, free it immediately
|
|
214
|
+
sessionManager.free();
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
throw new Error('[GossipSdk] Failed to load encrypted session. Please provide a valid encryptedSession and encryptionKey.');
|
|
218
|
+
}
|
|
219
|
+
}
|
|
218
220
|
// Generate keys from mnemonic
|
|
219
221
|
const userKeys = await generateUserKeys(options.mnemonic);
|
|
220
222
|
// Create session with persistence callback
|
|
@@ -223,8 +225,8 @@ class GossipSdk {
|
|
|
223
225
|
await this.handleSessionPersist();
|
|
224
226
|
}, options.sessionConfig);
|
|
225
227
|
// Restore existing session state if provided
|
|
226
|
-
if (options.encryptedSession
|
|
227
|
-
session.load(options.encryptedSession,
|
|
228
|
+
if (options.encryptedSession) {
|
|
229
|
+
session.load(options.encryptedSession, encryptionKey);
|
|
228
230
|
}
|
|
229
231
|
// Get config from initialized state
|
|
230
232
|
const { config } = this.state;
|
|
@@ -249,7 +251,7 @@ class GossipSdk {
|
|
|
249
251
|
config,
|
|
250
252
|
session,
|
|
251
253
|
userKeys,
|
|
252
|
-
|
|
254
|
+
encryptionKey,
|
|
253
255
|
onPersist: options.onPersist,
|
|
254
256
|
};
|
|
255
257
|
// Create cached service API wrappers
|
|
@@ -369,28 +371,12 @@ class GossipSdk {
|
|
|
369
371
|
* Get encrypted session blob for persistence.
|
|
370
372
|
* Throws if no session is open.
|
|
371
373
|
*/
|
|
372
|
-
getEncryptedSession(
|
|
374
|
+
getEncryptedSession() {
|
|
373
375
|
const state = this.requireSession();
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
/**
|
|
377
|
-
* Configure session persistence after session is opened.
|
|
378
|
-
* Use this when you need to set up persistence after account creation.
|
|
379
|
-
*
|
|
380
|
-
* @param encryptionKey - Key to encrypt session blob
|
|
381
|
-
* @param onPersist - Callback to save encrypted session blob
|
|
382
|
-
*/
|
|
383
|
-
configurePersistence(encryptionKey, onPersist) {
|
|
384
|
-
if (this.state.status !== SdkStatus.SESSION_OPEN) {
|
|
385
|
-
throw new Error('No session open. Call openSession() first.');
|
|
376
|
+
if (!state.encryptionKey) {
|
|
377
|
+
throw new Error('No encryption key found. Call openSession() first.');
|
|
386
378
|
}
|
|
387
|
-
|
|
388
|
-
this.state = {
|
|
389
|
-
...this.state,
|
|
390
|
-
persistEncryptionKey: encryptionKey,
|
|
391
|
-
onPersist,
|
|
392
|
-
};
|
|
393
|
-
console.log('[GossipSdk] Session persistence configured');
|
|
379
|
+
return state.session.toEncryptedBlob(state.encryptionKey);
|
|
394
380
|
}
|
|
395
381
|
// ─────────────────────────────────────────────────────────────────
|
|
396
382
|
// Services (accessible only when session is open)
|
|
@@ -524,13 +510,13 @@ class GossipSdk {
|
|
|
524
510
|
async handleSessionPersist() {
|
|
525
511
|
if (this.state.status !== SdkStatus.SESSION_OPEN)
|
|
526
512
|
return;
|
|
527
|
-
const { onPersist,
|
|
528
|
-
if (!onPersist || !
|
|
513
|
+
const { onPersist, encryptionKey, session } = this.state;
|
|
514
|
+
if (!onPersist || !encryptionKey)
|
|
529
515
|
return;
|
|
530
516
|
try {
|
|
531
|
-
const blob = session.toEncryptedBlob(
|
|
517
|
+
const blob = session.toEncryptedBlob(encryptionKey);
|
|
532
518
|
console.log(`[SessionPersist] Saving session blob (${blob.length} bytes)`);
|
|
533
|
-
await onPersist(blob,
|
|
519
|
+
await onPersist(blob, encryptionKey);
|
|
534
520
|
}
|
|
535
521
|
catch (error) {
|
|
536
522
|
this.eventEmitter.emit(SdkEventType.ERROR, error instanceof Error ? error : new Error(String(error)), 'session_persist');
|
package/package.json
CHANGED