@coti-io/coti-wallet-plugin 0.1.0 → 0.2.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/index.mjs CHANGED
@@ -574,6 +574,7 @@ var init_plugin = __esm({
574
574
  defaultNetworkId: void 0,
575
575
  debug: false,
576
576
  clearSessionKeyOnWagmiDisconnect: false,
577
+ waitForBalanceRefreshAfterTransfer: false,
577
578
  onboardingServices: { mode: "disabled" },
578
579
  onboardingGrantMinBalanceWei: 0,
579
580
  onboardingGrantPollIntervalMs: 2e3,
@@ -7363,7 +7364,7 @@ var sleep2 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
7363
7364
  function useAesKeyProvider(walletTypeInfo) {
7364
7365
  const [isOnboarding, setIsOnboarding] = useState10(false);
7365
7366
  const [onboardingError, setOnboardingError] = useState10(null);
7366
- const [onboardingWarning, setOnboardingWarning] = useState10(null);
7367
+ const [onboardingWarnings, setOnboardingWarnings] = useState10({});
7367
7368
  const [wasRestoreCancelled, setWasRestoreCancelled] = useState10(false);
7368
7369
  const [currentStep, setCurrentStep] = useState10("idle");
7369
7370
  const progressCallbackRef = useRef7();
@@ -7384,7 +7385,7 @@ function useAesKeyProvider(walletTypeInfo) {
7384
7385
  progressCallbackRef.current = onProgress ?? options.onProgress;
7385
7386
  setOnboardingError(null);
7386
7387
  debugTraceRef.current.clear();
7387
- setOnboardingWarning(null);
7388
+ setOnboardingWarnings({});
7388
7389
  setWasRestoreCancelled(false);
7389
7390
  const forceContractOnboarding = options?.forceContractOnboarding === true;
7390
7391
  if (!forceContractOnboarding) {
@@ -7493,7 +7494,9 @@ function useAesKeyProvider(walletTypeInfo) {
7493
7494
  }
7494
7495
  } catch (restoreError) {
7495
7496
  if (isUserRejection(restoreError)) {
7496
- setOnboardingWarning("Backup restore was cancelled. Approve the wallet signature to unlock from your encrypted backup.");
7497
+ setOnboardingWarnings({
7498
+ intro: "Backup restore was cancelled. Approve the wallet signature to unlock from your encrypted backup."
7499
+ });
7497
7500
  setWasRestoreCancelled(true);
7498
7501
  options.onRestoreCancelled?.();
7499
7502
  emitStep("idle");
@@ -7502,7 +7505,9 @@ function useAesKeyProvider(walletTypeInfo) {
7502
7505
  const message = restoreError instanceof Error ? restoreError.message : "Encrypted AES backup could not be restored.";
7503
7506
  logger.warn("\u26A0\uFE0F AES backup restore failed, falling back to contract onboarding:", restoreError);
7504
7507
  restoreBackupFailed = true;
7505
- setOnboardingWarning(`Encrypted backup could not be restored. Continuing with onboarding. ${message}`);
7508
+ setOnboardingWarnings({
7509
+ intro: `Encrypted backup could not be restored. Continuing with onboarding. ${message}`
7510
+ });
7506
7511
  }
7507
7512
  }
7508
7513
  if (options.restoreOnly) {
@@ -7663,9 +7668,9 @@ function useAesKeyProvider(walletTypeInfo) {
7663
7668
  savedToSnap = await saveAESKeyToSnap(aesKey, address);
7664
7669
  if (!savedToSnap) {
7665
7670
  logger.warn("\u26A0\uFE0F AES key retrieved but could not persist to Snap");
7666
- setOnboardingWarning(
7667
- "Onboarding succeeded, but the AES key could not be saved to MetaMask Snap. You can retry by unlocking again."
7668
- );
7671
+ setOnboardingWarnings({
7672
+ success: "Onboarding succeeded, but the AES key could not be saved to MetaMask Snap. You can retry by unlocking again."
7673
+ });
7669
7674
  }
7670
7675
  } else if (aesKey && walletTypeInfo.walletType === "metamask" && canPersistAesKeyToSnap() && !walletTypeInfo.isMetaMaskWithSnap) {
7671
7676
  logger.log(
@@ -7687,14 +7692,14 @@ function useAesKeyProvider(walletTypeInfo) {
7687
7692
  "\u26A0\uFE0F AES key retrieved but encrypted backup save failed:",
7688
7693
  backupResult.message
7689
7694
  );
7690
- setOnboardingWarning(
7691
- `Onboarding succeeded, but encrypted backup was not saved. ${backupResult.message}`
7692
- );
7695
+ setOnboardingWarnings({
7696
+ success: `Onboarding succeeded, but encrypted backup was not saved. ${backupResult.message}`
7697
+ });
7693
7698
  } else if (backupResult.status === "cancelled") {
7694
7699
  logger.warn("\u26A0\uFE0F AES key retrieved but encrypted backup save was cancelled");
7695
- setOnboardingWarning(
7696
- "Onboarding succeeded, but encrypted backup save was cancelled. You can save it later by re-entering your AES key."
7697
- );
7700
+ setOnboardingWarnings({
7701
+ success: "Onboarding succeeded, but encrypted backup save was cancelled. You can save it later by re-entering your AES key."
7702
+ });
7698
7703
  }
7699
7704
  }
7700
7705
  if (aesKey && isValidAesKey(aesKey)) {
@@ -7758,7 +7763,7 @@ function useAesKeyProvider(walletTypeInfo) {
7758
7763
  getAesKey,
7759
7764
  isOnboarding,
7760
7765
  onboardingError,
7761
- onboardingWarning,
7766
+ onboardingWarnings,
7762
7767
  wasRestoreCancelled,
7763
7768
  currentStep
7764
7769
  };
@@ -7866,7 +7871,7 @@ var usePrivacyBridgeSessionCore = ({
7866
7871
  getAesKey: getAesKeyFromProvider,
7867
7872
  isOnboarding,
7868
7873
  onboardingError,
7869
- onboardingWarning
7874
+ onboardingWarnings
7870
7875
  } = useAesKeyProvider(walletTypeInfo);
7871
7876
  const { fetchPrivateBalance } = usePrivateTokenBalance();
7872
7877
  useEffect9(() => {
@@ -7922,7 +7927,7 @@ var usePrivacyBridgeSessionCore = ({
7922
7927
  fetchPrivateBalance,
7923
7928
  getAesKeyFromProvider,
7924
7929
  onboardingError,
7925
- onboardingWarning
7930
+ onboardingWarnings
7926
7931
  };
7927
7932
  };
7928
7933
 
@@ -8554,6 +8559,7 @@ var usePrivacyBridgeWalletConnection = ({
8554
8559
  };
8555
8560
 
8556
8561
  // src/context/privacyBridge/usePrivacyBridgeUnlockSession.ts
8562
+ init_plugin();
8557
8563
  init_logger();
8558
8564
  import { useCallback as useCallback17 } from "react";
8559
8565
  import { useAccount as useAccount9 } from "wagmi";
@@ -8825,6 +8831,13 @@ var usePrivacyBridgeUnlockSession = ({
8825
8831
  }, [resolveAesAccess, resolveSessionAesKey, walletAddress, aesKeyChainId, checkSnapStatus, hasAesKeyInSnap, walletTypeInfo.walletType, currentChainId]);
8826
8832
  const refreshPrivateBalances = useCallback17(async (aesKeyOptions) => {
8827
8833
  if (!walletAddress) return false;
8834
+ const lockSessionOnAesFailure = !aesKeyOptions?.preserveSessionOnError;
8835
+ const clearSessionAfterAesFailure = () => {
8836
+ setSessionAesKey(null);
8837
+ clearAesKeyValidatedForUnlock(walletAddress);
8838
+ clearSnapCache();
8839
+ setArePrivateBalancesHidden(true);
8840
+ };
8828
8841
  logger.log("Triggering private balance fetch...");
8829
8842
  try {
8830
8843
  const chainOverride = wagmiSyncRef.current ? wagmiChainId : void 0;
@@ -8903,10 +8916,7 @@ var usePrivacyBridgeUnlockSession = ({
8903
8916
  );
8904
8917
  }
8905
8918
  if (errorInfo.message?.includes("ACCOUNT_NOT_ONBOARDED")) {
8906
- setSessionAesKey(null);
8907
- clearAesKeyValidatedForUnlock(walletAddress);
8908
- clearSnapCache();
8909
- setArePrivateBalancesHidden(true);
8919
+ if (lockSessionOnAesFailure) clearSessionAfterAesFailure();
8910
8920
  throw new CotiPluginError(
8911
8921
  "ACCOUNT_NOT_ONBOARDED" /* ACCOUNT_NOT_ONBOARDED */,
8912
8922
  "Account has not been onboarded to the COTI network.",
@@ -8914,17 +8924,11 @@ var usePrivacyBridgeUnlockSession = ({
8914
8924
  );
8915
8925
  }
8916
8926
  if (err instanceof CotiPluginError && err.code === "AES_KEY_MISMATCH" /* AES_KEY_MISMATCH */) {
8917
- setSessionAesKey(null);
8918
- clearAesKeyValidatedForUnlock(walletAddress);
8919
- clearSnapCache();
8920
- setArePrivateBalancesHidden(true);
8927
+ if (lockSessionOnAesFailure) clearSessionAfterAesFailure();
8921
8928
  throw err;
8922
8929
  }
8923
8930
  if (errorInfo.message?.includes("AES key") || errorInfo.message?.includes("onboarding")) {
8924
- setSessionAesKey(null);
8925
- clearAesKeyValidatedForUnlock(walletAddress);
8926
- clearSnapCache();
8927
- setArePrivateBalancesHidden(true);
8931
+ if (lockSessionOnAesFailure) clearSessionAfterAesFailure();
8928
8932
  throw new CotiPluginError(
8929
8933
  "AES_KEY_MISMATCH" /* AES_KEY_MISMATCH */,
8930
8934
  "AES key mismatch or onboarding error.",
@@ -8969,7 +8973,13 @@ var usePrivacyBridgeUnlockSession = ({
8969
8973
  hasSnap: strategy.snapInstalled,
8970
8974
  getAESKeyFromSnap: strategy.snapInstalled ? getAESKeyFromSnap : void 0
8971
8975
  });
8972
- await refreshPrivateBalances();
8976
+ if (getPluginConfig().waitForBalanceRefreshAfterTransfer) {
8977
+ await refreshPrivateBalances();
8978
+ } else {
8979
+ void refreshPrivateBalances({ preserveSessionOnError: true }).catch(
8980
+ (err) => logger.error("Background balance refresh after transfer failed", err)
8981
+ );
8982
+ }
8973
8983
  return result;
8974
8984
  }, [
8975
8985
  walletAddress,
@@ -9119,7 +9129,7 @@ var usePrivacyBridgeSession = ({ modals }) => {
9119
9129
  refreshPublicBalances: unlock.refreshPublicBalances,
9120
9130
  refreshPrivateBalances: unlock.refreshPrivateBalances,
9121
9131
  onboardingError: core.onboardingError,
9122
- onboardingWarning: core.onboardingWarning,
9132
+ onboardingWarnings: core.onboardingWarnings,
9123
9133
  lockPrivateBalances: unlock.lockPrivateBalances,
9124
9134
  saveManualAesKey: unlock.saveManualAesKey,
9125
9135
  sendPrivateToken: unlock.sendPrivateToken,
@@ -9492,6 +9502,40 @@ function deriveOnboardScreen({
9492
9502
 
9493
9503
  // src/components/OnboardModal.tsx
9494
9504
  init_logger();
9505
+
9506
+ // src/lib/onboardModalWarnings.ts
9507
+ function mergeOnboardModalWarnings(...sources) {
9508
+ const merged = {};
9509
+ for (const source of sources) {
9510
+ if (!source) continue;
9511
+ for (const page of Object.keys(source)) {
9512
+ const message = source[page];
9513
+ if (message) {
9514
+ merged[page] = message;
9515
+ }
9516
+ }
9517
+ }
9518
+ return merged;
9519
+ }
9520
+ function getDefaultSuccessWarning(saveBackup) {
9521
+ return saveBackup ? "Important: An encrypted backup can help restore this key later, but you should still store it safely." : "Important: This key will be lost when you refresh the page. Store it in a secure location.";
9522
+ }
9523
+ function resolveOnboardPageWarning(page, options) {
9524
+ const runtime = options.runtimeWarnings?.[page]?.trim();
9525
+ if (runtime) return runtime;
9526
+ const app = options.warnings?.[page]?.trim();
9527
+ if (app) return app;
9528
+ if (page === "success") {
9529
+ return getDefaultSuccessWarning(options.saveBackup ?? true);
9530
+ }
9531
+ return null;
9532
+ }
9533
+ function hasOnboardModalWarnings(warnings) {
9534
+ if (!warnings) return false;
9535
+ return Object.values(warnings).some((message) => !!message?.trim());
9536
+ }
9537
+
9538
+ // src/components/OnboardModal.tsx
9495
9539
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9496
9540
  var defaultStyles = {
9497
9541
  backdrop: {
@@ -9663,28 +9707,23 @@ var defaultStyles = {
9663
9707
  },
9664
9708
  saveOptionBody: {
9665
9709
  flex: 1,
9666
- minWidth: 0
9710
+ minWidth: 0,
9711
+ display: "flex",
9712
+ alignItems: "center",
9713
+ minHeight: "32px"
9667
9714
  },
9668
9715
  saveOptionTitleRow: {
9669
9716
  display: "flex",
9670
9717
  alignItems: "center",
9671
- gap: "5px",
9672
- marginBottom: "2px"
9718
+ gap: "5px"
9673
9719
  },
9674
9720
  saveOptionTitle: {
9675
9721
  fontSize: "13px",
9676
9722
  fontWeight: 600,
9677
- lineHeight: 1.25,
9678
- color: "#ffffff"
9679
- },
9680
- saveOptionDescription: {
9681
- fontSize: "11px",
9682
- lineHeight: 1.3,
9683
- color: "rgba(255, 255, 255, 0.55)",
9684
- margin: 0,
9685
- whiteSpace: "nowrap",
9686
- overflow: "hidden",
9687
- textOverflow: "ellipsis"
9723
+ lineHeight: "14px",
9724
+ color: "#ffffff",
9725
+ display: "inline-flex",
9726
+ alignItems: "center"
9688
9727
  },
9689
9728
  saveOptionSwitchTrack: {
9690
9729
  position: "relative",
@@ -9726,12 +9765,13 @@ var defaultStyles = {
9726
9765
  tooltipButton: {
9727
9766
  width: "14px",
9728
9767
  height: "14px",
9768
+ boxSizing: "border-box",
9729
9769
  borderRadius: "50%",
9730
9770
  border: "1px solid rgba(255, 255, 255, 0.25)",
9731
9771
  backgroundColor: "rgba(255, 255, 255, 0.08)",
9732
9772
  color: "rgba(255, 255, 255, 0.8)",
9733
9773
  fontSize: "9px",
9734
- lineHeight: 1,
9774
+ lineHeight: "12px",
9735
9775
  padding: 0,
9736
9776
  cursor: "help",
9737
9777
  flexShrink: 0,
@@ -10035,8 +10075,7 @@ var MUTED_TEXT_KEYS = [
10035
10075
  "closeButton",
10036
10076
  "tooltipButton",
10037
10077
  "cancelButton",
10038
- "stepDescription",
10039
- "saveOptionDescription"
10078
+ "stepDescription"
10040
10079
  ];
10041
10080
  var ACCENT_TEXT_KEYS = [
10042
10081
  "keyInput",
@@ -10086,7 +10125,8 @@ var LIGHT_INTERACTIVE_SURFACE_KEYS = [
10086
10125
  "saveOptionCard",
10087
10126
  "saveOptionIconWrap",
10088
10127
  "saveOptionSwitchTrackOff",
10089
- "saveOptionSwitchTrackOn"
10128
+ "saveOptionSwitchTrackOn",
10129
+ "tooltipButton"
10090
10130
  ];
10091
10131
  function isDefaultDarkSurfaceBackground(backgroundColor) {
10092
10132
  if (!backgroundColor) return true;
@@ -10170,6 +10210,11 @@ function applyLightInteractiveSurfaceGaps(merged, theme) {
10170
10210
  saveOptionSwitchTrackOn: {
10171
10211
  backgroundColor: primary,
10172
10212
  borderColor: colorWithAlpha(primary, 0.45)
10213
+ },
10214
+ tooltipButton: {
10215
+ color: muted2,
10216
+ backgroundColor: colorWithAlpha(foreground, 0.08),
10217
+ border: `1px solid ${colorWithAlpha(foreground, 0.2)}`
10173
10218
  }
10174
10219
  };
10175
10220
  for (const key of LIGHT_INTERACTIVE_SURFACE_KEYS) {
@@ -10316,7 +10361,8 @@ var OnboardModal = ({
10316
10361
  showSaveBackupOption = true,
10317
10362
  onSaveBackupChange,
10318
10363
  onManualAesKeySubmit,
10319
- warning,
10364
+ warnings,
10365
+ runtimeWarnings,
10320
10366
  theme
10321
10367
  }) => {
10322
10368
  const [copied, setCopied] = useState14(false);
@@ -10362,6 +10408,15 @@ var OnboardModal = ({
10362
10408
  /* @__PURE__ */ jsx("div", { style: styles2.iconContainer, children: icon }),
10363
10409
  /* @__PURE__ */ jsx("h2", { id: "onboard-modal-title", style: styles2.title, children: title })
10364
10410
  ] });
10411
+ const renderPageWarning = (page) => {
10412
+ const message = resolveOnboardPageWarning(page, {
10413
+ warnings,
10414
+ runtimeWarnings,
10415
+ saveBackup
10416
+ });
10417
+ if (!message) return null;
10418
+ return /* @__PURE__ */ jsx("div", { style: warningStyles.box, children: /* @__PURE__ */ jsx("p", { style: warningStyles.text, children: message }) });
10419
+ };
10365
10420
  const renderSaveLocallyOption = () => {
10366
10421
  if (!showSaveBackupOption) return null;
10367
10422
  return /* @__PURE__ */ jsxs(
@@ -10373,29 +10428,26 @@ var OnboardModal = ({
10373
10428
  },
10374
10429
  children: [
10375
10430
  /* @__PURE__ */ jsx("div", { style: styles2.saveOptionIconWrap, "aria-hidden": "true", children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0 3 3L22 7l-3-3m-3.5 3.5L19 4" }) }) }),
10376
- /* @__PURE__ */ jsxs("div", { style: styles2.saveOptionBody, children: [
10377
- /* @__PURE__ */ jsxs("div", { style: styles2.saveOptionTitleRow, children: [
10378
- /* @__PURE__ */ jsx("span", { style: styles2.saveOptionTitle, children: "Save Locally" }),
10379
- /* @__PURE__ */ jsxs("span", { style: styles2.tooltipWrap, children: [
10380
- /* @__PURE__ */ jsx(
10381
- "button",
10382
- {
10383
- type: "button",
10384
- "aria-label": "How local save works",
10385
- "aria-describedby": showBackupTooltip ? "backup-details-tooltip" : void 0,
10386
- onMouseEnter: () => setShowBackupTooltip(true),
10387
- onMouseLeave: () => setShowBackupTooltip(false),
10388
- onFocus: () => setShowBackupTooltip(true),
10389
- onBlur: () => setShowBackupTooltip(false),
10390
- style: styles2.tooltipButton,
10391
- children: "?"
10392
- }
10393
- ),
10394
- showBackupTooltip && /* @__PURE__ */ jsx("span", { id: "backup-details-tooltip", role: "tooltip", style: styles2.tooltipBubble, children: "Only an encrypted blob is stored locally. Restoring it requires a wallet signature." })
10395
- ] })
10396
- ] }),
10397
- /* @__PURE__ */ jsx("p", { style: styles2.saveOptionDescription, children: "Encrypted locally. Restore via wallet signature." })
10398
- ] }),
10431
+ /* @__PURE__ */ jsx("div", { style: styles2.saveOptionBody, children: /* @__PURE__ */ jsxs("div", { style: styles2.saveOptionTitleRow, children: [
10432
+ /* @__PURE__ */ jsx("span", { style: styles2.saveOptionTitle, children: "Save Locally" }),
10433
+ /* @__PURE__ */ jsxs("span", { style: styles2.tooltipWrap, children: [
10434
+ /* @__PURE__ */ jsx(
10435
+ "button",
10436
+ {
10437
+ type: "button",
10438
+ "aria-label": "How local save works",
10439
+ "aria-describedby": showBackupTooltip ? "backup-details-tooltip" : void 0,
10440
+ onMouseEnter: () => setShowBackupTooltip(true),
10441
+ onMouseLeave: () => setShowBackupTooltip(false),
10442
+ onFocus: () => setShowBackupTooltip(true),
10443
+ onBlur: () => setShowBackupTooltip(false),
10444
+ style: styles2.tooltipButton,
10445
+ children: "?"
10446
+ }
10447
+ ),
10448
+ showBackupTooltip && /* @__PURE__ */ jsx("span", { id: "backup-details-tooltip", role: "tooltip", style: styles2.tooltipBubble, children: "Only an encrypted blob is stored locally. Restoring it requires a wallet signature." })
10449
+ ] })
10450
+ ] }) }),
10399
10451
  /* @__PURE__ */ jsx(
10400
10452
  "button",
10401
10453
  {
@@ -10591,7 +10643,7 @@ var OnboardModal = ({
10591
10643
  "Onboard User"
10592
10644
  ),
10593
10645
  /* @__PURE__ */ jsx("p", { id: "onboard-modal-description", style: styles2.description, children: "This will execute a transaction on the COTI Network to retrieve your encryption key." }),
10594
- warning && /* @__PURE__ */ jsx("div", { style: warningStyles.box, children: /* @__PURE__ */ jsx("p", { style: warningStyles.text, children: warning }) }),
10646
+ renderPageWarning("intro"),
10595
10647
  renderSaveLocallyOption(),
10596
10648
  /* @__PURE__ */ jsxs(
10597
10649
  "div",
@@ -10608,7 +10660,7 @@ var OnboardModal = ({
10608
10660
  type: "text",
10609
10661
  value: manualAesKey,
10610
10662
  onChange: (event) => setManualAesKey(event.target.value),
10611
- placeholder: "Paste AES key",
10663
+ placeholder: "Paste key",
10612
10664
  "aria-label": "Manual AES key",
10613
10665
  disabled: isSubmittingManualKey,
10614
10666
  style: { ...styles2.manualKeyInput, ...styles2.actionPrimary },
@@ -10682,7 +10734,7 @@ var OnboardModal = ({
10682
10734
  /* @__PURE__ */ jsx("div", { style: styles2.spinner }),
10683
10735
  getProgressTitle(currentStep)
10684
10736
  ),
10685
- warning && /* @__PURE__ */ jsx("div", { style: warningStyles.box, children: /* @__PURE__ */ jsx("p", { style: warningStyles.text, children: warning }) }),
10737
+ renderPageWarning("progress"),
10686
10738
  /* @__PURE__ */ jsx("div", { style: styles2.stepperContainer, children: displaySteps.map((step) => {
10687
10739
  const status = getOnboardingStepStatus(step.id, currentStep, !!error, includePersistStep);
10688
10740
  const isActive = status === "active";
@@ -10780,12 +10832,7 @@ var OnboardModal = ({
10780
10832
  )
10781
10833
  ] })
10782
10834
  ] }),
10783
- /* @__PURE__ */ jsx("div", { style: warningStyles.box, children: /* @__PURE__ */ jsxs("p", { style: warningStyles.text, children: [
10784
- /* @__PURE__ */ jsx("strong", { children: "Important:" }),
10785
- " ",
10786
- saveBackup ? "An encrypted backup can help restore this key later, but you should still store it safely." : "This key will be lost when you refresh the page. Store it in a secure location."
10787
- ] }) }),
10788
- warning && /* @__PURE__ */ jsx("div", { style: warningStyles.box, children: /* @__PURE__ */ jsx("p", { style: warningStyles.text, children: warning }) }),
10835
+ renderPageWarning("success"),
10789
10836
  /* @__PURE__ */ jsx(
10790
10837
  "button",
10791
10838
  {
@@ -10819,6 +10866,7 @@ var OnboardModal = ({
10819
10866
  ),
10820
10867
  /* @__PURE__ */ jsx("p", { id: "onboard-modal-description", style: styles2.description, children: "The onboarding process encountered an error. You can retry the signature request." }),
10821
10868
  /* @__PURE__ */ jsx("div", { style: styles2.errorBox, children: /* @__PURE__ */ jsx("p", { style: styles2.errorText, children: error || "An unknown error occurred" }) }),
10869
+ renderPageWarning("error"),
10822
10870
  /* @__PURE__ */ jsx(
10823
10871
  "button",
10824
10872
  {
@@ -10929,14 +10977,14 @@ function keepForwardContractProgress(previous, next) {
10929
10977
  return nextOrder >= previousOrder ? next : previous;
10930
10978
  }
10931
10979
  function usePrivateUnlockController(options = {}) {
10932
- const { theme, warning, onUnlocked, onRestoreCancelled, onOnboardingCancelled } = options;
10980
+ const { theme, warnings, onUnlocked, onRestoreCancelled, onOnboardingCancelled } = options;
10933
10981
  const unlock = usePrivacyBridgeUnlock();
10934
10982
  const wallet = usePrivacyBridgeWallet();
10935
10983
  const walletTypeInfo = useWalletType();
10936
10984
  const [showOnboardModal, setShowOnboardModal] = useState15(false);
10937
10985
  const [isUnlocking, setIsUnlocking] = useState15(false);
10938
10986
  const [modalError, setModalError] = useState15(null);
10939
- const [modalWarning, setModalWarning] = useState15(null);
10987
+ const [modalRuntimeWarnings, setModalRuntimeWarnings] = useState15({});
10940
10988
  const [snapConnectedInModal, setSnapConnectedInModal] = useState15(false);
10941
10989
  const [saveBackup, setSaveBackup] = useState15(true);
10942
10990
  const [currentStep, setCurrentStep] = useState15("idle");
@@ -10973,7 +11021,7 @@ function usePrivateUnlockController(options = {}) {
10973
11021
  pendingActionOwnerRef.current = null;
10974
11022
  setCurrentStep("idle");
10975
11023
  setModalError(null);
10976
- setModalWarning(null);
11024
+ setModalRuntimeWarnings({});
10977
11025
  backupSaveProgressStartedAtRef.current = null;
10978
11026
  pendingCompleteRequestIdRef.current = null;
10979
11027
  contractOnboardingCancelledRef.current = false;
@@ -11002,7 +11050,7 @@ function usePrivateUnlockController(options = {}) {
11002
11050
  setShowOnboardModal(false);
11003
11051
  setCurrentStep("idle");
11004
11052
  setModalError(null);
11005
- setModalWarning(null);
11053
+ setModalRuntimeWarnings({});
11006
11054
  setIsUnlockInProgress(false);
11007
11055
  setIsUnlocking(false);
11008
11056
  backupSaveProgressStartedAtRef.current = null;
@@ -11027,7 +11075,7 @@ function usePrivateUnlockController(options = {}) {
11027
11075
  setShowOnboardModal(false);
11028
11076
  setCurrentStep("idle");
11029
11077
  setModalError(null);
11030
- setModalWarning(null);
11078
+ setModalRuntimeWarnings({});
11031
11079
  unlockInProgressOwnerRef.current = null;
11032
11080
  setIsUnlockInProgress(false);
11033
11081
  setIsUnlocking(false);
@@ -11063,14 +11111,18 @@ function usePrivateUnlockController(options = {}) {
11063
11111
  try {
11064
11112
  const connected = await unlock.requestSnapConnection();
11065
11113
  if (!connected) {
11066
- setModalWarning("Snap connection was skipped or rejected. Continuing without Snap storage.");
11114
+ setModalRuntimeWarnings({
11115
+ intro: "Snap connection was skipped or rejected. Continuing without Snap storage."
11116
+ });
11067
11117
  return false;
11068
11118
  }
11069
11119
  snapConnectedInModalRef.current = true;
11070
11120
  setSnapConnectedInModal(true);
11071
11121
  return true;
11072
11122
  } catch {
11073
- setModalWarning("Snap connection failed. Continuing without Snap storage.");
11123
+ setModalRuntimeWarnings({
11124
+ intro: "Snap connection failed. Continuing without Snap storage."
11125
+ });
11074
11126
  return false;
11075
11127
  }
11076
11128
  }, [canAttemptSnapInstall, unlock]);
@@ -11104,15 +11156,13 @@ function usePrivateUnlockController(options = {}) {
11104
11156
  if (failureMessage) {
11105
11157
  setCurrentStep("error");
11106
11158
  setModalError(failureMessage);
11107
- setModalWarning(unlock.onboardingWarning ?? null);
11108
11159
  releaseUnlockInProgress(requestId);
11109
11160
  return;
11110
11161
  }
11111
11162
  setCurrentStep("error");
11112
11163
  setModalError("Onboarding did not complete. Please retry.");
11113
- setModalWarning(unlock.onboardingWarning ?? null);
11114
11164
  releaseUnlockInProgress(requestId);
11115
- }, [dismissOnboardModal, isActiveUnlockRequest, onOnboardingCancelled, releaseUnlockInProgress, unlock.onboardingWarning]);
11165
+ }, [dismissOnboardModal, isActiveUnlockRequest, onOnboardingCancelled, releaseUnlockInProgress]);
11116
11166
  const handleStaleRestoreCompletion = useCallback19((requestId, refreshSucceeded) => {
11117
11167
  clearPendingActionForRequest(requestId);
11118
11168
  const unlocked = refreshSucceeded || isPrivateUnlockedRef.current;
@@ -11128,7 +11178,7 @@ function usePrivateUnlockController(options = {}) {
11128
11178
  setPendingActionForRequest(requestId, pendingAction);
11129
11179
  }
11130
11180
  setModalError(null);
11131
- setModalWarning(null);
11181
+ setModalRuntimeWarnings({});
11132
11182
  inFlightRestoreRequestIdRef.current = requestId;
11133
11183
  setIsUnlocking(true);
11134
11184
  try {
@@ -11162,7 +11212,6 @@ function usePrivateUnlockController(options = {}) {
11162
11212
  return false;
11163
11213
  }
11164
11214
  setCurrentStep("idle");
11165
- setModalWarning(unlock.onboardingWarning ?? null);
11166
11215
  setShowOnboardModal(true);
11167
11216
  return false;
11168
11217
  } catch (error) {
@@ -11224,7 +11273,6 @@ function usePrivateUnlockController(options = {}) {
11224
11273
  contractOnboardingFailureRef.current = failureMessage;
11225
11274
  setCurrentStep("error");
11226
11275
  setModalError(failureMessage);
11227
- setModalWarning(unlock.onboardingWarning ?? null);
11228
11276
  releaseUnlockInProgress(unlockRequestIdRef.current);
11229
11277
  }
11230
11278
  return;
@@ -11236,7 +11284,7 @@ function usePrivateUnlockController(options = {}) {
11236
11284
  if (step === "idle") {
11237
11285
  setModalError(null);
11238
11286
  }
11239
- }, [currentStep, showOnboardModal, releaseUnlockInProgress, unlock.onboardingWarning]);
11287
+ }, [currentStep, showOnboardModal, releaseUnlockInProgress]);
11240
11288
  const showOnboardingComplete = useCallback19((requestId) => {
11241
11289
  if (!isActiveUnlockRequest(requestId)) return;
11242
11290
  pendingCompleteRequestIdRef.current = null;
@@ -11254,7 +11302,7 @@ function usePrivateUnlockController(options = {}) {
11254
11302
  if (!connectedAddress) return;
11255
11303
  const requestId = unlockRequestIdRef.current;
11256
11304
  setModalError(null);
11257
- setModalWarning(null);
11305
+ setModalRuntimeWarnings({});
11258
11306
  setIsUnlocking(true);
11259
11307
  setShowOnboardModal(true);
11260
11308
  setCurrentStep("preparing-onboard");
@@ -11289,7 +11337,7 @@ function usePrivateUnlockController(options = {}) {
11289
11337
  currentStep,
11290
11338
  hasSessionAesKey: !!unlock.sessionAesKey,
11291
11339
  hasOnboardingError: !!unlock.onboardingError,
11292
- hasOnboardingWarning: !!unlock.onboardingWarning
11340
+ hasOnboardingWarning: hasOnboardModalWarnings(unlock.onboardingWarnings)
11293
11341
  });
11294
11342
  const backupSaveProgressStartedAt = backupSaveProgressStartedAtRef.current;
11295
11343
  if (backupSaveProgressStartedAt !== null) {
@@ -11405,7 +11453,7 @@ function usePrivateUnlockController(options = {}) {
11405
11453
  onSaveBackupChange: setSaveBackup,
11406
11454
  onManualAesKeySubmit: async (aesKey, { saveBackup: shouldSaveBackup }) => {
11407
11455
  const requestId = unlockRequestIdRef.current;
11408
- setModalWarning(null);
11456
+ setModalRuntimeWarnings({});
11409
11457
  const manualSaveResult = await unlock.saveManualAesKey(aesKey, {
11410
11458
  saveBackup: shouldSaveBackup,
11411
11459
  onProgress: (step) => {
@@ -11426,7 +11474,7 @@ function usePrivateUnlockController(options = {}) {
11426
11474
  return;
11427
11475
  }
11428
11476
  if (manualSaveResult.backupWarning) {
11429
- setModalWarning(manualSaveResult.backupWarning);
11477
+ setModalRuntimeWarnings({ success: manualSaveResult.backupWarning });
11430
11478
  setShowOnboardModal(true);
11431
11479
  setCurrentStep("complete");
11432
11480
  releaseUnlockInProgress(requestId);
@@ -11435,7 +11483,8 @@ function usePrivateUnlockController(options = {}) {
11435
11483
  await completeUnlock(requestId);
11436
11484
  },
11437
11485
  theme,
11438
- warning: modalWarning ?? unlock.onboardingWarning ?? warning ?? null
11486
+ warnings,
11487
+ runtimeWarnings: mergeOnboardModalWarnings(unlock.onboardingWarnings, modalRuntimeWarnings)
11439
11488
  }
11440
11489
  );
11441
11490
  return {
@@ -11608,7 +11657,7 @@ var PrivacyBridgeProvider = ({
11608
11657
  decryptPrivateValue: session.decryptPrivateValue,
11609
11658
  refreshPrivateBalances: session.refreshPrivateBalances,
11610
11659
  onboardingError: session.onboardingError,
11611
- onboardingWarning: session.onboardingWarning,
11660
+ onboardingWarnings: session.onboardingWarnings,
11612
11661
  lockPrivateBalances: session.lockPrivateBalances,
11613
11662
  handleOnboard: session.handleOnboard,
11614
11663
  saveManualAesKey: session.saveManualAesKey,