@coti-io/coti-wallet-plugin 0.1.0 → 0.2.1
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.d.mts +34 -19
- package/dist/index.d.ts +34 -19
- package/dist/index.js +162 -102
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +162 -102
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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,
|
|
@@ -3672,6 +3673,17 @@ var usePrivateTokenBalance = () => {
|
|
|
3672
3673
|
if (error instanceof CotiPluginError) {
|
|
3673
3674
|
throw error;
|
|
3674
3675
|
}
|
|
3676
|
+
const message = error instanceof Error ? error.message : String(error?.message ?? error ?? "");
|
|
3677
|
+
const code = error?.code;
|
|
3678
|
+
const isDecryptPayloadFailure = message.includes("Invalid encrypted payload") || code === -32603 && /encrypt|decrypt|ciphertext/i.test(message);
|
|
3679
|
+
if (isDecryptPayloadFailure || canUseSnapDecrypt) {
|
|
3680
|
+
logger.error(`\u274C Failed to decrypt private balance for ${contractAddress}`, error);
|
|
3681
|
+
throw new CotiPluginError(
|
|
3682
|
+
"AES_KEY_MISMATCH" /* AES_KEY_MISMATCH */,
|
|
3683
|
+
isDecryptPayloadFailure ? "Could not decrypt private balances. The Snap AES key may be missing or invalid \u2014 re-onboarding is required." : "Could not decrypt private balances via Snap. Re-onboarding may be required.",
|
|
3684
|
+
message
|
|
3685
|
+
);
|
|
3686
|
+
}
|
|
3675
3687
|
logger.error(`\u274C Failed to fetch/decrypt for ${contractAddress}`, error);
|
|
3676
3688
|
return "0.00";
|
|
3677
3689
|
}
|
|
@@ -4072,7 +4084,7 @@ var useBalanceUpdater = ({
|
|
|
4072
4084
|
return { symbol: token.symbol, value, isMismatch: false };
|
|
4073
4085
|
} catch (e) {
|
|
4074
4086
|
const msg = e?.message || "";
|
|
4075
|
-
const isMismatch = msg.includes("AES key mismatch") || msg.includes("onboarding") || msg.includes("ACCOUNT_NOT_ONBOARDED") || msg.includes("implausible decrypted balance");
|
|
4087
|
+
const isMismatch = e instanceof CotiPluginError && (e.code === "AES_KEY_MISMATCH" /* AES_KEY_MISMATCH */ || e.code === "ACCOUNT_NOT_ONBOARDED" /* ACCOUNT_NOT_ONBOARDED */) || msg.includes("AES key mismatch") || msg.includes("Invalid encrypted payload") || msg.includes("onboarding") || msg.includes("ACCOUNT_NOT_ONBOARDED") || msg.includes("implausible decrypted balance");
|
|
4076
4088
|
if (isMismatch) {
|
|
4077
4089
|
logger.warn(`\u26A0\uFE0F Private token decrypt mismatch for ${tokenAddress}. Falling back to 0.`);
|
|
4078
4090
|
return { symbol: token.symbol, value: "0", isMismatch: true };
|
|
@@ -7363,7 +7375,7 @@ var sleep2 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
|
7363
7375
|
function useAesKeyProvider(walletTypeInfo) {
|
|
7364
7376
|
const [isOnboarding, setIsOnboarding] = useState10(false);
|
|
7365
7377
|
const [onboardingError, setOnboardingError] = useState10(null);
|
|
7366
|
-
const [
|
|
7378
|
+
const [onboardingWarnings, setOnboardingWarnings] = useState10({});
|
|
7367
7379
|
const [wasRestoreCancelled, setWasRestoreCancelled] = useState10(false);
|
|
7368
7380
|
const [currentStep, setCurrentStep] = useState10("idle");
|
|
7369
7381
|
const progressCallbackRef = useRef7();
|
|
@@ -7384,7 +7396,7 @@ function useAesKeyProvider(walletTypeInfo) {
|
|
|
7384
7396
|
progressCallbackRef.current = onProgress ?? options.onProgress;
|
|
7385
7397
|
setOnboardingError(null);
|
|
7386
7398
|
debugTraceRef.current.clear();
|
|
7387
|
-
|
|
7399
|
+
setOnboardingWarnings({});
|
|
7388
7400
|
setWasRestoreCancelled(false);
|
|
7389
7401
|
const forceContractOnboarding = options?.forceContractOnboarding === true;
|
|
7390
7402
|
if (!forceContractOnboarding) {
|
|
@@ -7493,7 +7505,9 @@ function useAesKeyProvider(walletTypeInfo) {
|
|
|
7493
7505
|
}
|
|
7494
7506
|
} catch (restoreError) {
|
|
7495
7507
|
if (isUserRejection(restoreError)) {
|
|
7496
|
-
|
|
7508
|
+
setOnboardingWarnings({
|
|
7509
|
+
intro: "Backup restore was cancelled. Approve the wallet signature to unlock from your encrypted backup."
|
|
7510
|
+
});
|
|
7497
7511
|
setWasRestoreCancelled(true);
|
|
7498
7512
|
options.onRestoreCancelled?.();
|
|
7499
7513
|
emitStep("idle");
|
|
@@ -7502,7 +7516,9 @@ function useAesKeyProvider(walletTypeInfo) {
|
|
|
7502
7516
|
const message = restoreError instanceof Error ? restoreError.message : "Encrypted AES backup could not be restored.";
|
|
7503
7517
|
logger.warn("\u26A0\uFE0F AES backup restore failed, falling back to contract onboarding:", restoreError);
|
|
7504
7518
|
restoreBackupFailed = true;
|
|
7505
|
-
|
|
7519
|
+
setOnboardingWarnings({
|
|
7520
|
+
intro: `Encrypted backup could not be restored. Continuing with onboarding. ${message}`
|
|
7521
|
+
});
|
|
7506
7522
|
}
|
|
7507
7523
|
}
|
|
7508
7524
|
if (options.restoreOnly) {
|
|
@@ -7663,9 +7679,9 @@ function useAesKeyProvider(walletTypeInfo) {
|
|
|
7663
7679
|
savedToSnap = await saveAESKeyToSnap(aesKey, address);
|
|
7664
7680
|
if (!savedToSnap) {
|
|
7665
7681
|
logger.warn("\u26A0\uFE0F AES key retrieved but could not persist to Snap");
|
|
7666
|
-
|
|
7667
|
-
"Onboarding succeeded, but the AES key could not be saved to MetaMask Snap. You can retry by unlocking again."
|
|
7668
|
-
);
|
|
7682
|
+
setOnboardingWarnings({
|
|
7683
|
+
success: "Onboarding succeeded, but the AES key could not be saved to MetaMask Snap. You can retry by unlocking again."
|
|
7684
|
+
});
|
|
7669
7685
|
}
|
|
7670
7686
|
} else if (aesKey && walletTypeInfo.walletType === "metamask" && canPersistAesKeyToSnap() && !walletTypeInfo.isMetaMaskWithSnap) {
|
|
7671
7687
|
logger.log(
|
|
@@ -7687,14 +7703,14 @@ function useAesKeyProvider(walletTypeInfo) {
|
|
|
7687
7703
|
"\u26A0\uFE0F AES key retrieved but encrypted backup save failed:",
|
|
7688
7704
|
backupResult.message
|
|
7689
7705
|
);
|
|
7690
|
-
|
|
7691
|
-
`Onboarding succeeded, but encrypted backup was not saved. ${backupResult.message}`
|
|
7692
|
-
);
|
|
7706
|
+
setOnboardingWarnings({
|
|
7707
|
+
success: `Onboarding succeeded, but encrypted backup was not saved. ${backupResult.message}`
|
|
7708
|
+
});
|
|
7693
7709
|
} else if (backupResult.status === "cancelled") {
|
|
7694
7710
|
logger.warn("\u26A0\uFE0F AES key retrieved but encrypted backup save was cancelled");
|
|
7695
|
-
|
|
7696
|
-
"Onboarding succeeded, but encrypted backup save was cancelled. You can save it later by re-entering your AES key."
|
|
7697
|
-
);
|
|
7711
|
+
setOnboardingWarnings({
|
|
7712
|
+
success: "Onboarding succeeded, but encrypted backup save was cancelled. You can save it later by re-entering your AES key."
|
|
7713
|
+
});
|
|
7698
7714
|
}
|
|
7699
7715
|
}
|
|
7700
7716
|
if (aesKey && isValidAesKey(aesKey)) {
|
|
@@ -7758,7 +7774,7 @@ function useAesKeyProvider(walletTypeInfo) {
|
|
|
7758
7774
|
getAesKey,
|
|
7759
7775
|
isOnboarding,
|
|
7760
7776
|
onboardingError,
|
|
7761
|
-
|
|
7777
|
+
onboardingWarnings,
|
|
7762
7778
|
wasRestoreCancelled,
|
|
7763
7779
|
currentStep
|
|
7764
7780
|
};
|
|
@@ -7866,7 +7882,7 @@ var usePrivacyBridgeSessionCore = ({
|
|
|
7866
7882
|
getAesKey: getAesKeyFromProvider,
|
|
7867
7883
|
isOnboarding,
|
|
7868
7884
|
onboardingError,
|
|
7869
|
-
|
|
7885
|
+
onboardingWarnings
|
|
7870
7886
|
} = useAesKeyProvider(walletTypeInfo);
|
|
7871
7887
|
const { fetchPrivateBalance } = usePrivateTokenBalance();
|
|
7872
7888
|
useEffect9(() => {
|
|
@@ -7922,7 +7938,7 @@ var usePrivacyBridgeSessionCore = ({
|
|
|
7922
7938
|
fetchPrivateBalance,
|
|
7923
7939
|
getAesKeyFromProvider,
|
|
7924
7940
|
onboardingError,
|
|
7925
|
-
|
|
7941
|
+
onboardingWarnings
|
|
7926
7942
|
};
|
|
7927
7943
|
};
|
|
7928
7944
|
|
|
@@ -8554,6 +8570,7 @@ var usePrivacyBridgeWalletConnection = ({
|
|
|
8554
8570
|
};
|
|
8555
8571
|
|
|
8556
8572
|
// src/context/privacyBridge/usePrivacyBridgeUnlockSession.ts
|
|
8573
|
+
init_plugin();
|
|
8557
8574
|
init_logger();
|
|
8558
8575
|
import { useCallback as useCallback17 } from "react";
|
|
8559
8576
|
import { useAccount as useAccount9 } from "wagmi";
|
|
@@ -8825,6 +8842,13 @@ var usePrivacyBridgeUnlockSession = ({
|
|
|
8825
8842
|
}, [resolveAesAccess, resolveSessionAesKey, walletAddress, aesKeyChainId, checkSnapStatus, hasAesKeyInSnap, walletTypeInfo.walletType, currentChainId]);
|
|
8826
8843
|
const refreshPrivateBalances = useCallback17(async (aesKeyOptions) => {
|
|
8827
8844
|
if (!walletAddress) return false;
|
|
8845
|
+
const lockSessionOnAesFailure = !aesKeyOptions?.preserveSessionOnError;
|
|
8846
|
+
const clearSessionAfterAesFailure = () => {
|
|
8847
|
+
setSessionAesKey(null);
|
|
8848
|
+
clearAesKeyValidatedForUnlock(walletAddress);
|
|
8849
|
+
clearSnapCache();
|
|
8850
|
+
setArePrivateBalancesHidden(true);
|
|
8851
|
+
};
|
|
8828
8852
|
logger.log("Triggering private balance fetch...");
|
|
8829
8853
|
try {
|
|
8830
8854
|
const chainOverride = wagmiSyncRef.current ? wagmiChainId : void 0;
|
|
@@ -8903,10 +8927,7 @@ var usePrivacyBridgeUnlockSession = ({
|
|
|
8903
8927
|
);
|
|
8904
8928
|
}
|
|
8905
8929
|
if (errorInfo.message?.includes("ACCOUNT_NOT_ONBOARDED")) {
|
|
8906
|
-
|
|
8907
|
-
clearAesKeyValidatedForUnlock(walletAddress);
|
|
8908
|
-
clearSnapCache();
|
|
8909
|
-
setArePrivateBalancesHidden(true);
|
|
8930
|
+
if (lockSessionOnAesFailure) clearSessionAfterAesFailure();
|
|
8910
8931
|
throw new CotiPluginError(
|
|
8911
8932
|
"ACCOUNT_NOT_ONBOARDED" /* ACCOUNT_NOT_ONBOARDED */,
|
|
8912
8933
|
"Account has not been onboarded to the COTI network.",
|
|
@@ -8914,17 +8935,11 @@ var usePrivacyBridgeUnlockSession = ({
|
|
|
8914
8935
|
);
|
|
8915
8936
|
}
|
|
8916
8937
|
if (err instanceof CotiPluginError && err.code === "AES_KEY_MISMATCH" /* AES_KEY_MISMATCH */) {
|
|
8917
|
-
|
|
8918
|
-
clearAesKeyValidatedForUnlock(walletAddress);
|
|
8919
|
-
clearSnapCache();
|
|
8920
|
-
setArePrivateBalancesHidden(true);
|
|
8938
|
+
if (lockSessionOnAesFailure) clearSessionAfterAesFailure();
|
|
8921
8939
|
throw err;
|
|
8922
8940
|
}
|
|
8923
8941
|
if (errorInfo.message?.includes("AES key") || errorInfo.message?.includes("onboarding")) {
|
|
8924
|
-
|
|
8925
|
-
clearAesKeyValidatedForUnlock(walletAddress);
|
|
8926
|
-
clearSnapCache();
|
|
8927
|
-
setArePrivateBalancesHidden(true);
|
|
8942
|
+
if (lockSessionOnAesFailure) clearSessionAfterAesFailure();
|
|
8928
8943
|
throw new CotiPluginError(
|
|
8929
8944
|
"AES_KEY_MISMATCH" /* AES_KEY_MISMATCH */,
|
|
8930
8945
|
"AES key mismatch or onboarding error.",
|
|
@@ -8969,7 +8984,13 @@ var usePrivacyBridgeUnlockSession = ({
|
|
|
8969
8984
|
hasSnap: strategy.snapInstalled,
|
|
8970
8985
|
getAESKeyFromSnap: strategy.snapInstalled ? getAESKeyFromSnap : void 0
|
|
8971
8986
|
});
|
|
8972
|
-
|
|
8987
|
+
if (getPluginConfig().waitForBalanceRefreshAfterTransfer) {
|
|
8988
|
+
await refreshPrivateBalances();
|
|
8989
|
+
} else {
|
|
8990
|
+
void refreshPrivateBalances({ preserveSessionOnError: true }).catch(
|
|
8991
|
+
(err) => logger.error("Background balance refresh after transfer failed", err)
|
|
8992
|
+
);
|
|
8993
|
+
}
|
|
8973
8994
|
return result;
|
|
8974
8995
|
}, [
|
|
8975
8996
|
walletAddress,
|
|
@@ -9119,7 +9140,7 @@ var usePrivacyBridgeSession = ({ modals }) => {
|
|
|
9119
9140
|
refreshPublicBalances: unlock.refreshPublicBalances,
|
|
9120
9141
|
refreshPrivateBalances: unlock.refreshPrivateBalances,
|
|
9121
9142
|
onboardingError: core.onboardingError,
|
|
9122
|
-
|
|
9143
|
+
onboardingWarnings: core.onboardingWarnings,
|
|
9123
9144
|
lockPrivateBalances: unlock.lockPrivateBalances,
|
|
9124
9145
|
saveManualAesKey: unlock.saveManualAesKey,
|
|
9125
9146
|
sendPrivateToken: unlock.sendPrivateToken,
|
|
@@ -9492,6 +9513,40 @@ function deriveOnboardScreen({
|
|
|
9492
9513
|
|
|
9493
9514
|
// src/components/OnboardModal.tsx
|
|
9494
9515
|
init_logger();
|
|
9516
|
+
|
|
9517
|
+
// src/lib/onboardModalWarnings.ts
|
|
9518
|
+
function mergeOnboardModalWarnings(...sources) {
|
|
9519
|
+
const merged = {};
|
|
9520
|
+
for (const source of sources) {
|
|
9521
|
+
if (!source) continue;
|
|
9522
|
+
for (const page of Object.keys(source)) {
|
|
9523
|
+
const message = source[page];
|
|
9524
|
+
if (message) {
|
|
9525
|
+
merged[page] = message;
|
|
9526
|
+
}
|
|
9527
|
+
}
|
|
9528
|
+
}
|
|
9529
|
+
return merged;
|
|
9530
|
+
}
|
|
9531
|
+
function getDefaultSuccessWarning(saveBackup) {
|
|
9532
|
+
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.";
|
|
9533
|
+
}
|
|
9534
|
+
function resolveOnboardPageWarning(page, options) {
|
|
9535
|
+
const runtime = options.runtimeWarnings?.[page]?.trim();
|
|
9536
|
+
if (runtime) return runtime;
|
|
9537
|
+
const app = options.warnings?.[page]?.trim();
|
|
9538
|
+
if (app) return app;
|
|
9539
|
+
if (page === "success") {
|
|
9540
|
+
return getDefaultSuccessWarning(options.saveBackup ?? true);
|
|
9541
|
+
}
|
|
9542
|
+
return null;
|
|
9543
|
+
}
|
|
9544
|
+
function hasOnboardModalWarnings(warnings) {
|
|
9545
|
+
if (!warnings) return false;
|
|
9546
|
+
return Object.values(warnings).some((message) => !!message?.trim());
|
|
9547
|
+
}
|
|
9548
|
+
|
|
9549
|
+
// src/components/OnboardModal.tsx
|
|
9495
9550
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
9496
9551
|
var defaultStyles = {
|
|
9497
9552
|
backdrop: {
|
|
@@ -9663,28 +9718,23 @@ var defaultStyles = {
|
|
|
9663
9718
|
},
|
|
9664
9719
|
saveOptionBody: {
|
|
9665
9720
|
flex: 1,
|
|
9666
|
-
minWidth: 0
|
|
9721
|
+
minWidth: 0,
|
|
9722
|
+
display: "flex",
|
|
9723
|
+
alignItems: "center",
|
|
9724
|
+
minHeight: "32px"
|
|
9667
9725
|
},
|
|
9668
9726
|
saveOptionTitleRow: {
|
|
9669
9727
|
display: "flex",
|
|
9670
9728
|
alignItems: "center",
|
|
9671
|
-
gap: "5px"
|
|
9672
|
-
marginBottom: "2px"
|
|
9729
|
+
gap: "5px"
|
|
9673
9730
|
},
|
|
9674
9731
|
saveOptionTitle: {
|
|
9675
9732
|
fontSize: "13px",
|
|
9676
9733
|
fontWeight: 600,
|
|
9677
|
-
lineHeight:
|
|
9678
|
-
color: "#ffffff"
|
|
9679
|
-
|
|
9680
|
-
|
|
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"
|
|
9734
|
+
lineHeight: "14px",
|
|
9735
|
+
color: "#ffffff",
|
|
9736
|
+
display: "inline-flex",
|
|
9737
|
+
alignItems: "center"
|
|
9688
9738
|
},
|
|
9689
9739
|
saveOptionSwitchTrack: {
|
|
9690
9740
|
position: "relative",
|
|
@@ -9726,12 +9776,13 @@ var defaultStyles = {
|
|
|
9726
9776
|
tooltipButton: {
|
|
9727
9777
|
width: "14px",
|
|
9728
9778
|
height: "14px",
|
|
9779
|
+
boxSizing: "border-box",
|
|
9729
9780
|
borderRadius: "50%",
|
|
9730
9781
|
border: "1px solid rgba(255, 255, 255, 0.25)",
|
|
9731
9782
|
backgroundColor: "rgba(255, 255, 255, 0.08)",
|
|
9732
9783
|
color: "rgba(255, 255, 255, 0.8)",
|
|
9733
9784
|
fontSize: "9px",
|
|
9734
|
-
lineHeight:
|
|
9785
|
+
lineHeight: "12px",
|
|
9735
9786
|
padding: 0,
|
|
9736
9787
|
cursor: "help",
|
|
9737
9788
|
flexShrink: 0,
|
|
@@ -10035,8 +10086,7 @@ var MUTED_TEXT_KEYS = [
|
|
|
10035
10086
|
"closeButton",
|
|
10036
10087
|
"tooltipButton",
|
|
10037
10088
|
"cancelButton",
|
|
10038
|
-
"stepDescription"
|
|
10039
|
-
"saveOptionDescription"
|
|
10089
|
+
"stepDescription"
|
|
10040
10090
|
];
|
|
10041
10091
|
var ACCENT_TEXT_KEYS = [
|
|
10042
10092
|
"keyInput",
|
|
@@ -10086,7 +10136,8 @@ var LIGHT_INTERACTIVE_SURFACE_KEYS = [
|
|
|
10086
10136
|
"saveOptionCard",
|
|
10087
10137
|
"saveOptionIconWrap",
|
|
10088
10138
|
"saveOptionSwitchTrackOff",
|
|
10089
|
-
"saveOptionSwitchTrackOn"
|
|
10139
|
+
"saveOptionSwitchTrackOn",
|
|
10140
|
+
"tooltipButton"
|
|
10090
10141
|
];
|
|
10091
10142
|
function isDefaultDarkSurfaceBackground(backgroundColor) {
|
|
10092
10143
|
if (!backgroundColor) return true;
|
|
@@ -10170,6 +10221,11 @@ function applyLightInteractiveSurfaceGaps(merged, theme) {
|
|
|
10170
10221
|
saveOptionSwitchTrackOn: {
|
|
10171
10222
|
backgroundColor: primary,
|
|
10172
10223
|
borderColor: colorWithAlpha(primary, 0.45)
|
|
10224
|
+
},
|
|
10225
|
+
tooltipButton: {
|
|
10226
|
+
color: muted2,
|
|
10227
|
+
backgroundColor: colorWithAlpha(foreground, 0.08),
|
|
10228
|
+
border: `1px solid ${colorWithAlpha(foreground, 0.2)}`
|
|
10173
10229
|
}
|
|
10174
10230
|
};
|
|
10175
10231
|
for (const key of LIGHT_INTERACTIVE_SURFACE_KEYS) {
|
|
@@ -10316,7 +10372,8 @@ var OnboardModal = ({
|
|
|
10316
10372
|
showSaveBackupOption = true,
|
|
10317
10373
|
onSaveBackupChange,
|
|
10318
10374
|
onManualAesKeySubmit,
|
|
10319
|
-
|
|
10375
|
+
warnings,
|
|
10376
|
+
runtimeWarnings,
|
|
10320
10377
|
theme
|
|
10321
10378
|
}) => {
|
|
10322
10379
|
const [copied, setCopied] = useState14(false);
|
|
@@ -10362,6 +10419,15 @@ var OnboardModal = ({
|
|
|
10362
10419
|
/* @__PURE__ */ jsx("div", { style: styles2.iconContainer, children: icon }),
|
|
10363
10420
|
/* @__PURE__ */ jsx("h2", { id: "onboard-modal-title", style: styles2.title, children: title })
|
|
10364
10421
|
] });
|
|
10422
|
+
const renderPageWarning = (page) => {
|
|
10423
|
+
const message = resolveOnboardPageWarning(page, {
|
|
10424
|
+
warnings,
|
|
10425
|
+
runtimeWarnings,
|
|
10426
|
+
saveBackup
|
|
10427
|
+
});
|
|
10428
|
+
if (!message) return null;
|
|
10429
|
+
return /* @__PURE__ */ jsx("div", { style: warningStyles.box, children: /* @__PURE__ */ jsx("p", { style: warningStyles.text, children: message }) });
|
|
10430
|
+
};
|
|
10365
10431
|
const renderSaveLocallyOption = () => {
|
|
10366
10432
|
if (!showSaveBackupOption) return null;
|
|
10367
10433
|
return /* @__PURE__ */ jsxs(
|
|
@@ -10373,29 +10439,26 @@ var OnboardModal = ({
|
|
|
10373
10439
|
},
|
|
10374
10440
|
children: [
|
|
10375
10441
|
/* @__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__ */
|
|
10377
|
-
/* @__PURE__ */
|
|
10378
|
-
|
|
10379
|
-
/* @__PURE__ */
|
|
10380
|
-
|
|
10381
|
-
|
|
10382
|
-
|
|
10383
|
-
|
|
10384
|
-
|
|
10385
|
-
|
|
10386
|
-
|
|
10387
|
-
|
|
10388
|
-
|
|
10389
|
-
|
|
10390
|
-
|
|
10391
|
-
|
|
10392
|
-
|
|
10393
|
-
|
|
10394
|
-
|
|
10395
|
-
|
|
10396
|
-
] }),
|
|
10397
|
-
/* @__PURE__ */ jsx("p", { style: styles2.saveOptionDescription, children: "Encrypted locally. Restore via wallet signature." })
|
|
10398
|
-
] }),
|
|
10442
|
+
/* @__PURE__ */ jsx("div", { style: styles2.saveOptionBody, children: /* @__PURE__ */ jsxs("div", { style: styles2.saveOptionTitleRow, children: [
|
|
10443
|
+
/* @__PURE__ */ jsx("span", { style: styles2.saveOptionTitle, children: "Save Locally" }),
|
|
10444
|
+
/* @__PURE__ */ jsxs("span", { style: styles2.tooltipWrap, children: [
|
|
10445
|
+
/* @__PURE__ */ jsx(
|
|
10446
|
+
"button",
|
|
10447
|
+
{
|
|
10448
|
+
type: "button",
|
|
10449
|
+
"aria-label": "How local save works",
|
|
10450
|
+
"aria-describedby": showBackupTooltip ? "backup-details-tooltip" : void 0,
|
|
10451
|
+
onMouseEnter: () => setShowBackupTooltip(true),
|
|
10452
|
+
onMouseLeave: () => setShowBackupTooltip(false),
|
|
10453
|
+
onFocus: () => setShowBackupTooltip(true),
|
|
10454
|
+
onBlur: () => setShowBackupTooltip(false),
|
|
10455
|
+
style: styles2.tooltipButton,
|
|
10456
|
+
children: "?"
|
|
10457
|
+
}
|
|
10458
|
+
),
|
|
10459
|
+
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." })
|
|
10460
|
+
] })
|
|
10461
|
+
] }) }),
|
|
10399
10462
|
/* @__PURE__ */ jsx(
|
|
10400
10463
|
"button",
|
|
10401
10464
|
{
|
|
@@ -10591,7 +10654,7 @@ var OnboardModal = ({
|
|
|
10591
10654
|
"Onboard User"
|
|
10592
10655
|
),
|
|
10593
10656
|
/* @__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
|
-
|
|
10657
|
+
renderPageWarning("intro"),
|
|
10595
10658
|
renderSaveLocallyOption(),
|
|
10596
10659
|
/* @__PURE__ */ jsxs(
|
|
10597
10660
|
"div",
|
|
@@ -10608,7 +10671,7 @@ var OnboardModal = ({
|
|
|
10608
10671
|
type: "text",
|
|
10609
10672
|
value: manualAesKey,
|
|
10610
10673
|
onChange: (event) => setManualAesKey(event.target.value),
|
|
10611
|
-
placeholder: "Paste
|
|
10674
|
+
placeholder: "Paste key",
|
|
10612
10675
|
"aria-label": "Manual AES key",
|
|
10613
10676
|
disabled: isSubmittingManualKey,
|
|
10614
10677
|
style: { ...styles2.manualKeyInput, ...styles2.actionPrimary },
|
|
@@ -10682,7 +10745,7 @@ var OnboardModal = ({
|
|
|
10682
10745
|
/* @__PURE__ */ jsx("div", { style: styles2.spinner }),
|
|
10683
10746
|
getProgressTitle(currentStep)
|
|
10684
10747
|
),
|
|
10685
|
-
|
|
10748
|
+
renderPageWarning("progress"),
|
|
10686
10749
|
/* @__PURE__ */ jsx("div", { style: styles2.stepperContainer, children: displaySteps.map((step) => {
|
|
10687
10750
|
const status = getOnboardingStepStatus(step.id, currentStep, !!error, includePersistStep);
|
|
10688
10751
|
const isActive = status === "active";
|
|
@@ -10780,12 +10843,7 @@ var OnboardModal = ({
|
|
|
10780
10843
|
)
|
|
10781
10844
|
] })
|
|
10782
10845
|
] }),
|
|
10783
|
-
|
|
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 }) }),
|
|
10846
|
+
renderPageWarning("success"),
|
|
10789
10847
|
/* @__PURE__ */ jsx(
|
|
10790
10848
|
"button",
|
|
10791
10849
|
{
|
|
@@ -10819,6 +10877,7 @@ var OnboardModal = ({
|
|
|
10819
10877
|
),
|
|
10820
10878
|
/* @__PURE__ */ jsx("p", { id: "onboard-modal-description", style: styles2.description, children: "The onboarding process encountered an error. You can retry the signature request." }),
|
|
10821
10879
|
/* @__PURE__ */ jsx("div", { style: styles2.errorBox, children: /* @__PURE__ */ jsx("p", { style: styles2.errorText, children: error || "An unknown error occurred" }) }),
|
|
10880
|
+
renderPageWarning("error"),
|
|
10822
10881
|
/* @__PURE__ */ jsx(
|
|
10823
10882
|
"button",
|
|
10824
10883
|
{
|
|
@@ -10929,14 +10988,14 @@ function keepForwardContractProgress(previous, next) {
|
|
|
10929
10988
|
return nextOrder >= previousOrder ? next : previous;
|
|
10930
10989
|
}
|
|
10931
10990
|
function usePrivateUnlockController(options = {}) {
|
|
10932
|
-
const { theme,
|
|
10991
|
+
const { theme, warnings, onUnlocked, onRestoreCancelled, onOnboardingCancelled } = options;
|
|
10933
10992
|
const unlock = usePrivacyBridgeUnlock();
|
|
10934
10993
|
const wallet = usePrivacyBridgeWallet();
|
|
10935
10994
|
const walletTypeInfo = useWalletType();
|
|
10936
10995
|
const [showOnboardModal, setShowOnboardModal] = useState15(false);
|
|
10937
10996
|
const [isUnlocking, setIsUnlocking] = useState15(false);
|
|
10938
10997
|
const [modalError, setModalError] = useState15(null);
|
|
10939
|
-
const [
|
|
10998
|
+
const [modalRuntimeWarnings, setModalRuntimeWarnings] = useState15({});
|
|
10940
10999
|
const [snapConnectedInModal, setSnapConnectedInModal] = useState15(false);
|
|
10941
11000
|
const [saveBackup, setSaveBackup] = useState15(true);
|
|
10942
11001
|
const [currentStep, setCurrentStep] = useState15("idle");
|
|
@@ -10973,7 +11032,7 @@ function usePrivateUnlockController(options = {}) {
|
|
|
10973
11032
|
pendingActionOwnerRef.current = null;
|
|
10974
11033
|
setCurrentStep("idle");
|
|
10975
11034
|
setModalError(null);
|
|
10976
|
-
|
|
11035
|
+
setModalRuntimeWarnings({});
|
|
10977
11036
|
backupSaveProgressStartedAtRef.current = null;
|
|
10978
11037
|
pendingCompleteRequestIdRef.current = null;
|
|
10979
11038
|
contractOnboardingCancelledRef.current = false;
|
|
@@ -11002,7 +11061,7 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11002
11061
|
setShowOnboardModal(false);
|
|
11003
11062
|
setCurrentStep("idle");
|
|
11004
11063
|
setModalError(null);
|
|
11005
|
-
|
|
11064
|
+
setModalRuntimeWarnings({});
|
|
11006
11065
|
setIsUnlockInProgress(false);
|
|
11007
11066
|
setIsUnlocking(false);
|
|
11008
11067
|
backupSaveProgressStartedAtRef.current = null;
|
|
@@ -11027,7 +11086,7 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11027
11086
|
setShowOnboardModal(false);
|
|
11028
11087
|
setCurrentStep("idle");
|
|
11029
11088
|
setModalError(null);
|
|
11030
|
-
|
|
11089
|
+
setModalRuntimeWarnings({});
|
|
11031
11090
|
unlockInProgressOwnerRef.current = null;
|
|
11032
11091
|
setIsUnlockInProgress(false);
|
|
11033
11092
|
setIsUnlocking(false);
|
|
@@ -11063,14 +11122,18 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11063
11122
|
try {
|
|
11064
11123
|
const connected = await unlock.requestSnapConnection();
|
|
11065
11124
|
if (!connected) {
|
|
11066
|
-
|
|
11125
|
+
setModalRuntimeWarnings({
|
|
11126
|
+
intro: "Snap connection was skipped or rejected. Continuing without Snap storage."
|
|
11127
|
+
});
|
|
11067
11128
|
return false;
|
|
11068
11129
|
}
|
|
11069
11130
|
snapConnectedInModalRef.current = true;
|
|
11070
11131
|
setSnapConnectedInModal(true);
|
|
11071
11132
|
return true;
|
|
11072
11133
|
} catch {
|
|
11073
|
-
|
|
11134
|
+
setModalRuntimeWarnings({
|
|
11135
|
+
intro: "Snap connection failed. Continuing without Snap storage."
|
|
11136
|
+
});
|
|
11074
11137
|
return false;
|
|
11075
11138
|
}
|
|
11076
11139
|
}, [canAttemptSnapInstall, unlock]);
|
|
@@ -11104,15 +11167,13 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11104
11167
|
if (failureMessage) {
|
|
11105
11168
|
setCurrentStep("error");
|
|
11106
11169
|
setModalError(failureMessage);
|
|
11107
|
-
setModalWarning(unlock.onboardingWarning ?? null);
|
|
11108
11170
|
releaseUnlockInProgress(requestId);
|
|
11109
11171
|
return;
|
|
11110
11172
|
}
|
|
11111
11173
|
setCurrentStep("error");
|
|
11112
11174
|
setModalError("Onboarding did not complete. Please retry.");
|
|
11113
|
-
setModalWarning(unlock.onboardingWarning ?? null);
|
|
11114
11175
|
releaseUnlockInProgress(requestId);
|
|
11115
|
-
}, [dismissOnboardModal, isActiveUnlockRequest, onOnboardingCancelled, releaseUnlockInProgress
|
|
11176
|
+
}, [dismissOnboardModal, isActiveUnlockRequest, onOnboardingCancelled, releaseUnlockInProgress]);
|
|
11116
11177
|
const handleStaleRestoreCompletion = useCallback19((requestId, refreshSucceeded) => {
|
|
11117
11178
|
clearPendingActionForRequest(requestId);
|
|
11118
11179
|
const unlocked = refreshSucceeded || isPrivateUnlockedRef.current;
|
|
@@ -11128,7 +11189,7 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11128
11189
|
setPendingActionForRequest(requestId, pendingAction);
|
|
11129
11190
|
}
|
|
11130
11191
|
setModalError(null);
|
|
11131
|
-
|
|
11192
|
+
setModalRuntimeWarnings({});
|
|
11132
11193
|
inFlightRestoreRequestIdRef.current = requestId;
|
|
11133
11194
|
setIsUnlocking(true);
|
|
11134
11195
|
try {
|
|
@@ -11162,7 +11223,6 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11162
11223
|
return false;
|
|
11163
11224
|
}
|
|
11164
11225
|
setCurrentStep("idle");
|
|
11165
|
-
setModalWarning(unlock.onboardingWarning ?? null);
|
|
11166
11226
|
setShowOnboardModal(true);
|
|
11167
11227
|
return false;
|
|
11168
11228
|
} catch (error) {
|
|
@@ -11224,7 +11284,6 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11224
11284
|
contractOnboardingFailureRef.current = failureMessage;
|
|
11225
11285
|
setCurrentStep("error");
|
|
11226
11286
|
setModalError(failureMessage);
|
|
11227
|
-
setModalWarning(unlock.onboardingWarning ?? null);
|
|
11228
11287
|
releaseUnlockInProgress(unlockRequestIdRef.current);
|
|
11229
11288
|
}
|
|
11230
11289
|
return;
|
|
@@ -11236,7 +11295,7 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11236
11295
|
if (step === "idle") {
|
|
11237
11296
|
setModalError(null);
|
|
11238
11297
|
}
|
|
11239
|
-
}, [currentStep, showOnboardModal, releaseUnlockInProgress
|
|
11298
|
+
}, [currentStep, showOnboardModal, releaseUnlockInProgress]);
|
|
11240
11299
|
const showOnboardingComplete = useCallback19((requestId) => {
|
|
11241
11300
|
if (!isActiveUnlockRequest(requestId)) return;
|
|
11242
11301
|
pendingCompleteRequestIdRef.current = null;
|
|
@@ -11254,7 +11313,7 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11254
11313
|
if (!connectedAddress) return;
|
|
11255
11314
|
const requestId = unlockRequestIdRef.current;
|
|
11256
11315
|
setModalError(null);
|
|
11257
|
-
|
|
11316
|
+
setModalRuntimeWarnings({});
|
|
11258
11317
|
setIsUnlocking(true);
|
|
11259
11318
|
setShowOnboardModal(true);
|
|
11260
11319
|
setCurrentStep("preparing-onboard");
|
|
@@ -11289,7 +11348,7 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11289
11348
|
currentStep,
|
|
11290
11349
|
hasSessionAesKey: !!unlock.sessionAesKey,
|
|
11291
11350
|
hasOnboardingError: !!unlock.onboardingError,
|
|
11292
|
-
hasOnboardingWarning:
|
|
11351
|
+
hasOnboardingWarning: hasOnboardModalWarnings(unlock.onboardingWarnings)
|
|
11293
11352
|
});
|
|
11294
11353
|
const backupSaveProgressStartedAt = backupSaveProgressStartedAtRef.current;
|
|
11295
11354
|
if (backupSaveProgressStartedAt !== null) {
|
|
@@ -11405,7 +11464,7 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11405
11464
|
onSaveBackupChange: setSaveBackup,
|
|
11406
11465
|
onManualAesKeySubmit: async (aesKey, { saveBackup: shouldSaveBackup }) => {
|
|
11407
11466
|
const requestId = unlockRequestIdRef.current;
|
|
11408
|
-
|
|
11467
|
+
setModalRuntimeWarnings({});
|
|
11409
11468
|
const manualSaveResult = await unlock.saveManualAesKey(aesKey, {
|
|
11410
11469
|
saveBackup: shouldSaveBackup,
|
|
11411
11470
|
onProgress: (step) => {
|
|
@@ -11426,7 +11485,7 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11426
11485
|
return;
|
|
11427
11486
|
}
|
|
11428
11487
|
if (manualSaveResult.backupWarning) {
|
|
11429
|
-
|
|
11488
|
+
setModalRuntimeWarnings({ success: manualSaveResult.backupWarning });
|
|
11430
11489
|
setShowOnboardModal(true);
|
|
11431
11490
|
setCurrentStep("complete");
|
|
11432
11491
|
releaseUnlockInProgress(requestId);
|
|
@@ -11435,7 +11494,8 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11435
11494
|
await completeUnlock(requestId);
|
|
11436
11495
|
},
|
|
11437
11496
|
theme,
|
|
11438
|
-
|
|
11497
|
+
warnings,
|
|
11498
|
+
runtimeWarnings: mergeOnboardModalWarnings(unlock.onboardingWarnings, modalRuntimeWarnings)
|
|
11439
11499
|
}
|
|
11440
11500
|
);
|
|
11441
11501
|
return {
|
|
@@ -11608,7 +11668,7 @@ var PrivacyBridgeProvider = ({
|
|
|
11608
11668
|
decryptPrivateValue: session.decryptPrivateValue,
|
|
11609
11669
|
refreshPrivateBalances: session.refreshPrivateBalances,
|
|
11610
11670
|
onboardingError: session.onboardingError,
|
|
11611
|
-
|
|
11671
|
+
onboardingWarnings: session.onboardingWarnings,
|
|
11612
11672
|
lockPrivateBalances: session.lockPrivateBalances,
|
|
11613
11673
|
handleOnboard: session.handleOnboard,
|
|
11614
11674
|
saveManualAesKey: session.saveManualAesKey,
|