decane-connect-kit 2.23.0 → 2.24.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 +104 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -1
- package/dist/index.d.ts +18 -1
- package/dist/index.js +103 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -358,6 +358,19 @@ interface DecaneConnect {
|
|
|
358
358
|
connectWithToken(token: string, opts?: {
|
|
359
359
|
providerId?: string;
|
|
360
360
|
}): Promise<ConnectResult>;
|
|
361
|
+
/**
|
|
362
|
+
* Adopt a Decane access token another app of the same project handed over
|
|
363
|
+
* (in a URL, say): signed in at once, unlocked on the first signature.
|
|
364
|
+
*
|
|
365
|
+
* The token is the one every API call carries as a Bearer. The backend
|
|
366
|
+
* judges it — a revoked or foreign token is refused — and the session lasts
|
|
367
|
+
* as long as the token does, at most two hours; when it lapses the client
|
|
368
|
+
* emits `session-expired` and reads as signed out. No enclave session is
|
|
369
|
+
* opened: the first `unlock()` (or any signing call) provisions or unwraps
|
|
370
|
+
* the device share as an ordinary returning sign-in would, and with
|
|
371
|
+
* `deferDeviceProtection` prompts for nothing.
|
|
372
|
+
*/
|
|
373
|
+
connectWithAccessToken(token: string): Promise<ConnectResult>;
|
|
361
374
|
verifyEmailCode(email: string, code: string): Promise<ConnectResult>;
|
|
362
375
|
/**
|
|
363
376
|
* Send a 6-digit sign-in code by SMS (delivered via Termii).
|
|
@@ -1130,6 +1143,9 @@ declare class PromptPasswordNotConfiguredError extends DecaneConnectError {
|
|
|
1130
1143
|
declare class WrongUnlockPasswordError extends DecaneConnectError {
|
|
1131
1144
|
constructor();
|
|
1132
1145
|
}
|
|
1146
|
+
declare class InvalidAccessTokenError extends DecaneConnectError {
|
|
1147
|
+
constructor(reason: string);
|
|
1148
|
+
}
|
|
1133
1149
|
declare class UnlockTokenRejectedError extends DecaneConnectError {
|
|
1134
1150
|
constructor();
|
|
1135
1151
|
}
|
|
@@ -1423,6 +1439,7 @@ declare function useSocialAuth(): {
|
|
|
1423
1439
|
signInWithToken: (token: string, opts?: {
|
|
1424
1440
|
providerId?: string;
|
|
1425
1441
|
}) => Promise<void>;
|
|
1442
|
+
signInWithAccessToken: (token: string) => Promise<void>;
|
|
1426
1443
|
signInWithCustomAuth: (() => Promise<void>) | undefined;
|
|
1427
1444
|
signInWithPasskey: () => Promise<void>;
|
|
1428
1445
|
unlock: () => Promise<void>;
|
|
@@ -1598,4 +1615,4 @@ declare class WeakPasswordError extends Error {
|
|
|
1598
1615
|
*/
|
|
1599
1616
|
declare function validateUnlockPassword(password: string): void;
|
|
1600
1617
|
|
|
1601
|
-
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 };
|
|
1618
|
+
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, InvalidAccessTokenError, 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
|
@@ -358,6 +358,19 @@ interface DecaneConnect {
|
|
|
358
358
|
connectWithToken(token: string, opts?: {
|
|
359
359
|
providerId?: string;
|
|
360
360
|
}): Promise<ConnectResult>;
|
|
361
|
+
/**
|
|
362
|
+
* Adopt a Decane access token another app of the same project handed over
|
|
363
|
+
* (in a URL, say): signed in at once, unlocked on the first signature.
|
|
364
|
+
*
|
|
365
|
+
* The token is the one every API call carries as a Bearer. The backend
|
|
366
|
+
* judges it — a revoked or foreign token is refused — and the session lasts
|
|
367
|
+
* as long as the token does, at most two hours; when it lapses the client
|
|
368
|
+
* emits `session-expired` and reads as signed out. No enclave session is
|
|
369
|
+
* opened: the first `unlock()` (or any signing call) provisions or unwraps
|
|
370
|
+
* the device share as an ordinary returning sign-in would, and with
|
|
371
|
+
* `deferDeviceProtection` prompts for nothing.
|
|
372
|
+
*/
|
|
373
|
+
connectWithAccessToken(token: string): Promise<ConnectResult>;
|
|
361
374
|
verifyEmailCode(email: string, code: string): Promise<ConnectResult>;
|
|
362
375
|
/**
|
|
363
376
|
* Send a 6-digit sign-in code by SMS (delivered via Termii).
|
|
@@ -1130,6 +1143,9 @@ declare class PromptPasswordNotConfiguredError extends DecaneConnectError {
|
|
|
1130
1143
|
declare class WrongUnlockPasswordError extends DecaneConnectError {
|
|
1131
1144
|
constructor();
|
|
1132
1145
|
}
|
|
1146
|
+
declare class InvalidAccessTokenError extends DecaneConnectError {
|
|
1147
|
+
constructor(reason: string);
|
|
1148
|
+
}
|
|
1133
1149
|
declare class UnlockTokenRejectedError extends DecaneConnectError {
|
|
1134
1150
|
constructor();
|
|
1135
1151
|
}
|
|
@@ -1423,6 +1439,7 @@ declare function useSocialAuth(): {
|
|
|
1423
1439
|
signInWithToken: (token: string, opts?: {
|
|
1424
1440
|
providerId?: string;
|
|
1425
1441
|
}) => Promise<void>;
|
|
1442
|
+
signInWithAccessToken: (token: string) => Promise<void>;
|
|
1426
1443
|
signInWithCustomAuth: (() => Promise<void>) | undefined;
|
|
1427
1444
|
signInWithPasskey: () => Promise<void>;
|
|
1428
1445
|
unlock: () => Promise<void>;
|
|
@@ -1598,4 +1615,4 @@ declare class WeakPasswordError extends Error {
|
|
|
1598
1615
|
*/
|
|
1599
1616
|
declare function validateUnlockPassword(password: string): void;
|
|
1600
1617
|
|
|
1601
|
-
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 };
|
|
1618
|
+
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, InvalidAccessTokenError, 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.js
CHANGED
|
@@ -15,6 +15,7 @@ __export(errors_exports, {
|
|
|
15
15
|
CallSequenceError: () => CallSequenceError,
|
|
16
16
|
DecaneConnectError: () => DecaneConnectError,
|
|
17
17
|
ExportNotAuthorizedError: () => ExportNotAuthorizedError,
|
|
18
|
+
InvalidAccessTokenError: () => InvalidAccessTokenError,
|
|
18
19
|
InvalidApiKeyError: () => InvalidApiKeyError,
|
|
19
20
|
InvalidPinError: () => InvalidPinError,
|
|
20
21
|
InvalidRecoveryFileError: () => InvalidRecoveryFileError,
|
|
@@ -37,7 +38,7 @@ __export(errors_exports, {
|
|
|
37
38
|
WrongPasswordError: () => WrongPasswordError,
|
|
38
39
|
WrongUnlockPasswordError: () => WrongUnlockPasswordError
|
|
39
40
|
});
|
|
40
|
-
var DecaneConnectError, InvalidApiKeyError, OriginNotAllowedError, SessionExpiredError, UnlockRequiredError, ReconnectRequiredError, UserCancelledError, WebAuthnNotSupportedError, InvalidPinError, CallSequenceError, NetworkError, ShareCorruptedError, ProvisioningTimeoutError, NewDeviceError, StaleDeviceShareError, PromptPinNotConfiguredError, PromptPasswordNotConfiguredError, WrongUnlockPasswordError, UnlockTokenRejectedError, AttestationError, RecoveryFailedError, InvalidRecoveryFileError, WrongPasswordError, RecoveryWalletMismatchError, ExportNotAuthorizedError;
|
|
41
|
+
var DecaneConnectError, InvalidApiKeyError, OriginNotAllowedError, SessionExpiredError, UnlockRequiredError, ReconnectRequiredError, UserCancelledError, WebAuthnNotSupportedError, InvalidPinError, CallSequenceError, NetworkError, ShareCorruptedError, ProvisioningTimeoutError, NewDeviceError, StaleDeviceShareError, PromptPinNotConfiguredError, PromptPasswordNotConfiguredError, WrongUnlockPasswordError, InvalidAccessTokenError, UnlockTokenRejectedError, AttestationError, RecoveryFailedError, InvalidRecoveryFileError, WrongPasswordError, RecoveryWalletMismatchError, ExportNotAuthorizedError;
|
|
41
42
|
var init_errors = __esm({
|
|
42
43
|
"src/social/errors.ts"() {
|
|
43
44
|
"use strict";
|
|
@@ -142,6 +143,11 @@ var init_errors = __esm({
|
|
|
142
143
|
super("WRONG_UNLOCK_PASSWORD", "That password did not unlock this device");
|
|
143
144
|
}
|
|
144
145
|
};
|
|
146
|
+
InvalidAccessTokenError = class extends DecaneConnectError {
|
|
147
|
+
constructor(reason) {
|
|
148
|
+
super("INVALID_ACCESS_TOKEN", `That access token cannot open a session: ${reason}`);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
145
151
|
UnlockTokenRejectedError = class extends DecaneConnectError {
|
|
146
152
|
constructor() {
|
|
147
153
|
super("UNLOCK_TOKEN_REJECTED", "This device's unlock token is no longer valid \u2014 sign in normally to re-enable password unlock");
|
|
@@ -2273,6 +2279,20 @@ function b64ToBytes(b644) {
|
|
|
2273
2279
|
return Uint8Array.from(atob(b644), (c) => c.charCodeAt(0));
|
|
2274
2280
|
}
|
|
2275
2281
|
|
|
2282
|
+
// src/social/accessToken.ts
|
|
2283
|
+
function decodeAccessToken(token) {
|
|
2284
|
+
try {
|
|
2285
|
+
const payload = token.split(".")[1];
|
|
2286
|
+
if (!payload) return null;
|
|
2287
|
+
const json = JSON.parse(atob(payload.replace(/-/g, "+").replace(/_/g, "/")));
|
|
2288
|
+
if (typeof json.uid !== "string" || json.uid === "") return null;
|
|
2289
|
+
if (typeof json.exp !== "number" || !Number.isFinite(json.exp)) return null;
|
|
2290
|
+
return { userId: json.uid, expiresAt: json.exp * 1e3 };
|
|
2291
|
+
} catch {
|
|
2292
|
+
return null;
|
|
2293
|
+
}
|
|
2294
|
+
}
|
|
2295
|
+
|
|
2276
2296
|
// src/social/storage.ts
|
|
2277
2297
|
import { openDB } from "idb";
|
|
2278
2298
|
var DB_NAME = "decane-connect-kit";
|
|
@@ -3667,8 +3687,10 @@ async function createDecaneConnect(config) {
|
|
|
3667
3687
|
const durationMs = (config.sessionDurationMinutes ?? DEFAULT_SESSION_MINUTES) * 6e4;
|
|
3668
3688
|
const rpId = config.rpId ?? (typeof window !== "undefined" ? window.location.hostname : "localhost");
|
|
3669
3689
|
const rpName = config.rpName ?? "Decane Connect";
|
|
3670
|
-
const PERSIST_KEY = makePersistKey(config.
|
|
3671
|
-
const LAST_USER_KEY = makeLastUserKey(config.
|
|
3690
|
+
const PERSIST_KEY = makePersistKey(config.appId);
|
|
3691
|
+
const LAST_USER_KEY = makeLastUserKey(config.appId);
|
|
3692
|
+
const LEGACY_PERSIST_KEY = makePersistKey(config.apiKey);
|
|
3693
|
+
const LEGACY_LAST_USER_KEY = makeLastUserKey(config.apiKey);
|
|
3672
3694
|
const teeUrl = config.teeUrl ?? DEFAULT_TEE_URL;
|
|
3673
3695
|
const events = new EventEmitter();
|
|
3674
3696
|
const api = new ApiClient(baseUrl, config.apiKey, config.appId);
|
|
@@ -3681,7 +3703,14 @@ async function createDecaneConnect(config) {
|
|
|
3681
3703
|
);
|
|
3682
3704
|
let auth = null;
|
|
3683
3705
|
let persisted = loadPersisted(PERSIST_KEY);
|
|
3684
|
-
|
|
3706
|
+
if (!persisted && LEGACY_PERSIST_KEY !== PERSIST_KEY) {
|
|
3707
|
+
persisted = loadPersisted(LEGACY_PERSIST_KEY);
|
|
3708
|
+
if (persisted) {
|
|
3709
|
+
savePersisted(PERSIST_KEY, persisted);
|
|
3710
|
+
clearPersisted(LEGACY_PERSIST_KEY);
|
|
3711
|
+
}
|
|
3712
|
+
}
|
|
3713
|
+
let lastUserId = loadLastUser(LAST_USER_KEY) ?? (LEGACY_LAST_USER_KEY !== LAST_USER_KEY ? loadLastUser(LEGACY_LAST_USER_KEY) : null);
|
|
3685
3714
|
let ethProvider = null;
|
|
3686
3715
|
const persistSession = config.persistSession !== false;
|
|
3687
3716
|
const deferDeviceProtection = config.deferDeviceProtection === true;
|
|
@@ -3744,12 +3773,13 @@ async function createDecaneConnect(config) {
|
|
|
3744
3773
|
})
|
|
3745
3774
|
]).finally(() => clearTimeout(timer));
|
|
3746
3775
|
}
|
|
3747
|
-
const SESSION_KEY = sessionPersistKey(config.
|
|
3776
|
+
const SESSION_KEY = sessionPersistKey(config.appId);
|
|
3777
|
+
const LEGACY_SESSION_KEY = sessionPersistKey(config.apiKey);
|
|
3748
3778
|
function persistLiveSession() {
|
|
3749
|
-
if (!persistSession) return;
|
|
3779
|
+
if (!persistSession || !auth) return;
|
|
3750
3780
|
const handle = session.getHandle();
|
|
3751
|
-
const expiresAt = session.expiresAtTimestamp();
|
|
3752
|
-
if (!
|
|
3781
|
+
const expiresAt = handle ? session.expiresAtTimestamp() : decodeAccessToken(auth.jwt)?.expiresAt ?? null;
|
|
3782
|
+
if (!expiresAt) return;
|
|
3753
3783
|
saveSession(SESSION_KEY, {
|
|
3754
3784
|
handle,
|
|
3755
3785
|
jwt: auth.jwt,
|
|
@@ -3761,11 +3791,23 @@ async function createDecaneConnect(config) {
|
|
|
3761
3791
|
function dropLiveSession() {
|
|
3762
3792
|
clearSessionPersist(SESSION_KEY);
|
|
3763
3793
|
}
|
|
3794
|
+
let accessTokenExpiry = null;
|
|
3795
|
+
function scheduleAccessTokenExpiry(jwt, expiresAt) {
|
|
3796
|
+
if (accessTokenExpiry) clearTimeout(accessTokenExpiry);
|
|
3797
|
+
accessTokenExpiry = setTimeout(() => {
|
|
3798
|
+
accessTokenExpiry = null;
|
|
3799
|
+
if (auth?.jwt !== jwt || session.isActive()) return;
|
|
3800
|
+
auth = null;
|
|
3801
|
+
dropLiveSession();
|
|
3802
|
+
events.emit("session-expired");
|
|
3803
|
+
}, Math.max(0, expiresAt - Date.now()));
|
|
3804
|
+
}
|
|
3764
3805
|
if (persistSession) {
|
|
3765
|
-
const saved = loadSession(SESSION_KEY);
|
|
3766
|
-
if (saved
|
|
3806
|
+
const saved = loadSession(SESSION_KEY) ?? (LEGACY_SESSION_KEY !== SESSION_KEY ? loadSession(LEGACY_SESSION_KEY) : null);
|
|
3807
|
+
if (saved && saved.expiresAt > Date.now() + 5e3) {
|
|
3767
3808
|
try {
|
|
3768
|
-
session.resume(saved.handle, saved.addresses, saved.expiresAt);
|
|
3809
|
+
if (saved.handle) session.resume(saved.handle, saved.addresses, saved.expiresAt);
|
|
3810
|
+
else scheduleAccessTokenExpiry(saved.jwt, saved.expiresAt);
|
|
3769
3811
|
auth = { jwt: saved.jwt, userId: saved.userId, addresses: saved.addresses };
|
|
3770
3812
|
persisted = { userId: saved.userId, addresses: saved.addresses };
|
|
3771
3813
|
} catch {
|
|
@@ -3774,6 +3816,7 @@ async function createDecaneConnect(config) {
|
|
|
3774
3816
|
} else if (saved) {
|
|
3775
3817
|
dropLiveSession();
|
|
3776
3818
|
}
|
|
3819
|
+
if (LEGACY_SESSION_KEY !== SESSION_KEY) clearSessionPersist(LEGACY_SESSION_KEY);
|
|
3777
3820
|
}
|
|
3778
3821
|
events.on("session-expired", () => dropLiveSession());
|
|
3779
3822
|
async function passwordSetup() {
|
|
@@ -4491,6 +4534,27 @@ async function createDecaneConnect(config) {
|
|
|
4491
4534
|
const result = await api.authExternal(token, opts?.providerId);
|
|
4492
4535
|
return handleAuthResult(result);
|
|
4493
4536
|
},
|
|
4537
|
+
async connectWithAccessToken(token) {
|
|
4538
|
+
const claims = decodeAccessToken(token);
|
|
4539
|
+
if (!claims) throw new InvalidAccessTokenError("not a Decane access token");
|
|
4540
|
+
if (claims.expiresAt <= Date.now() + 5e3) throw new InvalidAccessTokenError("it has expired");
|
|
4541
|
+
const raw = await api.getAddresses(token);
|
|
4542
|
+
if (!raw.evm || !raw.solana) throw new InvalidAccessTokenError("this account holds no wallet yet");
|
|
4543
|
+
const addresses = { evm: raw.evm, solana: raw.solana, tron: raw.tron ?? evmToTronAddress2(raw.evm) };
|
|
4544
|
+
if (session.isActive()) session.end();
|
|
4545
|
+
auth = { jwt: token, userId: claims.userId, addresses };
|
|
4546
|
+
persisted = { userId: claims.userId, addresses };
|
|
4547
|
+
savePersisted(PERSIST_KEY, persisted);
|
|
4548
|
+
events.emit("connected");
|
|
4549
|
+
persistLiveSession();
|
|
4550
|
+
scheduleAccessTokenExpiry(token, claims.expiresAt);
|
|
4551
|
+
const stored = await storage.getShare(claims.userId);
|
|
4552
|
+
return {
|
|
4553
|
+
addresses,
|
|
4554
|
+
isNewUser: false,
|
|
4555
|
+
...stored?.profile ? { profile: stored.profile } : {}
|
|
4556
|
+
};
|
|
4557
|
+
},
|
|
4494
4558
|
async connectWithEmail(email) {
|
|
4495
4559
|
await startEmailAuth(api, email);
|
|
4496
4560
|
return { codeRequired: true };
|
|
@@ -7483,6 +7547,18 @@ function DecaneKit({ config, children }) {
|
|
|
7483
7547
|
throw e;
|
|
7484
7548
|
}
|
|
7485
7549
|
}, [clearPhase]);
|
|
7550
|
+
const connectWithAccessToken = useCallback3(async (token) => {
|
|
7551
|
+
const sdk = socialRef.current;
|
|
7552
|
+
if (!sdk) throw new Error("Social sign-in not configured");
|
|
7553
|
+
try {
|
|
7554
|
+
const result = await sdk.connectWithAccessToken(token);
|
|
7555
|
+
applyResult(result);
|
|
7556
|
+
setSelectorOpen(false);
|
|
7557
|
+
} catch (e) {
|
|
7558
|
+
clearPhase();
|
|
7559
|
+
throw e;
|
|
7560
|
+
}
|
|
7561
|
+
}, [clearPhase]);
|
|
7486
7562
|
const customAuthConfig = config?.social?.customAuth;
|
|
7487
7563
|
const connectWithCustomAuth = useCallback3(async () => {
|
|
7488
7564
|
if (!customAuthConfig) throw new Error("Custom auth not configured");
|
|
@@ -7675,6 +7751,7 @@ function DecaneKit({ config, children }) {
|
|
|
7675
7751
|
connectWithPhone,
|
|
7676
7752
|
verifyPhoneCode: verifyPhoneCode2,
|
|
7677
7753
|
connectWithToken,
|
|
7754
|
+
connectWithAccessToken,
|
|
7678
7755
|
customAuthLabel: customAuthConfig?.label,
|
|
7679
7756
|
connectWithCustomAuth: customAuthConfig ? connectWithCustomAuth : void 0,
|
|
7680
7757
|
socialUnlock,
|
|
@@ -7790,6 +7867,7 @@ function useSocialAuth() {
|
|
|
7790
7867
|
connectWithPhone,
|
|
7791
7868
|
verifyPhoneCode: verifyPhoneCode2,
|
|
7792
7869
|
connectWithToken,
|
|
7870
|
+
connectWithAccessToken,
|
|
7793
7871
|
customAuthLabel,
|
|
7794
7872
|
connectWithCustomAuth,
|
|
7795
7873
|
signInWithPasskey: ctxSignInWithPasskey,
|
|
@@ -7898,6 +7976,18 @@ function useSocialAuth() {
|
|
|
7898
7976
|
setTokenLoading(false);
|
|
7899
7977
|
}
|
|
7900
7978
|
}, [connectWithToken]);
|
|
7979
|
+
const signInWithAccessToken = useCallback4(async (token) => {
|
|
7980
|
+
setTokenLoading(true);
|
|
7981
|
+
setError(null);
|
|
7982
|
+
try {
|
|
7983
|
+
await connectWithAccessToken(token);
|
|
7984
|
+
} catch (e) {
|
|
7985
|
+
setError(e.message);
|
|
7986
|
+
throw e;
|
|
7987
|
+
} finally {
|
|
7988
|
+
setTokenLoading(false);
|
|
7989
|
+
}
|
|
7990
|
+
}, [connectWithAccessToken]);
|
|
7901
7991
|
const signInWithCustomAuth = useCallback4(async () => {
|
|
7902
7992
|
if (!connectWithCustomAuth) throw new Error("Custom auth not configured");
|
|
7903
7993
|
setCustomLoading(true);
|
|
@@ -7980,6 +8070,7 @@ function useSocialAuth() {
|
|
|
7980
8070
|
sendPhoneCode,
|
|
7981
8071
|
confirmPhoneCode,
|
|
7982
8072
|
signInWithToken,
|
|
8073
|
+
signInWithAccessToken,
|
|
7983
8074
|
signInWithCustomAuth: connectWithCustomAuth ? signInWithCustomAuth : void 0,
|
|
7984
8075
|
signInWithPasskey,
|
|
7985
8076
|
unlock,
|
|
@@ -8528,6 +8619,7 @@ export {
|
|
|
8528
8619
|
DecaneMark,
|
|
8529
8620
|
DecaneWordmark,
|
|
8530
8621
|
ExportNotAuthorizedError,
|
|
8622
|
+
InvalidAccessTokenError,
|
|
8531
8623
|
InvalidApiKeyError,
|
|
8532
8624
|
InvalidPinError,
|
|
8533
8625
|
InvalidRecoveryFileError,
|