@volr/sdk-core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1338 @@
1
+ import { AxiosInstance } from 'axios';
2
+
3
+ /**
4
+ * HKDF-SHA256 key derivation
5
+ *
6
+ * @param ikm - Input Key Material (32 bytes recommended)
7
+ * @param salt - Salt (can be empty, but 32 bytes recommended)
8
+ * @param info - Application-specific info string
9
+ * @param len - Output length in bytes (default: 32)
10
+ * @returns Derived key material
11
+ * @throws VolrError if info is empty or other validation fails
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * const ikm = new Uint8Array(32).fill(0x01);
16
+ * const salt = new Uint8Array(32).fill(0x02);
17
+ * const key = hkdfSha256(ikm, salt, 'volr/wrap-key/v1', 32);
18
+ * ```
19
+ */
20
+ declare function hkdfSha256(ikm: Uint8Array, salt: Uint8Array, info: string, len?: number): Uint8Array;
21
+
22
+ /**
23
+ * AES-GCM encryption parameters
24
+ */
25
+ type AesGcmParams = {
26
+ /** 32-byte encryption key */
27
+ key: Uint8Array;
28
+ /** 12-byte nonce (optional, will be generated if not provided) */
29
+ nonce?: Uint8Array;
30
+ /** Additional Authenticated Data (optional) */
31
+ aad?: Uint8Array;
32
+ };
33
+ /**
34
+ * AES-256-GCM encryption
35
+ *
36
+ * @param plain - Plaintext to encrypt
37
+ * @param params - Encryption parameters (key, optional nonce, optional AAD)
38
+ * @returns Object containing ciphertext and nonce
39
+ * @throws VolrError if key is not 32 bytes, nonce is not 12 bytes, or encryption fails
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * const key = getRandomBytes(32);
44
+ * const plaintext = new TextEncoder().encode('secret data');
45
+ * const { cipher, nonce } = await aesGcmEncrypt(plaintext, { key });
46
+ * ```
47
+ */
48
+ declare function aesGcmEncrypt(plain: Uint8Array, params: AesGcmParams): Promise<{
49
+ cipher: Uint8Array;
50
+ nonce: Uint8Array;
51
+ }>;
52
+ /**
53
+ * AES-256-GCM decryption
54
+ *
55
+ * @param cipher - Ciphertext to decrypt
56
+ * @param params - Decryption parameters (key, nonce, optional AAD)
57
+ * @returns Decrypted plaintext
58
+ * @throws VolrError if decryption fails (wrong key, wrong AAD, corrupted data)
59
+ *
60
+ * @example
61
+ * ```ts
62
+ * const plaintext = await aesGcmDecrypt(cipher, { key, nonce });
63
+ * ```
64
+ */
65
+ declare function aesGcmDecrypt(cipher: Uint8Array, params: AesGcmParams & {
66
+ nonce: Uint8Array;
67
+ }): Promise<Uint8Array>;
68
+
69
+ /**
70
+ * Zeroize (overwrite with zeros) a buffer in place
71
+ * This helps prevent sensitive data from remaining in memory
72
+ *
73
+ * @param buf - Uint8Array or ArrayBuffer to zeroize
74
+ */
75
+ declare function zeroize(buf: Uint8Array | ArrayBuffer): void;
76
+
77
+ /**
78
+ * Get secure random bytes using WebCrypto API
79
+ * Falls back to Node.js crypto.webcrypto if WebCrypto is not available
80
+ *
81
+ * @param len - Number of bytes to generate
82
+ * @returns Uint8Array of random bytes
83
+ * @throws VolrError if random generation fails
84
+ */
85
+ declare function getRandomBytes(len: number): Uint8Array;
86
+
87
+ /**
88
+ * Opaque type for WrapKey (32 bytes)
89
+ * This is a type-level marker to prevent accidental misuse
90
+ */
91
+ type WrapKey = Uint8Array & {
92
+ readonly __brand: 'WrapKey';
93
+ };
94
+ /**
95
+ * Opaque type for MasterSeed (32 bytes)
96
+ * This is a type-level marker to prevent accidental misuse
97
+ */
98
+ type MasterSeed = Uint8Array & {
99
+ readonly __brand: 'MasterSeed';
100
+ };
101
+
102
+ /**
103
+ * Opaque handle to master seed
104
+ * Provides controlled access and ensures cleanup via destroy()
105
+ */
106
+ type MasterSeedHandle = {
107
+ /** Read-only access to master seed bytes */
108
+ readonly bytes: MasterSeed;
109
+ /** Destroy the handle and zeroize the seed */
110
+ destroy(): void;
111
+ };
112
+ /**
113
+ * Master key provider interface
114
+ * Handles generation and unsealing of master seeds
115
+ */
116
+ interface MasterKeyProvider {
117
+ /**
118
+ * Unseal master seed from encrypted blob
119
+ *
120
+ * @param blob - Encrypted blob containing ciphertext, nonce, and AAD
121
+ * @param wrapKey - Wrap key for decryption
122
+ * @returns Handle to unsealed master seed
123
+ */
124
+ unsealFromBlob(blob: {
125
+ cipher: Uint8Array;
126
+ nonce: Uint8Array;
127
+ aad: Uint8Array;
128
+ }, wrapKey: WrapKey): Promise<MasterSeedHandle>;
129
+ /**
130
+ * Generate a new master seed
131
+ *
132
+ * @returns Handle to newly generated master seed
133
+ */
134
+ generate(): Promise<MasterSeedHandle>;
135
+ }
136
+ /**
137
+ * Create a master key provider instance
138
+ *
139
+ * @returns MasterKeyProvider instance
140
+ *
141
+ * @example
142
+ * ```ts
143
+ * const provider = createMasterKeyProvider();
144
+ * const handle = await provider.generate();
145
+ * // Use handle.bytes for key derivation
146
+ * handle.destroy(); // Cleanup
147
+ * ```
148
+ */
149
+ declare function createMasterKeyProvider(): MasterKeyProvider;
150
+
151
+ /**
152
+ * Seal (encrypt) master seed with wrap key
153
+ *
154
+ * @param masterSeed - 32-byte master seed to encrypt
155
+ * @param wrapKey - 32-byte wrap key
156
+ * @param aad - Additional Authenticated Data
157
+ * @returns Object containing ciphertext and nonce
158
+ *
159
+ * @example
160
+ * ```ts
161
+ * const masterSeed = getRandomBytes(32);
162
+ * const wrapKey = deriveWrapKey({ origin, projectId, credentialId });
163
+ * const aad = new TextEncoder().encode('volr/master-seed/v1');
164
+ * const { cipher, nonce } = await sealMasterSeed(masterSeed, wrapKey, aad);
165
+ * ```
166
+ */
167
+ declare function sealMasterSeed(masterSeed: Uint8Array, wrapKey: WrapKey, aad: Uint8Array): Promise<{
168
+ cipher: Uint8Array;
169
+ nonce: Uint8Array;
170
+ }>;
171
+ /**
172
+ * Unseal (decrypt) master seed with wrap key
173
+ *
174
+ * @param cipher - Encrypted master seed
175
+ * @param wrapKey - 32-byte wrap key
176
+ * @param aad - Additional Authenticated Data (must match encryption)
177
+ * @param nonce - 12-byte nonce used during encryption
178
+ * @returns Decrypted master seed (32 bytes)
179
+ * @throws Error if decryption fails (wrong key, wrong AAD, corrupted data)
180
+ *
181
+ * @example
182
+ * ```ts
183
+ * const masterSeed = await unsealMasterSeed(cipher, wrapKey, aad, nonce);
184
+ * // Use masterSeed, then zeroize it
185
+ * zeroize(masterSeed);
186
+ * ```
187
+ */
188
+ declare function unsealMasterSeed(cipher: Uint8Array, wrapKey: WrapKey, aad: Uint8Array, nonce: Uint8Array): Promise<MasterSeed>;
189
+
190
+ /**
191
+ * PRF input parameters for wrap key derivation
192
+ */
193
+ type PrfInput = {
194
+ /** Origin (e.g., "https://example.com") */
195
+ origin: string;
196
+ /** Project ID */
197
+ projectId: string;
198
+ /** Credential ID from WebAuthn */
199
+ credentialId: string;
200
+ /** Optional salt (defaults to SHA256 of concatenated inputs) */
201
+ salt?: Uint8Array;
202
+ };
203
+ /**
204
+ * Derive wrap key from PRF inputs using HKDF
205
+ *
206
+ * PRF input domain is fixed: rpId|projectId (credentialId excluded)
207
+ * This ensures consistent wrap key derivation across sessions
208
+ *
209
+ * Note: credentialId is NOT included in salt derivation because:
210
+ * - During enrollment, actual credentialId is not known until after credential creation
211
+ * - Using credentialId would create different salts for enrollment vs authentication
212
+ * - This would cause PRF to return different outputs, breaking decryption
213
+ *
214
+ * This function maps PRF output (from WebAuthn) to a 32-byte wrap key.
215
+ * In the real implementation, the PRF output would come from WebAuthn PRF API.
216
+ * For now, we simulate it by using SHA256 of the inputs.
217
+ *
218
+ * @param input - PRF input parameters
219
+ * @returns 32-byte wrap key
220
+ *
221
+ * @example
222
+ * ```ts
223
+ * const wrapKey = deriveWrapKey({
224
+ * origin: 'https://example.com',
225
+ * projectId: 'project-123',
226
+ * credentialId: 'cred-456' // stored for authentication, but not used in salt derivation
227
+ * });
228
+ * ```
229
+ */
230
+ declare function deriveWrapKey(input: PrfInput): WrapKey;
231
+
232
+ /**
233
+ * Default BIP-32 derivation path for Ethereum
234
+ * m / purpose' / coin_type' / account' / change / address_index
235
+ * 60' = Ethereum coin type
236
+ */
237
+ declare const DEFAULT_EVM_PATH = "m/60'/0'/0'/0/0";
238
+ /**
239
+ * Arguments for EVM key derivation
240
+ */
241
+ type DeriveArgs = {
242
+ /** Master seed (32 bytes recommended) */
243
+ masterSeed: Uint8Array;
244
+ /** BIP-32 derivation path (default: m/60'/0'/0'/0/0) */
245
+ path?: string;
246
+ };
247
+ /**
248
+ * EVM keypair derived from master seed
249
+ */
250
+ type EvmKeypair = {
251
+ /** 32-byte private key */
252
+ privateKey: Uint8Array;
253
+ /** 65-byte uncompressed public key (0x04 prefix) */
254
+ publicKey: Uint8Array;
255
+ /** 20-byte EOA address (checksummed) */
256
+ address: `0x${string}`;
257
+ /** Derivation path used */
258
+ path: string;
259
+ };
260
+ /**
261
+ * Derive EVM keypair from master seed using BIP-32
262
+ *
263
+ * @param args - Derivation arguments
264
+ * @returns EVM keypair with private key, public key, and address
265
+ *
266
+ * @example
267
+ * ```ts
268
+ * const masterSeed = getRandomBytes(32);
269
+ * const keypair = deriveEvmKey({ masterSeed });
270
+ * // Use keypair.privateKey for signing
271
+ * // Use keypair.address as EOA address
272
+ * ```
273
+ */
274
+ declare function deriveEvmKey(args: DeriveArgs): EvmKeypair;
275
+
276
+ /**
277
+ * Convert Ethereum address to EIP-55 checksum format
278
+ *
279
+ * EIP-55: Mixed-case checksum address encoding
280
+ * https://eips.ethereum.org/EIPS/eip-55
281
+ *
282
+ * @param addr - Lowercase Ethereum address (0x prefix required)
283
+ * @returns Checksummed address
284
+ * @throws Error if address is invalid (wrong length, non-hex, missing 0x prefix)
285
+ *
286
+ * @example
287
+ * ```ts
288
+ * const checksummed = toChecksumAddress('0x742d35cc6634c0532925a3b844bc9e7595f0bebd');
289
+ * // Returns: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbD'
290
+ * ```
291
+ */
292
+ declare function toChecksumAddress(addr: `0x${string}`): `0x${string}`;
293
+
294
+ /**
295
+ * EVM signature structure
296
+ */
297
+ type Sig$1 = {
298
+ /** 32-byte r value */
299
+ r: Uint8Array;
300
+ /** 32-byte s value (low-S canonicalized) */
301
+ s: Uint8Array;
302
+ /** y-parity (0 or 1) */
303
+ yParity: 0 | 1;
304
+ };
305
+ /**
306
+ * Sign a message hash with secp256k1 private key
307
+ *
308
+ * Produces deterministic, low-S canonicalized signatures compatible with EVM.
309
+ *
310
+ * @param privKey - 32-byte private key
311
+ * @param msgHash32 - 32-byte message hash
312
+ * @returns Signature with r, s, and yParity
313
+ * @throws Error if private key or message hash is invalid
314
+ *
315
+ * @example
316
+ * ```ts
317
+ * const privateKey = getRandomBytes(32);
318
+ * const msgHash = sha256(new TextEncoder().encode('Hello'));
319
+ * const sig = evmSign(privateKey, msgHash);
320
+ * // Use sig.r, sig.s, sig.yParity for transaction signing
321
+ * ```
322
+ */
323
+ declare function evmSign(privKey: Uint8Array, msgHash32: Uint8Array): Sig$1;
324
+
325
+ /**
326
+ * Provider types for EVM wallet operations
327
+ */
328
+
329
+ /**
330
+ * RPC client interface for capability detection
331
+ */
332
+ interface RpcLike {
333
+ call(args: {
334
+ to: `0x${string}`;
335
+ data: `0x${string}`;
336
+ }): Promise<`0x${string}`>;
337
+ }
338
+ /**
339
+ * EIP-712 typed data structure
340
+ */
341
+ type TypedDataInput = {
342
+ domain: any;
343
+ types: any;
344
+ message: any;
345
+ };
346
+ /**
347
+ * Common wallet provider port interface
348
+ * Both Passkey and MPC providers implement this interface
349
+ */
350
+ interface WalletProviderPort {
351
+ /** Key storage type: 'passkey' or 'mpc' */
352
+ keyStorageType: KeyStorageType;
353
+ /**
354
+ * Ensure session is established
355
+ * - Passkey: PRF → unwrap master seed
356
+ * - MPC: Backend proxy session setup
357
+ *
358
+ * @param opts - Session options
359
+ * @param opts.interactive - If true, requires user gesture (WebAuthn prompt)
360
+ * @param opts.force - If true, invalidates existing session and re-authenticates
361
+ */
362
+ ensureSession(opts?: {
363
+ interactive?: boolean;
364
+ force?: boolean;
365
+ }): Promise<void>;
366
+ /**
367
+ * Lock the provider (zeroize sensitive data from memory)
368
+ * Should be called after each transaction for TTL=0 behavior
369
+ */
370
+ lock?(): Promise<void>;
371
+ /**
372
+ * Get EOA address
373
+ * @returns Ethereum address (checksummed)
374
+ */
375
+ getAddress(): Promise<`0x${string}`>;
376
+ /**
377
+ * Sign message hash with secp256k1
378
+ * @param hash32 - 32-byte message hash
379
+ * @returns Signature components
380
+ */
381
+ signMessage(hash32: Uint8Array): Promise<{
382
+ r: Uint8Array;
383
+ s: Uint8Array;
384
+ yParity: 0 | 1;
385
+ }>;
386
+ /**
387
+ * Sign EIP-712 typed data
388
+ * @param input - Typed data structure
389
+ * @returns Signature hex string
390
+ */
391
+ signTypedData(input: TypedDataInput): Promise<`0x${string}`>;
392
+ /**
393
+ * Get public key (optional, for signer creation)
394
+ * @returns 65-byte uncompressed public key (0x04 prefix)
395
+ */
396
+ getPublicKey?(): Promise<Uint8Array>;
397
+ /**
398
+ * Optional capability hints
399
+ * - p256: Whether P-256 signing is supported
400
+ * - secp256k1: Whether secp256k1 signing is supported (default: true)
401
+ */
402
+ capabilities?: {
403
+ p256?: boolean;
404
+ secp256k1?: boolean;
405
+ };
406
+ }
407
+ /**
408
+ * MPC transport interface for backend proxy communication
409
+ * Vendor-agnostic: no vendor names in interface
410
+ */
411
+ interface MpcTransport {
412
+ /**
413
+ * Ensure session is established with backend
414
+ */
415
+ ensureSession(): Promise<void>;
416
+ /**
417
+ * Get EOA address from backend
418
+ * @returns Ethereum address
419
+ */
420
+ getAddress(): Promise<`0x${string}`>;
421
+ /**
422
+ * Sign message hash via backend proxy
423
+ * @param hash32 - 32-byte message hash
424
+ * @returns Signature components
425
+ */
426
+ signMessage(hash32: Uint8Array): Promise<{
427
+ r: Uint8Array;
428
+ s: Uint8Array;
429
+ yParity: 0 | 1;
430
+ }>;
431
+ /**
432
+ * Sign EIP-712 typed data via backend proxy
433
+ * @param input - Typed data structure
434
+ * @returns Signature hex string
435
+ */
436
+ signTypedData(input: TypedDataInput): Promise<`0x${string}`>;
437
+ /**
438
+ * Get public key from backend (optional, for signer creation)
439
+ * @returns 65-byte uncompressed public key (0x04 prefix)
440
+ */
441
+ getPublicKey?(): Promise<Uint8Array>;
442
+ }
443
+
444
+ /**
445
+ * Signer port interface for abstracting signing operations
446
+ * Supports both P-256 (TEE/passkey) and secp256k1 (software) signing
447
+ */
448
+ interface SignerPort {
449
+ /**
450
+ * Get public key in uncompressed format
451
+ * - secp256k1: 65 bytes (0x04 || x || y)
452
+ * - P-256: 65 bytes (0x04 || x || y)
453
+ *
454
+ * @returns Uncompressed public key
455
+ */
456
+ getPublicKey(): Promise<Uint8Array>;
457
+ /**
458
+ * Sign a message hash
459
+ *
460
+ * @param msgHash32 - 32-byte message hash (already hashed)
461
+ * @returns Signature with r, s, and yParity
462
+ */
463
+ signMessage(msgHash32: Uint8Array): Promise<{
464
+ r: Uint8Array;
465
+ s: Uint8Array;
466
+ yParity: 0 | 1;
467
+ }>;
468
+ /**
469
+ * Sign raw hash without EIP-191 prefix (for EIP-7702)
470
+ *
471
+ * @param digest - 32-byte digest to sign (raw, no prefix)
472
+ * @returns Signature with r, s, and yParity
473
+ */
474
+ signRawHash(digest: Uint8Array): Promise<{
475
+ r: Uint8Array;
476
+ s: Uint8Array;
477
+ yParity: 0 | 1;
478
+ }>;
479
+ /**
480
+ * Sign typed data (optional, for future EIP-712 support)
481
+ *
482
+ * @param typed - Typed data structure
483
+ * @returns Signature hex string
484
+ */
485
+ signTyped?(typed: unknown): Promise<`0x${string}`>;
486
+ }
487
+ /**
488
+ * Passkey provider port interface
489
+ * Abstracts WebAuthn passkey operations (to be implemented in react package)
490
+ */
491
+ interface PasskeyProviderPort {
492
+ /**
493
+ * Get P-256 public key from passkey
494
+ *
495
+ * @returns Public key coordinates (x, y)
496
+ */
497
+ getPublicKey(): Promise<{
498
+ x: Uint8Array;
499
+ y: Uint8Array;
500
+ }>;
501
+ /**
502
+ * Sign message hash using P-256 passkey
503
+ *
504
+ * @param msgHash32 - 32-byte message hash
505
+ * @returns Signature components (r, s)
506
+ */
507
+ signP256(msgHash32: Uint8Array): Promise<{
508
+ r: Uint8Array;
509
+ s: Uint8Array;
510
+ }>;
511
+ /**
512
+ * Authenticate with WebAuthn and get PRF output
513
+ * This triggers a user gesture (biometric/PIN prompt)
514
+ *
515
+ * @param prfInput - PRF evaluation input (salt)
516
+ * @param credentialId - Optional credential ID to use
517
+ * @returns PRF output (32 bytes)
518
+ */
519
+ authenticate(prfInput: {
520
+ salt: Uint8Array;
521
+ credentialId?: string;
522
+ }): Promise<{
523
+ prfOutput: Uint8Array;
524
+ credentialId: string;
525
+ }>;
526
+ }
527
+ /**
528
+ * Key storage type identifier
529
+ * Represents the method used to store cryptographic keys: Passkey (hardware-based) or MPC (Multi-Party Computation)
530
+ */
531
+ type KeyStorageType = 'passkey' | 'mpc';
532
+ /**
533
+ * Signer kind identifier
534
+ */
535
+ type SignerKind = 'secp256k1' | 'passkey-p256';
536
+ /**
537
+ * Signer context for routing
538
+ */
539
+ type SignerContext = {
540
+ /** RPC client for capability detection */
541
+ client: any;
542
+ /** Chain ID */
543
+ chainId: number;
544
+ /** Optional wallet provider (for provider-based routing) */
545
+ provider?: WalletProviderPort;
546
+ /** Optional passkey provider (for P-256 path) */
547
+ passkey?: PasskeyProviderPort;
548
+ /** Optional secp256k1 private key (for fallback path) */
549
+ secpKey?: Uint8Array;
550
+ };
551
+
552
+ /**
553
+ * Select appropriate signer based on chain capabilities and available inputs
554
+ *
555
+ * Routing logic:
556
+ * 1. If provider provided → ProviderBackedSigner (delegates to provider)
557
+ * 2. Else if secpKey provided → Secp256k1SoftwareSigner
558
+ * 3. Else → throw error
559
+ *
560
+ * @param ctx - Signer context
561
+ * @returns Selected signer with kind identifier
562
+ * @throws VolrError if no signer input is available
563
+ *
564
+ * @example
565
+ * ```ts
566
+ * const ctx = {
567
+ * client: rpcClient,
568
+ * chainId: 10,
569
+ * provider: walletProvider,
570
+ * };
571
+ * const { kind, signer } = await selectSigner(ctx);
572
+ * const sig = await signer.signMessage(msgHash);
573
+ * ```
574
+ */
575
+ declare function selectSigner$1(ctx: SignerContext): Promise<{
576
+ kind: SignerKind;
577
+ signer: SignerPort;
578
+ }>;
579
+
580
+ /**
581
+ * EVM signature structure
582
+ */
583
+ type Sig = {
584
+ /** 32-byte r value */
585
+ r: Uint8Array;
586
+ /** 32-byte s value (low-S canonicalized) */
587
+ s: Uint8Array;
588
+ /** y-parity (0 or 1) */
589
+ yParity: 0 | 1;
590
+ };
591
+ /**
592
+ * Secp256k1 software signer implementation
593
+ * Uses existing master-key → BIP-32 → secp256k1 derivation path
594
+ *
595
+ * @example
596
+ * ```ts
597
+ * const privateKey = getRandomBytes(32);
598
+ * const signer = new Secp256k1SoftwareSigner(privateKey);
599
+ * const sig = await signer.signMessage(msgHash);
600
+ * ```
601
+ */
602
+ declare class Secp256k1SoftwareSigner implements SignerPort {
603
+ private privateKey;
604
+ constructor(privateKey: Uint8Array);
605
+ /**
606
+ * Get uncompressed public key (65 bytes)
607
+ *
608
+ * @returns Uncompressed public key with 0x04 prefix
609
+ */
610
+ getPublicKey(): Promise<Uint8Array>;
611
+ /**
612
+ * Sign message hash with deterministic, low-S canonicalization
613
+ *
614
+ * @param msgHash32 - 32-byte message hash
615
+ * @returns Signature with r, s, and yParity
616
+ * @throws Error if message hash is invalid
617
+ */
618
+ signMessage(msgHash32: Uint8Array): Promise<{
619
+ r: Uint8Array;
620
+ s: Uint8Array;
621
+ yParity: 0 | 1;
622
+ }>;
623
+ /**
624
+ * Sign raw hash without EIP-191 prefix (for EIP-7702)
625
+ *
626
+ * @param digest - 32-byte digest to sign
627
+ * @returns Signature with r, s, and yParity
628
+ * @throws Error if digest is invalid
629
+ */
630
+ signRawHash(digest: Uint8Array): Promise<{
631
+ r: Uint8Array;
632
+ s: Uint8Array;
633
+ yParity: 0 | 1;
634
+ }>;
635
+ /**
636
+ * Sign EIP-712 typed data
637
+ */
638
+ signTyped(data: {
639
+ domain: any;
640
+ types: any;
641
+ primaryType: string;
642
+ message: any;
643
+ }): Promise<`0x${string}`>;
644
+ }
645
+ /**
646
+ * Verify a secp256k1 signature against a public key and message hash
647
+ *
648
+ * @param pubKeyUncompressed - 65-byte uncompressed public key (0x04 prefix)
649
+ * @param msgHash32 - 32-byte message hash
650
+ * @param sig - Signature to verify
651
+ * @returns true if signature is valid, false otherwise
652
+ * @throws Error if public key or message hash is invalid
653
+ *
654
+ * @example
655
+ * ```ts
656
+ * const isValid = evmVerify(publicKey, msgHash, sig);
657
+ * if (isValid) {
658
+ * console.log('Signature is valid');
659
+ * }
660
+ * ```
661
+ */
662
+ declare function evmVerify(pubKeyUncompressed: Uint8Array, msgHash32: Uint8Array, sig: Sig): boolean;
663
+
664
+ /**
665
+ * Passkey P-256 signer implementation
666
+ * Uses device TEE/passkey for signing (P-256 curve)
667
+ *
668
+ * @example
669
+ * ```ts
670
+ * const passkeyProvider = createPasskeyProvider();
671
+ * const signer = new PasskeyP256Signer(passkeyProvider);
672
+ * const sig = await signer.signMessage(msgHash);
673
+ * ```
674
+ */
675
+ declare class PasskeyP256Signer implements SignerPort {
676
+ private provider;
677
+ constructor(provider: PasskeyProviderPort);
678
+ /**
679
+ * Get uncompressed P-256 public key (65 bytes)
680
+ *
681
+ * @returns Uncompressed public key with 0x04 prefix
682
+ */
683
+ getPublicKey(): Promise<Uint8Array>;
684
+ /**
685
+ * Sign message hash using P-256 passkey
686
+ *
687
+ * @param msgHash32 - 32-byte message hash
688
+ * @returns Signature with r, s, and yParity
689
+ * @throws Error if message hash is invalid
690
+ */
691
+ signMessage(msgHash32: Uint8Array): Promise<{
692
+ r: Uint8Array;
693
+ s: Uint8Array;
694
+ yParity: 0 | 1;
695
+ }>;
696
+ /**
697
+ * Sign raw hash without EIP-191 prefix (for EIP-7702)
698
+ *
699
+ * @param _digest - 32-byte digest to sign
700
+ * @returns Signature with r, s, and yParity
701
+ * @throws Error - P-256 cannot be used for EIP-7702
702
+ */
703
+ signRawHash(_digest: Uint8Array): Promise<{
704
+ r: Uint8Array;
705
+ s: Uint8Array;
706
+ yParity: 0 | 1;
707
+ }>;
708
+ /**
709
+ * Sign EIP-712 typed data
710
+ */
711
+ signTyped(data: {
712
+ domain: any;
713
+ types: any;
714
+ primaryType: string;
715
+ message: any;
716
+ }): Promise<`0x${string}`>;
717
+ }
718
+
719
+ /**
720
+ * EIP-1193 Provider interface
721
+ * https://eips.ethereum.org/EIPS/eip-1193
722
+ */
723
+ interface EIP1193Provider {
724
+ request(args: {
725
+ method: string;
726
+ params?: unknown[] | object;
727
+ }): Promise<unknown>;
728
+ on?(event: string, listener: (...args: any[]) => void): void;
729
+ removeListener?(event: string, listener: (...args: any[]) => void): void;
730
+ }
731
+ /**
732
+ * External Wallet Signer
733
+ *
734
+ * Uses an external wallet (MetaMask, WalletConnect, etc.) via EIP-1193 provider
735
+ * for signing operations. This signer performs network validation before each
736
+ * signing operation to prevent cross-chain replay attacks.
737
+ *
738
+ * Security features:
739
+ * - Network validation before signing
740
+ * - Error normalization for consistent error handling
741
+ * - Support for EIP-712 typed data signing
742
+ *
743
+ * @example
744
+ * ```ts
745
+ * const provider = window.ethereum;
746
+ * const signer = new ExternalWalletSigner(provider, 1, '0xAbC...');
747
+ * const sig = await signer.signMessage(msgHash);
748
+ * ```
749
+ */
750
+ declare class ExternalWalletSigner implements SignerPort {
751
+ private readonly provider;
752
+ private readonly expectedChainId;
753
+ private readonly address;
754
+ constructor(provider: EIP1193Provider, expectedChainId: number, address: string);
755
+ /**
756
+ * Verify that the wallet is on the correct network
757
+ * @throws WrongNetworkError if network mismatch
758
+ */
759
+ private verifyNetwork;
760
+ /**
761
+ * Get the wallet address
762
+ */
763
+ getAddress(): Promise<`0x${string}`>;
764
+ /**
765
+ * Get public key - not directly supported by EIP-1193
766
+ * Returns a placeholder as external wallets don't expose raw public keys
767
+ *
768
+ * For external wallets, we rely on address-based verification instead
769
+ */
770
+ getPublicKey(): Promise<Uint8Array>;
771
+ /**
772
+ * Sign a message hash using personal_sign
773
+ *
774
+ * Note: personal_sign automatically adds EIP-191 prefix
775
+ *
776
+ * @param msgHash32 - 32-byte message hash
777
+ * @returns Signature components (r, s, yParity)
778
+ */
779
+ signMessage(msgHash32: Uint8Array): Promise<{
780
+ r: Uint8Array;
781
+ s: Uint8Array;
782
+ yParity: 0 | 1;
783
+ }>;
784
+ /**
785
+ * Sign raw hash for EIP-7702 authorization
786
+ *
787
+ * External wallets don't support raw hash signing directly (eth_sign is deprecated/disabled).
788
+ * Instead, we use personal_sign which adds EIP-191 prefix, then we need to account for this
789
+ * when verifying the signature on-chain.
790
+ *
791
+ * ⚠️ IMPORTANT: This creates a signature over the EIP-191 prefixed message, NOT the raw digest.
792
+ * The backend/contract must verify accordingly.
793
+ *
794
+ * Alternative approach: Use EIP-712 typed data for authorization (more wallet-friendly)
795
+ *
796
+ * @param digest - 32-byte digest to sign
797
+ * @returns Signature components (r, s, yParity)
798
+ * @throws WalletError if signing fails
799
+ */
800
+ signRawHash(digest: Uint8Array): Promise<{
801
+ r: Uint8Array;
802
+ s: Uint8Array;
803
+ yParity: 0 | 1;
804
+ }>;
805
+ /**
806
+ * Sign typed data (EIP-712)
807
+ *
808
+ * @param typed - Typed data structure with domain, types, and message
809
+ * @returns Signature hex string
810
+ */
811
+ signTyped(typed: unknown): Promise<`0x${string}`>;
812
+ /**
813
+ * Switch to the expected network
814
+ *
815
+ * @returns true if switch successful, false if user rejected
816
+ * @throws Error if switch fails for other reasons
817
+ */
818
+ switchNetwork(): Promise<boolean>;
819
+ /**
820
+ * Add a new network to the wallet
821
+ *
822
+ * @param chainConfig - Network configuration
823
+ * @returns true if add successful, false if user rejected
824
+ */
825
+ addNetwork(chainConfig: {
826
+ chainId: string;
827
+ chainName: string;
828
+ nativeCurrency: {
829
+ name: string;
830
+ symbol: string;
831
+ decimals: number;
832
+ };
833
+ rpcUrls: string[];
834
+ blockExplorerUrls?: string[];
835
+ }): Promise<boolean>;
836
+ }
837
+
838
+ /**
839
+ * EIP-1193 Provider Error Codes
840
+ * https://eips.ethereum.org/EIPS/eip-1193#provider-errors
841
+ */
842
+ declare enum EIP1193ErrorCode {
843
+ USER_REJECTED = 4001,
844
+ UNAUTHORIZED = 4100,
845
+ UNSUPPORTED_METHOD = 4200,
846
+ DISCONNECTED = 4900,
847
+ CHAIN_DISCONNECTED = 4901,
848
+ UNRECOGNIZED_CHAIN = 4902,
849
+ RESOURCE_UNAVAILABLE = -32002,
850
+ RESOURCE_NOT_FOUND = -32001,
851
+ INVALID_INPUT = -32000,
852
+ INTERNAL_ERROR = -32603,
853
+ INVALID_REQUEST = -32600,
854
+ METHOD_NOT_FOUND = -32601,
855
+ INVALID_PARAMS = -32602,
856
+ PARSE_ERROR = -32700
857
+ }
858
+ /**
859
+ * Normalized wallet error types
860
+ */
861
+ declare class WalletError extends Error {
862
+ readonly code: EIP1193ErrorCode | number;
863
+ readonly originalError?: unknown | undefined;
864
+ constructor(message: string, code: EIP1193ErrorCode | number, originalError?: unknown | undefined);
865
+ }
866
+ declare class UserRejectedError extends WalletError {
867
+ constructor(message?: string, originalError?: unknown);
868
+ }
869
+ declare class UnauthorizedError extends WalletError {
870
+ constructor(message?: string, originalError?: unknown);
871
+ }
872
+ declare class UnsupportedMethodError extends WalletError {
873
+ constructor(message?: string, originalError?: unknown);
874
+ }
875
+ declare class WrongNetworkError extends WalletError {
876
+ readonly expectedChainId?: number | undefined;
877
+ readonly actualChainId?: number | undefined;
878
+ constructor(message?: string, expectedChainId?: number | undefined, actualChainId?: number | undefined, originalError?: unknown);
879
+ }
880
+ declare class ChainNotAddedError extends WalletError {
881
+ constructor(message?: string, originalError?: unknown);
882
+ }
883
+ declare class RequestPendingError extends WalletError {
884
+ constructor(message?: string, originalError?: unknown);
885
+ }
886
+ /**
887
+ * Normalize EIP-1193 provider errors to typed error classes
888
+ */
889
+ declare function normalizeWalletError(error: unknown): WalletError;
890
+
891
+ /**
892
+ * Cross‑platform helper to upload an encrypted blob via backend (backend handles S3 upload).
893
+ * Uses axios for consistent error handling and request/response interceptors.
894
+ */
895
+
896
+ interface UploadBlobOptions {
897
+ /** Backend base URL, e.g. https://api.example.com */
898
+ baseUrl: string;
899
+ /** Project API key to send as X-API-Key header */
900
+ apiKey: string;
901
+ /** Bearer token for Authorization header */
902
+ accessToken: string;
903
+ /** Blob or binary content to upload */
904
+ blob: Blob | ArrayBuffer | Uint8Array;
905
+ /** Optional axios instance (if you want to reuse an existing instance with interceptors) */
906
+ axiosInstance?: AxiosInstance;
907
+ }
908
+ /**
909
+ * Uploads blob to backend, which handles S3 upload directly.
910
+ * Returns `{ key: string }` (S3 key) on success.
911
+ *
912
+ * This helper intentionally lives in @volr/sdk-core (not UI, not backend) so it can be reused
913
+ * by web, React Native, Node, etc. It uses axios for consistent error handling.
914
+ */
915
+ declare function uploadBlob(options: UploadBlobOptions): Promise<{
916
+ key: string;
917
+ }>;
918
+ /**
919
+ * Cross‑platform helper to upload an encrypted blob via S3 presigned PUT.
920
+ * Runs in browsers (uses global fetch) and in Node 18+ (built‑in fetch).
921
+ */
922
+ interface UploadViaPresignOptions {
923
+ /** Backend base URL, e.g. https://api.example.com */
924
+ baseUrl: string;
925
+ /** Project API key to send as X-API-Key header (optional if backend not requiring it) */
926
+ apiKey?: string | null;
927
+ /** Bearer token for Authorization header (optional if cookie-based auth is sufficient) */
928
+ accessToken?: string | null;
929
+ /** Blob or binary content to upload */
930
+ blob: Blob | ArrayBuffer | Uint8Array;
931
+ /** MIME type for the uploaded object; defaults to application/octet-stream */
932
+ contentType?: string;
933
+ /** Optional fetch implementation override (e.g. pass global fetch in RN) */
934
+ fetchFn?: typeof fetch;
935
+ }
936
+ /**
937
+ * Calls backend `/blob/presign` with `{ op:'put', contentType }`, then uploads `blob`
938
+ * to the returned S3 presigned URL. Returns `{ s3Key, url }` on success.
939
+ *
940
+ * This helper intentionally lives in @volr/sdk-core (not UI, not backend) so it can be reused
941
+ * by web, React Native, Node, etc. It uses fetch instead of axios to avoid extra deps.
942
+ */
943
+ declare function uploadBlobViaPresign(options: UploadViaPresignOptions): Promise<{
944
+ s3Key: string;
945
+ url: string;
946
+ }>;
947
+
948
+ /**
949
+ * Base error class for Volr SDK
950
+ */
951
+ declare class VolrError extends Error {
952
+ readonly code: string;
953
+ readonly cause?: Error | undefined;
954
+ constructor(code: string, message: string, cause?: Error | undefined);
955
+ }
956
+ /**
957
+ * Error codes
958
+ */
959
+ declare const ERR_INVALID_PARAM = "ERR_INVALID_PARAM";
960
+ declare const ERR_CRYPTO_FAIL = "ERR_CRYPTO_FAIL";
961
+ declare const ERR_AAD_MISMATCH = "ERR_AAD_MISMATCH";
962
+ declare const ERR_NONCE_SIZE = "ERR_NONCE_SIZE";
963
+ declare const ERR_LOW_ENTROPY = "ERR_LOW_ENTROPY";
964
+ declare const ERR_CHAIN_MISMATCH = "ERR_CHAIN_MISMATCH";
965
+
966
+ /**
967
+ * EVM constants
968
+ */
969
+ /**
970
+ * Zero hash (32 bytes of zeros)
971
+ * Equivalent to ethers.ZeroHash or keccak256("")
972
+ */
973
+ declare const ZERO_HASH: `0x${string}`;
974
+ /**
975
+ * Zero address (20 bytes of zeros)
976
+ */
977
+ declare const ZERO_ADDRESS: `0x${string}`;
978
+
979
+ /**
980
+ * Public types for EVM chain operations
981
+ * These types match backend DTOs 1:1 for consistency
982
+ */
983
+ /**
984
+ * Session authorization data
985
+ */
986
+ type SessionAuth = {
987
+ chainId: number;
988
+ sessionKey: `0x${string}`;
989
+ sessionId: bigint;
990
+ expiresAt: number;
991
+ nonce: bigint;
992
+ policyId: `0x${string}`;
993
+ policySnapshotHash: `0x${string}`;
994
+ gasLimitMax: bigint;
995
+ maxFeePerGas: bigint;
996
+ maxPriorityFeePerGas: bigint;
997
+ totalGasCap: bigint;
998
+ };
999
+ /**
1000
+ * Call structure for batch execution
1001
+ */
1002
+ type Call = {
1003
+ target: `0x${string}`;
1004
+ data: `0x${string}`;
1005
+ value: bigint;
1006
+ gasLimit: bigint;
1007
+ };
1008
+ /**
1009
+ * Precheck input (matches PrecheckDto)
1010
+ */
1011
+ type PrecheckInput = {
1012
+ auth: SessionAuth;
1013
+ calls: Call[];
1014
+ };
1015
+ /**
1016
+ * Precheck quote response
1017
+ */
1018
+ type PrecheckQuote = {
1019
+ maxGas: bigint;
1020
+ chainId: number;
1021
+ currentOpNonce?: string;
1022
+ gasCost?: bigint;
1023
+ fee?: bigint;
1024
+ policyId: `0x${string}`;
1025
+ policySnapshotHash: `0x${string}`;
1026
+ };
1027
+ /**
1028
+ * Authorization tuple for EIP-7702
1029
+ */
1030
+ type AuthorizationTuple = {
1031
+ chainId: number;
1032
+ address: `0x${string}`;
1033
+ nonce: bigint;
1034
+ yParity: 0 | 1;
1035
+ r: `0x${string}`;
1036
+ s: `0x${string}`;
1037
+ };
1038
+ /**
1039
+ * Relay input (matches RelayDto)
1040
+ */
1041
+ type RelayInput = {
1042
+ chainId: number;
1043
+ from: `0x${string}`;
1044
+ auth: SessionAuth;
1045
+ calls: Call[];
1046
+ sessionSig: `0x${string}`;
1047
+ authorizationList: [AuthorizationTuple] | [];
1048
+ };
1049
+ /**
1050
+ * Relay result
1051
+ */
1052
+ type RelayResult = {
1053
+ txId: string;
1054
+ status: 'QUEUED' | 'PENDING';
1055
+ txHash?: `0x${string}`;
1056
+ } | {
1057
+ txId: string;
1058
+ status: 'CONFIRMED';
1059
+ txHash: `0x${string}`;
1060
+ } | {
1061
+ txId: string;
1062
+ status: 'FAILED';
1063
+ txHash?: `0x${string}`;
1064
+ };
1065
+
1066
+ declare function computeCallsHash(calls: Call[]): `0x${string}`;
1067
+
1068
+ declare const DOMAIN: (chainId: number, verifyingContract: `0x${string}`) => {
1069
+ name: string;
1070
+ version: string;
1071
+ chainId: number;
1072
+ verifyingContract: `0x${string}`;
1073
+ };
1074
+ declare const EIP712_DOMAIN: (chainId: number, verifyingContract: `0x${string}`) => {
1075
+ name: string;
1076
+ version: string;
1077
+ chainId: number;
1078
+ verifyingContract: `0x${string}`;
1079
+ };
1080
+ declare const TYPES: {
1081
+ readonly Call: readonly [{
1082
+ readonly name: "target";
1083
+ readonly type: "address";
1084
+ }, {
1085
+ readonly name: "data";
1086
+ readonly type: "bytes";
1087
+ }, {
1088
+ readonly name: "value";
1089
+ readonly type: "uint256";
1090
+ }, {
1091
+ readonly name: "gasLimit";
1092
+ readonly type: "uint256";
1093
+ }];
1094
+ readonly SessionAuth: readonly [{
1095
+ readonly name: "chainId";
1096
+ readonly type: "uint256";
1097
+ }, {
1098
+ readonly name: "sessionKey";
1099
+ readonly type: "address";
1100
+ }, {
1101
+ readonly name: "sessionId";
1102
+ readonly type: "uint64";
1103
+ }, {
1104
+ readonly name: "nonce";
1105
+ readonly type: "uint64";
1106
+ }, {
1107
+ readonly name: "expiresAt";
1108
+ readonly type: "uint64";
1109
+ }, {
1110
+ readonly name: "policyId";
1111
+ readonly type: "bytes32";
1112
+ }, {
1113
+ readonly name: "policySnapshotHash";
1114
+ readonly type: "bytes32";
1115
+ }, {
1116
+ readonly name: "gasLimitMax";
1117
+ readonly type: "uint256";
1118
+ }, {
1119
+ readonly name: "maxFeePerGas";
1120
+ readonly type: "uint256";
1121
+ }, {
1122
+ readonly name: "maxPriorityFeePerGas";
1123
+ readonly type: "uint256";
1124
+ }, {
1125
+ readonly name: "totalGasCap";
1126
+ readonly type: "uint256";
1127
+ }];
1128
+ readonly SignedBatch: readonly [{
1129
+ readonly name: "auth";
1130
+ readonly type: "SessionAuth";
1131
+ }, {
1132
+ readonly name: "calls";
1133
+ readonly type: "Call[]";
1134
+ }, {
1135
+ readonly name: "revertOnFail";
1136
+ readonly type: "bool";
1137
+ }, {
1138
+ readonly name: "callsHash";
1139
+ readonly type: "bytes32";
1140
+ }];
1141
+ };
1142
+ type SessionAuthExtended = SessionAuth;
1143
+ /**
1144
+ * Build EIP-712 signed batch message
1145
+ */
1146
+ declare function buildSignedBatchMessage(input: {
1147
+ auth: SessionAuthExtended;
1148
+ calls: Call[];
1149
+ revertOnFail?: boolean;
1150
+ invokerAddress: `0x${string}`;
1151
+ }): {
1152
+ domain: ReturnType<typeof DOMAIN>;
1153
+ primaryType: "SignedBatch";
1154
+ message: {
1155
+ auth: any;
1156
+ calls: Call[];
1157
+ revertOnFail: boolean;
1158
+ callsHash: `0x${string}`;
1159
+ };
1160
+ callsHash: `0x${string}`;
1161
+ };
1162
+ /**
1163
+ * Sign EIP-712 session
1164
+ */
1165
+ declare function signSession(input: {
1166
+ signer: SignerPort;
1167
+ from: `0x${string}`;
1168
+ auth: SessionAuthExtended;
1169
+ calls: Call[];
1170
+ invokerAddress: `0x${string}`;
1171
+ }): Promise<{
1172
+ sessionSig: `0x${string}`;
1173
+ callsHash: `0x${string}`;
1174
+ }>;
1175
+
1176
+ /**
1177
+ * EIP-7702 authorization tuple signing
1178
+ */
1179
+
1180
+ /**
1181
+ * Sign EIP-7702 authorization tuple
1182
+ *
1183
+ * Authorization tuple signs: chainId || address || nonce
1184
+ * This is separate from session signature
1185
+ *
1186
+ * @param input - Signing parameters
1187
+ * @returns Authorization tuple with signature
1188
+ */
1189
+ declare function signAuthorization(input: {
1190
+ signer: SignerPort;
1191
+ chainId: number;
1192
+ address: `0x${string}`;
1193
+ nonce: bigint;
1194
+ }): Promise<AuthorizationTuple>;
1195
+
1196
+ /**
1197
+ * Authorization nonce utilities for EIP-7702
1198
+ */
1199
+ /**
1200
+ * Relay mode for nonce calculation
1201
+ */
1202
+ type RelayMode = 'self' | 'sponsored';
1203
+ /**
1204
+ * Get authorization nonce based on relay mode
1205
+ *
1206
+ * Rules (EIP-7702):
1207
+ * - self: getTransactionCount(latest) + 1
1208
+ * - sponsored: getTransactionCount(latest)
1209
+ *
1210
+ * Note: 'latest' is safer than 'pending' for sponsored mode to avoid race conditions.
1211
+ * The nonce MUST exactly match the user EOA's current account nonce for Authorization validation.
1212
+ *
1213
+ * @param client - Extended RPC client with getTransactionCount method
1214
+ * @param from - EOA address
1215
+ * @param mode - Relay mode
1216
+ * @returns Authorization nonce
1217
+ */
1218
+ declare function getAuthNonce(client: ExtendedRPCClient, from: `0x${string}`, mode: RelayMode): Promise<bigint>;
1219
+ /**
1220
+ * Extended RPC client interface with transaction count method
1221
+ * This should be implemented by the actual RPC client in React SDK
1222
+ */
1223
+ interface ExtendedRPCClient {
1224
+ /**
1225
+ * Low-level eth_call (optional, not required here)
1226
+ */
1227
+ call?: (args: {
1228
+ to: `0x${string}`;
1229
+ data: `0x${string}`;
1230
+ }) => Promise<`0x${string}`>;
1231
+ /**
1232
+ * Get transaction count for an address
1233
+ *
1234
+ * @param address - Address to query
1235
+ * @param blockTag - Block tag ('pending', 'latest', etc.)
1236
+ * @returns Transaction count as bigint
1237
+ */
1238
+ getTransactionCount(address: `0x${string}`, blockTag?: 'pending' | 'latest'): Promise<bigint>;
1239
+ }
1240
+
1241
+ /**
1242
+ * Passkey provider implementation
1243
+ * Uses PRF/HKDF to unwrap master seed and derive secp256k1 key
1244
+ */
1245
+
1246
+ /**
1247
+ * Options for passkey provider
1248
+ */
1249
+ type PasskeyProviderOptions = {
1250
+ /** PRF input parameters */
1251
+ prfInput: PrfInput;
1252
+ /** Encrypted master seed blob */
1253
+ encryptedBlob: {
1254
+ cipher: Uint8Array;
1255
+ nonce: Uint8Array;
1256
+ };
1257
+ /** Additional Authenticated Data for unwrapping */
1258
+ aad?: Uint8Array;
1259
+ };
1260
+ /**
1261
+ * Create passkey provider
1262
+ *
1263
+ * @param passkey - Passkey provider port (for WebAuthn PRF authentication)
1264
+ * @param options - Provider options (PRF input, encrypted blob)
1265
+ * @returns Wallet provider port
1266
+ *
1267
+ * @example
1268
+ * ```ts
1269
+ * const provider = createPasskeyProvider(passkeyAdapter, {
1270
+ * prfInput: { origin, projectId, credentialId },
1271
+ * encryptedBlob: { cipher, nonce }
1272
+ * });
1273
+ * await provider.ensureSession({ interactive: true, force: true });
1274
+ * const address = await provider.getAddress();
1275
+ * ```
1276
+ */
1277
+ declare function createPasskeyProvider(passkey: PasskeyProviderPort, options: PasskeyProviderOptions): WalletProviderPort;
1278
+
1279
+ /**
1280
+ * MPC provider implementation
1281
+ * Delegates to backend proxy via transport
1282
+ */
1283
+
1284
+ /**
1285
+ * Create MPC provider
1286
+ *
1287
+ * @param transport - MPC transport interface (backend proxy)
1288
+ * @returns Wallet provider port
1289
+ *
1290
+ * @example
1291
+ * ```ts
1292
+ * const transport = createMpcTransport({ backendUrl: '...' });
1293
+ * const provider = createMpcProvider(transport);
1294
+ * await provider.ensureSession();
1295
+ * const address = await provider.getAddress();
1296
+ * ```
1297
+ */
1298
+ declare function createMpcProvider(transport: MpcTransport): WalletProviderPort;
1299
+
1300
+ /**
1301
+ * Provider-based signer selection (simplified, no 7212 probing)
1302
+ * Always uses secp256k1 path today.
1303
+ */
1304
+
1305
+ /**
1306
+ * Context for signer selection
1307
+ */
1308
+ type SelectSignerContext = {
1309
+ /** Wallet provider */
1310
+ provider: WalletProviderPort;
1311
+ /** Chain ID */
1312
+ chainId: number;
1313
+ };
1314
+ /**
1315
+ * Select appropriate signer based on provider
1316
+ *
1317
+ * Routing logic:
1318
+ * 1. Provider-backed signer (delegates to provider, secp256k1)
1319
+ *
1320
+ * Note: 7702 authorization always uses secp256k1
1321
+ *
1322
+ * @param ctx - Selection context
1323
+ * @returns Signer port
1324
+ * @throws Error if provider cannot provide required signing capability
1325
+ *
1326
+ * @example
1327
+ * ```ts
1328
+ * const signer = await selectSigner({
1329
+ * provider: passkeyProvider,
1330
+ * chainId: 10,
1331
+ * client: rpcClient
1332
+ * });
1333
+ * const sig = await signer.signMessage(msgHash);
1334
+ * ```
1335
+ */
1336
+ declare function selectSigner(ctx: SelectSignerContext): Promise<SignerPort>;
1337
+
1338
+ export { type AesGcmParams, type AuthorizationTuple, type Call, ChainNotAddedError, DEFAULT_EVM_PATH, DOMAIN, type DeriveArgs, EIP1193ErrorCode, type EIP1193Provider, EIP712_DOMAIN, ERR_AAD_MISMATCH, ERR_CHAIN_MISMATCH, ERR_CRYPTO_FAIL, ERR_INVALID_PARAM, ERR_LOW_ENTROPY, ERR_NONCE_SIZE, type EvmKeypair, type ExtendedRPCClient, ExternalWalletSigner, type KeyStorageType, type Sig$1 as LegacySig, type MasterKeyProvider, type MasterSeed, type MasterSeedHandle, type MpcTransport, PasskeyP256Signer, type PasskeyProviderOptions, type PasskeyProviderPort, type PrecheckInput, type PrecheckQuote, type PrfInput, type RelayInput, type RelayMode, type RelayResult, RequestPendingError, type RpcLike, Secp256k1SoftwareSigner, type SelectSignerContext, type SessionAuth, type Sig, type SignerContext, type SignerKind, type SignerPort, TYPES, type TypedDataInput, UnauthorizedError, UnsupportedMethodError, type UploadBlobOptions, type UploadViaPresignOptions, UserRejectedError, VolrError, WalletError, type WalletProviderPort, type WrapKey, WrongNetworkError, ZERO_ADDRESS, ZERO_HASH, aesGcmDecrypt, aesGcmEncrypt, buildSignedBatchMessage, computeCallsHash, createMasterKeyProvider, createMpcProvider, createPasskeyProvider, deriveEvmKey, deriveWrapKey, evmSign, evmVerify, getAuthNonce, getRandomBytes, hkdfSha256, normalizeWalletError, sealMasterSeed, selectSigner, selectSigner$1 as selectSignerLegacy, signAuthorization, signSession, toChecksumAddress, unsealMasterSeed, uploadBlob, uploadBlobViaPresign, zeroize };