w3pk 0.9.2 → 0.9.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.
@@ -2308,11 +2308,23 @@ const hybridBackup = await w3pk.createBackupFile('hybrid', 'MySecurePassword123!
2308
2308
 
2309
2309
  ---
2310
2310
 
2311
- ### `setupSocialRecovery(guardians: Guardian[], threshold: number): Promise<Guardian[]>`
2311
+ ## Social Recovery API
2312
2312
 
2313
- Set up social recovery with M-of-N guardian shares using Shamir Secret Sharing.
2313
+ Social recovery is handled by the `SocialRecoveryManager` class, which splits password-encrypted backup files into guardian shares using Shamir Secret Sharing.
2314
+
2315
+ ### Import
2316
+
2317
+ ```typescript
2318
+ import { SocialRecoveryManager } from 'w3pk';
2319
+ ```
2320
+
2321
+ ### `SocialRecoveryManager.setupSocialRecovery(backupFileJson: string, ethereumAddress: string, guardians: Guardian[], threshold: number): Promise<Guardian[]>`
2322
+
2323
+ Set up social recovery by splitting an encrypted backup file among guardians.
2314
2324
 
2315
2325
  **Parameters:**
2326
+ - `backupFileJson: string` - Password-encrypted backup file JSON
2327
+ - `ethereumAddress: string` - Ethereum address for verification
2316
2328
  - `guardians: Guardian[]`
2317
2329
  ```typescript
2318
2330
  interface Guardian {
@@ -2323,15 +2335,27 @@ Set up social recovery with M-of-N guardian shares using Shamir Secret Sharing.
2323
2335
  ```
2324
2336
  - `threshold: number` - Number of guardians required to recover (M in M-of-N)
2325
2337
 
2326
- **Returns:** Array of guardians with encrypted shares
2338
+ **Returns:** Array of guardians with encrypted share fragments
2327
2339
 
2328
- **Security:** Forces fresh authentication
2340
+ **Security:**
2341
+ - Guardians receive fragments of an already-encrypted backup file
2342
+ - Password is never shared with guardians
2343
+ - Requires both threshold shares + password to recover
2329
2344
 
2330
2345
  **Example:**
2331
2346
 
2332
2347
  ```typescript
2333
- // Setup 3-of-5 social recovery
2334
- const guardians = await w3pk.setupSocialRecovery(
2348
+ import { SocialRecoveryManager } from 'w3pk';
2349
+
2350
+ // Step 1: Create password-encrypted backup file
2351
+ const { blob } = await w3pk.createBackupFile('password', 'MySecurePassword123!');
2352
+ const backupFileJson = await blob.text();
2353
+
2354
+ // Step 2: Setup social recovery with 3-of-5 threshold
2355
+ const socialRecovery = new SocialRecoveryManager();
2356
+ const guardians = await socialRecovery.setupSocialRecovery(
2357
+ backupFileJson,
2358
+ w3pk.user.ethereumAddress,
2335
2359
  [
2336
2360
  { name: 'Alice', email: 'alice@example.com' },
2337
2361
  { name: 'Bob', phone: '+1234567890' },
@@ -2340,19 +2364,19 @@ const guardians = await w3pk.setupSocialRecovery(
2340
2364
  { name: 'Eve', email: 'eve@example.com' }
2341
2365
  ],
2342
2366
  3 // Need 3 guardians to recover
2343
- )
2367
+ );
2344
2368
 
2345
- console.log('Social recovery configured with', guardians.length, 'guardians')
2369
+ console.log('Social recovery configured with', guardians.length, 'guardians');
2346
2370
  ```
2347
2371
 
2348
2372
  ---
2349
2373
 
2350
- ### `generateGuardianInvite(guardianId: string): Promise<GuardianInvite>`
2374
+ ### `SocialRecoveryManager.generateGuardianInvite(guardian: Guardian): Promise<GuardianInvite>`
2351
2375
 
2352
- Generate invitation for a guardian with their recovery share.
2376
+ Generate invitation for a guardian with their encrypted share fragment.
2353
2377
 
2354
2378
  **Parameters:**
2355
- - `guardianId: string` - Guardian ID
2379
+ - `guardian: Guardian` - Guardian object with share
2356
2380
 
2357
2381
  **Returns:**
2358
2382
 
@@ -2360,57 +2384,89 @@ Generate invitation for a guardian with their recovery share.
2360
2384
  interface GuardianInvite {
2361
2385
  guardianId: string;
2362
2386
  qrCode: string; // Data URL for QR code
2363
- shareCode: string; // Text code for manual entry
2387
+ shareCode: string; // JSON string for manual entry
2364
2388
  explainer: string; // Educational text for guardian
2365
- link?: string; // Optional deep link
2366
2389
  }
2367
2390
  ```
2368
2391
 
2369
2392
  **Example:**
2370
2393
 
2371
2394
  ```typescript
2372
- const invite = await w3pk.generateGuardianInvite(guardian.id)
2395
+ const socialRecovery = new SocialRecoveryManager();
2396
+
2397
+ for (const guardian of guardians) {
2398
+ const invite = await socialRecovery.generateGuardianInvite(guardian);
2399
+
2400
+ // Show QR code to guardian
2401
+ console.log('QR code:', invite.qrCode);
2402
+ console.log('Share code:', invite.shareCode);
2403
+ console.log('Instructions:', invite.explainer);
2373
2404
 
2374
- // Show QR code to guardian
2375
- console.log('Show this QR code to guardian:', invite.qrCode)
2376
- console.log('Or share this code:', invite.shareCode)
2377
- console.log('Instructions:', invite.explainer)
2405
+ // Send via email, messaging app, etc.
2406
+ }
2378
2407
  ```
2379
2408
 
2380
2409
  ---
2381
2410
 
2382
- ### `recoverFromGuardians(shares: string[]): Promise<RecoveryResult>`
2411
+ ### `SocialRecoveryManager.recoverFromGuardians(shares: string[]): Promise<{ backupFileJson: string; ethereumAddress: string }>`
2383
2412
 
2384
- Recover wallet from guardian shares (Shamir Secret Sharing).
2413
+ Reconstruct encrypted backup file from guardian shares.
2385
2414
 
2386
2415
  **Parameters:**
2387
- - `shares: string[]` - Array of share data from guardians (JSON strings)
2416
+ - `shares: string[]` - Array of share codes from guardians (JSON strings)
2388
2417
 
2389
2418
  **Returns:**
2390
2419
 
2391
2420
  ```typescript
2392
- interface RecoveryResult {
2393
- mnemonic: string;
2394
- ethereumAddress: string;
2421
+ {
2422
+ backupFileJson: string; // Reconstructed encrypted backup file
2423
+ ethereumAddress: string; // Ethereum address from backup
2395
2424
  }
2396
2425
  ```
2397
2426
 
2398
2427
  **Example:**
2399
2428
 
2400
2429
  ```typescript
2401
- // Collect shares from 3 guardians
2430
+ import { SocialRecoveryManager } from 'w3pk';
2431
+
2432
+ const socialRecovery = new SocialRecoveryManager();
2433
+
2434
+ // Step 1: Collect shares from 3+ guardians
2402
2435
  const shares = [
2403
- aliceShare, // JSON string from Alice
2404
- bobShare, // JSON string from Bob
2405
- charlieShare // JSON string from Charlie
2406
- ]
2436
+ aliceShareCode, // JSON string from Alice
2437
+ bobShareCode, // JSON string from Bob
2438
+ charlieShareCode // JSON string from Charlie
2439
+ ];
2407
2440
 
2408
- const { mnemonic, ethereumAddress } = await w3pk.recoverFromGuardians(shares)
2409
- console.log('Wallet recovered:', ethereumAddress)
2410
- console.log('Mnemonic:', mnemonic)
2441
+ // Step 2: Reconstruct encrypted backup file
2442
+ const { backupFileJson, ethereumAddress } = await socialRecovery.recoverFromGuardians(shares);
2443
+ console.log('Backup file reconstructed for:', ethereumAddress);
2444
+
2445
+ // Step 3: Decrypt with password and register
2446
+ const password = 'MySecurePassword123!'; // Password set during setup
2447
+ await w3pk.registerWithBackupFile(backupFileJson, password, 'username');
2448
+ console.log('Wallet recovered and registered!');
2449
+ ```
2450
+
2451
+ ---
2411
2452
 
2412
- // Now import the mnemonic
2413
- await w3pk.importMnemonic(mnemonic)
2453
+ ### `SocialRecoveryManager.getSocialRecoveryConfig(): SocialRecoveryConfig | null`
2454
+
2455
+ Get current social recovery configuration from localStorage.
2456
+
2457
+ **Returns:** Social recovery configuration or null if not set up
2458
+
2459
+ **Example:**
2460
+
2461
+ ```typescript
2462
+ const socialRecovery = new SocialRecoveryManager();
2463
+ const config = socialRecovery.getSocialRecoveryConfig();
2464
+
2465
+ if (config) {
2466
+ console.log('Threshold:', config.threshold);
2467
+ console.log('Total guardians:', config.totalGuardians);
2468
+ console.log('Guardians:', config.guardians);
2469
+ }
2414
2470
  ```
2415
2471
 
2416
2472
  ---
package/docs/RECOVERY.md CHANGED
@@ -264,15 +264,25 @@ await sdk.importFromSync(syncData);
264
264
 
265
265
  ### **3. Social Recovery**
266
266
 
267
- **Purpose**: Distribute encrypted wallet data among trusted guardians using Shamir Secret Sharing (M-of-N)
267
+ **Purpose**: Distribute encrypted backup file fragments among trusted guardians using Shamir Secret Sharing (M-of-N)
268
268
 
269
269
  **Setup (3-of-5 example):**
270
270
  ```typescript
271
+ import { SocialRecoveryManager } from 'w3pk';
272
+
271
273
  const sdk = createWeb3Passkey();
272
274
  await sdk.login();
273
275
 
274
- // Create encrypted backup and split among guardians
275
- const { guardianShares } = await sdk.setupSocialRecovery(
276
+ // Step 1: Create password-encrypted backup file
277
+ const password = 'MySecurePassword123!'; // User must remember this
278
+ const { blob } = await sdk.createBackupFile('password', password);
279
+ const backupFileJson = await blob.text();
280
+
281
+ // Step 2: Split backup file among guardians
282
+ const socialRecovery = new SocialRecoveryManager();
283
+ const guardians = await socialRecovery.setupSocialRecovery(
284
+ backupFileJson, // Encrypted backup file JSON
285
+ sdk.user.ethereumAddress,
276
286
  [
277
287
  { name: 'Alice', email: 'alice@example.com' },
278
288
  { name: 'Bob', email: 'bob@example.com' },
@@ -280,84 +290,61 @@ const { guardianShares } = await sdk.setupSocialRecovery(
280
290
  { name: 'David', email: 'david@example.com' },
281
291
  { name: 'Eve', email: 'eve@example.com' },
282
292
  ],
283
- 3, // threshold: need 3 shares to recover
284
- 'OptionalPassword' // encrypts backup before splitting
293
+ 3 // threshold: need 3 shares to recover
285
294
  );
286
295
 
287
- // Generate invitation for each guardian
288
- for (const share of guardianShares) {
289
- const invitation = await sdk.generateGuardianInvite(share);
290
- // Send invitation.downloadBlob or invitation.qrCodeDataURL to guardian
296
+ // Step 3: Generate invitation for each guardian
297
+ for (const guardian of guardians) {
298
+ const invite = await socialRecovery.generateGuardianInvite(guardian);
299
+ // Send invite.qrCode and invite.explainer to guardian
300
+ // Guardian stores their share safely (password manager, etc.)
291
301
  }
292
302
  ```
293
303
 
294
- **Recover Wallet (Two Options):**
295
-
296
- **Option 1: Recover and register new passkey (recommended for lost devices)**
304
+ **Recover Wallet:**
297
305
  ```typescript
306
+ import { SocialRecoveryManager } from 'w3pk';
307
+
298
308
  const sdk = createWeb3Passkey();
309
+ const socialRecovery = new SocialRecoveryManager();
299
310
 
300
311
  // Step 1: Collect shares from 3+ guardians
301
- const shares = [aliceShare, bobShare, charlieShare];
312
+ const shares = [aliceShareCode, bobShareCode, charlieShareCode];
302
313
 
303
- // Step 2: Combine shares and decrypt to get mnemonic and address
304
- const { mnemonic, ethereumAddress } = await sdk.recoverFromGuardians(
305
- shares,
306
- 'OptionalPassword' // password used during setupSocialRecovery (if any)
307
- );
314
+ // Step 2: Reconstruct encrypted backup file from shares
315
+ const { backupFileJson, ethereumAddress } = await socialRecovery.recoverFromGuardians(shares);
308
316
 
309
- // Step 3: Create a new password-protected backup from recovered mnemonic
310
- const { BackupFileManager } = await import('w3pk/backup/backup-file');
311
- const manager = new BackupFileManager();
312
- const { backupFile } = await manager.createPasswordBackup(
313
- mnemonic,
314
- ethereumAddress,
315
- 'NewPassword123!' // Choose a new password
316
- );
317
+ // Step 3: Decrypt backup file with password
318
+ const password = prompt('Enter your backup password');
317
319
 
318
- // Step 4: Register new passkey using the backup
319
- const backupData = JSON.stringify(backupFile);
320
- await sdk.registerWithBackupFile(backupData, 'NewPassword123!', 'username');
320
+ // Step 4: Register new passkey with recovered backup file
321
+ await sdk.registerWithBackupFile(backupFileJson, password, 'username');
321
322
  // Now logged in with new passkey, credentials stored locally ✅
322
323
  ```
323
324
 
324
- **Option 2: Recover and import to existing passkey**
325
- ```typescript
326
- const sdk = createWeb3Passkey();
327
-
328
- // Step 1: Login with existing WebAuthn credential
329
- await sdk.login();
330
-
331
- // Step 2: Collect shares and recover mnemonic
332
- const shares = [aliceShare, bobShare, charlieShare];
333
- const { mnemonic } = await sdk.recoverFromGuardians(
334
- shares,
335
- 'OptionalPassword'
336
- );
337
-
338
- // Step 3: Import mnemonic to current logged-in user
339
- await sdk.importMnemonic(mnemonic);
340
- // Credentials stored locally under current passkey ✅
341
- ```
342
-
343
325
  **Encryption**:
344
- 1. Create BackupFile (password/passkey encrypted)
345
- 2. Serialize to JSON
346
- 3. Split using Shamir Secret Sharing (M-of-N)
347
- 4. Each guardian gets one share
326
+ 1. User creates password-encrypted BackupFile (AES-256-GCM)
327
+ 2. Serialize BackupFile to JSON
328
+ 3. Split JSON using Shamir Secret Sharing (M-of-N threshold)
329
+ 4. Each guardian gets one encrypted fragment
330
+ 5. Recovery requires: threshold shares + original password
348
331
 
349
332
  **Use Case**: Forgot password, lost all devices, ultimate safety net
350
333
 
351
- **Security**: No single guardian can recover wallet alone
334
+ **Security**: No single guardian can recover wallet alone. Guardians hold fragments of an already-encrypted backup file.
352
335
 
353
336
  **Pros:**
354
337
  - ✅ No single point of failure
338
+ - ✅ Double encryption: backup is encrypted, then fragments are distributed
339
+ - ✅ Guardians never see plaintext wallet data
340
+ - ✅ Password protection even after collecting shares
355
341
  - ✅ Survives your own forgetfulness
356
342
  - ✅ Survives any 2 guardians disappearing
357
343
  - ✅ Highest security and redundancy
358
344
 
359
345
  **Cons:**
360
346
  - ⚠️ Requires trusted friends/family
347
+ - ⚠️ Must remember password (guardians don't have it)
361
348
  - ⚠️ Setup complexity
362
349
  - ⚠️ Recovery takes time (24-48 hours)
363
350
  - ⚠️ Coordination required
@@ -365,9 +352,10 @@ await sdk.importMnemonic(mnemonic);
365
352
  **Recovery scenarios:**
366
353
  | Scenario | Can Recover? | How |
367
354
  |----------|--------------|-----|
368
- | Forgot password + lost devices | ✅ Yes | Contact 3 guardians → combine shares |
369
- | Lost backup + lost passkey | ✅ Yes | Contact 3 guardians |
355
+ | Lost all devices | ✅ Yes | Contact 3 guardians → combine shares → enter password |
356
+ | Lost backup + lost passkey | ✅ Yes | Contact 3 guardians → reconstruct backup file → enter password |
370
357
  | 2 guardians unavailable | ✅ Yes | Still have 3 others |
358
+ | Forgot password + have shares | ❌ No | Backup file is encrypted with password |
371
359
  | All guardians lost shares | ❌ No | Need another recovery layer |
372
360
 
373
361
  ---
@@ -396,45 +384,81 @@ await sdk.importMnemonic(mnemonic);
396
384
  ### **Social Recovery Cryptography**
397
385
 
398
386
  ```typescript
399
- Shamir Secret Sharing Algorithm:
387
+ Backup File-Based Shamir Secret Sharing:
400
388
 
401
389
  Example: 3-of-5 scheme
402
- - Split secret S into 5 shares: s1, s2, s3, s4, s5
403
- - Any 3 shares can reconstruct S
404
- - Any 2 shares reveal ZERO information about S
405
- - Each guardian only has an encrypted piece
390
+
391
+ Step 1: Create Encrypted Backup File
392
+ - User creates password-encrypted backup file
393
+ - Backup contains: { encryptedMnemonic, ethereumAddress, ... }
394
+ - Encryption: PBKDF2(password) → AES-256-GCM
395
+ - Result: BackupFile JSON (already encrypted)
396
+
397
+ Step 2: Split Backup File
398
+ - Serialize BackupFile to JSON string
399
+ - Convert JSON to bytes
400
+ - Split bytes using Shamir Secret Sharing (3-of-5)
401
+ - Result: 5 shares of encrypted data
402
+
403
+ Step 3: Distribute Shares
404
+ - Each guardian gets one share (hex-encoded fragment)
405
+ - Shares are fragments of the encrypted backup file
406
+ - Guardians never see the plaintext mnemonic
407
+ - Guardians don't have the password
408
+
409
+ Recovery Process:
410
+ - Collect 3+ shares from guardians
411
+ - Combine shares → reconstruct BackupFile JSON
412
+ - Decrypt with password → extract mnemonic
413
+ - Register new passkey or import to existing
406
414
 
407
415
  Mathematical basis:
408
- - Polynomial interpolation over finite field
416
+ - Polynomial interpolation over finite field GF(256)
409
417
  - Degree = threshold - 1 (e.g., degree-2 polynomial for 3-of-5)
410
418
  - Points on polynomial = shares
411
- - Reconstruct polynomial with 3 points → get secret
419
+ - Any 3 points → reconstruct polynomial → recover secret
420
+ - Any 2 points → mathematically impossible to recover
421
+ ```
422
+
423
+ **Security Model:**
424
+ ```
425
+ Double Encryption:
426
+ Layer 1: Backup file encrypted with password (AES-256-GCM)
427
+ Layer 2: Encrypted backup split into shares (Shamir)
428
+
429
+ Result:
430
+ - Guardians hold fragments of encrypted data
431
+ - Even with threshold shares, password still required
432
+ - No single guardian has access to wallet
433
+ - No collusion of guardians can bypass password
412
434
 
413
- Share encryption:
414
- Each share is encrypted with guardian's public key:
415
- - Guardian generates key pair (on their device)
416
- - Share encrypted with guardian's public key
417
- - Only guardian can decrypt their share
418
- - Prevents share theft from coordinator
435
+ Attack Scenarios:
436
+ Attacker steals 2 shares Cannot reconstruct
437
+ Attacker steals 3+ shares Still needs password
438
+ Attacker has password Still needs threshold shares
439
+ Attacker has password + threshold shares → Can recover
419
440
  ```
420
441
 
421
442
  **Trust model:**
422
443
  ```
423
444
  Coordinator (You):
445
+ - Must remember password (guardians don't have it)
424
446
  - Cannot recover from less than threshold shares
425
- - Can revoke/replace guardians
426
- - Can update threshold
447
+ - Can revoke/replace guardians (requires new setup)
448
+ - Can verify guardian shares are distributed
427
449
 
428
450
  Guardians:
429
- - Cannot recover alone
430
- - Cannot collude unless threshold met
451
+ - Hold encrypted fragments only
452
+ - Cannot decrypt without password
453
+ - Cannot recover alone (need threshold + password)
431
454
  - Can verify share validity
432
- - Can export/backup their share
455
+ - Can store share safely (it's already encrypted)
433
456
 
434
457
  Attacker:
435
458
  - Cannot recover with < threshold shares
436
- - Cannot brute-force (mathematically secure)
437
- - Must compromise guardians directly
459
+ - Cannot decrypt backup without password
460
+ - Must compromise both guardians AND password
461
+ - Mathematically secure (Shamir + AES-256-GCM)
438
462
  ```
439
463
 
440
464
  ---
@@ -485,24 +509,36 @@ await w3pk.importFromSync(backupData);
485
509
  ### Social Recovery
486
510
 
487
511
  ```typescript
488
- // Setup
489
- const { guardianShares } = await w3pk.setupSocialRecovery(guardians, threshold, password);
512
+ import { SocialRecoveryManager } from 'w3pk';
490
513
 
491
- // Generate invitations
492
- const invitation = await w3pk.generateGuardianInvite(guardianShare);
514
+ // Setup - Create password-encrypted backup and split among guardians
515
+ const { blob } = await w3pk.createBackupFile('password', 'MyPassword123!');
516
+ const backupFileJson = await blob.text();
493
517
 
494
- // Recover (returns mnemonic - then register or import)
495
- const { mnemonic, ethereumAddress } = await w3pk.recoverFromGuardians(shares, password);
518
+ const socialRecovery = new SocialRecoveryManager();
519
+ const guardians = await socialRecovery.setupSocialRecovery(
520
+ backupFileJson,
521
+ w3pk.user.ethereumAddress,
522
+ [
523
+ { name: 'Alice', email: 'alice@example.com' },
524
+ { name: 'Bob', email: 'bob@example.com' },
525
+ { name: 'Charlie', email: 'charlie@example.com' }
526
+ ],
527
+ 2 // threshold
528
+ );
496
529
 
497
- // Option 1: Register new passkey (stores credentials)
498
- const { BackupFileManager } = await import('w3pk/backup/backup-file');
499
- const manager = new BackupFileManager();
500
- const { backupFile } = await manager.createPasswordBackup(mnemonic, ethereumAddress, 'newpass');
501
- await w3pk.registerWithBackupFile(JSON.stringify(backupFile), 'newpass', 'username');
530
+ // Generate invitations for guardians
531
+ for (const guardian of guardians) {
532
+ const invite = await socialRecovery.generateGuardianInvite(guardian);
533
+ // Send invite.qrCode and invite.shareCode to guardian
534
+ }
502
535
 
503
- // Option 2: Import to existing passkey (stores credentials)
504
- await w3pk.login();
505
- await w3pk.importMnemonic(mnemonic);
536
+ // Recover - Collect shares and reconstruct encrypted backup file
537
+ const shares = [aliceShareCode, bobShareCode]; // JSON strings from guardians
538
+ const { backupFileJson, ethereumAddress } = await socialRecovery.recoverFromGuardians(shares);
539
+
540
+ // Decrypt and register with password
541
+ await w3pk.registerWithBackupFile(backupFileJson, 'MyPassword123!', 'username');
506
542
  ```
507
543
 
508
544
  ---
@@ -705,17 +741,20 @@ Platform-specific:
705
741
  3. Contact your guardians (need 3 of 5)
706
742
  4. Each guardian provides their share:
707
743
  - Scan QR code, OR
708
- - Enter share code manually
709
- 5. After 3 shares collected:
710
- - System reconstructs backup file
711
- - Enter password if used during setup
712
- - System extracts mnemonic
713
- 6. Choose recovery path:
714
- - "Register New Passkey" Creates new WebAuthn credential, stores locally ✅
715
- - "Login & Import"Login with existing passkey, import mnemonic
744
+ - Paste share code manually (JSON format)
745
+ 5. After collecting threshold shares (e.g., 3):
746
+ - System reconstructs encrypted backup file
747
+ - Backup file is still encrypted
748
+ 6. Enter your password:
749
+ - This is the password you set during social recovery setup
750
+ - Guardians DO NOT have this password
751
+ - System decrypts backup file extracts mnemonic
752
+ 7. Choose username and register:
753
+ - System creates new passkey on your device
754
+ - Wallet credentials stored locally ✅
716
755
 
717
756
  Timeline: ~24-48 hours (depends on guardian availability)
718
- Note: Either path stores credentials locally after recovery
757
+ Security: Requires both guardian shares AND your password
719
758
  ```
720
759
 
721
760
  #### **Method 4: Manual Mnemonic Import**
@@ -764,7 +803,7 @@ A: You'll need to use another recovery method (passkey sync or social recovery).
764
803
  A: Mathematically secure with Shamir's Secret Sharing. Any 2 guardians cannot recover (need 3 of 5).
765
804
 
766
805
  **Q: Can guardians steal my wallet?**
767
- A: No, each guardian only has an encrypted piece. They need 3 pieces minimum, and even then, the backup may be password-protected.
806
+ A: No. Guardians hold encrypted fragments of an already-encrypted backup file. Even if they collude and combine all shares, they still need your password to decrypt the backup file. The password is never shared with guardians.
768
807
 
769
808
  **Q: What happens if a guardian loses their share?**
770
809
  A: No problem! You only need 3 out of 5. As long as 3 guardians have their shares, you can recover.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "w3pk",
3
- "version": "0.9.2",
3
+ "version": "0.9.3",
4
4
  "description": "WebAuthn SDK for passwordless authentication, encrypted wallets, ERC-5564 stealth addresses, and zero-knowledge proofs",
5
5
  "author": "Julien Béranger",
6
6
  "license": "GPL-3.0",