merge master

pull/401/head
slowbackspace 5 years ago
commit 74b466be05

@ -1,17 +1,22 @@
## 1.1.0-beta
__added__
- Ripple support enabled
- Ripple support
- responsive sidebar
- QR code scanner in send form
- clear send form button
- backup notification modal
__updated__
- connect v7
- babel v7
- ethereum tokens list
- most of dependencies
__changed__
- update dependencies
- upgrade babel7
- split icons for T1 and TT
- icons for T1 and TT
- device header styles
- input styles
- split sign and verify title
- sign and verify title
__fixed__
- beta disclaimer wrapper position

@ -1,6 +1,6 @@
{
"name": "trezor-wallet",
"version": "1.0.3-beta",
"version": "1.1.0-beta",
"author": "TREZOR <info@trezor.io>",
"description": "",
"bin": {
@ -78,9 +78,9 @@
"styled-components": "^4.1.3",
"styled-normalize": "^8.0.6",
"trezor-bridge-communicator": "1.0.2",
"trezor-connect": "7.0.0-beta.2",
"trezor-connect": "7.0.0-beta.3",
"wallet-address-validator": "^0.2.4",
"web3": "1.0.0-beta.38",
"web3": "1.0.0-beta.35",
"webpack": "^4.29.3",
"webpack-build-notifier": "^0.1.30",
"webpack-bundle-analyzer": "^3.0.3",

Binary file not shown.

File diff suppressed because it is too large Load Diff

@ -205,7 +205,7 @@ const discoverAccount = (device: TrezorDevice, discoveryProcess: Discovery): Asy
}
// handle outdated firmware error
if (error.message === UI.FIRMWARE) {
if (error.message === UI.FIRMWARE_OLD) {
dispatch({
type: DISCOVERY.FIRMWARE_OUTDATED,
device,

@ -59,6 +59,17 @@ export const onPassphraseSubmit = (passphrase: string): AsyncAction => async (di
});
};
export const onReceiveConfirmation = (confirmation: any): AsyncAction => async (dispatch: Dispatch): Promise<void> => {
await TrezorConnect.uiResponse({
type: UI.RECEIVE_CONFIRMATION,
payload: confirmation,
});
dispatch({
type: MODAL.CLOSE,
});
};
export const onRememberDevice = (device: TrezorDevice): Action => ({
type: CONNECT.REMEMBER,
device,
@ -173,6 +184,7 @@ export const onQrScan = (parsedUri: parsedURI, networkType: string): ThunkAction
export default {
onPinSubmit,
onPassphraseSubmit,
onReceiveConfirmation,
onRememberDevice,
onForgetDevice,
onForgetSingleDevice,

@ -94,6 +94,10 @@ export const showAddress = (path: Array<number>): AsyncAction => async (dispatch
type: RECEIVE.HIDE_ADDRESS,
});
// special case: device no-backup permissions not granted
// $FlowIssue: remove this after trezor-connect@7.0.0 release
if (response.payload.code === 403) return;
dispatch({
type: NOTIFICATION.ADD,
payload: {

@ -347,6 +347,17 @@ export const gotoFirmwareUpdate = (): ThunkAction => (dispatch: Dispatch, getSta
dispatch(goto(`/device/${devUrl}/firmware-update`));
};
/*
* Go to NoBackup page
*/
export const gotoBackup = (): ThunkAction => (dispatch: Dispatch, getState: GetState): void => {
const { selectedDevice } = getState().wallet;
if (!selectedDevice || !selectedDevice.features) return;
const devUrl: string = `${selectedDevice.features.device_id}${selectedDevice.instance ? `:${selectedDevice.instance}` : ''}`;
dispatch(goto(`/device/${devUrl}/backup`));
};
/*
* Try to redirect to initial url
*/

@ -3,6 +3,7 @@ import TrezorConnect, {
DEVICE, DEVICE_EVENT, UI_EVENT, TRANSPORT_EVENT, BLOCKCHAIN_EVENT,
} from 'trezor-connect';
import { CONTEXT_NONE } from 'actions/constants/modal';
import urlConstants from 'constants/urls';
import * as CONNECT from 'actions/constants/TrezorConnect';
import * as NOTIFICATION from 'actions/constants/notification';
import { getDuplicateInstanceNumber } from 'reducers/utils';
@ -120,7 +121,7 @@ export const init = (): AsyncAction => async (dispatch: Dispatch, getState: GetS
if (buildUtils.isDev()) {
window.__TREZOR_CONNECT_SRC = typeof LOCAL === 'string' ? LOCAL : 'https://sisyfos.trezor.io/connect/'; // eslint-disable-line no-underscore-dangle
// window.__TREZOR_CONNECT_SRC = typeof LOCAL === 'string' ? LOCAL : 'https://connect.trezor.io/5/'; // eslint-disable-line no-underscore-dangle
// window.__TREZOR_CONNECT_SRC = typeof LOCAL === 'string' ? LOCAL : 'https://localhost:8088/'; // eslint-disable-line no-underscore-dangle
window.TrezorConnect = TrezorConnect;
}
@ -131,6 +132,10 @@ export const init = (): AsyncAction => async (dispatch: Dispatch, getState: GetS
popup: false,
webusb: true,
pendingTransportEvent: (getState().devices.length < 1),
manifest: {
email: 'info@trezor.io',
appUrl: urlConstants.NEXT_WALLET,
},
});
} catch (error) {
dispatch({

@ -7,3 +7,4 @@ export const CONTEXT_DEVICE: 'modal_ctx_device' = 'modal_ctx_device';
export const CONTEXT_EXTERNAL_WALLET: 'modal_ctx_external-wallet' = 'modal_ctx_external-wallet';
export const OPEN_SCAN_QR: 'modal__open_scan_qr' = 'modal__open_scan_qr';
export const CONTEXT_SCAN_QR: 'modal__ctx_scan_qr' = 'modal__ctx_scan_qr';
export const CONTEXT_CONFIRMATION: 'modal__ctx_confirmation' = 'modal__ctx_confirmation';

@ -28,7 +28,7 @@ const Backdrop = ({
);
Backdrop.propTypes = {
show: PropTypes.bool.isRequired,
show: PropTypes.bool,
className: PropTypes.string,
animated: PropTypes.bool,
onClick: PropTypes.func,

@ -63,7 +63,7 @@ const Footer = ({ opened, toggle, isLanding }: Props) => (
<Left>
<Copy>&copy; {getYear(new Date())}</Copy>
<StyledLink href="http://satoshilabs.com" isGreen>SatoshiLabs</StyledLink>
<StyledLink href="./assets/tos.pdf" isGreen>
<StyledLink href="https://trezor.io/static/pdf/tos.pdf" isGreen>
<FormattedMessage {...l10nMessages.TR_TERMS} />
</StyledLink>
<StyledLink onClick={toggle} isGreen>{ opened ? 'Hide Log' : 'Show Log' }</StyledLink>

@ -0,0 +1,85 @@
/* @flow */
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import icons from 'config/icons';
import { getOldWalletUrl } from 'utils/url';
import colors from 'config/colors';
import { H2 } from 'components/Heading';
import P from 'components/Paragraph';
import Icon from 'components/Icon';
import Button from 'components/Button';
import Link from 'components/Link';
import type { TrezorDevice } from 'flowtype';
import type { Props as BaseProps } from '../../Container';
type Props = {
onReceiveConfirmation: $ElementType<$ElementType<BaseProps, 'modalActions'>, 'onReceiveConfirmation'>;
device: ?TrezorDevice;
}
const Wrapper = styled.div`
max-width: 370px;
padding: 30px 48px;
`;
const StyledLink = styled(Link)`
position: absolute;
right: 15px;
top: 15px;
`;
const BackupButton = styled(Button)`
width: 100%;
margin-bottom: 10px;
`;
const ProceedButton = styled(Button)`
background: transparent;
border-color: ${colors.WARNING_PRIMARY};
color: ${colors.WARNING_PRIMARY};
&:focus,
&:hover,
&:active {
color: ${colors.WHITE};
background: ${colors.WARNING_PRIMARY};
box-shadow: none;
}
`;
const StyledP = styled(P)`
padding-bottom: 20px;
`;
const Row = styled.div`
display: flex;
flex-direction: column;
`;
const Confirmation = (props: Props) => (
<Wrapper>
<StyledLink onClick={() => props.onReceiveConfirmation(false)}>
<Icon size={24} color={colors.TEXT_SECONDARY} icon={icons.CLOSE} />
</StyledLink>
<H2>Your Trezor is not backed up</H2>
<Icon size={48} color={colors.WARNING_PRIMARY} icon={icons.WARNING} />
<StyledP isSmaller>If your device is ever lost or damaged, your funds will be lost. Backup your device first, to protect your coins against such events.</StyledP>
<Row>
<Link href={`${getOldWalletUrl(props.device)}/?backup`}>
<BackupButton onClick={() => props.onReceiveConfirmation(false)}>Create a backup in 3 minutes</BackupButton>
</Link>
<ProceedButton isWhite onClick={() => props.onReceiveConfirmation(true)}>Show address, I will take the risk</ProceedButton>
</Row>
</Wrapper>
);
Confirmation.propTypes = {
onReceiveConfirmation: PropTypes.func.isRequired,
};
export default Confirmation;

@ -2,7 +2,7 @@
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import { getOldWalletUrl } from 'utils/url';
import icons from 'config/icons';
import colors from 'config/colors';
@ -34,11 +34,23 @@ const StyledLink = styled(Link)`
const Wrapper = styled.div`
max-width: 370px;
padding: 30px 48px;
padding: 30px 0px;
`;
const Content = styled.div`
padding: 0px 48px;
`;
const StyledP = styled(P)`
padding: 20px 0px;
padding-bottom: 20px;
`;
const Divider = styled.div`
width: 100%;
height: 1px;
background: ${colors.DIVIDER};
margin: 20px 0px;
`;
const Row = styled.div`
@ -50,6 +62,24 @@ const Row = styled.div`
}
`;
const BackupButton = styled(Button)`
width: 100%;
`;
const WarnButton = styled(Button)`
background: transparent;
border-color: ${colors.WARNING_PRIMARY};
color: ${colors.WARNING_PRIMARY};
&:focus,
&:hover,
&:active {
color: ${colors.WHITE};
background: ${colors.WARNING_PRIMARY};
box-shadow: none;
}
`;
class ConfirmUnverifiedAddress extends PureComponent<Props> {
componentDidMount(): void {
this.keyboardHandler = this.keyboardHandler.bind(this);
@ -100,22 +130,44 @@ class ConfirmUnverifiedAddress extends PureComponent<Props> {
: <FormattedMessage {...l10nMessages.TR_PLEASE_DISABLE_PASSPHRASE} />;
}
const needsBackup = device.features && device.features.needs_backup;
return (
<Wrapper>
<StyledLink onClick={onCancel}>
<Icon size={24} color={colors.TEXT_SECONDARY} icon={icons.CLOSE} />
</StyledLink>
<H2>{ deviceStatus }</H2>
<StyledP isSmaller>
<FormattedMessage
{...l10nMessages.TR_TO_PREVENT_PHISHING_ATTACKS_COMMA}
values={{ claim }}
/>
</StyledP>
<Row>
<Button onClick={() => (!account ? this.verifyAddress() : 'false')}><FormattedMessage {...l10nMessages.TR_TRY_AGAIN} /></Button>
<Button isWhite onClick={() => this.showUnverifiedAddress()}><FormattedMessage {...l10nMessages.TR_SHOW_UNVERIFIED_ADDRESS} /></Button>
</Row>
<Content>
<StyledLink onClick={onCancel}>
<Icon size={24} color={colors.TEXT_SECONDARY} icon={icons.CLOSE} />
</StyledLink>
<H2>{ deviceStatus }</H2>
<StyledP isSmaller>
<FormattedMessage
{...l10nMessages.TR_TO_PREVENT_PHISHING_ATTACKS_COMMA}
values={{ claim }}
/>
</StyledP>
</Content>
<Content>
<Row>
<Button onClick={() => (!account ? this.verifyAddress() : 'false')}><FormattedMessage {...l10nMessages.TR_TRY_AGAIN} /></Button>
<WarnButton isWhite onClick={() => this.showUnverifiedAddress()}><FormattedMessage {...l10nMessages.TR_SHOW_UNVERIFIED_ADDRESS} /></WarnButton>
</Row>
</Content>
{needsBackup && <Divider />}
{needsBackup && (
<>
<Content>
<H2>Device {device.label} is not backed up</H2>
<StyledP isSmaller>If your device is ever lost or damaged, your funds will be lost. Backup your device first, to protect your coins against such events.</StyledP>
</Content>
<Content>
<Row>
<Link href={`${getOldWalletUrl(device)}/?backup`}>
<BackupButton>Create a backup in 3 minutes</BackupButton>
</Link>
</Row>
</Content>
</>
)}
</Wrapper>
);
}

@ -19,6 +19,7 @@ import PassphraseType from 'components/modals/passphrase/Type';
import ConfirmSignTx from 'components/modals/confirm/SignTx';
import ConfirmAction from 'components/modals/confirm/Action';
import ConfirmUnverifiedAddress from 'components/modals/confirm/UnverifiedAddress';
import ConfirmNoBackup from 'components/modals/confirm/NoBackup';
import ForgetDevice from 'components/modals/device/Forget';
import RememberDevice from 'components/modals/device/Remember';
import DuplicateDevice from 'components/modals/device/Duplicate';
@ -189,6 +190,19 @@ const getQrModal = (props: Props) => {
);
};
const getConfirmationModal = (props: Props) => {
const { modal, modalActions, wallet } = props;
if (modal.context !== MODAL.CONTEXT_CONFIRMATION) return null;
switch (modal.windowType) {
case 'no-backup':
return (<ConfirmNoBackup device={wallet.selectedDevice} onReceiveConfirmation={modalActions.onReceiveConfirmation} />);
default:
return null;
}
};
// modal container component
const Modal = (props: Props) => {
const { modal } = props;
@ -205,6 +219,9 @@ const Modal = (props: Props) => {
case MODAL.CONTEXT_SCAN_QR:
component = getQrModal(props);
break;
case MODAL.CONTEXT_CONFIRMATION:
component = getConfirmationModal(props);
break;
default:
break;
}

@ -0,0 +1,25 @@
/* @flow */
import * as React from 'react';
import Notification from 'components/Notification';
import type { Props } from '../../index';
export default (props: Props) => {
const { selectedDevice } = props.wallet;
const needsBackup = selectedDevice && selectedDevice.features && selectedDevice.features.needs_backup;
if (!needsBackup) return null;
return (
<Notification
key="no-backup"
type="warning"
title="Your Trezor is not backed up!"
message="If your device is ever lost or damaged, your funds will be lost. Backup your device first, to protect your coins against such events."
actions={
[{
label: 'Create a backup',
callback: props.routerActions.gotoBackup,
}]
}
/>
);
};

@ -13,6 +13,7 @@ import * as RouterActions from 'actions/RouterActions';
import OnlineStatus from './components/OnlineStatus';
import UpdateBridge from './components/UpdateBridge';
import UpdateFirmware from './components/UpdateFirmware';
import NoBackup from './components/NoBackup';
export type StateProps = {
connect: $ElementType<State, 'connect'>;
@ -36,6 +37,7 @@ const Notifications = (props: Props) => (
<OnlineStatus {...props} />
<UpdateBridge {...props} />
<UpdateFirmware {...props} />
<NoBackup {...props} />
</React.Fragment>
);

@ -47,6 +47,21 @@ export default (props: Props) => {
)}
/>,
);
} else if (location.state.send) {
notifications.push(
<Notification
key="xrp-warning"
type="warning"
title="Do not send to accounts requiring a destination tag!"
message={(
<>
Destination tag is an arbitrary number which serves as a unique identifier of your transaction. Some services may require this to process your transaction. The current firmware version <strong>does not support</strong> destination tags yet.
<br /><br />
If the receiver requires a destination tag, do not use Trezor to send XRP. We are working on adding this feature.
</>
)}
/>,
);
}
}

@ -0,0 +1,5 @@
export default {
NEXT_WALLET: 'https://beta-wallet.trezor.io/next',
OLD_WALLET: 'https://wallet.trezor.io',
OLD_WALLET_BETA: 'https://beta-wallet.trezor.io',
};

@ -38,6 +38,7 @@ import type {
Device,
Features,
DeviceStatus,
FirmwareRelease,
DeviceFirmwareStatus,
DeviceMode,
DeviceMessageType,
@ -55,6 +56,7 @@ export type AcquiredDevice = $Exact<{
+label: string,
+features: Features,
+firmware: DeviceFirmwareStatus,
+firmwareRelease: ?FirmwareRelease,
status: DeviceStatus,
+mode: DeviceMode,
state: ?string,

@ -20,7 +20,10 @@ export type State = {
windowType?: string;
} | {
context: typeof MODAL.CONTEXT_SCAN_QR,
}
} | {
context: typeof MODAL.CONTEXT_CONFIRMATION,
windowType: string;
};
const initialState: State = {
context: MODAL.CONTEXT_NONE,
@ -98,6 +101,12 @@ export default function modal(state: State = initialState, action: Action): Stat
context: MODAL.CONTEXT_SCAN_QR,
};
case UI.REQUEST_CONFIRMATION:
return {
context: MODAL.CONTEXT_CONFIRMATION,
windowType: action.payload.view,
};
default:
return state;
}

@ -62,6 +62,11 @@ export const routes: Array<Route> = [
pattern: '/device/:device/firmware-update',
fields: ['device', 'firmware-update'],
},
{
name: 'wallet-backup',
pattern: '/device/:device/backup',
fields: ['device', 'backup'],
},
{
name: 'wallet-device-settings',
pattern: '/device/:device/settings',

@ -0,0 +1,24 @@
/* @flow */
import urlConstants from 'constants/urls';
import type { TrezorDevice } from 'flowtype';
const getOldWalletUrl = (device: ?TrezorDevice): string => {
if (!device || !device.firmwareRelease) return urlConstants.OLD_WALLET_BETA;
const release = device.firmwareRelease;
const url = release.channel === 'beta' ? urlConstants.OLD_WALLET_BETA : urlConstants.OLD_WALLET;
return url;
};
// TODO: use uri template to build urls
const getOldWalletReleaseUrl = (device: ?TrezorDevice): string => {
if (!device || !device.firmwareRelease) return urlConstants.OLD_WALLET_BETA;
const release = device.firmwareRelease;
const url = getOldWalletUrl(device);
const version = release.version.join('.');
return `${url}?fw=${version}`;
};
export {
getOldWalletUrl,
getOldWalletReleaseUrl,
};

@ -82,16 +82,16 @@ const getFeeInputState = (feeErrors: string, feeWarnings: string): string => {
return state;
};
const getDestinationTagInputState = (errors: string, warnings: string): string => {
let state = '';
if (warnings && !errors) {
state = 'warning';
}
if (errors) {
state = 'error';
}
return state;
};
// const getDestinationTagInputState = (errors: string, warnings: string): string => {
// let state = '';
// if (warnings && !errors) {
// state = 'warning';
// }
// if (errors) {
// state = 'error';
// }
// return state;
// };
const Left = styled.div`
display: flex;
@ -109,11 +109,11 @@ const AdvancedForm = (props: Props) => {
warnings,
infos,
fee,
destinationTag,
// destinationTag,
} = props.sendForm;
const {
onFeeChange,
onDestinationTagChange,
// onDestinationTagChange,
} = props.sendFormActions;
return (
@ -150,7 +150,7 @@ const AdvancedForm = (props: Props) => {
/>
</InputRow>
<InputRow>
{/* <InputRow>
<StyledInput
state={getDestinationTagInputState(errors.destinationTag, warnings.destinationTag)}
autoComplete="off"
@ -180,7 +180,7 @@ const AdvancedForm = (props: Props) => {
value={destinationTag}
onChange={event => onDestinationTagChange(event.target.value)}
/>
</InputRow>
</InputRow> */}
<AdvancedSettingsSendButtonWrapper>
{ props.children }

@ -6,6 +6,7 @@ import styled from 'styled-components';
import Icon from 'components/Icon';
import colors from 'config/colors';
import ICONS from 'config/icons';
import Tooltip from 'components/Tooltip';
import { FONT_SIZE, FONT_WEIGHT } from 'config/variables';
import type { Network, State as ReducersState } from 'flowtype';
import l10nMessages from './index.messages';
@ -58,6 +59,7 @@ const FiatValue = styled.div`
margin: 7px 0;
min-height: 25px;
color: ${colors.TEXT_PRIMARY};
align-items: center;
`;
const FiatValueRate = styled.div`
@ -88,6 +90,15 @@ const Label = styled.div`
color: ${colors.TEXT_SECONDARY};
`;
const StyledIcon = styled(Icon)`
cursor: pointer;
margin-top: -5px;
`;
const TooltipWrapper = styled.div`
display: flex;
align-items: center;
`;
class AccountBalance extends PureComponent<Props, State> {
constructor(props: Props) {
@ -117,6 +128,20 @@ class AccountBalance extends PureComponent<Props, State> {
fiat = accountBalance.times(fiatRateValue).toFixed(2);
}
const NoRatesTooltip = (
<Tooltip
maxWidth={285}
placement="top"
content="Fiat rates are not currently available."
>
<StyledIcon
icon={ICONS.HELP}
color={colors.TEXT_SECONDARY}
size={26}
/>
</Tooltip>
);
return (
<Wrapper isHidden={this.state.isHidden}>
<HideBalanceIconWrapper
@ -134,18 +159,20 @@ class AccountBalance extends PureComponent<Props, State> {
<React.Fragment>
<BalanceWrapper>
<Label><FormattedMessage {...l10nMessages.TR_BALANCE} /></Label>
{fiatRate && (
<FiatValue>${fiat}</FiatValue>
)}
<TooltipWrapper>
<FiatValue>{fiatRate ? `$ ${fiat}` : 'N/A'}</FiatValue>
{!fiatRate && NoRatesTooltip}
</TooltipWrapper>
<CoinBalance>{this.props.balance} {network.symbol}</CoinBalance>
</BalanceWrapper>
{fiatRate && (
<BalanceRateWrapper>
<Label><FormattedMessage {...l10nMessages.TR_RATE} /></Label>
<FiatValueRate>${fiatRateValue}</FiatValueRate>
<CoinBalance>1.00 {network.symbol}</CoinBalance>
</BalanceRateWrapper>
)}
<BalanceRateWrapper>
<Label><FormattedMessage {...l10nMessages.TR_RATE} /></Label>
<TooltipWrapper>
<FiatValueRate>{fiatRate ? `$ ${fiatRateValue}` : 'N/A'}</FiatValueRate>
{!fiatRate && NoRatesTooltip}
</TooltipWrapper>
<CoinBalance>1 {network.symbol}</CoinBalance>
</BalanceRateWrapper>
</React.Fragment>
)}
</Wrapper>

@ -6,7 +6,7 @@ import Icon from 'components/Icon';
import colors from 'config/colors';
import ICONS from 'config/icons';
import { FONT_SIZE, FONT_WEIGHT } from 'config/variables';
import Tooltip from 'components/Tooltip';
import type { Network, State as ReducersState } from 'flowtype';
type Props = {
@ -57,6 +57,7 @@ const FiatValue = styled.div`
margin: 7px 0;
min-height: 25px;
color: ${colors.TEXT_PRIMARY};
align-items: center;
`;
const FiatValueRate = styled.div`
@ -65,8 +66,8 @@ const FiatValueRate = styled.div`
min-height: 25px;
margin: 7px 0;
display: flex;
align-items: center;
color: ${colors.TEXT_PRIMARY};
align-items: center;
`;
const BalanceWrapper = styled.div`
@ -87,6 +88,15 @@ const Label = styled.div`
color: ${colors.TEXT_SECONDARY};
`;
const StyledIcon = styled(Icon)`
cursor: pointer;
margin-top: -5px;
`;
const TooltipWrapper = styled.div`
display: flex;
align-items: center;
`;
class AccountBalance extends PureComponent<Props, State> {
constructor(props: Props) {
@ -116,6 +126,20 @@ class AccountBalance extends PureComponent<Props, State> {
fiat = accountBalance.times(fiatRateValue).toFixed(2);
}
const NoRatesTooltip = (
<Tooltip
maxWidth={285}
placement="top"
content="Fiat rates are not currently available."
>
<StyledIcon
icon={ICONS.HELP}
color={colors.TEXT_SECONDARY}
size={26}
/>
</Tooltip>
);
return (
<Wrapper isHidden={this.state.isHidden}>
<HideBalanceIconWrapper
@ -133,24 +157,28 @@ class AccountBalance extends PureComponent<Props, State> {
<React.Fragment>
<BalanceWrapper>
<Label>Balance</Label>
{fiatRate && (
<FiatValue>${fiat}</FiatValue>
)}
<TooltipWrapper>
<FiatValue>{fiatRate ? `$ ${fiat}` : 'N/A'}</FiatValue>
{!fiatRate && NoRatesTooltip}
</TooltipWrapper>
<CoinBalance>{this.props.balance} {network.symbol}</CoinBalance>
</BalanceWrapper>
{this.props.reserve !== '0' && (
<BalanceWrapper>
<Label>Reserve</Label>
<CoinBalance>{this.props.reserve} {network.symbol}</CoinBalance>
<FiatValueRate>{this.props.reserve} {network.symbol}</FiatValueRate>
</BalanceWrapper>
)}
{fiatRate && (
<BalanceRateWrapper>
<Label>Rate</Label>
<FiatValueRate>${fiatRateValue}</FiatValueRate>
<CoinBalance>1.00 {network.symbol}</CoinBalance>
</BalanceRateWrapper>
)}
<BalanceRateWrapper>
<Label>Rate</Label>
<TooltipWrapper>
<FiatValueRate>{fiatRate ? `$ ${fiatRateValue}` : 'N/A'}</FiatValueRate>
{!fiatRate && NoRatesTooltip}
</TooltipWrapper>
<CoinBalance>1 {network.symbol}</CoinBalance>
</BalanceRateWrapper>
</React.Fragment>
)}
</Wrapper>

@ -1,3 +1,4 @@
/* @flow */
import React from 'react';
import styled from 'styled-components';
import { H1 } from 'components/Heading';
@ -7,9 +8,16 @@ import Button from 'components/Button';
import P from 'components/Paragraph';
import Link from 'components/Link';
import ICONS from 'config/icons';
import { getOldWalletUrl } from 'utils/url';
import Content from 'views/Wallet/components/Content';
import { connect } from 'react-redux';
import type { TrezorDevice } from 'flowtype';
type Props = {
device: ?TrezorDevice;
}
const Section = styled.section`
display: flex;
flex-direction: column;
@ -32,7 +40,7 @@ const StyledH1 = styled(H1)`
text-align: center;
`;
const DeviceSettings = () => (
const DeviceSettings = (props: Props) => (
<Content>
<Section>
<Row>
@ -43,7 +51,7 @@ const DeviceSettings = () => (
/>
<StyledH1>Device settings is under construction</StyledH1>
<StyledP>Please use Bitcoin wallet interface to change your device settings</StyledP>
<Link href="https://beta-wallet.trezor.io/">
<Link href={getOldWalletUrl(props.device)}>
<Button>Take me to the Bitcoin wallet</Button>
</Link>
</Row>

@ -4,6 +4,7 @@ import React from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { FormattedMessage } from 'react-intl';
import { getOldWalletReleaseUrl } from 'utils/url';
import styled from 'styled-components';
import { H1 } from 'components/Heading';
@ -136,7 +137,7 @@ const FirmwareUpdate = (props: Props) => (
<StyledP>
<FormattedMessage {...l10nMessages.TR_PLEASE_USE_OLD_WALLET} />
</StyledP>
<Link href="https://beta-wallet.trezor.io">
<Link href={getOldWalletReleaseUrl(props.device)}>
<Button>
<FormattedMessage {...l10nCommonMessages.TR_TAKE_ME_TO_BITCOIN_WALLET} />
</Button>

@ -1,14 +1,22 @@
/* @flow */
import styled from 'styled-components';
import { H1 } from 'components/Heading';
import Button from 'components/Button';
import { getOldWalletUrl } from 'utils/url';
import Paragraph from 'components/Paragraph';
import React from 'react';
import { connect } from 'react-redux';
import { FormattedMessage } from 'react-intl';
import l10nCommonMessages from 'views/common.messages';
import type { TrezorDevice } from 'flowtype';
import l10nMessages from './index.messages';
type Props = {
device: ?TrezorDevice;
}
const Wrapper = styled.div`
display: flex;
flex-direction: column;
@ -29,12 +37,12 @@ const StyledParagraph = styled(Paragraph)`
text-align: center;
`;
const Initialize = () => (
const Initialize = (props: Props) => (
<Wrapper data-test="Page__device__not__initialized">
<Row>
<H1><FormattedMessage {...l10nMessages.TR_YOUR_DEVICE_IS_NOT_INITIALIZED} /></H1>
<StyledParagraph><FormattedMessage {...l10nMessages.TR_PLEASE_USE_TO_START_INITIALIZATION} /></StyledParagraph>
<A href="https://beta-wallet.trezor.io/">
<A href={getOldWalletUrl(props.device)}>
<Button><FormattedMessage {...l10nCommonMessages.TR_TAKE_ME_TO_BITCOIN_WALLET} /></Button>
</A>
</Row>

@ -0,0 +1,67 @@
/* @flow */
import React from 'react';
import styled from 'styled-components';
import { H1 } from 'components/Heading';
import P from 'components/Paragraph';
import Link from 'components/Link';
import { getOldWalletUrl } from 'utils/url';
import Button from 'components/Button';
import Icon from 'components/Icon';
import { FONT_SIZE } from 'config/variables';
import colors from 'config/colors';
import icons from 'config/icons';
import type { TrezorDevice } from 'flowtype';
type Props = {
device: ?TrezorDevice;
}
const Wrapper = styled.section`
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 90px 35px 40px 35px;
`;
const StyledNavLink = styled(Link)`
color: ${colors.TEXT_SECONDARY};
padding-top: 20px;
font-size: ${FONT_SIZE.BASE};
`;
const StyledH1 = styled(H1)`
text-align: center;
`;
const StyledP = styled(P)`
max-width: 550px;
padding-bottom: 15px;
`;
const Message = styled.div`
text-align: center;
padding: 0 0 15px 0;
`;
const FirmwareUpdate = (props: Props) => (
<Wrapper>
<Icon
size={128}
color={colors.WARNING_PRIMARY}
icon={icons.WARNING}
/>
<StyledH1>Your Trezor is not backed up!</StyledH1>
<Message>
<StyledP>If your device is ever lost or damaged, your funds will be lost. Backup your device first, to protect your coins against such events.</StyledP>
<P>Please use Bitcoin wallet interface to create a backup.</P>
</Message>
<Link href={`${getOldWalletUrl(props.device)}?backup=1`}>
<Button>Take me to the Bitcoin wallet</Button>
</Link>
<StyledNavLink to="/">Ill do that later.</StyledNavLink>
</Wrapper>
);
export default FirmwareUpdate;

@ -28,6 +28,7 @@ import WalletDeviceSettings from 'views/Wallet/views/DeviceSettings';
import WalletSettings from 'views/Wallet/views/WalletSettings';
import WalletBootloader from 'views/Wallet/views/Bootloader';
import WalletFirmwareUpdate from 'views/Wallet/views/FirmwareUpdate';
import WalletNoBackup from 'views/Wallet/views/NoBackup';
import WalletInitialize from 'views/Wallet/views/Initialize';
import WalletSeedless from 'views/Wallet/views/Seedless';
import WalletAcquire from 'views/Wallet/views/Acquire';
@ -56,6 +57,7 @@ const App = () => (
<Route exact path={getPattern('wallet-initialize')} component={WalletInitialize} />
<Route exact path={getPattern('wallet-seedless')} component={WalletSeedless} />
<Route exact path={getPattern('wallet-firmware-update')} component={WalletFirmwareUpdate} />
<Route exact path={getPattern('wallet-backup')} component={WalletNoBackup} />
<Route exact path={getPattern('wallet-device-settings')} component={WalletDeviceSettings} />
<Route exact path={getPattern('wallet-account-summary')} component={AccountSummary} />
<Route path={getPattern('wallet-account-send')} component={AccountSend} />

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save