@massalabs/gossip-sdk 0.0.2-dev.20260130145448 → 0.0.2-dev.20260211110128
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/contacts.d.ts +1 -1
- package/dist/gossipSdk.d.ts +3 -2
- package/dist/gossipSdk.js +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.js +6 -4
- package/dist/services/announcement.d.ts +2 -2
- package/dist/services/announcement.js +7 -50
- package/dist/services/auth.d.ts +1 -1
- package/dist/services/auth.js +1 -1
- package/dist/services/discussion.d.ts +14 -2
- package/dist/services/discussion.js +21 -30
- package/dist/services/message.js +1 -1
- package/dist/services/refresh.js +1 -1
- package/dist/utils/announcementPayload.d.ts +6 -0
- package/dist/utils/announcementPayload.js +23 -0
- package/dist/wasm/bindings.d.ts +9 -0
- package/dist/wasm/bindings.js +9 -0
- package/dist/wasm/encryption.d.ts +1 -1
- package/dist/wasm/encryption.js +1 -1
- package/dist/wasm/loader.d.ts +4 -4
- package/dist/wasm/loader.js +26 -13
- package/dist/wasm/session.d.ts +1 -1
- package/dist/wasm/session.js +1 -1
- package/dist/wasm/userKeys.d.ts +1 -1
- package/dist/wasm/userKeys.js +1 -1
- package/package.json +5 -9
- package/dist/assets/generated/wasm-node/README.md +0 -281
- package/dist/assets/generated/wasm-node/gossip_wasm.d.ts +0 -443
- package/dist/assets/generated/wasm-node/gossip_wasm.js +0 -1488
- package/dist/assets/generated/wasm-node/gossip_wasm_bg.wasm +0 -0
- package/dist/assets/generated/wasm-node/gossip_wasm_bg.wasm.d.ts +0 -164
- package/dist/assets/generated/wasm-node/package.json +0 -11
package/dist/contacts.d.ts
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
*/
|
|
20
20
|
import { type Contact, type GossipDatabase } from './db';
|
|
21
21
|
import type { UpdateContactNameResult, DeleteContactResult } from './utils/contacts';
|
|
22
|
-
import type { UserPublicKeys } from '
|
|
22
|
+
import type { UserPublicKeys } from './wasm/bindings';
|
|
23
23
|
import type { SessionModule } from './wasm/session';
|
|
24
24
|
export type { UpdateContactNameResult, DeleteContactResult };
|
|
25
25
|
/**
|
package/dist/gossipSdk.d.ts
CHANGED
|
@@ -46,8 +46,9 @@ import { type MessageResult, type SendMessageResult } from './services/message';
|
|
|
46
46
|
import { AuthService } from './services/auth';
|
|
47
47
|
import type { DeleteContactResult, UpdateContactNameResult } from './utils/contacts';
|
|
48
48
|
import { type ValidationResult } from './utils/validation';
|
|
49
|
-
import type { UserPublicKeys } from '
|
|
49
|
+
import type { UserPublicKeys } from './wasm/bindings';
|
|
50
50
|
import { type SdkEventType, type SdkEventHandlers } from './core/SdkEventEmitter';
|
|
51
|
+
import { AnnouncementPayload } from './utils/announcementPayload';
|
|
51
52
|
export type { SdkEventType, SdkEventHandlers };
|
|
52
53
|
export interface GossipSdkInitOptions {
|
|
53
54
|
/** Database instance */
|
|
@@ -210,7 +211,7 @@ interface MessageServiceAPI {
|
|
|
210
211
|
}
|
|
211
212
|
interface DiscussionServiceAPI {
|
|
212
213
|
/** Start a new discussion with a contact */
|
|
213
|
-
start(contact: Contact,
|
|
214
|
+
start(contact: Contact, payload: AnnouncementPayload): Promise<{
|
|
214
215
|
discussionId: number;
|
|
215
216
|
announcement: Uint8Array;
|
|
216
217
|
}>;
|
package/dist/gossipSdk.js
CHANGED
|
@@ -322,7 +322,7 @@ class GossipSdkImpl {
|
|
|
322
322
|
findBySeeker: (seeker, ownerUserId) => this._message.findMessageBySeeker(seeker, ownerUserId),
|
|
323
323
|
};
|
|
324
324
|
this._discussionsAPI = {
|
|
325
|
-
start: (contact,
|
|
325
|
+
start: (contact, payload) => this._discussion.initialize(contact, payload),
|
|
326
326
|
accept: discussion => this._discussion.accept(discussion),
|
|
327
327
|
renew: contactUserId => this._discussion.renew(contactUserId),
|
|
328
328
|
isStable: (ownerUserId, contactUserId) => this._discussion.isStableState(ownerUserId, contactUserId),
|
package/dist/index.d.ts
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* Main entry point for the Gossip SDK.
|
|
5
5
|
* Works in both browser and Node.js environments.
|
|
6
6
|
*
|
|
7
|
-
* WASM is loaded via the
|
|
8
|
-
* - Browser:
|
|
9
|
-
* - Node
|
|
7
|
+
* WASM is loaded via the web target build with runtime detection:
|
|
8
|
+
* - Browser: init() uses import.meta.url + fetch
|
|
9
|
+
* - Node.js / Jiti: init(bytes) reads the .wasm file from disk
|
|
10
10
|
*
|
|
11
11
|
* @example
|
|
12
12
|
* ```typescript
|
|
@@ -35,6 +35,8 @@ export { getContacts, getContact, addContact, updateContactName, deleteContact,
|
|
|
35
35
|
export type { UpdateContactNameResult, DeleteContactResult, } from './utils/contacts';
|
|
36
36
|
export { updateDiscussionName } from './utils/discussions';
|
|
37
37
|
export type { UpdateDiscussionNameResult } from './utils/discussions';
|
|
38
|
+
export { encodeAnnouncementPayload, decodeAnnouncementPayload, } from './utils/announcementPayload';
|
|
39
|
+
export type { AnnouncementPayload } from './utils/announcementPayload';
|
|
38
40
|
export * from './types';
|
|
39
41
|
export { createMessageProtocol, restMessageProtocol, RestMessageProtocol, MessageProtocol, } from './api/messageProtocol';
|
|
40
42
|
export type { IMessageProtocol, EncryptedMessage, MessageProtocolResponse, BulletinItem, } from './api/messageProtocol';
|
|
@@ -56,4 +58,4 @@ export { MESSAGE_TYPE_KEEP_ALIVE, serializeKeepAliveMessage, serializeRegularMes
|
|
|
56
58
|
export type { DeserializedMessage } from './utils/messageSerialization';
|
|
57
59
|
export { generateMnemonic, validateMnemonic, mnemonicToSeed, accountFromMnemonic, PRIVATE_KEY_VERSION, } from './crypto/bip39';
|
|
58
60
|
export { encrypt, decrypt, deriveKey } from './crypto/encryption';
|
|
59
|
-
export { UserPublicKeys, UserSecretKeys, SessionStatus, SessionConfig, SessionManagerWrapper, SendMessageOutput, ReceiveMessageOutput, AnnouncementResult, generate_user_keys, } from '
|
|
61
|
+
export { UserPublicKeys, UserSecretKeys, SessionStatus, SessionConfig, SessionManagerWrapper, SendMessageOutput, ReceiveMessageOutput, AnnouncementResult, generate_user_keys, } from './wasm/bindings';
|
package/dist/index.js
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* Main entry point for the Gossip SDK.
|
|
5
5
|
* Works in both browser and Node.js environments.
|
|
6
6
|
*
|
|
7
|
-
* WASM is loaded via the
|
|
8
|
-
* - Browser:
|
|
9
|
-
* - Node
|
|
7
|
+
* WASM is loaded via the web target build with runtime detection:
|
|
8
|
+
* - Browser: init() uses import.meta.url + fetch
|
|
9
|
+
* - Node.js / Jiti: init(bytes) reads the .wasm file from disk
|
|
10
10
|
*
|
|
11
11
|
* @example
|
|
12
12
|
* ```typescript
|
|
@@ -34,6 +34,8 @@ export { RefreshService } from './services/refresh';
|
|
|
34
34
|
export { getContacts, getContact, addContact, updateContactName, deleteContact, } from './contacts';
|
|
35
35
|
// Discussion utilities
|
|
36
36
|
export { updateDiscussionName } from './utils/discussions';
|
|
37
|
+
// Announcement payload helpers
|
|
38
|
+
export { encodeAnnouncementPayload, decodeAnnouncementPayload, } from './utils/announcementPayload';
|
|
37
39
|
// Types
|
|
38
40
|
export * from './types';
|
|
39
41
|
// Message Protocol
|
|
@@ -58,4 +60,4 @@ export { MESSAGE_TYPE_KEEP_ALIVE, serializeKeepAliveMessage, serializeRegularMes
|
|
|
58
60
|
export { generateMnemonic, validateMnemonic, mnemonicToSeed, accountFromMnemonic, PRIVATE_KEY_VERSION, } from './crypto/bip39';
|
|
59
61
|
export { encrypt, decrypt, deriveKey } from './crypto/encryption';
|
|
60
62
|
// WASM types re-exported for convenience
|
|
61
|
-
export { UserPublicKeys, UserSecretKeys, SessionStatus, SessionConfig, SessionManagerWrapper, SendMessageOutput, ReceiveMessageOutput, AnnouncementResult, generate_user_keys, } from '
|
|
63
|
+
export { UserPublicKeys, UserSecretKeys, SessionStatus, SessionConfig, SessionManagerWrapper, SendMessageOutput, ReceiveMessageOutput, AnnouncementResult, generate_user_keys, } from './wasm/bindings';
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { type Discussion, type GossipDatabase } from '../db';
|
|
7
7
|
import { IMessageProtocol } from '../api/messageProtocol';
|
|
8
|
-
import { UserPublicKeys } from '
|
|
8
|
+
import { UserPublicKeys } from '../wasm/bindings';
|
|
9
9
|
import { SessionModule } from '../wasm/session';
|
|
10
10
|
import { GossipSdkEvents } from '../types/events';
|
|
11
11
|
import { SdkConfig } from '../config/sdk';
|
|
@@ -29,7 +29,7 @@ export declare class AnnouncementService {
|
|
|
29
29
|
counter?: string;
|
|
30
30
|
error?: string;
|
|
31
31
|
}>;
|
|
32
|
-
establishSession(contactPublicKeys: UserPublicKeys,
|
|
32
|
+
establishSession(contactPublicKeys: UserPublicKeys, payloadBytes?: Uint8Array): Promise<{
|
|
33
33
|
success: boolean;
|
|
34
34
|
error?: string;
|
|
35
35
|
announcement: Uint8Array;
|
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { DiscussionStatus, DiscussionDirection, } from '../db';
|
|
7
7
|
import { decodeUserId, encodeUserId } from '../utils/userId';
|
|
8
|
-
import { SessionStatus } from '
|
|
8
|
+
import { SessionStatus } from '../wasm/bindings';
|
|
9
9
|
import { sessionStatusToString } from '../wasm/session';
|
|
10
10
|
import { Logger } from '../utils/logs';
|
|
11
11
|
import { defaultSdkConfig } from '../config/sdk';
|
|
12
|
+
import { decodeAnnouncementPayload } from '../utils/announcementPayload';
|
|
12
13
|
const logger = new Logger('AnnouncementService');
|
|
13
14
|
export const EstablishSessionError = 'Session manager failed to establish outgoing session';
|
|
14
15
|
export class AnnouncementService {
|
|
@@ -73,11 +74,11 @@ export class AnnouncementService {
|
|
|
73
74
|
};
|
|
74
75
|
}
|
|
75
76
|
}
|
|
76
|
-
async establishSession(contactPublicKeys,
|
|
77
|
+
async establishSession(contactPublicKeys, payloadBytes) {
|
|
77
78
|
const log = logger.forMethod('establishSession');
|
|
78
79
|
const contactUserId = encodeUserId(contactPublicKeys.derive_id());
|
|
79
80
|
// CRITICAL: await to ensure session state is persisted before sending
|
|
80
|
-
const announcement = await this.session.establishOutgoingSession(contactPublicKeys,
|
|
81
|
+
const announcement = await this.session.establishOutgoingSession(contactPublicKeys, payloadBytes);
|
|
81
82
|
if (announcement.length === 0) {
|
|
82
83
|
log.error('empty announcement returned', { contactUserId });
|
|
83
84
|
return {
|
|
@@ -367,51 +368,7 @@ export class AnnouncementService {
|
|
|
367
368
|
return { success: true };
|
|
368
369
|
}
|
|
369
370
|
log.info('announcement intended for us — decrypting');
|
|
370
|
-
|
|
371
|
-
if (result.user_data?.length > 0) {
|
|
372
|
-
try {
|
|
373
|
-
rawMessage = new TextDecoder().decode(result.user_data);
|
|
374
|
-
}
|
|
375
|
-
catch (error) {
|
|
376
|
-
log.error('failed to decode user data', error);
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
// Parse announcement message format:
|
|
380
|
-
// - JSON format: {"u":"username","m":"message"} (current)
|
|
381
|
-
// - Legacy colon format: "username:message" (backwards compat)
|
|
382
|
-
// - Plain text: "message" (oldest format)
|
|
383
|
-
// The username is used as the initial contact name if present.
|
|
384
|
-
// TODO: Remove legacy colon and plain text format support once all clients are updated
|
|
385
|
-
let extractedUsername;
|
|
386
|
-
let announcementMessage;
|
|
387
|
-
if (rawMessage) {
|
|
388
|
-
// Try JSON format first (starts with '{')
|
|
389
|
-
if (rawMessage.startsWith('{')) {
|
|
390
|
-
try {
|
|
391
|
-
const parsed = JSON.parse(rawMessage);
|
|
392
|
-
extractedUsername = parsed.u?.trim() || undefined;
|
|
393
|
-
announcementMessage = parsed.m?.trim() || undefined;
|
|
394
|
-
}
|
|
395
|
-
catch {
|
|
396
|
-
// Invalid JSON, treat as plain text
|
|
397
|
-
announcementMessage = rawMessage;
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
else {
|
|
401
|
-
// Legacy format: check for colon separator
|
|
402
|
-
const colonIndex = rawMessage.indexOf(':');
|
|
403
|
-
if (colonIndex !== -1) {
|
|
404
|
-
extractedUsername =
|
|
405
|
-
rawMessage.slice(0, colonIndex).trim() || undefined;
|
|
406
|
-
announcementMessage =
|
|
407
|
-
rawMessage.slice(colonIndex + 1).trim() || undefined;
|
|
408
|
-
}
|
|
409
|
-
else {
|
|
410
|
-
// Plain text (oldest format)
|
|
411
|
-
announcementMessage = rawMessage;
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
}
|
|
371
|
+
const { username, message } = decodeAnnouncementPayload(result.user_data);
|
|
415
372
|
const announcerPkeys = result.announcer_public_keys;
|
|
416
373
|
const contactUserIdRaw = announcerPkeys.derive_id();
|
|
417
374
|
const contactUserId = encodeUserId(contactUserIdRaw);
|
|
@@ -426,7 +383,7 @@ export class AnnouncementService {
|
|
|
426
383
|
const isNewContact = !contact;
|
|
427
384
|
if (isNewContact) {
|
|
428
385
|
// Use extracted username if present, otherwise generate temporary name
|
|
429
|
-
const name =
|
|
386
|
+
const name = username ||
|
|
430
387
|
(await this._generateTemporaryContactName(this.session.userIdEncoded));
|
|
431
388
|
await this.db.contacts.add({
|
|
432
389
|
ownerUserId: this.session.userIdEncoded,
|
|
@@ -445,7 +402,7 @@ export class AnnouncementService {
|
|
|
445
402
|
log.error('contact lookup failed after creation');
|
|
446
403
|
throw new Error('Could not find or create contact');
|
|
447
404
|
}
|
|
448
|
-
const { discussionId } = await this._handleReceivedDiscussion(this.session.userIdEncoded, contactUserId,
|
|
405
|
+
const { discussionId } = await this._handleReceivedDiscussion(this.session.userIdEncoded, contactUserId, message);
|
|
449
406
|
// Emit event for new discussion request
|
|
450
407
|
if (this.events.onDiscussionRequest) {
|
|
451
408
|
const discussion = await this.db.discussions.get(discussionId);
|
package/dist/services/auth.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Handles storing and retrieving public keys by userId hash via the auth API.
|
|
5
5
|
*/
|
|
6
|
-
import { UserPublicKeys } from '
|
|
6
|
+
import { UserPublicKeys } from '../wasm/bindings';
|
|
7
7
|
import { IMessageProtocol } from '../api/messageProtocol/types';
|
|
8
8
|
import { type GossipDatabase } from '../db';
|
|
9
9
|
export type PublicKeyResult = {
|
package/dist/services/auth.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Handles storing and retrieving public keys by userId hash via the auth API.
|
|
5
5
|
*/
|
|
6
|
-
import { UserPublicKeys } from '
|
|
6
|
+
import { UserPublicKeys } from '../wasm/bindings';
|
|
7
7
|
import { decodeUserId } from '../utils/userId';
|
|
8
8
|
import { encodeToBase64, decodeFromBase64 } from '../utils/base64';
|
|
9
9
|
export class AuthService {
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import { type Discussion, type Contact, type GossipDatabase } from '../db';
|
|
7
7
|
import { AnnouncementService } from './announcement';
|
|
8
8
|
import { SessionModule } from '../wasm/session';
|
|
9
|
+
import { AnnouncementPayload } from '../utils/announcementPayload';
|
|
9
10
|
import { GossipSdkEvents } from '../types/events';
|
|
10
11
|
/**
|
|
11
12
|
* Service for managing discussions between users.
|
|
@@ -33,10 +34,21 @@ export declare class DiscussionService {
|
|
|
33
34
|
/**
|
|
34
35
|
* Initialize a discussion with a contact using SessionManager
|
|
35
36
|
* @param contact - The contact to start a discussion with
|
|
36
|
-
* @param
|
|
37
|
+
* @param payload - Optional payload to include in the announcement (username and message)
|
|
37
38
|
* @returns The discussion ID and the created announcement
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* const payload: AnnouncementPayload = {
|
|
43
|
+
* username: 'alice',
|
|
44
|
+
* message: 'Hello!',
|
|
45
|
+
* };
|
|
46
|
+
*
|
|
47
|
+
* const { discussionId, announcement } =
|
|
48
|
+
* await discussionService.initialize(contact, payload);
|
|
49
|
+
* ```
|
|
38
50
|
*/
|
|
39
|
-
initialize(contact: Contact,
|
|
51
|
+
initialize(contact: Contact, payload?: AnnouncementPayload): Promise<{
|
|
40
52
|
discussionId: number;
|
|
41
53
|
announcement: Uint8Array;
|
|
42
54
|
}>;
|
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
* Class-based service for initializing, accepting, and managing discussions.
|
|
5
5
|
*/
|
|
6
6
|
import { DiscussionStatus, MessageDirection, MessageStatus, DiscussionDirection, } from '../db';
|
|
7
|
-
import { UserPublicKeys, SessionStatus } from '
|
|
7
|
+
import { UserPublicKeys, SessionStatus } from '../wasm/bindings';
|
|
8
8
|
import { EstablishSessionError } from './announcement';
|
|
9
9
|
import { sessionStatusToString } from '../wasm/session';
|
|
10
10
|
import { decodeUserId } from '../utils/userId';
|
|
11
|
+
import { encodeAnnouncementPayload, } from '../utils/announcementPayload';
|
|
11
12
|
import { Logger } from '../utils/logs';
|
|
12
13
|
const logger = new Logger('DiscussionService');
|
|
13
14
|
/**
|
|
@@ -61,19 +62,29 @@ export class DiscussionService {
|
|
|
61
62
|
/**
|
|
62
63
|
* Initialize a discussion with a contact using SessionManager
|
|
63
64
|
* @param contact - The contact to start a discussion with
|
|
64
|
-
* @param
|
|
65
|
+
* @param payload - Optional payload to include in the announcement (username and message)
|
|
65
66
|
* @returns The discussion ID and the created announcement
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* const payload: AnnouncementPayload = {
|
|
71
|
+
* username: 'alice',
|
|
72
|
+
* message: 'Hello!',
|
|
73
|
+
* };
|
|
74
|
+
*
|
|
75
|
+
* const { discussionId, announcement } =
|
|
76
|
+
* await discussionService.initialize(contact, payload);
|
|
77
|
+
* ```
|
|
66
78
|
*/
|
|
67
|
-
async initialize(contact,
|
|
79
|
+
async initialize(contact, payload) {
|
|
68
80
|
const log = logger.forMethod('initialize');
|
|
69
81
|
try {
|
|
70
82
|
const userId = this.session.userIdEncoded;
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const result = await this.announcementService.establishSession(UserPublicKeys.from_bytes(contact.publicKeys), userData);
|
|
83
|
+
let payloadBytes;
|
|
84
|
+
if (payload) {
|
|
85
|
+
payloadBytes = encodeAnnouncementPayload(payload.username, payload.message);
|
|
86
|
+
}
|
|
87
|
+
const result = await this.announcementService.establishSession(UserPublicKeys.from_bytes(contact.publicKeys), payloadBytes);
|
|
77
88
|
let status = DiscussionStatus.PENDING;
|
|
78
89
|
if (!result.success) {
|
|
79
90
|
log.error(`Failed to establish session with contact ${contact.name}, got error: ${result.error}`);
|
|
@@ -85,26 +96,6 @@ export class DiscussionService {
|
|
|
85
96
|
else {
|
|
86
97
|
log.info(`session established with contact and announcement sent: ${result.announcement.length}... bytes`);
|
|
87
98
|
}
|
|
88
|
-
// Parse announcement message to extract only the actual message content.
|
|
89
|
-
// The message parameter may be JSON format: {"u":"username","m":"message"}
|
|
90
|
-
// We only want to store the "m" (message) field, not the full JSON.
|
|
91
|
-
let parsedAnnouncementMessage;
|
|
92
|
-
if (message) {
|
|
93
|
-
if (message.startsWith('{')) {
|
|
94
|
-
try {
|
|
95
|
-
const parsed = JSON.parse(message);
|
|
96
|
-
parsedAnnouncementMessage = parsed.m?.trim() || undefined;
|
|
97
|
-
}
|
|
98
|
-
catch {
|
|
99
|
-
// Invalid JSON, treat as plain text
|
|
100
|
-
parsedAnnouncementMessage = message;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
parsedAnnouncementMessage = message;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
// Persist discussion immediately with the announcement for reliable retry
|
|
108
99
|
const discussionId = await this.db.discussions.add({
|
|
109
100
|
ownerUserId: userId,
|
|
110
101
|
contactUserId: contact.userId,
|
|
@@ -112,7 +103,7 @@ export class DiscussionService {
|
|
|
112
103
|
status: status,
|
|
113
104
|
nextSeeker: undefined,
|
|
114
105
|
initiationAnnouncement: result.announcement,
|
|
115
|
-
announcementMessage:
|
|
106
|
+
announcementMessage: payload?.message,
|
|
116
107
|
unreadCount: 0,
|
|
117
108
|
createdAt: new Date(),
|
|
118
109
|
updatedAt: new Date(),
|
package/dist/services/message.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { DiscussionStatus, MessageDirection, MessageStatus, MessageType, } from '../db';
|
|
8
8
|
import { decodeUserId, encodeUserId } from '../utils/userId';
|
|
9
|
-
import { SessionStatus } from '
|
|
9
|
+
import { SessionStatus } from '../wasm/bindings';
|
|
10
10
|
import { serializeRegularMessage, serializeReplyMessage, serializeForwardMessage, serializeKeepAliveMessage, deserializeMessage, } from '../utils/messageSerialization';
|
|
11
11
|
import { encodeToBase64 } from '../utils/base64';
|
|
12
12
|
import { sessionStatusToString } from '../wasm/session';
|
package/dist/services/refresh.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { MessageDirection, MessageStatus, MessageType, } from '../db';
|
|
8
8
|
import { sessionStatusToString } from '../wasm/session';
|
|
9
|
-
import { SessionStatus } from '
|
|
9
|
+
import { SessionStatus } from '../wasm/bindings';
|
|
10
10
|
import { decodeUserId, encodeUserId } from '../utils/userId';
|
|
11
11
|
import { Logger } from '../utils/logs';
|
|
12
12
|
const logger = new Logger('RefreshService');
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export interface AnnouncementPayload {
|
|
2
|
+
username?: string;
|
|
3
|
+
message?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare const encodeAnnouncementPayload: (username?: string, message?: string) => Uint8Array | undefined;
|
|
6
|
+
export declare const decodeAnnouncementPayload: (data?: Uint8Array) => AnnouncementPayload;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Args } from '@massalabs/massa-web3';
|
|
2
|
+
export const encodeAnnouncementPayload = (username, message) => {
|
|
3
|
+
const u = username?.trim() || '';
|
|
4
|
+
const m = message?.trim() || '';
|
|
5
|
+
if (!u && !m) {
|
|
6
|
+
return undefined;
|
|
7
|
+
}
|
|
8
|
+
return new Args().addString(u).addString(m).serialize();
|
|
9
|
+
};
|
|
10
|
+
export const decodeAnnouncementPayload = (data) => {
|
|
11
|
+
if (!data) {
|
|
12
|
+
return { username: undefined, message: undefined };
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
const args = new Args(data);
|
|
16
|
+
const username = args.nextString() || undefined;
|
|
17
|
+
const message = args.nextString() || undefined;
|
|
18
|
+
return { username, message };
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return { username: undefined, message: undefined };
|
|
22
|
+
}
|
|
23
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WASM Bindings Barrel
|
|
3
|
+
*
|
|
4
|
+
* Re-exports all WASM-generated types and functions from the web target.
|
|
5
|
+
* This centralizes the WASM import so the rest of the codebase uses
|
|
6
|
+
* a standard relative import instead of conditional #wasm subpath imports.
|
|
7
|
+
*/
|
|
8
|
+
export { default as init } from '../assets/generated/wasm/gossip_wasm';
|
|
9
|
+
export * from '../assets/generated/wasm/gossip_wasm';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WASM Bindings Barrel
|
|
3
|
+
*
|
|
4
|
+
* Re-exports all WASM-generated types and functions from the web target.
|
|
5
|
+
* This centralizes the WASM import so the rest of the codebase uses
|
|
6
|
+
* a standard relative import instead of conditional #wasm subpath imports.
|
|
7
|
+
*/
|
|
8
|
+
export { default as init } from '../assets/generated/wasm/gossip_wasm';
|
|
9
|
+
export * from '../assets/generated/wasm/gossip_wasm';
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* and AEAD (Authenticated Encryption with Additional Data) operations,
|
|
6
6
|
* ensuring proper initialization before calling any WASM functions.
|
|
7
7
|
*/
|
|
8
|
-
import { EncryptionKey, Nonce } from '
|
|
8
|
+
import { EncryptionKey, Nonce } from './bindings';
|
|
9
9
|
export { EncryptionKey, Nonce };
|
|
10
10
|
/**
|
|
11
11
|
* Generate a new random encryption key (64 bytes)
|
package/dist/wasm/encryption.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* ensuring proper initialization before calling any WASM functions.
|
|
7
7
|
*/
|
|
8
8
|
import { ensureWasmInitialized } from './loader';
|
|
9
|
-
import { EncryptionKey, Nonce, aead_encrypt as _aead_encrypt, aead_decrypt as _aead_decrypt, } from '
|
|
9
|
+
import { EncryptionKey, Nonce, aead_encrypt as _aead_encrypt, aead_decrypt as _aead_decrypt, } from './bindings';
|
|
10
10
|
// Re-export classes
|
|
11
11
|
export { EncryptionKey, Nonce };
|
|
12
12
|
/**
|
package/dist/wasm/loader.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WASM Module Loader and Initialization Service
|
|
3
3
|
*
|
|
4
|
-
* This file handles WASM initialization.
|
|
5
|
-
*
|
|
6
|
-
* - Browser:
|
|
7
|
-
* - Node
|
|
4
|
+
* This file handles WASM initialization. It uses a single web-target build
|
|
5
|
+
* and detects the runtime to load the WASM binary appropriately:
|
|
6
|
+
* - Browser: init() with no args (uses import.meta.url + fetch internally)
|
|
7
|
+
* - Node.js / Jiti: init(bytes) with WASM bytes read from the filesystem
|
|
8
8
|
*/
|
|
9
9
|
/**
|
|
10
10
|
* Initialize WASM modules if not already initialized
|
package/dist/wasm/loader.js
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WASM Module Loader and Initialization Service
|
|
3
3
|
*
|
|
4
|
-
* This file handles WASM initialization.
|
|
5
|
-
*
|
|
6
|
-
* - Browser:
|
|
7
|
-
* - Node
|
|
4
|
+
* This file handles WASM initialization. It uses a single web-target build
|
|
5
|
+
* and detects the runtime to load the WASM binary appropriately:
|
|
6
|
+
* - Browser: init() with no args (uses import.meta.url + fetch internally)
|
|
7
|
+
* - Node.js / Jiti: init(bytes) with WASM bytes read from the filesystem
|
|
8
8
|
*/
|
|
9
|
-
import
|
|
10
|
-
// The web target has a default export (init function), nodejs target doesn't
|
|
11
|
-
const init = wasmModule
|
|
12
|
-
.default;
|
|
9
|
+
import { init } from './bindings';
|
|
13
10
|
/**
|
|
14
11
|
* WASM Initialization State
|
|
15
12
|
*/
|
|
@@ -17,6 +14,14 @@ let isInitializing = false;
|
|
|
17
14
|
let isInitialized = false;
|
|
18
15
|
let initializationPromise = null;
|
|
19
16
|
let initError = null;
|
|
17
|
+
/**
|
|
18
|
+
* Detect if running in a Node.js-like environment (Node, Bun, Jiti, etc.)
|
|
19
|
+
*/
|
|
20
|
+
function isNodeRuntime() {
|
|
21
|
+
return (typeof process !== 'undefined' &&
|
|
22
|
+
process.versions != null &&
|
|
23
|
+
process.versions.node != null);
|
|
24
|
+
}
|
|
20
25
|
/**
|
|
21
26
|
* Initialize WASM modules if not already initialized
|
|
22
27
|
* This function is idempotent - safe to call multiple times
|
|
@@ -35,13 +40,21 @@ export async function initializeWasm() {
|
|
|
35
40
|
initError = null;
|
|
36
41
|
initializationPromise = (async () => {
|
|
37
42
|
try {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
if (isNodeRuntime()) {
|
|
44
|
+
// Node.js / Jiti: read WASM bytes from filesystem and pass to init()
|
|
45
|
+
// Dynamic imports ensure these Node.js modules are tree-shaken in browser builds
|
|
46
|
+
const fs = await import('node:fs');
|
|
47
|
+
const url = await import('node:url');
|
|
48
|
+
const path = await import('node:path');
|
|
49
|
+
const currentDir = path.dirname(url.fileURLToPath(import.meta.url));
|
|
50
|
+
const wasmPath = path.resolve(currentDir, '../assets/generated/wasm/gossip_wasm_bg.wasm');
|
|
51
|
+
const wasmBytes = fs.readFileSync(wasmPath);
|
|
52
|
+
await init(wasmBytes);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
// Browser: use default loading (import.meta.url + fetch internally)
|
|
42
56
|
await init();
|
|
43
57
|
}
|
|
44
|
-
// For nodejs target, wasm is already initialized on import
|
|
45
58
|
isInitialized = true;
|
|
46
59
|
isInitializing = false;
|
|
47
60
|
}
|
package/dist/wasm/session.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This file contains the real WASM implementation of the SessionModule
|
|
5
5
|
* using SessionManagerWrapper and related WASM classes.
|
|
6
6
|
*/
|
|
7
|
-
import { UserPublicKeys, UserSecretKeys, ReceiveMessageOutput, SendMessageOutput, SessionStatus, EncryptionKey, SessionConfig, AnnouncementResult, UserKeys } from '
|
|
7
|
+
import { UserPublicKeys, UserSecretKeys, ReceiveMessageOutput, SendMessageOutput, SessionStatus, EncryptionKey, SessionConfig, AnnouncementResult, UserKeys } from './bindings';
|
|
8
8
|
import { UserProfile } from '../db';
|
|
9
9
|
export declare class SessionModule {
|
|
10
10
|
private sessionManager;
|
package/dist/wasm/session.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This file contains the real WASM implementation of the SessionModule
|
|
5
5
|
* using SessionManagerWrapper and related WASM classes.
|
|
6
6
|
*/
|
|
7
|
-
import { SessionManagerWrapper, SessionStatus, SessionConfig, } from '
|
|
7
|
+
import { SessionManagerWrapper, SessionStatus, SessionConfig, } from './bindings';
|
|
8
8
|
import { encodeUserId } from '../utils/userId';
|
|
9
9
|
export class SessionModule {
|
|
10
10
|
constructor(userKeys, onPersist, config) {
|
package/dist/wasm/userKeys.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This file provides proxy functions for user key generation,
|
|
5
5
|
* ensuring proper initialization before calling any WASM functions.
|
|
6
6
|
*/
|
|
7
|
-
import { UserKeys } from '
|
|
7
|
+
import { UserKeys } from './bindings';
|
|
8
8
|
export { UserKeys };
|
|
9
9
|
/**
|
|
10
10
|
* Generate user keys from a passphrase using password-based key derivation
|
package/dist/wasm/userKeys.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* ensuring proper initialization before calling any WASM functions.
|
|
6
6
|
*/
|
|
7
7
|
import { ensureWasmInitialized } from './loader';
|
|
8
|
-
import { generate_user_keys as _generate_user_keys, UserKeys } from '
|
|
8
|
+
import { generate_user_keys as _generate_user_keys, UserKeys, } from './bindings';
|
|
9
9
|
// Re-export classes
|
|
10
10
|
export { UserKeys };
|
|
11
11
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@massalabs/gossip-sdk",
|
|
3
|
-
"version": "0.0.2-dev.
|
|
3
|
+
"version": "0.0.2-dev.20260211110128",
|
|
4
4
|
"description": "Gossip SDK for automation, chatbot, and integration use cases",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -9,12 +9,6 @@
|
|
|
9
9
|
"dist",
|
|
10
10
|
"README.md"
|
|
11
11
|
],
|
|
12
|
-
"imports": {
|
|
13
|
-
"#wasm": {
|
|
14
|
-
"browser": "./dist/assets/generated/wasm/gossip_wasm.js",
|
|
15
|
-
"default": "./dist/assets/generated/wasm-node/gossip_wasm.js"
|
|
16
|
-
}
|
|
17
|
-
},
|
|
18
12
|
"exports": {
|
|
19
13
|
".": {
|
|
20
14
|
"types": "./dist/index.d.ts",
|
|
@@ -28,11 +22,13 @@
|
|
|
28
22
|
"scripts": {
|
|
29
23
|
"prebuild": "rimraf dist",
|
|
30
24
|
"build": "tsc && npm run copy:wasm",
|
|
31
|
-
"copy:wasm": "mkdir -p dist/assets/generated/wasm
|
|
25
|
+
"copy:wasm": "mkdir -p dist/assets/generated/wasm && cp -R src/assets/generated/wasm/* dist/assets/generated/wasm/",
|
|
32
26
|
"test": "vitest",
|
|
33
27
|
"test:run": "vitest run",
|
|
34
28
|
"test:coverage": "vitest run --coverage",
|
|
35
|
-
"test:e2e": "vitest run test/e2e/"
|
|
29
|
+
"test:e2e": "vitest run test/e2e/",
|
|
30
|
+
"lint": "eslint .",
|
|
31
|
+
"lint:fix": "eslint . --fix"
|
|
36
32
|
},
|
|
37
33
|
"keywords": [
|
|
38
34
|
"gossip",
|