@chipi-stack/chipi-react 14.13.1 → 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.mjs CHANGED
@@ -145,6 +145,17 @@ function useGetWallet(input) {
145
145
  fetchWallet
146
146
  };
147
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
+ }
148
159
  function useChipiWallet(config3) {
149
160
  const { chipiSDK } = useChipiContext();
150
161
  const queryClient = useQueryClient();
@@ -225,7 +236,7 @@ function useChipiWallet(config3) {
225
236
  const data = walletQuery.data;
226
237
  return {
227
238
  ...data,
228
- supportsSessionKeys: data.walletType === "CHIPI",
239
+ supportsSessionKeys: walletSupportsSessions(data),
229
240
  shortAddress: formatAddress(data.publicKey)
230
241
  };
231
242
  }, [walletQuery.data, walletQuery.isLoading]);
@@ -282,6 +293,7 @@ function useChipiSession(config3) {
282
293
  const {
283
294
  wallet,
284
295
  encryptKey,
296
+ getEncryptKey,
285
297
  getBearerToken,
286
298
  storedSession,
287
299
  onSessionCreated,
@@ -295,10 +307,13 @@ function useChipiSession(config3) {
295
307
  useEffect(() => {
296
308
  setLocalSession(storedSession ?? null);
297
309
  }, [storedSession]);
298
- const supportsSession = useMemo(() => {
299
- if (!wallet) return false;
300
- return wallet.walletType === "CHIPI";
301
- }, [wallet]);
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);
302
317
  const sessionStatusQuery = useQuery({
303
318
  queryKey: ["chipi-session-status", wallet?.publicKey, localSession?.publicKey],
304
319
  queryFn: async () => {
@@ -311,8 +326,12 @@ function useChipiSession(config3) {
311
326
  enabled: Boolean(
312
327
  autoCheckStatus && wallet?.publicKey && localSession?.publicKey && supportsSession
313
328
  ),
314
- staleTime: 3e4
329
+ staleTime: 3e4,
315
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
316
335
  });
317
336
  const [revokedSessionKey, setRevokedSessionKey] = useState(null);
318
337
  const sessionState = useMemo(() => {
@@ -335,13 +354,13 @@ function useChipiSession(config3) {
335
354
  const createSessionMutation = useMutation(
336
355
  {
337
356
  mutationFn: async (params = {}) => {
338
- if (!encryptKey) throw new Error("Encryption key (PIN) is required");
339
357
  if (!supportsSession)
340
358
  throw new Error(
341
- "Wallet does not support sessions. Only CHIPI wallets support session keys."
359
+ "Wallet does not support sessions. Session keys need a CHIPI wallet or a SHHH wallet with a STARK / ED25519 signer."
342
360
  );
361
+ const key = await resolveEncryptKey();
343
362
  const sessionData = chipiSDK.sessions.createSessionKey({
344
- encryptKey,
363
+ encryptKey: key,
345
364
  durationSeconds: params.durationSeconds ?? defaultDurationSeconds
346
365
  });
347
366
  return sessionData;
@@ -361,29 +380,38 @@ function useChipiSession(config3) {
361
380
  const registerSessionMutation = useMutation({
362
381
  mutationFn: async (sessionConfig = {}) => {
363
382
  if (!wallet) throw new Error("Wallet is required");
364
- if (!localSession) throw new Error("No session to register. Call createSession first.");
365
- if (!encryptKey) throw new Error("Encryption key (PIN) is required");
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
+ );
366
389
  if (!supportsSession) throw new Error("Wallet does not support sessions");
390
+ const key = await resolveEncryptKey();
367
391
  const bearerToken = await getBearerToken();
368
392
  if (!bearerToken) throw new Error("Bearer token is required");
369
- const txHash = await chipiSDK.sessions.addSessionKeyToContract(
370
- {
371
- encryptKey,
372
- wallet,
373
- sessionConfig: {
374
- sessionPublicKey: localSession.publicKey,
375
- validUntil: sessionConfig.validUntil ?? localSession.validUntil,
376
- maxCalls: sessionConfig.maxCalls ?? defaultMaxCalls,
377
- allowedEntrypoints: sessionConfig.allowedEntrypoints ?? []
378
- }
379
- },
380
- bearerToken
381
- );
382
- return txHash;
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);
383
410
  },
384
411
  onSuccess: () => {
385
412
  setError(null);
386
413
  if (localSession && revokedSessionKey === localSession.publicKey) setRevokedSessionKey(null);
414
+ setAwaitingRegistrationUntil(Date.now() + 12e4);
387
415
  queryClient.invalidateQueries({
388
416
  queryKey: ["chipi-session-status", wallet?.publicKey, localSession?.publicKey]
389
417
  });
@@ -393,26 +421,28 @@ function useChipiSession(config3) {
393
421
  }
394
422
  });
395
423
  const revokeSessionMutation = useMutation({
396
- mutationFn: async () => {
424
+ mutationFn: async (sessionPublicKey) => {
397
425
  if (!wallet) throw new Error("Wallet is required");
398
- if (!localSession) throw new Error("No session to revoke");
399
- if (!encryptKey) throw new Error("Encryption key (PIN) is required");
426
+ const target = sessionPublicKey ?? localSession?.publicKey;
427
+ if (!target) throw new Error("No session to revoke");
400
428
  if (!supportsSession) throw new Error("Wallet does not support sessions");
429
+ const key = await resolveEncryptKey();
401
430
  const bearerToken = await getBearerToken();
402
431
  if (!bearerToken) throw new Error("Bearer token is required");
403
432
  const txHash = await chipiSDK.sessions.revokeSessionKey(
404
433
  {
405
- encryptKey,
434
+ encryptKey: key,
406
435
  wallet,
407
- sessionPublicKey: localSession.publicKey
436
+ sessionPublicKey: target
408
437
  },
409
438
  bearerToken
410
439
  );
411
440
  return txHash;
412
441
  },
413
- onSuccess: () => {
442
+ onSuccess: (_txHash, sessionPublicKey) => {
414
443
  setError(null);
415
- if (localSession) setRevokedSessionKey(localSession.publicKey);
444
+ const target = sessionPublicKey ?? localSession?.publicKey;
445
+ if (target) setRevokedSessionKey(target);
416
446
  queryClient.invalidateQueries({
417
447
  queryKey: ["chipi-session-status", wallet?.publicKey, localSession?.publicKey]
418
448
  });
@@ -425,13 +455,13 @@ function useChipiSession(config3) {
425
455
  mutationFn: async (calls) => {
426
456
  if (!wallet) throw new Error("Wallet is required");
427
457
  if (!localSession) throw new Error("No active session");
428
- if (!encryptKey) throw new Error("Encryption key (PIN) is required");
429
458
  if (!hasActiveSession) throw new Error("Session is not active. Register the session first.");
459
+ const key = await resolveEncryptKey();
430
460
  const bearerToken = await getBearerToken();
431
461
  if (!bearerToken) throw new Error("Bearer token is required");
432
462
  const txHash = await chipiSDK.executeTransactionWithSession({
433
463
  params: {
434
- encryptKey,
464
+ encryptKey: key,
435
465
  wallet,
436
466
  session: localSession,
437
467
  calls
@@ -455,13 +485,13 @@ function useChipiSession(config3) {
455
485
  if (!wallet) throw new Error("Wallet is required");
456
486
  if (!localSession)
457
487
  throw new Error("No session to set policy on. Create and register a session first.");
458
- if (!encryptKey) throw new Error("Encryption key (PIN) is required");
459
488
  if (!supportsSession) throw new Error("Wallet does not support sessions");
489
+ const key = await resolveEncryptKey();
460
490
  const bearerToken = await getBearerToken();
461
491
  if (!bearerToken) throw new Error("Bearer token is required");
462
492
  const txHash = await chipiSDK.sessions.setSpendingPolicy(
463
493
  {
464
- encryptKey,
494
+ encryptKey: key,
465
495
  wallet,
466
496
  spendingPolicyConfig: {
467
497
  sessionPublicKey: localSession.publicKey,
@@ -483,13 +513,13 @@ function useChipiSession(config3) {
483
513
  mutationFn: async (token) => {
484
514
  if (!wallet) throw new Error("Wallet is required");
485
515
  if (!localSession) throw new Error("No session to remove policy from");
486
- if (!encryptKey) throw new Error("Encryption key (PIN) is required");
487
516
  if (!supportsSession) throw new Error("Wallet does not support sessions");
517
+ const key = await resolveEncryptKey();
488
518
  const bearerToken = await getBearerToken();
489
519
  if (!bearerToken) throw new Error("Bearer token is required");
490
520
  const txHash = await chipiSDK.sessions.removeSpendingPolicy(
491
521
  {
492
- encryptKey,
522
+ encryptKey: key,
493
523
  wallet,
494
524
  sessionPublicKey: localSession.publicKey,
495
525
  token
@@ -517,9 +547,14 @@ function useChipiSession(config3) {
517
547
  },
518
548
  [registerSessionMutation]
519
549
  );
520
- const revokeSession = useCallback(async () => {
521
- return revokeSessionMutation.mutateAsync();
522
- }, [revokeSessionMutation]);
550
+ const revokeSession = useCallback(
551
+ async (sessionPublicKey) => {
552
+ return revokeSessionMutation.mutateAsync(
553
+ typeof sessionPublicKey === "string" ? sessionPublicKey : void 0
554
+ );
555
+ },
556
+ [revokeSessionMutation]
557
+ );
523
558
  const executeWithSession = useCallback(
524
559
  async (calls) => {
525
560
  return executeWithSessionMutation.mutateAsync(calls);