@sparkvault/sdk 1.0.0

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 (50) hide show
  1. package/README.md +720 -0
  2. package/dist/auto-init.d.ts +51 -0
  3. package/dist/config.d.ts +25 -0
  4. package/dist/errors.d.ts +30 -0
  5. package/dist/http.d.ts +48 -0
  6. package/dist/identity/api.d.ts +101 -0
  7. package/dist/identity/container.d.ts +49 -0
  8. package/dist/identity/handlers/index.d.ts +9 -0
  9. package/dist/identity/handlers/passkey-handler.d.ts +52 -0
  10. package/dist/identity/handlers/sparklink-handler.d.ts +43 -0
  11. package/dist/identity/handlers/totp-handler.d.ts +52 -0
  12. package/dist/identity/index.d.ts +69 -0
  13. package/dist/identity/inline-container.d.ts +60 -0
  14. package/dist/identity/methods.d.ts +23 -0
  15. package/dist/identity/modal.d.ts +74 -0
  16. package/dist/identity/renderer.d.ts +97 -0
  17. package/dist/identity/state.d.ts +95 -0
  18. package/dist/identity/styles.d.ts +22 -0
  19. package/dist/identity/types.d.ts +183 -0
  20. package/dist/identity/utils/cooldown-timer.d.ts +73 -0
  21. package/dist/identity/utils/index.d.ts +5 -0
  22. package/dist/identity/utils.d.ts +27 -0
  23. package/dist/identity/views/base.d.ts +62 -0
  24. package/dist/identity/views/error.d.ts +25 -0
  25. package/dist/identity/views/icons.d.ts +34 -0
  26. package/dist/identity/views/identity-input.d.ts +48 -0
  27. package/dist/identity/views/index.d.ts +14 -0
  28. package/dist/identity/views/loading.d.ts +15 -0
  29. package/dist/identity/views/method-select.d.ts +29 -0
  30. package/dist/identity/views/passkey-prompt.d.ts +22 -0
  31. package/dist/identity/views/passkey.d.ts +38 -0
  32. package/dist/identity/views/sparklink-waiting.d.ts +33 -0
  33. package/dist/identity/views/totp-verify.d.ts +58 -0
  34. package/dist/index.d.ts +658 -0
  35. package/dist/logger.d.ts +45 -0
  36. package/dist/rng/index.d.ts +54 -0
  37. package/dist/rng/types.d.ts +26 -0
  38. package/dist/sparks/index.d.ts +37 -0
  39. package/dist/sparks/types.d.ts +56 -0
  40. package/dist/sparkvault.cjs.js +6152 -0
  41. package/dist/sparkvault.cjs.js.map +1 -0
  42. package/dist/sparkvault.esm.js +6137 -0
  43. package/dist/sparkvault.esm.js.map +1 -0
  44. package/dist/sparkvault.js +2 -0
  45. package/dist/sparkvault.js.map +1 -0
  46. package/dist/utils/base64url.d.ts +49 -0
  47. package/dist/utils/retry.d.ts +32 -0
  48. package/dist/vaults/index.d.ts +83 -0
  49. package/dist/vaults/types.d.ts +120 -0
  50. package/package.json +64 -0
package/README.md ADDED
@@ -0,0 +1,720 @@
1
+ # SparkVault JavaScript SDK
2
+
3
+ A unified JavaScript SDK for SparkVault services: Identity verification, encrypted Sparks, secure Vaults, and cryptographic RNG.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@sparkvault/sdk.svg)](https://www.npmjs.com/package/@sparkvault/sdk)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## Table of Contents
9
+
10
+ - [Installation](#installation)
11
+ - [Quick Start](#quick-start)
12
+ - [Architecture](#architecture)
13
+ - [Modules](#modules)
14
+ - [Identity](#identity)
15
+ - [Sparks](#sparks)
16
+ - [Vaults](#vaults)
17
+ - [RNG](#rng)
18
+ - [Configuration](#configuration)
19
+ - [Error Handling](#error-handling)
20
+ - [TypeScript](#typescript)
21
+ - [Security](#security)
22
+ - [Development](#development)
23
+ - [License](#license)
24
+
25
+ ## Installation
26
+
27
+ ### CDN (Browser)
28
+
29
+ Include the SDK directly in your HTML. This is the recommended approach for most web applications.
30
+
31
+ #### Zero-Config Auto-Init (Recommended)
32
+
33
+ The simplest way to add SparkVault authentication to your site:
34
+
35
+ ```html
36
+ <script
37
+ async
38
+ src="https://cdn.sparkvault.com/sdk/v1/sparkvault.js"
39
+ data-account-id="acc_your_account"
40
+ data-attach-selector=".js-sparkvault-auth"
41
+ data-success-url="https://example.com/auth/verify-token"
42
+ data-debug="true"
43
+ ></script>
44
+
45
+ <button class="js-sparkvault-auth">Login with SparkVault</button>
46
+ ```
47
+
48
+ That's it! The SDK automatically:
49
+ - Initializes with your account ID
50
+ - Attaches click handlers to matching elements
51
+ - Opens the verification modal on click
52
+ - POSTs the result to your success URL
53
+
54
+ #### Auto-Init Data Attributes
55
+
56
+ | Attribute | Description |
57
+ |-----------|-------------|
58
+ | `data-account-id` | Your SparkVault account ID (required for auto-init) |
59
+ | `data-attach-selector` | CSS selector for elements to attach click handlers |
60
+ | `data-success-url` | URL to POST `{ token, identity, identityType }` on success |
61
+ | `data-success-function` | Global function name to call on success (e.g., `"handleAuth"` or `"MyApp.auth.onSuccess"`) |
62
+ | `data-error-url` | URL to redirect to on error (appends `?error=message`) |
63
+ | `data-error-function` | Global function name to call on error |
64
+ | `data-debug` | Set to `"true"` for verbose console logging |
65
+
66
+ #### Success Handling
67
+
68
+ When verification succeeds, the SDK can call a function and/or POST to a URL:
69
+
70
+ ```html
71
+ <!-- Call a function -->
72
+ <script>
73
+ function handleSparkVaultAuth(result) {
74
+ console.log('Verified:', result.identity);
75
+ console.log('Token:', result.token);
76
+ // Your logic here...
77
+ }
78
+ </script>
79
+ <script
80
+ src="https://cdn.sparkvault.com/sdk/v1/sparkvault.js"
81
+ data-account-id="acc_your_account"
82
+ data-attach-selector=".login-btn"
83
+ data-success-function="handleSparkVaultAuth"
84
+ ></script>
85
+
86
+ <!-- POST to your backend -->
87
+ <script
88
+ src="https://cdn.sparkvault.com/sdk/v1/sparkvault.js"
89
+ data-account-id="acc_your_account"
90
+ data-attach-selector=".login-btn"
91
+ data-success-url="/auth/verify-sparkvault-token"
92
+ ></script>
93
+ ```
94
+
95
+ When POSTing to `data-success-url`, the SDK sends:
96
+ ```json
97
+ {
98
+ "token": "eyJ...",
99
+ "identity": "user@example.com",
100
+ "identityType": "email"
101
+ }
102
+ ```
103
+
104
+ Your backend can respond with:
105
+ ```json
106
+ { "redirectUrl": "/dashboard" } // SDK redirects to this URL
107
+ { "reload": true } // SDK reloads the page
108
+ ```
109
+
110
+ #### Manual Initialization
111
+
112
+ For more control, initialize the SDK manually:
113
+
114
+ ```html
115
+ <script src="https://cdn.sparkvault.com/sdk/v1/sparkvault.js"></script>
116
+ <script>
117
+ const sv = SparkVault.init({
118
+ accountId: 'acc_your_account'
119
+ });
120
+
121
+ // Trigger verification popup manually
122
+ document.getElementById('login-btn').addEventListener('click', async () => {
123
+ const result = await sv.identity.pop();
124
+ // Handle result...
125
+ });
126
+ </script>
127
+ ```
128
+
129
+ #### Available CDN Files
130
+
131
+ | File | Description |
132
+ |------|-------------|
133
+ | `sparkvault.js` | Minified UMD bundle (recommended) |
134
+ | `sparkvault.esm.js` | ES module bundle |
135
+ | `sparkvault.cjs.js` | CommonJS bundle |
136
+
137
+ ### npm
138
+
139
+ ```bash
140
+ npm install @sparkvault/sdk
141
+ ```
142
+
143
+ ```javascript
144
+ // ES Modules
145
+ import { SparkVault } from '@sparkvault/sdk';
146
+
147
+ // CommonJS
148
+ const { SparkVault } = require('@sparkvault/sdk');
149
+ ```
150
+
151
+ ## Quick Start
152
+
153
+ ```javascript
154
+ // Initialize the SDK
155
+ const sv = SparkVault.init({
156
+ accountId: 'acc_your_account'
157
+ });
158
+
159
+ // Identity - Open verification popup
160
+ const result = await sv.identity.pop({
161
+ email: 'user@example.com'
162
+ });
163
+
164
+ // The token is a single-use verification proof - send it to YOUR backend
165
+ await fetch('/api/auth/login', {
166
+ method: 'POST',
167
+ headers: { 'Content-Type': 'application/json' },
168
+ body: JSON.stringify({ token: result.token })
169
+ });
170
+ // Your backend verifies the token, then creates YOUR session
171
+ ```
172
+
173
+ ## Architecture
174
+
175
+ The SparkVault SDK follows a Stripe.js-like architecture:
176
+
177
+ ```
178
+ ┌─────────────────────────────────────────────────────────────┐
179
+ │ Your Application │
180
+ ├─────────────────────────────────────────────────────────────┤
181
+ │ SparkVault SDK │
182
+ │ ┌─────────────┬─────────────┬─────────────┬─────────────┐ │
183
+ │ │ Identity │ Sparks │ Vaults │ RNG │ │
184
+ │ │ Module │ Module │ Module │ Module │ │
185
+ │ └─────────────┴─────────────┴─────────────┴─────────────┘ │
186
+ │ │ │
187
+ │ HTTP Client │
188
+ ├─────────────────────────────────────────────────────────────┤
189
+ │ api.sparkvault.com │
190
+ └─────────────────────────────────────────────────────────────┘
191
+ ```
192
+
193
+ ### Identity Popup Flow
194
+
195
+ The Identity module uses a secure popup window for authentication:
196
+
197
+ 1. **SDK opens popup** → `api.sparkvault.com/apps/identity/{account_id}/embed`
198
+ 2. **User authenticates** → Passkey, TOTP, Magic Link, or Social OAuth
199
+ 3. **Popup posts result** → `postMessage` with signed JWT token
200
+ 4. **SDK validates origin** → Ensures message is from SparkVault
201
+ 5. **Promise resolves** → Returns verified user info and token
202
+
203
+ ```
204
+ ┌──────────────┐ ┌──────────────────┐ ┌──────────────┐
205
+ │ Your App │ │ SDK Popup │ │ SparkVault │
206
+ │ │ │ │ │ Identity │
207
+ ├──────────────┤ ├──────────────────┤ ├──────────────┤
208
+ │ sv.identity │────>│ Opens popup │ │ │
209
+ │ .pop() │ │ window │────>│ /embed page │
210
+ │ │ │ │ │ │
211
+ │ │ │ User selects │ │ Auth methods │
212
+ │ │ │ auth method │<────│ displayed │
213
+ │ │ │ │ │ │
214
+ │ │ │ User completes │────>│ Verify │
215
+ │ │ │ authentication │ │ credentials │
216
+ │ │ │ │ │ │
217
+ │ Promise │<────│ postMessage │<────│ Sign JWT │
218
+ │ resolves │ │ with token │ │ token │
219
+ └──────────────┘ └──────────────────┘ └──────────────┘
220
+ ```
221
+
222
+ ## Modules
223
+
224
+ ### Identity
225
+
226
+ Verify user identity through passkey, TOTP, magic link, or social authentication.
227
+
228
+ The SDK provides two methods:
229
+ - **`pop()`** — Opens a modal popup (most common)
230
+ - **`render()`** — Embeds UI inline in your page
231
+
232
+ ```javascript
233
+ // Open popup modal
234
+ const result = await sv.identity.pop();
235
+
236
+ // With options
237
+ const result = await sv.identity.pop({
238
+ email: 'user@example.com', // Pre-fill email
239
+ methods: ['passkey', 'totp_email', 'magic_link'], // Filter methods
240
+ theme: 'dark', // 'light', 'dark', or 'auto' (system preference)
241
+ backdropBlur: true, // Enable backdrop blur effect (default: true)
242
+ locale: 'en', // UI language
243
+ onSuccess: (result) => {}, // Success callback
244
+ onCancel: () => {}, // User cancelled
245
+ onError: (error) => {} // Error callback
246
+ });
247
+
248
+ // Result structure
249
+ console.log(result.token); // Signed JWT
250
+ console.log(result.identity); // Verified identity (email or phone)
251
+ console.log(result.identityType); // 'email' or 'phone'
252
+ ```
253
+
254
+ #### Inline Rendering
255
+
256
+ For cases where you want to embed the authentication UI directly in your page instead of a popup modal, use `render()`:
257
+
258
+ ```javascript
259
+ // Render inline in a container element
260
+ const result = await sv.identity.render({
261
+ target: document.getElementById('auth-container'),
262
+ email: 'user@example.com'
263
+ });
264
+
265
+ // Embed in your own dialog without SparkVault header/footer
266
+ const result = await sv.identity.render({
267
+ target: dialogContentElement,
268
+ showHeader: false,
269
+ showFooter: false
270
+ });
271
+
272
+ // Minimal - just the auth flow, no chrome
273
+ const result = await sv.identity.render({
274
+ target: myElement,
275
+ showHeader: false,
276
+ showCloseButton: false,
277
+ showFooter: false
278
+ });
279
+ ```
280
+
281
+ | Option | Type | Default | Description |
282
+ |--------|------|---------|-------------|
283
+ | `target` | `HTMLElement` | **required** | Element to render the auth UI into |
284
+ | `showHeader` | `boolean` | `true` | Show header with branding |
285
+ | `showCloseButton` | `boolean` | `true` | Show close button in header |
286
+ | `showFooter` | `boolean` | `true` | Show "Secured by SparkVault" footer |
287
+
288
+ All other options from `pop()` are also supported (`email`, `phone`, `onSuccess`, etc.).
289
+
290
+ #### Supported Authentication Methods
291
+
292
+ | Method | Description |
293
+ |--------|-------------|
294
+ | `passkey` | WebAuthn/FIDO2 passkey authentication |
295
+ | `totp_email` | Time-based OTP sent via email |
296
+ | `totp_sms` | Time-based OTP sent via SMS |
297
+ | `magic_link` | One-click email verification link |
298
+ | `google` | Google OAuth |
299
+ | `apple` | Apple Sign In |
300
+ | `microsoft` | Microsoft OAuth |
301
+ | `github` | GitHub OAuth |
302
+
303
+ #### Appearance Options
304
+
305
+ The Identity popup supports theming and visual effects:
306
+
307
+ ```javascript
308
+ // Dark mode
309
+ await sv.identity.pop({
310
+ theme: 'dark'
311
+ });
312
+
313
+ // Light mode
314
+ await sv.identity.pop({
315
+ theme: 'light'
316
+ });
317
+
318
+ // Auto (follows system preference)
319
+ await sv.identity.pop({
320
+ theme: 'auto'
321
+ });
322
+
323
+ // Disable backdrop blur (enabled by default)
324
+ await sv.identity.pop({
325
+ backdropBlur: false
326
+ });
327
+
328
+ // Combine options
329
+ await sv.identity.pop({
330
+ email: 'user@example.com',
331
+ theme: 'dark',
332
+ backdropBlur: true
333
+ });
334
+ ```
335
+
336
+ | Option | Type | Default | Description |
337
+ |--------|------|---------|-------------|
338
+ | `theme` | `'light' \| 'dark' \| 'auto'` | Tenant default | UI color theme. `'auto'` follows system preference. |
339
+ | `backdropBlur` | `boolean` | `true` | Apply blur effect to the page behind the popup. |
340
+
341
+ #### Token Verification
342
+
343
+ ```javascript
344
+ // Verify a token (validates expiration and issuer)
345
+ const claims = await sv.identity.verifyToken(token);
346
+ console.log(claims.identity); // Verified email or phone
347
+ console.log(claims.identity_type); // 'email' or 'phone'
348
+ console.log(claims.method); // Auth method used
349
+ console.log(claims.verified_at); // Verification timestamp
350
+ console.log(claims.exp); // Expiration timestamp
351
+ ```
352
+
353
+ ### Sparks
354
+
355
+ Create and read ephemeral encrypted secrets that burn on read.
356
+
357
+ ```javascript
358
+ // Create a spark
359
+ const spark = await sv.sparks.create({
360
+ payload: 'secret data', // String or binary data
361
+ ttl: 3600, // Time-to-live in seconds (default: 3600)
362
+ maxReads: 1, // Max reads before burn (default: 1)
363
+ password: 'optional-password' // Optional password protection
364
+ });
365
+
366
+ console.log(spark.id); // Spark ID
367
+ console.log(spark.url); // Direct shareable URL
368
+ console.log(spark.expiresAt); // Expiration timestamp
369
+ console.log(spark.maxReads); // Remaining reads
370
+
371
+ // Read a spark (burns it)
372
+ const data = await sv.sparks.read(sparkId);
373
+ // or
374
+ const data = await sv.sparks.read(sparkId, 'password');
375
+
376
+ console.log(data.payload); // Decrypted payload
377
+ console.log(data.burned); // true if this was the last read
378
+ ```
379
+
380
+ ### Vaults
381
+
382
+ Create and manage encrypted vaults with persistent storage for files (Ingots).
383
+
384
+ ```javascript
385
+ // Create a vault
386
+ const vault = await sv.vaults.create({
387
+ name: 'My Vault'
388
+ });
389
+
390
+ console.log(vault.id); // Vault ID
391
+ console.log(vault.name); // Vault name
392
+ console.log(vault.vmk); // Vault Master Key (24 chars) - SAVE THIS!
393
+ console.log(vault.createdAt); // Creation timestamp
394
+
395
+ // List vaults
396
+ const vaults = await sv.vaults.list();
397
+
398
+ // Unseal a vault (required before accessing ingots)
399
+ const unsealed = await sv.vaults.unseal(vaultId, vmk);
400
+ console.log(unsealed.vatToken); // Vault Access Token
401
+ console.log(unsealed.expiresAt); // Token expiration
402
+
403
+ // Upload a file (ingot)
404
+ const ingot = await sv.vaults.uploadIngot(unsealed, {
405
+ file: fileObject, // File or Blob
406
+ name: 'document.pdf' // Display name
407
+ });
408
+
409
+ console.log(ingot.id); // Ingot ID
410
+ console.log(ingot.name); // File name
411
+ console.log(ingot.size); // File size in bytes
412
+ console.log(ingot.mimeType); // MIME type
413
+
414
+ // List ingots
415
+ const ingots = await sv.vaults.listIngots(unsealed);
416
+
417
+ // Download an ingot
418
+ const blob = await sv.vaults.downloadIngot(unsealed, ingotId);
419
+
420
+ // Delete an ingot
421
+ await sv.vaults.deleteIngot(unsealed, ingotId);
422
+ ```
423
+
424
+ ### RNG
425
+
426
+ Generate cryptographically secure random numbers using hybrid entropy (KMS + local).
427
+
428
+ ```javascript
429
+ // Generate random bytes
430
+ const result = await sv.rng.generate({
431
+ bytes: 32, // 1-1024 bytes
432
+ format: 'hex' // Output format
433
+ });
434
+
435
+ console.log(result.value); // Random value in requested format
436
+ console.log(result.bytes); // Number of bytes generated
437
+ console.log(result.format); // Format used
438
+
439
+ // Available formats
440
+ // 'hex' - Hexadecimal string
441
+ // 'base64' - Base64 encoded
442
+ // 'base64url' - URL-safe Base64
443
+ // 'bytes' - Raw Uint8Array
444
+ // 'alphanumeric' - Alphanumeric string
445
+ // 'numeric' - Numeric string
446
+ // 'uuid' - UUID v4 format
447
+ // 'password' - Password-safe characters
448
+
449
+ // Convenience methods
450
+ const uuid = await sv.rng.uuid(); // UUID v4
451
+ const password = await sv.rng.password(16); // 16-char password
452
+ ```
453
+
454
+ ## Configuration
455
+
456
+ ```javascript
457
+ const sv = SparkVault.init({
458
+ // Required
459
+ accountId: 'acc_your_account', // Your SparkVault account ID
460
+
461
+ // Optional
462
+ locale: 'en', // Default UI locale
463
+ timeout: 30000, // Request timeout in ms (default: 30000)
464
+ preloadConfig: true // Preload Identity config on init (default: true)
465
+ });
466
+ ```
467
+
468
+ ### Configuration Options
469
+
470
+ | Option | Type | Default | Description |
471
+ |--------|------|---------|-------------|
472
+ | `accountId` | `string` | **required** | Your SparkVault account ID (starts with `acc_`) |
473
+ | `locale` | `string` | `'en'` | Default UI locale for the Identity modal |
474
+ | `timeout` | `number` | `30000` | Request timeout in milliseconds |
475
+ | `preloadConfig` | `boolean` | `true` | Preload Identity configuration on SDK init |
476
+
477
+ ### Config Preloading
478
+
479
+ By default, the SDK preloads your Identity configuration in the background when `SparkVault.init()` is called. This means when the user clicks your "Sign In" button and you call `pop()`, the modal opens **instantly** without a loading spinner.
480
+
481
+ ```javascript
482
+ // Default behavior (preloadConfig: true)
483
+ // Config is fetched immediately when SDK initializes
484
+ const sv = SparkVault.init({ accountId: 'acc_xxx' });
485
+
486
+ // Later, when user clicks "Sign In"...
487
+ await sv.identity.pop(); // Opens instantly - config already loaded!
488
+ ```
489
+
490
+ If you want to defer config loading until `pop()` is called (the legacy behavior), disable preloading:
491
+
492
+ ```javascript
493
+ // Disable preloading - config loads when pop() is called
494
+ const sv = SparkVault.init({
495
+ accountId: 'acc_xxx',
496
+ preloadConfig: false
497
+ });
498
+
499
+ // Config loads on-demand with a brief loading spinner
500
+ await sv.identity.pop();
501
+ ```
502
+
503
+ ### Environments
504
+
505
+ | Environment | API Base URL | Use Case |
506
+ |-------------|--------------|----------|
507
+ | `production` | `https://api.sparkvault.com` | Live applications |
508
+ | `sandbox` | `https://sandbox.api.sparkvault.com` | Testing and development |
509
+
510
+ ## Error Handling
511
+
512
+ The SDK provides typed errors for different failure scenarios:
513
+
514
+ ```javascript
515
+ import {
516
+ SparkVaultError, // Base error class
517
+ ValidationError, // Invalid input (400)
518
+ AuthenticationError, // Not authenticated (401)
519
+ AuthorizationError, // Not authorized (403)
520
+ NetworkError, // Network failure
521
+ TimeoutError, // Request timeout
522
+ PopupBlockedError, // Popup was blocked
523
+ UserCancelledError // User closed popup
524
+ } from '@sparkvault/sdk';
525
+
526
+ try {
527
+ await sv.identity.pop();
528
+ } catch (error) {
529
+ if (error instanceof PopupBlockedError) {
530
+ alert('Please allow popups for this site');
531
+ } else if (error instanceof UserCancelledError) {
532
+ console.log('User cancelled verification');
533
+ } else if (error instanceof ValidationError) {
534
+ console.error('Validation failed:', error.message);
535
+ console.error('Details:', error.details);
536
+ } else if (error instanceof AuthenticationError) {
537
+ console.error('Authentication failed:', error.message);
538
+ } else if (error instanceof NetworkError) {
539
+ console.error('Network error:', error.message);
540
+ } else if (error instanceof TimeoutError) {
541
+ console.error('Request timed out');
542
+ } else {
543
+ console.error('Unknown error:', error);
544
+ }
545
+ }
546
+ ```
547
+
548
+ ### Error Properties
549
+
550
+ All errors extend `SparkVaultError` and include:
551
+
552
+ ```typescript
553
+ interface SparkVaultError extends Error {
554
+ message: string; // Human-readable message
555
+ code: string; // Error code (e.g., 'validation_error')
556
+ statusCode?: number; // HTTP status code if applicable
557
+ details?: Record<string, any>; // Additional error details
558
+ }
559
+ ```
560
+
561
+ ## TypeScript
562
+
563
+ The SDK is written in TypeScript and includes full type definitions:
564
+
565
+ ```typescript
566
+ import {
567
+ SparkVault,
568
+ SparkVaultConfig,
569
+ VerifyOptions,
570
+ RenderOptions,
571
+ VerifyResult,
572
+ TokenClaims,
573
+ AuthMethod,
574
+ CreateSparkOptions,
575
+ Spark,
576
+ SparkPayload,
577
+ CreateVaultOptions,
578
+ Vault,
579
+ UnsealedVault,
580
+ Ingot,
581
+ UploadIngotOptions,
582
+ GenerateOptions,
583
+ RandomResult,
584
+ RNGFormat
585
+ } from '@sparkvault/sdk';
586
+
587
+ // All methods are fully typed
588
+ const sv = SparkVault.init({
589
+ accountId: 'acc_test'
590
+ });
591
+
592
+ // TypeScript knows the return types
593
+ const result: VerifyResult = await sv.identity.pop();
594
+ ```
595
+
596
+ ## Security
597
+
598
+ ### Token Security
599
+
600
+ - All tokens are Ed25519-signed JWTs
601
+ - Tokens are validated for expiration and issuer
602
+ - Tokens are short-lived (1 hour default) and scoped to your account
603
+ - **Tokens are single-use verification proofs** — not session tokens
604
+
605
+ ### Session Management
606
+
607
+ SparkVault Identity follows the same pattern as "Login with Google" and other major IdPs:
608
+
609
+ 1. **SparkVault verifies identity** → Returns signed ID token
610
+ 2. **Your backend validates the token** → Checks signature via JWKS
611
+ 3. **Your backend creates YOUR session** → Cookie, JWT, database session
612
+ 4. **Token is discarded** → Your session takes over
613
+
614
+ There are no refresh tokens by design. Your application owns the user relationship and decides session lifetime, storage, and re-verification policy. This is the industry standard approach used by Google, Okta, Auth0, and all major identity providers.
615
+
616
+ ### Popup Security
617
+
618
+ - Origin validation prevents cross-origin attacks
619
+ - `postMessage` is used securely with origin checking
620
+ - Popups are isolated from your main window context
621
+
622
+ ### API Security
623
+
624
+ - All requests use HTTPS
625
+ - The SDK only requires your account ID (no secrets in client-side code)
626
+
627
+ ### Best Practices
628
+
629
+ 1. **Validate tokens server-side** - Don't trust client-side token validation alone
630
+ 2. **Use HTTPS** - Always serve your application over HTTPS
631
+ 3. **Keep VMKs secure** - Vault Master Keys should be stored securely by users
632
+
633
+ ## Development
634
+
635
+ ### Setup
636
+
637
+ ```bash
638
+ git clone https://github.com/Spark-Vault/sdk-js.git
639
+ cd sdk-js
640
+ npm install
641
+ ```
642
+
643
+ ### Scripts
644
+
645
+ ```bash
646
+ npm run build # Build all bundles
647
+ npm run build:watch # Build with watch mode
648
+ npm run typecheck # Run TypeScript type checking
649
+ npm run lint # Run ESLint
650
+ npm run test # Run tests
651
+ npm run test:watch # Run tests in watch mode
652
+ ```
653
+
654
+ ### Project Structure
655
+
656
+ ```
657
+ sdk-js/
658
+ ├── src/
659
+ │ ├── index.ts # Main entry point
660
+ │ ├── config.ts # Configuration management
661
+ │ ├── http.ts # HTTP client
662
+ │ ├── errors.ts # Error types
663
+ │ ├── identity/ # Identity module
664
+ │ │ ├── index.ts
665
+ │ │ ├── modal.ts # Popup manager
666
+ │ │ └── types.ts
667
+ │ ├── sparks/ # Sparks module
668
+ │ │ ├── index.ts
669
+ │ │ └── types.ts
670
+ │ ├── vaults/ # Vaults module
671
+ │ │ ├── index.ts
672
+ │ │ └── types.ts
673
+ │ └── rng/ # RNG module
674
+ │ ├── index.ts
675
+ │ └── types.ts
676
+ ├── dist/ # Built bundles
677
+ ├── tests/ # Test files
678
+ ├── .github/workflows/ # CI/CD workflows
679
+ ├── rollup.config.js # Rollup bundler config
680
+ ├── tsconfig.json # TypeScript config
681
+ └── package.json
682
+ ```
683
+
684
+ ### CI/CD
685
+
686
+ The SDK uses GitHub Actions for automated testing and deployment:
687
+
688
+ - **On PR**: Runs build, lint, typecheck, and tests
689
+ - **On push to main**: Deploys to CDN (`cdn.sparkvault.com`)
690
+ - **On release commit**: Publishes to npm
691
+
692
+ Required secrets for deployment:
693
+ - `CLOUDFLARE_API_TOKEN` - Cloudflare API token with R2 access
694
+ - `CLOUDFLARE_ACCOUNT_ID` - Cloudflare account ID
695
+ - `NPM_TOKEN` - npm publish token (for releases)
696
+
697
+ ## Browser Support
698
+
699
+ - Chrome 80+
700
+ - Firefox 75+
701
+ - Safari 13.1+
702
+ - Edge 80+
703
+
704
+ The SDK requires:
705
+ - `fetch` API
706
+ - `Promise`
707
+ - `window.open` (for Identity popup)
708
+ - `postMessage` (for popup communication)
709
+
710
+ ## License
711
+
712
+ MIT License - see [LICENSE](LICENSE) for details.
713
+
714
+ ## Links
715
+
716
+ - [SparkVault Documentation](https://sparkvault.com/api/docs)
717
+ - [SDK API Reference](https://sparkvault.com/api/docs/sdk)
718
+ - [GitHub Repository](https://github.com/Spark-Vault/sdk-js)
719
+ - [npm Package](https://www.npmjs.com/package/@sparkvault/sdk)
720
+ - [Report Issues](https://github.com/Spark-Vault/sdk-js/issues)