@msssystems/mss-link-sdk 0.1.11 → 0.2.1

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 (73) hide show
  1. package/dist/client/browser-client.d.ts +16 -0
  2. package/dist/client/browser-client.js +35 -0
  3. package/dist/client/index.d.ts +3 -20
  4. package/dist/client/index.js +3 -20
  5. package/dist/client/mss-link-client.d.ts +12 -0
  6. package/dist/client/mss-link-client.js +17 -0
  7. package/dist/client/wasm-client.types.d.ts +1 -1
  8. package/dist/contracts/chat.contract.d.ts +189 -0
  9. package/dist/contracts/user-search.contract.d.ts +9 -0
  10. package/dist/core/http-client.d.ts +24 -0
  11. package/dist/core/http-client.js +80 -0
  12. package/dist/{client → core}/local-crypto-health.contracts.d.ts +1 -1
  13. package/dist/{client → core}/local-crypto-health.js +1 -1
  14. package/dist/core/wasm-crypto-engine.d.ts +34 -0
  15. package/dist/core/wasm-crypto-engine.js +75 -0
  16. package/dist/errors/api-error.d.ts +6 -0
  17. package/dist/errors/api-error.js +11 -0
  18. package/dist/errors/sdk-error.d.ts +3 -0
  19. package/dist/errors/sdk-error.js +6 -0
  20. package/dist/modules/chats/chats.client.d.ts +11 -0
  21. package/dist/modules/chats/chats.client.js +25 -0
  22. package/dist/modules/media/media-crypto.client.d.ts +10 -0
  23. package/dist/modules/media/media-crypto.client.js +90 -0
  24. package/dist/{client → modules/messages}/message-decryption-state.js +1 -1
  25. package/dist/{client → modules/messages}/message-decryption.contracts.d.ts +1 -1
  26. package/dist/modules/messages/messages-crypto.client.d.ts +14 -0
  27. package/dist/modules/messages/messages-crypto.client.js +34 -0
  28. package/dist/modules/messages/messages.client.d.ts +8 -0
  29. package/dist/modules/messages/messages.client.js +24 -0
  30. package/dist/{client → modules/storage}/drive-file-runtime.contracts.d.ts +2 -2
  31. package/dist/{client → modules/storage}/drive-file-runtime.d.ts +1 -1
  32. package/dist/{client → modules/storage}/drive-key-wrapping.contracts.d.ts +12 -0
  33. package/dist/modules/storage/drive-key-wrapping.d.ts +3 -0
  34. package/dist/{client → modules/storage}/drive-key-wrapping.js +30 -0
  35. package/dist/modules/storage/drive-sharing.contracts.js +1 -0
  36. package/dist/modules/storage/storage-crypto.client.d.ts +13 -0
  37. package/dist/modules/storage/storage-crypto.client.js +73 -0
  38. package/dist/modules/storage/storage-metadata-crypto.contracts.js +1 -0
  39. package/package.json +1 -1
  40. package/dist/client/drive-key-wrapping.d.ts +0 -2
  41. package/dist/client/mss-link-browser-client.d.ts +0 -45
  42. package/dist/client/mss-link-browser-client.js +0 -256
  43. /package/dist/{client/drive-file-runtime.contracts.js → contracts/chat.contract.js} +0 -0
  44. /package/dist/{client/drive-key-wrapping.contracts.js → contracts/user-search.contract.js} +0 -0
  45. /package/dist/{client → core}/api-base-url.d.ts +0 -0
  46. /package/dist/{client → core}/api-base-url.js +0 -0
  47. /package/dist/{client → core}/local-crypto-health.contracts.js +0 -0
  48. /package/dist/{client → core}/local-crypto-health.d.ts +0 -0
  49. /package/dist/{client → core}/wasm-call-queue.d.ts +0 -0
  50. /package/dist/{client → core}/wasm-call-queue.js +0 -0
  51. /package/dist/{client → errors}/decryption-errors.d.ts +0 -0
  52. /package/dist/{client → errors}/decryption-errors.js +0 -0
  53. /package/dist/{client → modules/media}/media-crypto.contracts.d.ts +0 -0
  54. /package/dist/{client → modules/media}/media-crypto.contracts.js +0 -0
  55. /package/dist/{client → modules/media}/media-message-metadata.d.ts +0 -0
  56. /package/dist/{client → modules/media}/media-message-metadata.js +0 -0
  57. /package/dist/{client → modules/media}/media-message.contracts.d.ts +0 -0
  58. /package/dist/{client → modules/media}/media-message.contracts.js +0 -0
  59. /package/dist/{client → modules/messages}/message-decryption-state.d.ts +0 -0
  60. /package/dist/{client → modules/messages}/message-decryption.contracts.js +0 -0
  61. /package/dist/{client → modules/messages}/message.contracts.d.ts +0 -0
  62. /package/dist/{client → modules/messages}/message.contracts.js +0 -0
  63. /package/dist/{client → modules/messages}/message.mapper.d.ts +0 -0
  64. /package/dist/{client → modules/messages}/message.mapper.js +0 -0
  65. /package/dist/{client/drive-sharing.contracts.js → modules/storage/drive-file-runtime.contracts.js} +0 -0
  66. /package/dist/{client → modules/storage}/drive-file-runtime.js +0 -0
  67. /package/dist/{client/storage-metadata-crypto.contracts.js → modules/storage/drive-key-wrapping.contracts.js} +0 -0
  68. /package/dist/{client → modules/storage}/drive-sharing.contracts.d.ts +0 -0
  69. /package/dist/{client → modules/storage}/drive-sharing.d.ts +0 -0
  70. /package/dist/{client → modules/storage}/drive-sharing.js +0 -0
  71. /package/dist/{client → modules/storage}/storage-metadata-crypto.contracts.d.ts +0 -0
  72. /package/dist/{client → modules/storage}/storage-metadata-crypto.d.ts +0 -0
  73. /package/dist/{client → modules/storage}/storage-metadata-crypto.js +0 -0
@@ -0,0 +1,16 @@
1
+ import { MssLinkClient, MssLinkClientOptions } from './mss-link-client';
2
+ import { WasmCryptoEngine, WasmCryptoEngineOptions } from '../core/wasm-crypto-engine';
3
+ import { MessagesCryptoClient } from '../modules/messages/messages-crypto.client';
4
+ import { StorageCryptoClient } from '../modules/storage/storage-crypto.client';
5
+ import { MediaCryptoClient } from '../modules/media/media-crypto.client';
6
+ export interface BrowserClientOptions extends MssLinkClientOptions, Omit<WasmCryptoEngineOptions, 'apiBaseUrl' | 'accessToken'> {
7
+ }
8
+ export declare class BrowserMssLinkClient extends MssLinkClient {
9
+ readonly cryptoEngine: WasmCryptoEngine;
10
+ readonly messagesCrypto: MessagesCryptoClient;
11
+ readonly storageCrypto: StorageCryptoClient;
12
+ readonly mediaCrypto: MediaCryptoClient;
13
+ constructor(options: BrowserClientOptions);
14
+ setToken(token: string): Promise<void>;
15
+ }
16
+ export declare function createBrowserClient(options: BrowserClientOptions): BrowserMssLinkClient;
@@ -0,0 +1,35 @@
1
+ import { MssLinkClient } from './mss-link-client';
2
+ import { WasmCryptoEngine } from '../core/wasm-crypto-engine';
3
+ import { MessagesCryptoClient } from '../modules/messages/messages-crypto.client';
4
+ import { StorageCryptoClient } from '../modules/storage/storage-crypto.client';
5
+ import { MediaCryptoClient } from '../modules/media/media-crypto.client';
6
+ export class BrowserMssLinkClient extends MssLinkClient {
7
+ cryptoEngine;
8
+ messagesCrypto;
9
+ storageCrypto;
10
+ mediaCrypto;
11
+ constructor(options) {
12
+ super(options);
13
+ this.cryptoEngine = new WasmCryptoEngine({
14
+ userId: options.userId,
15
+ apiBaseUrl: options.baseUrl,
16
+ accessToken: typeof options.token === 'string' ? options.token : undefined,
17
+ deviceId: options.deviceId,
18
+ registrationId: options.registrationId,
19
+ signedPrekeyId: options.signedPrekeyId,
20
+ initialOneTimePrekeyCount: options.initialOneTimePrekeyCount,
21
+ minOneTimePrekeys: options.minOneTimePrekeys,
22
+ replenishOneTimePrekeys: options.replenishOneTimePrekeys,
23
+ });
24
+ this.messagesCrypto = new MessagesCryptoClient(this.cryptoEngine);
25
+ this.storageCrypto = new StorageCryptoClient(this.cryptoEngine);
26
+ this.mediaCrypto = new MediaCryptoClient(this.cryptoEngine);
27
+ }
28
+ async setToken(token) {
29
+ await super.setToken(token);
30
+ this.cryptoEngine.setAccessToken(token);
31
+ }
32
+ }
33
+ export function createBrowserClient(options) {
34
+ return new BrowserMssLinkClient(options);
35
+ }
@@ -1,21 +1,4 @@
1
- export * from './api-base-url';
2
1
  export * from './client-options';
3
- export * from './decryption-errors';
4
- export * from './drive-file-runtime';
5
- export * from './drive-file-runtime.contracts';
6
- export * from './drive-key-wrapping';
7
- export * from './drive-key-wrapping.contracts';
8
- export * from './drive-sharing';
9
- export * from './drive-sharing.contracts';
10
- export * from './local-crypto-health';
11
- export * from './local-crypto-health.contracts';
12
- export * from './media-crypto.contracts';
13
- export * from './media-message.contracts';
14
- export * from './media-message-metadata';
15
- export * from './message.contracts';
16
- export * from './message-decryption.contracts';
17
- export * from './message-decryption-state';
18
- export * from './message.mapper';
19
- export * from './mss-link-browser-client';
20
- export * from './storage-metadata-crypto';
21
- export * from './storage-metadata-crypto.contracts';
2
+ export * from './mss-link-client';
3
+ export * from './browser-client';
4
+ export * from './wasm-client.types';
@@ -1,21 +1,4 @@
1
- export * from './api-base-url';
2
1
  export * from './client-options';
3
- export * from './decryption-errors';
4
- export * from './drive-file-runtime';
5
- export * from './drive-file-runtime.contracts';
6
- export * from './drive-key-wrapping';
7
- export * from './drive-key-wrapping.contracts';
8
- export * from './drive-sharing';
9
- export * from './drive-sharing.contracts';
10
- export * from './local-crypto-health';
11
- export * from './local-crypto-health.contracts';
12
- export * from './media-crypto.contracts';
13
- export * from './media-message.contracts';
14
- export * from './media-message-metadata';
15
- export * from './message.contracts';
16
- export * from './message-decryption.contracts';
17
- export * from './message-decryption-state';
18
- export * from './message.mapper';
19
- export * from './mss-link-browser-client';
20
- export * from './storage-metadata-crypto';
21
- export * from './storage-metadata-crypto.contracts';
2
+ export * from './mss-link-client';
3
+ export * from './browser-client';
4
+ export * from './wasm-client.types';
@@ -0,0 +1,12 @@
1
+ import { HttpClient, HttpClientOptions } from '../core/http-client';
2
+ import { ChatsClient } from '../modules/chats/chats.client';
3
+ import { MessagesClient } from '../modules/messages/messages.client';
4
+ export interface MssLinkClientOptions extends HttpClientOptions {
5
+ }
6
+ export declare class MssLinkClient {
7
+ readonly http: HttpClient;
8
+ readonly chats: ChatsClient;
9
+ readonly messages: MessagesClient;
10
+ constructor(options: MssLinkClientOptions);
11
+ setToken(token: string): Promise<void>;
12
+ }
@@ -0,0 +1,17 @@
1
+ import { HttpClient } from '../core/http-client';
2
+ import { ChatsClient } from '../modules/chats/chats.client';
3
+ import { MessagesClient } from '../modules/messages/messages.client';
4
+ export class MssLinkClient {
5
+ http;
6
+ chats;
7
+ messages;
8
+ constructor(options) {
9
+ this.http = new HttpClient(options);
10
+ // Initialize all modules
11
+ this.chats = new ChatsClient(this.http);
12
+ this.messages = new MessagesClient(this.http);
13
+ }
14
+ async setToken(token) {
15
+ await this.http.setToken(token);
16
+ }
17
+ }
@@ -1,5 +1,5 @@
1
1
  import type { WasmMssClient } from '@msssystems/mss-crypto-wasm';
2
- import type { WasmEncryptedMediaBytes } from './media-crypto.contracts';
2
+ import type { WasmEncryptedMediaBytes } from '../modules/media/media-crypto.contracts';
3
3
  export interface MssLinkWasmClient extends WasmMssClient {
4
4
  sendMediaMessage(chatId: string, targetUserId: string, metadataJson: string, mediaAssetIds: string[]): Promise<string>;
5
5
  }
@@ -0,0 +1,189 @@
1
+ import type { MediaMessageAttachmentInput, MediaMessageAttachmentMetadata } from '../modules/media/media-message.contracts';
2
+ import type { DecryptedMessage } from '../modules/messages/message.contracts';
3
+ export type MessageStatus = 'SENT' | 'DELIVERED' | 'READ';
4
+ export interface MessageReceiptSummary {
5
+ total: number;
6
+ sent: number;
7
+ delivered: number;
8
+ read: number;
9
+ }
10
+ export interface MessageMediaAttachment {
11
+ id: string;
12
+ assetId: string;
13
+ mimeType: string;
14
+ size: string;
15
+ status: 'ATTACHED';
16
+ uploadedAt: string;
17
+ }
18
+ export interface ChatMember {
19
+ id: string;
20
+ role: 'MEMBER' | 'ADMIN';
21
+ archivedAt?: string | null;
22
+ hiddenAt?: string | null;
23
+ lastReadAt?: string | null;
24
+ user: {
25
+ id: string;
26
+ username: string;
27
+ displayName: string;
28
+ avatarUrl?: string | null;
29
+ };
30
+ }
31
+ export interface Chat {
32
+ id: string;
33
+ type: 'DIRECT' | 'GROUP';
34
+ name?: string | null;
35
+ avatarUrl?: string | null;
36
+ members: ChatMember[];
37
+ messages?: Array<{
38
+ id: string;
39
+ ciphertext: string;
40
+ senderId: string;
41
+ createdAt: string;
42
+ }>;
43
+ myArchivedAt?: string | null;
44
+ myHiddenAt?: string | null;
45
+ myLastReadAt?: string | null;
46
+ createdAt: string;
47
+ updatedAt: string;
48
+ }
49
+ export interface Message {
50
+ id: string;
51
+ type: string;
52
+ status: MessageStatus;
53
+ myReceiptStatus?: MessageStatus | null;
54
+ receiptSummary: MessageReceiptSummary;
55
+ clientMessageId?: string | null;
56
+ ciphertext: string;
57
+ chatId: string;
58
+ senderId: string;
59
+ sender: {
60
+ id: string;
61
+ displayName: string;
62
+ avatarUrl?: string | null;
63
+ };
64
+ media: MessageMediaAttachment[];
65
+ createdAt: string;
66
+ updatedAt: string;
67
+ }
68
+ export interface CreateMediaUploadInput {
69
+ originalName: string;
70
+ mimeType: string;
71
+ size: number;
72
+ }
73
+ export interface MediaUploadInitResponse {
74
+ assetId: string;
75
+ uploadUrl: string;
76
+ metadata: Record<string, string>;
77
+ }
78
+ export interface MediaAssetUrlResponse {
79
+ assetId: string;
80
+ url: string;
81
+ }
82
+ export interface MediaAssetBlobResponse {
83
+ blob: Blob;
84
+ fileName: string;
85
+ }
86
+ export interface MessagesResponse {
87
+ messages: Message[];
88
+ nextCursor?: string | null;
89
+ }
90
+ export interface SyncCheckpoint {
91
+ lastAckedSequence: string;
92
+ acknowledgedAt: string;
93
+ }
94
+ export interface AckSyncInput {
95
+ sequence: string;
96
+ }
97
+ export interface MarkMessagesStatusInput {
98
+ chatId: string;
99
+ throughMessageId?: string;
100
+ limit?: number;
101
+ }
102
+ export type SyncEventType = 'MESSAGE_NEW' | 'MESSAGE_STATUS_UPDATED';
103
+ export interface SyncEvent {
104
+ sequence: string;
105
+ type: SyncEventType;
106
+ chatId: string;
107
+ messageId?: string | null;
108
+ messageStatus?: MessageStatus | null;
109
+ message?: Message | null;
110
+ createdAt: string;
111
+ }
112
+ export interface SyncEventsResponse {
113
+ events: SyncEvent[];
114
+ nextCursor?: string | null;
115
+ }
116
+ export interface SyncEventsInput {
117
+ cursor?: string | null;
118
+ limit?: number;
119
+ }
120
+ export interface SyncClientInput {
121
+ profileId: string;
122
+ accessToken: string;
123
+ }
124
+ export interface ChatMessagesPageInput {
125
+ chatId: string;
126
+ before?: string;
127
+ after?: string;
128
+ limit?: number;
129
+ }
130
+ export interface CreateDirectChatInput {
131
+ targetUserId: string;
132
+ }
133
+ export interface CreateGroupChatInput {
134
+ name: string;
135
+ memberUserIds: string[];
136
+ }
137
+ export interface DecryptedMessagesInput {
138
+ profileId: string;
139
+ accessToken: string;
140
+ chatId: string;
141
+ }
142
+ export interface SendEncryptedMessageInput {
143
+ profileId: string;
144
+ accessToken: string;
145
+ chatId: string;
146
+ targetUserId: string;
147
+ text: string;
148
+ }
149
+ export interface SendMediaMessageInput {
150
+ profileId: string;
151
+ accessToken: string;
152
+ chatId: string;
153
+ targetUserId: string;
154
+ attachments: MediaMessageAttachmentInput[];
155
+ caption?: string;
156
+ }
157
+ export interface EncryptMediaAssetInput {
158
+ profileId: string;
159
+ accessToken: string;
160
+ assetId: string;
161
+ file: Blob;
162
+ mimeType: string;
163
+ size: string | number;
164
+ originalName?: string;
165
+ uploadedAt?: string;
166
+ }
167
+ export interface DecryptMediaAssetInput {
168
+ profileId: string;
169
+ accessToken: string;
170
+ encryptedBlob: Blob;
171
+ metadata: MediaMessageAttachmentMetadata;
172
+ }
173
+ export interface UploadAndSendMediaMessageInput {
174
+ profileId: string;
175
+ accessToken: string;
176
+ chatId: string;
177
+ targetUserId: string;
178
+ file: File;
179
+ caption?: string;
180
+ onLifecycleChange?: (event: MediaUploadLifecycleEvent) => void;
181
+ }
182
+ export type MediaUploadLifecycleStatus = 'uploading' | 'uploaded' | 'attached' | 'failed';
183
+ export interface MediaUploadLifecycleEvent {
184
+ status: MediaUploadLifecycleStatus;
185
+ assetId?: string;
186
+ errorMessage?: string;
187
+ }
188
+ export type { DecryptedMessage };
189
+ export type { MediaMessageAttachmentMetadata };
@@ -0,0 +1,9 @@
1
+ export interface SearchUserResult {
2
+ id: string;
3
+ username: string;
4
+ displayName: string;
5
+ avatarUrl: string | null;
6
+ }
7
+ export interface SearchUsersResponse {
8
+ users: SearchUserResult[];
9
+ }
@@ -0,0 +1,24 @@
1
+ export interface HttpClientOptions {
2
+ baseUrl: string;
3
+ token?: string | (() => string | Promise<string>);
4
+ fetch?: typeof fetch;
5
+ }
6
+ export declare class HttpClient {
7
+ private baseUrl;
8
+ private token?;
9
+ private customFetch;
10
+ constructor(options: HttpClientOptions);
11
+ setToken(token: string): Promise<void>;
12
+ private getHeaders;
13
+ request<T>(method: string, path: string, options?: {
14
+ body?: any;
15
+ params?: Record<string, any>;
16
+ headers?: Record<string, string>;
17
+ responseType?: 'json' | 'blob';
18
+ }): Promise<T>;
19
+ get<T>(path: string, options?: Omit<Parameters<typeof this.request>[2], 'body'>): Promise<T>;
20
+ post<T>(path: string, body?: any, options?: Omit<Parameters<typeof this.request>[2], 'body'>): Promise<T>;
21
+ put<T>(path: string, body?: any, options?: Omit<Parameters<typeof this.request>[2], 'body'>): Promise<T>;
22
+ patch<T>(path: string, body?: any, options?: Omit<Parameters<typeof this.request>[2], 'body'>): Promise<T>;
23
+ delete<T>(path: string, options?: Omit<Parameters<typeof this.request>[2], 'body'>): Promise<T>;
24
+ }
@@ -0,0 +1,80 @@
1
+ import { ApiError } from '../errors/api-error';
2
+ export class HttpClient {
3
+ baseUrl;
4
+ token;
5
+ customFetch;
6
+ constructor(options) {
7
+ this.baseUrl = options.baseUrl.replace(/\/$/, '');
8
+ this.token = options.token;
9
+ // Fallback to global fetch if not provided
10
+ this.customFetch = options.fetch ?? (typeof globalThis !== 'undefined' ? globalThis.fetch.bind(globalThis) : fetch);
11
+ }
12
+ async setToken(token) {
13
+ this.token = token;
14
+ }
15
+ async getHeaders(customHeaders) {
16
+ const headers = {
17
+ 'Content-Type': 'application/json',
18
+ ...customHeaders,
19
+ };
20
+ if (this.token) {
21
+ const tokenStr = typeof this.token === 'function' ? await this.token() : this.token;
22
+ if (tokenStr) {
23
+ headers['Authorization'] = `Bearer ${tokenStr}`;
24
+ }
25
+ }
26
+ return headers;
27
+ }
28
+ async request(method, path, options = {}) {
29
+ const url = new URL(`${this.baseUrl}${path}`);
30
+ if (options.params) {
31
+ for (const [key, value] of Object.entries(options.params)) {
32
+ if (value !== undefined && value !== null) {
33
+ url.searchParams.append(key, String(value));
34
+ }
35
+ }
36
+ }
37
+ const headers = await this.getHeaders(options.headers);
38
+ const fetchOptions = {
39
+ method,
40
+ headers,
41
+ };
42
+ if (options.body) {
43
+ fetchOptions.body = JSON.stringify(options.body);
44
+ }
45
+ const response = await this.customFetch(url.toString(), fetchOptions);
46
+ if (!response.ok) {
47
+ let errorPayload;
48
+ try {
49
+ errorPayload = await response.json();
50
+ }
51
+ catch {
52
+ errorPayload = { message: response.statusText };
53
+ }
54
+ throw new ApiError(response.status, errorPayload.message || 'API request failed', errorPayload);
55
+ }
56
+ if (options.responseType === 'blob') {
57
+ return response.blob();
58
+ }
59
+ // Handle empty responses
60
+ if (response.status === 204 || response.headers.get('content-length') === '0') {
61
+ return null;
62
+ }
63
+ return response.json();
64
+ }
65
+ get(path, options) {
66
+ return this.request('GET', path, options);
67
+ }
68
+ post(path, body, options) {
69
+ return this.request('POST', path, { ...options, body });
70
+ }
71
+ put(path, body, options) {
72
+ return this.request('PUT', path, { ...options, body });
73
+ }
74
+ patch(path, body, options) {
75
+ return this.request('PATCH', path, { ...options, body });
76
+ }
77
+ delete(path, options) {
78
+ return this.request('DELETE', path, options);
79
+ }
80
+ }
@@ -1,4 +1,4 @@
1
- import type { LocalCryptoErrorCode } from './decryption-errors';
1
+ import type { LocalCryptoErrorCode } from '../errors/decryption-errors';
2
2
  export type LocalCryptoHealthStatus = 'ready' | 'recovery_required' | 'corrupt' | 'unavailable';
3
3
  export type LocalCryptoHealthErrorCode = LocalCryptoErrorCode;
4
4
  export interface LocalCryptoHealth {
@@ -1,4 +1,4 @@
1
- import { normalizeLocalCryptoError } from './decryption-errors';
1
+ import { normalizeLocalCryptoError } from '../errors/decryption-errors';
2
2
  export async function checkLocalCryptoHealth(checkReady) {
3
3
  try {
4
4
  await checkReady();
@@ -0,0 +1,34 @@
1
+ import { WasmCallQueue } from './wasm-call-queue';
2
+ import type { MssCryptoWasmModule, WasmMssClientInstance } from '../client/wasm-client.types';
3
+ export interface WasmCryptoEngineOptions {
4
+ userId: string;
5
+ apiBaseUrl: string;
6
+ accessToken?: string | undefined;
7
+ deviceId?: number | undefined;
8
+ registrationId?: number | undefined;
9
+ signedPrekeyId?: number | undefined;
10
+ initialOneTimePrekeyCount?: number | undefined;
11
+ minOneTimePrekeys?: number | undefined;
12
+ replenishOneTimePrekeys?: number | undefined;
13
+ }
14
+ export declare class WasmCryptoEngine {
15
+ private readonly userId;
16
+ private readonly apiBaseUrl;
17
+ private readonly deviceId;
18
+ private readonly registrationId;
19
+ private readonly signedPrekeyId;
20
+ private readonly initialOneTimePrekeyCount;
21
+ private readonly minOneTimePrekeys;
22
+ private readonly replenishOneTimePrekeys;
23
+ readonly queue: WasmCallQueue;
24
+ private wasmClient;
25
+ private wasmModulePromise;
26
+ private accessToken;
27
+ constructor(options: WasmCryptoEngineOptions);
28
+ setAccessToken(accessToken: string | null): void;
29
+ ensureReady(): Promise<void>;
30
+ reset(): void;
31
+ runWithClient<T>(callback: (client: WasmMssClientInstance) => Promise<T>): Promise<T>;
32
+ getClient(): Promise<WasmMssClientInstance>;
33
+ loadWasmModule(): Promise<MssCryptoWasmModule>;
34
+ }
@@ -0,0 +1,75 @@
1
+ import { normalizeProductApiBaseUrl } from './api-base-url';
2
+ import { normalizeLocalCryptoError } from '../errors/decryption-errors';
3
+ import { WasmCallQueue } from './wasm-call-queue';
4
+ const DEFAULT_DEVICE_ID = 1;
5
+ const DEFAULT_REGISTRATION_ID = 1;
6
+ const DEFAULT_SIGNED_PREKEY_ID = 1;
7
+ const DEFAULT_ONE_TIME_PREKEY_COUNT = 10;
8
+ const DEFAULT_MIN_ONE_TIME_PREKEYS = 5;
9
+ const DEFAULT_REPLENISH_ONE_TIME_PREKEYS = 10;
10
+ export class WasmCryptoEngine {
11
+ userId;
12
+ apiBaseUrl;
13
+ deviceId;
14
+ registrationId;
15
+ signedPrekeyId;
16
+ initialOneTimePrekeyCount;
17
+ minOneTimePrekeys;
18
+ replenishOneTimePrekeys;
19
+ queue = new WasmCallQueue();
20
+ wasmClient = null;
21
+ wasmModulePromise = null;
22
+ accessToken;
23
+ constructor(options) {
24
+ this.userId = options.userId;
25
+ this.apiBaseUrl = normalizeProductApiBaseUrl(options.apiBaseUrl);
26
+ this.accessToken = options.accessToken ?? null;
27
+ this.deviceId = options.deviceId ?? DEFAULT_DEVICE_ID;
28
+ this.registrationId = options.registrationId ?? DEFAULT_REGISTRATION_ID;
29
+ this.signedPrekeyId = options.signedPrekeyId ?? DEFAULT_SIGNED_PREKEY_ID;
30
+ this.initialOneTimePrekeyCount =
31
+ options.initialOneTimePrekeyCount ?? DEFAULT_ONE_TIME_PREKEY_COUNT;
32
+ this.minOneTimePrekeys =
33
+ options.minOneTimePrekeys ?? DEFAULT_MIN_ONE_TIME_PREKEYS;
34
+ this.replenishOneTimePrekeys =
35
+ options.replenishOneTimePrekeys ?? DEFAULT_REPLENISH_ONE_TIME_PREKEYS;
36
+ }
37
+ setAccessToken(accessToken) {
38
+ this.accessToken = accessToken;
39
+ this.wasmClient?.setAccessToken(accessToken);
40
+ }
41
+ async ensureReady() {
42
+ try {
43
+ await this.runWithClient(async (client) => {
44
+ await client.ensureDeviceRegistered(this.registrationId, this.signedPrekeyId, this.initialOneTimePrekeyCount);
45
+ await client.replenishOneTimePreKeys(this.minOneTimePrekeys, this.replenishOneTimePrekeys);
46
+ });
47
+ }
48
+ catch (error) {
49
+ throw normalizeLocalCryptoError(error);
50
+ }
51
+ }
52
+ reset() {
53
+ this.wasmClient?.free();
54
+ this.wasmClient = null;
55
+ this.wasmModulePromise = null;
56
+ }
57
+ async runWithClient(callback) {
58
+ return this.queue.run(async () => callback(await this.getClient()));
59
+ }
60
+ async getClient() {
61
+ if (typeof window === 'undefined') {
62
+ throw new Error('MSS Link browser client is available only in browser context.');
63
+ }
64
+ if (!this.wasmClient) {
65
+ const sdkModule = await this.loadWasmModule();
66
+ this.wasmClient = new sdkModule.WasmMssClient(this.userId, this.deviceId, this.apiBaseUrl);
67
+ this.wasmClient.setAccessToken(this.accessToken);
68
+ }
69
+ return this.wasmClient;
70
+ }
71
+ loadWasmModule() {
72
+ this.wasmModulePromise ??= import('@msssystems/mss-crypto-wasm').then((module) => module);
73
+ return this.wasmModulePromise;
74
+ }
75
+ }
@@ -0,0 +1,6 @@
1
+ import { SdkError } from './sdk-error';
2
+ export declare class ApiError extends SdkError {
3
+ readonly status: number;
4
+ readonly payload?: any | undefined;
5
+ constructor(status: number, message: string, payload?: any | undefined);
6
+ }
@@ -0,0 +1,11 @@
1
+ import { SdkError } from './sdk-error';
2
+ export class ApiError extends SdkError {
3
+ status;
4
+ payload;
5
+ constructor(status, message, payload) {
6
+ super(`[HTTP ${status}] ${message}`);
7
+ this.status = status;
8
+ this.payload = payload;
9
+ this.name = 'ApiError';
10
+ }
11
+ }
@@ -0,0 +1,3 @@
1
+ export declare class SdkError extends Error {
2
+ constructor(message: string);
3
+ }
@@ -0,0 +1,6 @@
1
+ export class SdkError extends Error {
2
+ constructor(message) {
3
+ super(message);
4
+ this.name = 'SdkError';
5
+ }
6
+ }
@@ -0,0 +1,11 @@
1
+ import { HttpClient } from '../../core/http-client';
2
+ export declare class ChatsClient {
3
+ private readonly http;
4
+ constructor(http: HttpClient);
5
+ list(): Promise<any[]>;
6
+ getDetails(chatId: string): Promise<any>;
7
+ createDirect(targetUserId: string): Promise<any>;
8
+ createGroup(name: string, userIds: string[]): Promise<any>;
9
+ archive(chatId: string): Promise<any>;
10
+ hide(chatId: string): Promise<any>;
11
+ }
@@ -0,0 +1,25 @@
1
+ // TODO: Import proper types from contracts
2
+ export class ChatsClient {
3
+ http;
4
+ constructor(http) {
5
+ this.http = http;
6
+ }
7
+ async list() {
8
+ return this.http.get('/link/v1/chats');
9
+ }
10
+ async getDetails(chatId) {
11
+ return this.http.get(`/link/v1/chats/${chatId}`);
12
+ }
13
+ async createDirect(targetUserId) {
14
+ return this.http.post('/link/v1/chats/direct', { targetUserId });
15
+ }
16
+ async createGroup(name, userIds) {
17
+ return this.http.post('/link/v1/chats/group', { name, userIds });
18
+ }
19
+ async archive(chatId) {
20
+ return this.http.post(`/link/v1/chats/${chatId}/archive`);
21
+ }
22
+ async hide(chatId) {
23
+ return this.http.post(`/link/v1/chats/${chatId}/hide`);
24
+ }
25
+ }
@@ -0,0 +1,10 @@
1
+ import { WasmCryptoEngine } from '../../core/wasm-crypto-engine';
2
+ import type { DecryptMediaBlobInput, DecryptedMediaBlobResult, EncryptedMediaBlobResult, EncryptMediaBlobInput } from './media-crypto.contracts';
3
+ import type { SendMediaMessageParams } from './media-message.contracts';
4
+ export declare class MediaCryptoClient {
5
+ private readonly engine;
6
+ constructor(engine: WasmCryptoEngine);
7
+ sendMediaMessage(params: SendMediaMessageParams): Promise<string>;
8
+ encryptMediaBlob(input: EncryptMediaBlobInput): Promise<EncryptedMediaBlobResult>;
9
+ decryptMediaBlob(input: DecryptMediaBlobInput): Promise<DecryptedMediaBlobResult>;
10
+ }