kentucky-signer-viem 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -111,6 +111,8 @@ interface PasskeyAuthOptions {
111
111
  rpId?: string;
112
112
  /** Credential IDs to allow (if known) */
113
113
  allowCredentials?: string[];
114
+ /** Optional ephemeral public key for secure mode binding (base64url encoded) */
115
+ ephemeralPublicKey?: string;
114
116
  }
115
117
  /**
116
118
  * Token storage interface for custom token persistence
@@ -178,6 +180,8 @@ interface PasswordAuthOptions {
178
180
  accountId: string;
179
181
  /** Password for authentication */
180
182
  password: string;
183
+ /** Optional ephemeral public key for secure mode binding (base64url encoded) */
184
+ ephemeralPublicKey?: string;
181
185
  }
182
186
  /**
183
187
  * Options for creating an account with password
@@ -208,7 +212,588 @@ interface PasswordAuthRequest {
208
212
  /** Password */
209
213
  password: string;
210
214
  }
215
+ /**
216
+ * Add password request
217
+ */
218
+ interface AddPasswordRequest {
219
+ /** Password for the account (8-128 characters) */
220
+ password: string;
221
+ /** Password confirmation (must match password) */
222
+ confirmation: string;
223
+ }
224
+ /**
225
+ * Add password response
226
+ */
227
+ interface AddPasswordResponse {
228
+ success: boolean;
229
+ message: string;
230
+ }
231
+ /**
232
+ * Add passkey request (using attestation object - simpler)
233
+ */
234
+ interface AddPasskeyRequest {
235
+ /** WebAuthn attestation object (base64url) - server extracts COSE key automatically */
236
+ attestation_object: string;
237
+ /** User-friendly label for the passkey */
238
+ label?: string;
239
+ }
240
+ /**
241
+ * Add passkey response
242
+ */
243
+ interface AddPasskeyResponse {
244
+ success: boolean;
245
+ message: string;
246
+ label: string;
247
+ }
248
+ /**
249
+ * Remove passkey response
250
+ */
251
+ interface RemovePasskeyResponse {
252
+ success: boolean;
253
+ message: string;
254
+ passkey_index: number;
255
+ }
256
+ /**
257
+ * Extended authentication response with ephemeral key binding
258
+ */
259
+ interface AuthResponseWithEphemeral extends AuthResponse {
260
+ /** Whether ephemeral key was bound to the token */
261
+ ephemeral_bound: boolean;
262
+ }
263
+ /**
264
+ * Auth configuration from account info
265
+ */
266
+ interface AuthConfig {
267
+ passkey: boolean;
268
+ password: boolean;
269
+ pin_4: boolean;
270
+ pin_6: boolean;
271
+ totp: boolean;
272
+ }
273
+ /**
274
+ * Extended account info response with auth config
275
+ */
276
+ interface AccountInfoExtendedResponse {
277
+ success: boolean;
278
+ account_id: string;
279
+ addresses: {
280
+ evm: string;
281
+ bitcoin: string;
282
+ solana: string;
283
+ };
284
+ auth_config: AuthConfig;
285
+ passkey_count: number;
286
+ guardian_count?: number;
287
+ recovery_active?: boolean;
288
+ }
289
+ /**
290
+ * Guardian info
291
+ */
292
+ interface GuardianInfo {
293
+ index: number;
294
+ label: string;
295
+ }
296
+ /**
297
+ * Add guardian request
298
+ */
299
+ interface AddGuardianRequest {
300
+ /** WebAuthn attestation object (base64url) */
301
+ attestation_object: string;
302
+ /** User-friendly label for the guardian */
303
+ label?: string;
304
+ }
305
+ /**
306
+ * Add guardian response
307
+ */
308
+ interface AddGuardianResponse {
309
+ success: boolean;
310
+ guardian_index: number;
311
+ guardian_count: number;
312
+ }
313
+ /**
314
+ * Remove guardian response
315
+ */
316
+ interface RemoveGuardianResponse {
317
+ success: boolean;
318
+ guardian_count: number;
319
+ }
320
+ /**
321
+ * Get guardians response
322
+ */
323
+ interface GetGuardiansResponse {
324
+ success: boolean;
325
+ guardian_count: number;
326
+ guardians: GuardianInfo[];
327
+ }
328
+ /**
329
+ * Initiate recovery request
330
+ */
331
+ interface InitiateRecoveryRequest {
332
+ /** Account ID to recover */
333
+ account_id: string;
334
+ /** WebAuthn attestation object for new owner passkey (base64url) */
335
+ attestation_object: string;
336
+ /** Label for new owner passkey */
337
+ label?: string;
338
+ }
339
+ /**
340
+ * Initiate recovery response
341
+ */
342
+ interface InitiateRecoveryResponse {
343
+ success: boolean;
344
+ /** Challenges for each guardian to sign (base64url) */
345
+ challenges: string[];
346
+ /** Number of guardians registered */
347
+ guardian_count: number;
348
+ /** Number of guardian signatures required */
349
+ threshold: number;
350
+ /** Seconds to wait after threshold reached before completion */
351
+ timelock_seconds: number;
352
+ }
353
+ /**
354
+ * Verify guardian signature request
355
+ */
356
+ interface VerifyGuardianRequest {
357
+ /** Account ID being recovered */
358
+ account_id: string;
359
+ /** Index of guardian (1-3) */
360
+ guardian_index: number;
361
+ /** WebAuthn authenticator data (base64url) */
362
+ authenticator_data: string;
363
+ /** WebAuthn client data JSON (base64url) */
364
+ client_data_json: string;
365
+ /** WebAuthn signature (base64url) */
366
+ signature: string;
367
+ }
368
+ /**
369
+ * Verify guardian response
370
+ */
371
+ interface VerifyGuardianResponse {
372
+ success: boolean;
373
+ /** Number of guardians who have verified */
374
+ verified_count: number;
375
+ /** Number of guardians required */
376
+ threshold: number;
377
+ }
378
+ /**
379
+ * Recovery status request
380
+ */
381
+ interface RecoveryStatusRequest {
382
+ /** Account ID to check */
383
+ account_id: string;
384
+ }
385
+ /**
386
+ * Recovery status response
387
+ */
388
+ interface RecoveryStatusResponse {
389
+ success: boolean;
390
+ /** Whether recovery is in progress */
391
+ recovery_active: boolean;
392
+ /** Number of guardians who have verified */
393
+ verified_count: number;
394
+ /** Number of guardians required */
395
+ threshold: number;
396
+ /** Whether recovery can be completed now */
397
+ can_complete: boolean;
398
+ /** Seconds remaining until timelock expires (0 if expired) */
399
+ timelock_remaining: number;
400
+ /** Number of guardians on this account */
401
+ guardian_count: number;
402
+ /** Challenge for each guardian to sign (base64url encoded) */
403
+ guardian_challenges: string[];
404
+ /** Indices of guardians who have verified */
405
+ verified_guardians: number[];
406
+ }
407
+ /**
408
+ * Complete recovery request
409
+ */
410
+ interface CompleteRecoveryRequest {
411
+ /** Account ID to complete recovery for */
412
+ account_id: string;
413
+ }
414
+ /**
415
+ * Complete recovery response
416
+ */
417
+ interface CompleteRecoveryResponse {
418
+ success: boolean;
419
+ message: string;
420
+ }
421
+ /**
422
+ * Cancel recovery response
423
+ */
424
+ interface CancelRecoveryResponse {
425
+ success: boolean;
426
+ message: string;
427
+ }
428
+ /**
429
+ * 2FA status response
430
+ */
431
+ interface TwoFactorStatusResponse {
432
+ success: boolean;
433
+ /** Whether TOTP is enabled */
434
+ totp_enabled: boolean;
435
+ /** Whether PIN is enabled */
436
+ pin_enabled: boolean;
437
+ /** PIN length if enabled (4 or 6), 0 if not enabled */
438
+ pin_length: number;
439
+ }
440
+ /**
441
+ * TOTP setup response
442
+ */
443
+ interface TotpSetupResponse {
444
+ success: boolean;
445
+ /** otpauth:// URI for QR code generation */
446
+ uri: string;
447
+ /** Base32 encoded secret for manual entry */
448
+ secret: string;
449
+ /** Instructions for the user */
450
+ message: string;
451
+ }
452
+ /**
453
+ * TOTP enable request
454
+ */
455
+ interface TotpEnableRequest {
456
+ /** 6-digit TOTP code from authenticator app */
457
+ code: string;
458
+ }
459
+ /**
460
+ * Generic 2FA response
461
+ */
462
+ interface TwoFactorResponse {
463
+ success: boolean;
464
+ message: string;
465
+ }
466
+ /**
467
+ * TOTP/PIN verify response
468
+ */
469
+ interface TwoFactorVerifyResponse {
470
+ success: boolean;
471
+ /** Whether the code/pin was valid */
472
+ valid: boolean;
473
+ /** Optional message if invalid */
474
+ message?: string;
475
+ }
476
+ /**
477
+ * PIN setup request
478
+ */
479
+ interface PinSetupRequest {
480
+ /** PIN (4 or 6 digits) */
481
+ pin: string;
482
+ }
483
+ /**
484
+ * PIN setup response
485
+ */
486
+ interface PinSetupResponse {
487
+ success: boolean;
488
+ message: string;
489
+ /** Length of the PIN that was set */
490
+ pin_length: number;
491
+ }
492
+ /**
493
+ * Sign request with optional 2FA codes
494
+ */
495
+ interface SignEvmRequestWith2FA extends SignEvmRequest {
496
+ /** TOTP code (required if TOTP is enabled) */
497
+ totp_code?: string;
498
+ /** PIN (required if PIN is enabled) */
499
+ pin?: string;
500
+ }
211
501
 
502
+ /**
503
+ * Ephemeral Key Management for Kentucky Signer
504
+ *
505
+ * Implements ephemeral ECDSA keys for request signing.
506
+ * The ephemeral public key is bound to the JWT token during authentication,
507
+ * and the private key is used to sign all subsequent request payloads.
508
+ *
509
+ * Security Properties:
510
+ * - Ephemeral keys are generated fresh for each session
511
+ * - Private keys never leave the client
512
+ * - SGX verifies payload signatures before processing
513
+ * - Prevents replay attacks and token theft
514
+ */
515
+ /**
516
+ * Ephemeral key pair for request signing
517
+ */
518
+ interface EphemeralKeyPair {
519
+ /** Public key in SPKI format (base64url encoded) */
520
+ publicKey: string;
521
+ /** Private CryptoKey for signing (not exportable) */
522
+ privateKey: CryptoKey;
523
+ /** Algorithm used (ES256 = P-256 with SHA-256) */
524
+ algorithm: 'ES256';
525
+ /** Creation timestamp */
526
+ createdAt: number;
527
+ }
528
+ /**
529
+ * Signed request payload
530
+ */
531
+ interface SignedPayload {
532
+ /** Original payload (JSON string) */
533
+ payload: string;
534
+ /** Signature (base64url encoded) */
535
+ signature: string;
536
+ /** Timestamp when signature was created */
537
+ timestamp: number;
538
+ }
539
+ /**
540
+ * Check if WebCrypto is available
541
+ */
542
+ declare function isWebCryptoAvailable(): boolean;
543
+ /**
544
+ * Generate an ephemeral ECDSA key pair using WebCrypto
545
+ *
546
+ * Uses P-256 curve (secp256r1) with SHA-256 for ES256 signatures.
547
+ *
548
+ * @returns Generated key pair
549
+ * @throws Error if WebCrypto is not available
550
+ */
551
+ declare function generateEphemeralKeyPair(): Promise<EphemeralKeyPair>;
552
+ /**
553
+ * Sign a request payload with the ephemeral private key
554
+ *
555
+ * The signature covers:
556
+ * - The JSON payload string
557
+ * - A timestamp to prevent replay attacks
558
+ *
559
+ * @param payload - Request payload (will be JSON stringified if object)
560
+ * @param keyPair - Ephemeral key pair
561
+ * @returns Signed payload with signature
562
+ */
563
+ declare function signPayload(payload: string | object, keyPair: EphemeralKeyPair): Promise<SignedPayload>;
564
+ /**
565
+ * Verify a signed payload (for testing purposes)
566
+ *
567
+ * @param signedPayload - The signed payload to verify
568
+ * @param publicKeyBase64 - Public key in SPKI format (base64url)
569
+ * @returns True if signature is valid
570
+ */
571
+ declare function verifyPayload(signedPayload: SignedPayload, publicKeyBase64: string): Promise<boolean>;
572
+ /**
573
+ * Ephemeral key storage interface
574
+ */
575
+ interface EphemeralKeyStorage {
576
+ save(keyPair: EphemeralKeyPair): Promise<void>;
577
+ load(): Promise<EphemeralKeyPair | null>;
578
+ clear(): Promise<void>;
579
+ }
580
+ /**
581
+ * In-memory ephemeral key storage
582
+ *
583
+ * Keys are lost when the page is refreshed.
584
+ */
585
+ declare class MemoryEphemeralKeyStorage implements EphemeralKeyStorage {
586
+ private keyPair;
587
+ save(keyPair: EphemeralKeyPair): Promise<void>;
588
+ load(): Promise<EphemeralKeyPair | null>;
589
+ clear(): Promise<void>;
590
+ }
591
+ /**
592
+ * IndexedDB ephemeral key storage
593
+ *
594
+ * Persists keys across page refreshes but not browser restarts.
595
+ * Uses non-extractable keys for security.
596
+ */
597
+ declare class IndexedDBEphemeralKeyStorage implements EphemeralKeyStorage {
598
+ private dbName;
599
+ private storeName;
600
+ private getDB;
601
+ save(keyPair: EphemeralKeyPair): Promise<void>;
602
+ load(): Promise<EphemeralKeyPair | null>;
603
+ clear(): Promise<void>;
604
+ }
605
+ /**
606
+ * Create an ephemeral key manager for a session
607
+ *
608
+ * The manager handles:
609
+ * - Key generation on first use
610
+ * - Key storage and retrieval
611
+ * - Automatic key rotation (optional)
612
+ * - Storage migration (switching between IndexedDB and memory)
613
+ */
614
+ declare class EphemeralKeyManager {
615
+ private keyPair;
616
+ private storage;
617
+ constructor(storage?: EphemeralKeyStorage);
618
+ /**
619
+ * Get or generate ephemeral key pair
620
+ */
621
+ getKeyPair(): Promise<EphemeralKeyPair>;
622
+ /**
623
+ * Get the public key for authentication
624
+ */
625
+ getPublicKey(): Promise<string>;
626
+ /**
627
+ * Sign a request payload
628
+ */
629
+ signPayload(payload: string | object): Promise<SignedPayload>;
630
+ /**
631
+ * Rotate the key pair (generate new keys)
632
+ */
633
+ rotate(): Promise<EphemeralKeyPair>;
634
+ /**
635
+ * Clear the key pair (logout)
636
+ */
637
+ clear(): Promise<void>;
638
+ /**
639
+ * Check if a key pair exists
640
+ */
641
+ hasKeyPair(): Promise<boolean>;
642
+ /**
643
+ * Migrate key pair to a new storage backend
644
+ *
645
+ * This preserves the existing key pair while switching storage.
646
+ * The key is saved to the new storage and removed from the old storage.
647
+ *
648
+ * @param newStorage - The new storage backend to migrate to
649
+ */
650
+ migrateStorage(newStorage: EphemeralKeyStorage): Promise<void>;
651
+ /**
652
+ * Get the current storage backend
653
+ */
654
+ getStorage(): EphemeralKeyStorage;
655
+ }
656
+
657
+ /**
658
+ * Secure Kentucky Signer Client with Ephemeral Key Signing
659
+ *
660
+ * This client automatically:
661
+ * - Generates an ephemeral key pair on initialization
662
+ * - Sends the public key during authentication
663
+ * - Signs all request payloads with the ephemeral private key
664
+ */
665
+
666
+ /**
667
+ * Options for the secure client
668
+ */
669
+ interface SecureClientOptions extends ClientOptions {
670
+ /** Custom ephemeral key storage (defaults to memory storage) */
671
+ ephemeralKeyStorage?: EphemeralKeyStorage;
672
+ /** Shared ephemeral key manager (takes precedence over storage) */
673
+ ephemeralKeyManager?: EphemeralKeyManager;
674
+ /** Whether to require ephemeral key verification (default: true) */
675
+ requireEphemeralSigning?: boolean;
676
+ }
677
+ /**
678
+ * Secure Kentucky Signer API client with ephemeral key signing
679
+ *
680
+ * All requests to authenticated endpoints are automatically signed
681
+ * with the ephemeral private key bound during authentication.
682
+ */
683
+ declare class SecureKentuckySignerClient {
684
+ private baseUrl;
685
+ private fetchImpl;
686
+ private timeout;
687
+ private keyManager;
688
+ private requireSigning;
689
+ constructor(options: SecureClientOptions);
690
+ /**
691
+ * Get the ephemeral key manager for advanced usage
692
+ */
693
+ getKeyManager(): EphemeralKeyManager;
694
+ /**
695
+ * Make a signed request to the API
696
+ */
697
+ private request;
698
+ /**
699
+ * Get a challenge for passkey authentication
700
+ */
701
+ getChallenge(accountId: string): Promise<ChallengeResponse>;
702
+ /**
703
+ * Authenticate with a passkey credential
704
+ *
705
+ * Automatically sends the ephemeral public key for binding.
706
+ */
707
+ authenticatePasskey(accountId: string, credential: PasskeyCredential): Promise<AuthResponseWithEphemeral>;
708
+ /**
709
+ * Authenticate with password
710
+ *
711
+ * Automatically sends the ephemeral public key for binding.
712
+ */
713
+ authenticatePassword(request: PasswordAuthRequest): Promise<AuthResponseWithEphemeral>;
714
+ /**
715
+ * Refresh an authentication token
716
+ *
717
+ * Generates a new ephemeral key pair and binds it to the new token.
718
+ */
719
+ refreshToken(token: string): Promise<AuthResponseWithEphemeral>;
720
+ /**
721
+ * Logout and invalidate token
722
+ *
723
+ * Clears the ephemeral key pair.
724
+ */
725
+ logout(token: string): Promise<void>;
726
+ /**
727
+ * Get account information (signed request)
728
+ */
729
+ getAccountInfo(accountId: string, token: string): Promise<AccountInfoResponse>;
730
+ /**
731
+ * Get extended account information (signed request)
732
+ */
733
+ getAccountInfoExtended(accountId: string, token: string): Promise<AccountInfoExtendedResponse>;
734
+ /**
735
+ * Sign an EVM transaction hash (signed request)
736
+ */
737
+ signEvmTransaction(request: SignEvmRequest, token: string): Promise<EvmSignatureResponse>;
738
+ /**
739
+ * Sign an EVM transaction hash with 2FA (signed request)
740
+ */
741
+ signEvmTransactionWith2FA(request: SignEvmRequest & {
742
+ totp_code?: string;
743
+ pin?: string;
744
+ }, token: string): Promise<EvmSignatureResponse>;
745
+ /**
746
+ * Sign a raw hash for EVM (signed request)
747
+ */
748
+ signHash(hash: Hex, chainId: number, token: string): Promise<Hex>;
749
+ /**
750
+ * Add password to account (signed request)
751
+ */
752
+ addPassword(accountId: string, request: AddPasswordRequest, token: string): Promise<AddPasswordResponse>;
753
+ /**
754
+ * Add passkey to account (signed request)
755
+ */
756
+ addPasskey(accountId: string, request: AddPasskeyRequest, token: string): Promise<AddPasskeyResponse>;
757
+ /**
758
+ * Remove passkey from account (signed request)
759
+ */
760
+ removePasskey(accountId: string, passkeyIndex: number, token: string): Promise<RemovePasskeyResponse>;
761
+ /**
762
+ * Create account with passkey (public endpoint, no signing)
763
+ */
764
+ createAccountWithPasskey(attestationObject: string, label?: string): Promise<AccountCreationResponse>;
765
+ /**
766
+ * Create account with password (public endpoint, no signing)
767
+ */
768
+ createAccountWithPassword(request: CreatePasswordAccountRequest): Promise<AccountCreationResponse>;
769
+ /**
770
+ * Health check (public endpoint)
771
+ */
772
+ healthCheck(): Promise<boolean>;
773
+ }
774
+ /**
775
+ * Create a new secure Kentucky Signer client
776
+ */
777
+ declare function createSecureClient(options: SecureClientOptions): SecureKentuckySignerClient;
778
+
779
+ /**
780
+ * 2FA codes for signing operations
781
+ */
782
+ interface TwoFactorCodes {
783
+ /** TOTP code from authenticator app */
784
+ totpCode?: string;
785
+ /** PIN code */
786
+ pin?: string;
787
+ }
788
+ /**
789
+ * Callback to request 2FA codes from the user
790
+ * Returns null/undefined if user cancels
791
+ */
792
+ type TwoFactorCallback = (requirements: {
793
+ totpRequired: boolean;
794
+ pinRequired: boolean;
795
+ pinLength: number;
796
+ }) => Promise<TwoFactorCodes | null | undefined>;
212
797
  /**
213
798
  * Options for creating a Kentucky Signer account
214
799
  */
@@ -221,6 +806,10 @@ interface KentuckySignerAccountOptions {
221
806
  defaultChainId?: number;
222
807
  /** Callback when session needs refresh */
223
808
  onSessionExpired?: () => Promise<AuthSession>;
809
+ /** Optional secure client for ephemeral key signing */
810
+ secureClient?: SecureKentuckySignerClient;
811
+ /** Callback to request 2FA codes when required */
812
+ on2FARequired?: TwoFactorCallback;
224
813
  }
225
814
  /**
226
815
  * Extended account type with Kentucky Signer specific properties
@@ -316,9 +905,10 @@ declare class KentuckySignerClient {
316
905
  *
317
906
  * @param accountId - Account ID to authenticate
318
907
  * @param credential - WebAuthn credential from navigator.credentials.get()
908
+ * @param ephemeralPublicKey - Optional ephemeral public key for secure mode binding
319
909
  * @returns Authentication response with JWT token
320
910
  */
321
- authenticatePasskey(accountId: string, credential: PasskeyCredential): Promise<AuthResponse>;
911
+ authenticatePasskey(accountId: string, credential: PasskeyCredential, ephemeralPublicKey?: string): Promise<AuthResponse>;
322
912
  /**
323
913
  * Refresh an authentication token
324
914
  *
@@ -370,12 +960,11 @@ declare class KentuckySignerClient {
370
960
  /**
371
961
  * Create a new account with passkey authentication
372
962
  *
373
- * @param credential - WebAuthn credential from navigator.credentials.create()
963
+ * @param attestationObject - Base64url encoded attestation object from WebAuthn
964
+ * @param label - Optional label for the passkey (defaults to "Owner Passkey")
374
965
  * @returns Account creation response with account ID and addresses
375
966
  */
376
- createAccountWithPasskey(credential: PasskeyCredential & {
377
- publicKey: string;
378
- }): Promise<AccountCreationResponse>;
967
+ createAccountWithPasskey(attestationObject: string, label?: string): Promise<AccountCreationResponse>;
379
968
  /**
380
969
  * Create a new account with password authentication
381
970
  *
@@ -390,6 +979,46 @@ declare class KentuckySignerClient {
390
979
  * @returns Authentication response with JWT token
391
980
  */
392
981
  authenticatePassword(request: PasswordAuthRequest): Promise<AuthResponse>;
982
+ /**
983
+ * Add password authentication to an existing account
984
+ *
985
+ * Enables password-based authentication for an account that was created
986
+ * with passkey-only authentication.
987
+ *
988
+ * @param accountId - Account ID
989
+ * @param request - Password and confirmation
990
+ * @param token - JWT token
991
+ * @returns Success response
992
+ */
993
+ addPassword(accountId: string, request: AddPasswordRequest, token: string): Promise<AddPasswordResponse>;
994
+ /**
995
+ * Get extended account information including auth config
996
+ *
997
+ * @param accountId - Account ID
998
+ * @param token - JWT token
999
+ * @returns Extended account info with auth config and passkey count
1000
+ */
1001
+ getAccountInfoExtended(accountId: string, token: string): Promise<AccountInfoExtendedResponse>;
1002
+ /**
1003
+ * Add a recovery passkey to an existing account
1004
+ *
1005
+ * @param accountId - Account ID
1006
+ * @param request - Passkey data (COSE public key, credential ID, algorithm, label)
1007
+ * @param token - JWT token
1008
+ * @returns Success response with label
1009
+ */
1010
+ addPasskey(accountId: string, request: AddPasskeyRequest, token: string): Promise<AddPasskeyResponse>;
1011
+ /**
1012
+ * Remove a passkey from an account
1013
+ *
1014
+ * Note: Cannot remove the owner passkey (index 0)
1015
+ *
1016
+ * @param accountId - Account ID
1017
+ * @param passkeyIndex - Index of passkey to remove (1-3 for recovery passkeys)
1018
+ * @param token - JWT token
1019
+ * @returns Success response
1020
+ */
1021
+ removePasskey(accountId: string, passkeyIndex: number, token: string): Promise<RemovePasskeyResponse>;
393
1022
  /**
394
1023
  * Health check
395
1024
  *
@@ -402,6 +1031,171 @@ declare class KentuckySignerClient {
402
1031
  * @returns Version string
403
1032
  */
404
1033
  getVersion(): Promise<string>;
1034
+ /**
1035
+ * Add a guardian passkey to an account
1036
+ *
1037
+ * Guardians can participate in account recovery but cannot access the wallet.
1038
+ * An account can have up to 3 guardians (indices 1-3).
1039
+ *
1040
+ * @param request - Guardian data (attestation object and optional label)
1041
+ * @param token - JWT token
1042
+ * @returns Success response with guardian index and count
1043
+ */
1044
+ addGuardian(request: AddGuardianRequest, token: string): Promise<AddGuardianResponse>;
1045
+ /**
1046
+ * Remove a guardian passkey from an account
1047
+ *
1048
+ * Cannot remove guardians during an active recovery.
1049
+ *
1050
+ * @param guardianIndex - Index of guardian to remove (1-3)
1051
+ * @param token - JWT token
1052
+ * @returns Success response with remaining guardian count
1053
+ */
1054
+ removeGuardian(guardianIndex: number, token: string): Promise<RemoveGuardianResponse>;
1055
+ /**
1056
+ * Get guardians for an account
1057
+ *
1058
+ * @param token - JWT token
1059
+ * @returns Guardian list with indices and labels
1060
+ */
1061
+ getGuardians(token: string): Promise<GetGuardiansResponse>;
1062
+ /**
1063
+ * Initiate account recovery
1064
+ *
1065
+ * Call this when you've lost access to your account. You'll need to register
1066
+ * a new passkey which will become the new owner passkey after recovery completes.
1067
+ *
1068
+ * @param accountId - Account ID to recover
1069
+ * @param attestationObject - WebAuthn attestation object for new owner passkey
1070
+ * @param label - Optional label for new owner passkey
1071
+ * @returns Challenges for guardians to sign, threshold, and timelock info
1072
+ */
1073
+ initiateRecovery(accountId: string, attestationObject: string, label?: string): Promise<InitiateRecoveryResponse>;
1074
+ /**
1075
+ * Submit a guardian signature for recovery
1076
+ *
1077
+ * Each guardian must sign their challenge using their passkey.
1078
+ *
1079
+ * @param request - Guardian signature data
1080
+ * @returns Current verification status
1081
+ */
1082
+ verifyGuardian(request: VerifyGuardianRequest): Promise<VerifyGuardianResponse>;
1083
+ /**
1084
+ * Get recovery status for an account
1085
+ *
1086
+ * @param accountId - Account ID to check
1087
+ * @returns Recovery status including verification count and timelock
1088
+ */
1089
+ getRecoveryStatus(accountId: string): Promise<RecoveryStatusResponse>;
1090
+ /**
1091
+ * Complete account recovery
1092
+ *
1093
+ * Call this after enough guardians have verified and the timelock has expired.
1094
+ * The new owner passkey will replace the old one.
1095
+ *
1096
+ * @param accountId - Account ID to complete recovery for
1097
+ * @returns Success message
1098
+ */
1099
+ completeRecovery(accountId: string): Promise<CompleteRecoveryResponse>;
1100
+ /**
1101
+ * Cancel a pending recovery
1102
+ *
1103
+ * Only the current owner (with valid auth) can cancel a recovery.
1104
+ * Use this if you regain access and want to stop an unauthorized recovery.
1105
+ *
1106
+ * @param token - JWT token (must be authenticated as owner)
1107
+ * @returns Success message
1108
+ */
1109
+ cancelRecovery(token: string): Promise<CancelRecoveryResponse>;
1110
+ /**
1111
+ * Get 2FA status for the authenticated account
1112
+ *
1113
+ * @param token - JWT token
1114
+ * @returns 2FA status including TOTP and PIN enablement
1115
+ */
1116
+ get2FAStatus(token: string): Promise<TwoFactorStatusResponse>;
1117
+ /**
1118
+ * Setup TOTP for the account
1119
+ *
1120
+ * Returns an otpauth:// URI for QR code generation and a base32 secret
1121
+ * for manual entry. After setup, call enableTOTP with a valid code to
1122
+ * complete the setup.
1123
+ *
1124
+ * @param token - JWT token
1125
+ * @returns TOTP setup response with URI and secret
1126
+ */
1127
+ setupTOTP(token: string): Promise<TotpSetupResponse>;
1128
+ /**
1129
+ * Verify and enable TOTP for the account
1130
+ *
1131
+ * Call this after setupTOTP with a valid code from the authenticator app.
1132
+ *
1133
+ * @param code - 6-digit TOTP code from authenticator app
1134
+ * @param token - JWT token
1135
+ * @returns Success response
1136
+ */
1137
+ enableTOTP(code: string, token: string): Promise<TwoFactorResponse>;
1138
+ /**
1139
+ * Disable TOTP for the account
1140
+ *
1141
+ * Requires a valid TOTP code for confirmation.
1142
+ *
1143
+ * @param code - Current 6-digit TOTP code
1144
+ * @param token - JWT token
1145
+ * @returns Success response
1146
+ */
1147
+ disableTOTP(code: string, token: string): Promise<TwoFactorResponse>;
1148
+ /**
1149
+ * Verify a TOTP code
1150
+ *
1151
+ * Use this to verify a TOTP code without performing any other operation.
1152
+ *
1153
+ * @param code - 6-digit TOTP code
1154
+ * @param token - JWT token
1155
+ * @returns Verification result
1156
+ */
1157
+ verifyTOTP(code: string, token: string): Promise<TwoFactorVerifyResponse>;
1158
+ /**
1159
+ * Setup PIN for the account
1160
+ *
1161
+ * Sets a 4-digit or 6-digit PIN. If a PIN is already set, this replaces it.
1162
+ *
1163
+ * @param pin - 4 or 6 digit PIN
1164
+ * @param token - JWT token
1165
+ * @returns Success response with PIN length
1166
+ */
1167
+ setupPIN(pin: string, token: string): Promise<PinSetupResponse>;
1168
+ /**
1169
+ * Disable PIN for the account
1170
+ *
1171
+ * Requires the current PIN for confirmation.
1172
+ *
1173
+ * @param pin - Current PIN
1174
+ * @param token - JWT token
1175
+ * @returns Success response
1176
+ */
1177
+ disablePIN(pin: string, token: string): Promise<TwoFactorResponse>;
1178
+ /**
1179
+ * Verify a PIN
1180
+ *
1181
+ * Use this to verify a PIN without performing any other operation.
1182
+ *
1183
+ * @param pin - PIN to verify
1184
+ * @param token - JWT token
1185
+ * @returns Verification result
1186
+ */
1187
+ verifyPIN(pin: string, token: string): Promise<TwoFactorVerifyResponse>;
1188
+ /**
1189
+ * Sign an EVM transaction with 2FA
1190
+ *
1191
+ * Use this method when 2FA is enabled. If 2FA is not enabled,
1192
+ * you can use the regular signEvmTransaction method instead.
1193
+ *
1194
+ * @param request - Sign request including tx_hash, chain_id, and optional 2FA codes
1195
+ * @param token - JWT token
1196
+ * @returns Signature response with r, s, v components
1197
+ */
1198
+ signEvmTransactionWith2FA(request: SignEvmRequestWith2FA, token: string): Promise<EvmSignatureResponse>;
405
1199
  }
406
1200
  /**
407
1201
  * Create a new Kentucky Signer client
@@ -464,10 +1258,11 @@ declare function authenticateWithToken(baseUrl: string, accountId: string, token
464
1258
  * Register a new passkey for account creation (browser only)
465
1259
  *
466
1260
  * @param options - Registration options
467
- * @returns Registration credential with public key
1261
+ * @returns Registration credential with public key and attestation object
468
1262
  */
469
1263
  declare function registerPasskey(options: PasskeyRegistrationOptions): Promise<PasskeyCredential & {
470
1264
  publicKey: string;
1265
+ attestationObject: string;
471
1266
  }>;
472
1267
  /**
473
1268
  * Check if a session is still valid
@@ -600,4 +1395,4 @@ declare function getJwtExpiration(token: string): number | null;
600
1395
  */
601
1396
  declare function formatError(error: unknown): string;
602
1397
 
603
- export { type AccountCreationResponse, type AccountInfoResponse, type ApiErrorResponse, type AuthResponse, type AuthSession, type ChallengeResponse, type ClientOptions, type CreatePasswordAccountRequest, type EvmSignatureResponse, type KentuckySignerAccount, type KentuckySignerAccountOptions, KentuckySignerClient, type KentuckySignerConfig, KentuckySignerError, LocalStorageTokenStorage, MemoryTokenStorage, type PasskeyAuthOptions, type PasskeyCredential, type PasskeyRegistrationOptions, type PasswordAccountCreationOptions, type PasswordAuthOptions, type PasswordAuthRequest, type SignEvmRequest, type TokenStorage, authenticateWithPasskey, authenticateWithPassword, authenticateWithToken, base64UrlDecode, base64UrlEncode, bytesToHex, createAccountWithPassword, createClient, createKentuckySignerAccount, createServerAccount, formatError, getJwtExpiration, hexToBytes, isSessionValid, isValidAccountId, isValidEvmAddress, isWebAuthnAvailable, parseJwt, refreshSessionIfNeeded, registerPasskey, withRetry };
1398
+ export { type AccountCreationResponse, type AccountInfoExtendedResponse, type AccountInfoResponse, type AddGuardianRequest, type AddGuardianResponse, type AddPasskeyRequest, type AddPasskeyResponse, type AddPasswordRequest, type AddPasswordResponse, type ApiErrorResponse, type AuthConfig, type AuthResponse, type AuthResponseWithEphemeral, type AuthSession, type CancelRecoveryResponse, type ChallengeResponse, type ClientOptions, type CompleteRecoveryRequest, type CompleteRecoveryResponse, type CreatePasswordAccountRequest, EphemeralKeyManager, type EphemeralKeyPair, type EphemeralKeyStorage, type EvmSignatureResponse, type GetGuardiansResponse, type GuardianInfo, IndexedDBEphemeralKeyStorage, type InitiateRecoveryRequest, type InitiateRecoveryResponse, type KentuckySignerAccount, type KentuckySignerAccountOptions, KentuckySignerClient, type KentuckySignerConfig, KentuckySignerError, LocalStorageTokenStorage, MemoryEphemeralKeyStorage, MemoryTokenStorage, type PasskeyAuthOptions, type PasskeyCredential, type PasskeyRegistrationOptions, type PasswordAccountCreationOptions, type PasswordAuthOptions, type PasswordAuthRequest, type PinSetupRequest, type PinSetupResponse, type RecoveryStatusRequest, type RecoveryStatusResponse, type RemoveGuardianResponse, type RemovePasskeyResponse, type SecureClientOptions, SecureKentuckySignerClient, type SignEvmRequest, type SignEvmRequestWith2FA, type SignedPayload, type TokenStorage, type TotpEnableRequest, type TotpSetupResponse, type TwoFactorCallback, type TwoFactorCodes, type TwoFactorResponse, type TwoFactorStatusResponse, type TwoFactorVerifyResponse, type VerifyGuardianRequest, type VerifyGuardianResponse, authenticateWithPasskey, authenticateWithPassword, authenticateWithToken, base64UrlDecode, base64UrlEncode, bytesToHex, createAccountWithPassword, createClient, createKentuckySignerAccount, createSecureClient, createServerAccount, formatError, generateEphemeralKeyPair, getJwtExpiration, hexToBytes, isSessionValid, isValidAccountId, isValidEvmAddress, isWebAuthnAvailable, isWebCryptoAvailable, parseJwt, refreshSessionIfNeeded, registerPasskey, signPayload, verifyPayload, withRetry };