@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.js
CHANGED
|
@@ -596,6 +596,7 @@ var init_plugin = __esm({
|
|
|
596
596
|
defaultNetworkId: void 0,
|
|
597
597
|
debug: false,
|
|
598
598
|
clearSessionKeyOnWagmiDisconnect: false,
|
|
599
|
+
waitForBalanceRefreshAfterTransfer: false,
|
|
599
600
|
onboardingServices: { mode: "disabled" },
|
|
600
601
|
onboardingGrantMinBalanceWei: 0,
|
|
601
602
|
onboardingGrantPollIntervalMs: 2e3,
|
|
@@ -3827,6 +3828,17 @@ var usePrivateTokenBalance = () => {
|
|
|
3827
3828
|
if (error instanceof CotiPluginError) {
|
|
3828
3829
|
throw error;
|
|
3829
3830
|
}
|
|
3831
|
+
const message = error instanceof Error ? error.message : String(error?.message ?? error ?? "");
|
|
3832
|
+
const code = error?.code;
|
|
3833
|
+
const isDecryptPayloadFailure = message.includes("Invalid encrypted payload") || code === -32603 && /encrypt|decrypt|ciphertext/i.test(message);
|
|
3834
|
+
if (isDecryptPayloadFailure || canUseSnapDecrypt) {
|
|
3835
|
+
logger.error(`\u274C Failed to decrypt private balance for ${contractAddress}`, error);
|
|
3836
|
+
throw new CotiPluginError(
|
|
3837
|
+
"AES_KEY_MISMATCH" /* AES_KEY_MISMATCH */,
|
|
3838
|
+
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.",
|
|
3839
|
+
message
|
|
3840
|
+
);
|
|
3841
|
+
}
|
|
3830
3842
|
logger.error(`\u274C Failed to fetch/decrypt for ${contractAddress}`, error);
|
|
3831
3843
|
return "0.00";
|
|
3832
3844
|
}
|
|
@@ -4227,7 +4239,7 @@ var useBalanceUpdater = ({
|
|
|
4227
4239
|
return { symbol: token.symbol, value, isMismatch: false };
|
|
4228
4240
|
} catch (e) {
|
|
4229
4241
|
const msg = e?.message || "";
|
|
4230
|
-
const isMismatch = msg.includes("AES key mismatch") || msg.includes("onboarding") || msg.includes("ACCOUNT_NOT_ONBOARDED") || msg.includes("implausible decrypted balance");
|
|
4242
|
+
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");
|
|
4231
4243
|
if (isMismatch) {
|
|
4232
4244
|
logger.warn(`\u26A0\uFE0F Private token decrypt mismatch for ${tokenAddress}. Falling back to 0.`);
|
|
4233
4245
|
return { symbol: token.symbol, value: "0", isMismatch: true };
|
|
@@ -7518,7 +7530,7 @@ var sleep2 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
|
7518
7530
|
function useAesKeyProvider(walletTypeInfo) {
|
|
7519
7531
|
const [isOnboarding, setIsOnboarding] = (0, import_react16.useState)(false);
|
|
7520
7532
|
const [onboardingError, setOnboardingError] = (0, import_react16.useState)(null);
|
|
7521
|
-
const [
|
|
7533
|
+
const [onboardingWarnings, setOnboardingWarnings] = (0, import_react16.useState)({});
|
|
7522
7534
|
const [wasRestoreCancelled, setWasRestoreCancelled] = (0, import_react16.useState)(false);
|
|
7523
7535
|
const [currentStep, setCurrentStep] = (0, import_react16.useState)("idle");
|
|
7524
7536
|
const progressCallbackRef = (0, import_react16.useRef)();
|
|
@@ -7539,7 +7551,7 @@ function useAesKeyProvider(walletTypeInfo) {
|
|
|
7539
7551
|
progressCallbackRef.current = onProgress ?? options.onProgress;
|
|
7540
7552
|
setOnboardingError(null);
|
|
7541
7553
|
debugTraceRef.current.clear();
|
|
7542
|
-
|
|
7554
|
+
setOnboardingWarnings({});
|
|
7543
7555
|
setWasRestoreCancelled(false);
|
|
7544
7556
|
const forceContractOnboarding = options?.forceContractOnboarding === true;
|
|
7545
7557
|
if (!forceContractOnboarding) {
|
|
@@ -7648,7 +7660,9 @@ function useAesKeyProvider(walletTypeInfo) {
|
|
|
7648
7660
|
}
|
|
7649
7661
|
} catch (restoreError) {
|
|
7650
7662
|
if (isUserRejection(restoreError)) {
|
|
7651
|
-
|
|
7663
|
+
setOnboardingWarnings({
|
|
7664
|
+
intro: "Backup restore was cancelled. Approve the wallet signature to unlock from your encrypted backup."
|
|
7665
|
+
});
|
|
7652
7666
|
setWasRestoreCancelled(true);
|
|
7653
7667
|
options.onRestoreCancelled?.();
|
|
7654
7668
|
emitStep("idle");
|
|
@@ -7657,7 +7671,9 @@ function useAesKeyProvider(walletTypeInfo) {
|
|
|
7657
7671
|
const message = restoreError instanceof Error ? restoreError.message : "Encrypted AES backup could not be restored.";
|
|
7658
7672
|
logger.warn("\u26A0\uFE0F AES backup restore failed, falling back to contract onboarding:", restoreError);
|
|
7659
7673
|
restoreBackupFailed = true;
|
|
7660
|
-
|
|
7674
|
+
setOnboardingWarnings({
|
|
7675
|
+
intro: `Encrypted backup could not be restored. Continuing with onboarding. ${message}`
|
|
7676
|
+
});
|
|
7661
7677
|
}
|
|
7662
7678
|
}
|
|
7663
7679
|
if (options.restoreOnly) {
|
|
@@ -7818,9 +7834,9 @@ function useAesKeyProvider(walletTypeInfo) {
|
|
|
7818
7834
|
savedToSnap = await saveAESKeyToSnap(aesKey, address);
|
|
7819
7835
|
if (!savedToSnap) {
|
|
7820
7836
|
logger.warn("\u26A0\uFE0F AES key retrieved but could not persist to Snap");
|
|
7821
|
-
|
|
7822
|
-
"Onboarding succeeded, but the AES key could not be saved to MetaMask Snap. You can retry by unlocking again."
|
|
7823
|
-
);
|
|
7837
|
+
setOnboardingWarnings({
|
|
7838
|
+
success: "Onboarding succeeded, but the AES key could not be saved to MetaMask Snap. You can retry by unlocking again."
|
|
7839
|
+
});
|
|
7824
7840
|
}
|
|
7825
7841
|
} else if (aesKey && walletTypeInfo.walletType === "metamask" && canPersistAesKeyToSnap() && !walletTypeInfo.isMetaMaskWithSnap) {
|
|
7826
7842
|
logger.log(
|
|
@@ -7842,14 +7858,14 @@ function useAesKeyProvider(walletTypeInfo) {
|
|
|
7842
7858
|
"\u26A0\uFE0F AES key retrieved but encrypted backup save failed:",
|
|
7843
7859
|
backupResult.message
|
|
7844
7860
|
);
|
|
7845
|
-
|
|
7846
|
-
`Onboarding succeeded, but encrypted backup was not saved. ${backupResult.message}`
|
|
7847
|
-
);
|
|
7861
|
+
setOnboardingWarnings({
|
|
7862
|
+
success: `Onboarding succeeded, but encrypted backup was not saved. ${backupResult.message}`
|
|
7863
|
+
});
|
|
7848
7864
|
} else if (backupResult.status === "cancelled") {
|
|
7849
7865
|
logger.warn("\u26A0\uFE0F AES key retrieved but encrypted backup save was cancelled");
|
|
7850
|
-
|
|
7851
|
-
"Onboarding succeeded, but encrypted backup save was cancelled. You can save it later by re-entering your AES key."
|
|
7852
|
-
);
|
|
7866
|
+
setOnboardingWarnings({
|
|
7867
|
+
success: "Onboarding succeeded, but encrypted backup save was cancelled. You can save it later by re-entering your AES key."
|
|
7868
|
+
});
|
|
7853
7869
|
}
|
|
7854
7870
|
}
|
|
7855
7871
|
if (aesKey && isValidAesKey(aesKey)) {
|
|
@@ -7913,7 +7929,7 @@ function useAesKeyProvider(walletTypeInfo) {
|
|
|
7913
7929
|
getAesKey,
|
|
7914
7930
|
isOnboarding,
|
|
7915
7931
|
onboardingError,
|
|
7916
|
-
|
|
7932
|
+
onboardingWarnings,
|
|
7917
7933
|
wasRestoreCancelled,
|
|
7918
7934
|
currentStep
|
|
7919
7935
|
};
|
|
@@ -8021,7 +8037,7 @@ var usePrivacyBridgeSessionCore = ({
|
|
|
8021
8037
|
getAesKey: getAesKeyFromProvider,
|
|
8022
8038
|
isOnboarding,
|
|
8023
8039
|
onboardingError,
|
|
8024
|
-
|
|
8040
|
+
onboardingWarnings
|
|
8025
8041
|
} = useAesKeyProvider(walletTypeInfo);
|
|
8026
8042
|
const { fetchPrivateBalance } = usePrivateTokenBalance();
|
|
8027
8043
|
(0, import_react18.useEffect)(() => {
|
|
@@ -8077,7 +8093,7 @@ var usePrivacyBridgeSessionCore = ({
|
|
|
8077
8093
|
fetchPrivateBalance,
|
|
8078
8094
|
getAesKeyFromProvider,
|
|
8079
8095
|
onboardingError,
|
|
8080
|
-
|
|
8096
|
+
onboardingWarnings
|
|
8081
8097
|
};
|
|
8082
8098
|
};
|
|
8083
8099
|
|
|
@@ -8711,6 +8727,7 @@ var usePrivacyBridgeWalletConnection = ({
|
|
|
8711
8727
|
// src/context/privacyBridge/usePrivacyBridgeUnlockSession.ts
|
|
8712
8728
|
var import_react23 = require("react");
|
|
8713
8729
|
var import_wagmi10 = require("wagmi");
|
|
8730
|
+
init_plugin();
|
|
8714
8731
|
init_logger();
|
|
8715
8732
|
|
|
8716
8733
|
// src/hooks/privacyBridge/privateValueCrypto.ts
|
|
@@ -8980,6 +8997,13 @@ var usePrivacyBridgeUnlockSession = ({
|
|
|
8980
8997
|
}, [resolveAesAccess, resolveSessionAesKey, walletAddress, aesKeyChainId, checkSnapStatus, hasAesKeyInSnap, walletTypeInfo.walletType, currentChainId]);
|
|
8981
8998
|
const refreshPrivateBalances = (0, import_react23.useCallback)(async (aesKeyOptions) => {
|
|
8982
8999
|
if (!walletAddress) return false;
|
|
9000
|
+
const lockSessionOnAesFailure = !aesKeyOptions?.preserveSessionOnError;
|
|
9001
|
+
const clearSessionAfterAesFailure = () => {
|
|
9002
|
+
setSessionAesKey(null);
|
|
9003
|
+
clearAesKeyValidatedForUnlock(walletAddress);
|
|
9004
|
+
clearSnapCache();
|
|
9005
|
+
setArePrivateBalancesHidden(true);
|
|
9006
|
+
};
|
|
8983
9007
|
logger.log("Triggering private balance fetch...");
|
|
8984
9008
|
try {
|
|
8985
9009
|
const chainOverride = wagmiSyncRef.current ? wagmiChainId : void 0;
|
|
@@ -9058,10 +9082,7 @@ var usePrivacyBridgeUnlockSession = ({
|
|
|
9058
9082
|
);
|
|
9059
9083
|
}
|
|
9060
9084
|
if (errorInfo.message?.includes("ACCOUNT_NOT_ONBOARDED")) {
|
|
9061
|
-
|
|
9062
|
-
clearAesKeyValidatedForUnlock(walletAddress);
|
|
9063
|
-
clearSnapCache();
|
|
9064
|
-
setArePrivateBalancesHidden(true);
|
|
9085
|
+
if (lockSessionOnAesFailure) clearSessionAfterAesFailure();
|
|
9065
9086
|
throw new CotiPluginError(
|
|
9066
9087
|
"ACCOUNT_NOT_ONBOARDED" /* ACCOUNT_NOT_ONBOARDED */,
|
|
9067
9088
|
"Account has not been onboarded to the COTI network.",
|
|
@@ -9069,17 +9090,11 @@ var usePrivacyBridgeUnlockSession = ({
|
|
|
9069
9090
|
);
|
|
9070
9091
|
}
|
|
9071
9092
|
if (err instanceof CotiPluginError && err.code === "AES_KEY_MISMATCH" /* AES_KEY_MISMATCH */) {
|
|
9072
|
-
|
|
9073
|
-
clearAesKeyValidatedForUnlock(walletAddress);
|
|
9074
|
-
clearSnapCache();
|
|
9075
|
-
setArePrivateBalancesHidden(true);
|
|
9093
|
+
if (lockSessionOnAesFailure) clearSessionAfterAesFailure();
|
|
9076
9094
|
throw err;
|
|
9077
9095
|
}
|
|
9078
9096
|
if (errorInfo.message?.includes("AES key") || errorInfo.message?.includes("onboarding")) {
|
|
9079
|
-
|
|
9080
|
-
clearAesKeyValidatedForUnlock(walletAddress);
|
|
9081
|
-
clearSnapCache();
|
|
9082
|
-
setArePrivateBalancesHidden(true);
|
|
9097
|
+
if (lockSessionOnAesFailure) clearSessionAfterAesFailure();
|
|
9083
9098
|
throw new CotiPluginError(
|
|
9084
9099
|
"AES_KEY_MISMATCH" /* AES_KEY_MISMATCH */,
|
|
9085
9100
|
"AES key mismatch or onboarding error.",
|
|
@@ -9124,7 +9139,13 @@ var usePrivacyBridgeUnlockSession = ({
|
|
|
9124
9139
|
hasSnap: strategy.snapInstalled,
|
|
9125
9140
|
getAESKeyFromSnap: strategy.snapInstalled ? getAESKeyFromSnap : void 0
|
|
9126
9141
|
});
|
|
9127
|
-
|
|
9142
|
+
if (getPluginConfig().waitForBalanceRefreshAfterTransfer) {
|
|
9143
|
+
await refreshPrivateBalances();
|
|
9144
|
+
} else {
|
|
9145
|
+
void refreshPrivateBalances({ preserveSessionOnError: true }).catch(
|
|
9146
|
+
(err) => logger.error("Background balance refresh after transfer failed", err)
|
|
9147
|
+
);
|
|
9148
|
+
}
|
|
9128
9149
|
return result;
|
|
9129
9150
|
}, [
|
|
9130
9151
|
walletAddress,
|
|
@@ -9274,7 +9295,7 @@ var usePrivacyBridgeSession = ({ modals }) => {
|
|
|
9274
9295
|
refreshPublicBalances: unlock.refreshPublicBalances,
|
|
9275
9296
|
refreshPrivateBalances: unlock.refreshPrivateBalances,
|
|
9276
9297
|
onboardingError: core.onboardingError,
|
|
9277
|
-
|
|
9298
|
+
onboardingWarnings: core.onboardingWarnings,
|
|
9278
9299
|
lockPrivateBalances: unlock.lockPrivateBalances,
|
|
9279
9300
|
saveManualAesKey: unlock.saveManualAesKey,
|
|
9280
9301
|
sendPrivateToken: unlock.sendPrivateToken,
|
|
@@ -9647,6 +9668,40 @@ function deriveOnboardScreen({
|
|
|
9647
9668
|
|
|
9648
9669
|
// src/components/OnboardModal.tsx
|
|
9649
9670
|
init_logger();
|
|
9671
|
+
|
|
9672
|
+
// src/lib/onboardModalWarnings.ts
|
|
9673
|
+
function mergeOnboardModalWarnings(...sources) {
|
|
9674
|
+
const merged = {};
|
|
9675
|
+
for (const source of sources) {
|
|
9676
|
+
if (!source) continue;
|
|
9677
|
+
for (const page of Object.keys(source)) {
|
|
9678
|
+
const message = source[page];
|
|
9679
|
+
if (message) {
|
|
9680
|
+
merged[page] = message;
|
|
9681
|
+
}
|
|
9682
|
+
}
|
|
9683
|
+
}
|
|
9684
|
+
return merged;
|
|
9685
|
+
}
|
|
9686
|
+
function getDefaultSuccessWarning(saveBackup) {
|
|
9687
|
+
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.";
|
|
9688
|
+
}
|
|
9689
|
+
function resolveOnboardPageWarning(page, options) {
|
|
9690
|
+
const runtime = options.runtimeWarnings?.[page]?.trim();
|
|
9691
|
+
if (runtime) return runtime;
|
|
9692
|
+
const app = options.warnings?.[page]?.trim();
|
|
9693
|
+
if (app) return app;
|
|
9694
|
+
if (page === "success") {
|
|
9695
|
+
return getDefaultSuccessWarning(options.saveBackup ?? true);
|
|
9696
|
+
}
|
|
9697
|
+
return null;
|
|
9698
|
+
}
|
|
9699
|
+
function hasOnboardModalWarnings(warnings) {
|
|
9700
|
+
if (!warnings) return false;
|
|
9701
|
+
return Object.values(warnings).some((message) => !!message?.trim());
|
|
9702
|
+
}
|
|
9703
|
+
|
|
9704
|
+
// src/components/OnboardModal.tsx
|
|
9650
9705
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
9651
9706
|
var defaultStyles = {
|
|
9652
9707
|
backdrop: {
|
|
@@ -9818,28 +9873,23 @@ var defaultStyles = {
|
|
|
9818
9873
|
},
|
|
9819
9874
|
saveOptionBody: {
|
|
9820
9875
|
flex: 1,
|
|
9821
|
-
minWidth: 0
|
|
9876
|
+
minWidth: 0,
|
|
9877
|
+
display: "flex",
|
|
9878
|
+
alignItems: "center",
|
|
9879
|
+
minHeight: "32px"
|
|
9822
9880
|
},
|
|
9823
9881
|
saveOptionTitleRow: {
|
|
9824
9882
|
display: "flex",
|
|
9825
9883
|
alignItems: "center",
|
|
9826
|
-
gap: "5px"
|
|
9827
|
-
marginBottom: "2px"
|
|
9884
|
+
gap: "5px"
|
|
9828
9885
|
},
|
|
9829
9886
|
saveOptionTitle: {
|
|
9830
9887
|
fontSize: "13px",
|
|
9831
9888
|
fontWeight: 600,
|
|
9832
|
-
lineHeight:
|
|
9833
|
-
color: "#ffffff"
|
|
9834
|
-
|
|
9835
|
-
|
|
9836
|
-
fontSize: "11px",
|
|
9837
|
-
lineHeight: 1.3,
|
|
9838
|
-
color: "rgba(255, 255, 255, 0.55)",
|
|
9839
|
-
margin: 0,
|
|
9840
|
-
whiteSpace: "nowrap",
|
|
9841
|
-
overflow: "hidden",
|
|
9842
|
-
textOverflow: "ellipsis"
|
|
9889
|
+
lineHeight: "14px",
|
|
9890
|
+
color: "#ffffff",
|
|
9891
|
+
display: "inline-flex",
|
|
9892
|
+
alignItems: "center"
|
|
9843
9893
|
},
|
|
9844
9894
|
saveOptionSwitchTrack: {
|
|
9845
9895
|
position: "relative",
|
|
@@ -9881,12 +9931,13 @@ var defaultStyles = {
|
|
|
9881
9931
|
tooltipButton: {
|
|
9882
9932
|
width: "14px",
|
|
9883
9933
|
height: "14px",
|
|
9934
|
+
boxSizing: "border-box",
|
|
9884
9935
|
borderRadius: "50%",
|
|
9885
9936
|
border: "1px solid rgba(255, 255, 255, 0.25)",
|
|
9886
9937
|
backgroundColor: "rgba(255, 255, 255, 0.08)",
|
|
9887
9938
|
color: "rgba(255, 255, 255, 0.8)",
|
|
9888
9939
|
fontSize: "9px",
|
|
9889
|
-
lineHeight:
|
|
9940
|
+
lineHeight: "12px",
|
|
9890
9941
|
padding: 0,
|
|
9891
9942
|
cursor: "help",
|
|
9892
9943
|
flexShrink: 0,
|
|
@@ -10190,8 +10241,7 @@ var MUTED_TEXT_KEYS = [
|
|
|
10190
10241
|
"closeButton",
|
|
10191
10242
|
"tooltipButton",
|
|
10192
10243
|
"cancelButton",
|
|
10193
|
-
"stepDescription"
|
|
10194
|
-
"saveOptionDescription"
|
|
10244
|
+
"stepDescription"
|
|
10195
10245
|
];
|
|
10196
10246
|
var ACCENT_TEXT_KEYS = [
|
|
10197
10247
|
"keyInput",
|
|
@@ -10241,7 +10291,8 @@ var LIGHT_INTERACTIVE_SURFACE_KEYS = [
|
|
|
10241
10291
|
"saveOptionCard",
|
|
10242
10292
|
"saveOptionIconWrap",
|
|
10243
10293
|
"saveOptionSwitchTrackOff",
|
|
10244
|
-
"saveOptionSwitchTrackOn"
|
|
10294
|
+
"saveOptionSwitchTrackOn",
|
|
10295
|
+
"tooltipButton"
|
|
10245
10296
|
];
|
|
10246
10297
|
function isDefaultDarkSurfaceBackground(backgroundColor) {
|
|
10247
10298
|
if (!backgroundColor) return true;
|
|
@@ -10325,6 +10376,11 @@ function applyLightInteractiveSurfaceGaps(merged, theme) {
|
|
|
10325
10376
|
saveOptionSwitchTrackOn: {
|
|
10326
10377
|
backgroundColor: primary,
|
|
10327
10378
|
borderColor: colorWithAlpha(primary, 0.45)
|
|
10379
|
+
},
|
|
10380
|
+
tooltipButton: {
|
|
10381
|
+
color: muted2,
|
|
10382
|
+
backgroundColor: colorWithAlpha(foreground, 0.08),
|
|
10383
|
+
border: `1px solid ${colorWithAlpha(foreground, 0.2)}`
|
|
10328
10384
|
}
|
|
10329
10385
|
};
|
|
10330
10386
|
for (const key of LIGHT_INTERACTIVE_SURFACE_KEYS) {
|
|
@@ -10471,7 +10527,8 @@ var OnboardModal = ({
|
|
|
10471
10527
|
showSaveBackupOption = true,
|
|
10472
10528
|
onSaveBackupChange,
|
|
10473
10529
|
onManualAesKeySubmit,
|
|
10474
|
-
|
|
10530
|
+
warnings,
|
|
10531
|
+
runtimeWarnings,
|
|
10475
10532
|
theme
|
|
10476
10533
|
}) => {
|
|
10477
10534
|
const [copied, setCopied] = (0, import_react27.useState)(false);
|
|
@@ -10517,6 +10574,15 @@ var OnboardModal = ({
|
|
|
10517
10574
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: styles2.iconContainer, children: icon }),
|
|
10518
10575
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { id: "onboard-modal-title", style: styles2.title, children: title })
|
|
10519
10576
|
] });
|
|
10577
|
+
const renderPageWarning = (page) => {
|
|
10578
|
+
const message = resolveOnboardPageWarning(page, {
|
|
10579
|
+
warnings,
|
|
10580
|
+
runtimeWarnings,
|
|
10581
|
+
saveBackup
|
|
10582
|
+
});
|
|
10583
|
+
if (!message) return null;
|
|
10584
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: warningStyles.box, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: warningStyles.text, children: message }) });
|
|
10585
|
+
};
|
|
10520
10586
|
const renderSaveLocallyOption = () => {
|
|
10521
10587
|
if (!showSaveBackupOption) return null;
|
|
10522
10588
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
@@ -10528,29 +10594,26 @@ var OnboardModal = ({
|
|
|
10528
10594
|
},
|
|
10529
10595
|
children: [
|
|
10530
10596
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: styles2.saveOptionIconWrap, "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime.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" }) }) }),
|
|
10531
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
10532
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
10533
|
-
|
|
10534
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
10535
|
-
|
|
10536
|
-
|
|
10537
|
-
|
|
10538
|
-
|
|
10539
|
-
|
|
10540
|
-
|
|
10541
|
-
|
|
10542
|
-
|
|
10543
|
-
|
|
10544
|
-
|
|
10545
|
-
|
|
10546
|
-
|
|
10547
|
-
|
|
10548
|
-
|
|
10549
|
-
|
|
10550
|
-
|
|
10551
|
-
] }),
|
|
10552
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: styles2.saveOptionDescription, children: "Encrypted locally. Restore via wallet signature." })
|
|
10553
|
-
] }),
|
|
10597
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: styles2.saveOptionBody, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles2.saveOptionTitleRow, children: [
|
|
10598
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: styles2.saveOptionTitle, children: "Save Locally" }),
|
|
10599
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: styles2.tooltipWrap, children: [
|
|
10600
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
10601
|
+
"button",
|
|
10602
|
+
{
|
|
10603
|
+
type: "button",
|
|
10604
|
+
"aria-label": "How local save works",
|
|
10605
|
+
"aria-describedby": showBackupTooltip ? "backup-details-tooltip" : void 0,
|
|
10606
|
+
onMouseEnter: () => setShowBackupTooltip(true),
|
|
10607
|
+
onMouseLeave: () => setShowBackupTooltip(false),
|
|
10608
|
+
onFocus: () => setShowBackupTooltip(true),
|
|
10609
|
+
onBlur: () => setShowBackupTooltip(false),
|
|
10610
|
+
style: styles2.tooltipButton,
|
|
10611
|
+
children: "?"
|
|
10612
|
+
}
|
|
10613
|
+
),
|
|
10614
|
+
showBackupTooltip && /* @__PURE__ */ (0, import_jsx_runtime.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." })
|
|
10615
|
+
] })
|
|
10616
|
+
] }) }),
|
|
10554
10617
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
10555
10618
|
"button",
|
|
10556
10619
|
{
|
|
@@ -10746,7 +10809,7 @@ var OnboardModal = ({
|
|
|
10746
10809
|
"Onboard User"
|
|
10747
10810
|
),
|
|
10748
10811
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { id: "onboard-modal-description", style: styles2.description, children: "This will execute a transaction on the COTI Network to retrieve your encryption key." }),
|
|
10749
|
-
|
|
10812
|
+
renderPageWarning("intro"),
|
|
10750
10813
|
renderSaveLocallyOption(),
|
|
10751
10814
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
10752
10815
|
"div",
|
|
@@ -10763,7 +10826,7 @@ var OnboardModal = ({
|
|
|
10763
10826
|
type: "text",
|
|
10764
10827
|
value: manualAesKey,
|
|
10765
10828
|
onChange: (event) => setManualAesKey(event.target.value),
|
|
10766
|
-
placeholder: "Paste
|
|
10829
|
+
placeholder: "Paste key",
|
|
10767
10830
|
"aria-label": "Manual AES key",
|
|
10768
10831
|
disabled: isSubmittingManualKey,
|
|
10769
10832
|
style: { ...styles2.manualKeyInput, ...styles2.actionPrimary },
|
|
@@ -10837,7 +10900,7 @@ var OnboardModal = ({
|
|
|
10837
10900
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: styles2.spinner }),
|
|
10838
10901
|
getProgressTitle(currentStep)
|
|
10839
10902
|
),
|
|
10840
|
-
|
|
10903
|
+
renderPageWarning("progress"),
|
|
10841
10904
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: styles2.stepperContainer, children: displaySteps.map((step) => {
|
|
10842
10905
|
const status = getOnboardingStepStatus(step.id, currentStep, !!error, includePersistStep);
|
|
10843
10906
|
const isActive = status === "active";
|
|
@@ -10935,12 +10998,7 @@ var OnboardModal = ({
|
|
|
10935
10998
|
)
|
|
10936
10999
|
] })
|
|
10937
11000
|
] }),
|
|
10938
|
-
|
|
10939
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: "Important:" }),
|
|
10940
|
-
" ",
|
|
10941
|
-
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."
|
|
10942
|
-
] }) }),
|
|
10943
|
-
warning && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: warningStyles.box, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: warningStyles.text, children: warning }) }),
|
|
11001
|
+
renderPageWarning("success"),
|
|
10944
11002
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
10945
11003
|
"button",
|
|
10946
11004
|
{
|
|
@@ -10974,6 +11032,7 @@ var OnboardModal = ({
|
|
|
10974
11032
|
),
|
|
10975
11033
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { id: "onboard-modal-description", style: styles2.description, children: "The onboarding process encountered an error. You can retry the signature request." }),
|
|
10976
11034
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: styles2.errorBox, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: styles2.errorText, children: error || "An unknown error occurred" }) }),
|
|
11035
|
+
renderPageWarning("error"),
|
|
10977
11036
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
10978
11037
|
"button",
|
|
10979
11038
|
{
|
|
@@ -11084,14 +11143,14 @@ function keepForwardContractProgress(previous, next) {
|
|
|
11084
11143
|
return nextOrder >= previousOrder ? next : previous;
|
|
11085
11144
|
}
|
|
11086
11145
|
function usePrivateUnlockController(options = {}) {
|
|
11087
|
-
const { theme,
|
|
11146
|
+
const { theme, warnings, onUnlocked, onRestoreCancelled, onOnboardingCancelled } = options;
|
|
11088
11147
|
const unlock = usePrivacyBridgeUnlock();
|
|
11089
11148
|
const wallet = usePrivacyBridgeWallet();
|
|
11090
11149
|
const walletTypeInfo = useWalletType();
|
|
11091
11150
|
const [showOnboardModal, setShowOnboardModal] = (0, import_react28.useState)(false);
|
|
11092
11151
|
const [isUnlocking, setIsUnlocking] = (0, import_react28.useState)(false);
|
|
11093
11152
|
const [modalError, setModalError] = (0, import_react28.useState)(null);
|
|
11094
|
-
const [
|
|
11153
|
+
const [modalRuntimeWarnings, setModalRuntimeWarnings] = (0, import_react28.useState)({});
|
|
11095
11154
|
const [snapConnectedInModal, setSnapConnectedInModal] = (0, import_react28.useState)(false);
|
|
11096
11155
|
const [saveBackup, setSaveBackup] = (0, import_react28.useState)(true);
|
|
11097
11156
|
const [currentStep, setCurrentStep] = (0, import_react28.useState)("idle");
|
|
@@ -11128,7 +11187,7 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11128
11187
|
pendingActionOwnerRef.current = null;
|
|
11129
11188
|
setCurrentStep("idle");
|
|
11130
11189
|
setModalError(null);
|
|
11131
|
-
|
|
11190
|
+
setModalRuntimeWarnings({});
|
|
11132
11191
|
backupSaveProgressStartedAtRef.current = null;
|
|
11133
11192
|
pendingCompleteRequestIdRef.current = null;
|
|
11134
11193
|
contractOnboardingCancelledRef.current = false;
|
|
@@ -11157,7 +11216,7 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11157
11216
|
setShowOnboardModal(false);
|
|
11158
11217
|
setCurrentStep("idle");
|
|
11159
11218
|
setModalError(null);
|
|
11160
|
-
|
|
11219
|
+
setModalRuntimeWarnings({});
|
|
11161
11220
|
setIsUnlockInProgress(false);
|
|
11162
11221
|
setIsUnlocking(false);
|
|
11163
11222
|
backupSaveProgressStartedAtRef.current = null;
|
|
@@ -11182,7 +11241,7 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11182
11241
|
setShowOnboardModal(false);
|
|
11183
11242
|
setCurrentStep("idle");
|
|
11184
11243
|
setModalError(null);
|
|
11185
|
-
|
|
11244
|
+
setModalRuntimeWarnings({});
|
|
11186
11245
|
unlockInProgressOwnerRef.current = null;
|
|
11187
11246
|
setIsUnlockInProgress(false);
|
|
11188
11247
|
setIsUnlocking(false);
|
|
@@ -11218,14 +11277,18 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11218
11277
|
try {
|
|
11219
11278
|
const connected = await unlock.requestSnapConnection();
|
|
11220
11279
|
if (!connected) {
|
|
11221
|
-
|
|
11280
|
+
setModalRuntimeWarnings({
|
|
11281
|
+
intro: "Snap connection was skipped or rejected. Continuing without Snap storage."
|
|
11282
|
+
});
|
|
11222
11283
|
return false;
|
|
11223
11284
|
}
|
|
11224
11285
|
snapConnectedInModalRef.current = true;
|
|
11225
11286
|
setSnapConnectedInModal(true);
|
|
11226
11287
|
return true;
|
|
11227
11288
|
} catch {
|
|
11228
|
-
|
|
11289
|
+
setModalRuntimeWarnings({
|
|
11290
|
+
intro: "Snap connection failed. Continuing without Snap storage."
|
|
11291
|
+
});
|
|
11229
11292
|
return false;
|
|
11230
11293
|
}
|
|
11231
11294
|
}, [canAttemptSnapInstall, unlock]);
|
|
@@ -11259,15 +11322,13 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11259
11322
|
if (failureMessage) {
|
|
11260
11323
|
setCurrentStep("error");
|
|
11261
11324
|
setModalError(failureMessage);
|
|
11262
|
-
setModalWarning(unlock.onboardingWarning ?? null);
|
|
11263
11325
|
releaseUnlockInProgress(requestId);
|
|
11264
11326
|
return;
|
|
11265
11327
|
}
|
|
11266
11328
|
setCurrentStep("error");
|
|
11267
11329
|
setModalError("Onboarding did not complete. Please retry.");
|
|
11268
|
-
setModalWarning(unlock.onboardingWarning ?? null);
|
|
11269
11330
|
releaseUnlockInProgress(requestId);
|
|
11270
|
-
}, [dismissOnboardModal, isActiveUnlockRequest, onOnboardingCancelled, releaseUnlockInProgress
|
|
11331
|
+
}, [dismissOnboardModal, isActiveUnlockRequest, onOnboardingCancelled, releaseUnlockInProgress]);
|
|
11271
11332
|
const handleStaleRestoreCompletion = (0, import_react28.useCallback)((requestId, refreshSucceeded) => {
|
|
11272
11333
|
clearPendingActionForRequest(requestId);
|
|
11273
11334
|
const unlocked = refreshSucceeded || isPrivateUnlockedRef.current;
|
|
@@ -11283,7 +11344,7 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11283
11344
|
setPendingActionForRequest(requestId, pendingAction);
|
|
11284
11345
|
}
|
|
11285
11346
|
setModalError(null);
|
|
11286
|
-
|
|
11347
|
+
setModalRuntimeWarnings({});
|
|
11287
11348
|
inFlightRestoreRequestIdRef.current = requestId;
|
|
11288
11349
|
setIsUnlocking(true);
|
|
11289
11350
|
try {
|
|
@@ -11317,7 +11378,6 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11317
11378
|
return false;
|
|
11318
11379
|
}
|
|
11319
11380
|
setCurrentStep("idle");
|
|
11320
|
-
setModalWarning(unlock.onboardingWarning ?? null);
|
|
11321
11381
|
setShowOnboardModal(true);
|
|
11322
11382
|
return false;
|
|
11323
11383
|
} catch (error) {
|
|
@@ -11379,7 +11439,6 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11379
11439
|
contractOnboardingFailureRef.current = failureMessage;
|
|
11380
11440
|
setCurrentStep("error");
|
|
11381
11441
|
setModalError(failureMessage);
|
|
11382
|
-
setModalWarning(unlock.onboardingWarning ?? null);
|
|
11383
11442
|
releaseUnlockInProgress(unlockRequestIdRef.current);
|
|
11384
11443
|
}
|
|
11385
11444
|
return;
|
|
@@ -11391,7 +11450,7 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11391
11450
|
if (step === "idle") {
|
|
11392
11451
|
setModalError(null);
|
|
11393
11452
|
}
|
|
11394
|
-
}, [currentStep, showOnboardModal, releaseUnlockInProgress
|
|
11453
|
+
}, [currentStep, showOnboardModal, releaseUnlockInProgress]);
|
|
11395
11454
|
const showOnboardingComplete = (0, import_react28.useCallback)((requestId) => {
|
|
11396
11455
|
if (!isActiveUnlockRequest(requestId)) return;
|
|
11397
11456
|
pendingCompleteRequestIdRef.current = null;
|
|
@@ -11409,7 +11468,7 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11409
11468
|
if (!connectedAddress) return;
|
|
11410
11469
|
const requestId = unlockRequestIdRef.current;
|
|
11411
11470
|
setModalError(null);
|
|
11412
|
-
|
|
11471
|
+
setModalRuntimeWarnings({});
|
|
11413
11472
|
setIsUnlocking(true);
|
|
11414
11473
|
setShowOnboardModal(true);
|
|
11415
11474
|
setCurrentStep("preparing-onboard");
|
|
@@ -11444,7 +11503,7 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11444
11503
|
currentStep,
|
|
11445
11504
|
hasSessionAesKey: !!unlock.sessionAesKey,
|
|
11446
11505
|
hasOnboardingError: !!unlock.onboardingError,
|
|
11447
|
-
hasOnboardingWarning:
|
|
11506
|
+
hasOnboardingWarning: hasOnboardModalWarnings(unlock.onboardingWarnings)
|
|
11448
11507
|
});
|
|
11449
11508
|
const backupSaveProgressStartedAt = backupSaveProgressStartedAtRef.current;
|
|
11450
11509
|
if (backupSaveProgressStartedAt !== null) {
|
|
@@ -11560,7 +11619,7 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11560
11619
|
onSaveBackupChange: setSaveBackup,
|
|
11561
11620
|
onManualAesKeySubmit: async (aesKey, { saveBackup: shouldSaveBackup }) => {
|
|
11562
11621
|
const requestId = unlockRequestIdRef.current;
|
|
11563
|
-
|
|
11622
|
+
setModalRuntimeWarnings({});
|
|
11564
11623
|
const manualSaveResult = await unlock.saveManualAesKey(aesKey, {
|
|
11565
11624
|
saveBackup: shouldSaveBackup,
|
|
11566
11625
|
onProgress: (step) => {
|
|
@@ -11581,7 +11640,7 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11581
11640
|
return;
|
|
11582
11641
|
}
|
|
11583
11642
|
if (manualSaveResult.backupWarning) {
|
|
11584
|
-
|
|
11643
|
+
setModalRuntimeWarnings({ success: manualSaveResult.backupWarning });
|
|
11585
11644
|
setShowOnboardModal(true);
|
|
11586
11645
|
setCurrentStep("complete");
|
|
11587
11646
|
releaseUnlockInProgress(requestId);
|
|
@@ -11590,7 +11649,8 @@ function usePrivateUnlockController(options = {}) {
|
|
|
11590
11649
|
await completeUnlock(requestId);
|
|
11591
11650
|
},
|
|
11592
11651
|
theme,
|
|
11593
|
-
|
|
11652
|
+
warnings,
|
|
11653
|
+
runtimeWarnings: mergeOnboardModalWarnings(unlock.onboardingWarnings, modalRuntimeWarnings)
|
|
11594
11654
|
}
|
|
11595
11655
|
);
|
|
11596
11656
|
return {
|
|
@@ -11763,7 +11823,7 @@ var PrivacyBridgeProvider = ({
|
|
|
11763
11823
|
decryptPrivateValue: session.decryptPrivateValue,
|
|
11764
11824
|
refreshPrivateBalances: session.refreshPrivateBalances,
|
|
11765
11825
|
onboardingError: session.onboardingError,
|
|
11766
|
-
|
|
11826
|
+
onboardingWarnings: session.onboardingWarnings,
|
|
11767
11827
|
lockPrivateBalances: session.lockPrivateBalances,
|
|
11768
11828
|
handleOnboard: session.handleOnboard,
|
|
11769
11829
|
saveManualAesKey: session.saveManualAesKey,
|