decane-connect-kit 2.21.0 → 2.22.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 +58 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +58 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3689,6 +3689,29 @@ function clearPersisted(key) {
|
|
|
3689
3689
|
} catch {
|
|
3690
3690
|
}
|
|
3691
3691
|
}
|
|
3692
|
+
function makeLastUserKey(apiKey) {
|
|
3693
|
+
return `${makePersistKey(apiKey)}:last-user`;
|
|
3694
|
+
}
|
|
3695
|
+
function loadLastUser(key) {
|
|
3696
|
+
try {
|
|
3697
|
+
const raw = typeof localStorage !== "undefined" ? localStorage.getItem(key) : null;
|
|
3698
|
+
return raw ? JSON.parse(raw).userId ?? null : null;
|
|
3699
|
+
} catch {
|
|
3700
|
+
return null;
|
|
3701
|
+
}
|
|
3702
|
+
}
|
|
3703
|
+
function saveLastUser(key, userId) {
|
|
3704
|
+
try {
|
|
3705
|
+
localStorage.setItem(key, JSON.stringify({ userId }));
|
|
3706
|
+
} catch {
|
|
3707
|
+
}
|
|
3708
|
+
}
|
|
3709
|
+
function clearLastUser(key) {
|
|
3710
|
+
try {
|
|
3711
|
+
localStorage.removeItem(key);
|
|
3712
|
+
} catch {
|
|
3713
|
+
}
|
|
3714
|
+
}
|
|
3692
3715
|
function sessionPersistKey(apiKey) {
|
|
3693
3716
|
return `decane:sess:${apiKey.slice(0, 20)}`;
|
|
3694
3717
|
}
|
|
@@ -3727,6 +3750,7 @@ async function createDecaneConnect(config) {
|
|
|
3727
3750
|
const rpId = config.rpId ?? (typeof window !== "undefined" ? window.location.hostname : "localhost");
|
|
3728
3751
|
const rpName = config.rpName ?? "Decane Connect";
|
|
3729
3752
|
const PERSIST_KEY = makePersistKey(config.apiKey);
|
|
3753
|
+
const LAST_USER_KEY = makeLastUserKey(config.apiKey);
|
|
3730
3754
|
const teeUrl = config.teeUrl ?? DEFAULT_TEE_URL;
|
|
3731
3755
|
const events = new EventEmitter();
|
|
3732
3756
|
const api = new ApiClient(baseUrl, config.apiKey, config.appId);
|
|
@@ -3739,6 +3763,7 @@ async function createDecaneConnect(config) {
|
|
|
3739
3763
|
);
|
|
3740
3764
|
let auth = null;
|
|
3741
3765
|
let persisted = loadPersisted(PERSIST_KEY);
|
|
3766
|
+
let lastUserId = loadLastUser(LAST_USER_KEY);
|
|
3742
3767
|
let ethProvider = null;
|
|
3743
3768
|
const persistSession = config.persistSession !== false;
|
|
3744
3769
|
const serverAssistedRecovery = true;
|
|
@@ -3884,6 +3909,10 @@ async function createDecaneConnect(config) {
|
|
|
3884
3909
|
const stored = await storage.getShare(persisted.userId);
|
|
3885
3910
|
return hasPasswordUnlock(stored) ? stored : null;
|
|
3886
3911
|
}
|
|
3912
|
+
if (lastUserId) {
|
|
3913
|
+
const stored = await storage.getShare(lastUserId);
|
|
3914
|
+
return hasPasswordUnlock(stored) ? stored : null;
|
|
3915
|
+
}
|
|
3887
3916
|
const candidates = (await storage.listShares()).filter(hasPasswordUnlock);
|
|
3888
3917
|
return candidates.length === 1 ? candidates[0] : null;
|
|
3889
3918
|
}
|
|
@@ -4337,14 +4366,16 @@ async function createDecaneConnect(config) {
|
|
|
4337
4366
|
async function passkeyDeviceCandidate() {
|
|
4338
4367
|
if (!isPasskeySupported()) return null;
|
|
4339
4368
|
if (persisted?.userId) return passkeyLoginCandidate();
|
|
4369
|
+
if (lastUserId) return usablePasskeyShare(await storage.getShare(lastUserId));
|
|
4340
4370
|
const candidates = (await storage.listShares()).map(usablePasskeyShare).filter(Boolean);
|
|
4341
4371
|
return candidates.length === 1 ? candidates[0] : null;
|
|
4342
4372
|
}
|
|
4343
4373
|
async function canOfferPasskey() {
|
|
4344
4374
|
if (!isPasskeySupported()) return false;
|
|
4345
4375
|
if (await passkeyDeviceCandidate()) return true;
|
|
4346
|
-
|
|
4347
|
-
|
|
4376
|
+
const known = persisted?.userId ?? lastUserId;
|
|
4377
|
+
if (!known) return false;
|
|
4378
|
+
return await storage.getShare(known) == null;
|
|
4348
4379
|
}
|
|
4349
4380
|
async function rememberProfile(userId, profile) {
|
|
4350
4381
|
const incoming = Object.fromEntries(Object.entries(profile).filter(([, v]) => v));
|
|
@@ -4557,8 +4588,9 @@ async function createDecaneConnect(config) {
|
|
|
4557
4588
|
async signInWithPasskey() {
|
|
4558
4589
|
const candidate = await passkeyDeviceCandidate();
|
|
4559
4590
|
if (candidate) return passkeyLogin(candidate);
|
|
4560
|
-
|
|
4561
|
-
|
|
4591
|
+
const known = persisted?.userId ?? lastUserId;
|
|
4592
|
+
if (isPasskeySupported() && known && await storage.getShare(known) == null) {
|
|
4593
|
+
return passkeyLoginWithoutShare(known);
|
|
4562
4594
|
}
|
|
4563
4595
|
throw new NewDeviceError();
|
|
4564
4596
|
},
|
|
@@ -4898,12 +4930,21 @@ async function createDecaneConnect(config) {
|
|
|
4898
4930
|
await api.revoke(auth.jwt).catch(() => {
|
|
4899
4931
|
});
|
|
4900
4932
|
}
|
|
4933
|
+
const leaving = auth?.userId ?? persisted?.userId ?? null;
|
|
4934
|
+
if (leaving) {
|
|
4935
|
+
lastUserId = leaving;
|
|
4936
|
+
saveLastUser(LAST_USER_KEY, leaving);
|
|
4937
|
+
}
|
|
4901
4938
|
auth = null;
|
|
4902
4939
|
persisted = null;
|
|
4903
4940
|
clearPersisted(PERSIST_KEY);
|
|
4904
4941
|
dropLiveSession();
|
|
4905
4942
|
events.emit("disconnected");
|
|
4906
4943
|
},
|
|
4944
|
+
forgetLastUser() {
|
|
4945
|
+
lastUserId = null;
|
|
4946
|
+
clearLastUser(LAST_USER_KEY);
|
|
4947
|
+
},
|
|
4907
4948
|
getAddresses() {
|
|
4908
4949
|
return auth?.addresses ?? persisted?.addresses ?? null;
|
|
4909
4950
|
},
|
|
@@ -7611,6 +7652,14 @@ function DecaneKit({ config, children }) {
|
|
|
7611
7652
|
if (!sdk) return false;
|
|
7612
7653
|
return sdk.canUnlockWithPassword();
|
|
7613
7654
|
}, []);
|
|
7655
|
+
const socialForgetLastUser = (0, import_react5.useCallback)(() => {
|
|
7656
|
+
socialRef.current?.forgetLastUser();
|
|
7657
|
+
const sdk = socialRef.current;
|
|
7658
|
+
if (sdk) {
|
|
7659
|
+
sdk.canSignInWithPasskey().then((can) => setSocialAuth((p) => ({ ...p, canUsePasskey: can }))).catch(() => {
|
|
7660
|
+
});
|
|
7661
|
+
}
|
|
7662
|
+
}, []);
|
|
7614
7663
|
const socialUnlockWithPassword = (0, import_react5.useCallback)(async (password) => {
|
|
7615
7664
|
const sdk = socialRef.current;
|
|
7616
7665
|
if (!sdk) throw new Error("Social wallet not connected");
|
|
@@ -7687,6 +7736,7 @@ function DecaneKit({ config, children }) {
|
|
|
7687
7736
|
socialAddPasskey,
|
|
7688
7737
|
socialSetUnlockPassword,
|
|
7689
7738
|
socialCanUnlockWithPassword,
|
|
7739
|
+
socialForgetLastUser,
|
|
7690
7740
|
socialUnlockWithPassword,
|
|
7691
7741
|
socialRemoveUnlockPassword,
|
|
7692
7742
|
socialShouldPromptRecovery,
|
|
@@ -7996,6 +8046,7 @@ function useSocialWallet() {
|
|
|
7996
8046
|
socialAddPasskey,
|
|
7997
8047
|
socialSetUnlockPassword,
|
|
7998
8048
|
socialCanUnlockWithPassword,
|
|
8049
|
+
socialForgetLastUser,
|
|
7999
8050
|
socialUnlockWithPassword,
|
|
8000
8051
|
socialRemoveUnlockPassword,
|
|
8001
8052
|
socialShouldPromptRecovery,
|
|
@@ -8104,6 +8155,7 @@ function useSocialWallet() {
|
|
|
8104
8155
|
throw e;
|
|
8105
8156
|
}
|
|
8106
8157
|
}, [socialSetUnlockPassword]);
|
|
8158
|
+
const forgetLastUser = (0, import_react6.useCallback)(() => socialForgetLastUser(), [socialForgetLastUser]);
|
|
8107
8159
|
const canUnlockWithPassword = (0, import_react6.useCallback)(
|
|
8108
8160
|
() => socialCanUnlockWithPassword(),
|
|
8109
8161
|
[socialCanUnlockWithPassword]
|
|
@@ -8189,6 +8241,8 @@ function useSocialWallet() {
|
|
|
8189
8241
|
canUnlockWithPassword,
|
|
8190
8242
|
unlockWithPassword,
|
|
8191
8243
|
removeUnlockPassword,
|
|
8244
|
+
// "Use a different account": stop offering the account that signed out.
|
|
8245
|
+
forgetLastUser,
|
|
8192
8246
|
// Recovery (2-of-3 Shamir share set)
|
|
8193
8247
|
rotateShares,
|
|
8194
8248
|
exportPortableBackup,
|