decane-connect-kit 2.2.0 → 2.2.2
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 +36 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +36 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1983,7 +1983,11 @@ var EventEmitter = class {
|
|
|
1983
1983
|
init_errors();
|
|
1984
1984
|
var ERROR_MAP = {
|
|
1985
1985
|
INVALID_API_KEY: InvalidApiKeyError,
|
|
1986
|
-
ORIGIN_NOT_ALLOWED: OriginNotAllowedError
|
|
1986
|
+
ORIGIN_NOT_ALLOWED: OriginNotAllowedError,
|
|
1987
|
+
// The backend's authMiddleware code for an expired/revoked JWT. Surfacing it
|
|
1988
|
+
// as ReconnectRequiredError routes callers to the sign-in UI instead of a
|
|
1989
|
+
// generic failure message.
|
|
1990
|
+
UNAUTHORIZED: ReconnectRequiredError
|
|
1987
1991
|
};
|
|
1988
1992
|
var ApiClient = class {
|
|
1989
1993
|
constructor(baseUrl, apiKey, appId) {
|
|
@@ -2269,11 +2273,22 @@ var TeeClient = class {
|
|
|
2269
2273
|
this.attested = false;
|
|
2270
2274
|
/** Mirrors what the signer confirmed for this session, not what we asked for. */
|
|
2271
2275
|
this.assertionPerSignature = false;
|
|
2276
|
+
/** The signer's authoritative remaining lifetime (seconds), null until a session opens. */
|
|
2277
|
+
this.sessionExpiresInSec = null;
|
|
2272
2278
|
}
|
|
2273
2279
|
/** Whether this session actually got per-signature assertions. */
|
|
2274
2280
|
requiresAssertionPerSignature() {
|
|
2275
2281
|
return this.assertionPerSignature;
|
|
2276
2282
|
}
|
|
2283
|
+
/**
|
|
2284
|
+
* The lifetime the signer granted this session, in seconds — which can be
|
|
2285
|
+
* shorter than the client's configured duration when the JWT expires first.
|
|
2286
|
+
* Null if the signer didn't report one (older build). Callers clamp their own
|
|
2287
|
+
* countdown to this so it never promises time the handle doesn't have.
|
|
2288
|
+
*/
|
|
2289
|
+
sessionExpiresIn() {
|
|
2290
|
+
return this.sessionExpiresInSec;
|
|
2291
|
+
}
|
|
2277
2292
|
async ensureAttested() {
|
|
2278
2293
|
if (this.attested) return;
|
|
2279
2294
|
const nonce = crypto.getRandomValues(new Uint8Array(16));
|
|
@@ -2302,6 +2317,7 @@ var TeeClient = class {
|
|
|
2302
2317
|
const body = await res.json();
|
|
2303
2318
|
this.handle = body.handle;
|
|
2304
2319
|
this.assertionPerSignature = body.requireAssertionPerSignature === true;
|
|
2320
|
+
this.sessionExpiresInSec = typeof body.expiresIn === "number" ? body.expiresIn : null;
|
|
2305
2321
|
return body.addresses ?? null;
|
|
2306
2322
|
}
|
|
2307
2323
|
/**
|
|
@@ -2344,6 +2360,7 @@ var TeeClient = class {
|
|
|
2344
2360
|
headers: { Authorization: `Bearer ${jwt}`, "Content-Type": "application/json" },
|
|
2345
2361
|
body: JSON.stringify({ rpId: window.location.hostname })
|
|
2346
2362
|
});
|
|
2363
|
+
if (res.status === 401) throw new ReconnectRequiredError();
|
|
2347
2364
|
if (!res.ok) throw new ExportNotAuthorizedError();
|
|
2348
2365
|
const { challengeId, options } = await res.json();
|
|
2349
2366
|
let assertion;
|
|
@@ -2395,8 +2412,9 @@ var TeeClient = class {
|
|
|
2395
2412
|
/**
|
|
2396
2413
|
* `jwt` is only needed when this session requires per-signature assertions —
|
|
2397
2414
|
* it authenticates the challenge request. Passed per call rather than cached
|
|
2398
|
-
* on the instance deliberately:
|
|
2399
|
-
* TEE session TTL
|
|
2415
|
+
* on the instance deliberately: JWT lifetime is configured independently of
|
|
2416
|
+
* the TEE session TTL (they are aligned at 30min by default, but an operator
|
|
2417
|
+
* can shorten JWT_EXPIRY_SECONDS), so a stored copy could go stale mid-session.
|
|
2400
2418
|
*/
|
|
2401
2419
|
async sign(req, jwt) {
|
|
2402
2420
|
if (!this.handle) throw new Error("no session");
|
|
@@ -2486,12 +2504,14 @@ var SessionManager = class {
|
|
|
2486
2504
|
}
|
|
2487
2505
|
this.evmAddress = addresses.evm;
|
|
2488
2506
|
this.solanaAddress = addresses.solana;
|
|
2489
|
-
|
|
2507
|
+
const serverTtlMs = this.tee.sessionExpiresIn();
|
|
2508
|
+
const effectiveMs = serverTtlMs != null ? Math.min(this.durationMs, serverTtlMs * 1e3) : this.durationMs;
|
|
2509
|
+
this.expiresAt = Date.now() + effectiveMs;
|
|
2490
2510
|
if (this.timeoutId) clearTimeout(this.timeoutId);
|
|
2491
2511
|
this.timeoutId = setTimeout(() => {
|
|
2492
2512
|
this.end();
|
|
2493
2513
|
this.events.emit("session-expired");
|
|
2494
|
-
},
|
|
2514
|
+
}, effectiveMs);
|
|
2495
2515
|
this.events.emit("session-started");
|
|
2496
2516
|
return addresses;
|
|
2497
2517
|
}
|
|
@@ -5311,7 +5331,15 @@ function DecaneKit({ config, children }) {
|
|
|
5311
5331
|
(0, import_react4.useEffect)(() => {
|
|
5312
5332
|
if (!hasSocial(mode) || !config?.social || socialInitialized.current) return;
|
|
5313
5333
|
socialInitialized.current = true;
|
|
5314
|
-
const {
|
|
5334
|
+
const {
|
|
5335
|
+
apiKey,
|
|
5336
|
+
authMethods,
|
|
5337
|
+
promptPin,
|
|
5338
|
+
apiBaseUrl,
|
|
5339
|
+
chains,
|
|
5340
|
+
rpcUrls,
|
|
5341
|
+
requireAssertionPerSignature
|
|
5342
|
+
} = config.social;
|
|
5315
5343
|
createDecaneConnect({
|
|
5316
5344
|
appId: config.appId,
|
|
5317
5345
|
apiKey,
|
|
@@ -5319,7 +5347,8 @@ function DecaneKit({ config, children }) {
|
|
|
5319
5347
|
authMethods: authMethods ?? ["google", "email"],
|
|
5320
5348
|
chains: chains ?? ["evm:1", "solana:mainnet"],
|
|
5321
5349
|
rpcUrls,
|
|
5322
|
-
promptPin
|
|
5350
|
+
promptPin,
|
|
5351
|
+
requireAssertionPerSignature
|
|
5323
5352
|
}).then((sdk) => {
|
|
5324
5353
|
socialRef.current = sdk;
|
|
5325
5354
|
sdk.on(
|