w3pk 0.10.5 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +47 -46
  2. package/dist/chainlist/index.d.mts +2 -2
  3. package/dist/chainlist/index.d.ts +2 -2
  4. package/dist/chainlist/index.js.map +1 -1
  5. package/dist/chainlist/index.mjs.map +1 -1
  6. package/dist/index.d.mts +891 -745
  7. package/dist/index.d.ts +891 -745
  8. package/dist/index.js +1132 -440
  9. package/dist/index.js.map +1 -1
  10. package/dist/index.mjs +1132 -440
  11. package/dist/index.mjs.map +1 -1
  12. package/dist/zk/index.d.mts +177 -4
  13. package/dist/zk/index.d.ts +177 -4
  14. package/dist/zk/index.js +5 -5
  15. package/dist/zk/index.js.map +1 -1
  16. package/dist/zk/index.mjs +5 -5
  17. package/dist/zk/index.mjs.map +1 -1
  18. package/dist/zk/prove-worker.mjs.map +1 -0
  19. package/dist/zk/utils.js +3 -3
  20. package/dist/zk/utils.js.map +1 -1
  21. package/dist/zk/utils.mjs +3 -3
  22. package/dist/zk/utils.mjs.map +1 -1
  23. package/docs/API_REFERENCE.md +509 -636
  24. package/docs/ARCHITECTURE.md +86 -106
  25. package/docs/BUILD_VERIFICATION.md +35 -8
  26. package/docs/EIP-7951.md +1 -8
  27. package/docs/EIP_7702.md +35 -395
  28. package/docs/INTEGRATION_GUIDELINES.md +44 -515
  29. package/docs/JUNE_9_2026_AUDIT.md +207 -0
  30. package/docs/PORTABILITY.md +41 -186
  31. package/docs/POST_QUANTUM.md +61 -39
  32. package/docs/RECOVERY.md +165 -173
  33. package/docs/SECURITY.md +301 -755
  34. package/docs/ZK.md +250 -0
  35. package/package.json +27 -22
  36. package/dist/chainlist/index.js +0 -2
  37. package/dist/chainlist/index.mjs +0 -2
  38. package/docs/notes/IFRAME_IMPLEMENTATION_PLAN.md +0 -197
  39. package/docs/notes/JULY_13_ROADMAP.md +0 -29
  40. package/docs/notes/NOTES.md +0 -333
  41. package/docs/notes/SIWE_IMPLEMENTATION.md +0 -129
  42. package/docs/notes/SYNCING_ACROSS_DEVICES.md +0 -127
  43. package/docs/notes/ethereum-post-quantum-roadmap.md +0 -213
  44. package/docs/notes/old-computer.md +0 -99
  45. package/docs/notes/wulong-building-finding.md +0 -109
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { ethers } from 'ethers';
1
+ import { TypedDataDomain, ethers } from 'ethers';
2
2
 
3
3
  /**
4
4
  * ERC-5564 Stealth Address Cryptography
@@ -41,8 +41,6 @@ interface ParseResult {
41
41
  isForUser: boolean;
42
42
  /** The stealth address (only if isForUser is true) */
43
43
  stealthAddress?: string;
44
- /** The stealth private key (only if isForUser is true) */
45
- stealthPrivateKey?: string;
46
44
  }
47
45
  /**
48
46
  * Derive ERC-5564 compliant stealth keys from w3pk mnemonic using HD paths
@@ -85,7 +83,7 @@ declare function generateStealthAddress(stealthMetaAddress: string): StealthAddr
85
83
  * @param ephemeralPubKey - Ephemeral public key from announcement
86
84
  * @param stealthAddress - The stealth address to check
87
85
  * @param viewTag - View tag from announcement (optional, for optimization)
88
- * @returns ParseResult with stealth address and private key if it belongs to user
86
+ * @returns ParseResult with the stealth address if it belongs to the user
89
87
  */
90
88
  declare function checkStealthAddress(viewingKey: string, spendingPubKey: string, ephemeralPubKey: string, stealthAddress: string, viewTag?: string): ParseResult;
91
89
  /**
@@ -124,9 +122,11 @@ declare function canControlStealthAddress(viewingKey: string, spendingKey: strin
124
122
  * - Stealth addresses use SEPARATE derivation paths from the main wallet
125
123
  * - Viewing key: m/44'/60'/1'/0/0 (for scanning announcements)
126
124
  * - Spending key: m/44'/60'/1'/0/1 (for spending stealth funds)
127
- * - Applications that opt-in to stealth addresses WILL have access to stealth private keys
128
- * - This is REQUIRED for ERC-5564 compliance (to parse announcements and spend funds)
125
+ * - Applications that opt-in to stealth addresses get the viewing key, never the
126
+ * spending key or the private key of a stealth address; w3pk signs from
127
+ * stealth addresses itself
129
128
  * - Stealth keys are NOT derived from the main wallet's MAIN tag
129
+ * - Stealth keys are shared across origins: every app gets the same meta-address
130
130
  * - This module is OPT-IN only (must explicitly enable in SDK config)
131
131
  *
132
132
  * @see https://eips.ethereum.org/EIPS/eip-5564
@@ -164,8 +164,19 @@ interface ParseAnnouncementResult {
164
164
  isForUser: boolean;
165
165
  /** The stealth address (only if isForUser is true) */
166
166
  stealthAddress?: string;
167
- /** The stealth private key for spending (only if isForUser is true) */
168
- stealthPrivateKey?: string;
167
+ }
168
+ /**
169
+ * EIP-1559 transaction to sign from a stealth address
170
+ */
171
+ interface StealthTransaction {
172
+ to: string;
173
+ value?: bigint;
174
+ data?: string;
175
+ chainId: number;
176
+ nonce: number;
177
+ gasLimit: bigint;
178
+ maxFeePerGas: bigint;
179
+ maxPriorityFeePerGas: bigint;
169
180
  }
170
181
  /**
171
182
  * ERC-5564 Stealth Address Module
@@ -175,11 +186,18 @@ interface ParseAnnouncementResult {
175
186
  * By using this module, applications will have access to:
176
187
  * - Stealth meta-address (safe to share publicly)
177
188
  * - Viewing private key (required for scanning announcements)
178
- * - Spending private key (required for spending stealth funds)
179
- * - Computed stealth private keys (required for accessing received stealth payments)
180
- *
181
- * This is INTENTIONAL and REQUIRED for ERC-5564 stealth address functionality.
182
- * Stealth keys are derived from separate HD paths (not from main wallet).
189
+ * - Transactions signed from stealth addresses with `signTransaction()`, each
190
+ * after a fresh passkey assertion
191
+ *
192
+ * The spending key and stealth private keys never leave the SDK: a stealth
193
+ * private key plus the viewing key would give back the spending key (stealth
194
+ * key = spending key + hash of the shared secret). The viewing key lets an app
195
+ * see every stealth payment to the user, and an app with this module enabled
196
+ * can ask w3pk to sign from a stealth address, which prompts for the passkey
197
+ * every time. Stealth keys are derived from separate HD paths (not from main wallet)
198
+ * and are the same for every origin, so any app that enables this module sees
199
+ * the same viewing key and meta-address; scoping them per origin would change
200
+ * the meta-address and strand funds already sent to it.
183
201
  */
184
202
  declare class StealthAddressModule {
185
203
  private getMnemonic;
@@ -202,7 +220,7 @@ declare class StealthAddressModule {
202
220
  * @param announcement - The announcement to parse (from on-chain event)
203
221
  * @param options - Optional configuration
204
222
  * @param options.requireAuth - If true, force fresh authentication even if session is active
205
- * @returns ParseResult indicating if announcement is for user, plus stealth private key if true
223
+ * @returns ParseResult indicating if announcement is for user, plus the stealth address if true
206
224
  */
207
225
  parseAnnouncement(announcement: Announcement, options?: {
208
226
  requireAuth?: boolean;
@@ -214,21 +232,35 @@ declare class StealthAddressModule {
214
232
  * @param announcements - Array of announcements to scan
215
233
  * @param options - Optional configuration
216
234
  * @param options.requireAuth - If true, force fresh authentication even if session is active
217
- * @returns Array of announcements that belong to the user with their private keys
235
+ * @returns Array of announcements that belong to the user
218
236
  */
219
237
  scanAnnouncements(announcements: Announcement[], options?: {
220
238
  requireAuth?: boolean;
221
239
  }): Promise<ParseAnnouncementResult[]>;
240
+ /**
241
+ * Sign an EIP-1559 transaction from a stealth address found for the user
242
+ * The stealth private key is derived and used inside the SDK, never returned.
243
+ * Every call runs a fresh passkey assertion, even with an active session.
244
+ * The transaction is signed, not sent: broadcast it with your own RPC
245
+ * (`eth_sendRawTransaction`).
246
+ *
247
+ * @param announcement - The announcement of the stealth address to sign from
248
+ * @param tx - Fully populated transaction (nonce, gas limit and fees included)
249
+ * @returns The serialized signed transaction
250
+ */
251
+ signTransaction(announcement: Announcement, tx: StealthTransaction): Promise<string>;
222
252
  /**
223
253
  * Get ERC-5564 stealth keys
224
- * Returns the stealth meta-address and private keys
254
+ * Returns the stealth meta-address, both public keys and the viewing key;
255
+ * the spending private key is never returned. The keys are the same for
256
+ * every origin.
225
257
  *
226
258
  * @param options - Optional configuration
227
259
  * @param options.requireAuth - If true, force fresh authentication even if session is active
228
260
  */
229
261
  getKeys(options?: {
230
262
  requireAuth?: boolean;
231
- }): Promise<StealthKeys>;
263
+ }): Promise<Omit<StealthKeys, "spendingKey">>;
232
264
  /**
233
265
  * Get the stealth meta-address for receiving funds
234
266
  * This is what you share publicly for others to send you stealth payments
@@ -252,6 +284,7 @@ interface PrfExtensionResults {
252
284
  enabled?: boolean;
253
285
  results?: {
254
286
  first?: ArrayBuffer;
287
+ second?: ArrayBuffer;
255
288
  };
256
289
  };
257
290
  }
@@ -287,17 +320,368 @@ interface PrfSecret {
287
320
  credentialId: string;
288
321
  }
289
322
 
323
+ /**
324
+ * Semaphore v4 identities bound to a passkey
325
+ */
326
+ interface SemaphoreIdentity {
327
+ /** Poseidon(publicKey), the member value apps add to a Semaphore group */
328
+ commitment: bigint;
329
+ /** Credential the identity is bound to; a new credential gives a new commitment */
330
+ credentialId: string;
331
+ }
332
+
333
+ /**
334
+ * Zero-Knowledge Proof Types
335
+ * General-purpose ZK proof system for privacy-preserving assertions
336
+ */
337
+ interface ZKProofConfig {
338
+ /**
339
+ * Enable/disable specific proof types
340
+ */
341
+ enabledProofs?: ProofType[];
342
+ /**
343
+ * Custom circuit paths (optional)
344
+ */
345
+ customCircuits?: Record<string, CircuitArtifacts>;
346
+ }
347
+ type ProofType = "membership" | "threshold" | "range" | "equality" | "ownership" | "signature" | "nft";
348
+ interface CircuitArtifacts {
349
+ wasmPath: string;
350
+ zkeyPath: string;
351
+ verificationKey: unknown;
352
+ }
353
+ interface ZKProof {
354
+ type: ProofType;
355
+ proof: {
356
+ pi_a: string[];
357
+ pi_b: string[][];
358
+ pi_c: string[];
359
+ protocol: string;
360
+ curve: string;
361
+ };
362
+ publicSignals: string[];
363
+ timestamp: string;
364
+ }
365
+ interface VerificationResult {
366
+ valid: boolean;
367
+ type: ProofType;
368
+ publicSignals: Record<string, string>;
369
+ timestamp: string;
370
+ }
371
+ /**
372
+ * Membership Proof - Prove you're in a set without revealing which member
373
+ */
374
+ interface MembershipProofInput {
375
+ value: string;
376
+ pathIndices: number[];
377
+ pathElements: string[];
378
+ root: string;
379
+ }
380
+ /**
381
+ * Threshold Proof - Prove value exceeds threshold without revealing value
382
+ */
383
+ interface ThresholdProofInput {
384
+ value: bigint;
385
+ blinding: bigint;
386
+ threshold: bigint;
387
+ commitment: string;
388
+ }
389
+ /**
390
+ * Range Proof - Prove value is within range without revealing value
391
+ */
392
+ interface RangeProofInput {
393
+ value: bigint;
394
+ blinding: bigint;
395
+ min: bigint;
396
+ max: bigint;
397
+ commitment: string;
398
+ }
399
+ /**
400
+ * Ownership Proof - Prove you own an address without revealing private key
401
+ */
402
+ interface OwnershipProofInput {
403
+ privateKey: string;
404
+ nonce: bigint;
405
+ address: string;
406
+ challenge: string;
407
+ }
408
+ /**
409
+ * NFT Ownership Proof - Prove you own an NFT from a collection without revealing which one
410
+ */
411
+ interface NFTOwnershipProofInput {
412
+ ownerAddress: string;
413
+ holderIndex: number;
414
+ pathIndices: number[];
415
+ pathElements: string[];
416
+ holdersRoot: string;
417
+ contractAddress: string;
418
+ minBalance?: bigint;
419
+ }
420
+
421
+ /**
422
+ * Custom error classes for better error handling
423
+ */
424
+ declare class Web3PasskeyError extends Error {
425
+ code: string;
426
+ originalError?: unknown | undefined;
427
+ constructor(message: string, code: string, originalError?: unknown | undefined);
428
+ }
429
+ declare class AuthenticationError extends Web3PasskeyError {
430
+ constructor(message: string, originalError?: unknown);
431
+ }
432
+ declare class RegistrationError extends Web3PasskeyError {
433
+ constructor(message: string, originalError?: unknown);
434
+ }
435
+ declare class WalletError extends Web3PasskeyError {
436
+ constructor(message: string, originalError?: unknown);
437
+ }
438
+ declare class CryptoError extends Web3PasskeyError {
439
+ constructor(message: string, originalError?: unknown);
440
+ }
441
+ declare class StorageError extends Web3PasskeyError {
442
+ constructor(message: string, originalError?: unknown);
443
+ }
444
+ declare class ApiError extends Web3PasskeyError {
445
+ statusCode?: number | undefined;
446
+ constructor(message: string, statusCode?: number | undefined, originalError?: unknown);
447
+ }
448
+ /**
449
+ * The passkey authenticated, but this device has no credential metadata.
450
+ * The app should start a sync or restore flow.
451
+ */
452
+ declare class SyncRequiredError extends Web3PasskeyError {
453
+ credentialId: string;
454
+ constructor(credentialId: string);
455
+ }
456
+ /**
457
+ * The credential metadata is on this device, but the wallet record is gone.
458
+ * The app should offer a restore from backup.
459
+ */
460
+ declare class WalletMissingError extends Web3PasskeyError {
461
+ credentialId: string;
462
+ ethereumAddress: string;
463
+ constructor(credentialId: string, ethereumAddress: string);
464
+ }
465
+ type SyncBootstrapReason = "NO_CREDENTIAL" | "CREDENTIAL_MISMATCH" | "PUBLIC_KEY_MISMATCH";
466
+ /**
467
+ * A sync can't set up this device's passkey metadata from the backup.
468
+ */
469
+ declare class SyncBootstrapError extends Web3PasskeyError {
470
+ reason: SyncBootstrapReason;
471
+ credentialId: string;
472
+ constructor(reason: SyncBootstrapReason, credentialId: string);
473
+ }
474
+ /**
475
+ * The authenticator returned no WebAuthn PRF output, so no
476
+ * passkey-bound secret can be derived. There is no fallback.
477
+ */
478
+ declare class PrfUnsupportedError extends Web3PasskeyError {
479
+ credentialId: string;
480
+ constructor(credentialId: string);
481
+ }
482
+ /**
483
+ * The backup holds another wallet than the one this passkey opens on this
484
+ * device. Restoring it replaces that wallet, so the app must confirm it
485
+ * with the user and pass `allowAddressChange: true`.
486
+ */
487
+ declare class AddressChangeError extends Web3PasskeyError {
488
+ currentAddress: string;
489
+ newAddress: string;
490
+ constructor(currentAddress: string, newAddress: string);
491
+ }
492
+ /**
493
+ * The backup uses the removed `passkey` or `hybrid` method, whose key came
494
+ * from public data rather than from the passkey. It can't be restored.
495
+ */
496
+ declare class RemovedBackupMethodError extends Web3PasskeyError {
497
+ method: string;
498
+ constructor(method: string);
499
+ }
500
+ /**
501
+ * The backup file isn't BackupFile v3. w3pk restores v3 files only: decrypt
502
+ * an older password backup offline with the v0.10.6 extract-mnemonic tool,
503
+ * then create a new backup.
504
+ */
505
+ declare class UnsupportedBackupVersionError extends Web3PasskeyError {
506
+ version: unknown;
507
+ /** The rebuilt file, when it came from guardian shares, for the offline tool */
508
+ backupFileJson?: string;
509
+ constructor(version: unknown, method?: string);
510
+ }
511
+ /**
512
+ * The password for a password backup is too weak to resist an offline
513
+ * guess: `feedback` lists what it's missing
514
+ */
515
+ declare class WeakPasswordError extends Web3PasskeyError {
516
+ feedback: string[];
517
+ constructor(feedback: string[]);
518
+ }
519
+ type ZkArtifactName = "wasm" | "zkey";
520
+ /**
521
+ * A circuit artifact's IPFS CID doesn't match the CID pinned onchain,
522
+ * so it isn't the circuit the app chose.
523
+ */
524
+ declare class ZkArtifactMismatchError extends Web3PasskeyError {
525
+ artifact: ZkArtifactName;
526
+ expectedCid: string;
527
+ actualCid: string;
528
+ constructor(artifact: ZkArtifactName, expectedCid: string, actualCid: string);
529
+ }
530
+
531
+ /**
532
+ * Circuit artifact verification against CIDs pinned onchain
533
+ */
534
+
535
+ /** Artifact bytes, or a URL to fetch them from */
536
+ type ZkArtifactSource = ArrayBufferView | ArrayBuffer | string;
537
+ type ZkArtifactSources = Record<ZkArtifactName, ZkArtifactSource>;
538
+ /**
539
+ * IPFS CIDv1 strings in base32, as `ipfs add --cid-version 1` prints them,
540
+ * compared as exact strings
541
+ */
542
+ type ZkArtifactPins = Record<ZkArtifactName, string>;
543
+
544
+ /**
545
+ * Zero-Knowledge Proof Module for w3pk SDK
546
+ * Enables privacy-preserving proofs
547
+ */
548
+
549
+ declare class ZKProofModule {
550
+ private generator;
551
+ private verifier;
552
+ private config;
553
+ constructor(config?: ZKProofConfig);
554
+ private initializeCircuits;
555
+ /**
556
+ * Generate membership proof - prove you're in a set without revealing identity
557
+ * Use case: Prove you're a verified user without revealing which one
558
+ */
559
+ proveMembership(input: MembershipProofInput): Promise<ZKProof>;
560
+ /**
561
+ * Generate threshold proof - prove value exceeds threshold
562
+ * Use case: Prove balance > $1000 without revealing actual balance
563
+ */
564
+ proveThreshold(input: ThresholdProofInput): Promise<ZKProof>;
565
+ /**
566
+ * Generate range proof - prove value is within range
567
+ * Use case: Prove age between 18-65 without revealing exact age
568
+ */
569
+ proveRange(input: RangeProofInput): Promise<ZKProof>;
570
+ /**
571
+ * Generate ownership proof - prove you own an address
572
+ * Use case: Prove ownership without revealing private key
573
+ */
574
+ proveOwnership(input: OwnershipProofInput): Promise<ZKProof>;
575
+ /**
576
+ * Generate NFT ownership proof - prove you own an NFT from a collection
577
+ * Use case: Prove NFT/SBT ownership without revealing which NFT or exact address
578
+ */
579
+ proveNFTOwnership(input: NFTOwnershipProofInput): Promise<ZKProof>;
580
+ /**
581
+ * Verify any ZK proof
582
+ */
583
+ verify(proof: ZKProof): Promise<VerificationResult>;
584
+ /**
585
+ * Batch verify multiple proofs
586
+ */
587
+ verifyBatch(proofs: ZKProof[]): Promise<VerificationResult[]>;
588
+ /**
589
+ * Verify membership proof with expected root
590
+ */
591
+ verifyMembership(proof: ZKProof, expectedRoot: string): Promise<boolean>;
592
+ /**
593
+ * Verify threshold proof
594
+ */
595
+ verifyThreshold(proof: ZKProof, expectedCommitment: string, expectedThreshold: bigint): Promise<boolean>;
596
+ /**
597
+ * Verify range proof
598
+ */
599
+ verifyRange(proof: ZKProof, expectedCommitment: string, expectedMin: bigint, expectedMax: bigint): Promise<boolean>;
600
+ /**
601
+ * Verify ownership proof
602
+ */
603
+ verifyOwnership(proof: ZKProof, expectedAddress: string, expectedChallenge: string): Promise<boolean>;
604
+ /**
605
+ * Verify NFT ownership proof
606
+ */
607
+ verifyNFTOwnership(proof: ZKProof, expectedContract: string, expectedHoldersRoot: string, expectedMinBalance?: bigint): Promise<boolean>;
608
+ /**
609
+ * Create a Poseidon commitment for hiding values
610
+ */
611
+ createCommitment(value: bigint, blinding: bigint): Promise<string>;
612
+ /**
613
+ * Compute merkle root for membership proofs
614
+ */
615
+ computeMerkleRoot(leaf: string, pathIndices: number[], pathElements: string[]): Promise<string>;
616
+ /**
617
+ * Register a custom circuit
618
+ */
619
+ registerCircuit(type: ProofType, artifacts: CircuitArtifacts): void;
620
+ /**
621
+ * Check if proof type is enabled
622
+ */
623
+ private assertProofEnabled;
624
+ /**
625
+ * Check if ZK proofs are available
626
+ */
627
+ get isAvailable(): boolean;
628
+ }
629
+
630
+ /**
631
+ * Groth16 proofs over a passkey-bound secret the caller never sees
632
+ */
633
+
634
+ type ZkSignal = bigint | number | string | ZkSignal[];
635
+ /** Circuit inputs by signal name, as snarkjs takes them */
636
+ type ZkInputs = Record<string, ZkSignal>;
637
+ interface ZkProveArtifacts extends ZkArtifactSources {
638
+ /** CIDs the artifacts must match, e.g. from `readZkArtifactPins` */
639
+ pins: ZkArtifactPins;
640
+ }
641
+ /**
642
+ * - `"zk"`: a Baby Jubjub private key derived from the passkey under the
643
+ * `w3pk-zk-v1` label
644
+ * - `"semaphore"`: the `secretScalar` of `getSemaphoreIdentity(tag)`'s identity
645
+ */
646
+ type ZkSecretSource = "zk" | "semaphore";
647
+ /**
648
+ * A Poseidon input: a string names another input (the secret, a caller
649
+ * input, a random input or an earlier derivation), a bigint is a constant
650
+ */
651
+ type ZkDerivationTerm = string | bigint;
652
+ interface ZkProveOptions {
653
+ /** Default `"zk"` */
654
+ secret?: ZkSecretSource;
655
+ /** Circuit input that receives the secret. Default `"secret"` */
656
+ secretInput?: string;
657
+ /**
658
+ * Inputs w3pk computes as `Poseidon(terms)`, in order, e.g.
659
+ * `{ voteSecret: ["secret", "proposalId", 1n] }`. 1 to 16 terms each
660
+ */
661
+ derive?: Record<string, ZkDerivationTerm[]>;
662
+ /** Inputs w3pk fills with fresh random scalars in `[1, l)` and discards */
663
+ random?: string[];
664
+ }
665
+ interface Groth16Proof {
666
+ pi_a: string[];
667
+ pi_b: string[][];
668
+ pi_c: string[];
669
+ protocol: string;
670
+ curve: string;
671
+ }
672
+ interface ZkProveResult {
673
+ proof: Groth16Proof;
674
+ publicSignals: string[];
675
+ }
676
+
290
677
  /**
291
678
  * Shared types used across the SDK
292
679
  */
680
+
293
681
  interface UserInfo {
294
682
  username: string;
295
683
  ethereumAddress: string;
296
684
  credentialId: string;
297
- /** @deprecated Use ethereumAddress instead */
298
- id?: string;
299
- /** @deprecated Use username instead */
300
- displayName?: string;
301
685
  }
302
686
  /**
303
687
  * Security modes for origin-centric derivation
@@ -342,6 +726,8 @@ type SecurityMode = 'PRIMARY' | 'STANDARD' | 'STRICT' | 'YOLO';
342
726
  * - Sign raw 32-byte hashes without EIP-191 prefix
343
727
  * - Useful for pre-computed EIP-712 hashes or Safe transactions
344
728
  * - Message must be a 32-byte hex string (with or without 0x prefix)
729
+ * - Always requires a fresh user-verified passkey assertion: the hash could be
730
+ * an EIP-7702 authorization digest
345
731
  */
346
732
  type SigningMethod = 'EIP191' | 'SIWE' | 'EIP712' | 'rawHash';
347
733
  /**
@@ -352,15 +738,23 @@ interface SignMessageOptions {
352
738
  mode?: SecurityMode;
353
739
  tag?: string;
354
740
  requireAuth?: boolean;
355
- origin?: string;
356
741
  signingMethod?: SigningMethod;
357
- eip712Domain?: Record<string, any>;
742
+ eip712Domain?: TypedDataDomain;
358
743
  eip712Types?: Record<string, Array<{
359
744
  name: string;
360
745
  type: string;
361
746
  }>>;
362
747
  eip712PrimaryType?: string;
363
748
  }
749
+ /**
750
+ * Result of register()
751
+ */
752
+ interface RegisterResult {
753
+ address: string;
754
+ username: string;
755
+ hasBackup: boolean;
756
+ evictionRisk: boolean;
757
+ }
364
758
  /**
365
759
  * Generated wallet with mnemonic (from generateWallet)
366
760
  */
@@ -388,72 +782,6 @@ interface DerivedWallet {
388
782
  tag?: string;
389
783
  publicKey?: string;
390
784
  }
391
- /**
392
- * @deprecated Use GeneratedWallet or DerivedWallet instead
393
- */
394
- type WalletInfo = GeneratedWallet | DerivedWallet;
395
-
396
- /**
397
- * Custom error classes for better error handling
398
- */
399
- declare class Web3PasskeyError extends Error {
400
- code: string;
401
- originalError?: unknown | undefined;
402
- constructor(message: string, code: string, originalError?: unknown | undefined);
403
- }
404
- declare class AuthenticationError extends Web3PasskeyError {
405
- constructor(message: string, originalError?: unknown);
406
- }
407
- declare class RegistrationError extends Web3PasskeyError {
408
- constructor(message: string, originalError?: unknown);
409
- }
410
- declare class WalletError extends Web3PasskeyError {
411
- constructor(message: string, originalError?: unknown);
412
- }
413
- declare class CryptoError extends Web3PasskeyError {
414
- constructor(message: string, originalError?: unknown);
415
- }
416
- declare class StorageError extends Web3PasskeyError {
417
- constructor(message: string, originalError?: unknown);
418
- }
419
- declare class ApiError extends Web3PasskeyError {
420
- statusCode?: number | undefined;
421
- constructor(message: string, statusCode?: number | undefined, originalError?: unknown);
422
- }
423
- /**
424
- * The passkey authenticated, but this device has no credential metadata.
425
- * The app should start a sync or restore flow.
426
- */
427
- declare class SyncRequiredError extends Web3PasskeyError {
428
- credentialId: string;
429
- constructor(credentialId: string);
430
- }
431
- /**
432
- * The credential metadata is on this device, but the wallet record is gone.
433
- * The app should offer a restore from backup.
434
- */
435
- declare class WalletMissingError extends Web3PasskeyError {
436
- credentialId: string;
437
- ethereumAddress: string;
438
- constructor(credentialId: string, ethereumAddress: string);
439
- }
440
- type SyncBootstrapReason = "PASSKEY_BACKUP" | "NO_CREDENTIAL" | "CREDENTIAL_MISMATCH" | "PUBLIC_KEY_MISMATCH";
441
- /**
442
- * A sync can't set up this device's passkey metadata from the backup.
443
- */
444
- declare class SyncBootstrapError extends Web3PasskeyError {
445
- reason: SyncBootstrapReason;
446
- credentialId: string;
447
- constructor(reason: SyncBootstrapReason, credentialId: string);
448
- }
449
- /**
450
- * The authenticator returned no WebAuthn PRF output, so no
451
- * passkey-bound secret can be derived. There is no fallback.
452
- */
453
- declare class PrfUnsupportedError extends Web3PasskeyError {
454
- credentialId: string;
455
- constructor(credentialId: string);
456
- }
457
785
 
458
786
  /**
459
787
  * Persistent Session Storage
@@ -493,10 +821,7 @@ interface PersistentSessionConfig {
493
821
 
494
822
  interface StealthAddressConfig {
495
823
  }
496
- interface ZKProofConfig {
497
- enabledProofs?: Array<"membership" | "threshold" | "range" | "equality" | "ownership" | "signature" | "nft">;
498
- customCircuits?: Record<string, any>;
499
- }
824
+
500
825
  interface Web3PasskeyConfig {
501
826
  debug?: boolean;
502
827
  onError?: (error: Web3PasskeyError) => void;
@@ -544,20 +869,42 @@ interface Web3PasskeyConfig {
544
869
  * sign in with one click. PRF-derived secrets always require it.
545
870
  */
546
871
  userVerification?: 'required' | 'preferred';
872
+ /**
873
+ * RPC endpoints per chain ID, used before the chainid.network endpoints
874
+ * by `sendTransaction()`, `getEndpoints()` and `supportsEIP7702()`.
875
+ * A per-call `rpcUrl` still takes precedence.
876
+ *
877
+ * @example
878
+ * rpcUrls: { 1: ['https://eth.example.com'], 10: ['https://op.example.com'] }
879
+ */
880
+ rpcUrls?: Record<number, string[]>;
547
881
  }
548
882
 
549
883
  /**
550
884
  * Backup and Recovery Type Definitions
551
885
  */
552
- type BackupMethod = 'file' | 'qr' | 'phrase';
886
+
887
+ /**
888
+ * - `file`: password backup file, restores without a passkey
889
+ * - `qr`: QR backup, restores without a passkey
890
+ * - `phrase`: recovery phrase written down
891
+ * - `prf`: PRF backup from exportForSync(), restores only with the passkey
892
+ */
893
+ type BackupMethod = 'file' | 'qr' | 'phrase' | 'prf';
553
894
  interface BackupStatus {
895
+ /** A backup that restores without a passkey exists (file, QR or phrase) */
554
896
  hasBackup: boolean;
897
+ /**
898
+ * Next backup to make: `password` while no backup restores without a
899
+ * passkey (it's the one that must exist), then `prf` for convenient sync
900
+ * across devices where the passkey synced. Undefined once both exist.
901
+ */
902
+ recommendedMode?: 'password' | 'prf';
555
903
  evictionRisk: boolean;
556
904
  lastBackupAt?: string;
557
905
  methods: BackupMethod[];
558
906
  passkeySync: PasskeySyncStatus;
559
907
  recoveryPhrase: RecoveryPhraseStatus;
560
- socialRecovery?: SocialRecoveryStatus;
561
908
  securityScore: SecurityScore;
562
909
  }
563
910
  interface PasskeySyncStatus {
@@ -574,28 +921,11 @@ interface RecoveryPhraseStatus {
574
921
  }
575
922
  interface EncryptedBackupInfo {
576
923
  id: string;
577
- method: 'qr' | 'file';
924
+ method: 'qr' | 'file' | 'prf';
578
925
  location: string;
579
926
  createdAt: string;
580
927
  deviceFingerprint?: string;
581
928
  }
582
- interface SocialRecoveryStatus {
583
- enabled: boolean;
584
- guardians: Guardian$1[];
585
- threshold: number;
586
- sharesDistributed: number;
587
- verifiedGuardians: number;
588
- }
589
- interface Guardian$1 {
590
- id: string;
591
- name: string;
592
- email?: string;
593
- publicKey?: string;
594
- shareEncrypted: string;
595
- status: 'pending' | 'active' | 'revoked';
596
- addedAt: string;
597
- lastVerified?: string;
598
- }
599
929
  interface SecurityScore {
600
930
  total: number;
601
931
  breakdown: {
@@ -603,15 +933,10 @@ interface SecurityScore {
603
933
  passkeyMultiDevice: number;
604
934
  phraseVerified: number;
605
935
  encryptedBackup: number;
606
- socialRecovery: number;
607
936
  };
608
937
  level: 'vulnerable' | 'protected' | 'secured' | 'fort-knox';
609
938
  nextMilestone: string;
610
939
  }
611
- interface QRBackupOptions {
612
- password?: string;
613
- errorCorrection?: 'L' | 'M' | 'Q' | 'H';
614
- }
615
940
  interface RecoveryScenario {
616
941
  type: 'lost-device' | 'lost-phrase' | 'lost-both' | 'switch-platform';
617
942
  description: string;
@@ -630,6 +955,163 @@ interface RecoveryMethod {
630
955
  requirements: string[];
631
956
  }
632
957
 
958
+ /**
959
+ * Hybrid KEM keypair: ML-KEM-1024 and X25519, concatenated
960
+ */
961
+ interface MLKemKeypair {
962
+ publicKey: Uint8Array;
963
+ privateKey: Uint8Array;
964
+ }
965
+ interface EncryptedPayload {
966
+ version: 3;
967
+ recipients: Array<{
968
+ publicKey: string;
969
+ enc: string;
970
+ ciphertext: string;
971
+ }>;
972
+ encryptedData: string;
973
+ iv: string;
974
+ authTag: string;
975
+ }
976
+ /** Default context string for hybrid keypair derivation */
977
+ declare const MLKEM_DEFAULT_CONTEXT = "mlkem-v1";
978
+ /**
979
+ * Derive a deterministic hybrid keypair (ML-KEM-1024 + X25519) from any private key material
980
+ *
981
+ * HKDF-SHA256 extracts a PRK from the input (salt `w3pk-kem-keypair-v3`), then expands
982
+ * a 64-byte ML-KEM-1024 seed (info `ml-kem-1024:<context>`) and a 32-byte X25519 secret
983
+ * key (info `x25519:<context>`).
984
+ *
985
+ * @param privateKey - Private key material (hex string with optional 0x prefix, or Uint8Array)
986
+ * @param context - Context string for domain separation (default: MLKEM_DEFAULT_CONTEXT)
987
+ * @returns Hybrid keypair (publicKey: 1600 bytes, privateKey: 3200 bytes)
988
+ *
989
+ * @example
990
+ * ```typescript
991
+ * const keypair = await deriveMLKemKeypair('0x1234...', 'my-app');
992
+ * ```
993
+ */
994
+ declare function deriveMLKemKeypair(privateKey: string | Uint8Array, context?: string): Promise<MLKemKeypair>;
995
+ /**
996
+ * Encrypt data for one or more recipients (payload v3)
997
+ *
998
+ * The plaintext is encrypted once with AES-256-GCM under a random data key, which is
999
+ * sealed to each recipient with HPKE (RFC 9180, mode_base, HKDF-SHA256, AES-256-GCM)
1000
+ * over a hybrid ML-KEM-1024 + X25519 KEM.
1001
+ *
1002
+ * @param plaintext - The data to encrypt
1003
+ * @param publicKeys - Hybrid public keys (base64 strings or Uint8Arrays, 1600 bytes each)
1004
+ * @returns Encrypted payload with one entry per recipient
1005
+ */
1006
+ declare function mlkemEncrypt(plaintext: string, publicKeys: (string | Uint8Array) | Array<string | Uint8Array>): Promise<EncryptedPayload>;
1007
+ /**
1008
+ * Decrypt a v3 payload from mlkemEncrypt()
1009
+ *
1010
+ * The recipient entry is found by the public key derived from `privateKey`.
1011
+ * Payloads of any other version are rejected.
1012
+ *
1013
+ * @param payload - The encrypted payload
1014
+ * @param privateKey - Hybrid private key (base64 string or Uint8Array, 3200 bytes)
1015
+ * @returns Decrypted plaintext
1016
+ */
1017
+ declare function mlkemDecrypt(payload: EncryptedPayload, privateKey: string | Uint8Array): Promise<string>;
1018
+ /**
1019
+ * Encrypt with a hybrid keypair derived from private key material
1020
+ *
1021
+ * Derives the sender's keypair and adds its public key as the first recipient,
1022
+ * so the sender can decrypt later.
1023
+ *
1024
+ * @param plaintext - The data to encrypt
1025
+ * @param senderPrivateKey - Sender's private key (hex string or Uint8Array)
1026
+ * @param recipientPublicKeys - Recipient hybrid public keys (from deriveMLKemKeypair)
1027
+ * @param senderContext - Context for the sender's key derivation (default: MLKEM_DEFAULT_CONTEXT)
1028
+ * @returns Encrypted payload with sender + recipients
1029
+ */
1030
+ declare function mlkemEncryptWithKey(plaintext: string, senderPrivateKey: string | Uint8Array, recipientPublicKeys: Array<string | Uint8Array>, senderContext?: string): Promise<EncryptedPayload>;
1031
+ /**
1032
+ * Decrypt with a hybrid keypair derived from private key material
1033
+ *
1034
+ * @param payload - The encrypted payload
1035
+ * @param privateKey - Private key material (hex string or Uint8Array)
1036
+ * @param context - Context for key derivation (default: MLKEM_DEFAULT_CONTEXT)
1037
+ * @returns Decrypted plaintext
1038
+ */
1039
+ declare function mlkemDecryptWithKey(payload: EncryptedPayload, privateKey: string | Uint8Array, context?: string): Promise<string>;
1040
+
1041
+ /**
1042
+ * Cross-Device Sync Manager
1043
+ *
1044
+ * Syncs wallets across devices where passkey is already synced.
1045
+ * Use case: User has passkey on mobile and desktop, but wallet only on desktop.
1046
+ * They can export wallet data from desktop and import on mobile.
1047
+ */
1048
+
1049
+ interface DeviceSyncInfo {
1050
+ deviceName: string;
1051
+ platform: 'ios' | 'android' | 'macos' | 'windows' | 'linux' | 'unknown';
1052
+ lastSyncTime: string;
1053
+ walletsSynced: string[];
1054
+ }
1055
+
1056
+ /**
1057
+ * Cross-Device Sync Type Definitions
1058
+ */
1059
+ interface SyncCapabilities {
1060
+ passkeysSync: boolean;
1061
+ platform: 'apple' | 'google' | 'microsoft' | 'none';
1062
+ estimatedDevices: number;
1063
+ syncEnabled: boolean;
1064
+ }
1065
+
1066
+ /**
1067
+ * Social Recovery Manager
1068
+ *
1069
+ * Splits encrypted wallet data among guardians using Shamir Secret Sharing.
1070
+ * Guardians can combine their shares to help recover the wallet.
1071
+ */
1072
+
1073
+ interface GuardianShare {
1074
+ guardianId: string;
1075
+ guardianName: string;
1076
+ shareData: string;
1077
+ shareIndex: number;
1078
+ threshold: number;
1079
+ createdAt: string;
1080
+ walletAddress: string;
1081
+ }
1082
+
1083
+ /** Payload of the EIP-1193 `connect` event */
1084
+ interface ProviderConnectInfo {
1085
+ readonly chainId: string;
1086
+ }
1087
+ /** Error passed to EIP-1193 `disconnect` listeners */
1088
+ interface ProviderRpcError extends Error {
1089
+ code: number;
1090
+ data?: unknown;
1091
+ }
1092
+ /** Payload of the EIP-1193 `message` event */
1093
+ interface ProviderMessage {
1094
+ readonly type: string;
1095
+ readonly data: unknown;
1096
+ }
1097
+ /** EIP-1193 provider returned by `Web3Passkey.getEIP1193Provider()` */
1098
+ interface EIP1193ProviderInterface {
1099
+ request(args: {
1100
+ method: string;
1101
+ params?: unknown[];
1102
+ }): Promise<unknown>;
1103
+ on(event: 'accountsChanged', handler: (accounts: string[]) => void): void;
1104
+ on(event: 'chainChanged', handler: (chainId: string) => void): void;
1105
+ on(event: 'connect', handler: (info: ProviderConnectInfo) => void): void;
1106
+ on(event: 'disconnect', handler: (error: ProviderRpcError) => void): void;
1107
+ on(event: 'message', handler: (message: ProviderMessage) => void): void;
1108
+ removeListener(event: 'accountsChanged', handler: (accounts: string[]) => void): void;
1109
+ removeListener(event: 'chainChanged', handler: (chainId: string) => void): void;
1110
+ removeListener(event: 'connect', handler: (info: ProviderConnectInfo) => void): void;
1111
+ removeListener(event: 'disconnect', handler: (error: ProviderRpcError) => void): void;
1112
+ removeListener(event: 'message', handler: (message: ProviderMessage) => void): void;
1113
+ }
1114
+
633
1115
  /**
634
1116
  * Main Web3Passkey SDK
635
1117
  *
@@ -643,21 +1125,20 @@ interface RecoveryMethod {
643
1125
  * - Each origin receives isolated address derivation
644
1126
  *
645
1127
  * STEALTH ADDRESSES (opt-in via config.stealthAddresses):
646
- * - Applications receive stealth private keys (viewing and spending)
647
- * - Required for ERC-5564 compliance
1128
+ * - Applications receive the viewing key, never the spending key or a stealth
1129
+ * private key; w3pk signs from stealth addresses after a fresh assertion
1130
+ * - Stealth keys are shared across origins
648
1131
  * - Uses separate derivation: m/44'/60'/1'/0/0 and m/44'/60'/1'/0/1
649
1132
  * - Not derived from origin-specific addresses
650
1133
  */
651
1134
 
652
- /** Minimal EIP-1193 provider interface (matches the existing EIP1193Provider shape) */
653
- interface EIP1193ProviderInterface {
654
- request(args: {
655
- method: string;
656
- params?: any[];
657
- }): Promise<any>;
658
- on(event: string, handler: (...args: any[]) => void): void;
659
- removeListener(event: string, handler: (...args: any[]) => void): void;
660
- }
1135
+ /**
1136
+ * ZKProofModule members as exposed by `Web3Passkey.zk`: methods return a
1137
+ * Promise, properties become calls resolving to their value
1138
+ */
1139
+ type ZKMethods = {
1140
+ [K in keyof ZKProofModule]: ZKProofModule[K] extends (...args: infer A) => infer R ? (...args: A) => Promise<Awaited<R>> : () => Promise<ZKProofModule[K]>;
1141
+ };
661
1142
  declare class Web3Passkey {
662
1143
  private config;
663
1144
  private walletStorage;
@@ -667,7 +1148,10 @@ declare class Web3Passkey {
667
1148
  private sessionManager;
668
1149
  stealth?: StealthAddressModule;
669
1150
  private zkModule?;
1151
+ private readonly ctx;
670
1152
  constructor(config?: Web3PasskeyConfig);
1153
+ /** The internals the feature modules work on, read when they run */
1154
+ private createContext;
671
1155
  /**
672
1156
  * Lazy-load ZK module to prevent bundling unless accessed
673
1157
  */
@@ -678,18 +1162,18 @@ declare class Web3Passkey {
678
1162
  * @param securityMode - Security mode to use for session persistence (default: STANDARD)
679
1163
  */
680
1164
  private getMnemonicFromSession;
1165
+ /**
1166
+ * Store the wallet encrypted under the key derived from `prfOutput`,
1167
+ * the PRF output at `PRF_INPUT` of the wallet's passkey
1168
+ */
1169
+ private storeWallet;
681
1170
  /**
682
1171
  * Register new user with WebAuthn
683
1172
  * Automatically generates wallet if none exists and associates with passkey
684
1173
  */
685
1174
  register(options: {
686
1175
  username: string;
687
- }): Promise<{
688
- address: string;
689
- username: string;
690
- hasBackup: boolean;
691
- evictionRisk: boolean;
692
- }>;
1176
+ }): Promise<RegisterResult>;
693
1177
  /**
694
1178
  * Login with WebAuthn using resident credentials
695
1179
  * Starts session with decrypted mnemonic
@@ -739,16 +1223,6 @@ declare class Web3Passkey {
739
1223
  createdAt: string;
740
1224
  lastUsed: string;
741
1225
  }>>;
742
- /**
743
- * Check if there are existing credentials on this device
744
- * @deprecated Use listExistingCredentials().length > 0 instead
745
- */
746
- hasExistingCredential(): Promise<boolean>;
747
- /**
748
- * Get the number of existing credentials on this device
749
- * @deprecated Use listExistingCredentials().length instead
750
- */
751
- getExistingCredentialCount(): Promise<number>;
752
1226
  /**
753
1227
  * Generate new BIP39 wallet with 12-word mnemonic
754
1228
  * @internal - Called automatically by register()
@@ -765,7 +1239,6 @@ declare class Web3Passkey {
765
1239
  * @param mode - Security mode for derivation (default: "STANDARD")
766
1240
  * @param tag - Tag for derivation (default: "MAIN")
767
1241
  * @param options.requireAuth - Force fresh authentication
768
- * @param options.origin - Override origin URL (testing only)
769
1242
  *
770
1243
  * @example
771
1244
  * // Default: STANDARD mode with MAIN tag
@@ -779,7 +1252,6 @@ declare class Web3Passkey {
779
1252
  */
780
1253
  deriveWallet(mode?: SecurityMode, tag?: string, options?: {
781
1254
  requireAuth?: boolean;
782
- origin?: string;
783
1255
  }): Promise<DerivedWallet>;
784
1256
  /**
785
1257
  * Get public address for a specific security mode and tag
@@ -791,7 +1263,6 @@ declare class Web3Passkey {
791
1263
  *
792
1264
  * @param mode - Security mode (default: "STANDARD")
793
1265
  * @param tag - Derivation tag (default: "MAIN")
794
- * @param options.origin - Override origin URL (testing only)
795
1266
  * @returns The Ethereum address for this mode/tag combination
796
1267
  *
797
1268
  * @example
@@ -807,12 +1278,15 @@ declare class Web3Passkey {
807
1278
  * // Get STRICT address (will require authentication)
808
1279
  * const strictAddr = await w3pk.getAddress("STRICT")
809
1280
  */
810
- getAddress(mode?: SecurityMode, tag?: string, options?: {
811
- origin?: string;
812
- }): Promise<string>;
1281
+ getAddress(mode?: SecurityMode, tag?: string): Promise<string>;
813
1282
  /**
814
- * Import mnemonic phrase
815
- * Requires authentication and overwrites existing wallet
1283
+ * Import a mnemonic phrase as the logged-in passkey's wallet, replacing
1284
+ * the stored one. The imported wallet is stored under its own address
1285
+ * before the credential points at it, and the previous wallet is deleted
1286
+ * only after.
1287
+ *
1288
+ * @throws WalletError if not logged in, or the phrase isn't a valid BIP39 mnemonic
1289
+ * @throws AuthenticationError if the passkey prompt is cancelled, and PrfUnsupportedError if the authenticator returns no PRF output (nothing stored changes)
816
1290
  */
817
1291
  importMnemonic(mnemonic: string): Promise<void>;
818
1292
  /**
@@ -821,11 +1295,12 @@ declare class Web3Passkey {
821
1295
  * By default, signs with STANDARD mode + MAIN tag (origin-centric address).
822
1296
  * You can specify a different mode and tag to sign from a specific derived address.
823
1297
  *
824
- * @param message - Message to sign
1298
+ * @param message - Message to sign; bytes are signed as-is, and only with EIP191
825
1299
  * @param options.mode - Security mode for derivation (default: "STANDARD")
826
1300
  * @param options.tag - Tag for derivation (default: "MAIN")
827
1301
  * @param options.requireAuth - Force fresh authentication
828
- * @param options.origin - Override origin URL (testing only)
1302
+ * @param options.signingMethod - EIP191 (default), SIWE, EIP712 or rawHash;
1303
+ * rawHash always requires a fresh user-verified passkey assertion
829
1304
  * @returns Signature result with address, mode, and tag information
830
1305
  *
831
1306
  * @example
@@ -848,7 +1323,7 @@ declare class Web3Passkey {
848
1323
  * mode: 'STRICT'
849
1324
  * })
850
1325
  */
851
- signMessage(message: string, options?: SignMessageOptions): Promise<{
1326
+ signMessage(message: string | Uint8Array, options?: SignMessageOptions): Promise<{
852
1327
  signature: string;
853
1328
  address: string;
854
1329
  mode: SecurityMode;
@@ -897,8 +1372,9 @@ declare class Web3Passkey {
897
1372
  * @param options.mode - Security mode (default: STANDARD)
898
1373
  * @param options.tag - Wallet tag (optional)
899
1374
  * @param options.requireAuth - Force fresh authentication (optional)
900
- * @param options.origin - Origin override (optional)
901
- * @param options.rpcUrl - RPC endpoint override (optional, required for PRIMARY mode)
1375
+ * @param options.rpcUrl - RPC endpoint override (optional, required for PRIMARY mode);
1376
+ * without it, the first `rpcUrls` endpoint set for the chain is used, then the
1377
+ * first HTTPS chainid.network endpoint
902
1378
  * @returns Transaction hash and metadata
903
1379
  *
904
1380
  * @example
@@ -918,7 +1394,6 @@ declare class Web3Passkey {
918
1394
  mode?: SecurityMode;
919
1395
  tag?: string;
920
1396
  requireAuth?: boolean;
921
- origin?: string;
922
1397
  rpcUrl?: string;
923
1398
  }): Promise<{
924
1399
  hash: string;
@@ -935,16 +1410,19 @@ declare class Web3Passkey {
935
1410
  * @param params.contractAddress - Contract address to authorize
936
1411
  * @param params.chainId - Chain ID (default: 1)
937
1412
  * @param params.nonce - Nonce (default: 0)
938
- * @param params.privateKey - Private key for derived/stealth addresses
939
- * @param options.requireAuth - Force fresh authentication
1413
+ * @param options.mode - Security mode of the signing wallet (default: STANDARD, PRIMARY is refused)
1414
+ * @param options.tag - Wallet tag (default: MAIN)
1415
+ *
1416
+ * Signs with the origin-specific derived key (never the master key) after a
1417
+ * fresh user-verified passkey assertion.
940
1418
  */
941
1419
  signAuthorization(params: {
942
1420
  contractAddress: string;
943
1421
  chainId?: number;
944
1422
  nonce?: bigint;
945
- privateKey?: string;
946
1423
  }, options?: {
947
- requireAuth?: boolean;
1424
+ mode?: SecurityMode;
1425
+ tag?: string;
948
1426
  }): Promise<{
949
1427
  chainId: bigint;
950
1428
  address: string;
@@ -953,6 +1431,11 @@ declare class Web3Passkey {
953
1431
  r: string;
954
1432
  s: string;
955
1433
  }>;
1434
+ /**
1435
+ * RPC endpoints for a chain: those set in `rpcUrls` first, then the HTTPS
1436
+ * chainid.network endpoints that need no API key (skipped if chainid.network
1437
+ * can't be reached and the app set endpoints for the chain)
1438
+ */
956
1439
  getEndpoints(chainId: number): Promise<string[]>;
957
1440
  supportsEIP7702(chainId: number, options?: {
958
1441
  maxEndpoints?: number;
@@ -996,60 +1479,12 @@ declare class Web3Passkey {
996
1479
  rpcUrl?: string;
997
1480
  }): EIP1193ProviderInterface;
998
1481
  /**
999
- * Request EIP-7702 authorization from external wallet (MetaMask, Rabby, etc.)
1000
- * This allows users to delegate their ENS account to their w3pk STANDARD+MAIN account
1001
- *
1002
- * Flow:
1003
- * 1. User has ENS account in external wallet
1004
- * 2. User creates/logs into w3pk account
1005
- * 3. User signs EIP-7702 authorization delegating ENS account → w3pk account
1006
- * 4. User includes authorization in transaction to activate delegation
1007
- *
1008
- * @param params.provider - EIP-1193 provider (window.ethereum) - optional, auto-detected if not provided
1009
- * @param params.chainId - Chain ID for the authorization
1010
- * @param params.nonce - Nonce (default: 0n)
1011
- * @param params.accountIndex - Which account from external wallet to use (default: 0)
1012
- * @returns EIP-7702 authorization object
1013
- *
1014
- * @example
1015
- * ```typescript
1016
- * import { createWeb3Passkey } from 'w3pk';
1017
- *
1018
- * const w3pk = createWeb3Passkey();
1019
- * await w3pk.register({ username: 'alice' });
1020
- *
1021
- * // Request MetaMask to delegate to w3pk account
1022
- * const authorization = await w3pk.requestExternalWalletDelegation({
1023
- * chainId: 1,
1024
- * nonce: 0n
1025
- * });
1026
- *
1027
- * // Now user's ENS account delegates to w3pk account
1028
- * // Include in first transaction to activate
1029
- * await provider.request({
1030
- * method: 'eth_sendTransaction',
1031
- * params: [{
1032
- * to: someContract,
1033
- * data: txData,
1034
- * authorizationList: [authorization]
1035
- * }]
1036
- * });
1037
- * ```
1482
+ * Lazily loaded ZKProofModule (from `w3pk/zk`): each member loads the
1483
+ * module on first call and returns a Promise; a property such as
1484
+ * `isAvailable` resolves to its value, and `isAvailable()` resolves to
1485
+ * false when the module can't load
1038
1486
  */
1039
- requestExternalWalletDelegation(params?: {
1040
- provider?: any;
1041
- chainId?: number;
1042
- nonce?: bigint;
1043
- accountIndex?: number;
1044
- }): Promise<{
1045
- chainId: bigint;
1046
- address: string;
1047
- nonce: bigint;
1048
- yParity: number;
1049
- r: string;
1050
- s: string;
1051
- }>;
1052
- get zk(): any;
1487
+ get zk(): ZKMethods;
1053
1488
  /**
1054
1489
  * Get backup status
1055
1490
  */
@@ -1067,27 +1502,30 @@ declare class Web3Passkey {
1067
1502
  * - Sync wallet across devices
1068
1503
  * - Split among guardians for social recovery
1069
1504
  *
1070
- * @param encryptionType - 'password' (default), 'passkey', or 'hybrid'
1071
- * @param password - Required for 'password' and 'hybrid' encryption
1505
+ * Creates a password backup (BackupFile v3, Argon2id): the backup that
1506
+ * restores without a passkey. A PRF backup comes from exportForSync().
1507
+ *
1508
+ * @param password - Encrypts the backup
1509
+ * @throws WeakPasswordError when isStrongPassword() refuses the password, with its feedback
1072
1510
  */
1073
- createBackupFile(encryptionType?: 'password' | 'passkey' | 'hybrid', password?: string): Promise<{
1511
+ createBackupFile(password: string): Promise<{
1074
1512
  blob: Blob;
1075
1513
  filename: string;
1076
1514
  }>;
1077
- private backupCredential;
1078
1515
  /**
1079
1516
  * Set up social recovery by splitting backup file among guardians
1080
1517
  * Uses Shamir Secret Sharing to split the backup - requires M-of-N guardians to recover
1081
1518
  *
1082
1519
  * @param guardians - List of guardian names/emails
1083
1520
  * @param threshold - Number of guardians required to recover (M-of-N)
1084
- * @param password - Optional password for additional encryption layer
1521
+ * @param password - Encrypts the backup that the guardians' shares rebuild
1522
+ * @throws WeakPasswordError when isStrongPassword() refuses the password, with its feedback
1085
1523
  */
1086
1524
  setupSocialRecovery(guardians: {
1087
1525
  name: string;
1088
1526
  email?: string;
1089
- }[], threshold: number, password?: string): Promise<{
1090
- guardianShares: any[];
1527
+ }[], threshold: number, password: string): Promise<{
1528
+ guardianShares: GuardianShare[];
1091
1529
  setupComplete: boolean;
1092
1530
  }>;
1093
1531
  /**
@@ -1096,7 +1534,7 @@ declare class Web3Passkey {
1096
1534
  * @param guardianShare - The guardian's share data
1097
1535
  * @param message - Optional custom message for the guardian
1098
1536
  */
1099
- generateGuardianInvite(guardianShare: any, message?: string): Promise<{
1537
+ generateGuardianInvite(guardianShare: GuardianShare, message?: string): Promise<{
1100
1538
  qrCodeDataURL?: string;
1101
1539
  shareDocument: string;
1102
1540
  downloadBlob: Blob;
@@ -1104,25 +1542,45 @@ declare class Web3Passkey {
1104
1542
  }>;
1105
1543
  /**
1106
1544
  * Recover wallet from guardian shares
1107
- * Combines M-of-N guardian shares to reconstruct the backup file
1545
+ * Combines M-of-N guardian shares to reconstruct the backup file, then
1546
+ * restores it as restoreFromBackupFile() restores a password backup:
1547
+ * logged out, the wallet stays in memory for register(); logged in, it
1548
+ * replaces the stored wallet after a passkey assertion. The mnemonic is
1549
+ * never returned.
1108
1550
  *
1109
1551
  * @param shares - Array of guardian share objects (JSON strings or parsed objects)
1110
- * @param password - Password to decrypt the backup (if password-protected)
1552
+ * @param password - Password of the backup the shares rebuild
1553
+ * @throws AddressChangeError when logged in with another address, without `allowAddressChange`
1111
1554
  */
1112
- recoverFromGuardians(shares: Array<string | any>, password?: string): Promise<{
1113
- mnemonic: string;
1555
+ recoverFromGuardians(shares: Array<string | GuardianShare>, password: string, options?: {
1556
+ allowAddressChange?: boolean;
1557
+ }): Promise<{
1114
1558
  ethereumAddress: string;
1115
1559
  }>;
1116
1560
  /**
1117
1561
  * Restore wallet from backup file with existing passkey
1118
1562
  * Use case: User has passkey synced to this device
1119
1563
  *
1120
- * After restoration, you can either:
1121
- * - Use importMnemonic() to associate with current logged-in user
1122
- * - Use registerWithBackupFile() to create new passkey for this wallet
1564
+ * When logged out, a restored password backup stays in memory: call
1565
+ * register() to create a passkey for it, or log in and restore the file
1566
+ * again to store it under that passkey. The mnemonic is never returned.
1567
+ *
1568
+ * A PRF backup takes one assertion with its passkey, no password, and sets
1569
+ * this device up for that passkey (as importFromSync() does).
1570
+ *
1571
+ * When logged in, the restored wallet replaces the stored one only after
1572
+ * the passkey assertion succeeds. A backup of another address than the
1573
+ * logged-in one needs `allowAddressChange: true`, which the app sets once
1574
+ * the user confirms the replacement.
1575
+ *
1576
+ * @throws UnsupportedBackupVersionError for a file that isn't BackupFile v3
1577
+ * @throws SyncBootstrapError ('CREDENTIAL_MISMATCH') for a PRF backup of another passkey than the logged-in one
1578
+ * @throws AddressChangeError for a backup of another address without `allowAddressChange`
1579
+ * @throws AuthenticationError if the passkey prompt is cancelled, and PrfUnsupportedError if the authenticator returns no PRF output, when logged in (nothing stored changes)
1123
1580
  */
1124
- restoreFromBackupFile(backupData: string | Blob, password?: string): Promise<{
1125
- mnemonic: string;
1581
+ restoreFromBackupFile(backupData: string | Blob, password?: string, options?: {
1582
+ allowAddressChange?: boolean;
1583
+ }): Promise<{
1126
1584
  ethereumAddress: string;
1127
1585
  }>;
1128
1586
  /**
@@ -1137,26 +1595,20 @@ declare class Web3Passkey {
1137
1595
  * A PRF backup (from exportForSync()) takes a single assertion restricted
1138
1596
  * to its passkey and no password.
1139
1597
  *
1598
+ * A backup of another address than the one this device stores for the
1599
+ * passkey needs `allowAddressChange: true`, which the app sets once the
1600
+ * user confirms the replacement.
1601
+ *
1140
1602
  * @param backupData - Backup file (JSON string or Blob) - can be pasted by user
1141
1603
  * @param password - Password to decrypt backup (if password-encrypted)
1142
- * @returns Restored wallet info
1604
+ * @returns The restored wallet's address (the mnemonic is never returned)
1605
+ * @throws AddressChangeError for a backup of another address than the passkey's, without `allowAddressChange` (nothing stored changes)
1143
1606
  */
1144
- syncWalletWithPasskey(backupData: string | Blob, password?: string): Promise<{
1145
- mnemonic: string;
1607
+ syncWalletWithPasskey(backupData: string | Blob, password?: string, options?: {
1608
+ allowAddressChange?: boolean;
1609
+ }): Promise<{
1146
1610
  ethereumAddress: string;
1147
1611
  }>;
1148
- /**
1149
- * Restore a PRF backup with its passkey and set this device up for it.
1150
- * The public key is this device's when it has the passkey's metadata,
1151
- * else the backup's, checked against the assertion's signature.
1152
- */
1153
- private restorePrfBackup;
1154
- /**
1155
- * Set this device up for a passkey and a synced wallet: saves the
1156
- * passkey's metadata (or points it at the wallet), stores the wallet
1157
- * under the passkey-derived key and starts a session
1158
- */
1159
- private bootstrapCredential;
1160
1612
  /**
1161
1613
  * Register new passkey with wallet from backup file
1162
1614
  * Use case: Fresh device, user has backup file but no passkey yet
@@ -1174,7 +1626,7 @@ declare class Web3Passkey {
1174
1626
  /**
1175
1627
  * Get cross-device sync status
1176
1628
  */
1177
- getSyncStatus(): Promise<any>;
1629
+ getSyncStatus(): Promise<DeviceSyncInfo | null>;
1178
1630
  /**
1179
1631
  * Export wallet for syncing to another device
1180
1632
  *
@@ -1185,6 +1637,7 @@ declare class Web3Passkey {
1185
1637
  *
1186
1638
  * @param password - Fallback password when PRF is unavailable
1187
1639
  * @throws PrfUnsupportedError when PRF is unavailable and no password is given
1640
+ * @throws WeakPasswordError when isStrongPassword() refuses the password, with its feedback
1188
1641
  */
1189
1642
  exportForSync(password?: string): Promise<{
1190
1643
  blob: Blob;
@@ -1200,35 +1653,23 @@ declare class Web3Passkey {
1200
1653
  * login. For a password backup (exportForSync()'s fallback), use
1201
1654
  * syncWalletWithPasskey().
1202
1655
  *
1656
+ * A backup of another address than the one this device stores for the
1657
+ * passkey needs `allowAddressChange: true`, which the app sets once the
1658
+ * user confirms the replacement.
1659
+ *
1203
1660
  * @throws SyncBootstrapError ('CREDENTIAL_MISMATCH') when logged in with another passkey
1661
+ * @throws AddressChangeError for a backup of another address than the passkey's, without `allowAddressChange` (nothing stored changes)
1204
1662
  */
1205
- importFromSync(syncData: string | Blob): Promise<{
1663
+ importFromSync(syncData: string | Blob, options?: {
1664
+ allowAddressChange?: boolean;
1665
+ }): Promise<{
1206
1666
  ethereumAddress: string;
1207
1667
  success: boolean;
1208
1668
  }>;
1209
1669
  /**
1210
1670
  * Detect platform sync capabilities
1211
1671
  */
1212
- detectSyncCapabilities(): Promise<any>;
1213
- /**
1214
- * Simulate recovery scenario
1215
- */
1216
- simulateRecoveryScenario(scenario: {
1217
- type: "lost-device" | "lost-phrase" | "lost-both" | "switch-platform";
1218
- description: string;
1219
- }): Promise<any>;
1220
- /**
1221
- * Run interactive recovery test
1222
- */
1223
- runRecoveryTest(): Promise<{
1224
- scenarios: any[];
1225
- overallScore: number;
1226
- feedback: string;
1227
- }>;
1228
- /**
1229
- * Get educational content by topic
1230
- */
1231
- getEducation(topic: string): Promise<any>;
1672
+ detectSyncCapabilities(): Promise<SyncCapabilities>;
1232
1673
  hasActiveSession(): boolean;
1233
1674
  getSessionRemainingTime(): number;
1234
1675
  /**
@@ -1273,18 +1714,84 @@ declare class Web3Passkey {
1273
1714
  */
1274
1715
  derivePrfSecret(tag: string): Promise<PrfSecret>;
1275
1716
  /**
1276
- * Derive ML-KEM-1024 public key from the current wallet
1717
+ * Get the commitment of a Semaphore v4 identity bound to the passkey
1718
+ *
1719
+ * The identity's private key is a PRF secret for the current origin and
1720
+ * `tag`, derived under its own label so `derivePrfSecret(tag)` can't
1721
+ * return it. The private key is never returned or stored. A new
1722
+ * credential gives a new commitment: keep `credentialId` with the
1723
+ * commitment you add to a group, and replace the member when it changes.
1724
+ *
1725
+ * Requires the optional dependency `@semaphore-protocol/identity`.
1726
+ *
1727
+ * @param tag - Non-empty label without ':', e.g. "voting"
1728
+ * @returns The identity commitment and the credential it is bound to
1729
+ * @throws PrfUnsupportedError when the authenticator doesn't support PRF
1730
+ * @throws CryptoError when `@semaphore-protocol/identity` isn't installed
1731
+ * (before any prompt) or the tag is invalid
1732
+ *
1733
+ * @example
1734
+ * const { commitment, credentialId } = await w3pk.getSemaphoreIdentity("voting")
1735
+ * group.addMember(commitment)
1736
+ */
1737
+ getSemaphoreIdentity(tag: string): Promise<SemaphoreIdentity>;
1738
+ /**
1739
+ * Prove with a secret bound to the passkey that the app never sees
1740
+ *
1741
+ * w3pk derives the secret for the current origin and `tag` (by default
1742
+ * under its own `w3pk-zk-v1` label, or the Semaphore identity's
1743
+ * `secretScalar`), places it in the witness with any inputs `options`
1744
+ * declares as derived (Poseidon over the secret and other inputs) or
1745
+ * random (fresh, discarded after the call), checks the artifacts against
1746
+ * their pins, and runs snarkjs in a Web Worker (in-thread where `Worker`
1747
+ * doesn't exist, as in Node, or the worker can't start). Only the proof
1748
+ * and public signals come back;
1749
+ * a proof whose public signals contain the secret or a random input is
1750
+ * refused. Everything checkable without the passkey is checked before
1751
+ * the prompt.
1752
+ *
1753
+ * Only public signals equal to the secret or a random input are refused:
1754
+ * the circuit chooses its public signals and can output any function of
1755
+ * the secret, the Semaphore secret included. Only prove with circuits
1756
+ * you trust; the artifact pins say which circuit runs, not what it reveals.
1757
+ *
1758
+ * w3pk runs in the app's JavaScript context: this keeps the secret out
1759
+ * of the API, not out of reach of malicious code on the same page.
1760
+ *
1761
+ * Requires the optional dependencies `snarkjs`, `poseidon-lite` (for
1762
+ * derivations) and `@semaphore-protocol/identity` (for `"semaphore"`).
1763
+ *
1764
+ * @param tag - Non-empty label without ':', e.g. "voting"
1765
+ * @param artifacts - The circuit's `.wasm` and `.zkey` (bytes or URLs) and their pinned CIDs
1766
+ * @param publicInputs - The circuit's public inputs
1767
+ * @param extraWitness - Other private inputs the app provides
1768
+ * @param options - Secret source, its input name, derived and random inputs
1769
+ * @throws ZkArtifactMismatchError when an artifact doesn't match its pin
1770
+ * @throws PrfUnsupportedError when the authenticator doesn't support PRF
1771
+ * @throws CryptoError on invalid inputs, missing dependencies or a failed proof
1772
+ *
1773
+ * @example
1774
+ * const { proof, publicSignals } = await w3pk.zkProve(
1775
+ * "voting",
1776
+ * { wasm: wasmUrl, zkey: zkeyUrl, pins },
1777
+ * { proposalId, root },
1778
+ * { vote: 1 },
1779
+ * { secret: "semaphore", derive: { voteSecret: ["secret", "proposalId", 1n] }, random: ["r"] }
1780
+ * )
1781
+ */
1782
+ zkProve(tag: string, artifacts: ZkProveArtifacts, publicInputs: ZkInputs, extraWitness?: ZkInputs, options?: ZkProveOptions): Promise<ZkProveResult>;
1783
+ /**
1784
+ * Derive the hybrid ML-KEM-1024 + X25519 public key from the current wallet
1277
1785
  *
1278
1786
  * Returns the public key that can be shared with others for encryption.
1279
- * The keypair is derived deterministically from the wallet's private key.
1787
+ * The hybrid keypair is derived deterministically from the wallet's private key.
1280
1788
  *
1281
1789
  * @param options - Optional configuration
1282
- * @param options.context - Context string for domain separation (default: 'mlkem-v1')
1790
+ * @param options.context - Context string for domain separation (default: MLKEM_DEFAULT_CONTEXT)
1283
1791
  * @param options.mode - Security mode (default: 'YOLO' to access private key)
1284
1792
  * @param options.tag - Tag for address derivation (default: 'MAIN')
1285
- * @param options.origin - Origin for derivation (default: current origin)
1286
1793
  * @param options.requireAuth - Force WebAuthn re-authentication
1287
- * @returns Base64-encoded ML-KEM public key (1568 bytes)
1794
+ * @returns Base64-encoded hybrid public key (1600 bytes: ML-KEM-1024 || X25519)
1288
1795
  *
1289
1796
  * @example
1290
1797
  * ```typescript
@@ -1299,22 +1806,20 @@ declare class Web3Passkey {
1299
1806
  context?: string;
1300
1807
  mode?: SecurityMode;
1301
1808
  tag?: string;
1302
- origin?: string;
1303
1809
  requireAuth?: boolean;
1304
1810
  }): Promise<string>;
1305
1811
  /**
1306
- * Encrypt data using ML-KEM-1024 for self + additional recipients
1812
+ * Encrypt data with the hybrid ML-KEM-1024 + X25519 KEM (payload v3) for self + additional recipients
1307
1813
  *
1308
1814
  * Encrypts data such that you (the sender) and specified recipients can decrypt.
1309
- * Your ML-KEM keypair is derived from your wallet, so you can always decrypt later.
1815
+ * Your hybrid keypair is derived from your wallet, so you can always decrypt later.
1310
1816
  *
1311
1817
  * @param plaintext - The data to encrypt
1312
- * @param recipientPublicKeys - Array of recipient ML-KEM public keys (base64 strings or Uint8Arrays)
1818
+ * @param recipientPublicKeys - Array of recipient hybrid public keys (base64 strings or Uint8Arrays, 1600 bytes)
1313
1819
  * @param options - Optional configuration
1314
- * @param options.context - Context string for key derivation (default: 'mlkem-v1')
1820
+ * @param options.context - Context string for key derivation (default: MLKEM_DEFAULT_CONTEXT)
1315
1821
  * @param options.mode - Security mode (default: 'YOLO' to access private key)
1316
1822
  * @param options.tag - Tag for address derivation (default: 'MAIN')
1317
- * @param options.origin - Origin for derivation (default: current origin)
1318
1823
  * @param options.requireAuth - Force WebAuthn re-authentication
1319
1824
  * @returns Encrypted payload that can be decrypted by sender or recipients
1320
1825
  *
@@ -1340,21 +1845,19 @@ declare class Web3Passkey {
1340
1845
  context?: string;
1341
1846
  mode?: SecurityMode;
1342
1847
  tag?: string;
1343
- origin?: string;
1344
1848
  requireAuth?: boolean;
1345
- }): Promise<any>;
1849
+ }): Promise<EncryptedPayload>;
1346
1850
  /**
1347
1851
  * Decrypt ML-KEM encrypted data using current wallet
1348
1852
  *
1349
1853
  * Decrypts data that was encrypted for this wallet.
1350
- * The ML-KEM keypair is derived from your wallet's private key.
1854
+ * The hybrid keypair is derived from your wallet's private key. Only v3 payloads are read.
1351
1855
  *
1352
1856
  * @param payload - The encrypted payload (from mlkemEncrypt)
1353
1857
  * @param options - Optional configuration
1354
- * @param options.context - Context string for key derivation (default: 'mlkem-v1', must match encryption)
1858
+ * @param options.context - Context string for key derivation (default: MLKEM_DEFAULT_CONTEXT, must match encryption)
1355
1859
  * @param options.mode - Security mode (default: 'YOLO' to access private key)
1356
1860
  * @param options.tag - Tag for address derivation (default: 'MAIN')
1357
- * @param options.origin - Origin for derivation (default: current origin)
1358
1861
  * @param options.requireAuth - Force WebAuthn re-authentication
1359
1862
  * @returns Decrypted plaintext
1360
1863
  *
@@ -1368,194 +1871,43 @@ declare class Web3Passkey {
1368
1871
  *
1369
1872
  * // Decrypt locally (server never sees plaintext!)
1370
1873
  * const plaintext = await w3pk.mlkemDecrypt(encrypted);
1371
- * ```
1372
- */
1373
- mlkemDecrypt(payload: any, options?: {
1374
- context?: string;
1375
- mode?: SecurityMode;
1376
- tag?: string;
1377
- origin?: string;
1378
- requireAuth?: boolean;
1379
- }): Promise<string>;
1380
- }
1381
-
1382
- /**
1383
- * Wallet-related types
1384
- */
1385
- interface WalletData {
1386
- address: string;
1387
- mnemonic: string;
1388
- }
1389
- /**
1390
- * EIP-7702 Authorization signature components
1391
- */
1392
- interface EIP7702Authorization {
1393
- chainId: bigint;
1394
- address: string;
1395
- nonce: bigint;
1396
- yParity: number;
1397
- r: string;
1398
- s: string;
1399
- }
1400
- /**
1401
- * Parameters for signing EIP-7702 authorization
1402
- */
1403
- interface SignAuthorizationParams {
1404
- contractAddress: string;
1405
- chainId?: number;
1406
- nonce?: bigint;
1407
- privateKey?: string;
1408
- }
1409
-
1410
- /**
1411
- * External Wallet EIP-7702 Authorization Utilities
1412
- *
1413
- * This module provides utilities for users to sign EIP-7702 authorizations
1414
- * using external wallets (MetaMask, Rabby, hardware wallets, etc.) to delegate
1415
- * their external wallet accounts to W3PK accounts.
1416
- *
1417
- * Use cases:
1418
- * - Delegate ENS-linked addresses to W3PK for gasless transactions
1419
- * - Integrate hardware wallets for enhanced security
1420
- * - Enable multi-signature setups combining external and W3PK accounts
1421
- * - Migrate existing wallet users to W3PK while maintaining their addresses
1422
- *
1423
- * Flow:
1424
- * 1. User has an external wallet account (MetaMask, Ledger, etc.)
1425
- * 2. User creates or has a W3PK account
1426
- * 3. User signs EIP-7702 authorization delegating external account to W3PK account
1427
- * 4. User includes authorization in transaction to activate delegation
1428
- */
1429
-
1430
- /**
1431
- * EIP-1193 Provider interface (MetaMask, Rabby, etc.)
1432
- */
1433
- interface EIP1193Provider {
1434
- request(args: {
1435
- method: string;
1436
- params?: any[];
1437
- }): Promise<any>;
1438
- on?(event: string, handler: (...args: any[]) => void): void;
1439
- removeListener?(event: string, handler: (...args: any[]) => void): void;
1440
- }
1441
- /**
1442
- * Request user to sign EIP-7702 authorization with external wallet
1443
- *
1444
- * @param provider - EIP-1193 provider (window.ethereum)
1445
- * @param params - Authorization parameters
1446
- * @param params.delegateToAddress - The w3pk account address to delegate to
1447
- * @param params.chainId - Chain ID for the authorization
1448
- * @param params.nonce - Nonce (default: 0n)
1449
- * @param params.accountIndex - Optional: request specific account from wallet (default: 0)
1450
- * @returns EIP-7702 authorization object
1451
- *
1452
- * @example
1453
- * ```typescript
1454
- * import { requestExternalWalletAuthorization } from 'w3pk';
1455
- *
1456
- * // Get user's w3pk account
1457
- * const w3pkAddress = w3pk.getAddress();
1458
- *
1459
- * // Request MetaMask to sign authorization
1460
- * const authorization = await requestExternalWalletAuthorization(
1461
- * window.ethereum,
1462
- * {
1463
- * delegateToAddress: w3pkAddress,
1464
- * chainId: 1,
1465
- * nonce: 0n
1466
- * }
1467
- * );
1468
- *
1469
- * // Use in transaction
1470
- * await provider.request({
1471
- * method: 'eth_sendTransaction',
1472
- * params: [{
1473
- * to: someContract,
1474
- * data: txData,
1475
- * authorizationList: [authorization]
1476
- * }]
1477
- * });
1478
- * ```
1479
- */
1480
- declare function requestExternalWalletAuthorization(provider: EIP1193Provider, params: {
1481
- delegateToAddress: string;
1482
- chainId?: number;
1483
- nonce?: bigint;
1484
- accountIndex?: number;
1485
- }): Promise<EIP7702Authorization>;
1486
- /**
1487
- * Get the default Ethereum provider (window.ethereum)
1488
- * Handles multiple injected wallets and provider detection
1489
- *
1490
- * @returns EIP-1193 provider or null if not found
1491
- */
1492
- declare function getDefaultProvider(): EIP1193Provider | null;
1493
- /**
1494
- * Detect which wallet provider is being used
1495
- *
1496
- * @param provider - EIP-1193 provider
1497
- * @returns Wallet name or 'Unknown'
1498
- */
1499
- declare function detectWalletProvider(provider: EIP1193Provider): string;
1500
- /**
1501
- * Check if a provider supports EIP-7702
1502
- * Note: This is a best-effort check as EIP-7702 support is still rolling out
1503
- *
1504
- * @param provider - EIP-1193 provider
1505
- * @returns true if provider likely supports EIP-7702
1506
- */
1507
- declare function supportsEIP7702Authorization(provider: EIP1193Provider): Promise<boolean>;
1874
+ * ```
1875
+ */
1876
+ mlkemDecrypt(payload: EncryptedPayload, options?: {
1877
+ context?: string;
1878
+ mode?: SecurityMode;
1879
+ tag?: string;
1880
+ requireAuth?: boolean;
1881
+ }): Promise<string>;
1882
+ }
1508
1883
 
1509
1884
  /**
1510
- * EIP-7702 Utility Functions
1511
- * Shared encoding logic to ensure consistency across all implementations
1512
- */
1513
- /**
1514
- * Encode EIP-7702 authorization message
1515
- *
1516
- * @param chainId - Chain ID for the authorization
1517
- * @param contractAddress - Contract address to delegate to
1518
- * @param nonce - Nonce for the authorization
1519
- * @returns Encoded authorization message bytes
1520
- *
1521
- * @spec EIP-7702: 0x05 || rlp([chain_id, address, nonce])
1522
- */
1523
- declare function encodeEIP7702AuthorizationMessage(chainId: bigint, contractAddress: string, nonce: bigint): string;
1524
- /**
1525
- * Hash EIP-7702 authorization message
1526
- *
1527
- * @param chainId - Chain ID for the authorization
1528
- * @param contractAddress - Contract address to delegate to
1529
- * @param nonce - Nonce for the authorization
1530
- * @returns Keccak256 hash of the authorization message
1885
+ * Wallet-related types
1531
1886
  */
1532
- declare function hashEIP7702AuthorizationMessage(chainId: bigint, contractAddress: string, nonce: bigint): string;
1887
+ interface WalletData {
1888
+ address: string;
1889
+ mnemonic: string;
1890
+ }
1533
1891
  /**
1534
- * Verify EIP-7702 authorization signature
1535
- *
1536
- * @param chainId - Chain ID for the authorization
1537
- * @param contractAddress - Contract address being delegated to
1538
- * @param nonce - Nonce for the authorization
1539
- * @param signature - The signature components (yParity, r, s) or hex string
1540
- * @param expectedSigner - The expected signer address
1541
- * @returns true if signature is valid and from expected signer
1542
- *
1543
- * @example
1544
- * ```typescript
1545
- * const isValid = verifyEIP7702Authorization(
1546
- * 1n,
1547
- * "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1",
1548
- * 0n,
1549
- * { yParity: 1, r: "0x...", s: "0x..." },
1550
- * "0x1234567890123456789012345678901234567890"
1551
- * );
1552
- * ```
1892
+ * EIP-7702 Authorization signature components
1553
1893
  */
1554
- declare function verifyEIP7702Authorization(chainId: bigint, contractAddress: string, nonce: bigint, signature: {
1894
+ interface EIP7702Authorization {
1895
+ chainId: bigint;
1896
+ address: string;
1897
+ nonce: bigint;
1555
1898
  yParity: number;
1556
1899
  r: string;
1557
1900
  s: string;
1558
- } | string, expectedSigner: string): boolean;
1901
+ }
1902
+ /**
1903
+ * Parameters for signing EIP-7702 authorization
1904
+ */
1905
+ interface SignAuthorizationParams {
1906
+ contractAddress: string;
1907
+ chainId?: number;
1908
+ nonce?: bigint;
1909
+ privateKey?: string;
1910
+ }
1559
1911
 
1560
1912
  /**
1561
1913
  * Sync Authentication Helper
@@ -1569,6 +1921,10 @@ interface PasskeySelectionResult {
1569
1921
  username?: string;
1570
1922
  /** The selection assertion, to verify against a public key from a backup */
1571
1923
  assertion: AuthenticationCredential;
1924
+ /** Base64url challenge the assertion answers */
1925
+ challenge: string;
1926
+ /** PRF output at `PRF_INPUT`, the source of the wallet key; absent without PRF */
1927
+ prfOutput?: ArrayBuffer;
1572
1928
  }
1573
1929
  /**
1574
1930
  * Prompts the user to select a passkey/webauthn credential
@@ -1603,6 +1959,14 @@ declare function deriveIndexFromOriginModeAndTag(origin: string, mode?: Security
1603
1959
  * - STANDARD mode: Private key NOT exposed, persistent sessions allowed
1604
1960
  * - STRICT mode: Private key NOT exposed, persistent sessions NOT allowed
1605
1961
  * - YOLO mode: Private key exposed, persistent sessions allowed
1962
+ *
1963
+ * The key is derived at `m/44'/60'/0'/0/{index}`, a non-hardened BIP-32 child.
1964
+ * Under BIP-32, a leaked non-hardened child private key together with the
1965
+ * parent extended public key (`m/44'/60'/0'/0`) reveals the parent private key
1966
+ * and every sibling, so every origin's key. w3pk never exposes that extended
1967
+ * public key, but a YOLO-mode private key must be treated as sensitive for the
1968
+ * whole wallet, not only for its origin. The path is kept as is because
1969
+ * changing it would move every origin address.
1606
1970
  */
1607
1971
  declare function getOriginSpecificAddress(mnemonic: string, origin: string, mode?: SecurityMode, tag?: string): Promise<{
1608
1972
  address: string;
@@ -1692,17 +2056,7 @@ declare function assertEthereumAddress(address: string): void;
1692
2056
  declare function assertUsername(username: string): void;
1693
2057
  declare function assertMnemonic(mnemonic: string): void;
1694
2058
  /**
1695
- * Validates password strength based on security best practices
1696
- * @param password - The password to validate
1697
- * @returns true if password meets strength requirements, false otherwise
1698
- *
1699
- * Requirements:
1700
- * - At least 12 characters long
1701
- * - Contains at least one uppercase letter
1702
- * - Contains at least one lowercase letter
1703
- * - Contains at least one number
1704
- * - Contains at least one special character
1705
- * - Not a common password
2059
+ * The password rules of backups: see validatePasswordStrength()
1706
2060
  */
1707
2061
  declare function isStrongPassword(password: string): boolean;
1708
2062
 
@@ -1732,6 +2086,7 @@ declare function getW3pkBuildHash(distUrl: string): Promise<string>;
1732
2086
  declare function getPackageVersion(): string;
1733
2087
  /**
1734
2088
  * Computes build hash for the current w3pk version from unpkg CDN
2089
+ * (the published package, not the running code)
1735
2090
  * @returns IPFS CIDv1 hash of the build
1736
2091
  *
1737
2092
  * @example
@@ -1742,7 +2097,14 @@ declare function getPackageVersion(): string;
1742
2097
  */
1743
2098
  declare function getCurrentBuildHash(): Promise<string>;
1744
2099
  /**
1745
- * Verifies if a given hash matches the current build
2100
+ * Verifies if a given hash matches the build published on unpkg for the
2101
+ * installed version
2102
+ *
2103
+ * This hashes the files fetched from unpkg, not the code actually running:
2104
+ * a bundled, modified or injected copy is not checked, and compromised
2105
+ * running code can return any result. Hash the files you ship at build time
2106
+ * to check those.
2107
+ *
1746
2108
  * @param expectedHash The hash to verify against
1747
2109
  * @returns true if hashes match, false otherwise
1748
2110
  *
@@ -1802,9 +2164,6 @@ declare function safeBtoa(input: string): string;
1802
2164
  */
1803
2165
  declare function base64UrlDecode(base64url: string): ArrayBuffer;
1804
2166
 
1805
- /**
1806
- * Cryptographic utility functions for WebAuthn and P-256 signatures
1807
- */
1808
2167
  /**
1809
2168
  * Extracts r and s values from a DER-encoded ECDSA signature
1810
2169
  * Applies low-s normalization for Ethereum compatibility
@@ -1922,6 +2281,9 @@ declare function parseSiweMessage(message: string): SiweMessage;
1922
2281
  /**
1923
2282
  * Validate a SIWE message for correctness and expiration
1924
2283
  *
2284
+ * `Issued At`, `Expiration Time` and `Not Before` must be valid dates, and
2285
+ * the message fails once expired or before its not-before time.
2286
+ *
1925
2287
  * @param message - SIWE message string or parsed object
1926
2288
  * @param options - Validation options
1927
2289
  * @returns Validation result with details
@@ -1929,7 +2291,7 @@ declare function parseSiweMessage(message: string): SiweMessage;
1929
2291
  * @example
1930
2292
  * const validation = validateSiweMessage(message, {
1931
2293
  * domain: 'example.com',
1932
- * checkExpiration: true
2294
+ * chainId: 1
1933
2295
  * })
1934
2296
  *
1935
2297
  * if (validation.valid) {
@@ -1941,10 +2303,6 @@ declare function parseSiweMessage(message: string): SiweMessage;
1941
2303
  declare function validateSiweMessage(message: string | SiweMessage, options?: {
1942
2304
  /** Expected domain (validates domain matches) */
1943
2305
  domain?: string;
1944
- /** Check expiration time */
1945
- checkExpiration?: boolean;
1946
- /** Check not-before time */
1947
- checkNotBefore?: boolean;
1948
2306
  /** Expected chain ID */
1949
2307
  chainId?: number;
1950
2308
  }): {
@@ -1980,167 +2338,55 @@ declare function verifySiweSignature(message: string, signature: string, expecte
1980
2338
  }>;
1981
2339
 
1982
2340
  /**
1983
- * Social Recovery Type Definitions
2341
+ * EIP-7702 Utility Functions
2342
+ * Shared encoding logic to ensure consistency across all implementations
1984
2343
  */
1985
- interface Guardian {
1986
- id: string;
1987
- name: string;
1988
- email?: string;
1989
- phone?: string;
1990
- publicKey?: string;
1991
- shareEncrypted: string;
1992
- status: 'pending' | 'active' | 'revoked';
1993
- addedAt: string;
1994
- lastVerified?: string;
1995
- }
1996
- interface GuardianInvite {
1997
- guardianId: string;
1998
- qrCode: string;
1999
- shareCode: string;
2000
- explainer: string;
2001
- link?: string;
2002
- }
2003
- interface SocialRecoveryConfig {
2004
- threshold: number;
2005
- totalGuardians: number;
2006
- guardians: Guardian[];
2007
- createdAt: string;
2008
- ethereumAddress: string;
2009
- }
2010
- interface RecoveryShare {
2011
- guardianId: string;
2012
- share: string;
2013
- index: number;
2014
- }
2015
- interface RecoveryProgress {
2016
- collected: number;
2017
- required: number;
2018
- guardians: {
2019
- id: string;
2020
- name: string;
2021
- hasProvided: boolean;
2022
- }[];
2023
- canRecover: boolean;
2024
- }
2025
-
2026
2344
  /**
2027
- * Social Recovery Manager
2028
- * Manages guardian-based wallet recovery using Shamir Secret Sharing
2345
+ * Encode EIP-7702 authorization message
2346
+ *
2347
+ * @param chainId - Chain ID for the authorization
2348
+ * @param contractAddress - Contract address to delegate to
2349
+ * @param nonce - Nonce for the authorization
2350
+ * @returns Encoded authorization message bytes
2351
+ *
2352
+ * @spec EIP-7702: 0x05 || rlp([chain_id, address, nonce])
2029
2353
  */
2030
-
2031
- declare class SocialRecoveryManager {
2032
- private storageKey;
2033
- /**
2034
- * Get storage (localStorage or in-memory fallback)
2035
- */
2036
- private getItem;
2037
- /**
2038
- * Set storage (localStorage or in-memory fallback)
2039
- */
2040
- private setItem;
2041
- /**
2042
- * Set up social recovery
2043
- * Splits encrypted backup file into M-of-N shares and distributes to guardians
2044
- *
2045
- * @param backupFileJson - The complete backup file JSON string (password-encrypted)
2046
- * @param ethereumAddress - The Ethereum address for verification
2047
- * @param guardians - Array of guardian information
2048
- * @param threshold - Minimum number of guardians needed for recovery
2049
- */
2050
- setupSocialRecovery(backupFileJson: string, ethereumAddress: string, guardians: {
2051
- name: string;
2052
- email?: string;
2053
- phone?: string;
2054
- }[], threshold: number): Promise<Guardian[]>;
2055
- /**
2056
- * Get current social recovery configuration
2057
- */
2058
- getSocialRecoveryConfig(): SocialRecoveryConfig | null;
2059
- /**
2060
- * Generate guardian invitation
2061
- * Creates QR code and educational materials for guardian
2062
- */
2063
- generateGuardianInvite(guardian: Guardian): Promise<GuardianInvite>;
2064
- /**
2065
- * Generate QR code from share data
2066
- * Uses 'qrcode' library if available, falls back to canvas text
2067
- */
2068
- private generateQRCode;
2069
- /**
2070
- * Create fallback QR representation
2071
- */
2072
- private createPlaceholderQR;
2073
- /**
2074
- * Wrap text for display
2075
- */
2076
- private wrapText;
2077
- /**
2078
- * Get guardian explainer text
2079
- */
2080
- private getGuardianExplainer;
2081
- /**
2082
- * Recover backup file from guardian shares
2083
- * Returns the reconstructed backup file JSON that can be used with restoreFromBackupFile()
2084
- */
2085
- recoverFromGuardians(shareData: string[]): Promise<{
2086
- backupFileJson: string;
2087
- ethereumAddress: string;
2088
- }>;
2089
- /**
2090
- * Get recovery progress
2091
- */
2092
- getRecoveryProgress(collectedShares: string[]): RecoveryProgress;
2093
- /**
2094
- * Mark guardian as verified
2095
- * Note: This updates guardian status but does NOT automatically refresh security score.
2096
- * The security score will be updated on the next call to BackupManager.getBackupStatus()
2097
- */
2098
- markGuardianVerified(guardianId: string): void;
2099
- /**
2100
- * Revoke a guardian
2101
- */
2102
- revokeGuardian(guardianId: string): void;
2103
- /**
2104
- * Add new guardian (requires re-sharing with new backup file)
2105
- */
2106
- addGuardian(backupFileJson: string, newGuardian: {
2107
- name: string;
2108
- email?: string;
2109
- phone?: string;
2110
- }): Promise<Guardian>;
2111
- }
2112
-
2354
+ declare function encodeEIP7702AuthorizationMessage(chainId: bigint, contractAddress: string, nonce: bigint): string;
2113
2355
  /**
2114
- * Cross-Device Sync Type Definitions
2356
+ * Hash EIP-7702 authorization message
2357
+ *
2358
+ * @param chainId - Chain ID for the authorization
2359
+ * @param contractAddress - Contract address to delegate to
2360
+ * @param nonce - Nonce for the authorization
2361
+ * @returns Keccak256 hash of the authorization message
2115
2362
  */
2116
- interface SyncVault {
2117
- id: string;
2118
- encryptedData: string;
2119
- deviceFingerprints: string[];
2120
- syncMethod: 'icloud' | 'google' | 'microsoft' | 'custom';
2121
- version: number;
2122
- updatedAt: string;
2123
- }
2124
- interface DeviceInfo {
2125
- id: string;
2126
- name: string;
2127
- platform: 'ios' | 'android' | 'macos' | 'windows' | 'linux' | 'unknown';
2128
- lastActive: string;
2129
- trusted: boolean;
2130
- canRevoke: boolean;
2131
- }
2132
- interface SyncCapabilities {
2133
- passkeysSync: boolean;
2134
- platform: 'apple' | 'google' | 'microsoft' | 'none';
2135
- estimatedDevices: number;
2136
- syncEnabled: boolean;
2137
- }
2138
- interface SyncStatus {
2139
- enabled: boolean;
2140
- devices: DeviceInfo[];
2141
- lastSyncTime?: string;
2142
- platform: string;
2143
- }
2363
+ declare function hashEIP7702AuthorizationMessage(chainId: bigint, contractAddress: string, nonce: bigint): string;
2364
+ /**
2365
+ * Verify EIP-7702 authorization signature
2366
+ *
2367
+ * @param chainId - Chain ID for the authorization
2368
+ * @param contractAddress - Contract address being delegated to
2369
+ * @param nonce - Nonce for the authorization
2370
+ * @param signature - The signature components (yParity, r, s) or hex string
2371
+ * @param expectedSigner - The expected signer address
2372
+ * @returns true if signature is valid and from expected signer
2373
+ *
2374
+ * @example
2375
+ * ```typescript
2376
+ * const isValid = verifyEIP7702Authorization(
2377
+ * 1n,
2378
+ * "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1",
2379
+ * 0n,
2380
+ * { yParity: 1, r: "0x...", s: "0x..." },
2381
+ * "0x1234567890123456789012345678901234567890"
2382
+ * );
2383
+ * ```
2384
+ */
2385
+ declare function verifyEIP7702Authorization(chainId: bigint, contractAddress: string, nonce: bigint, signature: {
2386
+ yParity: number;
2387
+ r: string;
2388
+ s: string;
2389
+ } | string, expectedSigner: string): boolean;
2144
2390
 
2145
2391
  /**
2146
2392
  * Chainlist types
@@ -2195,11 +2441,11 @@ interface ChainlistOptions {
2195
2441
  */
2196
2442
 
2197
2443
  /**
2198
- * Get RPC endpoints for a specific chain ID, excluding those that require API keys
2444
+ * Get the HTTPS RPC endpoints for a specific chain ID, excluding those that require API keys
2199
2445
  *
2200
2446
  * @param chainId - The chain ID to get endpoints for
2201
2447
  * @param options - Optional configuration
2202
- * @returns Array of RPC URLs that don't require API keys
2448
+ * @returns Array of HTTPS RPC URLs that don't require API keys
2203
2449
  *
2204
2450
  * @example
2205
2451
  * ```typescript
@@ -2237,106 +2483,6 @@ declare function getChainById(chainId: number, options?: ChainlistOptions): Prom
2237
2483
  */
2238
2484
  declare function clearCache(): void;
2239
2485
 
2240
- interface MLKemKeypair {
2241
- publicKey: Uint8Array;
2242
- privateKey: Uint8Array;
2243
- }
2244
- interface EncryptedPayload {
2245
- version?: 2;
2246
- recipients: Array<{
2247
- publicKey: string;
2248
- ciphertext: string;
2249
- }>;
2250
- encryptedData: string;
2251
- iv: string;
2252
- authTag: string;
2253
- }
2254
- /**
2255
- * Derive deterministic ML-KEM-1024 keypair from any private key material
2256
- *
2257
- * Uses HKDF-SHA256 to derive a 64-byte seed from the input key material,
2258
- * then generates a reproducible ML-KEM-1024 keypair.
2259
- *
2260
- * @param privateKey - Private key material (hex string with optional 0x prefix, or Uint8Array)
2261
- * @param context - Context string for domain separation (default: 'mlkem-v1')
2262
- * @returns ML-KEM-1024 keypair (publicKey: 1568 bytes, privateKey: 3168 bytes)
2263
- *
2264
- * @example
2265
- * ```typescript
2266
- * // Derive from Ethereum private key
2267
- * const ethPrivateKey = '0x1234...';
2268
- * const keypair = await deriveMLKemKeypair(ethPrivateKey, 'my-app');
2269
- *
2270
- * // Derive from any 32-byte key
2271
- * const randomKey = crypto.getRandomValues(new Uint8Array(32));
2272
- * const keypair2 = await deriveMLKemKeypair(randomKey);
2273
- * ```
2274
- */
2275
- declare function deriveMLKemKeypair(privateKey: string | Uint8Array, context?: string): Promise<MLKemKeypair>;
2276
- /**
2277
- * Encrypt data using ML-KEM-1024 + AES-256-GCM for multiple recipients
2278
- *
2279
- * @param plaintext - The data to encrypt
2280
- * @param publicKeys - Array of ML-KEM-1024 public keys (base64 strings or Uint8Arrays, 1568 bytes each)
2281
- * @returns Encrypted payload with per-recipient ciphertexts and shared encrypted data
2282
- */
2283
- declare function mlkemEncrypt(plaintext: string, publicKeys: (string | Uint8Array) | Array<string | Uint8Array>): Promise<EncryptedPayload>;
2284
- /**
2285
- * Decrypt data encrypted with mlkemEncrypt()
2286
- *
2287
- * @param payload - The encrypted payload
2288
- * @param privateKey - ML-KEM-1024 private key (base64 string or Uint8Array, 3168 bytes)
2289
- * @param publicKey - Optional: Your public key to find the correct recipient entry (base64 string or Uint8Array, 1568 bytes)
2290
- * @returns Decrypted plaintext
2291
- */
2292
- declare function mlkemDecrypt(payload: EncryptedPayload, privateKey: string | Uint8Array, publicKey?: string | Uint8Array): Promise<string>;
2293
- /**
2294
- * Encrypt data with ML-KEM using derived keypairs from private keys
2295
- *
2296
- * This is a convenience function that derives ML-KEM keypairs from private key material,
2297
- * then encrypts the data for all recipients. The sender's keypair is derived and used
2298
- * as one of the recipients.
2299
- *
2300
- * @param plaintext - The data to encrypt
2301
- * @param senderPrivateKey - Sender's private key (hex string or Uint8Array)
2302
- * @param recipientPublicKeys - Array of recipient ML-KEM public keys (from deriveMLKemKeypair)
2303
- * @param senderContext - Context for sender's key derivation (default: 'mlkem-v1')
2304
- * @returns Encrypted payload with sender + recipients
2305
- *
2306
- * @example
2307
- * ```typescript
2308
- * // Encrypt for yourself + server
2309
- * const serverKeypair = await deriveMLKemKeypair(serverPrivateKey, 'server');
2310
- * const encrypted = await mlkemEncryptWithKey(
2311
- * 'secret data',
2312
- * myEthPrivateKey,
2313
- * [serverKeypair.publicKey]
2314
- * );
2315
- * ```
2316
- */
2317
- declare function mlkemEncryptWithKey(plaintext: string, senderPrivateKey: string | Uint8Array, recipientPublicKeys: Array<string | Uint8Array>, senderContext?: string): Promise<EncryptedPayload>;
2318
- /**
2319
- * Decrypt data with ML-KEM using a derived keypair from private key
2320
- *
2321
- * This is a convenience function that derives an ML-KEM keypair from private key material,
2322
- * then decrypts the payload.
2323
- *
2324
- * @param payload - The encrypted payload
2325
- * @param privateKey - Private key material (hex string or Uint8Array)
2326
- * @param context - Context for key derivation (default: 'mlkem-v1')
2327
- * @returns Decrypted plaintext
2328
- *
2329
- * @example
2330
- * ```typescript
2331
- * // Decrypt with your Ethereum private key
2332
- * const plaintext = await mlkemDecryptWithKey(
2333
- * encryptedPayload,
2334
- * myEthPrivateKey
2335
- * );
2336
- * ```
2337
- */
2338
- declare function mlkemDecryptWithKey(payload: EncryptedPayload, privateKey: string | Uint8Array, context?: string): Promise<string>;
2339
-
2340
2486
  declare function createWeb3Passkey(config?: Web3PasskeyConfig): Web3Passkey;
2341
2487
 
2342
- export { ApiError, AuthenticationError, type BackupMethod, type BackupStatus, CryptoError, DEFAULT_MODE, DEFAULT_TAG, type DeviceInfo, type EIP1193Provider, type EIP7702Authorization, type EncryptedBackupInfo, type EncryptedPayload, type Guardian, type GuardianInvite, type MLKemKeypair, type PasskeySelectionResult, type PrfSecret, PrfUnsupportedError, type QRBackupOptions, type RecoveryProgress, type RecoveryScenario, type RecoveryShare, RecoverySimulator, RegistrationError, type SecurityScore, type SignAuthorizationParams, type SimulationResult, type SiweMessage, type SocialRecoveryConfig, SocialRecoveryManager, type StealthAddressConfig, StealthAddressModule, type StealthAddressResult, type StealthKeys, StorageError, SyncBootstrapError, type SyncBootstrapReason, type SyncCapabilities, SyncRequiredError, type SyncStatus, type SyncVault, type UserInfo, WalletError, type WalletInfo, WalletMissingError, Web3Passkey, type Web3PasskeyConfig, Web3PasskeyError, arrayBufferToBase64Url, assertEthereumAddress, assertMnemonic, assertUsername, authenticateWithPasskey, base64ToArrayBuffer, base64UrlDecode, base64UrlToArrayBuffer, canControlStealthAddress, checkStealthAddress, clearCache, computeStealthPrivateKey, createSiweMessage, createWalletFromMnemonic, createWeb3Passkey, createWeb3Passkey as default, deriveAddressFromP256PublicKey, deriveIndexFromOriginModeAndTag, deriveMLKemKeypair, deriveStealthKeys, deriveWalletFromMnemonic, detectWalletProvider, encodeEIP7702AuthorizationMessage, extractRS, generateBIP39Wallet, generateSiweNonce, generateStealthAddress, getAllChains, getAllTopics, getChainById, getCurrentBuildHash, getCurrentOrigin, getDefaultProvider, getEndpoints, getExplainer, getOriginSpecificAddress, getPackageVersion, getW3pkBuildHash, hashEIP7702AuthorizationMessage, isStrongPassword, mlkemDecrypt, mlkemDecryptWithKey, mlkemEncrypt, mlkemEncryptWithKey, normalizeOrigin, parseSiweMessage, promptPasskeySelection, requestExternalWalletAuthorization, safeAtob, safeBtoa, searchExplainers, supportsEIP7702Authorization, validateEthereumAddress, validateMnemonic, validateSiweMessage, validateUsername, verifyBuildHash, verifyEIP7702Authorization, verifySiweSignature };
2488
+ export { AddressChangeError, type Announcement, ApiError, AuthenticationError, type BackupMethod, type BackupStatus, type Chain, type ChainlistOptions, type CircuitArtifacts, CryptoError, DEFAULT_MODE, DEFAULT_TAG, type DerivedWallet, type DeviceSyncInfo, type EIP1193ProviderInterface, type EIP7702Authorization, type EncryptedBackupInfo, type EncryptedPayload, type GeneratedWallet, type Groth16Proof, type GuardianShare, MLKEM_DEFAULT_CONTEXT, type MLKemKeypair, type MembershipProofInput, type NFTOwnershipProofInput, type OwnershipProofInput, type ParseAnnouncementResult, type PasskeySelectionResult, type PersistentSessionConfig, type PrfSecret, PrfUnsupportedError, type ProofType, type ProviderConnectInfo, type ProviderMessage, type ProviderRpcError, type RangeProofInput, type RecoveryScenario, RecoverySimulator, type RegisterResult, RegistrationError, RemovedBackupMethodError, type SecurityMode, type SecurityScore, type SemaphoreIdentity, type SignAuthorizationParams, type SignMessageOptions, type SigningMethod, type SimulationResult, type SiweMessage, type StealthAddressConfig, StealthAddressModule, type StealthAddressResult, type StealthKeys, type StealthTransaction, StorageError, SyncBootstrapError, type SyncBootstrapReason, type SyncCapabilities, SyncRequiredError, type ThresholdProofInput, UnsupportedBackupVersionError, type UserInfo, type VerificationResult, WalletError, WalletMissingError, WeakPasswordError, Web3Passkey, type Web3PasskeyConfig, Web3PasskeyError, type ZKMethods, type ZKProof, type ZKProofConfig, ZkArtifactMismatchError, type ZkArtifactName, type ZkDerivationTerm, type ZkInputs, type ZkProveArtifacts, type ZkProveOptions, type ZkProveResult, type ZkSecretSource, type ZkSignal, arrayBufferToBase64Url, assertEthereumAddress, assertMnemonic, assertUsername, authenticateWithPasskey, base64ToArrayBuffer, base64UrlDecode, base64UrlToArrayBuffer, canControlStealthAddress, checkStealthAddress, clearCache, computeStealthPrivateKey, createSiweMessage, createWalletFromMnemonic, createWeb3Passkey, createWeb3Passkey as default, deriveAddressFromP256PublicKey, deriveIndexFromOriginModeAndTag, deriveMLKemKeypair, deriveStealthKeys, deriveWalletFromMnemonic, encodeEIP7702AuthorizationMessage, extractRS, generateBIP39Wallet, generateSiweNonce, generateStealthAddress, getAllChains, getAllTopics, getChainById, getCurrentBuildHash, getCurrentOrigin, getEndpoints, getExplainer, getOriginSpecificAddress, getPackageVersion, getW3pkBuildHash, hashEIP7702AuthorizationMessage, isStrongPassword, mlkemDecrypt, mlkemDecryptWithKey, mlkemEncrypt, mlkemEncryptWithKey, normalizeOrigin, parseSiweMessage, promptPasskeySelection, safeAtob, safeBtoa, searchExplainers, validateEthereumAddress, validateMnemonic, validateSiweMessage, validateUsername, verifyBuildHash, verifyEIP7702Authorization, verifySiweSignature };