decane-connect-kit 2.5.0 → 2.6.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.cjs +368 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +138 -7
- package/dist/index.d.ts +138 -7
- package/dist/index.js +366 -5
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.d.cts
CHANGED
|
@@ -76,7 +76,12 @@ interface DecaneProvider {
|
|
|
76
76
|
type ConnectMode = "all" | "social" | "wallets" | "evm" | "solana" | "tron" | "evm+social" | "solana+social" | "tron+social" | "evm+tron" | "evm+tron+social";
|
|
77
77
|
interface SocialConfig {
|
|
78
78
|
apiKey: string;
|
|
79
|
-
authMethods?: ("google" | "email")[];
|
|
79
|
+
authMethods?: ("google" | "email" | "kingschat")[];
|
|
80
|
+
/**
|
|
81
|
+
* Scopes requested from KingsChat. Defaults to `['send_chat_message']`, which
|
|
82
|
+
* is what KingsChat's own SDK asks for and is enough to establish identity.
|
|
83
|
+
*/
|
|
84
|
+
kingsChatScopes?: string[];
|
|
80
85
|
promptPin?: () => Promise<string>;
|
|
81
86
|
apiBaseUrl?: string;
|
|
82
87
|
chains?: string[];
|
|
@@ -170,6 +175,23 @@ declare class ApiClient {
|
|
|
170
175
|
getGoogleInitUrl(): Promise<{
|
|
171
176
|
url: string;
|
|
172
177
|
}>;
|
|
178
|
+
/**
|
|
179
|
+
* Exchange a Google ID token the app already holds for a Decane session.
|
|
180
|
+
* Resolves to the SAME identity as the redirect flow, so one Google account
|
|
181
|
+
* means one wallet across web and mobile.
|
|
182
|
+
*/
|
|
183
|
+
authGoogleToken(idToken: string): Promise<AuthResult>;
|
|
184
|
+
/** The project's KingsChat clientId, so the dApp never has to hardcode it. */
|
|
185
|
+
getKingsChatConfig(): Promise<{
|
|
186
|
+
clientId: string;
|
|
187
|
+
authorizationUrl: string;
|
|
188
|
+
}>;
|
|
189
|
+
/**
|
|
190
|
+
* Exchange a KingsChat access token for a Decane session. The backend spends
|
|
191
|
+
* the token against KingsChat's own API to establish the identity — it is
|
|
192
|
+
* never trusted on its face, and never stored.
|
|
193
|
+
*/
|
|
194
|
+
authKingsChat(accessToken: string): Promise<AuthResult>;
|
|
173
195
|
authEmailStart(email: string): Promise<void>;
|
|
174
196
|
authEmailVerify(email: string, code: string): Promise<AuthResult>;
|
|
175
197
|
getAddresses(jwt: string): Promise<{
|
|
@@ -346,7 +368,15 @@ interface DecaneConnectConfig {
|
|
|
346
368
|
appId: string;
|
|
347
369
|
apiKey: string;
|
|
348
370
|
chains: Chain[];
|
|
349
|
-
authMethods: Array<'google' | 'email'>;
|
|
371
|
+
authMethods: Array<'google' | 'email' | 'kingschat'>;
|
|
372
|
+
/**
|
|
373
|
+
* Scopes requested from KingsChat at sign-in. Defaults to
|
|
374
|
+
* `['send_chat_message']`, which is what KingsChat's own SDK asks for and is
|
|
375
|
+
* enough to establish identity. Widen only if the app actually calls
|
|
376
|
+
* KingsChat APIs on the user's behalf — the consent screen lists every scope,
|
|
377
|
+
* so asking for more than you use costs conversions.
|
|
378
|
+
*/
|
|
379
|
+
kingsChatScopes?: string[];
|
|
350
380
|
apiBaseUrl?: string;
|
|
351
381
|
sessionDurationMinutes?: number;
|
|
352
382
|
promptPin?: () => Promise<string>;
|
|
@@ -412,6 +442,48 @@ interface DecaneConnectConfig {
|
|
|
412
442
|
}>;
|
|
413
443
|
/** Recovery stage callbacks, for dApp UI. */
|
|
414
444
|
onRecoveryProgress?: (event: RecoveryProgress) => void;
|
|
445
|
+
/**
|
|
446
|
+
* Let the enclave hand a device a working share on the strength of a valid
|
|
447
|
+
* login alone — no synced passkey, no recovery file, nothing for the user to
|
|
448
|
+
* keep. Default TRUE, because a wallet a person cannot re-enter after
|
|
449
|
+
* clearing their browser is worse than useless to them.
|
|
450
|
+
*
|
|
451
|
+
* The trade, stated plainly: enrolling stores a second Shamir share sealed to
|
|
452
|
+
* the enclave, so the enclave can reconstruct a wallet by itself. It is sealed
|
|
453
|
+
* with a key derived inside the TEE, so your backend and its database still
|
|
454
|
+
* cannot — but a malicious enclave image, or anyone able to mint JWTs, could.
|
|
455
|
+
*
|
|
456
|
+
* Set false to keep the stricter property that no single party can
|
|
457
|
+
* reconstruct. Users then need a synced passkey or their recovery file on
|
|
458
|
+
* every new device, and losing both means losing the wallet.
|
|
459
|
+
*/
|
|
460
|
+
serverAssistedRecovery?: boolean;
|
|
461
|
+
/**
|
|
462
|
+
* Rotate the whole share set whenever a NEW device recovers via passkey sync
|
|
463
|
+
* (Flow A) — the "every device holds a distinct share" model.
|
|
464
|
+
*
|
|
465
|
+
* Default false, which preserves the historical behaviour: every device
|
|
466
|
+
* synced to the same passkey caches the byte-identical wrapped share, so a
|
|
467
|
+
* device that is later lost keeps a share that stays valid until someone
|
|
468
|
+
* explicitly calls rotateShares(). There is no way to revoke one device
|
|
469
|
+
* without revoking all of them.
|
|
470
|
+
*
|
|
471
|
+
* With this on, joining a new device re-splits the master and issues that
|
|
472
|
+
* device its own share, which invalidates every other device's cached copy
|
|
473
|
+
* at the same instant. That is what makes per-device revocation possible,
|
|
474
|
+
* and it has three consequences worth accepting deliberately:
|
|
475
|
+
*
|
|
476
|
+
* - **Other devices are logged out, not just the lost one.** Each surviving
|
|
477
|
+
* device hits StaleDeviceShareError on its next unlock, clears its share,
|
|
478
|
+
* and silently re-recovers through Flow A (one passkey prompt). Expected,
|
|
479
|
+
* but it means a shared-family-device setup re-prompts more often.
|
|
480
|
+
* - **The user's recovery FILE dies too.** Rotation issues a new recovery
|
|
481
|
+
* share, so `onRecoveryRotated` MUST be configured to capture it —
|
|
482
|
+
* enabling this without that callback throws at connect time rather than
|
|
483
|
+
* stranding the user with a dead file.
|
|
484
|
+
* - **Adding a device costs a TEE round trip.** Recovery is slower.
|
|
485
|
+
*/
|
|
486
|
+
rotateOnNewDeviceRecovery?: boolean;
|
|
415
487
|
}
|
|
416
488
|
interface ConnectResult {
|
|
417
489
|
addresses: {
|
|
@@ -467,6 +539,30 @@ type SdkEvent = 'connected' | 'disconnected' | 'session-expired' | 'session-star
|
|
|
467
539
|
interface DecaneConnect {
|
|
468
540
|
connect(): Promise<ConnectResult>;
|
|
469
541
|
connectWithGoogle(): Promise<ConnectResult>;
|
|
542
|
+
/**
|
|
543
|
+
* Sign in with a Google ID token the app already obtained — native Google
|
|
544
|
+
* Sign-In on mobile, or Google Identity Services on the web.
|
|
545
|
+
*
|
|
546
|
+
* Resolves to the SAME wallet as connectWithGoogle(): both end at the
|
|
547
|
+
* backend's Google identity, so a user who signs in on your website and then
|
|
548
|
+
* on your app lands on one wallet, not two.
|
|
549
|
+
*/
|
|
550
|
+
connectWithGoogleToken(idToken: string): Promise<ConnectResult>;
|
|
551
|
+
/**
|
|
552
|
+
* Sign in with KingsChat.
|
|
553
|
+
*
|
|
554
|
+
* Opens KingsChat's consent screen in a popup, so this MUST be called
|
|
555
|
+
* directly from a click handler — a popup opened after an await is blocked by
|
|
556
|
+
* every browser. The resulting access token is exchanged server-side for a
|
|
557
|
+
* Decane session; it is never treated as one on its own.
|
|
558
|
+
*/
|
|
559
|
+
connectWithKingsChat(): Promise<ConnectResult>;
|
|
560
|
+
/**
|
|
561
|
+
* Sign in with a KingsChat access token the app already holds — from
|
|
562
|
+
* kingschat-web-sdk, a native SDK, or any other flow. Use when you want to
|
|
563
|
+
* own the consent step yourself; connectWithKingsChat() is the turnkey path.
|
|
564
|
+
*/
|
|
565
|
+
connectWithKingsChatToken(accessToken: string): Promise<ConnectResult>;
|
|
470
566
|
connectWithEmail(email: string): Promise<{
|
|
471
567
|
codeRequired: true;
|
|
472
568
|
}>;
|
|
@@ -640,6 +736,24 @@ declare function startEmailAuth(api: ApiClient, email: string): Promise<void>;
|
|
|
640
736
|
*/
|
|
641
737
|
declare function verifyEmailCode(api: ApiClient, email: string, code: string): Promise<AuthResult>;
|
|
642
738
|
|
|
739
|
+
interface KingsChatTokens {
|
|
740
|
+
accessToken: string;
|
|
741
|
+
refreshToken?: string;
|
|
742
|
+
expiresInMillis?: number;
|
|
743
|
+
}
|
|
744
|
+
/**
|
|
745
|
+
* Open the KingsChat consent popup and resolve with the tokens it returns.
|
|
746
|
+
*
|
|
747
|
+
* Must be called synchronously from a user gesture (a click handler) — popup
|
|
748
|
+
* blockers reject a window.open that happens after an await, which is why the
|
|
749
|
+
* clientId is fetched by the caller *before* this runs.
|
|
750
|
+
*/
|
|
751
|
+
declare function loginWithKingsChatPopup(opts: {
|
|
752
|
+
clientId: string;
|
|
753
|
+
scopes?: string[];
|
|
754
|
+
timeoutMs?: number;
|
|
755
|
+
}): Promise<KingsChatTokens>;
|
|
756
|
+
|
|
643
757
|
declare class DecaneConnectError extends Error {
|
|
644
758
|
code: string;
|
|
645
759
|
retryable: boolean;
|
|
@@ -694,6 +808,21 @@ declare class ShareCorruptedError extends DecaneConnectError {
|
|
|
694
808
|
declare class NewDeviceError extends DecaneConnectError {
|
|
695
809
|
constructor();
|
|
696
810
|
}
|
|
811
|
+
/**
|
|
812
|
+
* The device share this device just used no longer reconstructs the account's
|
|
813
|
+
* real key — almost always because another device recovered via passkey sync
|
|
814
|
+
* since and rotated the whole share set (see rotateOnNewDeviceRecovery in
|
|
815
|
+
* DecaneConnectConfig), silently invalidating every other device's cached
|
|
816
|
+
* copy. Thrown instead of signing: two mismatched shares from different
|
|
817
|
+
* share-set versions still combine to *something*, just not the user's real
|
|
818
|
+
* key, so continuing would risk operating on a wrong (though not
|
|
819
|
+
* attacker-chosen) address. The stale local share is cleared by the caller
|
|
820
|
+
* before this propagates, so the next connect() naturally falls through to
|
|
821
|
+
* recovery instead of repeating the same failure.
|
|
822
|
+
*/
|
|
823
|
+
declare class StaleDeviceShareError extends DecaneConnectError {
|
|
824
|
+
constructor();
|
|
825
|
+
}
|
|
697
826
|
declare class PromptPinNotConfiguredError extends DecaneConnectError {
|
|
698
827
|
constructor();
|
|
699
828
|
}
|
|
@@ -812,8 +941,9 @@ interface WalletSelectorProps {
|
|
|
812
941
|
theme?: "light" | "dark" | "auto";
|
|
813
942
|
networks?: "evm" | "solana" | "tron" | "bitcoin" | "all";
|
|
814
943
|
mode?: ConnectMode;
|
|
815
|
-
socialAuthMethods?: ("google" | "email")[];
|
|
944
|
+
socialAuthMethods?: ("google" | "email" | "kingschat")[];
|
|
816
945
|
onGoogleSignIn?: () => Promise<void>;
|
|
946
|
+
onKingsChatSignIn?: () => Promise<void>;
|
|
817
947
|
onEmailStart?: (email: string) => Promise<{
|
|
818
948
|
codeRequired: true;
|
|
819
949
|
}>;
|
|
@@ -827,7 +957,7 @@ interface WalletSelectorProps {
|
|
|
827
957
|
passkeyAddress?: string | null;
|
|
828
958
|
onPasskeySignIn?: () => Promise<unknown>;
|
|
829
959
|
}
|
|
830
|
-
declare function WalletSelector({ provider, open, onClose, onConnect, theme, networks, mode, socialAuthMethods, onGoogleSignIn, onEmailStart, onEmailVerify, customAuthLabel, onCustomAuthSignIn, canUsePasskey, passkeyAddress, onPasskeySignIn, }: WalletSelectorProps): React.ReactPortal | null;
|
|
960
|
+
declare function WalletSelector({ provider, open, onClose, onConnect, theme, networks, mode, socialAuthMethods, onGoogleSignIn, onKingsChatSignIn, onEmailStart, onEmailVerify, customAuthLabel, onCustomAuthSignIn, canUsePasskey, passkeyAddress, onPasskeySignIn, }: WalletSelectorProps): React.ReactPortal | null;
|
|
831
961
|
|
|
832
962
|
type Theme = "light" | "dark" | "auto";
|
|
833
963
|
interface SocialAuthState {
|
|
@@ -876,11 +1006,12 @@ interface SocialWalletModalProps {
|
|
|
876
1006
|
onUnlock: () => Promise<void>;
|
|
877
1007
|
onDisconnect: () => Promise<void>;
|
|
878
1008
|
onGoogleSignIn: () => Promise<void>;
|
|
1009
|
+
onKingsChatSignIn?: () => Promise<void>;
|
|
879
1010
|
onEmailStart: (email: string) => Promise<{
|
|
880
1011
|
codeRequired: true;
|
|
881
1012
|
}>;
|
|
882
1013
|
onEmailVerify: (email: string, code: string) => Promise<void>;
|
|
883
|
-
authMethods?: Array<"google" | "email">;
|
|
1014
|
+
authMethods?: Array<"google" | "email" | "kingschat">;
|
|
884
1015
|
customAuthLabel?: string;
|
|
885
1016
|
onCustomAuthSignIn?: () => Promise<void>;
|
|
886
1017
|
canUsePasskey?: boolean;
|
|
@@ -897,7 +1028,7 @@ interface SocialWalletModalProps {
|
|
|
897
1028
|
rpcUrls?: Record<string, string>;
|
|
898
1029
|
chains?: string[];
|
|
899
1030
|
}
|
|
900
|
-
declare function SocialWalletModal({ open, onClose, theme, socialAuth, onUnlock, onDisconnect, onGoogleSignIn, onEmailStart, onEmailVerify, authMethods, customAuthLabel, onCustomAuthSignIn, canUsePasskey, passkeyAddress, onPasskeySignIn, onRotateShares, onExportPortableBackup, rpcUrls, chains, }: SocialWalletModalProps): React.ReactPortal | null;
|
|
1031
|
+
declare function SocialWalletModal({ open, onClose, theme, socialAuth, onUnlock, onDisconnect, onGoogleSignIn, onKingsChatSignIn, onEmailStart, onEmailVerify, authMethods, customAuthLabel, onCustomAuthSignIn, canUsePasskey, passkeyAddress, onPasskeySignIn, onRotateShares, onExportPortableBackup, rpcUrls, chains, }: SocialWalletModalProps): React.ReactPortal | null;
|
|
901
1032
|
|
|
902
1033
|
declare function DecaneMark({ size, muted }: {
|
|
903
1034
|
size?: number;
|
|
@@ -1095,4 +1226,4 @@ declare function useSignTypedData(): {
|
|
|
1095
1226
|
reset: () => void;
|
|
1096
1227
|
};
|
|
1097
1228
|
|
|
1098
|
-
export { type ActiveSession, AttestationError, 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, NetworkError, NewDeviceError, OriginNotAllowedError, type PortableBackup, PromptPinNotConfiguredError, 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, type Theme, type TransactionRecord, type TxParams, type UnifiedWalletAccount, UnlockRequiredError, UserCancelledError, WalletSelector, WebAuthnNotSupportedError, type WrappedShareMeta, WrongPasswordError, createDecane, createDecaneConnect, createEthereumProvider, startEmailAuth, useChainSwitch, useDecane, useEthereumProvider, useSendTransaction, useSignMessage, useSignTypedData, useSocialAuth, useSocialBalance, useSocialWallet, useWalletSelector, verifyEmailCode };
|
|
1229
|
+
export { type ActiveSession, AttestationError, 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, 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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -76,7 +76,12 @@ interface DecaneProvider {
|
|
|
76
76
|
type ConnectMode = "all" | "social" | "wallets" | "evm" | "solana" | "tron" | "evm+social" | "solana+social" | "tron+social" | "evm+tron" | "evm+tron+social";
|
|
77
77
|
interface SocialConfig {
|
|
78
78
|
apiKey: string;
|
|
79
|
-
authMethods?: ("google" | "email")[];
|
|
79
|
+
authMethods?: ("google" | "email" | "kingschat")[];
|
|
80
|
+
/**
|
|
81
|
+
* Scopes requested from KingsChat. Defaults to `['send_chat_message']`, which
|
|
82
|
+
* is what KingsChat's own SDK asks for and is enough to establish identity.
|
|
83
|
+
*/
|
|
84
|
+
kingsChatScopes?: string[];
|
|
80
85
|
promptPin?: () => Promise<string>;
|
|
81
86
|
apiBaseUrl?: string;
|
|
82
87
|
chains?: string[];
|
|
@@ -170,6 +175,23 @@ declare class ApiClient {
|
|
|
170
175
|
getGoogleInitUrl(): Promise<{
|
|
171
176
|
url: string;
|
|
172
177
|
}>;
|
|
178
|
+
/**
|
|
179
|
+
* Exchange a Google ID token the app already holds for a Decane session.
|
|
180
|
+
* Resolves to the SAME identity as the redirect flow, so one Google account
|
|
181
|
+
* means one wallet across web and mobile.
|
|
182
|
+
*/
|
|
183
|
+
authGoogleToken(idToken: string): Promise<AuthResult>;
|
|
184
|
+
/** The project's KingsChat clientId, so the dApp never has to hardcode it. */
|
|
185
|
+
getKingsChatConfig(): Promise<{
|
|
186
|
+
clientId: string;
|
|
187
|
+
authorizationUrl: string;
|
|
188
|
+
}>;
|
|
189
|
+
/**
|
|
190
|
+
* Exchange a KingsChat access token for a Decane session. The backend spends
|
|
191
|
+
* the token against KingsChat's own API to establish the identity — it is
|
|
192
|
+
* never trusted on its face, and never stored.
|
|
193
|
+
*/
|
|
194
|
+
authKingsChat(accessToken: string): Promise<AuthResult>;
|
|
173
195
|
authEmailStart(email: string): Promise<void>;
|
|
174
196
|
authEmailVerify(email: string, code: string): Promise<AuthResult>;
|
|
175
197
|
getAddresses(jwt: string): Promise<{
|
|
@@ -346,7 +368,15 @@ interface DecaneConnectConfig {
|
|
|
346
368
|
appId: string;
|
|
347
369
|
apiKey: string;
|
|
348
370
|
chains: Chain[];
|
|
349
|
-
authMethods: Array<'google' | 'email'>;
|
|
371
|
+
authMethods: Array<'google' | 'email' | 'kingschat'>;
|
|
372
|
+
/**
|
|
373
|
+
* Scopes requested from KingsChat at sign-in. Defaults to
|
|
374
|
+
* `['send_chat_message']`, which is what KingsChat's own SDK asks for and is
|
|
375
|
+
* enough to establish identity. Widen only if the app actually calls
|
|
376
|
+
* KingsChat APIs on the user's behalf — the consent screen lists every scope,
|
|
377
|
+
* so asking for more than you use costs conversions.
|
|
378
|
+
*/
|
|
379
|
+
kingsChatScopes?: string[];
|
|
350
380
|
apiBaseUrl?: string;
|
|
351
381
|
sessionDurationMinutes?: number;
|
|
352
382
|
promptPin?: () => Promise<string>;
|
|
@@ -412,6 +442,48 @@ interface DecaneConnectConfig {
|
|
|
412
442
|
}>;
|
|
413
443
|
/** Recovery stage callbacks, for dApp UI. */
|
|
414
444
|
onRecoveryProgress?: (event: RecoveryProgress) => void;
|
|
445
|
+
/**
|
|
446
|
+
* Let the enclave hand a device a working share on the strength of a valid
|
|
447
|
+
* login alone — no synced passkey, no recovery file, nothing for the user to
|
|
448
|
+
* keep. Default TRUE, because a wallet a person cannot re-enter after
|
|
449
|
+
* clearing their browser is worse than useless to them.
|
|
450
|
+
*
|
|
451
|
+
* The trade, stated plainly: enrolling stores a second Shamir share sealed to
|
|
452
|
+
* the enclave, so the enclave can reconstruct a wallet by itself. It is sealed
|
|
453
|
+
* with a key derived inside the TEE, so your backend and its database still
|
|
454
|
+
* cannot — but a malicious enclave image, or anyone able to mint JWTs, could.
|
|
455
|
+
*
|
|
456
|
+
* Set false to keep the stricter property that no single party can
|
|
457
|
+
* reconstruct. Users then need a synced passkey or their recovery file on
|
|
458
|
+
* every new device, and losing both means losing the wallet.
|
|
459
|
+
*/
|
|
460
|
+
serverAssistedRecovery?: boolean;
|
|
461
|
+
/**
|
|
462
|
+
* Rotate the whole share set whenever a NEW device recovers via passkey sync
|
|
463
|
+
* (Flow A) — the "every device holds a distinct share" model.
|
|
464
|
+
*
|
|
465
|
+
* Default false, which preserves the historical behaviour: every device
|
|
466
|
+
* synced to the same passkey caches the byte-identical wrapped share, so a
|
|
467
|
+
* device that is later lost keeps a share that stays valid until someone
|
|
468
|
+
* explicitly calls rotateShares(). There is no way to revoke one device
|
|
469
|
+
* without revoking all of them.
|
|
470
|
+
*
|
|
471
|
+
* With this on, joining a new device re-splits the master and issues that
|
|
472
|
+
* device its own share, which invalidates every other device's cached copy
|
|
473
|
+
* at the same instant. That is what makes per-device revocation possible,
|
|
474
|
+
* and it has three consequences worth accepting deliberately:
|
|
475
|
+
*
|
|
476
|
+
* - **Other devices are logged out, not just the lost one.** Each surviving
|
|
477
|
+
* device hits StaleDeviceShareError on its next unlock, clears its share,
|
|
478
|
+
* and silently re-recovers through Flow A (one passkey prompt). Expected,
|
|
479
|
+
* but it means a shared-family-device setup re-prompts more often.
|
|
480
|
+
* - **The user's recovery FILE dies too.** Rotation issues a new recovery
|
|
481
|
+
* share, so `onRecoveryRotated` MUST be configured to capture it —
|
|
482
|
+
* enabling this without that callback throws at connect time rather than
|
|
483
|
+
* stranding the user with a dead file.
|
|
484
|
+
* - **Adding a device costs a TEE round trip.** Recovery is slower.
|
|
485
|
+
*/
|
|
486
|
+
rotateOnNewDeviceRecovery?: boolean;
|
|
415
487
|
}
|
|
416
488
|
interface ConnectResult {
|
|
417
489
|
addresses: {
|
|
@@ -467,6 +539,30 @@ type SdkEvent = 'connected' | 'disconnected' | 'session-expired' | 'session-star
|
|
|
467
539
|
interface DecaneConnect {
|
|
468
540
|
connect(): Promise<ConnectResult>;
|
|
469
541
|
connectWithGoogle(): Promise<ConnectResult>;
|
|
542
|
+
/**
|
|
543
|
+
* Sign in with a Google ID token the app already obtained — native Google
|
|
544
|
+
* Sign-In on mobile, or Google Identity Services on the web.
|
|
545
|
+
*
|
|
546
|
+
* Resolves to the SAME wallet as connectWithGoogle(): both end at the
|
|
547
|
+
* backend's Google identity, so a user who signs in on your website and then
|
|
548
|
+
* on your app lands on one wallet, not two.
|
|
549
|
+
*/
|
|
550
|
+
connectWithGoogleToken(idToken: string): Promise<ConnectResult>;
|
|
551
|
+
/**
|
|
552
|
+
* Sign in with KingsChat.
|
|
553
|
+
*
|
|
554
|
+
* Opens KingsChat's consent screen in a popup, so this MUST be called
|
|
555
|
+
* directly from a click handler — a popup opened after an await is blocked by
|
|
556
|
+
* every browser. The resulting access token is exchanged server-side for a
|
|
557
|
+
* Decane session; it is never treated as one on its own.
|
|
558
|
+
*/
|
|
559
|
+
connectWithKingsChat(): Promise<ConnectResult>;
|
|
560
|
+
/**
|
|
561
|
+
* Sign in with a KingsChat access token the app already holds — from
|
|
562
|
+
* kingschat-web-sdk, a native SDK, or any other flow. Use when you want to
|
|
563
|
+
* own the consent step yourself; connectWithKingsChat() is the turnkey path.
|
|
564
|
+
*/
|
|
565
|
+
connectWithKingsChatToken(accessToken: string): Promise<ConnectResult>;
|
|
470
566
|
connectWithEmail(email: string): Promise<{
|
|
471
567
|
codeRequired: true;
|
|
472
568
|
}>;
|
|
@@ -640,6 +736,24 @@ declare function startEmailAuth(api: ApiClient, email: string): Promise<void>;
|
|
|
640
736
|
*/
|
|
641
737
|
declare function verifyEmailCode(api: ApiClient, email: string, code: string): Promise<AuthResult>;
|
|
642
738
|
|
|
739
|
+
interface KingsChatTokens {
|
|
740
|
+
accessToken: string;
|
|
741
|
+
refreshToken?: string;
|
|
742
|
+
expiresInMillis?: number;
|
|
743
|
+
}
|
|
744
|
+
/**
|
|
745
|
+
* Open the KingsChat consent popup and resolve with the tokens it returns.
|
|
746
|
+
*
|
|
747
|
+
* Must be called synchronously from a user gesture (a click handler) — popup
|
|
748
|
+
* blockers reject a window.open that happens after an await, which is why the
|
|
749
|
+
* clientId is fetched by the caller *before* this runs.
|
|
750
|
+
*/
|
|
751
|
+
declare function loginWithKingsChatPopup(opts: {
|
|
752
|
+
clientId: string;
|
|
753
|
+
scopes?: string[];
|
|
754
|
+
timeoutMs?: number;
|
|
755
|
+
}): Promise<KingsChatTokens>;
|
|
756
|
+
|
|
643
757
|
declare class DecaneConnectError extends Error {
|
|
644
758
|
code: string;
|
|
645
759
|
retryable: boolean;
|
|
@@ -694,6 +808,21 @@ declare class ShareCorruptedError extends DecaneConnectError {
|
|
|
694
808
|
declare class NewDeviceError extends DecaneConnectError {
|
|
695
809
|
constructor();
|
|
696
810
|
}
|
|
811
|
+
/**
|
|
812
|
+
* The device share this device just used no longer reconstructs the account's
|
|
813
|
+
* real key — almost always because another device recovered via passkey sync
|
|
814
|
+
* since and rotated the whole share set (see rotateOnNewDeviceRecovery in
|
|
815
|
+
* DecaneConnectConfig), silently invalidating every other device's cached
|
|
816
|
+
* copy. Thrown instead of signing: two mismatched shares from different
|
|
817
|
+
* share-set versions still combine to *something*, just not the user's real
|
|
818
|
+
* key, so continuing would risk operating on a wrong (though not
|
|
819
|
+
* attacker-chosen) address. The stale local share is cleared by the caller
|
|
820
|
+
* before this propagates, so the next connect() naturally falls through to
|
|
821
|
+
* recovery instead of repeating the same failure.
|
|
822
|
+
*/
|
|
823
|
+
declare class StaleDeviceShareError extends DecaneConnectError {
|
|
824
|
+
constructor();
|
|
825
|
+
}
|
|
697
826
|
declare class PromptPinNotConfiguredError extends DecaneConnectError {
|
|
698
827
|
constructor();
|
|
699
828
|
}
|
|
@@ -812,8 +941,9 @@ interface WalletSelectorProps {
|
|
|
812
941
|
theme?: "light" | "dark" | "auto";
|
|
813
942
|
networks?: "evm" | "solana" | "tron" | "bitcoin" | "all";
|
|
814
943
|
mode?: ConnectMode;
|
|
815
|
-
socialAuthMethods?: ("google" | "email")[];
|
|
944
|
+
socialAuthMethods?: ("google" | "email" | "kingschat")[];
|
|
816
945
|
onGoogleSignIn?: () => Promise<void>;
|
|
946
|
+
onKingsChatSignIn?: () => Promise<void>;
|
|
817
947
|
onEmailStart?: (email: string) => Promise<{
|
|
818
948
|
codeRequired: true;
|
|
819
949
|
}>;
|
|
@@ -827,7 +957,7 @@ interface WalletSelectorProps {
|
|
|
827
957
|
passkeyAddress?: string | null;
|
|
828
958
|
onPasskeySignIn?: () => Promise<unknown>;
|
|
829
959
|
}
|
|
830
|
-
declare function WalletSelector({ provider, open, onClose, onConnect, theme, networks, mode, socialAuthMethods, onGoogleSignIn, onEmailStart, onEmailVerify, customAuthLabel, onCustomAuthSignIn, canUsePasskey, passkeyAddress, onPasskeySignIn, }: WalletSelectorProps): React.ReactPortal | null;
|
|
960
|
+
declare function WalletSelector({ provider, open, onClose, onConnect, theme, networks, mode, socialAuthMethods, onGoogleSignIn, onKingsChatSignIn, onEmailStart, onEmailVerify, customAuthLabel, onCustomAuthSignIn, canUsePasskey, passkeyAddress, onPasskeySignIn, }: WalletSelectorProps): React.ReactPortal | null;
|
|
831
961
|
|
|
832
962
|
type Theme = "light" | "dark" | "auto";
|
|
833
963
|
interface SocialAuthState {
|
|
@@ -876,11 +1006,12 @@ interface SocialWalletModalProps {
|
|
|
876
1006
|
onUnlock: () => Promise<void>;
|
|
877
1007
|
onDisconnect: () => Promise<void>;
|
|
878
1008
|
onGoogleSignIn: () => Promise<void>;
|
|
1009
|
+
onKingsChatSignIn?: () => Promise<void>;
|
|
879
1010
|
onEmailStart: (email: string) => Promise<{
|
|
880
1011
|
codeRequired: true;
|
|
881
1012
|
}>;
|
|
882
1013
|
onEmailVerify: (email: string, code: string) => Promise<void>;
|
|
883
|
-
authMethods?: Array<"google" | "email">;
|
|
1014
|
+
authMethods?: Array<"google" | "email" | "kingschat">;
|
|
884
1015
|
customAuthLabel?: string;
|
|
885
1016
|
onCustomAuthSignIn?: () => Promise<void>;
|
|
886
1017
|
canUsePasskey?: boolean;
|
|
@@ -897,7 +1028,7 @@ interface SocialWalletModalProps {
|
|
|
897
1028
|
rpcUrls?: Record<string, string>;
|
|
898
1029
|
chains?: string[];
|
|
899
1030
|
}
|
|
900
|
-
declare function SocialWalletModal({ open, onClose, theme, socialAuth, onUnlock, onDisconnect, onGoogleSignIn, onEmailStart, onEmailVerify, authMethods, customAuthLabel, onCustomAuthSignIn, canUsePasskey, passkeyAddress, onPasskeySignIn, onRotateShares, onExportPortableBackup, rpcUrls, chains, }: SocialWalletModalProps): React.ReactPortal | null;
|
|
1031
|
+
declare function SocialWalletModal({ open, onClose, theme, socialAuth, onUnlock, onDisconnect, onGoogleSignIn, onKingsChatSignIn, onEmailStart, onEmailVerify, authMethods, customAuthLabel, onCustomAuthSignIn, canUsePasskey, passkeyAddress, onPasskeySignIn, onRotateShares, onExportPortableBackup, rpcUrls, chains, }: SocialWalletModalProps): React.ReactPortal | null;
|
|
901
1032
|
|
|
902
1033
|
declare function DecaneMark({ size, muted }: {
|
|
903
1034
|
size?: number;
|
|
@@ -1095,4 +1226,4 @@ declare function useSignTypedData(): {
|
|
|
1095
1226
|
reset: () => void;
|
|
1096
1227
|
};
|
|
1097
1228
|
|
|
1098
|
-
export { type ActiveSession, AttestationError, 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, NetworkError, NewDeviceError, OriginNotAllowedError, type PortableBackup, PromptPinNotConfiguredError, 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, type Theme, type TransactionRecord, type TxParams, type UnifiedWalletAccount, UnlockRequiredError, UserCancelledError, WalletSelector, WebAuthnNotSupportedError, type WrappedShareMeta, WrongPasswordError, createDecane, createDecaneConnect, createEthereumProvider, startEmailAuth, useChainSwitch, useDecane, useEthereumProvider, useSendTransaction, useSignMessage, useSignTypedData, useSocialAuth, useSocialBalance, useSocialWallet, useWalletSelector, verifyEmailCode };
|
|
1229
|
+
export { type ActiveSession, AttestationError, 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, 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 };
|