diff --git a/web/cashtab/src/components/App.css b/web/cashtab/src/components/App.css
index ce6fd4716..7578f5f4f 100644
--- a/web/cashtab/src/components/App.css
+++ b/web/cashtab/src/components/App.css
@@ -1,141 +1,61 @@
@import '~antd/dist/antd.less';
@import '~@fortawesome/fontawesome-free/css/all.css';
@import url('https://fonts.googleapis.com/css?family=Khula&display=swap&.css');
/* Hide up and down arros on input type="number" */
/* Chrome, Safari, Edge, Opera */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* Hide up and down arros on input type="number" */
/* Firefox */
input[type='number'] {
-moz-appearance: textfield;
}
html,
body {
max-width: 100%;
overflow-x: hidden;
}
/* Hide scroll bars on antd modals*/
.ant-modal-wrap.ant-modal-centered::-webkit-scrollbar {
display: none;
}
/* ITEMS BELOW TO BE MOVED TO STYLED COMPONENTS*/
/* useWallet.js, useBCH.js */
@media (max-width: 768px) {
.ant-notification {
width: 100%;
top: 20px !important;
max-width: unset;
margin-right: 0;
}
}
/* OK and Cancel button colors on Modals*/
.ant-card-actions > li > span:hover,
.ant-btn:hover,
.ant-btn:focus {
color: #f59332;
transition: color 0.3s;
background-color: white;
}
.ant-btn {
border-radius: 8px;
background-color: #fff;
color: rgb(62, 63, 66);
font-weight: bold;
}
-/*Custom Input Fields */
-input.ant-input,
-.ant-select-selection {
- background-color: #fff !important;
- box-shadow: none !important;
- border-radius: 4px;
- font-weight: bold;
- color: rgb(62, 63, 66);
- opacity: 1;
- height: 50px;
-}
-
-.ant-select-selection:hover {
- border: 1px solid #eaedf3;
-}
-
-.ant-select-selection-selected-value {
- color: rgb(62, 63, 66);
-}
-
-.ant-select-dropdown-menu-item {
- color: #444;
- background-color: #fff;
-}
-
-.ant-select-dropdown-menu-item-active,
-.ant-select-dropdown-menu-item:hover {
- color: #fff;
- background-color: #ff8d00 !important;
-}
+/*Hover on currency dropdowns */
.selectedCurrencyOption:hover {
color: #fff !important;
background-color: #ff8d00 !important;
}
-.ant-input-affix-wrapper {
- background-color: #fff;
- border: 1px solid #eaedf3 !important;
-}
-input.ant-input,
-.ant-select-selection {
- border: none;
-}
-.ant-input::placeholder {
- text-align: left;
-}
-.ant-select-selector {
- height: 60px !important;
- border: 1px solid #eaedf3 !important;
-}
-
-/*Revs with updated Antd*/
-.ant-select-single .ant-select-selector .ant-select-selection-item,
-.ant-select-single .ant-select-selector .ant-select-selection-placeholder {
- line-height: 60px;
- text-align: left;
- color: #3e3f42;
- font-weight: bold;
-}
-
-/* Handle new antd error formatting */
-.ant-form-item-has-error
- > div
- > div.ant-form-item-control-input
- > div
- > span
- > span
- > span.ant-input-affix-wrapper {
- background-color: #fff;
- border-color: #f04134 !important;
-}
-
-.ant-form-item-has-error .ant-input,
-.ant-form-item-has-error .ant-input-affix-wrapper,
-.ant-form-item-has-error .ant-input:hover,
-.ant-form-item-has-error .ant-input-affix-wrapper:hover {
- background-color: #fff;
- border-color: #f04134 !important;
-}
-
-.ant-form-item-has-error
- .ant-select:not(.ant-select-disabled):not(.ant-select-customize-input)
- .ant-select-selector {
- background-color: #fff;
- border-color: #f04134 !important;
-}
diff --git a/web/cashtab/src/components/Common/EnhancedInputs.js b/web/cashtab/src/components/Common/EnhancedInputs.js
index 9ae8a5b44..30062da44 100644
--- a/web/cashtab/src/components/Common/EnhancedInputs.js
+++ b/web/cashtab/src/components/Common/EnhancedInputs.js
@@ -1,208 +1,265 @@
import * as React from 'react';
import { Form, Input, Select } from 'antd';
import {
ThemedDollarOutlined,
ThemedWalletOutlined,
} from '@components/Common/CustomIcons';
import styled, { css } from 'styled-components/macro';
import { ScanQRCode } from './ScanQRCode';
import useBCH from '@hooks/useBCH';
import { currency } from '@components/Common/Ticker.js';
export const AntdFormCss = css`
.ant-input-group-addon {
background-color: ${props =>
props.theme.formAddonBackground} !important;
border: 1px solid ${props => props.theme.formBorders};
color: ${props => props.theme.formAddonForeground} !important;
}
+ input.ant-input,
+ .ant-select-selection {
+ background-color: #fff !important;
+ box-shadow: none !important;
+ border-radius: 4px;
+ font-weight: bold;
+ color: rgb(62, 63, 66);
+ opacity: 1;
+ height: 50px;
+ }
+ .ant-input-affix-wrapper {
+ background-color: #fff;
+ border: 1px solid #eaedf3 !important;
+ }
+ .ant-select-selector {
+ height: 60px !important;
+ border: 1px solid #eaedf3 !important;
+ }
+ .ant-form-item-has-error
+ > div
+ > div.ant-form-item-control-input
+ > div
+ > span
+ > span
+ > span.ant-input-affix-wrapper {
+ background-color: #fff;
+ border-color: #f04134 !important;
+ }
+
+ .ant-form-item-has-error .ant-input,
+ .ant-form-item-has-error .ant-input-affix-wrapper,
+ .ant-form-item-has-error .ant-input:hover,
+ .ant-form-item-has-error .ant-input-affix-wrapper:hover {
+ background-color: #fff;
+ border-color: #f04134 !important;
+ }
+
+ .ant-form-item-has-error
+ .ant-select:not(.ant-select-disabled):not(.ant-select-customize-input)
+ .ant-select-selector {
+ background-color: #fff;
+ border-color: #f04134 !important;
+ }
+ .ant-select-single .ant-select-selector .ant-select-selection-item,
+ .ant-select-single .ant-select-selector .ant-select-selection-placeholder {
+ line-height: 60px;
+ text-align: left;
+ color: #3e3f42;
+ font-weight: bold;
+ }
`;
+
export const AntdFormWrapper = styled.div`
${AntdFormCss}
`;
export const InputAddonText = styled.span`
width: 100%;
height: 100%;
display: block;
${props =>
props.disabled
? `
cursor: not-allowed;
`
: `cursor: pointer;`}
`;
export const InputNumberAddonText = styled.span`
background-color: ${props =>
props.theme.formAddonBackground} !important;
border: border: 1px solid ${props => props.theme.formBorders};
color: ${props => props.theme.formAddonForeground} !important;
height: 50px;
line-height: 47px;
* {
color: ${props => props.theme.formAddonForeground} !important;
}
${props =>
props.disabled
? `
cursor: not-allowed;
`
: `cursor: pointer;`}
`;
export const SendBchInput = ({
onMax,
inputProps,
selectProps,
...otherProps
}) => {
const { Option } = Select;
const currencies = [
{
value: currency.ticker,
label: currency.ticker,
},
{ value: 'USD', label: 'USD' },
];
const currencyOptions = currencies.map(currency => {
return (
{currency.label}
);
});
const CurrencySelect = (
{currencyOptions}
);
return (
-
-
-
- ) : (
-
- )
- }
- {...inputProps}
- />
- {CurrencySelect}
-
- max
-
-
-
+
+
+
+
+ ) : (
+
+ )
+ }
+ {...inputProps}
+ />
+ {CurrencySelect}
+
+ max
+
+
+
+
);
};
export const FormItemWithMaxAddon = ({ onMax, inputProps, ...otherProps }) => {
return (
}
addonAfter={
max
}
{...inputProps}
/>
);
};
// loadWithCameraOpen prop: if true, load page with camera scanning open
export const FormItemWithQRCodeAddon = ({
onScan,
loadWithCameraOpen,
inputProps,
...otherProps
}) => {
return (
}
autoComplete="off"
addonAfter={
}
{...inputProps}
/>
);
};
export const AddressValidators = () => {
const { BCH } = useBCH();
return {
safelyDetectAddressFormat: value => {
try {
return BCH.Address.detectAddressFormat(value);
} catch (error) {
return null;
}
},
isSLPAddress: value =>
AddressValidators.safelyDetectAddressFormat(value) === 'slpaddr',
isBCHAddress: value =>
AddressValidators.safelyDetectAddressFormat(value) === 'cashaddr',
isLegacyAddress: value =>
AddressValidators.safelyDetectAddressFormat(value) === 'legacy',
}();
};
diff --git a/web/cashtab/src/components/Configure/Configure.js b/web/cashtab/src/components/Configure/Configure.js
index 64ad4e137..0c9e876c4 100644
--- a/web/cashtab/src/components/Configure/Configure.js
+++ b/web/cashtab/src/components/Configure/Configure.js
@@ -1,589 +1,598 @@
/* eslint-disable react-hooks/exhaustive-deps */
import React, { useState, useEffect } from 'react';
import styled from 'styled-components';
import { Collapse, Form, Input, Modal, Spin, Alert } from 'antd';
import {
PlusSquareOutlined,
WalletFilled,
ImportOutlined,
LockOutlined,
} from '@ant-design/icons';
import { WalletContext } from '@utils/context';
import { StyledCollapse } from '@components/Common/StyledCollapse';
+import { AntdFormWrapper } from '@components/Common/EnhancedInputs';
import PrimaryButton, {
SecondaryButton,
SmartButton,
} from '@components/Common/PrimaryButton';
import {
CashLoader,
CashLoadingIcon,
ThemedCopyOutlined,
ThemedWalletOutlined,
} from '@components/Common/CustomIcons';
import { ReactComponent as Trashcan } from '@assets/trashcan.svg';
import { ReactComponent as Edit } from '@assets/edit.svg';
import { Event } from '@utils/GoogleAnalytics';
const { Panel } = Collapse;
const SettingsLink = styled.a`
text-decoration: underline;
color: #ff8d00;
:visited {
text-decoration: underline;
color: #ff8d00;
}
`;
const SWRow = styled.div`
border-radius: 3px;
padding: 10px 0;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 6px;
@media (max-width: 500px) {
flex-direction: column;
margin-bottom: 12px;
}
`;
const SWName = styled.div`
width: 50%;
display: flex;
align-items: center;
justify-content: space-between;
word-wrap: break-word;
hyphens: auto;
@media (max-width: 500px) {
width: 100%;
justify-content: center;
margin-bottom: 15px;
}
h3 {
font-size: 16px;
color: #444;
margin: 0;
text-align: left;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
`;
const SWButtonCtn = styled.div`
width: 50%;
display: flex;
align-items: center;
justify-content: flex-end;
@media (max-width: 500px) {
width: 100%;
justify-content: center;
}
button {
cursor: pointer;
@media (max-width: 768px) {
font-size: 14px;
}
}
svg {
stroke: #444;
fill: #444;
width: 25px;
height: 25px;
margin-right: 20px;
cursor: pointer;
:first-child:hover {
stroke: #ff8d00;
fill: #ff8d00;
}
:hover {
stroke: red;
fill: red;
}
}
`;
const AWRow = styled.div`
padding: 10px 0;
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 6px;
h3 {
font-size: 16px;
display: inline-block;
color: #444;
margin: 0;
text-align: left;
font-weight: bold;
@media (max-width: 500px) {
font-size: 14px;
}
}
h4 {
font-size: 16px;
display: inline-block;
color: #ff8d00 !important;
margin: 0;
text-align: right;
}
@media (max-width: 500px) {
flex-direction: column;
margin-bottom: 12px;
}
`;
const StyledConfigure = styled.div`
h2 {
color: #444;
font-size: 25px;
}
p {
color: #444;
}
`;
const StyledSpacer = styled.div`
height: 1px;
width: 100%;
background-color: #e2e2e2;
margin: 60px 0 50px;
`;
const Configure = () => {
const ContextValue = React.useContext(WalletContext);
const { wallet, loading, apiError } = ContextValue;
const {
addNewSavedWallet,
activateWallet,
renameWallet,
deleteWallet,
validateMnemonic,
getSavedWallets,
} = ContextValue;
const [savedWallets, setSavedWallets] = useState([]);
const [formData, setFormData] = useState({
dirty: true,
mnemonic: '',
});
const [showRenameWalletModal, setShowRenameWalletModal] = useState(false);
const [showDeleteWalletModal, setShowDeleteWalletModal] = useState(false);
const [walletToBeRenamed, setWalletToBeRenamed] = useState(null);
const [walletToBeDeleted, setWalletToBeDeleted] = useState(null);
const [newWalletName, setNewWalletName] = useState('');
const [
confirmationOfWalletToBeDeleted,
setConfirmationOfWalletToBeDeleted,
] = useState('');
const [newWalletNameIsValid, setNewWalletNameIsValid] = useState(null);
const [walletDeleteValid, setWalletDeleteValid] = useState(null);
const [seedInput, openSeedInput] = useState(false);
const showPopulatedDeleteWalletModal = walletInfo => {
setWalletToBeDeleted(walletInfo);
setShowDeleteWalletModal(true);
};
const showPopulatedRenameWalletModal = walletInfo => {
setWalletToBeRenamed(walletInfo);
setShowRenameWalletModal(true);
};
const cancelRenameWallet = () => {
// Delete form value
setNewWalletName('');
setShowRenameWalletModal(false);
};
const cancelDeleteWallet = () => {
setWalletToBeDeleted(null);
setConfirmationOfWalletToBeDeleted('');
setShowDeleteWalletModal(false);
};
const updateSavedWallets = async activeWallet => {
if (activeWallet) {
let savedWallets;
try {
savedWallets = await getSavedWallets(activeWallet);
setSavedWallets(savedWallets);
} catch (err) {
console.log(`Error in getSavedWallets()`);
console.log(err);
}
}
};
const [isValidMnemonic, setIsValidMnemonic] = useState(false);
useEffect(() => {
// Update savedWallets every time the active wallet changes
updateSavedWallets(wallet);
}, [wallet]);
// Need this function to ensure that savedWallets are updated on new wallet creation
const updateSavedWalletsOnCreate = async importMnemonic => {
// Event("Category", "Action", "Label")
// Track number of times a different wallet is activated
Event('Configure.js', 'Create Wallet', 'New');
const walletAdded = await addNewSavedWallet(importMnemonic);
if (!walletAdded) {
Modal.error({
title: 'This wallet already exists!',
content: 'Wallet not added',
});
} else {
Modal.success({
content: 'Wallet added to your saved wallets',
});
}
await updateSavedWallets(wallet);
};
// Same here
// TODO you need to lock UI here until this is complete
// Otherwise user may try to load an already-loading wallet, wreak havoc with indexedDB
const updateSavedWalletsOnLoad = async walletToActivate => {
// Event("Category", "Action", "Label")
// Track number of times a different wallet is activated
Event('Configure.js', 'Activate', '');
await activateWallet(walletToActivate);
await updateSavedWallets(wallet);
};
async function submit() {
setFormData({
...formData,
dirty: false,
});
// Exit if no user input
if (!formData.mnemonic) {
return;
}
// Exit if mnemonic is invalid
if (!isValidMnemonic) {
return;
}
// Event("Category", "Action", "Label")
// Track number of times a different wallet is activated
Event('Configure.js', 'Create Wallet', 'Imported');
updateSavedWalletsOnCreate(formData.mnemonic);
}
const handleChange = e => {
const { value, name } = e.target;
// Validate mnemonic on change
// Import button should be disabled unless mnemonic is valid
setIsValidMnemonic(validateMnemonic(value));
setFormData(p => ({ ...p, [name]: value }));
};
const changeWalletName = async () => {
if (newWalletName === '' || newWalletName.length > 24) {
setNewWalletNameIsValid(false);
return;
}
// Hide modal
setShowRenameWalletModal(false);
// Change wallet name
console.log(
`Changing wallet ${walletToBeRenamed.name} name to ${newWalletName}`,
);
const renameSuccess = await renameWallet(
walletToBeRenamed.name,
newWalletName,
);
if (renameSuccess) {
Modal.success({
content: `Wallet "${walletToBeRenamed.name}" renamed to "${newWalletName}"`,
});
} else {
Modal.error({
content: `Rename failed. All wallets must have a unique name.`,
});
}
await updateSavedWallets(wallet);
// Clear wallet name for form
setNewWalletName('');
};
const deleteSelectedWallet = async () => {
if (!walletDeleteValid) {
return;
}
if (
confirmationOfWalletToBeDeleted !==
`delete ${walletToBeDeleted.name}`
) {
setWalletDeleteValid(false);
return;
}
// Hide modal
setShowDeleteWalletModal(false);
// Change wallet name
console.log(`Deleting wallet "${walletToBeDeleted.name}"`);
const walletDeletedSuccess = await deleteWallet(walletToBeDeleted);
if (walletDeletedSuccess) {
Modal.success({
content: `Wallet "${walletToBeDeleted.name}" successfully deleted`,
});
} else {
Modal.error({
content: `Error deleting ${walletToBeDeleted.name}.`,
});
}
await updateSavedWallets(wallet);
// Clear wallet delete confirmation from form
setConfirmationOfWalletToBeDeleted('');
};
const handleWalletNameInput = e => {
const { value } = e.target;
// validation
if (value && value.length && value.length < 24) {
setNewWalletNameIsValid(true);
} else {
setNewWalletNameIsValid(false);
}
setNewWalletName(value);
};
const handleWalletToDeleteInput = e => {
const { value } = e.target;
if (value && value === `delete ${walletToBeDeleted.name}`) {
setWalletDeleteValid(true);
} else {
setWalletDeleteValid(false);
}
setConfirmationOfWalletToBeDeleted(value);
};
return (
{walletToBeRenamed !== null && (
cancelRenameWallet()}
>
-
- }
- placeholder="Enter new wallet name"
- name="newName"
- value={newWalletName}
- onChange={e => handleWalletNameInput(e)}
- />
-
-
+
+
+ }
+ placeholder="Enter new wallet name"
+ name="newName"
+ value={newWalletName}
+ onChange={e => handleWalletNameInput(e)}
+ />
+
+
+
)}
{walletToBeDeleted !== null && (
cancelDeleteWallet()}
>
-
- }
- placeholder={`Type "delete ${walletToBeDeleted.name}" to confirm`}
- name="walletToBeDeletedInput"
- value={confirmationOfWalletToBeDeleted}
- onChange={e => handleWalletToDeleteInput(e)}
- />
-
-
+
+
+ }
+ placeholder={`Type "delete ${walletToBeDeleted.name}" to confirm`}
+ name="walletToBeDeletedInput"
+ value={confirmationOfWalletToBeDeleted}
+ onChange={e =>
+ handleWalletToDeleteInput(e)
+ }
+ />
+
+
+
)}
Backup your wallet
{wallet && wallet.mnemonic && (
{wallet && wallet.mnemonic
? wallet.mnemonic
: ''}
)}
Manage Wallets
{apiError ? (
<>
An error occured on our end. Reconnecting...
>
) : (
<>
updateSavedWalletsOnCreate()}
>
New Wallet
openSeedInput(!seedInput)}
>
Import Wallet
{seedInput && (
<>
Copy and paste your mnemonic seed phrase
below to import an existing wallet
-
- }
- placeholder="mnemonic (seed phrase)"
- name="mnemonic"
- autoComplete="off"
- onChange={e => handleChange(e)}
- required
- />
-
- submit()}
- >
- Import
-
-
+
+
+ }
+ placeholder="mnemonic (seed phrase)"
+ name="mnemonic"
+ autoComplete="off"
+ onChange={e => handleChange(e)}
+ required
+ />
+
+ submit()}
+ >
+ Import
+
+
+
>
)}
>
)}
{savedWallets && savedWallets.length > 0 && (
<>
{wallet.name}
Currently active
{savedWallets.map(sw => (
{sw.name}
showPopulatedRenameWalletModal(
sw,
)
}
/>
showPopulatedDeleteWalletModal(
sw,
)
}
/>
updateSavedWalletsOnLoad(
sw,
)
}
>
Activate
))}
>
)}
[
Documentation
]
);
};
export default Configure;
diff --git a/web/cashtab/src/components/Configure/__tests__/__snapshots__/Configure.test.js.snap b/web/cashtab/src/components/Configure/__tests__/__snapshots__/Configure.test.js.snap
index 945f92d06..64b5b9d70 100644
--- a/web/cashtab/src/components/Configure/__tests__/__snapshots__/Configure.test.js.snap
+++ b/web/cashtab/src/components/Configure/__tests__/__snapshots__/Configure.test.js.snap
@@ -1,449 +1,449 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Configure with a wallet 1`] = `
Backup your wallet
Your seed phrase is the only way to restore your wallet. Write it down. Keep it safe.
Click to reveal seed phrase
Manage Wallets
New Wallet
Import Wallet
[
Documentation
]
`;
exports[`Configure without a wallet 1`] = `
Backup your wallet
Your seed phrase is the only way to restore your wallet. Write it down. Keep it safe.
Manage Wallets
New Wallet
Import Wallet
[
Documentation
]
`;
diff --git a/web/cashtab/src/components/OnBoarding/OnBoarding.js b/web/cashtab/src/components/OnBoarding/OnBoarding.js
index 60c067d27..67a56c406 100644
--- a/web/cashtab/src/components/OnBoarding/OnBoarding.js
+++ b/web/cashtab/src/components/OnBoarding/OnBoarding.js
@@ -1,152 +1,155 @@
import React, { useState } from 'react';
import styled from 'styled-components';
import { WalletContext } from '@utils/context';
import { Input, Form, Modal } from 'antd';
+import { AntdFormWrapper } from '@components/Common/EnhancedInputs';
import {
ExclamationCircleOutlined,
PlusSquareOutlined,
ImportOutlined,
LockOutlined,
} from '@ant-design/icons';
import StyledOnboarding from '@components/Common/StyledOnBoarding';
import PrimaryButton, {
SecondaryButton,
SmartButton,
} from '@components/Common/PrimaryButton';
import { currency } from '@components/Common/Ticker.js';
import { Event } from '@utils/GoogleAnalytics';
export const WelcomeText = styled.p`
color: #444;
width: 100%;
font-size: 16px;
margin-bottom: 60px;
text-align: left;
`;
export const WelcomeLink = styled.a`
text-decoration: underline;
color: #ff8d00;
`;
export const OnBoarding = ({ history }) => {
const ContextValue = React.useContext(WalletContext);
const { createWallet, validateMnemonic } = ContextValue;
const [formData, setFormData] = useState({
dirty: true,
mnemonic: '',
});
const [seedInput, openSeedInput] = useState(false);
const [isValidMnemonic, setIsValidMnemonic] = useState(false);
const { confirm } = Modal;
async function submit() {
setFormData({
...formData,
dirty: false,
});
if (!formData.mnemonic) {
return;
}
// Event("Category", "Action", "Label")
// Track number of created wallets from onboarding
Event('Onboarding.js', 'Create Wallet', 'Imported');
createWallet(formData.mnemonic);
}
const handleChange = e => {
const { value, name } = e.target;
// Validate mnemonic on change
// Import button should be disabled unless mnemonic is valid
setIsValidMnemonic(validateMnemonic(value));
setFormData(p => ({ ...p, [name]: value }));
};
function showBackupConfirmModal() {
confirm({
title: "Don't forget to back up your wallet",
icon: ,
content: `Once your wallet is created you can back it up by writing down your 12-word seed. You can find your seed on the Settings page. If you are browsing in Incognito mode or if you clear your browser history, you will lose any funds that are not backed up!`,
okText: 'Okay, make me a wallet!',
onOk() {
// Event("Category", "Action", "Label")
// Track number of created wallets from onboarding
Event('Onboarding.js', 'Create Wallet', 'New');
createWallet();
},
});
}
return (
<>
Welcome to Cashtab!
Cashtab is an{' '}
open source,
{' '}
non-custodial web wallet for {currency.name}.
Want to learn more?{' '}
Check out the Cashtab documentation.
showBackupConfirmModal()}>
New Wallet
openSeedInput(!seedInput)}>
Import Wallet
{seedInput && (
-
- }
- placeholder="mnemonic (seed phrase)"
- name="mnemonic"
- autoComplete="off"
- onChange={e => handleChange(e)}
- required
- />
-
+
+
+ }
+ placeholder="mnemonic (seed phrase)"
+ name="mnemonic"
+ autoComplete="off"
+ onChange={e => handleChange(e)}
+ required
+ />
+
- submit()}
- >
- Import
-
-
+ submit()}
+ >
+ Import
+
+
+
)}
>
);
};
diff --git a/web/cashtab/src/components/Wallet/__tests__/__snapshots__/Wallet.test.js.snap b/web/cashtab/src/components/Wallet/__tests__/__snapshots__/Wallet.test.js.snap
index 82db81ee8..5e613c8cb 100644
--- a/web/cashtab/src/components/Wallet/__tests__/__snapshots__/Wallet.test.js.snap
+++ b/web/cashtab/src/components/Wallet/__tests__/__snapshots__/Wallet.test.js.snap
@@ -1,508 +1,508 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Wallet with BCH balances 1`] = `
Array [
0.06047469
BCHA
,
$
NaN
USD
,
,
,
View Transactions
,
]
`;
exports[`Wallet with BCH balances and tokens 1`] = `
Array [
0.06047469
BCHA
,
$
NaN
USD
,
,
,
View Transactions
,
,
]
`;
exports[`Wallet without BCH balance 1`] = `
Array [
🎉
Congratulations on your new wallet!
🎉
Start using the wallet immediately to receive
BCHA
payments, or load it up with
BCHA
to send to others
,
0
BCHA
,
,
,
]
`;
exports[`Without wallet defined 1`] = `
Array [
Welcome to Cashtab!
,
Cashtab is an
open source,
non-custodial web wallet for
Bitcoin ABC
.
Want to learn more?
Check out the Cashtab documentation.
,
New Wallet
,
Import Wallet
,
]
`;