decane-connect-kit 2.10.0 → 2.12.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.
package/dist/index.d.cts CHANGED
@@ -104,6 +104,18 @@ interface DecaneConnectConfig {
104
104
  apiBaseUrl?: string;
105
105
  sessionDurationMinutes?: number;
106
106
  promptPin?: () => Promise<string>;
107
+ /**
108
+ * Prompts for the device unlock password. Required on any device that has
109
+ * one — both to set it (`kind: 'set'`, ask twice and confirm) and to use it
110
+ * (`kind: 'unlock'`).
111
+ *
112
+ * Unlike promptPin, this secret can open a session on its own, so treat it
113
+ * with the care a password deserves: never log it, never persist it, and let
114
+ * a password manager fill it.
115
+ */
116
+ promptUnlockPassword?: (ctx: {
117
+ kind: 'set' | 'unlock';
118
+ }) => Promise<string>;
107
119
  /**
108
120
  * Require a fresh WebAuthn assertion for every signature, instead of letting
109
121
  * an unlocked session sign freely until it expires. The TEE session stays
@@ -359,6 +371,18 @@ interface DecaneConnect {
359
371
  signInWithPasskey(): Promise<ConnectResult>;
360
372
  /** Whether THIS device's share is wrapped by a passkey rather than a PIN. */
361
373
  hasPasskey(): Promise<boolean>;
374
+ /**
375
+ * Turn on "unlock with your password": re-wraps the device share under the
376
+ * password and stores an unlock token beside it. Needs a live session.
377
+ * Throws WeakPasswordError if the password is too weak to carry a session.
378
+ */
379
+ setUnlockPassword(password: string): Promise<void>;
380
+ /** True when this device can open a session from a password alone. */
381
+ canUnlockWithPassword(): Promise<boolean>;
382
+ /** Open a session from the password alone — no provider, no passkey. */
383
+ unlockWithPassword(password: string): Promise<ConnectResult>;
384
+ /** Turn the password path off, revoking the token account-wide. */
385
+ removeUnlockPassword(): Promise<void>;
362
386
  /**
363
387
  * Add a passkey to this device after the fact, re-wrapping its device share
364
388
  * under it.
@@ -581,6 +605,22 @@ declare class ApiClient {
581
605
  */
582
606
  getWebAuthnLoginOptions(userId: string, rpId: string): Promise<_simplewebauthn_browser.PublicKeyCredentialRequestOptionsJSON | null>;
583
607
  postWebAuthnLogin(userId: string, response: _simplewebauthn_browser.AuthenticationResponseJSON, origin: string): Promise<AuthResult>;
608
+ /**
609
+ * Issue this device an unlock token. Returned in the clear once and never
610
+ * again — the backend stores only its hash — so the caller must encrypt and
611
+ * persist it before the value is dropped.
612
+ */
613
+ issueUnlockToken(jwt: string): Promise<{
614
+ token: string;
615
+ expiresInDays: number;
616
+ }>;
617
+ /** Redeem a decrypted unlock token for a session. */
618
+ exchangeUnlockToken(token: string): Promise<{
619
+ jwt: string;
620
+ userId: string;
621
+ }>;
622
+ /** Turn the password path off account-wide, so a lost device stops working. */
623
+ revokeUnlockTokens(jwt: string): Promise<void>;
584
624
  revoke(jwt: string): Promise<void>;
585
625
  hasRecoveryBackup(jwt: string): Promise<boolean>;
586
626
  getRecoveryBackup(jwt: string): Promise<{
@@ -977,6 +1017,15 @@ declare class StaleDeviceShareError extends DecaneConnectError {
977
1017
  declare class PromptPinNotConfiguredError extends DecaneConnectError {
978
1018
  constructor();
979
1019
  }
1020
+ declare class PromptPasswordNotConfiguredError extends DecaneConnectError {
1021
+ constructor();
1022
+ }
1023
+ declare class WrongUnlockPasswordError extends DecaneConnectError {
1024
+ constructor();
1025
+ }
1026
+ declare class UnlockTokenRejectedError extends DecaneConnectError {
1027
+ constructor();
1028
+ }
980
1029
  declare class AttestationError extends DecaneConnectError {
981
1030
  constructor(msg: string);
982
1031
  }
@@ -1126,9 +1175,14 @@ interface SocialAuthState {
1126
1175
  * Who the provider said the user is — `{ name?, email?, picture? }`.
1127
1176
  *
1128
1177
  * `null` until a sign-in returns one, and stays null for email sign-in and
1129
- * for providers the user withheld a profile from. It is not persisted across
1130
- * reloads: the backend stores no profile, so a restored session has an
1131
- * address but no name. Copy it somewhere durable if you need it to survive.
1178
+ * for providers the user withheld a profile from.
1179
+ *
1180
+ * The backend stores no profile, so this cannot be re-fetched — but whatever
1181
+ * a sign-in does reveal is kept beside this device's share, and a passkey
1182
+ * login hands it back. A passkey sign-in therefore carries the same name and
1183
+ * email the original Google sign-in did. A session merely restored from a
1184
+ * reload still has an address and no name, so copy it somewhere durable if
1185
+ * you need it in that state.
1132
1186
  */
1133
1187
  profile: AuthProfile | null;
1134
1188
  isUnlocked: boolean;
@@ -1222,6 +1276,7 @@ declare function useSocialAuth(): {
1222
1276
  } | null;
1223
1277
  sessionExpiresAt: number | null;
1224
1278
  canUsePasskey: boolean;
1279
+ profile: AuthProfile | null;
1225
1280
  phase: "creating" | "unlocking" | null;
1226
1281
  isCreatingWallet: boolean;
1227
1282
  needsReconnect: boolean;
@@ -1307,6 +1362,10 @@ declare function useSocialWallet(): {
1307
1362
  getAccessToken: () => string | null;
1308
1363
  hasPasskey: () => Promise<boolean>;
1309
1364
  addPasskey: () => Promise<void>;
1365
+ setUnlockPassword: (password: string) => Promise<void>;
1366
+ canUnlockWithPassword: () => Promise<boolean>;
1367
+ unlockWithPassword: (password: string) => Promise<void>;
1368
+ removeUnlockPassword: () => Promise<void>;
1310
1369
  rotateShares: (opts: {
1311
1370
  password: string;
1312
1371
  passwordHint?: string;
@@ -1403,4 +1462,16 @@ declare function useSignTypedData(): {
1403
1462
  reset: () => void;
1404
1463
  };
1405
1464
 
1406
- export { type ActiveSession, AttestationError, type AuthProfile, type AuthResult, BUILT_IN_CHAINS, type BalanceResult, type CAIP25Method, type CAIP25SessionRequest, type CAIP25SessionResult, CHAINS, CallSequenceError, type Chain, type ChainDescriptor, type ChainId, type ChainScope, type ChainSupport, type ChainType, type ConnectMode, type ConnectResult, type DecaneConfig, type DecaneConnect, type DecaneConnectConfig, DecaneConnectError, DecaneError, DecaneErrorCode, DecaneKit, DecaneLogo, DecaneMark, type DecaneProvider, DecaneWordmark, type Eip1193Provider, type EthereumProviderOptions, ExportNotAuthorizedError, InvalidApiKeyError, InvalidPinError, InvalidRecoveryFileError, type KingsChatTokens, NetworkError, NewDeviceError, OriginNotAllowedError, type PortableBackup, PromptPinNotConfiguredError, ProvisioningTimeoutError, ReconnectRequiredError, type RecordTransactionInput, RecoveryFailedError, type RecoveryProgress, type RecoveryShareFile, RecoveryWalletMismatchError, type SdkEvent, type SendTransactionRequest, SessionExpiredError, ShareCorruptedError, type SignMessageRequest, type SignTypedDataRequest, type SignedAuthorization, type SocialAuthState, type SocialConfig, SocialWalletModal, StaleDeviceShareError, type Theme, type TransactionRecord, type TxParams, type UnifiedWalletAccount, UnlockRequiredError, UserCancelledError, WalletSelector, WebAuthnNotSupportedError, type WrappedShareMeta, WrongPasswordError, createDecane, createDecaneConnect, createEthereumProvider, loginWithKingsChatPopup, startEmailAuth, useChainSwitch, useDecane, useEthereumProvider, useSendTransaction, useSignMessage, useSignTypedData, useSocialAuth, useSocialBalance, useSocialWallet, useWalletSelector, verifyEmailCode };
1465
+ declare const MIN_PASSWORD_LENGTH = 12;
1466
+ declare class WeakPasswordError extends Error {
1467
+ constructor(message: string);
1468
+ }
1469
+ /**
1470
+ * Reject what cannot carry the weight this secret now bears.
1471
+ *
1472
+ * Intentionally not a strength meter: a score shown to a user is advice, and
1473
+ * this is a floor. Anything above the floor is the user's call.
1474
+ */
1475
+ declare function validateUnlockPassword(password: string): void;
1476
+
1477
+ export { type ActiveSession, AttestationError, type AuthProfile, type AuthResult, BUILT_IN_CHAINS, type BalanceResult, type CAIP25Method, type CAIP25SessionRequest, type CAIP25SessionResult, CHAINS, CallSequenceError, type Chain, type ChainDescriptor, type ChainId, type ChainScope, type ChainSupport, type ChainType, type ConnectMode, type ConnectResult, type DecaneConfig, type DecaneConnect, type DecaneConnectConfig, DecaneConnectError, DecaneError, DecaneErrorCode, DecaneKit, DecaneLogo, DecaneMark, type DecaneProvider, DecaneWordmark, type Eip1193Provider, type EthereumProviderOptions, ExportNotAuthorizedError, InvalidApiKeyError, InvalidPinError, InvalidRecoveryFileError, type KingsChatTokens, MIN_PASSWORD_LENGTH, NetworkError, NewDeviceError, OriginNotAllowedError, type PortableBackup, PromptPasswordNotConfiguredError, PromptPinNotConfiguredError, ProvisioningTimeoutError, ReconnectRequiredError, type RecordTransactionInput, RecoveryFailedError, type RecoveryProgress, type RecoveryShareFile, RecoveryWalletMismatchError, type SdkEvent, type SendTransactionRequest, SessionExpiredError, ShareCorruptedError, type SignMessageRequest, type SignTypedDataRequest, type SignedAuthorization, type SocialAuthState, type SocialConfig, SocialWalletModal, StaleDeviceShareError, type Theme, type TransactionRecord, type TxParams, type UnifiedWalletAccount, UnlockRequiredError, UnlockTokenRejectedError, UserCancelledError, WalletSelector, WeakPasswordError, WebAuthnNotSupportedError, type WrappedShareMeta, WrongPasswordError, WrongUnlockPasswordError, createDecane, createDecaneConnect, createEthereumProvider, loginWithKingsChatPopup, startEmailAuth, useChainSwitch, useDecane, useEthereumProvider, useSendTransaction, useSignMessage, useSignTypedData, useSocialAuth, useSocialBalance, useSocialWallet, useWalletSelector, validateUnlockPassword, verifyEmailCode };
package/dist/index.d.ts CHANGED
@@ -104,6 +104,18 @@ interface DecaneConnectConfig {
104
104
  apiBaseUrl?: string;
105
105
  sessionDurationMinutes?: number;
106
106
  promptPin?: () => Promise<string>;
107
+ /**
108
+ * Prompts for the device unlock password. Required on any device that has
109
+ * one — both to set it (`kind: 'set'`, ask twice and confirm) and to use it
110
+ * (`kind: 'unlock'`).
111
+ *
112
+ * Unlike promptPin, this secret can open a session on its own, so treat it
113
+ * with the care a password deserves: never log it, never persist it, and let
114
+ * a password manager fill it.
115
+ */
116
+ promptUnlockPassword?: (ctx: {
117
+ kind: 'set' | 'unlock';
118
+ }) => Promise<string>;
107
119
  /**
108
120
  * Require a fresh WebAuthn assertion for every signature, instead of letting
109
121
  * an unlocked session sign freely until it expires. The TEE session stays
@@ -359,6 +371,18 @@ interface DecaneConnect {
359
371
  signInWithPasskey(): Promise<ConnectResult>;
360
372
  /** Whether THIS device's share is wrapped by a passkey rather than a PIN. */
361
373
  hasPasskey(): Promise<boolean>;
374
+ /**
375
+ * Turn on "unlock with your password": re-wraps the device share under the
376
+ * password and stores an unlock token beside it. Needs a live session.
377
+ * Throws WeakPasswordError if the password is too weak to carry a session.
378
+ */
379
+ setUnlockPassword(password: string): Promise<void>;
380
+ /** True when this device can open a session from a password alone. */
381
+ canUnlockWithPassword(): Promise<boolean>;
382
+ /** Open a session from the password alone — no provider, no passkey. */
383
+ unlockWithPassword(password: string): Promise<ConnectResult>;
384
+ /** Turn the password path off, revoking the token account-wide. */
385
+ removeUnlockPassword(): Promise<void>;
362
386
  /**
363
387
  * Add a passkey to this device after the fact, re-wrapping its device share
364
388
  * under it.
@@ -581,6 +605,22 @@ declare class ApiClient {
581
605
  */
582
606
  getWebAuthnLoginOptions(userId: string, rpId: string): Promise<_simplewebauthn_browser.PublicKeyCredentialRequestOptionsJSON | null>;
583
607
  postWebAuthnLogin(userId: string, response: _simplewebauthn_browser.AuthenticationResponseJSON, origin: string): Promise<AuthResult>;
608
+ /**
609
+ * Issue this device an unlock token. Returned in the clear once and never
610
+ * again — the backend stores only its hash — so the caller must encrypt and
611
+ * persist it before the value is dropped.
612
+ */
613
+ issueUnlockToken(jwt: string): Promise<{
614
+ token: string;
615
+ expiresInDays: number;
616
+ }>;
617
+ /** Redeem a decrypted unlock token for a session. */
618
+ exchangeUnlockToken(token: string): Promise<{
619
+ jwt: string;
620
+ userId: string;
621
+ }>;
622
+ /** Turn the password path off account-wide, so a lost device stops working. */
623
+ revokeUnlockTokens(jwt: string): Promise<void>;
584
624
  revoke(jwt: string): Promise<void>;
585
625
  hasRecoveryBackup(jwt: string): Promise<boolean>;
586
626
  getRecoveryBackup(jwt: string): Promise<{
@@ -977,6 +1017,15 @@ declare class StaleDeviceShareError extends DecaneConnectError {
977
1017
  declare class PromptPinNotConfiguredError extends DecaneConnectError {
978
1018
  constructor();
979
1019
  }
1020
+ declare class PromptPasswordNotConfiguredError extends DecaneConnectError {
1021
+ constructor();
1022
+ }
1023
+ declare class WrongUnlockPasswordError extends DecaneConnectError {
1024
+ constructor();
1025
+ }
1026
+ declare class UnlockTokenRejectedError extends DecaneConnectError {
1027
+ constructor();
1028
+ }
980
1029
  declare class AttestationError extends DecaneConnectError {
981
1030
  constructor(msg: string);
982
1031
  }
@@ -1126,9 +1175,14 @@ interface SocialAuthState {
1126
1175
  * Who the provider said the user is — `{ name?, email?, picture? }`.
1127
1176
  *
1128
1177
  * `null` until a sign-in returns one, and stays null for email sign-in and
1129
- * for providers the user withheld a profile from. It is not persisted across
1130
- * reloads: the backend stores no profile, so a restored session has an
1131
- * address but no name. Copy it somewhere durable if you need it to survive.
1178
+ * for providers the user withheld a profile from.
1179
+ *
1180
+ * The backend stores no profile, so this cannot be re-fetched — but whatever
1181
+ * a sign-in does reveal is kept beside this device's share, and a passkey
1182
+ * login hands it back. A passkey sign-in therefore carries the same name and
1183
+ * email the original Google sign-in did. A session merely restored from a
1184
+ * reload still has an address and no name, so copy it somewhere durable if
1185
+ * you need it in that state.
1132
1186
  */
1133
1187
  profile: AuthProfile | null;
1134
1188
  isUnlocked: boolean;
@@ -1222,6 +1276,7 @@ declare function useSocialAuth(): {
1222
1276
  } | null;
1223
1277
  sessionExpiresAt: number | null;
1224
1278
  canUsePasskey: boolean;
1279
+ profile: AuthProfile | null;
1225
1280
  phase: "creating" | "unlocking" | null;
1226
1281
  isCreatingWallet: boolean;
1227
1282
  needsReconnect: boolean;
@@ -1307,6 +1362,10 @@ declare function useSocialWallet(): {
1307
1362
  getAccessToken: () => string | null;
1308
1363
  hasPasskey: () => Promise<boolean>;
1309
1364
  addPasskey: () => Promise<void>;
1365
+ setUnlockPassword: (password: string) => Promise<void>;
1366
+ canUnlockWithPassword: () => Promise<boolean>;
1367
+ unlockWithPassword: (password: string) => Promise<void>;
1368
+ removeUnlockPassword: () => Promise<void>;
1310
1369
  rotateShares: (opts: {
1311
1370
  password: string;
1312
1371
  passwordHint?: string;
@@ -1403,4 +1462,16 @@ declare function useSignTypedData(): {
1403
1462
  reset: () => void;
1404
1463
  };
1405
1464
 
1406
- export { type ActiveSession, AttestationError, type AuthProfile, type AuthResult, BUILT_IN_CHAINS, type BalanceResult, type CAIP25Method, type CAIP25SessionRequest, type CAIP25SessionResult, CHAINS, CallSequenceError, type Chain, type ChainDescriptor, type ChainId, type ChainScope, type ChainSupport, type ChainType, type ConnectMode, type ConnectResult, type DecaneConfig, type DecaneConnect, type DecaneConnectConfig, DecaneConnectError, DecaneError, DecaneErrorCode, DecaneKit, DecaneLogo, DecaneMark, type DecaneProvider, DecaneWordmark, type Eip1193Provider, type EthereumProviderOptions, ExportNotAuthorizedError, InvalidApiKeyError, InvalidPinError, InvalidRecoveryFileError, type KingsChatTokens, NetworkError, NewDeviceError, OriginNotAllowedError, type PortableBackup, PromptPinNotConfiguredError, ProvisioningTimeoutError, ReconnectRequiredError, type RecordTransactionInput, RecoveryFailedError, type RecoveryProgress, type RecoveryShareFile, RecoveryWalletMismatchError, type SdkEvent, type SendTransactionRequest, SessionExpiredError, ShareCorruptedError, type SignMessageRequest, type SignTypedDataRequest, type SignedAuthorization, type SocialAuthState, type SocialConfig, SocialWalletModal, StaleDeviceShareError, type Theme, type TransactionRecord, type TxParams, type UnifiedWalletAccount, UnlockRequiredError, UserCancelledError, WalletSelector, WebAuthnNotSupportedError, type WrappedShareMeta, WrongPasswordError, createDecane, createDecaneConnect, createEthereumProvider, loginWithKingsChatPopup, startEmailAuth, useChainSwitch, useDecane, useEthereumProvider, useSendTransaction, useSignMessage, useSignTypedData, useSocialAuth, useSocialBalance, useSocialWallet, useWalletSelector, verifyEmailCode };
1465
+ declare const MIN_PASSWORD_LENGTH = 12;
1466
+ declare class WeakPasswordError extends Error {
1467
+ constructor(message: string);
1468
+ }
1469
+ /**
1470
+ * Reject what cannot carry the weight this secret now bears.
1471
+ *
1472
+ * Intentionally not a strength meter: a score shown to a user is advice, and
1473
+ * this is a floor. Anything above the floor is the user's call.
1474
+ */
1475
+ declare function validateUnlockPassword(password: string): void;
1476
+
1477
+ export { type ActiveSession, AttestationError, type AuthProfile, type AuthResult, BUILT_IN_CHAINS, type BalanceResult, type CAIP25Method, type CAIP25SessionRequest, type CAIP25SessionResult, CHAINS, CallSequenceError, type Chain, type ChainDescriptor, type ChainId, type ChainScope, type ChainSupport, type ChainType, type ConnectMode, type ConnectResult, type DecaneConfig, type DecaneConnect, type DecaneConnectConfig, DecaneConnectError, DecaneError, DecaneErrorCode, DecaneKit, DecaneLogo, DecaneMark, type DecaneProvider, DecaneWordmark, type Eip1193Provider, type EthereumProviderOptions, ExportNotAuthorizedError, InvalidApiKeyError, InvalidPinError, InvalidRecoveryFileError, type KingsChatTokens, MIN_PASSWORD_LENGTH, NetworkError, NewDeviceError, OriginNotAllowedError, type PortableBackup, PromptPasswordNotConfiguredError, PromptPinNotConfiguredError, ProvisioningTimeoutError, ReconnectRequiredError, type RecordTransactionInput, RecoveryFailedError, type RecoveryProgress, type RecoveryShareFile, RecoveryWalletMismatchError, type SdkEvent, type SendTransactionRequest, SessionExpiredError, ShareCorruptedError, type SignMessageRequest, type SignTypedDataRequest, type SignedAuthorization, type SocialAuthState, type SocialConfig, SocialWalletModal, StaleDeviceShareError, type Theme, type TransactionRecord, type TxParams, type UnifiedWalletAccount, UnlockRequiredError, UnlockTokenRejectedError, UserCancelledError, WalletSelector, WeakPasswordError, WebAuthnNotSupportedError, type WrappedShareMeta, WrongPasswordError, WrongUnlockPasswordError, createDecane, createDecaneConnect, createEthereumProvider, loginWithKingsChatPopup, startEmailAuth, useChainSwitch, useDecane, useEthereumProvider, useSendTransaction, useSignMessage, useSignTypedData, useSocialAuth, useSocialBalance, useSocialWallet, useWalletSelector, validateUnlockPassword, verifyEmailCode };