@morseai/sdk 0.1.0-beta.3

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.
@@ -0,0 +1,510 @@
1
+ type SignalMode = "private" | "shared_wallet";
2
+ type SignalStatus = "active" | "used" | "expired";
3
+ type OnChainNotificationStatus = "pending" | "minted" | "failed" | null;
4
+ interface OnChainNotification {
5
+ enabled: boolean;
6
+ network: string;
7
+ status: OnChainNotificationStatus;
8
+ txHash: string | null;
9
+ tokenId: string | null;
10
+ expiresAt: string | null;
11
+ }
12
+ interface SignalFile {
13
+ storagePath: string;
14
+ payloadNonce: string;
15
+ originalName: string;
16
+ mimeType: string;
17
+ sizeBytes: number;
18
+ sealedDataKey?: string | null;
19
+ sealedNonce?: string | null;
20
+ senderEphemeralPublicKey?: string | null;
21
+ aadHash?: string | null;
22
+ }
23
+ interface CreateSignalOptions {
24
+ signalId?: string;
25
+ walletTarget?: string;
26
+ shareWithRecipient: boolean;
27
+ mode: SignalMode;
28
+ hasFile: boolean;
29
+ hasMessage: boolean;
30
+ cipherVersion: string;
31
+ encryptedText?: string;
32
+ payloadNonce?: string;
33
+ sealedDataKey?: string;
34
+ sealedNonce?: string;
35
+ senderEphemeralPublicKey?: string;
36
+ aadHash?: string;
37
+ file?: {
38
+ storagePath: string;
39
+ payloadNonce: string;
40
+ originalName: string;
41
+ mimeType: string;
42
+ sizeBytes: number;
43
+ sealedDataKey?: string;
44
+ sealedNonce?: string;
45
+ senderEphemeralPublicKey?: string;
46
+ aadHash?: string;
47
+ };
48
+ onChainNotification?: {
49
+ enabled: boolean;
50
+ network: string;
51
+ };
52
+ expiresAt?: string;
53
+ expiresIn?: string;
54
+ }
55
+ interface CreateSignalOptionsEncrypted {
56
+ signalId?: string;
57
+ walletTarget?: string;
58
+ /**
59
+ * @deprecated shareWithRecipient is automatically determined by mode.
60
+ * - mode: "shared_wallet" → shareWithRecipient = true
61
+ * - mode: "private" → shareWithRecipient = false
62
+ * This field is ignored if provided.
63
+ */
64
+ shareWithRecipient?: boolean;
65
+ mode: SignalMode;
66
+ message?: string;
67
+ file?: {
68
+ data: ArrayBuffer | Uint8Array | Buffer;
69
+ originalName: string;
70
+ mimeType: string;
71
+ };
72
+ onChainNotification?: {
73
+ enabled: boolean;
74
+ network: string;
75
+ };
76
+ /**
77
+ * Specific expiration date and time (ISO 8601 format).
78
+ * Use this for custom expiration dates.
79
+ *
80
+ * Either `expiresAt` OR `expiresIn` must be provided (not both).
81
+ *
82
+ * @example "2026-12-31T23:59:59.000Z" - New Year's Eve 2026
83
+ * @example new Date("2026-12-31").toISOString() - Specific date
84
+ */
85
+ expiresAt?: string;
86
+ /**
87
+ * Expiration time from now (relative).
88
+ *
89
+ * Format: "{number}{unit}" where unit is one of: s (seconds), m (minutes), h (hours), d (days)
90
+ *
91
+ * Either `expiresAt` OR `expiresIn` must be provided (not both).
92
+ *
93
+ * @example "24h" - 24 hours from now
94
+ * @example "7d" - 7 days from now
95
+ * @example "1h" - 1 hour from now
96
+ * @example "30m" - 30 minutes from now
97
+ * @example "5s" - 5 seconds from now
98
+ */
99
+ expiresIn?: string;
100
+ }
101
+ interface CreateSignalResponse {
102
+ signalId: string;
103
+ expiresAt: string;
104
+ }
105
+ interface CreateSignalResponseEncrypted extends CreateSignalResponse {
106
+ keyBase64: string;
107
+ shareableLink: string;
108
+ }
109
+ interface OpenSignalResponse {
110
+ encryptedText: string | null;
111
+ payloadNonce: string | null;
112
+ sealedDataKey: string | null;
113
+ sealedNonce: string | null;
114
+ senderEphemeralPublicKey: string | null;
115
+ aadHash: string | null;
116
+ walletCreator: string | null;
117
+ walletTarget: string | null;
118
+ shareWithRecipient: boolean;
119
+ file: {
120
+ payloadNonce: string;
121
+ originalName: string;
122
+ mimeType: string;
123
+ sizeBytes: number;
124
+ sealedDataKey?: string | null;
125
+ sealedNonce?: string | null;
126
+ senderEphemeralPublicKey?: string | null;
127
+ aadHash?: string | null;
128
+ } | null;
129
+ expiresAt: string;
130
+ onChainNotification: OnChainNotification | null;
131
+ cipherVersion: string;
132
+ }
133
+ interface OpenSignalResponseDecrypted {
134
+ message: string | null;
135
+ file: {
136
+ data: ArrayBuffer;
137
+ originalName: string;
138
+ mimeType: string;
139
+ sizeBytes: number;
140
+ } | null;
141
+ expiresAt: string;
142
+ onChainNotification: OnChainNotification | null;
143
+ keySource: "derived" | "provided";
144
+ }
145
+ interface SignalListItem {
146
+ signalId: string;
147
+ shareWithRecipient: boolean;
148
+ hasFile: boolean;
149
+ hasMessage: boolean;
150
+ createdAt: string;
151
+ expiresAt: string;
152
+ used: boolean;
153
+ status: SignalStatus;
154
+ file: {
155
+ originalName: string;
156
+ } | null;
157
+ }
158
+ interface ListMySignalsResponse {
159
+ signals: SignalListItem[];
160
+ count: number;
161
+ }
162
+ interface UploadFileOptions {
163
+ file: string;
164
+ originalName: string;
165
+ mimeType: string;
166
+ }
167
+ interface UploadFileResponse {
168
+ storagePath: string;
169
+ sizeBytes: number;
170
+ }
171
+ interface DownloadFileResponse {
172
+ file: string;
173
+ originalName: string;
174
+ mimeType: string;
175
+ sizeBytes: number;
176
+ }
177
+ interface SignalErrorResponse {
178
+ status: "error";
179
+ code: "WALLET_NOT_ALLOWED" | "SIGNAL_EXPIRED" | "SIGNAL_ALREADY_USED" | "SIGNAL_NOT_FOUND" | "VALIDATION_ERROR";
180
+ message: string;
181
+ }
182
+ interface WalletAuth {
183
+ address: string;
184
+ signMessage: (message: string) => Promise<string>;
185
+ }
186
+ interface RateLimitConfig {
187
+ enabled?: boolean;
188
+ maxRequests?: number;
189
+ windowMs?: number;
190
+ }
191
+ interface MorseSDKConfig {
192
+ apiKey: string;
193
+ apiVersion?: string;
194
+ onRequest?: (url: string, options: RequestInit) => void;
195
+ onResponse?: (url: string, response: Response) => void;
196
+ onError?: (error: Error) => void;
197
+ timeout?: number;
198
+ retries?: number;
199
+ retryDelay?: number;
200
+ rateLimit?: RateLimitConfig;
201
+ }
202
+ interface MorseSDKConfigV1 extends MorseSDKConfig {
203
+ apiVersion?: "v1";
204
+ }
205
+
206
+ interface MorseContract {
207
+ createSignal(wallet: WalletAuth, options: CreateSignalOptions): Promise<CreateSignalResponse>;
208
+ openSignal(wallet: WalletAuth, signalId: string): Promise<OpenSignalResponse>;
209
+ listMySignals(wallet: WalletAuth): Promise<ListMySignalsResponse>;
210
+ uploadFile(wallet: WalletAuth, options: UploadFileOptions): Promise<UploadFileResponse>;
211
+ downloadFile(wallet: WalletAuth, signalId: string): Promise<DownloadFileResponse>;
212
+ burnSignal(wallet: WalletAuth, signalId: string): Promise<{
213
+ success: boolean;
214
+ }>;
215
+ }
216
+
217
+ interface MorseSDKCallbacks {
218
+ onRequest?: (url: string, options: RequestInit) => void;
219
+ onResponse?: (url: string, response: Response) => void;
220
+ onError?: (error: Error) => void;
221
+ }
222
+ declare class MorseSDK implements MorseContract {
223
+ private contract;
224
+ private apiVersion;
225
+ private config;
226
+ constructor(config: MorseSDKConfig);
227
+ getConfig(): Readonly<MorseSDKConfig>;
228
+ getApiVersion(): string;
229
+ getContract(): MorseContract;
230
+ createSignal(wallet: WalletAuth, options: CreateSignalOptions): Promise<CreateSignalResponse>;
231
+ openSignal(wallet: WalletAuth, signalId: string): Promise<OpenSignalResponse>;
232
+ listMySignals(wallet: WalletAuth): Promise<ListMySignalsResponse>;
233
+ uploadFile(wallet: WalletAuth, options: UploadFileOptions): Promise<UploadFileResponse>;
234
+ downloadFile(wallet: WalletAuth, signalId: string): Promise<DownloadFileResponse>;
235
+ burnSignal(wallet: WalletAuth, signalId: string): Promise<{
236
+ success: boolean;
237
+ }>;
238
+ createSignalEncrypted(wallet: WalletAuth, options: CreateSignalOptionsEncrypted): Promise<CreateSignalResponseEncrypted>;
239
+ openSignalDecrypted(wallet: WalletAuth, signalId: string, keyBase64?: string): Promise<OpenSignalResponseDecrypted>;
240
+ uploadFileEncrypted(wallet: WalletAuth, fileData: ArrayBuffer | Uint8Array | Buffer, originalName: string, mimeType: string, key: CryptoKey): Promise<UploadFileResponse>;
241
+ downloadFileDecrypted(wallet: WalletAuth, signalId: string, keyBase64: string): Promise<{
242
+ data: ArrayBuffer;
243
+ originalName: string;
244
+ mimeType: string;
245
+ sizeBytes: number;
246
+ }>;
247
+ }
248
+
249
+ interface MorseContractV1 extends MorseContract {
250
+ readonly version: "v1";
251
+ createSignal(wallet: WalletAuth, options: CreateSignalOptions): Promise<CreateSignalResponse>;
252
+ createSignalEncrypted(wallet: WalletAuth, options: CreateSignalOptionsEncrypted): Promise<CreateSignalResponseEncrypted>;
253
+ openSignal(wallet: WalletAuth, signalId: string): Promise<OpenSignalResponse>;
254
+ openSignalDecrypted(wallet: WalletAuth, signalId: string, keyBase64?: string): Promise<OpenSignalResponseDecrypted>;
255
+ listMySignals(wallet: WalletAuth): Promise<ListMySignalsResponse>;
256
+ uploadFile(wallet: WalletAuth, options: UploadFileOptions): Promise<UploadFileResponse>;
257
+ uploadFileEncrypted(wallet: WalletAuth, fileData: ArrayBuffer | Uint8Array | Buffer, originalName: string, mimeType: string, key: CryptoKey): Promise<UploadFileResponse>;
258
+ downloadFile(wallet: WalletAuth, signalId: string): Promise<DownloadFileResponse>;
259
+ downloadFileDecrypted(wallet: WalletAuth, signalId: string, keyBase64: string): Promise<{
260
+ data: ArrayBuffer;
261
+ originalName: string;
262
+ mimeType: string;
263
+ sizeBytes: number;
264
+ }>;
265
+ burnSignal(wallet: WalletAuth, signalId: string): Promise<{
266
+ success: boolean;
267
+ }>;
268
+ }
269
+
270
+ declare class MorseSDKV1 implements MorseContractV1 {
271
+ readonly version: "v1";
272
+ private config;
273
+ private timeout;
274
+ private retries;
275
+ private retryDelay;
276
+ private rateLimiter;
277
+ constructor(config: MorseSDKConfig);
278
+ private base64ToUint8Array;
279
+ private arrayBufferToBase64;
280
+ private sanitizeRequestOptions;
281
+ private getApiUrl;
282
+ private createAuthMessage;
283
+ private signMessage;
284
+ private makeRequest;
285
+ createSignal(wallet: WalletAuth, options: CreateSignalOptions): Promise<CreateSignalResponse>;
286
+ openSignal(wallet: WalletAuth, signalId: string): Promise<OpenSignalResponse>;
287
+ openSignalDecrypted(wallet: WalletAuth, signalId: string, keyBase64?: string): Promise<OpenSignalResponseDecrypted>;
288
+ listMySignals(wallet: WalletAuth): Promise<ListMySignalsResponse>;
289
+ uploadFile(wallet: WalletAuth, options: UploadFileOptions): Promise<UploadFileResponse>;
290
+ downloadFile(wallet: WalletAuth, signalId: string): Promise<DownloadFileResponse>;
291
+ downloadFileDecrypted(wallet: WalletAuth, signalId: string, keyBase64: string): Promise<{
292
+ data: ArrayBuffer;
293
+ originalName: string;
294
+ mimeType: string;
295
+ sizeBytes: number;
296
+ }>;
297
+ createSignalEncrypted(wallet: WalletAuth, options: CreateSignalOptionsEncrypted): Promise<CreateSignalResponseEncrypted>;
298
+ private createPrivateSignalEncrypted;
299
+ private createSharedSignalEncrypted;
300
+ uploadFileEncrypted(wallet: WalletAuth, fileData: ArrayBuffer | Uint8Array | Buffer, originalName: string, mimeType: string, key: CryptoKey): Promise<UploadFileResponse>;
301
+ burnSignal(wallet: WalletAuth, signalId: string): Promise<{
302
+ success: boolean;
303
+ }>;
304
+ }
305
+
306
+ interface PrivateKeyWalletConfig {
307
+ privateKey: string;
308
+ }
309
+ interface PreSignedWalletConfig {
310
+ address: string;
311
+ signature: string;
312
+ message: string;
313
+ }
314
+ declare function createWalletFromPrivateKey(config: PrivateKeyWalletConfig): WalletAuth;
315
+ declare function createWalletFromPreSigned(config: PreSignedWalletConfig): WalletAuth;
316
+ declare function createBrowserWallet(ethereum: any, address?: string): Promise<WalletAuth>;
317
+
318
+ declare class RateLimitError extends Error {
319
+ readonly retryAfterMs: number;
320
+ constructor(message: string, retryAfterMs: number);
321
+ }
322
+
323
+ declare class MorseSDKError extends Error {
324
+ code?: string | undefined;
325
+ statusCode?: number | undefined;
326
+ constructor(message: string, code?: string | undefined, statusCode?: number | undefined);
327
+ }
328
+ declare class SignalNotFoundError extends MorseSDKError {
329
+ constructor(message?: string);
330
+ }
331
+ declare class SignalExpiredError extends MorseSDKError {
332
+ constructor(message?: string);
333
+ }
334
+ declare class SignalAlreadyUsedError extends MorseSDKError {
335
+ constructor(message?: string);
336
+ }
337
+ declare class WalletNotAllowedError extends MorseSDKError {
338
+ constructor(message?: string);
339
+ }
340
+ declare class ValidationError extends MorseSDKError {
341
+ constructor(message?: string);
342
+ }
343
+ declare class NetworkError extends MorseSDKError {
344
+ originalError?: Error | undefined;
345
+ constructor(message?: string, originalError?: Error | undefined);
346
+ }
347
+
348
+ type LogLevel = "none" | "error" | "warn" | "info" | "debug";
349
+ declare class Logger {
350
+ private level;
351
+ private levels;
352
+ setLevel(level: LogLevel): void;
353
+ getLevel(): LogLevel;
354
+ private shouldLog;
355
+ error(message: string, ...args: any[]): void;
356
+ warn(message: string, ...args: any[]): void;
357
+ info(message: string, ...args: any[]): void;
358
+ debug(message: string, ...args: any[]): void;
359
+ }
360
+ declare const logger: Logger;
361
+
362
+ declare function isValidSignalId(signalId: string): boolean;
363
+ declare function isValidWalletAddress(address: string): boolean;
364
+ declare function validateSignalId(signalId: string): void;
365
+ declare function validateWalletAddress(address: string): void;
366
+ declare function formatExpiration(expiresAt: string): string;
367
+ declare function isSignalExpired(expiresAt: string): boolean;
368
+ declare function getTimeUntilExpiration(expiresAt: string): number;
369
+ declare function parseExpiresIn(expiresIn: string): number;
370
+ declare function filterActiveSignals<T extends {
371
+ status: string;
372
+ expiresAt: string;
373
+ }>(signals: T[]): T[];
374
+ declare function sortSignalsByDate<T extends {
375
+ createdAt: string;
376
+ }>(signals: T[], order?: "asc" | "desc"): T[];
377
+ declare function getSignalUrl(baseUrl: string, signalId: string, keyBase64?: string): string;
378
+ declare function extractSignalIdFromUrl(url: string): string | null;
379
+
380
+ declare function getCipherVersion(): string;
381
+ declare function generateShareableLink(baseUrl: string, signalId: string, keyBase64: string): string;
382
+
383
+ /**
384
+ * MORSE SDK - X25519 + XChaCha20-Poly1305 Encryption
385
+ *
386
+ * Compatible with morse-frontend's crypto-x25519.ts
387
+ *
388
+ * Security Model:
389
+ * - X25519 for ECDH key exchange
390
+ * - XChaCha20-Poly1305 for authenticated encryption
391
+ * - HKDF-SHA-256 for key derivation
392
+ * - Ephemeral sender keys (forward secrecy)
393
+ */
394
+ declare const X25519_CIPHER_VERSION = "morse-x25519-xchacha20poly1305-v2";
395
+ /**
396
+ * Derive deterministic X25519 keypair from wallet signature
397
+ */
398
+ declare function deriveKeyPairFromWalletSignature(walletAddress: string, domain: string, chainId: number, signMessage: (message: string) => Promise<string>): Promise<{
399
+ publicKey: Uint8Array;
400
+ privateKey: Uint8Array;
401
+ }>;
402
+ /**
403
+ * Key Certificate interface
404
+ */
405
+ interface MorseKeyCert {
406
+ walletAddress: string;
407
+ x25519PublicKey: string;
408
+ keyId: string;
409
+ expiresAt: number;
410
+ issuedAt: number;
411
+ domain: string;
412
+ chainId: number;
413
+ signature: string;
414
+ }
415
+ /**
416
+ * Create and sign a key certificate
417
+ */
418
+ declare function createKeyCertificate(walletAddress: string, x25519PublicKey: string, domain: string, chainId: number, expiresAt: number, signTypedData: (domain: any, types: any, value: any) => Promise<string>): Promise<MorseKeyCert>;
419
+ /**
420
+ * Verify a key certificate signature
421
+ */
422
+ declare function verifyKeyCertificate(cert: MorseKeyCert): boolean;
423
+ interface CreateSharedSignalResult {
424
+ cipherVersion: string;
425
+ encryptedPayload: string;
426
+ payloadNonce: string;
427
+ sealedDataKey: string;
428
+ sealedNonce: string;
429
+ senderEphemeralPublicKey: string;
430
+ aadHash: string;
431
+ }
432
+ /**
433
+ * Create shared signal (sender side)
434
+ */
435
+ declare function createSharedSignal(payloadBytes: Uint8Array, recipientPubKey: Uint8Array, walletTarget: string, walletCreator: string, expiresAt: number, signalId: string): Promise<CreateSharedSignalResult>;
436
+ /**
437
+ * Open shared signal (recipient side)
438
+ */
439
+ declare function openSharedSignal(encryptedPayloadBase64: string, payloadNonceBase64: string, sealedDataKeyBase64: string, sealedNonceBase64: string, senderEphemeralPublicKeyBase64: string, signalId: string, walletTarget: string, walletCreator: string, expiresAt: number, aadHash: string, walletAddress: string, domain: string, chainId: number, signMessage: (message: string) => Promise<string>): Promise<Uint8Array>;
440
+ /**
441
+ * Generate a random UUID for signal ID
442
+ */
443
+ declare function generateSignalId(): string;
444
+
445
+ /**
446
+ * Wallet Key Registry Service
447
+ *
448
+ * Fetches and publishes X25519 public keys from/to the backend registry
449
+ */
450
+
451
+ interface GetPublicKeyResponse {
452
+ walletAddress: string;
453
+ certificate: MorseKeyCert | null;
454
+ exists: boolean;
455
+ }
456
+ declare class WalletKeyService {
457
+ private baseUrl;
458
+ private apiKey;
459
+ private apiVersion;
460
+ constructor(baseUrl: string, apiKey: string, apiVersion?: string);
461
+ private getApiUrl;
462
+ getPublicKey(walletAddress: string): Promise<GetPublicKeyResponse>;
463
+ publishPublicKey(certificate: MorseKeyCert): Promise<void>;
464
+ }
465
+
466
+ /**
467
+ * Common expiration time constants for signals
468
+ *
469
+ * Use these constants to ensure correct format and get autocomplete support
470
+ *
471
+ * @example
472
+ * ```typescript
473
+ * await sdk.createSignalEncrypted(wallet, {
474
+ * mode: "shared_wallet",
475
+ * walletTarget: "0x...",
476
+ * message: "...",
477
+ * expiresIn: Expiration.ONE_DAY, // "24h"
478
+ * });
479
+ * ```
480
+ */
481
+ declare const Expiration: {
482
+ /** 5 seconds */
483
+ readonly FIVE_SECONDS: "5s";
484
+ /** 30 seconds */
485
+ readonly THIRTY_SECONDS: "30s";
486
+ /** 1 minute */
487
+ readonly ONE_MINUTE: "1m";
488
+ /** 5 minutes */
489
+ readonly FIVE_MINUTES: "5m";
490
+ /** 30 minutes */
491
+ readonly THIRTY_MINUTES: "30m";
492
+ /** 1 hour */
493
+ readonly ONE_HOUR: "1h";
494
+ /** 6 hours */
495
+ readonly SIX_HOURS: "6h";
496
+ /** 12 hours */
497
+ readonly TWELVE_HOURS: "12h";
498
+ /** 24 hours (1 day) */
499
+ readonly ONE_DAY: "24h";
500
+ /** 7 days (1 week) */
501
+ readonly ONE_WEEK: "7d";
502
+ /** 30 days (1 month) */
503
+ readonly ONE_MONTH: "30d";
504
+ };
505
+ /**
506
+ * Type for expiration values
507
+ */
508
+ type ExpirationValue = typeof Expiration[keyof typeof Expiration] | string;
509
+
510
+ export { type CreateSharedSignalResult, type CreateSignalOptions, type CreateSignalOptionsEncrypted, type CreateSignalResponse, type CreateSignalResponseEncrypted, type DownloadFileResponse, Expiration, type ExpirationValue, type ListMySignalsResponse, type LogLevel, type MorseContract, type MorseContractV1, type MorseKeyCert, MorseSDK, type MorseSDKCallbacks, type MorseSDKConfig, type MorseSDKConfigV1, MorseSDKError, MorseSDKV1, NetworkError, type OnChainNotification, type OnChainNotificationStatus, type OpenSignalResponse, type OpenSignalResponseDecrypted, type PreSignedWalletConfig, type PrivateKeyWalletConfig, type RateLimitConfig, RateLimitError, SignalAlreadyUsedError, type SignalErrorResponse, SignalExpiredError, type SignalFile, type SignalListItem, type SignalMode, SignalNotFoundError, type SignalStatus, type UploadFileOptions, type UploadFileResponse, ValidationError, type WalletAuth, WalletKeyService, WalletNotAllowedError, X25519_CIPHER_VERSION, createBrowserWallet, createKeyCertificate, createSharedSignal, createWalletFromPreSigned, createWalletFromPrivateKey, deriveKeyPairFromWalletSignature, extractSignalIdFromUrl, filterActiveSignals, formatExpiration, generateShareableLink, generateSignalId, getCipherVersion, getSignalUrl, getTimeUntilExpiration, isSignalExpired, isValidSignalId, isValidWalletAddress, logger, openSharedSignal, parseExpiresIn, sortSignalsByDate, validateSignalId, validateWalletAddress, verifyKeyCertificate };