@massalabs/gossip-sdk 0.0.2-dev.20260128094509
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 +484 -0
- package/package.json +41 -0
- package/src/api/messageProtocol/index.ts +53 -0
- package/src/api/messageProtocol/mock.ts +13 -0
- package/src/api/messageProtocol/rest.ts +209 -0
- package/src/api/messageProtocol/types.ts +70 -0
- package/src/config/protocol.ts +97 -0
- package/src/config/sdk.ts +131 -0
- package/src/contacts.ts +210 -0
- package/src/core/SdkEventEmitter.ts +91 -0
- package/src/core/SdkPolling.ts +134 -0
- package/src/core/index.ts +9 -0
- package/src/crypto/bip39.ts +84 -0
- package/src/crypto/encryption.ts +77 -0
- package/src/db.ts +465 -0
- package/src/gossipSdk.ts +994 -0
- package/src/index.ts +211 -0
- package/src/services/announcement.ts +653 -0
- package/src/services/auth.ts +95 -0
- package/src/services/discussion.ts +380 -0
- package/src/services/message.ts +1055 -0
- package/src/services/refresh.ts +234 -0
- package/src/sw.ts +17 -0
- package/src/types/events.ts +108 -0
- package/src/types.ts +70 -0
- package/src/utils/base64.ts +39 -0
- package/src/utils/contacts.ts +161 -0
- package/src/utils/discussions.ts +55 -0
- package/src/utils/logs.ts +86 -0
- package/src/utils/messageSerialization.ts +257 -0
- package/src/utils/queue.ts +106 -0
- package/src/utils/type.ts +7 -0
- package/src/utils/userId.ts +114 -0
- package/src/utils/validation.ts +144 -0
- package/src/utils.ts +47 -0
- package/src/wasm/encryption.ts +108 -0
- package/src/wasm/index.ts +20 -0
- package/src/wasm/loader.ts +123 -0
- package/src/wasm/session.ts +276 -0
- package/src/wasm/userKeys.ts +31 -0
- package/test/config/protocol.spec.ts +31 -0
- package/test/config/sdk.spec.ts +163 -0
- package/test/db/helpers.spec.ts +142 -0
- package/test/db/operations.spec.ts +128 -0
- package/test/db/states.spec.ts +535 -0
- package/test/integration/discussion-flow.spec.ts +422 -0
- package/test/integration/messaging-flow.spec.ts +708 -0
- package/test/integration/sdk-lifecycle.spec.ts +325 -0
- package/test/mocks/index.ts +9 -0
- package/test/mocks/mockMessageProtocol.ts +100 -0
- package/test/services/auth.spec.ts +311 -0
- package/test/services/discussion.spec.ts +279 -0
- package/test/services/message-deduplication.spec.ts +299 -0
- package/test/services/message-startup.spec.ts +331 -0
- package/test/services/message.spec.ts +817 -0
- package/test/services/refresh.spec.ts +199 -0
- package/test/services/session-status.spec.ts +349 -0
- package/test/session/wasm.spec.ts +227 -0
- package/test/setup.ts +52 -0
- package/test/utils/contacts.spec.ts +156 -0
- package/test/utils/discussions.spec.ts +66 -0
- package/test/utils/queue.spec.ts +52 -0
- package/test/utils/serialization.spec.ts +120 -0
- package/test/utils/userId.spec.ts +120 -0
- package/test/utils/validation.spec.ts +223 -0
- package/test/utils.ts +212 -0
- package/tsconfig.json +26 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/vitest.config.ts +28 -0
package/README.md
ADDED
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
# Gossip SDK
|
|
2
|
+
|
|
3
|
+
A platform-agnostic SDK for the Gossip messenger app. This SDK enables automation, chatbot integrations, and programmatic access to Gossip functionality.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The Gossip SDK provides a clean, typed interface for:
|
|
8
|
+
|
|
9
|
+
- **Account Management** - Create, load, restore, and manage user accounts
|
|
10
|
+
- **Contact Management** - Add, update, and delete contacts
|
|
11
|
+
- **Discussion Management** - Initialize and manage encrypted discussions
|
|
12
|
+
- **Message Operations** - Send and receive encrypted messages
|
|
13
|
+
- **Announcement Handling** - Process protocol announcements
|
|
14
|
+
- **Session Management** - Automatic session renewal and persistence
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
cd gossip-sdk
|
|
20
|
+
npm install
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Peer Dependencies
|
|
24
|
+
|
|
25
|
+
The SDK requires these peer dependencies (provided by the host project):
|
|
26
|
+
|
|
27
|
+
- `dexie` ^4.0.0 - IndexedDB wrapper for local storage
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
The SDK uses a singleton pattern with a simple lifecycle:
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import { gossipSdk, GossipDatabase } from 'gossip-sdk';
|
|
35
|
+
|
|
36
|
+
// 1. Initialize once at app startup
|
|
37
|
+
const db = new GossipDatabase();
|
|
38
|
+
await db.open();
|
|
39
|
+
|
|
40
|
+
await gossipSdk.init({
|
|
41
|
+
db,
|
|
42
|
+
protocolBaseUrl: 'https://api.example.com',
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// 2. Open session (login)
|
|
46
|
+
await gossipSdk.openSession({
|
|
47
|
+
mnemonic: 'word1 word2 word3 ... word12',
|
|
48
|
+
// For existing session:
|
|
49
|
+
encryptedSession: savedBlob,
|
|
50
|
+
encryptionKey: savedKey,
|
|
51
|
+
// For persistence:
|
|
52
|
+
persistEncryptionKey: encryptionKey,
|
|
53
|
+
onPersist: async (blob, key) => {
|
|
54
|
+
await saveToStorage(blob, key);
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// 3. Use the SDK
|
|
59
|
+
const contacts = await gossipSdk.contacts.list(gossipSdk.userId);
|
|
60
|
+
await gossipSdk.discussions.start(contact, 'Hello!');
|
|
61
|
+
await gossipSdk.messages.send(message);
|
|
62
|
+
|
|
63
|
+
// 4. Listen to events
|
|
64
|
+
gossipSdk.on('message', msg => {
|
|
65
|
+
console.log('New message:', msg.content);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// 5. Logout
|
|
69
|
+
await gossipSdk.closeSession();
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Lifecycle
|
|
73
|
+
|
|
74
|
+
### 1. Initialize
|
|
75
|
+
|
|
76
|
+
Call `init()` once at app startup to configure the database and protocol:
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
await gossipSdk.init({
|
|
80
|
+
// Required: Database instance
|
|
81
|
+
db: new GossipDatabase(),
|
|
82
|
+
|
|
83
|
+
// Optional: API base URL (uses default if not provided)
|
|
84
|
+
protocolBaseUrl: 'https://api.usegossip.com',
|
|
85
|
+
|
|
86
|
+
// Optional: Configuration overrides
|
|
87
|
+
config: {
|
|
88
|
+
polling: {
|
|
89
|
+
enabled: true,
|
|
90
|
+
messagesIntervalMs: 3000,
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 2. Open Session (Login)
|
|
97
|
+
|
|
98
|
+
Call `openSession()` to authenticate and create a cryptographic session:
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
// New account (no existing session)
|
|
102
|
+
await gossipSdk.openSession({
|
|
103
|
+
mnemonic: 'word1 word2 word3 ... word12',
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Restore existing session
|
|
107
|
+
await gossipSdk.openSession({
|
|
108
|
+
mnemonic: 'word1 word2 word3 ... word12',
|
|
109
|
+
encryptedSession: savedBlob,
|
|
110
|
+
encryptionKey: savedKey,
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// With persistence (saves session on changes)
|
|
114
|
+
await gossipSdk.openSession({
|
|
115
|
+
mnemonic: 'word1 word2 word3 ... word12',
|
|
116
|
+
persistEncryptionKey: encryptionKey,
|
|
117
|
+
onPersist: async (blob, key) => {
|
|
118
|
+
await db.userProfile.update(userId, { session: blob });
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### 3. Close Session (Logout)
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
await gossipSdk.closeSession();
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Service APIs
|
|
130
|
+
|
|
131
|
+
All services are available after `openSession()` is called.
|
|
132
|
+
|
|
133
|
+
### Messages
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
// Send a message
|
|
137
|
+
const result = await gossipSdk.messages.send({
|
|
138
|
+
ownerUserId: gossipSdk.userId,
|
|
139
|
+
contactUserId: contactId,
|
|
140
|
+
content: 'Hello!',
|
|
141
|
+
type: MessageType.TEXT,
|
|
142
|
+
direction: MessageDirection.OUTGOING,
|
|
143
|
+
status: MessageStatus.SENDING,
|
|
144
|
+
timestamp: new Date(),
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// Fetch new messages from server
|
|
148
|
+
const fetchResult = await gossipSdk.messages.fetch();
|
|
149
|
+
|
|
150
|
+
// Resend failed messages
|
|
151
|
+
await gossipSdk.messages.resend(failedMessagesMap);
|
|
152
|
+
|
|
153
|
+
// Find message by seeker
|
|
154
|
+
const msg = await gossipSdk.messages.findBySeeker(seeker, ownerUserId);
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Discussions
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
// Start a new discussion
|
|
161
|
+
const { discussionId } = await gossipSdk.discussions.start(contact, 'Hello!');
|
|
162
|
+
|
|
163
|
+
// Accept an incoming discussion request
|
|
164
|
+
await gossipSdk.discussions.accept(discussion);
|
|
165
|
+
|
|
166
|
+
// Renew a broken session
|
|
167
|
+
await gossipSdk.discussions.renew(contactUserId);
|
|
168
|
+
|
|
169
|
+
// Check if discussion can send messages
|
|
170
|
+
const canSend = await gossipSdk.discussions.isStable(
|
|
171
|
+
ownerUserId,
|
|
172
|
+
contactUserId
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
// List all discussions
|
|
176
|
+
const discussions = await gossipSdk.discussions.list(ownerUserId);
|
|
177
|
+
|
|
178
|
+
// Get a specific discussion
|
|
179
|
+
const discussion = await gossipSdk.discussions.get(ownerUserId, contactUserId);
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Contacts
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
// List all contacts
|
|
186
|
+
const contacts = await gossipSdk.contacts.list(ownerUserId);
|
|
187
|
+
|
|
188
|
+
// Get a specific contact
|
|
189
|
+
const contact = await gossipSdk.contacts.get(ownerUserId, contactUserId);
|
|
190
|
+
|
|
191
|
+
// Add a new contact
|
|
192
|
+
const result = await gossipSdk.contacts.add(
|
|
193
|
+
ownerUserId,
|
|
194
|
+
contactUserId,
|
|
195
|
+
'Alice',
|
|
196
|
+
publicKeys
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
// Update contact name
|
|
200
|
+
await gossipSdk.contacts.updateName(ownerUserId, contactUserId, 'Alice Smith');
|
|
201
|
+
|
|
202
|
+
// Delete contact and all associated data
|
|
203
|
+
await gossipSdk.contacts.delete(ownerUserId, contactUserId);
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Announcements
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
// Fetch and process announcements from server
|
|
210
|
+
const result = await gossipSdk.announcements.fetch();
|
|
211
|
+
|
|
212
|
+
// Resend failed announcements
|
|
213
|
+
await gossipSdk.announcements.resend(failedDiscussions);
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Auth (Available before session)
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
// Create a new account
|
|
220
|
+
const result = await gossipSdk.auth.createAccount(
|
|
221
|
+
username,
|
|
222
|
+
mnemonic,
|
|
223
|
+
encryptionKey
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
// Restore account from mnemonic
|
|
227
|
+
const result = await gossipSdk.auth.restoreAccount(
|
|
228
|
+
username,
|
|
229
|
+
mnemonic,
|
|
230
|
+
encryptionKey
|
|
231
|
+
);
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Refresh
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
// Handle session refresh for active discussions
|
|
238
|
+
await gossipSdk.refresh.handleSessionRefresh(activeDiscussions);
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Events
|
|
242
|
+
|
|
243
|
+
Subscribe to SDK events for real-time updates:
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
// Message events
|
|
247
|
+
gossipSdk.on('message', message => {
|
|
248
|
+
// New message received
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
gossipSdk.on('messageSent', message => {
|
|
252
|
+
// Message sent successfully
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
gossipSdk.on('messageFailed', (message, error) => {
|
|
256
|
+
// Message failed to send
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
// Discussion events
|
|
260
|
+
gossipSdk.on('discussionRequest', (discussion, contact) => {
|
|
261
|
+
// Incoming discussion request
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
gossipSdk.on('discussionStatusChanged', discussion => {
|
|
265
|
+
// Discussion status changed
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
// Session events
|
|
269
|
+
gossipSdk.on('sessionBroken', discussion => {
|
|
270
|
+
// Session broken (deprecated - use auto-renewal)
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
gossipSdk.on('sessionRenewed', discussion => {
|
|
274
|
+
// Session successfully renewed
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
// Error handling
|
|
278
|
+
gossipSdk.on('error', (error, context) => {
|
|
279
|
+
console.error(`Error in ${context}:`, error);
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
// Unsubscribe
|
|
283
|
+
gossipSdk.off('message', handler);
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## Polling
|
|
287
|
+
|
|
288
|
+
The SDK can automatically poll for messages, announcements, and session refresh:
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
// Enable via config
|
|
292
|
+
await gossipSdk.init({
|
|
293
|
+
db,
|
|
294
|
+
config: {
|
|
295
|
+
polling: {
|
|
296
|
+
enabled: true,
|
|
297
|
+
messagesIntervalMs: 5000,
|
|
298
|
+
announcementsIntervalMs: 10000,
|
|
299
|
+
sessionRefreshIntervalMs: 30000,
|
|
300
|
+
},
|
|
301
|
+
},
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
// Or control manually
|
|
305
|
+
gossipSdk.polling.start();
|
|
306
|
+
gossipSdk.polling.stop();
|
|
307
|
+
console.log(gossipSdk.polling.isRunning);
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## Session Info
|
|
311
|
+
|
|
312
|
+
Access session information after `openSession()`:
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
// User ID (encoded string)
|
|
316
|
+
const userId = gossipSdk.userId;
|
|
317
|
+
|
|
318
|
+
// User ID (raw bytes)
|
|
319
|
+
const userIdBytes = gossipSdk.userIdBytes;
|
|
320
|
+
|
|
321
|
+
// Public keys
|
|
322
|
+
const publicKeys = gossipSdk.publicKeys;
|
|
323
|
+
|
|
324
|
+
// Check session state
|
|
325
|
+
console.log(gossipSdk.isInitialized); // true after init()
|
|
326
|
+
console.log(gossipSdk.isSessionOpen); // true after openSession()
|
|
327
|
+
|
|
328
|
+
// Get encrypted session for manual persistence
|
|
329
|
+
const blob = gossipSdk.getEncryptedSession(encryptionKey);
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
## Configuration
|
|
333
|
+
|
|
334
|
+
Full configuration options with defaults:
|
|
335
|
+
|
|
336
|
+
```typescript
|
|
337
|
+
await gossipSdk.init({
|
|
338
|
+
db,
|
|
339
|
+
config: {
|
|
340
|
+
// Network settings
|
|
341
|
+
protocol: {
|
|
342
|
+
baseUrl: 'https://api.usegossip.com', // API endpoint
|
|
343
|
+
timeout: 10000, // Request timeout (ms)
|
|
344
|
+
retryAttempts: 3, // Retry count
|
|
345
|
+
},
|
|
346
|
+
|
|
347
|
+
// Polling settings
|
|
348
|
+
polling: {
|
|
349
|
+
enabled: false, // Auto-start polling
|
|
350
|
+
messagesIntervalMs: 5000, // Message fetch interval
|
|
351
|
+
announcementsIntervalMs: 10000, // Announcement fetch interval
|
|
352
|
+
sessionRefreshIntervalMs: 30000, // Session refresh interval
|
|
353
|
+
},
|
|
354
|
+
|
|
355
|
+
// Message settings
|
|
356
|
+
messages: {
|
|
357
|
+
fetchDelayMs: 100, // Delay between fetch iterations
|
|
358
|
+
maxFetchIterations: 30, // Max iterations per fetch call
|
|
359
|
+
deduplicationWindowMs: 30000, // Duplicate detection window
|
|
360
|
+
},
|
|
361
|
+
|
|
362
|
+
// Announcement settings
|
|
363
|
+
announcements: {
|
|
364
|
+
fetchLimit: 500, // Max announcements per request
|
|
365
|
+
brokenThresholdMs: 3600000, // Time before marking broken (1 hour)
|
|
366
|
+
},
|
|
367
|
+
},
|
|
368
|
+
});
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
## Utilities
|
|
372
|
+
|
|
373
|
+
```typescript
|
|
374
|
+
const utils = gossipSdk.utils;
|
|
375
|
+
|
|
376
|
+
// Validate user ID format
|
|
377
|
+
const result = utils.validateUserId(userId);
|
|
378
|
+
if (!result.valid) console.error(result.error);
|
|
379
|
+
|
|
380
|
+
// Validate username format
|
|
381
|
+
const result = utils.validateUsername(username);
|
|
382
|
+
|
|
383
|
+
// Encode/decode user IDs
|
|
384
|
+
const encoded = utils.encodeUserId(rawBytes);
|
|
385
|
+
const decoded = utils.decodeUserId(encodedString);
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
## Session Persistence
|
|
389
|
+
|
|
390
|
+
For restoring sessions across app restarts:
|
|
391
|
+
|
|
392
|
+
```typescript
|
|
393
|
+
// Option 1: Provide persistence config in openSession
|
|
394
|
+
await gossipSdk.openSession({
|
|
395
|
+
mnemonic,
|
|
396
|
+
persistEncryptionKey: key,
|
|
397
|
+
onPersist: async (blob, key) => {
|
|
398
|
+
// Save blob to your storage
|
|
399
|
+
await db.userProfile.update(userId, { session: blob });
|
|
400
|
+
},
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
// Option 2: Configure persistence after account creation
|
|
404
|
+
await gossipSdk.openSession({ mnemonic });
|
|
405
|
+
// ... create account, get encryption key ...
|
|
406
|
+
gossipSdk.configurePersistence(encryptionKey, async (blob, key) => {
|
|
407
|
+
await db.userProfile.update(userId, { session: blob });
|
|
408
|
+
});
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
## Auto-Renewal Behavior
|
|
412
|
+
|
|
413
|
+
The SDK automatically handles session recovery:
|
|
414
|
+
|
|
415
|
+
1. **Session Lost** - When a session is killed/lost, messages are queued as `WAITING_SESSION`
|
|
416
|
+
2. **Auto-Renewal** - SDK emits `onSessionRenewalNeeded` and attempts renewal
|
|
417
|
+
3. **Auto-Accept** - When peer sends announcement, SDK auto-accepts for existing contacts
|
|
418
|
+
4. **Message Processing** - After session becomes active, queued messages are sent automatically
|
|
419
|
+
|
|
420
|
+
See [STATUS-REFERENCE.md](./docs/STATUS-REFERENCE.md) for detailed status documentation.
|
|
421
|
+
|
|
422
|
+
## Types
|
|
423
|
+
|
|
424
|
+
Import types from the SDK:
|
|
425
|
+
|
|
426
|
+
```typescript
|
|
427
|
+
import type {
|
|
428
|
+
UserProfile,
|
|
429
|
+
Contact,
|
|
430
|
+
Discussion,
|
|
431
|
+
Message,
|
|
432
|
+
DiscussionStatus,
|
|
433
|
+
DiscussionDirection,
|
|
434
|
+
MessageStatus,
|
|
435
|
+
MessageDirection,
|
|
436
|
+
MessageType,
|
|
437
|
+
} from 'gossip-sdk';
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
## Testing
|
|
441
|
+
|
|
442
|
+
```bash
|
|
443
|
+
npm test # Watch mode
|
|
444
|
+
npm run test:run # Single run
|
|
445
|
+
npm run test:coverage # With coverage report
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
Tests use `fake-indexeddb` to simulate IndexedDB in Node.js environment.
|
|
449
|
+
|
|
450
|
+
## Architecture
|
|
451
|
+
|
|
452
|
+
```
|
|
453
|
+
gossip-sdk/
|
|
454
|
+
├── src/
|
|
455
|
+
│ ├── gossipSdk.ts # Main singleton SDK class
|
|
456
|
+
│ ├── db.ts # Database (Dexie) implementation
|
|
457
|
+
│ ├── contacts.ts # Contact operations
|
|
458
|
+
│ ├── api/
|
|
459
|
+
│ │ └── messageProtocol/ # REST protocol implementation
|
|
460
|
+
│ ├── config/
|
|
461
|
+
│ │ ├── protocol.ts # API configuration
|
|
462
|
+
│ │ └── sdk.ts # SDK configuration
|
|
463
|
+
│ ├── core/
|
|
464
|
+
│ │ ├── SdkEventEmitter.ts # Event system
|
|
465
|
+
│ │ └── SdkPolling.ts # Polling manager
|
|
466
|
+
│ ├── services/
|
|
467
|
+
│ │ ├── auth.ts # Auth service
|
|
468
|
+
│ │ ├── message.ts # Message service
|
|
469
|
+
│ │ ├── discussion.ts # Discussion service
|
|
470
|
+
│ │ ├── announcement.ts # Announcement service
|
|
471
|
+
│ │ └── refresh.ts # Session refresh service
|
|
472
|
+
│ ├── types/
|
|
473
|
+
│ │ └── events.ts # Event type definitions
|
|
474
|
+
│ ├── utils/ # Utility modules
|
|
475
|
+
│ └── wasm/ # WASM module wrappers
|
|
476
|
+
├── test/ # Test files
|
|
477
|
+
├── docs/
|
|
478
|
+
│ └── STATUS-REFERENCE.md # Status documentation
|
|
479
|
+
└── README.md
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
## License
|
|
483
|
+
|
|
484
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@massalabs/gossip-sdk",
|
|
3
|
+
"version": "0.0.2-dev.20260128094509",
|
|
4
|
+
"description": "Gossip SDK for automation, chatbot, and integration use cases",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./sw": {
|
|
14
|
+
"types": "./dist/sw.d.ts",
|
|
15
|
+
"import": "./dist/sw.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc && mkdir -p dist/assets/generated/wasm && cp -R src/assets/generated/wasm/* dist/assets/generated/wasm/",
|
|
20
|
+
"test": "vitest",
|
|
21
|
+
"test:run": "vitest run",
|
|
22
|
+
"test:coverage": "vitest run --coverage"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"gossip",
|
|
26
|
+
"messenger",
|
|
27
|
+
"sdk",
|
|
28
|
+
"massa",
|
|
29
|
+
"blockchain"
|
|
30
|
+
],
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"fake-indexeddb": "^6.2.5",
|
|
34
|
+
"typescript": "^5.9.3",
|
|
35
|
+
"vitest": "^4.0.17"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"dexie": "^4.0.0",
|
|
39
|
+
"zustand": "^5.0.0"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message Protocol Module
|
|
3
|
+
*
|
|
4
|
+
* Factory functions and exports for message protocol implementations.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export type {
|
|
8
|
+
EncryptedMessage,
|
|
9
|
+
IMessageProtocol,
|
|
10
|
+
MessageProtocolResponse,
|
|
11
|
+
BulletinItem,
|
|
12
|
+
} from './types';
|
|
13
|
+
export { RestMessageProtocol } from './rest';
|
|
14
|
+
export { MessageProtocol } from './mock';
|
|
15
|
+
|
|
16
|
+
import type { IMessageProtocol } from './types';
|
|
17
|
+
import {
|
|
18
|
+
defaultMessageProtocol,
|
|
19
|
+
protocolConfig,
|
|
20
|
+
type MessageProtocolType,
|
|
21
|
+
} from '../../config/protocol';
|
|
22
|
+
|
|
23
|
+
import { RestMessageProtocol } from './rest';
|
|
24
|
+
import { MessageProtocol } from './mock';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Factory function to create message protocol instances
|
|
28
|
+
*/
|
|
29
|
+
export function createMessageProtocol(
|
|
30
|
+
type: MessageProtocolType = defaultMessageProtocol,
|
|
31
|
+
config?: Partial<{ baseUrl: string; timeout: number; retryAttempts: number }>
|
|
32
|
+
): IMessageProtocol {
|
|
33
|
+
switch (type) {
|
|
34
|
+
case 'rest': {
|
|
35
|
+
return new RestMessageProtocol(
|
|
36
|
+
config?.baseUrl || protocolConfig.baseUrl,
|
|
37
|
+
config?.timeout || 10000,
|
|
38
|
+
config?.retryAttempts || 3
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
case 'mock': {
|
|
42
|
+
return new MessageProtocol(
|
|
43
|
+
config?.baseUrl || protocolConfig.baseUrl,
|
|
44
|
+
config?.timeout || 10000,
|
|
45
|
+
config?.retryAttempts || 3
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
default:
|
|
49
|
+
throw new Error(`Unsupported message protocol type: ${type}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export const restMessageProtocol = createMessageProtocol();
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message Protocol Implementation
|
|
3
|
+
*
|
|
4
|
+
* Provides a concrete protocol class backed by the REST implementation.
|
|
5
|
+
* This uses the real Gossip API rather than a mock transport.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { RestMessageProtocol } from './rest';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Create a MessageProtocol instance backed by REST.
|
|
12
|
+
*/
|
|
13
|
+
export class MessageProtocol extends RestMessageProtocol {}
|