@massalabs/gossip-sdk 0.0.2-dev.20260128094509 → 0.0.2-dev.20260128160824

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.
Files changed (148) hide show
  1. package/dist/api/messageProtocol/index.d.ts +19 -0
  2. package/dist/api/messageProtocol/index.js +26 -0
  3. package/dist/api/messageProtocol/mock.d.ts +12 -0
  4. package/{src/api/messageProtocol/mock.ts → dist/api/messageProtocol/mock.js} +2 -3
  5. package/dist/api/messageProtocol/rest.d.ts +22 -0
  6. package/dist/api/messageProtocol/rest.js +161 -0
  7. package/dist/api/messageProtocol/types.d.ts +61 -0
  8. package/dist/api/messageProtocol/types.js +6 -0
  9. package/dist/assets/generated/wasm/README.md +281 -0
  10. package/dist/assets/generated/wasm/gossip_wasm.d.ts +638 -0
  11. package/dist/assets/generated/wasm/gossip_wasm.js +1557 -0
  12. package/dist/assets/generated/wasm/gossip_wasm_bg.wasm +0 -0
  13. package/dist/assets/generated/wasm/gossip_wasm_bg.wasm.d.ts +164 -0
  14. package/dist/assets/generated/wasm/package.json +15 -0
  15. package/dist/assets/generated/wasm-node/README.md +281 -0
  16. package/dist/assets/generated/wasm-node/gossip_wasm.d.ts +443 -0
  17. package/dist/assets/generated/wasm-node/gossip_wasm.js +1488 -0
  18. package/dist/assets/generated/wasm-node/gossip_wasm_bg.wasm +0 -0
  19. package/dist/assets/generated/wasm-node/gossip_wasm_bg.wasm.d.ts +164 -0
  20. package/dist/assets/generated/wasm-node/package.json +11 -0
  21. package/dist/config/protocol.d.ts +36 -0
  22. package/dist/config/protocol.js +77 -0
  23. package/dist/config/sdk.d.ts +82 -0
  24. package/dist/config/sdk.js +55 -0
  25. package/{src/contacts.ts → dist/contacts.d.ts} +11 -95
  26. package/dist/contacts.js +166 -0
  27. package/dist/core/SdkEventEmitter.d.ts +36 -0
  28. package/dist/core/SdkEventEmitter.js +59 -0
  29. package/dist/core/SdkPolling.d.ts +35 -0
  30. package/dist/core/SdkPolling.js +100 -0
  31. package/{src/core/index.ts → dist/core/index.d.ts} +0 -2
  32. package/dist/core/index.js +5 -0
  33. package/dist/crypto/bip39.d.ts +34 -0
  34. package/dist/crypto/bip39.js +62 -0
  35. package/dist/crypto/encryption.d.ts +37 -0
  36. package/dist/crypto/encryption.js +46 -0
  37. package/dist/db.d.ts +190 -0
  38. package/dist/db.js +311 -0
  39. package/dist/gossipSdk.d.ts +274 -0
  40. package/dist/gossipSdk.js +690 -0
  41. package/dist/index.d.ts +59 -0
  42. package/dist/index.js +61 -0
  43. package/dist/services/announcement.d.ts +43 -0
  44. package/dist/services/announcement.js +491 -0
  45. package/dist/services/auth.d.ts +37 -0
  46. package/dist/services/auth.js +76 -0
  47. package/dist/services/discussion.d.ts +63 -0
  48. package/dist/services/discussion.js +297 -0
  49. package/dist/services/message.d.ts +74 -0
  50. package/dist/services/message.js +826 -0
  51. package/dist/services/refresh.d.ts +41 -0
  52. package/dist/services/refresh.js +205 -0
  53. package/{src/sw.ts → dist/sw.d.ts} +1 -8
  54. package/dist/sw.js +10 -0
  55. package/dist/types/events.d.ts +80 -0
  56. package/dist/types/events.js +7 -0
  57. package/dist/types.d.ts +32 -0
  58. package/dist/types.js +7 -0
  59. package/dist/utils/base64.d.ts +10 -0
  60. package/dist/utils/base64.js +30 -0
  61. package/dist/utils/contacts.d.ts +42 -0
  62. package/dist/utils/contacts.js +113 -0
  63. package/dist/utils/discussions.d.ts +24 -0
  64. package/dist/utils/discussions.js +38 -0
  65. package/dist/utils/logs.d.ts +19 -0
  66. package/dist/utils/logs.js +89 -0
  67. package/dist/utils/messageSerialization.d.ts +64 -0
  68. package/dist/utils/messageSerialization.js +184 -0
  69. package/dist/utils/queue.d.ts +50 -0
  70. package/dist/utils/queue.js +110 -0
  71. package/dist/utils/type.d.ts +10 -0
  72. package/dist/utils/type.js +4 -0
  73. package/dist/utils/userId.d.ts +40 -0
  74. package/dist/utils/userId.js +90 -0
  75. package/dist/utils/validation.d.ts +50 -0
  76. package/dist/utils/validation.js +112 -0
  77. package/dist/utils.d.ts +30 -0
  78. package/{src/utils.ts → dist/utils.js} +9 -19
  79. package/dist/wasm/encryption.d.ts +56 -0
  80. package/{src/wasm/encryption.ts → dist/wasm/encryption.js} +22 -51
  81. package/dist/wasm/index.d.ts +10 -0
  82. package/{src/wasm/index.ts → dist/wasm/index.js} +1 -8
  83. package/dist/wasm/loader.d.ts +22 -0
  84. package/dist/wasm/loader.js +78 -0
  85. package/dist/wasm/session.d.ts +85 -0
  86. package/dist/wasm/session.js +226 -0
  87. package/dist/wasm/userKeys.d.ts +17 -0
  88. package/{src/wasm/userKeys.ts → dist/wasm/userKeys.js} +6 -13
  89. package/package.json +15 -2
  90. package/src/api/messageProtocol/index.ts +0 -53
  91. package/src/api/messageProtocol/rest.ts +0 -209
  92. package/src/api/messageProtocol/types.ts +0 -70
  93. package/src/config/protocol.ts +0 -97
  94. package/src/config/sdk.ts +0 -131
  95. package/src/core/SdkEventEmitter.ts +0 -91
  96. package/src/core/SdkPolling.ts +0 -134
  97. package/src/crypto/bip39.ts +0 -84
  98. package/src/crypto/encryption.ts +0 -77
  99. package/src/db.ts +0 -465
  100. package/src/gossipSdk.ts +0 -994
  101. package/src/index.ts +0 -211
  102. package/src/services/announcement.ts +0 -653
  103. package/src/services/auth.ts +0 -95
  104. package/src/services/discussion.ts +0 -380
  105. package/src/services/message.ts +0 -1055
  106. package/src/services/refresh.ts +0 -234
  107. package/src/types/events.ts +0 -108
  108. package/src/types.ts +0 -70
  109. package/src/utils/base64.ts +0 -39
  110. package/src/utils/contacts.ts +0 -161
  111. package/src/utils/discussions.ts +0 -55
  112. package/src/utils/logs.ts +0 -86
  113. package/src/utils/messageSerialization.ts +0 -257
  114. package/src/utils/queue.ts +0 -106
  115. package/src/utils/type.ts +0 -7
  116. package/src/utils/userId.ts +0 -114
  117. package/src/utils/validation.ts +0 -144
  118. package/src/wasm/loader.ts +0 -123
  119. package/src/wasm/session.ts +0 -276
  120. package/test/config/protocol.spec.ts +0 -31
  121. package/test/config/sdk.spec.ts +0 -163
  122. package/test/db/helpers.spec.ts +0 -142
  123. package/test/db/operations.spec.ts +0 -128
  124. package/test/db/states.spec.ts +0 -535
  125. package/test/integration/discussion-flow.spec.ts +0 -422
  126. package/test/integration/messaging-flow.spec.ts +0 -708
  127. package/test/integration/sdk-lifecycle.spec.ts +0 -325
  128. package/test/mocks/index.ts +0 -9
  129. package/test/mocks/mockMessageProtocol.ts +0 -100
  130. package/test/services/auth.spec.ts +0 -311
  131. package/test/services/discussion.spec.ts +0 -279
  132. package/test/services/message-deduplication.spec.ts +0 -299
  133. package/test/services/message-startup.spec.ts +0 -331
  134. package/test/services/message.spec.ts +0 -817
  135. package/test/services/refresh.spec.ts +0 -199
  136. package/test/services/session-status.spec.ts +0 -349
  137. package/test/session/wasm.spec.ts +0 -227
  138. package/test/setup.ts +0 -52
  139. package/test/utils/contacts.spec.ts +0 -156
  140. package/test/utils/discussions.spec.ts +0 -66
  141. package/test/utils/queue.spec.ts +0 -52
  142. package/test/utils/serialization.spec.ts +0 -120
  143. package/test/utils/userId.spec.ts +0 -120
  144. package/test/utils/validation.spec.ts +0 -223
  145. package/test/utils.ts +0 -212
  146. package/tsconfig.json +0 -26
  147. package/tsconfig.tsbuildinfo +0 -1
  148. package/vitest.config.ts +0 -28
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Validation Utilities
3
+ *
4
+ * Functions for validating user input like usernames, passwords, and user IDs.
5
+ */
6
+ import { type GossipDatabase } from '../db';
7
+ export type ValidationResult = {
8
+ valid: true;
9
+ error?: never;
10
+ } | {
11
+ valid: false;
12
+ error: string;
13
+ };
14
+ /**
15
+ * Validate a password meets requirements
16
+ *
17
+ * @param value - The password to validate
18
+ * @returns Validation result
19
+ */
20
+ export declare function validatePassword(value: string): ValidationResult;
21
+ /**
22
+ * Validate a username format (without checking availability)
23
+ *
24
+ * @param value - The username to validate
25
+ * @returns Validation result
26
+ */
27
+ export declare function validateUsernameFormat(value: string): ValidationResult;
28
+ /**
29
+ * Validate a username is available (not already in use)
30
+ *
31
+ * @param value - The username to check
32
+ * @param db - Database instance
33
+ * @returns Validation result
34
+ */
35
+ export declare function validateUsernameAvailability(value: string, db: GossipDatabase): Promise<ValidationResult>;
36
+ /**
37
+ * Validate a username format and availability
38
+ *
39
+ * @param value - The username to validate
40
+ * @param db - Database instance
41
+ * @returns Validation result
42
+ */
43
+ export declare function validateUsernameFormatAndAvailability(value: string, db: GossipDatabase): Promise<ValidationResult>;
44
+ /**
45
+ * Validate a user ID format (Bech32 gossip1... format)
46
+ *
47
+ * @param value - The user ID to validate
48
+ * @returns Validation result
49
+ */
50
+ export declare function validateUserIdFormat(value: string): ValidationResult;
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Validation Utilities
3
+ *
4
+ * Functions for validating user input like usernames, passwords, and user IDs.
5
+ */
6
+ import { isValidUserId } from './userId';
7
+ /**
8
+ * Validate a password meets requirements
9
+ *
10
+ * @param value - The password to validate
11
+ * @returns Validation result
12
+ */
13
+ export function validatePassword(value) {
14
+ if (!value || value.trim().length === 0) {
15
+ return { valid: false, error: 'Password is required' };
16
+ }
17
+ if (value.length < 8) {
18
+ return {
19
+ valid: false,
20
+ error: 'Password must be at least 8 characters long',
21
+ };
22
+ }
23
+ return { valid: true };
24
+ }
25
+ /**
26
+ * Validate a username format (without checking availability)
27
+ *
28
+ * @param value - The username to validate
29
+ * @returns Validation result
30
+ */
31
+ export function validateUsernameFormat(value) {
32
+ const trimmed = value.trim();
33
+ if (!trimmed) {
34
+ return { valid: false, error: 'Username is required' };
35
+ }
36
+ // Disallow any whitespace inside the username (single token only)
37
+ if (/\s/.test(trimmed)) {
38
+ return {
39
+ valid: false,
40
+ error: 'Username cannot contain spaces',
41
+ };
42
+ }
43
+ if (trimmed.length < 3) {
44
+ return {
45
+ valid: false,
46
+ error: 'Username must be at least 3 characters long',
47
+ };
48
+ }
49
+ return { valid: true };
50
+ }
51
+ /**
52
+ * Validate a username is available (not already in use)
53
+ *
54
+ * @param value - The username to check
55
+ * @param db - Database instance
56
+ * @returns Validation result
57
+ */
58
+ export async function validateUsernameAvailability(value, db) {
59
+ try {
60
+ if (!db.isOpen()) {
61
+ await db.open();
62
+ }
63
+ const existingProfile = await db.userProfile
64
+ .filter((profile) => profile.username.trim().toLowerCase() === value.trim().toLowerCase())
65
+ .first();
66
+ if (existingProfile) {
67
+ return {
68
+ valid: false,
69
+ error: 'This username is already in use. Please choose another.',
70
+ };
71
+ }
72
+ return { valid: true };
73
+ }
74
+ catch (error) {
75
+ return {
76
+ valid: false,
77
+ error: error instanceof Error
78
+ ? error.message
79
+ : 'Unable to verify username availability. Please try again.',
80
+ };
81
+ }
82
+ }
83
+ /**
84
+ * Validate a username format and availability
85
+ *
86
+ * @param value - The username to validate
87
+ * @param db - Database instance
88
+ * @returns Validation result
89
+ */
90
+ export async function validateUsernameFormatAndAvailability(value, db) {
91
+ const result = validateUsernameFormat(value);
92
+ if (!result.valid) {
93
+ return result;
94
+ }
95
+ return await validateUsernameAvailability(value, db);
96
+ }
97
+ /**
98
+ * Validate a user ID format (Bech32 gossip1... format)
99
+ *
100
+ * @param value - The user ID to validate
101
+ * @returns Validation result
102
+ */
103
+ export function validateUserIdFormat(value) {
104
+ const userId = value.trim();
105
+ if (!isValidUserId(userId)) {
106
+ return {
107
+ valid: false,
108
+ error: 'Invalid format — must be a valid user ID',
109
+ };
110
+ }
111
+ return { valid: true };
112
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * SDK Utilities
3
+ *
4
+ * Helper functions for SDK configuration.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { configureSdk } from 'gossip-sdk';
9
+ *
10
+ * configureSdk({
11
+ * db,
12
+ * protocolBaseUrl: 'https://api.example.com',
13
+ * });
14
+ * ```
15
+ */
16
+ import type { GossipDatabase } from './db';
17
+ export interface SdkRuntimeConfig {
18
+ db?: GossipDatabase;
19
+ protocolBaseUrl?: string;
20
+ }
21
+ /**
22
+ * Configure runtime adapters for the SDK.
23
+ * Call this once during application startup.
24
+ *
25
+ * This also starts WASM initialization in the background.
26
+ *
27
+ * Note: Service instances (MessageService, AnnouncementService, etc.)
28
+ * should be created by the app with the required dependencies.
29
+ */
30
+ export declare function configureSdk(config: SdkRuntimeConfig): void;
@@ -13,17 +13,9 @@
13
13
  * });
14
14
  * ```
15
15
  */
16
-
17
- import type { GossipDatabase } from './db';
18
16
  import { setDb } from './db';
19
17
  import { startWasmInitialization } from './wasm/loader';
20
18
  import { setProtocolBaseUrl } from './config/protocol';
21
-
22
- export interface SdkRuntimeConfig {
23
- db?: GossipDatabase;
24
- protocolBaseUrl?: string;
25
- }
26
-
27
19
  /**
28
20
  * Configure runtime adapters for the SDK.
29
21
  * Call this once during application startup.
@@ -33,15 +25,13 @@ export interface SdkRuntimeConfig {
33
25
  * Note: Service instances (MessageService, AnnouncementService, etc.)
34
26
  * should be created by the app with the required dependencies.
35
27
  */
36
- export function configureSdk(config: SdkRuntimeConfig): void {
37
- if (config.db) {
38
- setDb(config.db);
39
- }
40
-
41
- if (config.protocolBaseUrl) {
42
- setProtocolBaseUrl(config.protocolBaseUrl);
43
- }
44
-
45
- // Start WASM initialization in the background (non-blocking)
46
- startWasmInitialization();
28
+ export function configureSdk(config) {
29
+ if (config.db) {
30
+ setDb(config.db);
31
+ }
32
+ if (config.protocolBaseUrl) {
33
+ setProtocolBaseUrl(config.protocolBaseUrl);
34
+ }
35
+ // Start WASM initialization in the background (non-blocking)
36
+ startWasmInitialization();
47
37
  }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Encryption, Keys, and AEAD Support
3
+ *
4
+ * This file provides proxy functions for EncryptionKey, Nonce classes,
5
+ * and AEAD (Authenticated Encryption with Additional Data) operations,
6
+ * ensuring proper initialization before calling any WASM functions.
7
+ */
8
+ import { EncryptionKey, Nonce } from '#wasm';
9
+ export { EncryptionKey, Nonce };
10
+ /**
11
+ * Generate a new random encryption key (64 bytes)
12
+ * This ensures WASM is initialized before calling
13
+ */
14
+ export declare function generateEncryptionKey(): Promise<EncryptionKey>;
15
+ /**
16
+ * Generate a deterministic encryption key (64 bytes) from a seed string.
17
+ * This ensures WASM is initialized before calling.
18
+ */
19
+ export declare function generateEncryptionKeyFromSeed(seed: string, salt: Uint8Array): Promise<EncryptionKey>;
20
+ /**
21
+ * Create an encryption key from raw bytes (must be 64 bytes)
22
+ * This ensures WASM is initialized before calling
23
+ */
24
+ export declare function encryptionKeyFromBytes(bytes: Uint8Array): Promise<EncryptionKey>;
25
+ /**
26
+ * Generate a new random nonce (16 bytes)
27
+ * This ensures WASM is initialized before calling
28
+ */
29
+ export declare function generateNonce(): Promise<Nonce>;
30
+ /**
31
+ * Create a nonce from raw bytes (must be 16 bytes)
32
+ * This ensures WASM is initialized before calling
33
+ */
34
+ export declare function nonceFromBytes(bytes: Uint8Array): Promise<Nonce>;
35
+ /**
36
+ * Encrypt data using AES-256-SIV authenticated encryption
37
+ * This ensures WASM is initialized before calling
38
+ *
39
+ * @param key - The encryption key (64 bytes)
40
+ * @param nonce - The nonce (16 bytes, should be unique per encryption)
41
+ * @param plaintext - The data to encrypt
42
+ * @param aad - Additional authenticated data (not encrypted, but authenticated)
43
+ * @returns The ciphertext with authentication tag appended
44
+ */
45
+ export declare function encryptAead(key: EncryptionKey, nonce: Nonce, plaintext: Uint8Array, aad: Uint8Array): Promise<Uint8Array>;
46
+ /**
47
+ * Decrypt data using AES-256-SIV authenticated encryption
48
+ * This ensures WASM is initialized before calling
49
+ *
50
+ * @param key - The encryption key (64 bytes, must match encryption key)
51
+ * @param nonce - The nonce (16 bytes, must match encryption nonce)
52
+ * @param ciphertext - The encrypted data with authentication tag
53
+ * @param aad - Additional authenticated data (must match encryption AAD)
54
+ * @returns The decrypted plaintext, or undefined if authentication fails
55
+ */
56
+ export declare function decryptAead(key: EncryptionKey, nonce: Nonce, ciphertext: Uint8Array, aad: Uint8Array): Promise<Uint8Array | undefined>;
@@ -5,68 +5,50 @@
5
5
  * and AEAD (Authenticated Encryption with Additional Data) operations,
6
6
  * ensuring proper initialization before calling any WASM functions.
7
7
  */
8
-
9
8
  import { ensureWasmInitialized } from './loader';
10
- import {
11
- EncryptionKey,
12
- Nonce,
13
- aead_encrypt as _aead_encrypt,
14
- aead_decrypt as _aead_decrypt,
15
- } from '../assets/generated/wasm/gossip_wasm';
16
-
9
+ import { EncryptionKey, Nonce, aead_encrypt as _aead_encrypt, aead_decrypt as _aead_decrypt, } from '#wasm';
17
10
  // Re-export classes
18
11
  export { EncryptionKey, Nonce };
19
-
20
12
  /**
21
13
  * Generate a new random encryption key (64 bytes)
22
14
  * This ensures WASM is initialized before calling
23
15
  */
24
- export async function generateEncryptionKey(): Promise<EncryptionKey> {
25
- await ensureWasmInitialized();
26
- return EncryptionKey.generate();
16
+ export async function generateEncryptionKey() {
17
+ await ensureWasmInitialized();
18
+ return EncryptionKey.generate();
27
19
  }
28
-
29
20
  /**
30
21
  * Generate a deterministic encryption key (64 bytes) from a seed string.
31
22
  * This ensures WASM is initialized before calling.
32
23
  */
33
- export async function generateEncryptionKeyFromSeed(
34
- seed: string,
35
- salt: Uint8Array
36
- ): Promise<EncryptionKey> {
37
- await ensureWasmInitialized();
38
- return EncryptionKey.from_seed(seed, salt);
24
+ export async function generateEncryptionKeyFromSeed(seed, salt) {
25
+ await ensureWasmInitialized();
26
+ return EncryptionKey.from_seed(seed, salt);
39
27
  }
40
-
41
28
  /**
42
29
  * Create an encryption key from raw bytes (must be 64 bytes)
43
30
  * This ensures WASM is initialized before calling
44
31
  */
45
- export async function encryptionKeyFromBytes(
46
- bytes: Uint8Array
47
- ): Promise<EncryptionKey> {
48
- await ensureWasmInitialized();
49
- return EncryptionKey.from_bytes(bytes);
32
+ export async function encryptionKeyFromBytes(bytes) {
33
+ await ensureWasmInitialized();
34
+ return EncryptionKey.from_bytes(bytes);
50
35
  }
51
-
52
36
  /**
53
37
  * Generate a new random nonce (16 bytes)
54
38
  * This ensures WASM is initialized before calling
55
39
  */
56
- export async function generateNonce(): Promise<Nonce> {
57
- await ensureWasmInitialized();
58
- return Nonce.generate();
40
+ export async function generateNonce() {
41
+ await ensureWasmInitialized();
42
+ return Nonce.generate();
59
43
  }
60
-
61
44
  /**
62
45
  * Create a nonce from raw bytes (must be 16 bytes)
63
46
  * This ensures WASM is initialized before calling
64
47
  */
65
- export async function nonceFromBytes(bytes: Uint8Array): Promise<Nonce> {
66
- await ensureWasmInitialized();
67
- return Nonce.from_bytes(bytes);
48
+ export async function nonceFromBytes(bytes) {
49
+ await ensureWasmInitialized();
50
+ return Nonce.from_bytes(bytes);
68
51
  }
69
-
70
52
  /**
71
53
  * Encrypt data using AES-256-SIV authenticated encryption
72
54
  * This ensures WASM is initialized before calling
@@ -77,16 +59,10 @@ export async function nonceFromBytes(bytes: Uint8Array): Promise<Nonce> {
77
59
  * @param aad - Additional authenticated data (not encrypted, but authenticated)
78
60
  * @returns The ciphertext with authentication tag appended
79
61
  */
80
- export async function encryptAead(
81
- key: EncryptionKey,
82
- nonce: Nonce,
83
- plaintext: Uint8Array,
84
- aad: Uint8Array
85
- ): Promise<Uint8Array> {
86
- await ensureWasmInitialized();
87
- return _aead_encrypt(key, nonce, plaintext, aad);
62
+ export async function encryptAead(key, nonce, plaintext, aad) {
63
+ await ensureWasmInitialized();
64
+ return _aead_encrypt(key, nonce, plaintext, aad);
88
65
  }
89
-
90
66
  /**
91
67
  * Decrypt data using AES-256-SIV authenticated encryption
92
68
  * This ensures WASM is initialized before calling
@@ -97,12 +73,7 @@ export async function encryptAead(
97
73
  * @param aad - Additional authenticated data (must match encryption AAD)
98
74
  * @returns The decrypted plaintext, or undefined if authentication fails
99
75
  */
100
- export async function decryptAead(
101
- key: EncryptionKey,
102
- nonce: Nonce,
103
- ciphertext: Uint8Array,
104
- aad: Uint8Array
105
- ): Promise<Uint8Array | undefined> {
106
- await ensureWasmInitialized();
107
- return _aead_decrypt(key, nonce, ciphertext, aad);
76
+ export async function decryptAead(key, nonce, ciphertext, aad) {
77
+ await ensureWasmInitialized();
78
+ return _aead_decrypt(key, nonce, ciphertext, aad);
108
79
  }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * WASM Module Exports
3
+ *
4
+ * This file provides a clean interface for importing WASM modules
5
+ * and related functionality.
6
+ */
7
+ export { SessionModule, sessionStatusToString } from './session';
8
+ export { initializeWasm, ensureWasmInitialized, startWasmInitialization, } from './loader';
9
+ export * from './encryption';
10
+ export * from './userKeys';
@@ -4,17 +4,10 @@
4
4
  * This file provides a clean interface for importing WASM modules
5
5
  * and related functionality.
6
6
  */
7
-
8
7
  // Export modules
9
8
  export { SessionModule, sessionStatusToString } from './session';
10
-
11
9
  // Export initialization functions
12
- export {
13
- initializeWasm,
14
- ensureWasmInitialized,
15
- startWasmInitialization,
16
- } from './loader';
17
-
10
+ export { initializeWasm, ensureWasmInitialized, startWasmInitialization, } from './loader';
18
11
  // Export specialized WASM functionality
19
12
  export * from './encryption';
20
13
  export * from './userKeys';
@@ -0,0 +1,22 @@
1
+ /**
2
+ * WASM Module Loader and Initialization Service
3
+ *
4
+ * This file handles WASM initialization. The actual wasm module is resolved
5
+ * via the #wasm import which conditionally loads the correct target:
6
+ * - Browser: web target (has init function, uses import.meta.url + fetch)
7
+ * - Node: nodejs target (auto-initializes, no init function needed)
8
+ */
9
+ /**
10
+ * Initialize WASM modules if not already initialized
11
+ * This function is idempotent - safe to call multiple times
12
+ */
13
+ export declare function initializeWasm(): Promise<void>;
14
+ /**
15
+ * Ensure WASM is initialized, throwing an error if initialization failed
16
+ */
17
+ export declare function ensureWasmInitialized(): Promise<void>;
18
+ /**
19
+ * Start WASM initialization in the background.
20
+ * Call this early in the app lifecycle (for example in main.tsx).
21
+ */
22
+ export declare function startWasmInitialization(): void;
@@ -0,0 +1,78 @@
1
+ /**
2
+ * WASM Module Loader and Initialization Service
3
+ *
4
+ * This file handles WASM initialization. The actual wasm module is resolved
5
+ * via the #wasm import which conditionally loads the correct target:
6
+ * - Browser: web target (has init function, uses import.meta.url + fetch)
7
+ * - Node: nodejs target (auto-initializes, no init function needed)
8
+ */
9
+ import * as wasmModule from '#wasm';
10
+ // The web target has a default export (init function), nodejs target doesn't
11
+ const init = wasmModule
12
+ .default;
13
+ /**
14
+ * WASM Initialization State
15
+ */
16
+ let isInitializing = false;
17
+ let isInitialized = false;
18
+ let initializationPromise = null;
19
+ let initError = null;
20
+ /**
21
+ * Initialize WASM modules if not already initialized
22
+ * This function is idempotent - safe to call multiple times
23
+ */
24
+ export async function initializeWasm() {
25
+ // If already initialized, return immediately
26
+ if (isInitialized) {
27
+ return;
28
+ }
29
+ // If initialization is in progress, wait for it to complete
30
+ if (isInitializing && initializationPromise) {
31
+ return initializationPromise;
32
+ }
33
+ // Start initialization
34
+ isInitializing = true;
35
+ initError = null;
36
+ initializationPromise = (async () => {
37
+ try {
38
+ // The #wasm import resolves to the correct target based on environment:
39
+ // - Browser (web target): has init() function that needs to be called
40
+ // - Node (nodejs target): auto-initializes on import, no init needed
41
+ if (typeof init === 'function') {
42
+ await init();
43
+ }
44
+ // For nodejs target, wasm is already initialized on import
45
+ isInitialized = true;
46
+ isInitializing = false;
47
+ }
48
+ catch (error) {
49
+ initError = error;
50
+ isInitializing = false;
51
+ console.error('[WASM] Failed to initialize WASM modules:', error);
52
+ throw error;
53
+ }
54
+ })();
55
+ return initializationPromise;
56
+ }
57
+ /**
58
+ * Ensure WASM is initialized, throwing an error if initialization failed
59
+ */
60
+ export async function ensureWasmInitialized() {
61
+ await initializeWasm();
62
+ if (initError) {
63
+ throw new Error(`WASM initialization failed: ${initError.message}`);
64
+ }
65
+ if (!isInitialized) {
66
+ throw new Error('WASM not initialized');
67
+ }
68
+ }
69
+ /**
70
+ * Start WASM initialization in the background.
71
+ * Call this early in the app lifecycle (for example in main.tsx).
72
+ */
73
+ export function startWasmInitialization() {
74
+ // Fire and forget - start initialization in background
75
+ initializeWasm().catch(error => {
76
+ console.error('[WASM] Background initialization error:', error);
77
+ });
78
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Session Module Implementation
3
+ *
4
+ * This file contains the real WASM implementation of the SessionModule
5
+ * using SessionManagerWrapper and related WASM classes.
6
+ */
7
+ import { UserPublicKeys, UserSecretKeys, ReceiveMessageOutput, SendMessageOutput, SessionStatus, EncryptionKey, SessionConfig, AnnouncementResult, UserKeys } from '#wasm';
8
+ import { UserProfile } from '../db';
9
+ export declare class SessionModule {
10
+ private sessionManager;
11
+ private onPersist?;
12
+ ourPk: UserPublicKeys;
13
+ ourSk: UserSecretKeys;
14
+ userId: Uint8Array;
15
+ userIdEncoded: string;
16
+ constructor(userKeys: UserKeys, onPersist?: () => Promise<void>, config?: SessionConfig);
17
+ /**
18
+ * Set the persistence callback
19
+ */
20
+ setOnPersist(callback: () => Promise<void>): void;
21
+ /**
22
+ * Helper to trigger persistence after state changes.
23
+ * Returns a promise that resolves when persistence is complete.
24
+ * IMPORTANT: Callers should await this before sending data to network
25
+ * to prevent state loss on app crash.
26
+ */
27
+ private persistIfNeeded;
28
+ /**
29
+ * Trigger persistence explicitly and wait for completion.
30
+ * Use this when you need to ensure state is saved before proceeding.
31
+ */
32
+ persist(): Promise<void>;
33
+ /**
34
+ * Initialize session from an encrypted blob
35
+ */
36
+ load(profile: UserProfile, encryptionKey: EncryptionKey): void;
37
+ /**
38
+ * Serialize session to an encrypted blob
39
+ */
40
+ toEncryptedBlob(key: EncryptionKey): Uint8Array;
41
+ cleanup(): void;
42
+ /**
43
+ * Establish an outgoing session with a peer via the underlying WASM wrapper
44
+ * @param peerPk - The peer's public keys
45
+ * @param userData - Optional user data to include in the announcement (defaults to empty array)
46
+ * @returns The announcement bytes to publish
47
+ */
48
+ establishOutgoingSession(peerPk: UserPublicKeys, userData?: Uint8Array): Promise<Uint8Array>;
49
+ /**
50
+ * Feed an incoming announcement into the session manager
51
+ * @returns AnnouncementResult containing the announcer's public keys, timestamp, and user data, or undefined if invalid
52
+ */
53
+ feedIncomingAnnouncement(announcementBytes: Uint8Array): Promise<AnnouncementResult | undefined>;
54
+ /**
55
+ * Get the list of message board read keys (seekers) to monitor
56
+ */
57
+ getMessageBoardReadKeys(): Array<Uint8Array>;
58
+ /**
59
+ * Process an incoming ciphertext from the message board
60
+ */
61
+ feedIncomingMessageBoardRead(seeker: Uint8Array, ciphertext: Uint8Array): Promise<ReceiveMessageOutput | undefined>;
62
+ /**
63
+ * Send a message to a peer.
64
+ * IMPORTANT: This persists session state before returning.
65
+ * The returned output should only be sent to network AFTER this resolves.
66
+ */
67
+ sendMessage(peerId: Uint8Array, message: Uint8Array): Promise<SendMessageOutput | undefined>;
68
+ /**
69
+ * List all known peer IDs
70
+ */
71
+ peerList(): Array<Uint8Array>;
72
+ /**
73
+ * Get the session status for a peer
74
+ */
75
+ peerSessionStatus(peerId: Uint8Array): SessionStatus;
76
+ /**
77
+ * Discard a peer and all associated session state
78
+ */
79
+ peerDiscard(peerId: Uint8Array): Promise<void>;
80
+ /**
81
+ * Refresh sessions, returning peer IDs that need keep-alive messages
82
+ */
83
+ refresh(): Promise<Array<Uint8Array>>;
84
+ }
85
+ export declare function sessionStatusToString(status: SessionStatus): string;