decane-connect-kit 2.2.7 → 2.2.8
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 +111 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +111 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2293,6 +2293,22 @@ var TeeClient = class {
|
|
|
2293
2293
|
sessionExpiresIn() {
|
|
2294
2294
|
return this.sessionExpiresInSec;
|
|
2295
2295
|
}
|
|
2296
|
+
/** The opaque session handle, so a live session can be persisted and resumed after a reload. */
|
|
2297
|
+
getHandle() {
|
|
2298
|
+
return this.handle;
|
|
2299
|
+
}
|
|
2300
|
+
/**
|
|
2301
|
+
* Adopt a handle from a persisted session (page reload) instead of opening a
|
|
2302
|
+
* new one. The session was already attested when first opened, and the handle
|
|
2303
|
+
* is bound to that CVM session — a swapped CVM would simply not recognise it —
|
|
2304
|
+
* so re-attestation is skipped. If the handle has expired server-side, the
|
|
2305
|
+
* first sign() 401s and clears it, falling back to a normal reconnect.
|
|
2306
|
+
*/
|
|
2307
|
+
adoptHandle(handle, assertionPerSignature) {
|
|
2308
|
+
this.handle = handle;
|
|
2309
|
+
this.assertionPerSignature = assertionPerSignature;
|
|
2310
|
+
this.attested = true;
|
|
2311
|
+
}
|
|
2296
2312
|
async ensureAttested() {
|
|
2297
2313
|
if (this.attested) return;
|
|
2298
2314
|
const nonce = crypto.getRandomValues(new Uint8Array(16));
|
|
@@ -2473,9 +2489,33 @@ var SessionManager = class {
|
|
|
2473
2489
|
this.solanaAddress = null;
|
|
2474
2490
|
this.expiresAt = null;
|
|
2475
2491
|
this.timeoutId = null;
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2492
|
+
}
|
|
2493
|
+
setExpiryTimer(effectiveMs) {
|
|
2494
|
+
if (this.timeoutId) clearTimeout(this.timeoutId);
|
|
2495
|
+
this.timeoutId = setTimeout(() => {
|
|
2496
|
+
this.end();
|
|
2497
|
+
this.events.emit("session-expired");
|
|
2498
|
+
}, Math.max(0, effectiveMs));
|
|
2499
|
+
}
|
|
2500
|
+
/** The live session handle, for persisting a resumable session across reloads. */
|
|
2501
|
+
getHandle() {
|
|
2502
|
+
return this.tee?.getHandle() ?? null;
|
|
2503
|
+
}
|
|
2504
|
+
/**
|
|
2505
|
+
* Resume a persisted session without re-authenticating: adopt the handle,
|
|
2506
|
+
* addresses, and expiry from storage. No key material or prompt involved — the
|
|
2507
|
+
* TEE still holds the shares behind this handle. If the handle turns out to be
|
|
2508
|
+
* dead (server restarted, TTL passed), the next sign() fails and the caller
|
|
2509
|
+
* reconnects; nothing here can sign on its own.
|
|
2510
|
+
*/
|
|
2511
|
+
resume(handle, addresses, expiresAtMs) {
|
|
2512
|
+
this.tee = new TeeClient(this.teeUrl);
|
|
2513
|
+
this.tee.adoptHandle(handle, this.requireAssertionPerSignature);
|
|
2514
|
+
this.evmAddress = addresses.evm;
|
|
2515
|
+
this.solanaAddress = addresses.solana;
|
|
2516
|
+
this.expiresAt = expiresAtMs;
|
|
2517
|
+
this.setExpiryTimer(expiresAtMs - Date.now());
|
|
2518
|
+
this.events.emit("session-started");
|
|
2479
2519
|
}
|
|
2480
2520
|
/**
|
|
2481
2521
|
* Opens the TEE session and resolves which addresses this wallet really has.
|
|
@@ -3060,6 +3100,29 @@ function clearPersisted(key) {
|
|
|
3060
3100
|
} catch {
|
|
3061
3101
|
}
|
|
3062
3102
|
}
|
|
3103
|
+
function sessionPersistKey(apiKey) {
|
|
3104
|
+
return `decane:sess:${apiKey.slice(0, 20)}`;
|
|
3105
|
+
}
|
|
3106
|
+
function loadSession(key) {
|
|
3107
|
+
try {
|
|
3108
|
+
const raw = typeof sessionStorage !== "undefined" ? sessionStorage.getItem(key) : null;
|
|
3109
|
+
return raw ? JSON.parse(raw) : null;
|
|
3110
|
+
} catch {
|
|
3111
|
+
return null;
|
|
3112
|
+
}
|
|
3113
|
+
}
|
|
3114
|
+
function saveSession(key, s) {
|
|
3115
|
+
try {
|
|
3116
|
+
sessionStorage.setItem(key, JSON.stringify(s));
|
|
3117
|
+
} catch {
|
|
3118
|
+
}
|
|
3119
|
+
}
|
|
3120
|
+
function clearSessionPersist(key) {
|
|
3121
|
+
try {
|
|
3122
|
+
sessionStorage.removeItem(key);
|
|
3123
|
+
} catch {
|
|
3124
|
+
}
|
|
3125
|
+
}
|
|
3063
3126
|
async function createDecaneConnect(config) {
|
|
3064
3127
|
if (!config.appId) throw new Error("decane-connect-kit: appId is required");
|
|
3065
3128
|
if (!config.apiKey) throw new Error("decane-connect-kit: apiKey is required");
|
|
@@ -3082,6 +3145,39 @@ async function createDecaneConnect(config) {
|
|
|
3082
3145
|
);
|
|
3083
3146
|
let auth = null;
|
|
3084
3147
|
let persisted = loadPersisted(PERSIST_KEY);
|
|
3148
|
+
const persistSession = config.persistSession !== false;
|
|
3149
|
+
const SESSION_KEY = sessionPersistKey(config.apiKey);
|
|
3150
|
+
function persistLiveSession() {
|
|
3151
|
+
if (!persistSession) return;
|
|
3152
|
+
const handle = session.getHandle();
|
|
3153
|
+
const expiresAt = session.expiresAtTimestamp();
|
|
3154
|
+
if (!handle || !auth || !expiresAt) return;
|
|
3155
|
+
saveSession(SESSION_KEY, {
|
|
3156
|
+
handle,
|
|
3157
|
+
jwt: auth.jwt,
|
|
3158
|
+
userId: auth.userId,
|
|
3159
|
+
addresses: auth.addresses,
|
|
3160
|
+
expiresAt
|
|
3161
|
+
});
|
|
3162
|
+
}
|
|
3163
|
+
function dropLiveSession() {
|
|
3164
|
+
clearSessionPersist(SESSION_KEY);
|
|
3165
|
+
}
|
|
3166
|
+
if (persistSession) {
|
|
3167
|
+
const saved = loadSession(SESSION_KEY);
|
|
3168
|
+
if (saved?.handle && saved.expiresAt > Date.now() + 5e3) {
|
|
3169
|
+
try {
|
|
3170
|
+
session.resume(saved.handle, saved.addresses, saved.expiresAt);
|
|
3171
|
+
auth = { jwt: saved.jwt, userId: saved.userId, addresses: saved.addresses };
|
|
3172
|
+
persisted = { userId: saved.userId, addresses: saved.addresses };
|
|
3173
|
+
} catch {
|
|
3174
|
+
dropLiveSession();
|
|
3175
|
+
}
|
|
3176
|
+
} else if (saved) {
|
|
3177
|
+
dropLiveSession();
|
|
3178
|
+
}
|
|
3179
|
+
}
|
|
3180
|
+
events.on("session-expired", () => dropLiveSession());
|
|
3085
3181
|
async function pinSetup() {
|
|
3086
3182
|
if (!config.promptPin) throw new PromptPinNotConfiguredError();
|
|
3087
3183
|
const pin = await config.promptPin();
|
|
@@ -3365,6 +3461,7 @@ async function createDecaneConnect(config) {
|
|
|
3365
3461
|
persisted = { userId, addresses };
|
|
3366
3462
|
savePersisted(PERSIST_KEY, persisted);
|
|
3367
3463
|
events.emit("connected");
|
|
3464
|
+
persistLiveSession();
|
|
3368
3465
|
return { addresses, isNewUser: false };
|
|
3369
3466
|
}
|
|
3370
3467
|
async function handleAuthResult(result) {
|
|
@@ -3380,6 +3477,7 @@ async function createDecaneConnect(config) {
|
|
|
3380
3477
|
persisted = { userId: result.userId, addresses };
|
|
3381
3478
|
savePersisted(PERSIST_KEY, persisted);
|
|
3382
3479
|
events.emit("connected");
|
|
3480
|
+
persistLiveSession();
|
|
3383
3481
|
return { addresses, isNewUser: result.isNewUser };
|
|
3384
3482
|
}
|
|
3385
3483
|
const client = {
|
|
@@ -3574,6 +3672,7 @@ async function createDecaneConnect(config) {
|
|
|
3574
3672
|
auth = null;
|
|
3575
3673
|
persisted = null;
|
|
3576
3674
|
clearPersisted(PERSIST_KEY);
|
|
3675
|
+
dropLiveSession();
|
|
3577
3676
|
events.emit("disconnected");
|
|
3578
3677
|
},
|
|
3579
3678
|
getAddresses() {
|
|
@@ -5610,7 +5709,15 @@ function DecaneKit({ config, children }) {
|
|
|
5610
5709
|
sdk.on("wallet-unlocking", () => setSocialAuth((p) => ({ ...p, phase: "unlocking" })));
|
|
5611
5710
|
sdk.on("connected", () => setSocialAuth((p) => ({ ...p, phase: null })));
|
|
5612
5711
|
const saved = sdk.getAddresses();
|
|
5613
|
-
if (
|
|
5712
|
+
if (sdk.isUnlocked()) {
|
|
5713
|
+
setSocialAuth((p) => ({
|
|
5714
|
+
...p,
|
|
5715
|
+
addresses: saved,
|
|
5716
|
+
isUnlocked: true,
|
|
5717
|
+
needsReconnect: false,
|
|
5718
|
+
sessionExpiresAt: sdk.sessionExpiresAt()
|
|
5719
|
+
}));
|
|
5720
|
+
} else if (saved) {
|
|
5614
5721
|
setSocialAuth((p) => ({ ...p, addresses: saved, isUnlocked: false, needsReconnect: true }));
|
|
5615
5722
|
}
|
|
5616
5723
|
sdk.canSignInWithPasskey().then((can) => setSocialAuth((p) => ({ ...p, canUsePasskey: can }))).catch(() => {
|