@massalabs/gossip-sdk 0.0.2-dev.20260128094509 → 0.0.2-dev.20260128111120
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/messageProtocol/index.d.ts +19 -0
- package/dist/api/messageProtocol/index.js +26 -0
- package/dist/api/messageProtocol/mock.d.ts +12 -0
- package/{src/api/messageProtocol/mock.ts → dist/api/messageProtocol/mock.js} +2 -3
- package/dist/api/messageProtocol/rest.d.ts +22 -0
- package/dist/api/messageProtocol/rest.js +161 -0
- package/dist/api/messageProtocol/types.d.ts +61 -0
- package/dist/api/messageProtocol/types.js +6 -0
- package/dist/assets/generated/wasm/README.md +281 -0
- package/dist/assets/generated/wasm/gossip_wasm.d.ts +498 -0
- package/dist/assets/generated/wasm/gossip_wasm.js +1399 -0
- package/dist/assets/generated/wasm/gossip_wasm_bg.wasm +0 -0
- package/dist/assets/generated/wasm/gossip_wasm_bg.wasm.d.ts +68 -0
- package/dist/assets/generated/wasm/package.json +15 -0
- package/dist/config/protocol.d.ts +36 -0
- package/dist/config/protocol.js +77 -0
- package/dist/config/sdk.d.ts +82 -0
- package/dist/config/sdk.js +55 -0
- package/{src/contacts.ts → dist/contacts.d.ts} +10 -94
- package/dist/contacts.js +166 -0
- package/dist/core/SdkEventEmitter.d.ts +36 -0
- package/dist/core/SdkEventEmitter.js +59 -0
- package/dist/core/SdkPolling.d.ts +35 -0
- package/dist/core/SdkPolling.js +100 -0
- package/{src/core/index.ts → dist/core/index.d.ts} +0 -2
- package/dist/core/index.js +5 -0
- package/dist/crypto/bip39.d.ts +34 -0
- package/dist/crypto/bip39.js +62 -0
- package/dist/crypto/encryption.d.ts +37 -0
- package/dist/crypto/encryption.js +46 -0
- package/dist/db.d.ts +190 -0
- package/dist/db.js +311 -0
- package/dist/gossipSdk.d.ts +274 -0
- package/dist/gossipSdk.js +690 -0
- package/dist/index.d.ts +73 -0
- package/dist/index.js +77 -0
- package/dist/services/announcement.d.ts +43 -0
- package/dist/services/announcement.js +491 -0
- package/dist/services/auth.d.ts +37 -0
- package/dist/services/auth.js +76 -0
- package/dist/services/discussion.d.ts +63 -0
- package/dist/services/discussion.js +297 -0
- package/dist/services/message.d.ts +74 -0
- package/dist/services/message.js +826 -0
- package/dist/services/refresh.d.ts +41 -0
- package/dist/services/refresh.js +205 -0
- package/{src/sw.ts → dist/sw.d.ts} +1 -8
- package/dist/sw.js +10 -0
- package/dist/types/events.d.ts +80 -0
- package/dist/types/events.js +7 -0
- package/dist/types.d.ts +32 -0
- package/dist/types.js +7 -0
- package/dist/utils/base64.d.ts +10 -0
- package/dist/utils/base64.js +30 -0
- package/dist/utils/contacts.d.ts +42 -0
- package/dist/utils/contacts.js +113 -0
- package/dist/utils/discussions.d.ts +24 -0
- package/dist/utils/discussions.js +38 -0
- package/dist/utils/logs.d.ts +19 -0
- package/dist/utils/logs.js +89 -0
- package/dist/utils/messageSerialization.d.ts +64 -0
- package/dist/utils/messageSerialization.js +184 -0
- package/dist/utils/queue.d.ts +50 -0
- package/dist/utils/queue.js +110 -0
- package/dist/utils/type.d.ts +10 -0
- package/dist/utils/type.js +4 -0
- package/dist/utils/userId.d.ts +40 -0
- package/dist/utils/userId.js +90 -0
- package/dist/utils/validation.d.ts +50 -0
- package/dist/utils/validation.js +112 -0
- package/dist/utils.d.ts +30 -0
- package/{src/utils.ts → dist/utils.js} +9 -19
- package/dist/wasm/encryption.d.ts +56 -0
- package/{src/wasm/encryption.ts → dist/wasm/encryption.js} +22 -51
- package/dist/wasm/index.d.ts +10 -0
- package/{src/wasm/index.ts → dist/wasm/index.js} +1 -8
- package/dist/wasm/loader.d.ts +21 -0
- package/dist/wasm/loader.js +103 -0
- package/dist/wasm/session.d.ts +85 -0
- package/dist/wasm/session.js +226 -0
- package/dist/wasm/userKeys.d.ts +17 -0
- package/{src/wasm/userKeys.ts → dist/wasm/userKeys.js} +6 -13
- package/package.json +5 -1
- package/src/api/messageProtocol/index.ts +0 -53
- package/src/api/messageProtocol/rest.ts +0 -209
- package/src/api/messageProtocol/types.ts +0 -70
- package/src/config/protocol.ts +0 -97
- package/src/config/sdk.ts +0 -131
- package/src/core/SdkEventEmitter.ts +0 -91
- package/src/core/SdkPolling.ts +0 -134
- package/src/crypto/bip39.ts +0 -84
- package/src/crypto/encryption.ts +0 -77
- package/src/db.ts +0 -465
- package/src/gossipSdk.ts +0 -994
- package/src/index.ts +0 -211
- package/src/services/announcement.ts +0 -653
- package/src/services/auth.ts +0 -95
- package/src/services/discussion.ts +0 -380
- package/src/services/message.ts +0 -1055
- package/src/services/refresh.ts +0 -234
- package/src/types/events.ts +0 -108
- package/src/types.ts +0 -70
- package/src/utils/base64.ts +0 -39
- package/src/utils/contacts.ts +0 -161
- package/src/utils/discussions.ts +0 -55
- package/src/utils/logs.ts +0 -86
- package/src/utils/messageSerialization.ts +0 -257
- package/src/utils/queue.ts +0 -106
- package/src/utils/type.ts +0 -7
- package/src/utils/userId.ts +0 -114
- package/src/utils/validation.ts +0 -144
- package/src/wasm/loader.ts +0 -123
- package/src/wasm/session.ts +0 -276
- package/test/config/protocol.spec.ts +0 -31
- package/test/config/sdk.spec.ts +0 -163
- package/test/db/helpers.spec.ts +0 -142
- package/test/db/operations.spec.ts +0 -128
- package/test/db/states.spec.ts +0 -535
- package/test/integration/discussion-flow.spec.ts +0 -422
- package/test/integration/messaging-flow.spec.ts +0 -708
- package/test/integration/sdk-lifecycle.spec.ts +0 -325
- package/test/mocks/index.ts +0 -9
- package/test/mocks/mockMessageProtocol.ts +0 -100
- package/test/services/auth.spec.ts +0 -311
- package/test/services/discussion.spec.ts +0 -279
- package/test/services/message-deduplication.spec.ts +0 -299
- package/test/services/message-startup.spec.ts +0 -331
- package/test/services/message.spec.ts +0 -817
- package/test/services/refresh.spec.ts +0 -199
- package/test/services/session-status.spec.ts +0 -349
- package/test/session/wasm.spec.ts +0 -227
- package/test/setup.ts +0 -52
- package/test/utils/contacts.spec.ts +0 -156
- package/test/utils/discussions.spec.ts +0 -66
- package/test/utils/queue.spec.ts +0 -52
- package/test/utils/serialization.spec.ts +0 -120
- package/test/utils/userId.spec.ts +0 -120
- package/test/utils/validation.spec.ts +0 -223
- package/test/utils.ts +0 -212
- package/tsconfig.json +0 -26
- package/tsconfig.tsbuildinfo +0 -1
- package/vitest.config.ts +0 -28
package/src/config/protocol.ts
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Protocol API Configuration
|
|
3
|
-
*
|
|
4
|
-
* Centralized configuration for the message protocol API endpoints.
|
|
5
|
-
* This allows easy switching between different protocol implementations.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
export interface ProtocolConfig {
|
|
9
|
-
baseUrl: string;
|
|
10
|
-
timeout: number;
|
|
11
|
-
retryAttempts: number;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// Default API URL for the hosted REST protocol.
|
|
15
|
-
// Override via setProtocolBaseUrl() or environment variables.
|
|
16
|
-
const DEFAULT_API_URL = 'https://api.usegossip.com';
|
|
17
|
-
|
|
18
|
-
// Mutable config that can be updated at runtime
|
|
19
|
-
let currentBaseUrl: string | null = null;
|
|
20
|
-
|
|
21
|
-
function buildProtocolApiBaseUrl(): string {
|
|
22
|
-
// If runtime override is set, use it
|
|
23
|
-
if (currentBaseUrl !== null) {
|
|
24
|
-
return currentBaseUrl;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// Try to get from environment variable (Vite)
|
|
28
|
-
let apiUrl: string | undefined;
|
|
29
|
-
try {
|
|
30
|
-
// Check if import.meta.env is available (Vite environment)
|
|
31
|
-
if (
|
|
32
|
-
typeof import.meta !== 'undefined' &&
|
|
33
|
-
import.meta.env?.VITE_GOSSIP_API_URL
|
|
34
|
-
) {
|
|
35
|
-
apiUrl = import.meta.env.VITE_GOSSIP_API_URL;
|
|
36
|
-
}
|
|
37
|
-
} catch {
|
|
38
|
-
// import.meta.env not available (Node.js without Vite)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Check process.env for Node.js environment
|
|
42
|
-
if (
|
|
43
|
-
!apiUrl &&
|
|
44
|
-
typeof process !== 'undefined' &&
|
|
45
|
-
process.env?.GOSSIP_API_URL
|
|
46
|
-
) {
|
|
47
|
-
apiUrl = process.env.GOSSIP_API_URL;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Fall back to default
|
|
51
|
-
if (!apiUrl) apiUrl = DEFAULT_API_URL;
|
|
52
|
-
|
|
53
|
-
// Normalize trailing slashes to avoid `//api`
|
|
54
|
-
const trimmed = apiUrl.replace(/\/+$/, '');
|
|
55
|
-
return `${trimmed}/api`;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export const protocolConfig: ProtocolConfig = {
|
|
59
|
-
get baseUrl() {
|
|
60
|
-
return buildProtocolApiBaseUrl();
|
|
61
|
-
},
|
|
62
|
-
timeout: 10000,
|
|
63
|
-
retryAttempts: 3,
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
export enum MessageProtocolType {
|
|
67
|
-
REST = 'rest',
|
|
68
|
-
MOCK = 'mock',
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export const defaultMessageProtocol: MessageProtocolType =
|
|
72
|
-
MessageProtocolType.REST;
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Set the base URL for the protocol API at runtime.
|
|
76
|
-
* This overrides environment variables and defaults.
|
|
77
|
-
*
|
|
78
|
-
* @param baseUrl - The base URL to use (e.g., 'https://api.example.com/api')
|
|
79
|
-
*
|
|
80
|
-
* @example
|
|
81
|
-
* ```typescript
|
|
82
|
-
* import { setProtocolBaseUrl } from 'gossip-sdk';
|
|
83
|
-
*
|
|
84
|
-
* // Set custom API endpoint
|
|
85
|
-
* setProtocolBaseUrl('https://my-server.com/api');
|
|
86
|
-
* ```
|
|
87
|
-
*/
|
|
88
|
-
export function setProtocolBaseUrl(baseUrl: string): void {
|
|
89
|
-
currentBaseUrl = baseUrl;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Reset the base URL to use environment variables or defaults.
|
|
94
|
-
*/
|
|
95
|
-
export function resetProtocolBaseUrl(): void {
|
|
96
|
-
currentBaseUrl = null;
|
|
97
|
-
}
|
package/src/config/sdk.ts
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SDK Configuration
|
|
3
|
-
*
|
|
4
|
-
* Centralized configuration for the Gossip SDK.
|
|
5
|
-
* All values have sensible defaults that can be overridden.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Protocol configuration for network requests
|
|
10
|
-
*/
|
|
11
|
-
export interface ProtocolConfig {
|
|
12
|
-
/** API base URL (default: from environment or https://api.usegossip.com) */
|
|
13
|
-
baseUrl?: string;
|
|
14
|
-
/** Request timeout in milliseconds (default: 10000) */
|
|
15
|
-
timeout: number;
|
|
16
|
-
/** Number of retry attempts for failed requests (default: 3) */
|
|
17
|
-
retryAttempts: number;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Polling configuration for automatic message/announcement fetching
|
|
22
|
-
*/
|
|
23
|
-
export interface PollingConfig {
|
|
24
|
-
/** Enable automatic polling (default: false) */
|
|
25
|
-
enabled: boolean;
|
|
26
|
-
/** Interval for fetching messages in milliseconds (default: 5000) */
|
|
27
|
-
messagesIntervalMs: number;
|
|
28
|
-
/** Interval for fetching announcements in milliseconds (default: 10000) */
|
|
29
|
-
announcementsIntervalMs: number;
|
|
30
|
-
/** Interval for session refresh/keep-alive in milliseconds (default: 30000) */
|
|
31
|
-
sessionRefreshIntervalMs: number;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Message fetching configuration
|
|
36
|
-
*/
|
|
37
|
-
export interface MessagesConfig {
|
|
38
|
-
/** Delay between fetch iterations in milliseconds (default: 100) */
|
|
39
|
-
fetchDelayMs: number;
|
|
40
|
-
/** Maximum number of fetch iterations per call (default: 30) */
|
|
41
|
-
maxFetchIterations: number;
|
|
42
|
-
/**
|
|
43
|
-
* Time window in milliseconds for duplicate detection (default: 30000 = 30 seconds).
|
|
44
|
-
* Messages with same content from same sender within this window are considered duplicates.
|
|
45
|
-
* This handles edge case where app crashes after network send but before DB update,
|
|
46
|
-
* resulting in message being re-sent on restart.
|
|
47
|
-
*/
|
|
48
|
-
deduplicationWindowMs: number;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Announcement configuration
|
|
53
|
-
*/
|
|
54
|
-
export interface AnnouncementsConfig {
|
|
55
|
-
/** Maximum announcements to fetch per request (default: 500) */
|
|
56
|
-
fetchLimit: number;
|
|
57
|
-
/** Time before marking failed announcements as broken in ms (default: 3600000 = 1 hour) */
|
|
58
|
-
brokenThresholdMs: number;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Complete SDK configuration
|
|
63
|
-
*/
|
|
64
|
-
export interface SdkConfig {
|
|
65
|
-
/** Network/protocol settings */
|
|
66
|
-
protocol: ProtocolConfig;
|
|
67
|
-
/** Automatic polling settings */
|
|
68
|
-
polling: PollingConfig;
|
|
69
|
-
/** Message fetching settings */
|
|
70
|
-
messages: MessagesConfig;
|
|
71
|
-
/** Announcement settings */
|
|
72
|
-
announcements: AnnouncementsConfig;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Default SDK configuration values
|
|
77
|
-
*/
|
|
78
|
-
export const defaultSdkConfig: SdkConfig = {
|
|
79
|
-
protocol: {
|
|
80
|
-
timeout: 10000,
|
|
81
|
-
retryAttempts: 3,
|
|
82
|
-
},
|
|
83
|
-
polling: {
|
|
84
|
-
enabled: false,
|
|
85
|
-
messagesIntervalMs: 5000,
|
|
86
|
-
announcementsIntervalMs: 10000,
|
|
87
|
-
sessionRefreshIntervalMs: 30000,
|
|
88
|
-
},
|
|
89
|
-
messages: {
|
|
90
|
-
fetchDelayMs: 100,
|
|
91
|
-
maxFetchIterations: 30,
|
|
92
|
-
deduplicationWindowMs: 30000, // 30 seconds
|
|
93
|
-
},
|
|
94
|
-
announcements: {
|
|
95
|
-
fetchLimit: 500,
|
|
96
|
-
brokenThresholdMs: 60 * 60 * 1000, // 1 hour
|
|
97
|
-
},
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Deep merge partial config with defaults
|
|
102
|
-
*/
|
|
103
|
-
export function mergeConfig(partial?: DeepPartial<SdkConfig>): SdkConfig {
|
|
104
|
-
if (!partial) return { ...defaultSdkConfig };
|
|
105
|
-
|
|
106
|
-
return {
|
|
107
|
-
protocol: {
|
|
108
|
-
...defaultSdkConfig.protocol,
|
|
109
|
-
...partial.protocol,
|
|
110
|
-
},
|
|
111
|
-
polling: {
|
|
112
|
-
...defaultSdkConfig.polling,
|
|
113
|
-
...partial.polling,
|
|
114
|
-
},
|
|
115
|
-
messages: {
|
|
116
|
-
...defaultSdkConfig.messages,
|
|
117
|
-
...partial.messages,
|
|
118
|
-
},
|
|
119
|
-
announcements: {
|
|
120
|
-
...defaultSdkConfig.announcements,
|
|
121
|
-
...partial.announcements,
|
|
122
|
-
},
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Helper type for deep partial objects
|
|
128
|
-
*/
|
|
129
|
-
export type DeepPartial<T> = {
|
|
130
|
-
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
|
|
131
|
-
};
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SDK Event Emitter
|
|
3
|
-
*
|
|
4
|
-
* Type-safe event emitter for SDK events.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { Message, Discussion, Contact } from '../db';
|
|
8
|
-
|
|
9
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
10
|
-
// Event Types
|
|
11
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
12
|
-
|
|
13
|
-
export type SdkEventType =
|
|
14
|
-
| 'message'
|
|
15
|
-
| 'messageSent'
|
|
16
|
-
| 'messageFailed'
|
|
17
|
-
| 'discussionRequest'
|
|
18
|
-
| 'discussionStatusChanged'
|
|
19
|
-
| 'sessionBroken'
|
|
20
|
-
| 'sessionRenewed'
|
|
21
|
-
| 'error';
|
|
22
|
-
|
|
23
|
-
export interface SdkEventHandlers {
|
|
24
|
-
message: (message: Message) => void;
|
|
25
|
-
messageSent: (message: Message) => void;
|
|
26
|
-
messageFailed: (message: Message, error: Error) => void;
|
|
27
|
-
discussionRequest: (discussion: Discussion, contact: Contact) => void;
|
|
28
|
-
discussionStatusChanged: (discussion: Discussion) => void;
|
|
29
|
-
sessionBroken: (discussion: Discussion) => void;
|
|
30
|
-
sessionRenewed: (discussion: Discussion) => void;
|
|
31
|
-
error: (error: Error, context: string) => void;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
35
|
-
// Event Emitter Class
|
|
36
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
37
|
-
|
|
38
|
-
export class SdkEventEmitter {
|
|
39
|
-
private handlers = {
|
|
40
|
-
message: new Set<SdkEventHandlers['message']>(),
|
|
41
|
-
messageSent: new Set<SdkEventHandlers['messageSent']>(),
|
|
42
|
-
messageFailed: new Set<SdkEventHandlers['messageFailed']>(),
|
|
43
|
-
discussionRequest: new Set<SdkEventHandlers['discussionRequest']>(),
|
|
44
|
-
discussionStatusChanged: new Set<
|
|
45
|
-
SdkEventHandlers['discussionStatusChanged']
|
|
46
|
-
>(),
|
|
47
|
-
sessionBroken: new Set<SdkEventHandlers['sessionBroken']>(),
|
|
48
|
-
sessionRenewed: new Set<SdkEventHandlers['sessionRenewed']>(),
|
|
49
|
-
error: new Set<SdkEventHandlers['error']>(),
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Register an event handler
|
|
54
|
-
*/
|
|
55
|
-
on<K extends SdkEventType>(event: K, handler: SdkEventHandlers[K]): void {
|
|
56
|
-
(this.handlers[event] as Set<SdkEventHandlers[K]>).add(handler);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Remove an event handler
|
|
61
|
-
*/
|
|
62
|
-
off<K extends SdkEventType>(event: K, handler: SdkEventHandlers[K]): void {
|
|
63
|
-
(this.handlers[event] as Set<SdkEventHandlers[K]>).delete(handler);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Emit an event to all registered handlers
|
|
68
|
-
*/
|
|
69
|
-
emit<K extends SdkEventType>(
|
|
70
|
-
event: K,
|
|
71
|
-
...args: Parameters<SdkEventHandlers[K]>
|
|
72
|
-
): void {
|
|
73
|
-
const handlers = this.handlers[event] as Set<SdkEventHandlers[K]>;
|
|
74
|
-
handlers.forEach(handler => {
|
|
75
|
-
try {
|
|
76
|
-
(handler as (...args: Parameters<SdkEventHandlers[K]>) => void)(
|
|
77
|
-
...args
|
|
78
|
-
);
|
|
79
|
-
} catch (error) {
|
|
80
|
-
console.error(`[SdkEventEmitter] Error in ${event} handler:`, error);
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Remove all handlers for all events
|
|
87
|
-
*/
|
|
88
|
-
clear(): void {
|
|
89
|
-
Object.values(this.handlers).forEach(set => set.clear());
|
|
90
|
-
}
|
|
91
|
-
}
|
package/src/core/SdkPolling.ts
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SDK Polling Manager
|
|
3
|
-
*
|
|
4
|
-
* Manages polling timers for messages, announcements, and session refresh.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { SdkConfig } from '../config/sdk';
|
|
8
|
-
import type { Discussion } from '../db';
|
|
9
|
-
|
|
10
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
11
|
-
// Types
|
|
12
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
13
|
-
|
|
14
|
-
export interface PollingCallbacks {
|
|
15
|
-
/** Fetch messages from protocol */
|
|
16
|
-
fetchMessages: () => Promise<void>;
|
|
17
|
-
/** Fetch and process announcements */
|
|
18
|
-
fetchAnnouncements: () => Promise<void>;
|
|
19
|
-
/** Handle session refresh for active discussions */
|
|
20
|
-
handleSessionRefresh: (discussions: Discussion[]) => Promise<void>;
|
|
21
|
-
/** Get active discussions for session refresh */
|
|
22
|
-
getActiveDiscussions: () => Promise<Discussion[]>;
|
|
23
|
-
/** Called when a polling error occurs */
|
|
24
|
-
onError: (error: Error, context: string) => void;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
interface PollingTimers {
|
|
28
|
-
messages: ReturnType<typeof setInterval> | null;
|
|
29
|
-
announcements: ReturnType<typeof setInterval> | null;
|
|
30
|
-
sessionRefresh: ReturnType<typeof setInterval> | null;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
34
|
-
// Polling Manager Class
|
|
35
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
36
|
-
|
|
37
|
-
export class SdkPolling {
|
|
38
|
-
private timers: PollingTimers = {
|
|
39
|
-
messages: null,
|
|
40
|
-
announcements: null,
|
|
41
|
-
sessionRefresh: null,
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
private callbacks: PollingCallbacks | null = null;
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Start polling with the given configuration and callbacks.
|
|
48
|
-
*/
|
|
49
|
-
start(config: SdkConfig, callbacks: PollingCallbacks): void {
|
|
50
|
-
// Stop any existing timers first
|
|
51
|
-
this.stop();
|
|
52
|
-
|
|
53
|
-
this.callbacks = callbacks;
|
|
54
|
-
|
|
55
|
-
console.log('[SdkPolling] Starting polling', {
|
|
56
|
-
messagesIntervalMs: config.polling.messagesIntervalMs,
|
|
57
|
-
announcementsIntervalMs: config.polling.announcementsIntervalMs,
|
|
58
|
-
sessionRefreshIntervalMs: config.polling.sessionRefreshIntervalMs,
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
// Start message polling
|
|
62
|
-
this.timers.messages = setInterval(async () => {
|
|
63
|
-
try {
|
|
64
|
-
await this.callbacks?.fetchMessages();
|
|
65
|
-
} catch (error) {
|
|
66
|
-
console.error('[SdkPolling] Message polling error:', error);
|
|
67
|
-
this.callbacks?.onError(
|
|
68
|
-
error instanceof Error ? error : new Error(String(error)),
|
|
69
|
-
'message_polling'
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
}, config.polling.messagesIntervalMs);
|
|
73
|
-
|
|
74
|
-
// Start announcement polling
|
|
75
|
-
this.timers.announcements = setInterval(async () => {
|
|
76
|
-
try {
|
|
77
|
-
await this.callbacks?.fetchAnnouncements();
|
|
78
|
-
} catch (error) {
|
|
79
|
-
console.error('[SdkPolling] Announcement polling error:', error);
|
|
80
|
-
this.callbacks?.onError(
|
|
81
|
-
error instanceof Error ? error : new Error(String(error)),
|
|
82
|
-
'announcement_polling'
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
}, config.polling.announcementsIntervalMs);
|
|
86
|
-
|
|
87
|
-
// Start session refresh polling
|
|
88
|
-
this.timers.sessionRefresh = setInterval(async () => {
|
|
89
|
-
try {
|
|
90
|
-
const discussions = await this.callbacks?.getActiveDiscussions();
|
|
91
|
-
if (discussions && discussions.length > 0) {
|
|
92
|
-
await this.callbacks?.handleSessionRefresh(discussions);
|
|
93
|
-
}
|
|
94
|
-
} catch (error) {
|
|
95
|
-
console.error('[SdkPolling] Session refresh polling error:', error);
|
|
96
|
-
this.callbacks?.onError(
|
|
97
|
-
error instanceof Error ? error : new Error(String(error)),
|
|
98
|
-
'session_refresh_polling'
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
}, config.polling.sessionRefreshIntervalMs);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Stop all polling timers.
|
|
106
|
-
*/
|
|
107
|
-
stop(): void {
|
|
108
|
-
if (this.timers.messages) {
|
|
109
|
-
clearInterval(this.timers.messages);
|
|
110
|
-
this.timers.messages = null;
|
|
111
|
-
}
|
|
112
|
-
if (this.timers.announcements) {
|
|
113
|
-
clearInterval(this.timers.announcements);
|
|
114
|
-
this.timers.announcements = null;
|
|
115
|
-
}
|
|
116
|
-
if (this.timers.sessionRefresh) {
|
|
117
|
-
clearInterval(this.timers.sessionRefresh);
|
|
118
|
-
this.timers.sessionRefresh = null;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
this.callbacks = null;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Check if polling is currently running.
|
|
126
|
-
*/
|
|
127
|
-
isRunning(): boolean {
|
|
128
|
-
return (
|
|
129
|
-
this.timers.messages !== null ||
|
|
130
|
-
this.timers.announcements !== null ||
|
|
131
|
-
this.timers.sessionRefresh !== null
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
}
|
package/src/crypto/bip39.ts
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* BIP39 utilities for mnemonic generation, validation, and seed derivation
|
|
3
|
-
* Using @scure/bip39 for browser compatibility
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
generateMnemonic as generateMnemonicScure,
|
|
8
|
-
mnemonicToSeedSync,
|
|
9
|
-
validateMnemonic as validateMnemonicScure,
|
|
10
|
-
} from '@scure/bip39';
|
|
11
|
-
import { wordlist } from '@scure/bip39/wordlists/english.js';
|
|
12
|
-
import { Account, PrivateKey } from '@massalabs/massa-web3';
|
|
13
|
-
import varint from 'varint';
|
|
14
|
-
|
|
15
|
-
export const PRIVATE_KEY_VERSION = 0;
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Generate a new BIP39 mnemonic phrase
|
|
19
|
-
* @param strength - Entropy strength in bits (128, 160, 192, 224, 256)
|
|
20
|
-
* @returns Generated mnemonic phrase
|
|
21
|
-
*/
|
|
22
|
-
export function generateMnemonic(strength = 256): string {
|
|
23
|
-
// @scure/bip39 generateMnemonic expects strength in bits (128, 160, 192, 224, 256)
|
|
24
|
-
return generateMnemonicScure(wordlist, strength);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Validate a BIP39 mnemonic phrase
|
|
29
|
-
* @param mnemonic - The mnemonic phrase to validate
|
|
30
|
-
* @returns True if valid, false otherwise
|
|
31
|
-
*/
|
|
32
|
-
export function validateMnemonic(mnemonic: string): boolean {
|
|
33
|
-
return validateMnemonicScure(mnemonic, wordlist);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Generate a seed from mnemonic and optional passphrase
|
|
38
|
-
* @param mnemonic - The BIP39 mnemonic phrase
|
|
39
|
-
* @param passphrase - Optional passphrase (empty string if not provided)
|
|
40
|
-
* @returns Uint8Array seed
|
|
41
|
-
*/
|
|
42
|
-
export function mnemonicToSeed(
|
|
43
|
-
mnemonic: string,
|
|
44
|
-
passphrase: string = ''
|
|
45
|
-
): Uint8Array {
|
|
46
|
-
return mnemonicToSeedSync(mnemonic, passphrase);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Create a Massa blockchain account from a mnemonic phrase
|
|
51
|
-
*
|
|
52
|
-
* @param mnemonic - The BIP39 mnemonic phrase
|
|
53
|
-
* @param passphrase - Optional passphrase for additional security
|
|
54
|
-
* @returns Massa Account object
|
|
55
|
-
* @throws Error if mnemonic is invalid
|
|
56
|
-
*/
|
|
57
|
-
export async function accountFromMnemonic(
|
|
58
|
-
mnemonic: string,
|
|
59
|
-
passphrase?: string
|
|
60
|
-
): Promise<Account> {
|
|
61
|
-
try {
|
|
62
|
-
if (!validateMnemonic(mnemonic)) {
|
|
63
|
-
throw new Error('Invalid mnemonic phrase');
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const seed = mnemonicToSeed(mnemonic, passphrase);
|
|
67
|
-
|
|
68
|
-
const versionArray = varint.encode(PRIVATE_KEY_VERSION);
|
|
69
|
-
|
|
70
|
-
const privateKeyBytes = seed.slice(0, 32);
|
|
71
|
-
const privateKey = new Uint8Array([...versionArray, ...privateKeyBytes]);
|
|
72
|
-
|
|
73
|
-
const pkey = PrivateKey.fromBytes(privateKey);
|
|
74
|
-
const account = await Account.fromPrivateKey(pkey);
|
|
75
|
-
return account;
|
|
76
|
-
} catch (error) {
|
|
77
|
-
console.error('Error in accountFromMnemonic:', error);
|
|
78
|
-
console.error(
|
|
79
|
-
'Error stack:',
|
|
80
|
-
error instanceof Error ? error.stack : 'No stack'
|
|
81
|
-
);
|
|
82
|
-
throw error;
|
|
83
|
-
}
|
|
84
|
-
}
|
package/src/crypto/encryption.ts
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* High-level encryption utilities
|
|
3
|
-
*
|
|
4
|
-
* Provides convenient wrappers for encrypting and decrypting strings
|
|
5
|
-
* using the WASM encryption primitives.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
decryptAead,
|
|
10
|
-
encryptAead,
|
|
11
|
-
EncryptionKey,
|
|
12
|
-
generateNonce,
|
|
13
|
-
Nonce,
|
|
14
|
-
} from '../wasm/encryption';
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Encrypt a plaintext string using AES-256-SIV
|
|
18
|
-
*
|
|
19
|
-
* @param plaintext - The string to encrypt
|
|
20
|
-
* @param key - The encryption key (64 bytes)
|
|
21
|
-
* @param salt - Optional salt/nonce bytes (will generate random if not provided)
|
|
22
|
-
* @returns Object containing encrypted data and nonce bytes
|
|
23
|
-
*/
|
|
24
|
-
export async function encrypt(
|
|
25
|
-
plaintext: string,
|
|
26
|
-
key: EncryptionKey,
|
|
27
|
-
salt?: Uint8Array
|
|
28
|
-
): Promise<{ encryptedData: Uint8Array; nonce: Uint8Array }> {
|
|
29
|
-
const nonce = salt ? Nonce.from_bytes(salt) : await generateNonce();
|
|
30
|
-
const encryptedData = await encryptAead(
|
|
31
|
-
key,
|
|
32
|
-
nonce,
|
|
33
|
-
new TextEncoder().encode(plaintext),
|
|
34
|
-
new Uint8Array()
|
|
35
|
-
);
|
|
36
|
-
return { encryptedData, nonce: nonce.to_bytes() };
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Decrypt encrypted data back to a string
|
|
41
|
-
*
|
|
42
|
-
* @param encryptedData - The encrypted data bytes
|
|
43
|
-
* @param salt - The nonce/salt used during encryption
|
|
44
|
-
* @param key - The encryption key (must match encryption key)
|
|
45
|
-
* @returns The decrypted plaintext string
|
|
46
|
-
* @throws Error if decryption fails (wrong key, corrupted data, etc.)
|
|
47
|
-
*/
|
|
48
|
-
export async function decrypt(
|
|
49
|
-
encryptedData: Uint8Array,
|
|
50
|
-
salt: Uint8Array,
|
|
51
|
-
key: EncryptionKey
|
|
52
|
-
): Promise<string> {
|
|
53
|
-
const plain = await decryptAead(
|
|
54
|
-
key,
|
|
55
|
-
Nonce.from_bytes(salt),
|
|
56
|
-
encryptedData,
|
|
57
|
-
new Uint8Array()
|
|
58
|
-
);
|
|
59
|
-
if (!plain) {
|
|
60
|
-
throw new Error('Failed to decrypt data');
|
|
61
|
-
}
|
|
62
|
-
return new TextDecoder().decode(plain);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Derive an encryption key from a seed string and nonce
|
|
67
|
-
*
|
|
68
|
-
* @param seedString - The seed string (e.g., password)
|
|
69
|
-
* @param nonce - The nonce/salt for key derivation
|
|
70
|
-
* @returns The derived encryption key
|
|
71
|
-
*/
|
|
72
|
-
export async function deriveKey(
|
|
73
|
-
seedString: string,
|
|
74
|
-
nonce: Uint8Array
|
|
75
|
-
): Promise<EncryptionKey> {
|
|
76
|
-
return await EncryptionKey.from_seed(seedString, nonce);
|
|
77
|
-
}
|