decane-connect-kit 2.4.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 +425 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +182 -7
- package/dist/index.d.ts +182 -7
- package/dist/index.js +423 -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<{
|
|
@@ -185,6 +207,16 @@ declare class ApiClient {
|
|
|
185
207
|
solanaAddress: string;
|
|
186
208
|
tronAddress: string;
|
|
187
209
|
}): Promise<void>;
|
|
210
|
+
recordTransaction(jwt: string, tx: {
|
|
211
|
+
chain: string;
|
|
212
|
+
txHash?: string;
|
|
213
|
+
to?: string;
|
|
214
|
+
value?: string;
|
|
215
|
+
kind?: string;
|
|
216
|
+
status?: string;
|
|
217
|
+
metadata?: Record<string, unknown>;
|
|
218
|
+
}): Promise<TransactionRecord>;
|
|
219
|
+
getTransactions(jwt: string, limit?: number): Promise<TransactionRecord[]>;
|
|
188
220
|
getWebAuthnRegisterOptions(jwt: string, rpId: string, rpName: string): Promise<_simplewebauthn_browser.PublicKeyCredentialCreationOptionsJSON>;
|
|
189
221
|
postWebAuthnRegister(jwt: string, response: _simplewebauthn_browser.RegistrationResponseJSON, origin: string): Promise<void>;
|
|
190
222
|
/**
|
|
@@ -336,7 +368,15 @@ interface DecaneConnectConfig {
|
|
|
336
368
|
appId: string;
|
|
337
369
|
apiKey: string;
|
|
338
370
|
chains: Chain[];
|
|
339
|
-
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[];
|
|
340
380
|
apiBaseUrl?: string;
|
|
341
381
|
sessionDurationMinutes?: number;
|
|
342
382
|
promptPin?: () => Promise<string>;
|
|
@@ -402,6 +442,48 @@ interface DecaneConnectConfig {
|
|
|
402
442
|
}>;
|
|
403
443
|
/** Recovery stage callbacks, for dApp UI. */
|
|
404
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;
|
|
405
487
|
}
|
|
406
488
|
interface ConnectResult {
|
|
407
489
|
addresses: {
|
|
@@ -411,6 +493,29 @@ interface ConnectResult {
|
|
|
411
493
|
};
|
|
412
494
|
isNewUser: boolean;
|
|
413
495
|
}
|
|
496
|
+
/** A recorded on-chain transaction in the user's history. */
|
|
497
|
+
interface TransactionRecord {
|
|
498
|
+
id: string;
|
|
499
|
+
chain: string;
|
|
500
|
+
kind: string;
|
|
501
|
+
txHash: string | null;
|
|
502
|
+
to: string | null;
|
|
503
|
+
value: string | null;
|
|
504
|
+
status: 'submitted' | 'confirmed' | 'failed' | string;
|
|
505
|
+
metadata: Record<string, unknown> | null;
|
|
506
|
+
createdAt: string;
|
|
507
|
+
updatedAt?: string;
|
|
508
|
+
}
|
|
509
|
+
/** What the dApp passes to record a transaction it broadcast. */
|
|
510
|
+
interface RecordTransactionInput {
|
|
511
|
+
chain: string;
|
|
512
|
+
txHash?: string;
|
|
513
|
+
to?: string;
|
|
514
|
+
value?: string;
|
|
515
|
+
kind?: string;
|
|
516
|
+
status?: string;
|
|
517
|
+
metadata?: Record<string, unknown>;
|
|
518
|
+
}
|
|
414
519
|
interface SignMessageRequest {
|
|
415
520
|
chain: Chain;
|
|
416
521
|
message: string | Uint8Array;
|
|
@@ -434,6 +539,30 @@ type SdkEvent = 'connected' | 'disconnected' | 'session-expired' | 'session-star
|
|
|
434
539
|
interface DecaneConnect {
|
|
435
540
|
connect(): Promise<ConnectResult>;
|
|
436
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>;
|
|
437
566
|
connectWithEmail(email: string): Promise<{
|
|
438
567
|
codeRequired: true;
|
|
439
568
|
}>;
|
|
@@ -521,6 +650,15 @@ interface DecaneConnect {
|
|
|
521
650
|
* the transaction's `signature` array and broadcast via TronWeb / a full node.
|
|
522
651
|
*/
|
|
523
652
|
signTronTransaction(rawDataHex: string): Promise<string>;
|
|
653
|
+
/**
|
|
654
|
+
* Record a transaction this wallet broadcast, so it appears in the user's
|
|
655
|
+
* history (and the developer dashboard). EVM `sendTransaction` records itself
|
|
656
|
+
* automatically; call this for Solana/Tron transactions your dApp broadcasts,
|
|
657
|
+
* or to attach a `confirmed`/`failed` status update to an existing hash.
|
|
658
|
+
*/
|
|
659
|
+
recordTransaction(tx: RecordTransactionInput): Promise<TransactionRecord>;
|
|
660
|
+
/** The user's transaction history, most recent first. Requires a live session. */
|
|
661
|
+
getTransactionHistory(limit?: number): Promise<TransactionRecord[]>;
|
|
524
662
|
disconnect(): Promise<void>;
|
|
525
663
|
getAddresses(): {
|
|
526
664
|
evm?: string;
|
|
@@ -598,6 +736,24 @@ declare function startEmailAuth(api: ApiClient, email: string): Promise<void>;
|
|
|
598
736
|
*/
|
|
599
737
|
declare function verifyEmailCode(api: ApiClient, email: string, code: string): Promise<AuthResult>;
|
|
600
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
|
+
|
|
601
757
|
declare class DecaneConnectError extends Error {
|
|
602
758
|
code: string;
|
|
603
759
|
retryable: boolean;
|
|
@@ -652,6 +808,21 @@ declare class ShareCorruptedError extends DecaneConnectError {
|
|
|
652
808
|
declare class NewDeviceError extends DecaneConnectError {
|
|
653
809
|
constructor();
|
|
654
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
|
+
}
|
|
655
826
|
declare class PromptPinNotConfiguredError extends DecaneConnectError {
|
|
656
827
|
constructor();
|
|
657
828
|
}
|
|
@@ -770,8 +941,9 @@ interface WalletSelectorProps {
|
|
|
770
941
|
theme?: "light" | "dark" | "auto";
|
|
771
942
|
networks?: "evm" | "solana" | "tron" | "bitcoin" | "all";
|
|
772
943
|
mode?: ConnectMode;
|
|
773
|
-
socialAuthMethods?: ("google" | "email")[];
|
|
944
|
+
socialAuthMethods?: ("google" | "email" | "kingschat")[];
|
|
774
945
|
onGoogleSignIn?: () => Promise<void>;
|
|
946
|
+
onKingsChatSignIn?: () => Promise<void>;
|
|
775
947
|
onEmailStart?: (email: string) => Promise<{
|
|
776
948
|
codeRequired: true;
|
|
777
949
|
}>;
|
|
@@ -785,7 +957,7 @@ interface WalletSelectorProps {
|
|
|
785
957
|
passkeyAddress?: string | null;
|
|
786
958
|
onPasskeySignIn?: () => Promise<unknown>;
|
|
787
959
|
}
|
|
788
|
-
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;
|
|
789
961
|
|
|
790
962
|
type Theme = "light" | "dark" | "auto";
|
|
791
963
|
interface SocialAuthState {
|
|
@@ -834,11 +1006,12 @@ interface SocialWalletModalProps {
|
|
|
834
1006
|
onUnlock: () => Promise<void>;
|
|
835
1007
|
onDisconnect: () => Promise<void>;
|
|
836
1008
|
onGoogleSignIn: () => Promise<void>;
|
|
1009
|
+
onKingsChatSignIn?: () => Promise<void>;
|
|
837
1010
|
onEmailStart: (email: string) => Promise<{
|
|
838
1011
|
codeRequired: true;
|
|
839
1012
|
}>;
|
|
840
1013
|
onEmailVerify: (email: string, code: string) => Promise<void>;
|
|
841
|
-
authMethods?: Array<"google" | "email">;
|
|
1014
|
+
authMethods?: Array<"google" | "email" | "kingschat">;
|
|
842
1015
|
customAuthLabel?: string;
|
|
843
1016
|
onCustomAuthSignIn?: () => Promise<void>;
|
|
844
1017
|
canUsePasskey?: boolean;
|
|
@@ -855,7 +1028,7 @@ interface SocialWalletModalProps {
|
|
|
855
1028
|
rpcUrls?: Record<string, string>;
|
|
856
1029
|
chains?: string[];
|
|
857
1030
|
}
|
|
858
|
-
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;
|
|
859
1032
|
|
|
860
1033
|
declare function DecaneMark({ size, muted }: {
|
|
861
1034
|
size?: number;
|
|
@@ -933,6 +1106,8 @@ declare function useSocialWallet(): {
|
|
|
933
1106
|
}) => Promise<string>;
|
|
934
1107
|
signSolanaTransaction: (tx: Uint8Array) => Promise<Uint8Array<ArrayBufferLike>>;
|
|
935
1108
|
signTronTransaction: (rawDataHex: string) => Promise<string>;
|
|
1109
|
+
recordTransaction: (tx: RecordTransactionInput) => Promise<TransactionRecord>;
|
|
1110
|
+
getTransactionHistory: (limit?: number) => Promise<TransactionRecord[]>;
|
|
936
1111
|
signTypedData: (req: {
|
|
937
1112
|
chain: string;
|
|
938
1113
|
domain: Record<string, unknown>;
|
|
@@ -1051,4 +1226,4 @@ declare function useSignTypedData(): {
|
|
|
1051
1226
|
reset: () => void;
|
|
1052
1227
|
};
|
|
1053
1228
|
|
|
1054
|
-
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, 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 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<{
|
|
@@ -185,6 +207,16 @@ declare class ApiClient {
|
|
|
185
207
|
solanaAddress: string;
|
|
186
208
|
tronAddress: string;
|
|
187
209
|
}): Promise<void>;
|
|
210
|
+
recordTransaction(jwt: string, tx: {
|
|
211
|
+
chain: string;
|
|
212
|
+
txHash?: string;
|
|
213
|
+
to?: string;
|
|
214
|
+
value?: string;
|
|
215
|
+
kind?: string;
|
|
216
|
+
status?: string;
|
|
217
|
+
metadata?: Record<string, unknown>;
|
|
218
|
+
}): Promise<TransactionRecord>;
|
|
219
|
+
getTransactions(jwt: string, limit?: number): Promise<TransactionRecord[]>;
|
|
188
220
|
getWebAuthnRegisterOptions(jwt: string, rpId: string, rpName: string): Promise<_simplewebauthn_browser.PublicKeyCredentialCreationOptionsJSON>;
|
|
189
221
|
postWebAuthnRegister(jwt: string, response: _simplewebauthn_browser.RegistrationResponseJSON, origin: string): Promise<void>;
|
|
190
222
|
/**
|
|
@@ -336,7 +368,15 @@ interface DecaneConnectConfig {
|
|
|
336
368
|
appId: string;
|
|
337
369
|
apiKey: string;
|
|
338
370
|
chains: Chain[];
|
|
339
|
-
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[];
|
|
340
380
|
apiBaseUrl?: string;
|
|
341
381
|
sessionDurationMinutes?: number;
|
|
342
382
|
promptPin?: () => Promise<string>;
|
|
@@ -402,6 +442,48 @@ interface DecaneConnectConfig {
|
|
|
402
442
|
}>;
|
|
403
443
|
/** Recovery stage callbacks, for dApp UI. */
|
|
404
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;
|
|
405
487
|
}
|
|
406
488
|
interface ConnectResult {
|
|
407
489
|
addresses: {
|
|
@@ -411,6 +493,29 @@ interface ConnectResult {
|
|
|
411
493
|
};
|
|
412
494
|
isNewUser: boolean;
|
|
413
495
|
}
|
|
496
|
+
/** A recorded on-chain transaction in the user's history. */
|
|
497
|
+
interface TransactionRecord {
|
|
498
|
+
id: string;
|
|
499
|
+
chain: string;
|
|
500
|
+
kind: string;
|
|
501
|
+
txHash: string | null;
|
|
502
|
+
to: string | null;
|
|
503
|
+
value: string | null;
|
|
504
|
+
status: 'submitted' | 'confirmed' | 'failed' | string;
|
|
505
|
+
metadata: Record<string, unknown> | null;
|
|
506
|
+
createdAt: string;
|
|
507
|
+
updatedAt?: string;
|
|
508
|
+
}
|
|
509
|
+
/** What the dApp passes to record a transaction it broadcast. */
|
|
510
|
+
interface RecordTransactionInput {
|
|
511
|
+
chain: string;
|
|
512
|
+
txHash?: string;
|
|
513
|
+
to?: string;
|
|
514
|
+
value?: string;
|
|
515
|
+
kind?: string;
|
|
516
|
+
status?: string;
|
|
517
|
+
metadata?: Record<string, unknown>;
|
|
518
|
+
}
|
|
414
519
|
interface SignMessageRequest {
|
|
415
520
|
chain: Chain;
|
|
416
521
|
message: string | Uint8Array;
|
|
@@ -434,6 +539,30 @@ type SdkEvent = 'connected' | 'disconnected' | 'session-expired' | 'session-star
|
|
|
434
539
|
interface DecaneConnect {
|
|
435
540
|
connect(): Promise<ConnectResult>;
|
|
436
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>;
|
|
437
566
|
connectWithEmail(email: string): Promise<{
|
|
438
567
|
codeRequired: true;
|
|
439
568
|
}>;
|
|
@@ -521,6 +650,15 @@ interface DecaneConnect {
|
|
|
521
650
|
* the transaction's `signature` array and broadcast via TronWeb / a full node.
|
|
522
651
|
*/
|
|
523
652
|
signTronTransaction(rawDataHex: string): Promise<string>;
|
|
653
|
+
/**
|
|
654
|
+
* Record a transaction this wallet broadcast, so it appears in the user's
|
|
655
|
+
* history (and the developer dashboard). EVM `sendTransaction` records itself
|
|
656
|
+
* automatically; call this for Solana/Tron transactions your dApp broadcasts,
|
|
657
|
+
* or to attach a `confirmed`/`failed` status update to an existing hash.
|
|
658
|
+
*/
|
|
659
|
+
recordTransaction(tx: RecordTransactionInput): Promise<TransactionRecord>;
|
|
660
|
+
/** The user's transaction history, most recent first. Requires a live session. */
|
|
661
|
+
getTransactionHistory(limit?: number): Promise<TransactionRecord[]>;
|
|
524
662
|
disconnect(): Promise<void>;
|
|
525
663
|
getAddresses(): {
|
|
526
664
|
evm?: string;
|
|
@@ -598,6 +736,24 @@ declare function startEmailAuth(api: ApiClient, email: string): Promise<void>;
|
|
|
598
736
|
*/
|
|
599
737
|
declare function verifyEmailCode(api: ApiClient, email: string, code: string): Promise<AuthResult>;
|
|
600
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
|
+
|
|
601
757
|
declare class DecaneConnectError extends Error {
|
|
602
758
|
code: string;
|
|
603
759
|
retryable: boolean;
|
|
@@ -652,6 +808,21 @@ declare class ShareCorruptedError extends DecaneConnectError {
|
|
|
652
808
|
declare class NewDeviceError extends DecaneConnectError {
|
|
653
809
|
constructor();
|
|
654
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
|
+
}
|
|
655
826
|
declare class PromptPinNotConfiguredError extends DecaneConnectError {
|
|
656
827
|
constructor();
|
|
657
828
|
}
|
|
@@ -770,8 +941,9 @@ interface WalletSelectorProps {
|
|
|
770
941
|
theme?: "light" | "dark" | "auto";
|
|
771
942
|
networks?: "evm" | "solana" | "tron" | "bitcoin" | "all";
|
|
772
943
|
mode?: ConnectMode;
|
|
773
|
-
socialAuthMethods?: ("google" | "email")[];
|
|
944
|
+
socialAuthMethods?: ("google" | "email" | "kingschat")[];
|
|
774
945
|
onGoogleSignIn?: () => Promise<void>;
|
|
946
|
+
onKingsChatSignIn?: () => Promise<void>;
|
|
775
947
|
onEmailStart?: (email: string) => Promise<{
|
|
776
948
|
codeRequired: true;
|
|
777
949
|
}>;
|
|
@@ -785,7 +957,7 @@ interface WalletSelectorProps {
|
|
|
785
957
|
passkeyAddress?: string | null;
|
|
786
958
|
onPasskeySignIn?: () => Promise<unknown>;
|
|
787
959
|
}
|
|
788
|
-
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;
|
|
789
961
|
|
|
790
962
|
type Theme = "light" | "dark" | "auto";
|
|
791
963
|
interface SocialAuthState {
|
|
@@ -834,11 +1006,12 @@ interface SocialWalletModalProps {
|
|
|
834
1006
|
onUnlock: () => Promise<void>;
|
|
835
1007
|
onDisconnect: () => Promise<void>;
|
|
836
1008
|
onGoogleSignIn: () => Promise<void>;
|
|
1009
|
+
onKingsChatSignIn?: () => Promise<void>;
|
|
837
1010
|
onEmailStart: (email: string) => Promise<{
|
|
838
1011
|
codeRequired: true;
|
|
839
1012
|
}>;
|
|
840
1013
|
onEmailVerify: (email: string, code: string) => Promise<void>;
|
|
841
|
-
authMethods?: Array<"google" | "email">;
|
|
1014
|
+
authMethods?: Array<"google" | "email" | "kingschat">;
|
|
842
1015
|
customAuthLabel?: string;
|
|
843
1016
|
onCustomAuthSignIn?: () => Promise<void>;
|
|
844
1017
|
canUsePasskey?: boolean;
|
|
@@ -855,7 +1028,7 @@ interface SocialWalletModalProps {
|
|
|
855
1028
|
rpcUrls?: Record<string, string>;
|
|
856
1029
|
chains?: string[];
|
|
857
1030
|
}
|
|
858
|
-
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;
|
|
859
1032
|
|
|
860
1033
|
declare function DecaneMark({ size, muted }: {
|
|
861
1034
|
size?: number;
|
|
@@ -933,6 +1106,8 @@ declare function useSocialWallet(): {
|
|
|
933
1106
|
}) => Promise<string>;
|
|
934
1107
|
signSolanaTransaction: (tx: Uint8Array) => Promise<Uint8Array<ArrayBufferLike>>;
|
|
935
1108
|
signTronTransaction: (rawDataHex: string) => Promise<string>;
|
|
1109
|
+
recordTransaction: (tx: RecordTransactionInput) => Promise<TransactionRecord>;
|
|
1110
|
+
getTransactionHistory: (limit?: number) => Promise<TransactionRecord[]>;
|
|
936
1111
|
signTypedData: (req: {
|
|
937
1112
|
chain: string;
|
|
938
1113
|
domain: Record<string, unknown>;
|
|
@@ -1051,4 +1226,4 @@ declare function useSignTypedData(): {
|
|
|
1051
1226
|
reset: () => void;
|
|
1052
1227
|
};
|
|
1053
1228
|
|
|
1054
|
-
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, 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 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 };
|