Page MenuHomePhabricator

D15867.diff
No OneTemporary

D15867.diff

diff --git a/cashtab/package-lock.json b/cashtab/package-lock.json
--- a/cashtab/package-lock.json
+++ b/cashtab/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "cashtab",
- "version": "2.18.5",
+ "version": "2.19.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "cashtab",
- "version": "2.18.5",
+ "version": "2.19.0",
"dependencies": {
"@ant-design/icons": "^5.3.0",
"@bitgo/utxo-lib": "^9.33.0",
diff --git a/cashtab/package.json b/cashtab/package.json
--- a/cashtab/package.json
+++ b/cashtab/package.json
@@ -1,6 +1,6 @@
{
"name": "cashtab",
- "version": "2.18.5",
+ "version": "2.19.0",
"private": true,
"scripts": {
"start": "node scripts/start.js",
diff --git a/cashtab/src/components/App/App.js b/cashtab/src/components/App/App.js
--- a/cashtab/src/components/App/App.js
+++ b/cashtab/src/components/App/App.js
@@ -11,6 +11,7 @@
ReceiveIcon,
SettingsIcon,
AirdropIcon,
+ WalletIcon,
ThemedSignAndVerifyMsg,
ThemedUserProfileIcon,
SwapIcon,
@@ -24,6 +25,7 @@
import SendXec from 'components/Send/SendXec';
import SendToken from 'components/Send/SendToken';
import Airdrop from 'components/Airdrop/Airdrop';
+import BackupWallet from 'components/BackupWallet/BackupWallet';
import Alias from 'components/Alias/Alias';
import Etokens from 'components/Etokens/Etokens';
import Configure from 'components/Configure/Configure';
@@ -554,6 +556,13 @@
<AirdropIcon />
</NavHeader>
)}
+ {selectedKey ===
+ 'backup' && (
+ <NavHeader>
+ Wallet Backup
+ <WalletIcon />
+ </NavHeader>
+ )}
{selectedKey ===
'configure' && (
<NavHeader>
@@ -658,6 +667,12 @@
/>
}
/>
+ <Route
+ path="/backup"
+ element={
+ <BackupWallet />
+ }
+ />
<Route
path="/etokens"
@@ -760,6 +775,15 @@
data-testid="hamburger-menu"
open={navMenuClicked}
>
+ <NavItem
+ data-testid="nav-btn-backup"
+ active={selectedKey === 'backup'}
+ onClick={() => navigate('/backup')}
+ >
+ {' '}
+ <p>Wallet Backup</p>
+ <WalletIcon />
+ </NavItem>
<NavItem
data-testid="nav-btn-airdrop"
active={selectedKey === 'airdrop'}
diff --git a/cashtab/src/components/App/__tests__/App.test.js b/cashtab/src/components/App/__tests__/App.test.js
--- a/cashtab/src/components/App/__tests__/App.test.js
+++ b/cashtab/src/components/App/__tests__/App.test.js
@@ -259,6 +259,16 @@
// Now we see the Settings screen
expect(screen.getByTestId('configure-ctn')).toBeInTheDocument();
+
+ // Navigate to Backup screen
+ await user.click(screen.queryByTestId('nav-btn-backup'));
+
+ // Now we see the Backup screen
+ expect(
+ screen.getByText(
+ `ℹ️ Your seed phrase is the only way to restore your wallet. Write it down. Keep it safe.`,
+ ),
+ ).toBeInTheDocument();
});
it('Adding a contact to to a new contactList by clicking on tx history adds it to localforage and wallet context', async () => {
const mockedChronik = await initializeCashtabStateForTests(
diff --git a/cashtab/src/components/BackupWallet/BackupWallet.js b/cashtab/src/components/BackupWallet/BackupWallet.js
new file mode 100644
--- /dev/null
+++ b/cashtab/src/components/BackupWallet/BackupWallet.js
@@ -0,0 +1,93 @@
+// Copyright (c) 2024 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+import React, { useState } from 'react';
+import { WalletContext } from 'wallet/context';
+import styled from 'styled-components';
+import CopyToClipboard from 'components/Common/CopyToClipboard';
+import Seed from 'components/Common/Seed';
+import Switch from 'components/Common/Switch';
+import { getUserLocale } from 'helpers';
+import { Alert, Info } from 'components/Common/Atoms';
+
+const BackupFlex = styled.div`
+ margin: 12px 0;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 48px;
+ color: ${props => props.theme.contrast};
+ justify-content: flex-start;
+`;
+const FlexRow = styled.div`
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 12px;
+`;
+const SwitchRow = styled.div`
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+ width: 100%;
+ gap: 12px;
+`;
+const SwitchLabel = styled.div``;
+
+const BackupWallet = () => {
+ const ContextValue = React.useContext(WalletContext);
+ const { cashtabState } = ContextValue;
+ const { wallets } = cashtabState;
+
+ const userLocale = getUserLocale(navigator);
+ const [showSeed, setShowSeed] = useState(false);
+
+ const wallet = wallets.length > 0 ? wallets[0] : false;
+
+ return (
+ <BackupFlex>
+ <FlexRow>
+ <Info>
+ ℹ️ Your seed phrase is the only way to restore your wallet.
+ Write it down. Keep it safe.
+ </Info>
+ </FlexRow>
+ <FlexRow>
+ <Alert className="notranslate">
+ <b>
+ ⚠️ NEVER SHARE YOUR SEED PHRASE
+ {!userLocale.includes('en-') && (
+ <>
+ <br />
+ <br />
+ ⚠️ STORE YOUR SEED PHRASE IN ENGLISH
+ </>
+ )}
+ </b>
+ </Alert>
+ </FlexRow>
+ <SwitchRow>
+ <Switch
+ name="send-confirmations-switch"
+ checked={showSeed}
+ handleToggle={() => setShowSeed(!showSeed)}
+ />
+ <SwitchLabel>I understand, show me my seed phrase.</SwitchLabel>
+ </SwitchRow>
+ <FlexRow>
+ {showSeed && (
+ <CopyToClipboard
+ data={wallet.mnemonic}
+ showToast
+ customMsg={'Copied seed phrase'}
+ >
+ <Seed mnemonic={wallet.mnemonic} />
+ </CopyToClipboard>
+ )}
+ </FlexRow>
+ </BackupFlex>
+ );
+};
+
+export default BackupWallet;
diff --git a/cashtab/src/components/Common/Atoms.js b/cashtab/src/components/Common/Atoms.js
--- a/cashtab/src/components/Common/Atoms.js
+++ b/cashtab/src/components/Common/Atoms.js
@@ -74,3 +74,16 @@
color: ${props => props.theme.contrast};
font-size: 18px;
`;
+
+export const Alert = styled.div`
+ background-color: #fff2f0;
+ border-radius: 12px;
+ color: red;
+ padding: 12px;
+`;
+export const Info = styled.div`
+ background-color: #fff2f0;
+ border-radius: 12px;
+ color: ${props => props.theme.eCashBlue};
+ padding: 12px;
+`;
diff --git a/cashtab/src/components/Common/CustomIcons.js b/cashtab/src/components/Common/CustomIcons.js
--- a/cashtab/src/components/Common/CustomIcons.js
+++ b/cashtab/src/components/Common/CustomIcons.js
@@ -141,6 +141,9 @@
export const ThemedSignAndVerifyMsg = styled(Audit)`
min-width: 24px;
`;
+export const WalletIcon = styled(ThemedWalletOutlined)`
+ min-width: 24px;
+`;
export const ThemedUserProfileIcon = styled(User)`
height: 33px;
diff --git a/cashtab/src/components/Configure/Configure.js b/cashtab/src/components/Configure/Configure.js
--- a/cashtab/src/components/Configure/Configure.js
+++ b/cashtab/src/components/Configure/Configure.js
@@ -5,7 +5,7 @@
import React, { useState, useEffect } from 'react';
import styled from 'styled-components';
import { useLocation, Link } from 'react-router-dom';
-import { Collapse, Form, Alert, Tooltip, Checkbox } from 'antd';
+import { Collapse, Form, Tooltip } from 'antd';
import { Row, Col } from 'antd';
import { LockFilled } from '@ant-design/icons';
import { WalletContext } from 'wallet/context';
@@ -18,7 +18,6 @@
SecondaryButton,
} from 'components/Common/PrimaryButton';
import {
- ThemedCopyOutlined,
ThemedWalletOutlined,
ThemedDollarOutlined,
ThemedSettingOutlined,
@@ -29,7 +28,6 @@
ThemedCopySolid,
ThemedTrashcanOutlined,
ThemedEditOutlined,
- WarningIcon,
ThemedXIcon,
ThemedFacebookIcon,
ThemedGithubIcon,
@@ -59,7 +57,7 @@
import { toast } from 'react-toastify';
import { Input, ModalInput, InputFlex } from 'components/Common/Inputs';
import Switch from 'components/Common/Switch';
-import Seed from 'components/Common/Seed';
+import { Info } from 'components/Common/Atoms';
const { Panel } = Collapse;
@@ -375,26 +373,22 @@
`;
const StyledConfigure = styled.div`
+ margin: 12px 0;
h2 {
color: ${props => props.theme.contrast};
font-size: 25px;
}
svg {
fill: ${props => props.theme.eCashBlue};
-
}
p {
color: ${props => props.theme.darkBlue};
}
- .ant-alert {
- color: ${props => props.theme.lightGrey}
- font-size: 14px;
- }
- .ant-collapse-header{
- .anticon{
+ .ant-collapse-header {
+ .anticon {
flex: 1;
}
- .seedPhrase{
+ .seedPhrase {
flex: 2;
}
}
@@ -463,8 +457,6 @@
const [walletDeleteConfirmationError, setWalletDeleteConfirmationError] =
useState(false);
const [seedInput, openSeedInput] = useState(false);
- const [revealSeed, setRevealSeed] = useState(false);
- const [showTranslationWarning, setShowTranslationWarning] = useState(false);
const [savedWalletContactModal, setSavedWalletContactModal] =
useState(false);
@@ -547,11 +539,6 @@
};
useEffect(() => {
- const detectedBrowserLang = navigator.language;
- if (!detectedBrowserLang.includes('en-')) {
- setShowTranslationWarning(true);
- }
-
handleContactListRouting();
}, []);
@@ -1229,70 +1216,12 @@
/>
</CustomModal>
)}
- <h2>
- <ThemedCopyOutlined /> Backup your wallet
- </h2>
- <Alert
- style={{ marginBottom: '12px' }}
- description="Your seed phrase is the only way to restore your wallet. Write it down. Keep it safe."
- type="warning"
- showIcon
- />
- {showTranslationWarning && (
- <Alert
- style={{ marginBottom: '12px' }}
- description="Please do not translate your seed phrase. Store your seed phrase in English. You must re-enter these exact English words to restore your wallet from seed."
- type="warning"
- showIcon
- />
- )}
- {wallet && wallet.mnemonic && (
- <StyledCollapse expandIconPosition="start">
- <Panel
- header={
- <div className="seedPhrase">
- Click to reveal seed phrase
- </div>
- }
- >
- <p
- className="notranslate"
- style={{ userSelect: 'text' }}
- >
- {
- <>
- <WarningIcon />
- <br />
- <b>NEVER</b> share your seed phrase.
- <br />
- <b>DO NOT</b> enter it into 3rd party
- websites.
- <br />
- <br />
- <Checkbox
- onChange={() => {
- setRevealSeed(!revealSeed);
- }}
- >
- I understand, show me my seed phrase.
- </Checkbox>
- <br />
- </>
- }
- </p>
- {wallet && wallet.mnemonic && revealSeed && (
- <CopyToClipboard
- data={wallet.mnemonic}
- showToast
- customMsg={'Copied seed phrase'}
- >
- <Seed mnemonic={wallet.mnemonic} />
- </CopyToClipboard>
- )}
- </Panel>
- </StyledCollapse>
- )}
- <StyledSpacer />
+ <Info>
+ ℹ️ Backup wallet has moved
+ <br />
+ <br /> Go to the <Link to="/backup">Backup Wallet</Link> screen
+ to see your seed phrase
+ </Info>
<h2>
<ThemedWalletOutlined /> Manage Wallets
</h2>
diff --git a/cashtab/src/components/Home/Home.js b/cashtab/src/components/Home/Home.js
--- a/cashtab/src/components/Home/Home.js
+++ b/cashtab/src/components/Home/Home.js
@@ -10,6 +10,7 @@
import ApiError from 'components/Common/ApiError';
import { getWalletState } from 'utils/cashMethods';
import Receive from 'components/Receive/Receive';
+import { Alert } from 'components/Common/Atoms';
export const Tabs = styled.div`
margin: auto;
@@ -113,13 +114,6 @@
padding: 6px 0 12px 0;
`;
-const BackupWalletAlert = styled.div`
- background-color: #fff2f0;
- border-radius: 12px;
- color: red;
- padding: 12px;
-`;
-
const Home = () => {
const ContextValue = React.useContext(WalletContext);
const { fiatPrice, apiError, cashtabState } = ContextValue;
@@ -145,7 +139,7 @@
/>
{!hasHistory && (
<>
- <BackupWalletAlert>
+ <Alert>
<p>
<b>Backup your wallet</b>
</p>
@@ -154,7 +148,7 @@
safe place.{' '}
<em>Do not share your backup with anyone.</em>
</p>
- </BackupWalletAlert>
+ </Alert>
<Receive />
</>
)}

File Metadata

Mime Type
text/plain
Expires
Sat, Mar 1, 10:18 (8 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5187323
Default Alt Text
D15867.diff (16 KB)

Event Timeline