@chipi-stack/chipi-react 14.13.0 → 14.14.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/hooks.d.mts +2 -1
- package/dist/hooks.d.ts +2 -1
- package/dist/hooks.js +97 -45
- package/dist/hooks.js.map +1 -1
- package/dist/hooks.mjs +97 -45
- package/dist/hooks.mjs.map +1 -1
- package/dist/{index-D9-uVlda.d.mts → index-B8OIdrOX.d.mts} +43 -11
- package/dist/{index-D9-uVlda.d.ts → index-B8OIdrOX.d.ts} +43 -11
- package/dist/index.d.mts +49 -4
- package/dist/index.d.ts +49 -4
- package/dist/index.js +132 -59
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +131 -60
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/hooks.mjs
CHANGED
|
@@ -23,6 +23,18 @@ function useChipiContext() {
|
|
|
23
23
|
}
|
|
24
24
|
return context;
|
|
25
25
|
}
|
|
26
|
+
|
|
27
|
+
// src/utils/with-error-code.ts
|
|
28
|
+
function withErrorCode(wrapped, original) {
|
|
29
|
+
const code = original.code;
|
|
30
|
+
if (typeof code === "string") {
|
|
31
|
+
Object.defineProperty(wrapped, "code", { value: code, enumerable: true });
|
|
32
|
+
}
|
|
33
|
+
Object.defineProperty(wrapped, "cause", { value: original, enumerable: false });
|
|
34
|
+
return wrapped;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// src/hooks/useCreateWallet.ts
|
|
26
38
|
function useCreateWallet() {
|
|
27
39
|
const { chipiSDK } = useChipiContext();
|
|
28
40
|
const mutation = useMutation({
|
|
@@ -53,7 +65,7 @@ function useCreateWallet() {
|
|
|
53
65
|
}
|
|
54
66
|
} catch (error) {
|
|
55
67
|
if (error instanceof Error) {
|
|
56
|
-
throw new Error(`Passkey creation failed: ${error.message}`);
|
|
68
|
+
throw withErrorCode(new Error(`Passkey creation failed: ${error.message}`), error);
|
|
57
69
|
}
|
|
58
70
|
throw new Error("Failed to create passkey for wallet");
|
|
59
71
|
}
|
|
@@ -133,6 +145,17 @@ function useGetWallet(input) {
|
|
|
133
145
|
fetchWallet
|
|
134
146
|
};
|
|
135
147
|
}
|
|
148
|
+
|
|
149
|
+
// src/utils/wallet-capabilities.ts
|
|
150
|
+
var SHHH_SESSION_SIGNER_KINDS = /* @__PURE__ */ new Set(["STARK", "ED25519"]);
|
|
151
|
+
function walletSupportsSessions(wallet) {
|
|
152
|
+
if (!wallet) return false;
|
|
153
|
+
if (wallet.walletType === "CHIPI") return true;
|
|
154
|
+
if (wallet.walletType === "SHHH") {
|
|
155
|
+
return !wallet.signerKind || SHHH_SESSION_SIGNER_KINDS.has(wallet.signerKind);
|
|
156
|
+
}
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
136
159
|
function useChipiWallet(config3) {
|
|
137
160
|
const { chipiSDK } = useChipiContext();
|
|
138
161
|
const queryClient = useQueryClient();
|
|
@@ -213,7 +236,7 @@ function useChipiWallet(config3) {
|
|
|
213
236
|
const data = walletQuery.data;
|
|
214
237
|
return {
|
|
215
238
|
...data,
|
|
216
|
-
supportsSessionKeys: data
|
|
239
|
+
supportsSessionKeys: walletSupportsSessions(data),
|
|
217
240
|
shortAddress: formatAddress(data.publicKey)
|
|
218
241
|
};
|
|
219
242
|
}, [walletQuery.data, walletQuery.isLoading]);
|
|
@@ -270,6 +293,7 @@ function useChipiSession(config3) {
|
|
|
270
293
|
const {
|
|
271
294
|
wallet,
|
|
272
295
|
encryptKey,
|
|
296
|
+
getEncryptKey,
|
|
273
297
|
getBearerToken,
|
|
274
298
|
storedSession,
|
|
275
299
|
onSessionCreated,
|
|
@@ -283,10 +307,13 @@ function useChipiSession(config3) {
|
|
|
283
307
|
useEffect(() => {
|
|
284
308
|
setLocalSession(storedSession ?? null);
|
|
285
309
|
}, [storedSession]);
|
|
286
|
-
const supportsSession = useMemo(() =>
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
310
|
+
const supportsSession = useMemo(() => walletSupportsSessions(wallet), [wallet]);
|
|
311
|
+
const resolveEncryptKey = useCallback(async () => {
|
|
312
|
+
const key = encryptKey || (getEncryptKey ? await getEncryptKey() : void 0);
|
|
313
|
+
if (!key) throw new Error("Encryption key (PIN) is required");
|
|
314
|
+
return key;
|
|
315
|
+
}, [encryptKey, getEncryptKey]);
|
|
316
|
+
const [awaitingRegistrationUntil, setAwaitingRegistrationUntil] = useState(null);
|
|
290
317
|
const sessionStatusQuery = useQuery({
|
|
291
318
|
queryKey: ["chipi-session-status", wallet?.publicKey, localSession?.publicKey],
|
|
292
319
|
queryFn: async () => {
|
|
@@ -299,34 +326,41 @@ function useChipiSession(config3) {
|
|
|
299
326
|
enabled: Boolean(
|
|
300
327
|
autoCheckStatus && wallet?.publicKey && localSession?.publicKey && supportsSession
|
|
301
328
|
),
|
|
302
|
-
staleTime: 3e4
|
|
329
|
+
staleTime: 3e4,
|
|
303
330
|
// 30 seconds
|
|
331
|
+
// The registration hash comes back before the transaction is in a block, so
|
|
332
|
+
// right after registerSession the struct can still read as zero. Poll until
|
|
333
|
+
// it shows up (or for two minutes), then go back to on-demand reads.
|
|
334
|
+
refetchInterval: (query) => awaitingRegistrationUntil !== null && Date.now() < awaitingRegistrationUntil && (query.state.data?.validUntil ?? 0) === 0 ? 3e3 : false
|
|
304
335
|
});
|
|
336
|
+
const [revokedSessionKey, setRevokedSessionKey] = useState(null);
|
|
305
337
|
const sessionState = useMemo(() => {
|
|
306
338
|
if (!localSession) return "none";
|
|
339
|
+
if (revokedSessionKey === localSession.publicKey) return "revoked";
|
|
340
|
+
if (localSession.validUntil * 1e3 < Date.now()) return "expired";
|
|
307
341
|
const status = sessionStatusQuery.data;
|
|
308
342
|
if (status) {
|
|
309
|
-
if (
|
|
343
|
+
if (status.validUntil === 0) return "created";
|
|
310
344
|
if (status.validUntil * 1e3 < Date.now()) return "expired";
|
|
311
345
|
if (status.remainingCalls <= 0) return "expired";
|
|
346
|
+
if (!status.isActive) return "revoked";
|
|
312
347
|
return "active";
|
|
313
348
|
}
|
|
314
|
-
if (localSession.validUntil * 1e3 < Date.now()) return "expired";
|
|
315
349
|
return "created";
|
|
316
|
-
}, [localSession, sessionStatusQuery.data]);
|
|
350
|
+
}, [localSession, revokedSessionKey, sessionStatusQuery.data]);
|
|
317
351
|
const hasActiveSession = sessionState === "active";
|
|
318
352
|
const isSessionExpired = sessionState === "expired";
|
|
319
353
|
const remainingCalls = sessionStatusQuery.data?.remainingCalls;
|
|
320
354
|
const createSessionMutation = useMutation(
|
|
321
355
|
{
|
|
322
356
|
mutationFn: async (params = {}) => {
|
|
323
|
-
if (!encryptKey) throw new Error("Encryption key (PIN) is required");
|
|
324
357
|
if (!supportsSession)
|
|
325
358
|
throw new Error(
|
|
326
|
-
"Wallet does not support sessions.
|
|
359
|
+
"Wallet does not support sessions. Session keys need a CHIPI wallet or a SHHH wallet with a STARK / ED25519 signer."
|
|
327
360
|
);
|
|
361
|
+
const key = await resolveEncryptKey();
|
|
328
362
|
const sessionData = chipiSDK.sessions.createSessionKey({
|
|
329
|
-
encryptKey,
|
|
363
|
+
encryptKey: key,
|
|
330
364
|
durationSeconds: params.durationSeconds ?? defaultDurationSeconds
|
|
331
365
|
});
|
|
332
366
|
return sessionData;
|
|
@@ -346,28 +380,38 @@ function useChipiSession(config3) {
|
|
|
346
380
|
const registerSessionMutation = useMutation({
|
|
347
381
|
mutationFn: async (sessionConfig = {}) => {
|
|
348
382
|
if (!wallet) throw new Error("Wallet is required");
|
|
349
|
-
|
|
350
|
-
|
|
383
|
+
const sessionPublicKey = sessionConfig.sessionPublicKey ?? localSession?.publicKey;
|
|
384
|
+
const validUntil = sessionConfig.validUntil ?? localSession?.validUntil;
|
|
385
|
+
if (!sessionPublicKey || validUntil === void 0)
|
|
386
|
+
throw new Error(
|
|
387
|
+
"No session to register. Call createSession first, or pass sessionPublicKey and validUntil."
|
|
388
|
+
);
|
|
351
389
|
if (!supportsSession) throw new Error("Wallet does not support sessions");
|
|
390
|
+
const key = await resolveEncryptKey();
|
|
352
391
|
const bearerToken = await getBearerToken();
|
|
353
392
|
if (!bearerToken) throw new Error("Bearer token is required");
|
|
354
|
-
const
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
393
|
+
const params = {
|
|
394
|
+
encryptKey: key,
|
|
395
|
+
wallet,
|
|
396
|
+
sessionConfig: {
|
|
397
|
+
sessionPublicKey,
|
|
398
|
+
validUntil,
|
|
399
|
+
maxCalls: sessionConfig.maxCalls ?? defaultMaxCalls,
|
|
400
|
+
allowedEntrypoints: sessionConfig.allowedEntrypoints ?? []
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
if (sessionConfig.spendingPolicies?.length) {
|
|
404
|
+
return chipiSDK.sessions.setupSession(
|
|
405
|
+
{ ...params, spendingPolicies: sessionConfig.spendingPolicies },
|
|
406
|
+
bearerToken
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
return chipiSDK.sessions.addSessionKeyToContract(params, bearerToken);
|
|
368
410
|
},
|
|
369
411
|
onSuccess: () => {
|
|
370
412
|
setError(null);
|
|
413
|
+
if (localSession && revokedSessionKey === localSession.publicKey) setRevokedSessionKey(null);
|
|
414
|
+
setAwaitingRegistrationUntil(Date.now() + 12e4);
|
|
371
415
|
queryClient.invalidateQueries({
|
|
372
416
|
queryKey: ["chipi-session-status", wallet?.publicKey, localSession?.publicKey]
|
|
373
417
|
});
|
|
@@ -377,25 +421,28 @@ function useChipiSession(config3) {
|
|
|
377
421
|
}
|
|
378
422
|
});
|
|
379
423
|
const revokeSessionMutation = useMutation({
|
|
380
|
-
mutationFn: async () => {
|
|
424
|
+
mutationFn: async (sessionPublicKey) => {
|
|
381
425
|
if (!wallet) throw new Error("Wallet is required");
|
|
382
|
-
|
|
383
|
-
if (!
|
|
426
|
+
const target = sessionPublicKey ?? localSession?.publicKey;
|
|
427
|
+
if (!target) throw new Error("No session to revoke");
|
|
384
428
|
if (!supportsSession) throw new Error("Wallet does not support sessions");
|
|
429
|
+
const key = await resolveEncryptKey();
|
|
385
430
|
const bearerToken = await getBearerToken();
|
|
386
431
|
if (!bearerToken) throw new Error("Bearer token is required");
|
|
387
432
|
const txHash = await chipiSDK.sessions.revokeSessionKey(
|
|
388
433
|
{
|
|
389
|
-
encryptKey,
|
|
434
|
+
encryptKey: key,
|
|
390
435
|
wallet,
|
|
391
|
-
sessionPublicKey:
|
|
436
|
+
sessionPublicKey: target
|
|
392
437
|
},
|
|
393
438
|
bearerToken
|
|
394
439
|
);
|
|
395
440
|
return txHash;
|
|
396
441
|
},
|
|
397
|
-
onSuccess: () => {
|
|
442
|
+
onSuccess: (_txHash, sessionPublicKey) => {
|
|
398
443
|
setError(null);
|
|
444
|
+
const target = sessionPublicKey ?? localSession?.publicKey;
|
|
445
|
+
if (target) setRevokedSessionKey(target);
|
|
399
446
|
queryClient.invalidateQueries({
|
|
400
447
|
queryKey: ["chipi-session-status", wallet?.publicKey, localSession?.publicKey]
|
|
401
448
|
});
|
|
@@ -408,13 +455,13 @@ function useChipiSession(config3) {
|
|
|
408
455
|
mutationFn: async (calls) => {
|
|
409
456
|
if (!wallet) throw new Error("Wallet is required");
|
|
410
457
|
if (!localSession) throw new Error("No active session");
|
|
411
|
-
if (!encryptKey) throw new Error("Encryption key (PIN) is required");
|
|
412
458
|
if (!hasActiveSession) throw new Error("Session is not active. Register the session first.");
|
|
459
|
+
const key = await resolveEncryptKey();
|
|
413
460
|
const bearerToken = await getBearerToken();
|
|
414
461
|
if (!bearerToken) throw new Error("Bearer token is required");
|
|
415
462
|
const txHash = await chipiSDK.executeTransactionWithSession({
|
|
416
463
|
params: {
|
|
417
|
-
encryptKey,
|
|
464
|
+
encryptKey: key,
|
|
418
465
|
wallet,
|
|
419
466
|
session: localSession,
|
|
420
467
|
calls
|
|
@@ -438,13 +485,13 @@ function useChipiSession(config3) {
|
|
|
438
485
|
if (!wallet) throw new Error("Wallet is required");
|
|
439
486
|
if (!localSession)
|
|
440
487
|
throw new Error("No session to set policy on. Create and register a session first.");
|
|
441
|
-
if (!encryptKey) throw new Error("Encryption key (PIN) is required");
|
|
442
488
|
if (!supportsSession) throw new Error("Wallet does not support sessions");
|
|
489
|
+
const key = await resolveEncryptKey();
|
|
443
490
|
const bearerToken = await getBearerToken();
|
|
444
491
|
if (!bearerToken) throw new Error("Bearer token is required");
|
|
445
492
|
const txHash = await chipiSDK.sessions.setSpendingPolicy(
|
|
446
493
|
{
|
|
447
|
-
encryptKey,
|
|
494
|
+
encryptKey: key,
|
|
448
495
|
wallet,
|
|
449
496
|
spendingPolicyConfig: {
|
|
450
497
|
sessionPublicKey: localSession.publicKey,
|
|
@@ -466,13 +513,13 @@ function useChipiSession(config3) {
|
|
|
466
513
|
mutationFn: async (token) => {
|
|
467
514
|
if (!wallet) throw new Error("Wallet is required");
|
|
468
515
|
if (!localSession) throw new Error("No session to remove policy from");
|
|
469
|
-
if (!encryptKey) throw new Error("Encryption key (PIN) is required");
|
|
470
516
|
if (!supportsSession) throw new Error("Wallet does not support sessions");
|
|
517
|
+
const key = await resolveEncryptKey();
|
|
471
518
|
const bearerToken = await getBearerToken();
|
|
472
519
|
if (!bearerToken) throw new Error("Bearer token is required");
|
|
473
520
|
const txHash = await chipiSDK.sessions.removeSpendingPolicy(
|
|
474
521
|
{
|
|
475
|
-
encryptKey,
|
|
522
|
+
encryptKey: key,
|
|
476
523
|
wallet,
|
|
477
524
|
sessionPublicKey: localSession.publicKey,
|
|
478
525
|
token
|
|
@@ -500,9 +547,14 @@ function useChipiSession(config3) {
|
|
|
500
547
|
},
|
|
501
548
|
[registerSessionMutation]
|
|
502
549
|
);
|
|
503
|
-
const revokeSession = useCallback(
|
|
504
|
-
|
|
505
|
-
|
|
550
|
+
const revokeSession = useCallback(
|
|
551
|
+
async (sessionPublicKey) => {
|
|
552
|
+
return revokeSessionMutation.mutateAsync(
|
|
553
|
+
typeof sessionPublicKey === "string" ? sessionPublicKey : void 0
|
|
554
|
+
);
|
|
555
|
+
},
|
|
556
|
+
[revokeSessionMutation]
|
|
557
|
+
);
|
|
506
558
|
const executeWithSession = useCallback(
|
|
507
559
|
async (calls) => {
|
|
508
560
|
return executeWithSessionMutation.mutateAsync(calls);
|
|
@@ -636,7 +688,7 @@ function useMigrateWalletToPasskey() {
|
|
|
636
688
|
};
|
|
637
689
|
} catch (error) {
|
|
638
690
|
if (error instanceof Error) {
|
|
639
|
-
throw new Error(`Migration failed: ${error.message}`);
|
|
691
|
+
throw withErrorCode(new Error(`Migration failed: ${error.message}`), error);
|
|
640
692
|
}
|
|
641
693
|
throw new Error("Failed to migrate wallet to passkey");
|
|
642
694
|
}
|