@chipi-stack/chipi-react 14.13.1 → 14.15.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 +76 -41
- package/dist/hooks.js.map +1 -1
- package/dist/hooks.mjs +76 -41
- 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 +111 -55
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +110 -56
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -217,6 +217,17 @@ function useGetWallet(input) {
|
|
|
217
217
|
fetchWallet
|
|
218
218
|
};
|
|
219
219
|
}
|
|
220
|
+
|
|
221
|
+
// src/utils/wallet-capabilities.ts
|
|
222
|
+
var SHHH_SESSION_SIGNER_KINDS = /* @__PURE__ */ new Set(["STARK", "ED25519"]);
|
|
223
|
+
function walletSupportsSessions(wallet) {
|
|
224
|
+
if (!wallet) return false;
|
|
225
|
+
if (wallet.walletType === "CHIPI") return true;
|
|
226
|
+
if (wallet.walletType === "SHHH") {
|
|
227
|
+
return !wallet.signerKind || SHHH_SESSION_SIGNER_KINDS.has(wallet.signerKind);
|
|
228
|
+
}
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
220
231
|
function useChipiWallet(config3) {
|
|
221
232
|
const { chipiSDK } = useChipiContext();
|
|
222
233
|
const queryClient = reactQuery.useQueryClient();
|
|
@@ -297,7 +308,7 @@ function useChipiWallet(config3) {
|
|
|
297
308
|
const data = walletQuery.data;
|
|
298
309
|
return {
|
|
299
310
|
...data,
|
|
300
|
-
supportsSessionKeys: data
|
|
311
|
+
supportsSessionKeys: walletSupportsSessions(data),
|
|
301
312
|
shortAddress: formatAddress(data.publicKey)
|
|
302
313
|
};
|
|
303
314
|
}, [walletQuery.data, walletQuery.isLoading]);
|
|
@@ -354,6 +365,7 @@ function useChipiSession(config3) {
|
|
|
354
365
|
const {
|
|
355
366
|
wallet,
|
|
356
367
|
encryptKey,
|
|
368
|
+
getEncryptKey,
|
|
357
369
|
getBearerToken,
|
|
358
370
|
storedSession,
|
|
359
371
|
onSessionCreated,
|
|
@@ -367,10 +379,13 @@ function useChipiSession(config3) {
|
|
|
367
379
|
React.useEffect(() => {
|
|
368
380
|
setLocalSession(storedSession ?? null);
|
|
369
381
|
}, [storedSession]);
|
|
370
|
-
const supportsSession = React.useMemo(() =>
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
382
|
+
const supportsSession = React.useMemo(() => walletSupportsSessions(wallet), [wallet]);
|
|
383
|
+
const resolveEncryptKey = React.useCallback(async () => {
|
|
384
|
+
const key = encryptKey || (getEncryptKey ? await getEncryptKey() : void 0);
|
|
385
|
+
if (!key) throw new Error("Encryption key (PIN) is required");
|
|
386
|
+
return key;
|
|
387
|
+
}, [encryptKey, getEncryptKey]);
|
|
388
|
+
const [awaitingRegistrationUntil, setAwaitingRegistrationUntil] = React.useState(null);
|
|
374
389
|
const sessionStatusQuery = reactQuery.useQuery({
|
|
375
390
|
queryKey: ["chipi-session-status", wallet?.publicKey, localSession?.publicKey],
|
|
376
391
|
queryFn: async () => {
|
|
@@ -383,8 +398,12 @@ function useChipiSession(config3) {
|
|
|
383
398
|
enabled: Boolean(
|
|
384
399
|
autoCheckStatus && wallet?.publicKey && localSession?.publicKey && supportsSession
|
|
385
400
|
),
|
|
386
|
-
staleTime: 3e4
|
|
401
|
+
staleTime: 3e4,
|
|
387
402
|
// 30 seconds
|
|
403
|
+
// The registration hash comes back before the transaction is in a block, so
|
|
404
|
+
// right after registerSession the struct can still read as zero. Poll until
|
|
405
|
+
// it shows up (or for two minutes), then go back to on-demand reads.
|
|
406
|
+
refetchInterval: (query) => awaitingRegistrationUntil !== null && Date.now() < awaitingRegistrationUntil && (query.state.data?.validUntil ?? 0) === 0 ? 3e3 : false
|
|
388
407
|
});
|
|
389
408
|
const [revokedSessionKey, setRevokedSessionKey] = React.useState(null);
|
|
390
409
|
const sessionState = React.useMemo(() => {
|
|
@@ -407,13 +426,13 @@ function useChipiSession(config3) {
|
|
|
407
426
|
const createSessionMutation = reactQuery.useMutation(
|
|
408
427
|
{
|
|
409
428
|
mutationFn: async (params = {}) => {
|
|
410
|
-
if (!encryptKey) throw new Error("Encryption key (PIN) is required");
|
|
411
429
|
if (!supportsSession)
|
|
412
430
|
throw new Error(
|
|
413
|
-
"Wallet does not support sessions.
|
|
431
|
+
"Wallet does not support sessions. Session keys need a CHIPI wallet or a SHHH wallet with a STARK / ED25519 signer."
|
|
414
432
|
);
|
|
433
|
+
const key = await resolveEncryptKey();
|
|
415
434
|
const sessionData = chipiSDK.sessions.createSessionKey({
|
|
416
|
-
encryptKey,
|
|
435
|
+
encryptKey: key,
|
|
417
436
|
durationSeconds: params.durationSeconds ?? defaultDurationSeconds
|
|
418
437
|
});
|
|
419
438
|
return sessionData;
|
|
@@ -433,29 +452,38 @@ function useChipiSession(config3) {
|
|
|
433
452
|
const registerSessionMutation = reactQuery.useMutation({
|
|
434
453
|
mutationFn: async (sessionConfig = {}) => {
|
|
435
454
|
if (!wallet) throw new Error("Wallet is required");
|
|
436
|
-
|
|
437
|
-
|
|
455
|
+
const sessionPublicKey = sessionConfig.sessionPublicKey ?? localSession?.publicKey;
|
|
456
|
+
const validUntil = sessionConfig.validUntil ?? localSession?.validUntil;
|
|
457
|
+
if (!sessionPublicKey || validUntil === void 0)
|
|
458
|
+
throw new Error(
|
|
459
|
+
"No session to register. Call createSession first, or pass sessionPublicKey and validUntil."
|
|
460
|
+
);
|
|
438
461
|
if (!supportsSession) throw new Error("Wallet does not support sessions");
|
|
462
|
+
const key = await resolveEncryptKey();
|
|
439
463
|
const bearerToken = await getBearerToken();
|
|
440
464
|
if (!bearerToken) throw new Error("Bearer token is required");
|
|
441
|
-
const
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
465
|
+
const params = {
|
|
466
|
+
encryptKey: key,
|
|
467
|
+
wallet,
|
|
468
|
+
sessionConfig: {
|
|
469
|
+
sessionPublicKey,
|
|
470
|
+
validUntil,
|
|
471
|
+
maxCalls: sessionConfig.maxCalls ?? defaultMaxCalls,
|
|
472
|
+
allowedEntrypoints: sessionConfig.allowedEntrypoints ?? []
|
|
473
|
+
}
|
|
474
|
+
};
|
|
475
|
+
if (sessionConfig.spendingPolicies?.length) {
|
|
476
|
+
return chipiSDK.sessions.setupSession(
|
|
477
|
+
{ ...params, spendingPolicies: sessionConfig.spendingPolicies },
|
|
478
|
+
bearerToken
|
|
479
|
+
);
|
|
480
|
+
}
|
|
481
|
+
return chipiSDK.sessions.addSessionKeyToContract(params, bearerToken);
|
|
455
482
|
},
|
|
456
483
|
onSuccess: () => {
|
|
457
484
|
setError(null);
|
|
458
485
|
if (localSession && revokedSessionKey === localSession.publicKey) setRevokedSessionKey(null);
|
|
486
|
+
setAwaitingRegistrationUntil(Date.now() + 12e4);
|
|
459
487
|
queryClient.invalidateQueries({
|
|
460
488
|
queryKey: ["chipi-session-status", wallet?.publicKey, localSession?.publicKey]
|
|
461
489
|
});
|
|
@@ -465,26 +493,28 @@ function useChipiSession(config3) {
|
|
|
465
493
|
}
|
|
466
494
|
});
|
|
467
495
|
const revokeSessionMutation = reactQuery.useMutation({
|
|
468
|
-
mutationFn: async () => {
|
|
496
|
+
mutationFn: async (sessionPublicKey) => {
|
|
469
497
|
if (!wallet) throw new Error("Wallet is required");
|
|
470
|
-
|
|
471
|
-
if (!
|
|
498
|
+
const target = sessionPublicKey ?? localSession?.publicKey;
|
|
499
|
+
if (!target) throw new Error("No session to revoke");
|
|
472
500
|
if (!supportsSession) throw new Error("Wallet does not support sessions");
|
|
501
|
+
const key = await resolveEncryptKey();
|
|
473
502
|
const bearerToken = await getBearerToken();
|
|
474
503
|
if (!bearerToken) throw new Error("Bearer token is required");
|
|
475
504
|
const txHash = await chipiSDK.sessions.revokeSessionKey(
|
|
476
505
|
{
|
|
477
|
-
encryptKey,
|
|
506
|
+
encryptKey: key,
|
|
478
507
|
wallet,
|
|
479
|
-
sessionPublicKey:
|
|
508
|
+
sessionPublicKey: target
|
|
480
509
|
},
|
|
481
510
|
bearerToken
|
|
482
511
|
);
|
|
483
512
|
return txHash;
|
|
484
513
|
},
|
|
485
|
-
onSuccess: () => {
|
|
514
|
+
onSuccess: (_txHash, sessionPublicKey) => {
|
|
486
515
|
setError(null);
|
|
487
|
-
|
|
516
|
+
const target = sessionPublicKey ?? localSession?.publicKey;
|
|
517
|
+
if (target) setRevokedSessionKey(target);
|
|
488
518
|
queryClient.invalidateQueries({
|
|
489
519
|
queryKey: ["chipi-session-status", wallet?.publicKey, localSession?.publicKey]
|
|
490
520
|
});
|
|
@@ -497,13 +527,13 @@ function useChipiSession(config3) {
|
|
|
497
527
|
mutationFn: async (calls) => {
|
|
498
528
|
if (!wallet) throw new Error("Wallet is required");
|
|
499
529
|
if (!localSession) throw new Error("No active session");
|
|
500
|
-
if (!encryptKey) throw new Error("Encryption key (PIN) is required");
|
|
501
530
|
if (!hasActiveSession) throw new Error("Session is not active. Register the session first.");
|
|
531
|
+
const key = await resolveEncryptKey();
|
|
502
532
|
const bearerToken = await getBearerToken();
|
|
503
533
|
if (!bearerToken) throw new Error("Bearer token is required");
|
|
504
534
|
const txHash = await chipiSDK.executeTransactionWithSession({
|
|
505
535
|
params: {
|
|
506
|
-
encryptKey,
|
|
536
|
+
encryptKey: key,
|
|
507
537
|
wallet,
|
|
508
538
|
session: localSession,
|
|
509
539
|
calls
|
|
@@ -527,13 +557,13 @@ function useChipiSession(config3) {
|
|
|
527
557
|
if (!wallet) throw new Error("Wallet is required");
|
|
528
558
|
if (!localSession)
|
|
529
559
|
throw new Error("No session to set policy on. Create and register a session first.");
|
|
530
|
-
if (!encryptKey) throw new Error("Encryption key (PIN) is required");
|
|
531
560
|
if (!supportsSession) throw new Error("Wallet does not support sessions");
|
|
561
|
+
const key = await resolveEncryptKey();
|
|
532
562
|
const bearerToken = await getBearerToken();
|
|
533
563
|
if (!bearerToken) throw new Error("Bearer token is required");
|
|
534
564
|
const txHash = await chipiSDK.sessions.setSpendingPolicy(
|
|
535
565
|
{
|
|
536
|
-
encryptKey,
|
|
566
|
+
encryptKey: key,
|
|
537
567
|
wallet,
|
|
538
568
|
spendingPolicyConfig: {
|
|
539
569
|
sessionPublicKey: localSession.publicKey,
|
|
@@ -555,13 +585,13 @@ function useChipiSession(config3) {
|
|
|
555
585
|
mutationFn: async (token) => {
|
|
556
586
|
if (!wallet) throw new Error("Wallet is required");
|
|
557
587
|
if (!localSession) throw new Error("No session to remove policy from");
|
|
558
|
-
if (!encryptKey) throw new Error("Encryption key (PIN) is required");
|
|
559
588
|
if (!supportsSession) throw new Error("Wallet does not support sessions");
|
|
589
|
+
const key = await resolveEncryptKey();
|
|
560
590
|
const bearerToken = await getBearerToken();
|
|
561
591
|
if (!bearerToken) throw new Error("Bearer token is required");
|
|
562
592
|
const txHash = await chipiSDK.sessions.removeSpendingPolicy(
|
|
563
593
|
{
|
|
564
|
-
encryptKey,
|
|
594
|
+
encryptKey: key,
|
|
565
595
|
wallet,
|
|
566
596
|
sessionPublicKey: localSession.publicKey,
|
|
567
597
|
token
|
|
@@ -589,9 +619,14 @@ function useChipiSession(config3) {
|
|
|
589
619
|
},
|
|
590
620
|
[registerSessionMutation]
|
|
591
621
|
);
|
|
592
|
-
const revokeSession = React.useCallback(
|
|
593
|
-
|
|
594
|
-
|
|
622
|
+
const revokeSession = React.useCallback(
|
|
623
|
+
async (sessionPublicKey) => {
|
|
624
|
+
return revokeSessionMutation.mutateAsync(
|
|
625
|
+
typeof sessionPublicKey === "string" ? sessionPublicKey : void 0
|
|
626
|
+
);
|
|
627
|
+
},
|
|
628
|
+
[revokeSessionMutation]
|
|
629
|
+
);
|
|
595
630
|
const executeWithSession = React.useCallback(
|
|
596
631
|
async (calls) => {
|
|
597
632
|
return executeWithSessionMutation.mutateAsync(calls);
|
|
@@ -21278,6 +21313,21 @@ function ChipiInjector({ children, ...config3 }) {
|
|
|
21278
21313
|
}, [walletAddr]);
|
|
21279
21314
|
return children ?? null;
|
|
21280
21315
|
}
|
|
21316
|
+
var DEFAULT_RECOVER_LABELS = {
|
|
21317
|
+
proposeAddDevice: "Propose new device",
|
|
21318
|
+
proposeRecovery: "Initiate recovery",
|
|
21319
|
+
executeAddDevice: "Execute add-owner",
|
|
21320
|
+
executeRecovery: "Finalize recovery",
|
|
21321
|
+
timelockAddDevice: "48-hour timelock before this device becomes active.",
|
|
21322
|
+
timelockRecovery: "7-day timelock before the recovered wallet becomes active.",
|
|
21323
|
+
submitting: "Submitting\u2026",
|
|
21324
|
+
secondsRemaining: (s) => `${s}s remaining`,
|
|
21325
|
+
cancel: "Cancel pending op",
|
|
21326
|
+
timelockElapsed: "Timelock elapsed.",
|
|
21327
|
+
cancelling: "Cancelling\u2026",
|
|
21328
|
+
doneAddDevice: "New device added.",
|
|
21329
|
+
doneRecovery: "Wallet recovered."
|
|
21330
|
+
};
|
|
21281
21331
|
function deriveStaticPhase(pendingOp, executed, isReady, nowSecs) {
|
|
21282
21332
|
if (executed) return "done";
|
|
21283
21333
|
if (!pendingOp) return "form-idle";
|
|
@@ -21359,10 +21409,17 @@ function Recover(props) {
|
|
|
21359
21409
|
setSubmittingAction(null);
|
|
21360
21410
|
}
|
|
21361
21411
|
}, [activePendingOp, onCancel]);
|
|
21412
|
+
const L = React.useMemo(
|
|
21413
|
+
() => ({
|
|
21414
|
+
...DEFAULT_RECOVER_LABELS,
|
|
21415
|
+
...Object.fromEntries(Object.entries(props.labels ?? {}).filter(([, v]) => v !== void 0))
|
|
21416
|
+
}),
|
|
21417
|
+
[props.labels]
|
|
21418
|
+
);
|
|
21362
21419
|
const isAddDevice = mode === "add-device";
|
|
21363
|
-
const proposeLabel = isAddDevice ?
|
|
21364
|
-
const executeLabel = isAddDevice ?
|
|
21365
|
-
const timelockDescription = isAddDevice ?
|
|
21420
|
+
const proposeLabel = isAddDevice ? L.proposeAddDevice : L.proposeRecovery;
|
|
21421
|
+
const executeLabel = isAddDevice ? L.executeAddDevice : L.executeRecovery;
|
|
21422
|
+
const timelockDescription = isAddDevice ? L.timelockAddDevice : L.timelockRecovery;
|
|
21366
21423
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
21367
21424
|
"div",
|
|
21368
21425
|
{
|
|
@@ -21390,18 +21447,15 @@ function Recover(props) {
|
|
|
21390
21447
|
}
|
|
21391
21448
|
)
|
|
21392
21449
|
] }),
|
|
21393
|
-
phase === "submitting-propose" && /* @__PURE__ */ jsxRuntime.jsx("section", { "data-chipi-recover-section": "propose", children: /* @__PURE__ */ jsxRuntime.jsx("p", { "data-chipi-recover-status": "submitting", children:
|
|
21450
|
+
phase === "submitting-propose" && /* @__PURE__ */ jsxRuntime.jsx("section", { "data-chipi-recover-section": "propose", children: /* @__PURE__ */ jsxRuntime.jsx("p", { "data-chipi-recover-status": "submitting", children: L.submitting }) }),
|
|
21394
21451
|
phase === "awaiting-timelock" && activePendingOp && /* @__PURE__ */ jsxRuntime.jsxs("section", { "data-chipi-recover-section": "awaiting", children: [
|
|
21395
21452
|
/* @__PURE__ */ jsxRuntime.jsx("p", { "data-chipi-recover-status": "awaiting", children: timelockDescription }),
|
|
21396
|
-
/* @__PURE__ */ jsxRuntime.
|
|
21453
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21397
21454
|
"p",
|
|
21398
21455
|
{
|
|
21399
21456
|
"data-chipi-recover-countdown": "",
|
|
21400
21457
|
"data-chipi-recover-seconds-remaining": String(secondsRemaining),
|
|
21401
|
-
children:
|
|
21402
|
-
secondsRemaining,
|
|
21403
|
-
"s remaining"
|
|
21404
|
-
]
|
|
21458
|
+
children: L.secondsRemaining(secondsRemaining)
|
|
21405
21459
|
}
|
|
21406
21460
|
),
|
|
21407
21461
|
/* @__PURE__ */ jsxRuntime.jsx("p", { "data-chipi-recover-op-id": "", children: String(activePendingOp.opId) }),
|
|
@@ -21412,12 +21466,12 @@ function Recover(props) {
|
|
|
21412
21466
|
"data-chipi-recover-action": "cancel",
|
|
21413
21467
|
onClick: handleCancel,
|
|
21414
21468
|
disabled: submittingAction !== null,
|
|
21415
|
-
children:
|
|
21469
|
+
children: L.cancel
|
|
21416
21470
|
}
|
|
21417
21471
|
)
|
|
21418
21472
|
] }),
|
|
21419
21473
|
(phase === "ready-to-execute" || phase === "submitting-execute") && activePendingOp && /* @__PURE__ */ jsxRuntime.jsxs("section", { "data-chipi-recover-section": "execute", children: [
|
|
21420
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { "data-chipi-recover-status": "ready", children:
|
|
21474
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { "data-chipi-recover-status": "ready", children: L.timelockElapsed }),
|
|
21421
21475
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21422
21476
|
"button",
|
|
21423
21477
|
{
|
|
@@ -21435,12 +21489,12 @@ function Recover(props) {
|
|
|
21435
21489
|
"data-chipi-recover-action": "cancel",
|
|
21436
21490
|
onClick: handleCancel,
|
|
21437
21491
|
disabled: submittingAction !== null,
|
|
21438
|
-
children:
|
|
21492
|
+
children: L.cancel
|
|
21439
21493
|
}
|
|
21440
21494
|
)
|
|
21441
21495
|
] }),
|
|
21442
|
-
phase === "submitting-cancel" && /* @__PURE__ */ jsxRuntime.jsx("section", { "data-chipi-recover-section": "cancel", children: /* @__PURE__ */ jsxRuntime.jsx("p", { "data-chipi-recover-status": "submitting", children:
|
|
21443
|
-
phase === "done" && /* @__PURE__ */ jsxRuntime.jsx("section", { "data-chipi-recover-section": "done", children: /* @__PURE__ */ jsxRuntime.jsx("p", { "data-chipi-recover-status": "done", children: isAddDevice ?
|
|
21496
|
+
phase === "submitting-cancel" && /* @__PURE__ */ jsxRuntime.jsx("section", { "data-chipi-recover-section": "cancel", children: /* @__PURE__ */ jsxRuntime.jsx("p", { "data-chipi-recover-status": "submitting", children: L.cancelling }) }),
|
|
21497
|
+
phase === "done" && /* @__PURE__ */ jsxRuntime.jsx("section", { "data-chipi-recover-section": "done", children: /* @__PURE__ */ jsxRuntime.jsx("p", { "data-chipi-recover-status": "done", children: isAddDevice ? L.doneAddDevice : L.doneRecovery }) }),
|
|
21444
21498
|
error && /* @__PURE__ */ jsxRuntime.jsx("p", { "data-chipi-recover-error": "", role: "alert", children: error.message })
|
|
21445
21499
|
]
|
|
21446
21500
|
}
|
|
@@ -21480,6 +21534,7 @@ Object.defineProperty(exports, "ChainToken", {
|
|
|
21480
21534
|
});
|
|
21481
21535
|
exports.ChipiInjector = ChipiInjector;
|
|
21482
21536
|
exports.ChipiProvider = ChipiProvider;
|
|
21537
|
+
exports.DEFAULT_RECOVER_LABELS = DEFAULT_RECOVER_LABELS;
|
|
21483
21538
|
exports.Recover = Recover;
|
|
21484
21539
|
exports.createChipiWindowObject = createChipiWindowObject;
|
|
21485
21540
|
exports.derivePrivacyAccount = derivePrivacyAccount;
|
|
@@ -21520,5 +21575,6 @@ exports.useTransfer = useTransfer;
|
|
|
21520
21575
|
exports.useUnshield = useUnshield;
|
|
21521
21576
|
exports.useUpdateWalletEncryption = useUpdateWalletEncryption;
|
|
21522
21577
|
exports.useX402Payment = useX402Payment;
|
|
21578
|
+
exports.walletSupportsSessions = walletSupportsSessions;
|
|
21523
21579
|
//# sourceMappingURL=index.js.map
|
|
21524
21580
|
//# sourceMappingURL=index.js.map
|