From 524eb8c0f8f0399310f30fe606509e87ec977546 Mon Sep 17 00:00:00 2001 From: netbonus <151201453+netbonus@users.noreply.github.com> Date: Wed, 28 Jan 2026 13:42:08 -0500 Subject: [PATCH] feat: add seed phrase security warning banner Add dismissable warning banner to key pages reminding users that GridPlus will never ask for seed phrases, private keys, or recovery words. Warning uses sessionStorage so it reappears each browser session. - Create SeedPhraseWarning component with Ant Design Alert - Add warning to Connect, Pair, Landing, and Settings pages - Store acknowledgment in sessionStorage (per-session) - Install missing bs58check dependency --- package-lock.json | 1 + src/components/SeedPhraseWarning.tsx | 28 ++++++++++++++++++++++++++++ src/components/connect.tsx | 2 ++ src/components/landing.tsx | 2 ++ src/components/pair.tsx | 2 ++ src/components/settings.tsx | 2 ++ src/util/localStorage.ts | 12 ++++++++++++ 7 files changed, 49 insertions(+) create mode 100644 src/components/SeedPhraseWarning.tsx diff --git a/package-lock.json b/package-lock.json index 1a93c36..7b31ec6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3051,6 +3051,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "license": "MIT", "dependencies": { "bs58": "^4.0.0", "create-hash": "^1.1.0", diff --git a/src/components/SeedPhraseWarning.tsx b/src/components/SeedPhraseWarning.tsx new file mode 100644 index 0000000..1b79ea1 --- /dev/null +++ b/src/components/SeedPhraseWarning.tsx @@ -0,0 +1,28 @@ +import React, { useState } from "react"; +import { Alert } from "antd"; +import localStorage from "../util/localStorage"; + +const WARNING_MESSAGE = + "GridPlus will never ask for your seed phrase, private keys, or recovery words. If asked, you may be on a phishing site."; + +export const SeedPhraseWarning = ({ style }: { style?: React.CSSProperties }) => { + const [visible, setVisible] = useState( + !localStorage.getSeedWarningAcknowledged() + ); + + if (!visible) return null; + + return ( + { + localStorage.setSeedWarningAcknowledged(); + setVisible(false); + }} + style={{ marginBottom: "16px", textAlign: "left", ...style }} + /> + ); +}; diff --git a/src/components/connect.tsx b/src/components/connect.tsx index a481eaf..81c8fca 100644 --- a/src/components/connect.tsx +++ b/src/components/connect.tsx @@ -2,6 +2,7 @@ import React from "react"; import { Alert, Button, Card, Col, Input, Row, Modal } from "antd"; import { DesktopOutlined, LinkOutlined } from "@ant-design/icons"; import { Settings } from "./index"; +import { SeedPhraseWarning } from "./SeedPhraseWarning"; import { constants } from "../util/helpers"; import { NameEditor } from "./NameEditor"; import { LoginData } from "../types/authentication"; @@ -362,6 +363,7 @@ class Connect extends React.Component { /> ) : null} + {this.renderMsg()} {tooLong ? (

diff --git a/src/components/landing.tsx b/src/components/landing.tsx index 3969c2c..73b114e 100644 --- a/src/components/landing.tsx +++ b/src/components/landing.tsx @@ -16,6 +16,7 @@ import React from "react"; import { useFeature } from "../hooks/useFeature"; import { PageContent } from "./index"; import { LandingCard } from "./LandingCard"; +import { SeedPhraseWarning } from "./SeedPhraseWarning"; const Landing = ({ goToPage }) => { const { USES_AUTO_ABI } = useFeature(); @@ -37,6 +38,7 @@ const Landing = ({ goToPage }) => { justifyItems: "center", }} > +

{ const content = (
+

Please enter the pairing secret displayed on your Lattice screen:

{ renderCard() { return (
+ {this.renderKeyringsSetting()} {this.renderCustomEndpointSetting()} {this.renderBitcoinVersionSetting()} diff --git a/src/util/localStorage.ts b/src/util/localStorage.ts index 35f6474..d80889d 100644 --- a/src/util/localStorage.ts +++ b/src/util/localStorage.ts @@ -43,6 +43,16 @@ const removeRootStoreItem = (key) => // #endregion +// #region -- Seed Phrase Warning Functions (sessionStorage - resets each browser session) + +const SEED_WARNING_KEY = "gridplus_seed_phrase_warning_ack"; +const getSeedWarningAcknowledged = (): boolean => + window.sessionStorage.getItem(SEED_WARNING_KEY) === "true"; +const setSeedWarningAcknowledged = (): void => + window.sessionStorage.setItem(SEED_WARNING_KEY, "true"); + +// #endregion + // #region -- Settings Functions const getSettings = () => getRootStoreItem("settings"); @@ -151,6 +161,8 @@ const exports = { getRootStoreItem, setRootStoreItem, removeRootStoreItem, + getSeedWarningAcknowledged, + setSeedWarningAcknowledged, getSettings, setSettings, getLoginId,