@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.
- package/CHANGELOG.md +38 -0
- package/README.md +588 -0
- package/dist/index.d.mts +510 -0
- package/dist/index.d.ts +510 -0
- package/dist/index.js +1647 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1606 -0
- package/dist/index.mjs.map +1 -0
- package/docs/AUTHENTICATION.md +270 -0
- package/package.json +68 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0-beta.3] - 2025-01-XX
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- Updated package name to @morseai/sdk
|
|
12
|
+
- Updated repository URL to https://github.com/morseaitech/sdk.git
|
|
13
|
+
|
|
14
|
+
## [0.1.0-beta.1] - 2025-01-XX
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
- Initial beta release of MORSE SDK
|
|
18
|
+
- TypeScript SDK for creating and accessing encrypted signals
|
|
19
|
+
- Support for private and shared wallet signals
|
|
20
|
+
- X25519 + XChaCha20-Poly1305 encryption for shared signals
|
|
21
|
+
- AES-GCM-256 encryption for private signals
|
|
22
|
+
- Wallet authentication (browser, private key, custom)
|
|
23
|
+
- Automatic encryption/decryption
|
|
24
|
+
- Rate limiting support
|
|
25
|
+
- Request retry logic
|
|
26
|
+
- Comprehensive error handling
|
|
27
|
+
- Input validation
|
|
28
|
+
- Expiration utilities and constants
|
|
29
|
+
- File upload support
|
|
30
|
+
- Key certificate management (EIP-712)
|
|
31
|
+
- Deterministic key derivation from wallet signatures
|
|
32
|
+
|
|
33
|
+
### Security
|
|
34
|
+
- Zero-knowledge architecture (server never sees plaintext)
|
|
35
|
+
- One-time access enforcement (signals burned after opening)
|
|
36
|
+
- Atomic operations prevent race conditions
|
|
37
|
+
- Certificate signature verification prevents key substitution attacks
|
|
38
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,588 @@
|
|
|
1
|
+
# MORSE SDK
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for creating and accessing encrypted signals in the MORSE platform.
|
|
4
|
+
|
|
5
|
+
**Version:** 0.1.0-beta.3 (Beta Release)
|
|
6
|
+
|
|
7
|
+
> ⚠️ **Beta Notice**: This is a beta release. The API is stable but may have minor changes before the 1.0.0 release. Please report any issues you encounter.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- ✅ Full TypeScript support with autocomplete
|
|
12
|
+
- ✅ Automatic encryption/decryption (AES-GCM and X25519)
|
|
13
|
+
- ✅ Wallet authentication (browser, private key, custom)
|
|
14
|
+
- ✅ X25519 + XChaCha20-Poly1305 for shared signals
|
|
15
|
+
- ✅ Rate limiting (configurable)
|
|
16
|
+
- ✅ Request retry logic
|
|
17
|
+
- ✅ Comprehensive error handling
|
|
18
|
+
- ✅ Input validation
|
|
19
|
+
- ✅ Security-first design
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @morseai/sdk
|
|
25
|
+
# or
|
|
26
|
+
pnpm add @morseai/sdk
|
|
27
|
+
# or
|
|
28
|
+
yarn add @morseai/sdk
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Prerequisites
|
|
32
|
+
|
|
33
|
+
This SDK requires `ethers` v6+ as a peer dependency for wallet signature functionality.
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install ethers
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Authentication
|
|
40
|
+
|
|
41
|
+
MORSE uses **wallet signature authentication** - you sign a message with your Ethereum wallet to authenticate requests. See [AUTHENTICATION.md](./docs/AUTHENTICATION.md) for complete details.
|
|
42
|
+
|
|
43
|
+
**Quick summary:**
|
|
44
|
+
- ✅ API Key (required for SDK usage)
|
|
45
|
+
- ✅ Wallet signature (for frontend/operations)
|
|
46
|
+
- ✅ Private key (for backend/server)
|
|
47
|
+
- ✅ Custom implementation
|
|
48
|
+
|
|
49
|
+
## Quick Start
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import { MorseSDK, createWalletFromPrivateKey, Expiration } from "@morseai/sdk";
|
|
53
|
+
|
|
54
|
+
// Initialize SDK (only apiKey is required)
|
|
55
|
+
const sdk = new MorseSDK({
|
|
56
|
+
apiKey: process.env.MORSE_API_KEY!,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Create wallet from private key
|
|
60
|
+
const wallet = createWalletFromPrivateKey({
|
|
61
|
+
privateKey: process.env.PRIVATE_KEY!,
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// Create a shared signal (X25519 encryption)
|
|
65
|
+
const result = await sdk.createSignalEncrypted(wallet, {
|
|
66
|
+
walletTarget: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
|
|
67
|
+
mode: "shared_wallet",
|
|
68
|
+
message: "Secret message! 🔐",
|
|
69
|
+
expiresIn: Expiration.ONE_DAY, // or "24h", "7d", etc.
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
console.log("Signal ID:", result.signalId);
|
|
73
|
+
console.log("Shareable link:", result.shareableLink);
|
|
74
|
+
|
|
75
|
+
// Open and decrypt signal
|
|
76
|
+
const decrypted = await sdk.openSignalDecrypted(wallet, result.signalId);
|
|
77
|
+
console.log("Message:", decrypted.message);
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Configuration
|
|
81
|
+
|
|
82
|
+
### Basic Setup
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
import { MorseSDK } from "@morseai/sdk";
|
|
86
|
+
|
|
87
|
+
// Simple initialization (only apiKey is required)
|
|
88
|
+
const sdk = new MorseSDK({
|
|
89
|
+
apiKey: "sk_your_api_key_here", // REQUIRED
|
|
90
|
+
});
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Note:** `baseUrl` and `frontendUrl` are internal constants. The SDK automatically uses the correct API endpoints.
|
|
94
|
+
|
|
95
|
+
### Advanced Configuration
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
const sdk = new MorseSDK({
|
|
99
|
+
apiKey: "sk_your_api_key_here", // REQUIRED
|
|
100
|
+
apiVersion: "v1", // Optional, defaults to "v1"
|
|
101
|
+
timeout: 30000, // Request timeout in ms (default: 30000)
|
|
102
|
+
retries: 3, // Number of retries on failure (default: 0)
|
|
103
|
+
retryDelay: 1000, // Delay between retries in ms (default: 1000)
|
|
104
|
+
rateLimit: {
|
|
105
|
+
enabled: true, // Enable rate limiting (default: true)
|
|
106
|
+
maxRequests: 100, // Maximum requests per window (default: 100)
|
|
107
|
+
windowMs: 60000, // Time window in milliseconds (default: 60000 = 1 minute)
|
|
108
|
+
},
|
|
109
|
+
onRequest: (url, options) => {
|
|
110
|
+
console.log("Making request to:", url);
|
|
111
|
+
},
|
|
112
|
+
onResponse: (url, response) => {
|
|
113
|
+
console.log("Response received from:", url, response.status);
|
|
114
|
+
},
|
|
115
|
+
onError: (error) => {
|
|
116
|
+
console.error("Request error:", error);
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Wallet Authentication
|
|
122
|
+
|
|
123
|
+
The SDK supports multiple ways to authenticate, depending on your use case:
|
|
124
|
+
|
|
125
|
+
### 1. Browser/Web3 Wallet (Frontend)
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
import { MorseSDK, createBrowserWallet } from "@morseai/sdk";
|
|
129
|
+
|
|
130
|
+
const sdk = new MorseSDK({
|
|
131
|
+
apiKey: process.env.MORSE_API_KEY!,
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// For MetaMask or other browser wallets
|
|
135
|
+
const wallet = await createBrowserWallet(window.ethereum);
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### 2. Private Key (Backend/Server)
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
import { MorseSDK, createWalletFromPrivateKey } from "@morseai/sdk";
|
|
142
|
+
|
|
143
|
+
const sdk = new MorseSDK({
|
|
144
|
+
apiKey: process.env.MORSE_API_KEY!,
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// For backend applications with a private key
|
|
148
|
+
const wallet = createWalletFromPrivateKey({
|
|
149
|
+
privateKey: process.env.PRIVATE_KEY!, // Keep this secure!
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### 3. Custom Implementation
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
import { MorseSDK, type WalletAuth } from "@morseai/sdk";
|
|
157
|
+
|
|
158
|
+
const sdk = new MorseSDK({
|
|
159
|
+
apiKey: process.env.MORSE_API_KEY!,
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// Implement your own wallet auth
|
|
163
|
+
const wallet: WalletAuth = {
|
|
164
|
+
address: "0x...",
|
|
165
|
+
signMessage: async (message: string) => {
|
|
166
|
+
// Your custom signing logic
|
|
167
|
+
return signature;
|
|
168
|
+
},
|
|
169
|
+
};
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Creating Signals
|
|
173
|
+
|
|
174
|
+
### Automatic Encryption (Recommended)
|
|
175
|
+
|
|
176
|
+
The SDK can handle encryption automatically. This is the recommended approach:
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
import { MorseSDK, Expiration } from "@morseai/sdk";
|
|
180
|
+
|
|
181
|
+
// Create a private signal (AES-GCM, key in URL)
|
|
182
|
+
const privateSignal = await sdk.createSignalEncrypted(wallet, {
|
|
183
|
+
mode: "private",
|
|
184
|
+
message: "Private message - key will be in URL",
|
|
185
|
+
expiresIn: Expiration.ONE_DAY,
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// Create a shared signal (X25519, recipient decrypts with wallet)
|
|
189
|
+
const sharedSignal = await sdk.createSignalEncrypted(wallet, {
|
|
190
|
+
walletTarget: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
|
|
191
|
+
mode: "shared_wallet", // shareWithRecipient is automatically true
|
|
192
|
+
message: "Shared message - recipient decrypts with wallet",
|
|
193
|
+
expiresIn: Expiration.ONE_DAY,
|
|
194
|
+
});
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Signal Modes
|
|
198
|
+
|
|
199
|
+
- **`mode: "private"`** - Private signal, key stored in URL fragment (`#k=...`)
|
|
200
|
+
- Uses AES-GCM encryption
|
|
201
|
+
- `shareWithRecipient` is automatically `false`
|
|
202
|
+
- Key is derived from wallet (deterministic) or random (for URL sharing)
|
|
203
|
+
|
|
204
|
+
- **`mode: "shared_wallet"`** - Shared signal, recipient decrypts with their wallet
|
|
205
|
+
- Uses X25519 + XChaCha20-Poly1305 encryption
|
|
206
|
+
- `shareWithRecipient` is automatically `true`
|
|
207
|
+
- Requires `walletTarget` (recipient's wallet address)
|
|
208
|
+
- No key in URL needed
|
|
209
|
+
|
|
210
|
+
### Expiration
|
|
211
|
+
|
|
212
|
+
You can specify expiration in two ways:
|
|
213
|
+
|
|
214
|
+
#### Option 1: Relative Time (`expiresIn`)
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
import { Expiration } from "@morseai/sdk";
|
|
218
|
+
|
|
219
|
+
await sdk.createSignalEncrypted(wallet, {
|
|
220
|
+
mode: "shared_wallet",
|
|
221
|
+
walletTarget: "0x...",
|
|
222
|
+
message: "...",
|
|
223
|
+
expiresIn: Expiration.ONE_DAY, // Use constants for autocomplete
|
|
224
|
+
// Or use string format: "24h", "7d", "1h", "30m", "5s"
|
|
225
|
+
});
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
**Available Constants:**
|
|
229
|
+
- `Expiration.FIVE_SECONDS` → `"5s"`
|
|
230
|
+
- `Expiration.ONE_MINUTE` → `"1m"`
|
|
231
|
+
- `Expiration.ONE_HOUR` → `"1h"`
|
|
232
|
+
- `Expiration.ONE_DAY` → `"24h"`
|
|
233
|
+
- `Expiration.ONE_WEEK` → `"7d"`
|
|
234
|
+
- `Expiration.ONE_MONTH` → `"30d"`
|
|
235
|
+
- And more...
|
|
236
|
+
|
|
237
|
+
#### Option 2: Specific Date (`expiresAt`)
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
// Specific date and time
|
|
241
|
+
const customDate = new Date("2026-12-31T23:59:59.000Z");
|
|
242
|
+
await sdk.createSignalEncrypted(wallet, {
|
|
243
|
+
mode: "shared_wallet",
|
|
244
|
+
walletTarget: "0x...",
|
|
245
|
+
message: "...",
|
|
246
|
+
expiresAt: customDate.toISOString(), // ISO 8601 format
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
// Or calculate from now
|
|
250
|
+
const futureDate = new Date();
|
|
251
|
+
futureDate.setHours(futureDate.getHours() + 2); // 2 hours from now
|
|
252
|
+
await sdk.createSignalEncrypted(wallet, {
|
|
253
|
+
mode: "shared_wallet",
|
|
254
|
+
walletTarget: "0x...",
|
|
255
|
+
message: "...",
|
|
256
|
+
expiresAt: futureDate.toISOString(),
|
|
257
|
+
});
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
**Note:** Either `expiresIn` OR `expiresAt` must be provided (not both).
|
|
261
|
+
|
|
262
|
+
### Creating Signals with Files
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
import * as fs from "fs";
|
|
266
|
+
|
|
267
|
+
const fileData = fs.readFileSync("./document.pdf");
|
|
268
|
+
|
|
269
|
+
const result = await sdk.createSignalEncrypted(wallet, {
|
|
270
|
+
walletTarget: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
|
|
271
|
+
mode: "shared_wallet",
|
|
272
|
+
message: "Check out this document!",
|
|
273
|
+
file: {
|
|
274
|
+
data: fileData,
|
|
275
|
+
originalName: "document.pdf",
|
|
276
|
+
mimeType: "application/pdf",
|
|
277
|
+
},
|
|
278
|
+
expiresIn: Expiration.ONE_DAY,
|
|
279
|
+
});
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Opening Signals
|
|
283
|
+
|
|
284
|
+
### Automatic Decryption
|
|
285
|
+
|
|
286
|
+
The SDK automatically detects the encryption type and decrypts accordingly:
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
// Open and decrypt signal (automatic detection)
|
|
290
|
+
const decrypted = await sdk.openSignalDecrypted(wallet, signalId);
|
|
291
|
+
|
|
292
|
+
console.log("Message:", decrypted.message);
|
|
293
|
+
console.log("File:", decrypted.file);
|
|
294
|
+
console.log("Key source:", decrypted.keySource); // "derived" (X25519) or "provided" (URL key)
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
**For X25519 signals:**
|
|
298
|
+
- No key needed - recipient decrypts with their wallet
|
|
299
|
+
- SDK automatically derives the key from wallet signature
|
|
300
|
+
|
|
301
|
+
**For private signals (AES-GCM):**
|
|
302
|
+
- Key is in the URL fragment (`#k=...`)
|
|
303
|
+
- Or you can provide it manually:
|
|
304
|
+
|
|
305
|
+
```typescript
|
|
306
|
+
const decrypted = await sdk.openSignalDecrypted(wallet, signalId, keyFromUrl);
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### Raw Encrypted Data
|
|
310
|
+
|
|
311
|
+
If you need the raw encrypted data (for manual decryption):
|
|
312
|
+
|
|
313
|
+
```typescript
|
|
314
|
+
const encrypted = await sdk.openSignal(wallet, signalId);
|
|
315
|
+
|
|
316
|
+
console.log("Encrypted text:", encrypted.encryptedText);
|
|
317
|
+
console.log("Payload nonce:", encrypted.payloadNonce);
|
|
318
|
+
console.log("Cipher version:", encrypted.cipherVersion);
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## Listing Signals
|
|
322
|
+
|
|
323
|
+
```typescript
|
|
324
|
+
const mySignals = await sdk.listMySignals(wallet);
|
|
325
|
+
|
|
326
|
+
console.log(`You have ${mySignals.count} signals`);
|
|
327
|
+
mySignals.signals.forEach((signal) => {
|
|
328
|
+
console.log(`- ${signal.signalId}: ${signal.status}`);
|
|
329
|
+
console.log(` Created: ${signal.createdAt}`);
|
|
330
|
+
console.log(` Expires: ${signal.expiresAt}`);
|
|
331
|
+
});
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## Burning Signals
|
|
335
|
+
|
|
336
|
+
```typescript
|
|
337
|
+
await sdk.burnSignal(wallet, "signal-id-here");
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
**Note:** Only the signal creator or recipient can burn a signal.
|
|
341
|
+
|
|
342
|
+
## Encryption Methods
|
|
343
|
+
|
|
344
|
+
### X25519 (Shared Signals)
|
|
345
|
+
|
|
346
|
+
For `mode: "shared_wallet"` signals:
|
|
347
|
+
- **Encryption:** X25519 ECDH + XChaCha20-Poly1305
|
|
348
|
+
- **Key Exchange:** Ephemeral sender key + recipient's static key
|
|
349
|
+
- **Decryption:** Recipient uses their wallet to derive key
|
|
350
|
+
- **No key in URL:** Recipient decrypts with their wallet signature
|
|
351
|
+
|
|
352
|
+
### AES-GCM (Private Signals)
|
|
353
|
+
|
|
354
|
+
For `mode: "private"` signals:
|
|
355
|
+
- **Encryption:** AES-GCM-256
|
|
356
|
+
- **Key:** Derived from wallet or random (for URL sharing)
|
|
357
|
+
- **Key in URL:** For shareable links, key is in URL fragment (`#k=...`)
|
|
358
|
+
|
|
359
|
+
## Error Handling
|
|
360
|
+
|
|
361
|
+
The SDK throws specific error types for better error handling:
|
|
362
|
+
|
|
363
|
+
```typescript
|
|
364
|
+
import {
|
|
365
|
+
MorseSDKError,
|
|
366
|
+
SignalNotFoundError,
|
|
367
|
+
SignalExpiredError,
|
|
368
|
+
SignalAlreadyUsedError,
|
|
369
|
+
WalletNotAllowedError,
|
|
370
|
+
ValidationError,
|
|
371
|
+
NetworkError,
|
|
372
|
+
RateLimitError,
|
|
373
|
+
} from "@morseai/sdk";
|
|
374
|
+
|
|
375
|
+
try {
|
|
376
|
+
const signal = await sdk.openSignalDecrypted(wallet, signalId);
|
|
377
|
+
} catch (error) {
|
|
378
|
+
if (error instanceof SignalExpiredError) {
|
|
379
|
+
console.log("Signal expired");
|
|
380
|
+
} else if (error instanceof SignalAlreadyUsedError) {
|
|
381
|
+
console.log("Signal already used");
|
|
382
|
+
} else if (error instanceof WalletNotAllowedError) {
|
|
383
|
+
console.log("Wallet not allowed");
|
|
384
|
+
} else if (error instanceof RateLimitError) {
|
|
385
|
+
console.log(`Rate limit exceeded. Retry after ${error.retryAfterMs}ms`);
|
|
386
|
+
} else {
|
|
387
|
+
console.error("Unknown error:", error);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
## Examples
|
|
393
|
+
|
|
394
|
+
See the `examples/` directory for complete working examples:
|
|
395
|
+
|
|
396
|
+
- `create-signal-example.ts` - Creating signals
|
|
397
|
+
- `open-signal-example.ts` - Opening and decrypting signals
|
|
398
|
+
- `backend-to-backend.ts` - Backend-to-backend communication
|
|
399
|
+
- `browser-example.ts` - Browser/Web3 wallet usage
|
|
400
|
+
- `custom-expiration-example.ts` - Custom expiration dates
|
|
401
|
+
- `advanced-config.ts` - Advanced configuration options
|
|
402
|
+
|
|
403
|
+
**Running examples:**
|
|
404
|
+
|
|
405
|
+
```bash
|
|
406
|
+
# Set environment variables
|
|
407
|
+
export MORSE_API_KEY=sk_your_api_key
|
|
408
|
+
export PRIVATE_KEY=your_private_key_hex
|
|
409
|
+
|
|
410
|
+
# Run examples
|
|
411
|
+
npx tsx examples/create-signal-example.ts
|
|
412
|
+
npx tsx examples/open-signal-example.ts <signalId>
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
## API Reference
|
|
416
|
+
|
|
417
|
+
### `MorseSDK`
|
|
418
|
+
|
|
419
|
+
The main SDK class for creating and accessing encrypted signals.
|
|
420
|
+
|
|
421
|
+
#### Constructor
|
|
422
|
+
|
|
423
|
+
```typescript
|
|
424
|
+
new MorseSDK(config: MorseSDKConfig)
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
**Config Options:**
|
|
428
|
+
|
|
429
|
+
| Option | Type | Default | Description |
|
|
430
|
+
|--------|------|---------|-------------|
|
|
431
|
+
| `apiKey` | `string` | **Required** | Your MORSE API key (starts with `sk_`) |
|
|
432
|
+
| `apiVersion` | `string` | `"v1"` | API version to use |
|
|
433
|
+
| `timeout` | `number` | `30000` | Request timeout in milliseconds |
|
|
434
|
+
| `retries` | `number` | `0` | Number of retries on failure |
|
|
435
|
+
| `retryDelay` | `number` | `1000` | Delay between retries in ms |
|
|
436
|
+
| `rateLimit` | `RateLimitConfig` | `{ enabled: true, maxRequests: 100, windowMs: 60000 }` | Rate limiting config |
|
|
437
|
+
| `onRequest` | `function` | - | Callback before each request |
|
|
438
|
+
| `onResponse` | `function` | - | Callback after each response |
|
|
439
|
+
| `onError` | `function` | - | Callback on errors |
|
|
440
|
+
|
|
441
|
+
#### Methods
|
|
442
|
+
|
|
443
|
+
##### `createSignalEncrypted(wallet, options): Promise<CreateSignalResponseEncrypted>`
|
|
444
|
+
|
|
445
|
+
Create a signal with automatic encryption. **Recommended method.**
|
|
446
|
+
|
|
447
|
+
**Parameters:**
|
|
448
|
+
- `wallet: WalletAuth` - Wallet authentication object
|
|
449
|
+
- `options: CreateSignalOptionsEncrypted` - Signal creation options
|
|
450
|
+
|
|
451
|
+
**Returns:** `Promise<CreateSignalResponseEncrypted>` - Created signal with shareable link
|
|
452
|
+
|
|
453
|
+
**Example:**
|
|
454
|
+
```typescript
|
|
455
|
+
const result = await sdk.createSignalEncrypted(wallet, {
|
|
456
|
+
walletTarget: "0x...", // Required for shared_wallet mode
|
|
457
|
+
mode: "shared_wallet", // or "private"
|
|
458
|
+
message: "Secret message",
|
|
459
|
+
expiresIn: Expiration.ONE_DAY,
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
console.log("Signal ID:", result.signalId);
|
|
463
|
+
console.log("Shareable link:", result.shareableLink);
|
|
464
|
+
console.log("Key (for private signals):", result.keyBase64);
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
##### `openSignalDecrypted(wallet, signalId, keyBase64?): Promise<OpenSignalResponseDecrypted>`
|
|
468
|
+
|
|
469
|
+
Open and decrypt a signal automatically.
|
|
470
|
+
|
|
471
|
+
**Parameters:**
|
|
472
|
+
- `wallet: WalletAuth` - Wallet authentication object
|
|
473
|
+
- `signalId: string` - Signal ID to open
|
|
474
|
+
- `keyBase64?: string` - Optional key for private signals (from URL fragment)
|
|
475
|
+
|
|
476
|
+
**Returns:** `Promise<OpenSignalResponseDecrypted>` - Decrypted signal data
|
|
477
|
+
|
|
478
|
+
**Example:**
|
|
479
|
+
```typescript
|
|
480
|
+
const decrypted = await sdk.openSignalDecrypted(wallet, signalId);
|
|
481
|
+
console.log("Message:", decrypted.message);
|
|
482
|
+
console.log("File:", decrypted.file);
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
##### `createSignal(wallet, options): Promise<CreateSignalResponse>`
|
|
486
|
+
|
|
487
|
+
Create a signal with pre-encrypted data (manual encryption).
|
|
488
|
+
|
|
489
|
+
**Parameters:**
|
|
490
|
+
- `wallet: WalletAuth` - Wallet authentication object
|
|
491
|
+
- `options: CreateSignalOptions` - Signal creation options with encrypted data
|
|
492
|
+
|
|
493
|
+
**Returns:** `Promise<CreateSignalResponse>` - Created signal info
|
|
494
|
+
|
|
495
|
+
##### `openSignal(wallet, signalId): Promise<OpenSignalResponse>`
|
|
496
|
+
|
|
497
|
+
Open a signal and return encrypted data (for manual decryption).
|
|
498
|
+
|
|
499
|
+
**Parameters:**
|
|
500
|
+
- `wallet: WalletAuth` - Wallet authentication object
|
|
501
|
+
- `signalId: string` - Signal ID to open
|
|
502
|
+
|
|
503
|
+
**Returns:** `Promise<OpenSignalResponse>` - Encrypted signal data
|
|
504
|
+
|
|
505
|
+
##### `listMySignals(wallet): Promise<ListMySignalsResponse>`
|
|
506
|
+
|
|
507
|
+
List all signals accessible by the wallet.
|
|
508
|
+
|
|
509
|
+
**Parameters:**
|
|
510
|
+
- `wallet: WalletAuth` - Wallet authentication object
|
|
511
|
+
|
|
512
|
+
**Returns:** `Promise<ListMySignalsResponse>` - List of signals
|
|
513
|
+
|
|
514
|
+
##### `burnSignal(wallet, signalId): Promise<{ success: boolean }>`
|
|
515
|
+
|
|
516
|
+
Manually burn a signal (mark as used).
|
|
517
|
+
|
|
518
|
+
**Parameters:**
|
|
519
|
+
- `wallet: WalletAuth` - Wallet authentication object
|
|
520
|
+
- `signalId: string` - Signal ID to burn
|
|
521
|
+
|
|
522
|
+
**Returns:** `Promise<{ success: boolean }>`
|
|
523
|
+
|
|
524
|
+
## TypeScript Support
|
|
525
|
+
|
|
526
|
+
The SDK is fully typed. All types are exported:
|
|
527
|
+
|
|
528
|
+
```typescript
|
|
529
|
+
import type {
|
|
530
|
+
CreateSignalOptions,
|
|
531
|
+
CreateSignalOptionsEncrypted,
|
|
532
|
+
CreateSignalResponse,
|
|
533
|
+
CreateSignalResponseEncrypted,
|
|
534
|
+
OpenSignalResponse,
|
|
535
|
+
OpenSignalResponseDecrypted,
|
|
536
|
+
SignalMode,
|
|
537
|
+
SignalStatus,
|
|
538
|
+
WalletAuth,
|
|
539
|
+
MorseSDKConfig,
|
|
540
|
+
ExpirationValue,
|
|
541
|
+
} from "@morseai/sdk";
|
|
542
|
+
|
|
543
|
+
import { Expiration } from "@morseai/sdk";
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
## Helper Functions
|
|
547
|
+
|
|
548
|
+
### Signal Validation
|
|
549
|
+
|
|
550
|
+
```typescript
|
|
551
|
+
import { isValidSignalId, isValidWalletAddress } from "@morseai/sdk";
|
|
552
|
+
|
|
553
|
+
isValidSignalId("abc123"); // true
|
|
554
|
+
isValidWalletAddress("0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"); // true
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
### Expiration Utilities
|
|
558
|
+
|
|
559
|
+
```typescript
|
|
560
|
+
import {
|
|
561
|
+
formatExpiration,
|
|
562
|
+
isSignalExpired,
|
|
563
|
+
getTimeUntilExpiration,
|
|
564
|
+
parseExpiresIn,
|
|
565
|
+
} from "@morseai/sdk";
|
|
566
|
+
|
|
567
|
+
formatExpiration("2025-12-31T23:59:59Z");
|
|
568
|
+
isSignalExpired("2025-12-31T23:59:59Z");
|
|
569
|
+
getTimeUntilExpiration("2025-12-31T23:59:59Z");
|
|
570
|
+
parseExpiresIn("24h");
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
### Expiration Constants
|
|
574
|
+
|
|
575
|
+
```typescript
|
|
576
|
+
import { Expiration } from "@morseai/sdk";
|
|
577
|
+
|
|
578
|
+
// Use constants for autocomplete and type safety
|
|
579
|
+
Expiration.ONE_DAY // "24h"
|
|
580
|
+
Expiration.ONE_WEEK // "7d"
|
|
581
|
+
Expiration.ONE_HOUR // "1h"
|
|
582
|
+
Expiration.ONE_MONTH // "30d"
|
|
583
|
+
// ... and more
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
## License
|
|
587
|
+
|
|
588
|
+
MIT
|