mirror of
https://github.com/trezor/trezor-wallet
synced 2024-12-28 09:58:23 +00:00
merge
This commit is contained in:
commit
53f7a8ecef
@ -1,4 +1,4 @@
|
||||
image: node:8
|
||||
image: node:9.3
|
||||
|
||||
cache:
|
||||
paths:
|
||||
|
23
Makefile
23
Makefile
@ -10,19 +10,34 @@ build-%:
|
||||
# usage:
|
||||
# make stage-beta
|
||||
# make stage-stable
|
||||
stage-%:
|
||||
sync-stage-%:
|
||||
./scripts/s3sync.sh stage $*
|
||||
|
||||
# s3sync with beta.mytrezor.com
|
||||
# Upload build/beta only
|
||||
# usage:
|
||||
# make beta
|
||||
beta:
|
||||
sync-beta:
|
||||
./scripts/s3sync.sh beta beta
|
||||
|
||||
# s3sync with wallet.mytrezor.com
|
||||
# Upload build/stable only
|
||||
# usage:
|
||||
# make stable
|
||||
stable:
|
||||
./scripts/s3sync.sh stable stable
|
||||
sync-stable:
|
||||
./scripts/s3sync.sh stable stable
|
||||
|
||||
.DEFAULT_GOAL:= default
|
||||
default:
|
||||
@echo "Build:"
|
||||
@echo "git checkout to desired branch (beta|stable)"
|
||||
@echo " make build-beta"
|
||||
@echo " make build-stable"
|
||||
@echo "Sync:"
|
||||
@echo "s3 sync desired build to server (beta.mytrezor.com|wallet.mytrezor.com)"
|
||||
@echo " make sync-beta"
|
||||
@echo " make sync-stable"
|
||||
@echo "Staging:"
|
||||
@echo "s3 sync desired build to stage server (stage.mytrezor.com)"
|
||||
@echo " make sync-stage-beta"
|
||||
@echo " make sync-stage-stable"
|
@ -52,6 +52,7 @@
|
||||
"react": "^16.4.2",
|
||||
"react-dom": "^16.2.0",
|
||||
"react-hot-loader": "^4.3.4",
|
||||
"react-json-view": "^1.19.1",
|
||||
"react-qr-svg": "^2.1.0",
|
||||
"react-redux": "^5.0.7",
|
||||
"react-router-dom": "^4.2.2",
|
||||
|
@ -25,7 +25,19 @@ export const onPinSubmit = (value: string): Action => {
|
||||
};
|
||||
};
|
||||
|
||||
export const onPassphraseSubmit = (passphrase: string): AsyncAction => async (dispatch: Dispatch): Promise<void> => {
|
||||
export const onPassphraseSubmit = (passphrase: string): AsyncAction => async (dispatch: Dispatch, getState: GetState): Promise<void> => {
|
||||
const { modal } = getState();
|
||||
if (modal.context !== MODAL.CONTEXT_DEVICE) return;
|
||||
|
||||
if (passphrase === '') {
|
||||
// set standard wallet type if passphrase is blank
|
||||
dispatch({
|
||||
type: CONNECT.UPDATE_WALLET_TYPE,
|
||||
device: modal.device,
|
||||
hidden: false,
|
||||
});
|
||||
}
|
||||
|
||||
await TrezorConnect.uiResponse({
|
||||
type: UI.RECEIVE_PASSPHRASE,
|
||||
payload: {
|
||||
@ -106,15 +118,16 @@ export const onDeviceConnect = (device: Device): ThunkAction => (dispatch: Dispa
|
||||
}
|
||||
};
|
||||
|
||||
export const onWalletTypeRequest = (device: TrezorDevice, hidden: boolean, state: ?string): ThunkAction => (dispatch: Dispatch): void => {
|
||||
export const onWalletTypeRequest = (hidden: boolean): ThunkAction => (dispatch: Dispatch, getState: GetState): void => {
|
||||
const { modal } = getState();
|
||||
if (modal.context !== MODAL.CONTEXT_DEVICE) return;
|
||||
dispatch({
|
||||
type: MODAL.CLOSE,
|
||||
});
|
||||
dispatch({
|
||||
type: CONNECT.RECEIVE_WALLET_TYPE,
|
||||
device,
|
||||
device: modal.device,
|
||||
hidden,
|
||||
state,
|
||||
});
|
||||
};
|
||||
|
||||
@ -129,7 +142,6 @@ export const gotoExternalWallet = (id: string, url: string): ThunkAction => (dis
|
||||
export default {
|
||||
onPinSubmit,
|
||||
onPassphraseSubmit,
|
||||
// askForRemember,
|
||||
onRememberDevice,
|
||||
onForgetDevice,
|
||||
onForgetSingleDevice,
|
||||
|
@ -64,8 +64,8 @@ export const paramsValidation = (params: RouterLocationState): PayloadAction<boo
|
||||
if (!device) return false;
|
||||
|
||||
if (!deviceUtils.isDeviceAccessible(device)) {
|
||||
// TODO: there should be no access to deep links if device has incorrect mode/firmware
|
||||
// if (params.hasOwnProperty('network') || params.hasOwnProperty('account')) return false;
|
||||
// no access to deep links if device has incorrect mode/firmware
|
||||
if (params.hasOwnProperty('network') || params.hasOwnProperty('account')) return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,6 +190,8 @@ const getDeviceUrl = (device: TrezorDevice | Device): PayloadAction<?string> =>
|
||||
url = `/device/${device.path}/bootloader`;
|
||||
} else if (device.mode === 'initialize') {
|
||||
url = `/device/${device.features.device_id}/initialize`;
|
||||
} else if (device.mode === 'seedless') {
|
||||
url = `/device/${device.features.device_id}/seedless`;
|
||||
} else if (device.firmware === 'required') {
|
||||
url = `/device/${device.features.device_id}/firmware-update`;
|
||||
} else if (typeof device.instance === 'number') {
|
||||
|
@ -74,6 +74,9 @@ export const verify = (
|
||||
): AsyncAction => async (dispatch: Dispatch, getState: GetState): Promise<void> => {
|
||||
const selected = getState().wallet.selectedDevice;
|
||||
if (!selected) return;
|
||||
|
||||
dispatch({ type: SIGN_VERIFY.VERIFY_PROGRESS, isVerifyProgress: true });
|
||||
|
||||
const response = await TrezorConnect.ethereumVerifyMessage({
|
||||
device: {
|
||||
path: selected.path,
|
||||
@ -87,6 +90,8 @@ export const verify = (
|
||||
useEmptyPassphrase: selected.useEmptyPassphrase,
|
||||
});
|
||||
|
||||
dispatch({ type: SIGN_VERIFY.VERIFY_PROGRESS, isVerifyProgress: false });
|
||||
|
||||
if (response && response.success) {
|
||||
dispatch({
|
||||
type: NOTIFICATION.ADD,
|
||||
|
@ -78,10 +78,9 @@ export type TrezorConnectAction = {
|
||||
type: typeof CONNECT.REQUEST_WALLET_TYPE,
|
||||
device: TrezorDevice
|
||||
} | {
|
||||
type: typeof CONNECT.RECEIVE_WALLET_TYPE,
|
||||
type: typeof CONNECT.RECEIVE_WALLET_TYPE | typeof CONNECT.UPDATE_WALLET_TYPE,
|
||||
device: TrezorDevice,
|
||||
hidden: boolean,
|
||||
state: ?string,
|
||||
};
|
||||
|
||||
declare var LOCAL: ?string;
|
||||
|
@ -29,4 +29,5 @@ export const START_ACQUIRING: 'connect__start_acquiring' = 'connect__start_acqui
|
||||
export const STOP_ACQUIRING: 'connect__stop_acquiring' = 'connect__stop_acquiring';
|
||||
|
||||
export const REQUEST_WALLET_TYPE: 'connect__request_wallet_type' = 'connect__request_wallet_type';
|
||||
export const RECEIVE_WALLET_TYPE: 'connect__receive_wallet_type' = 'connect__receive_wallet_type';
|
||||
export const RECEIVE_WALLET_TYPE: 'connect__receive_wallet_type' = 'connect__receive_wallet_type';
|
||||
export const UPDATE_WALLET_TYPE: 'connect__update_wallet_type' = 'connect__update_wallet_type';
|
@ -5,6 +5,7 @@ import { bindActionCreators } from 'redux';
|
||||
import { connect } from 'react-redux';
|
||||
import colors from 'config/colors';
|
||||
import { H2 } from 'components/Heading';
|
||||
import ReactJson from 'react-json-view';
|
||||
import Icon from 'components/Icon';
|
||||
import P from 'components/Paragraph';
|
||||
|
||||
@ -44,22 +45,17 @@ const Click = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
const Textarea = styled.textarea`
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
min-height: 200px;
|
||||
resize: vertical;
|
||||
font-size: 10px;
|
||||
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledParagraph = styled(P)`
|
||||
margin: 10px 0;
|
||||
`;
|
||||
|
||||
const LogWrapper = styled.div`
|
||||
background: white;
|
||||
padding: 25px;
|
||||
height: 300px;
|
||||
overflow: scroll;
|
||||
`;
|
||||
|
||||
const Log = (props: Props): ?React$Element<string> => {
|
||||
if (!props.log.opened) return null;
|
||||
return (
|
||||
@ -69,7 +65,9 @@ const Log = (props: Props): ?React$Element<string> => {
|
||||
</Click>
|
||||
<H2>Log</H2>
|
||||
<StyledParagraph isSmaller>Attention: The log contains your XPUBs. Anyone with your XPUBs can see your account history.</StyledParagraph>
|
||||
<Textarea value={JSON.stringify(props.log.entries)} readOnly />
|
||||
<LogWrapper>
|
||||
<ReactJson src={props.log.entries} />
|
||||
</LogWrapper>
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
|
@ -1,10 +1,12 @@
|
||||
/* @flow */
|
||||
|
||||
import * as React from 'react';
|
||||
import styled, { css } from 'styled-components';
|
||||
import styled from 'styled-components';
|
||||
import PropTypes from 'prop-types';
|
||||
import Icon from 'components/Icon';
|
||||
import colors from 'config/colors';
|
||||
import { getPrimaryColor, getSecondaryColor } from 'utils/notification';
|
||||
import Loader from 'components/Loader';
|
||||
import { TRANSITION } from 'config/variables';
|
||||
|
||||
type Props = {
|
||||
@ -15,59 +17,39 @@ type Props = {
|
||||
size: number;
|
||||
};
|
||||
onClick: () => void;
|
||||
isLoading?: boolean;
|
||||
children: React.Node;
|
||||
};
|
||||
|
||||
const LoaderContent = styled.div`
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: default;
|
||||
background: ${props => getSecondaryColor(props.type)};
|
||||
`;
|
||||
|
||||
const Wrapper = styled.button`
|
||||
padding: 12px 58px;
|
||||
border-radius: 3px;
|
||||
background: transparent;
|
||||
font-size: 14px;
|
||||
position: relative;
|
||||
font-weight: 300;
|
||||
cursor: pointer;
|
||||
color: ${colors.WHITE};
|
||||
border: 0;
|
||||
color: ${props => getPrimaryColor(props.type)};
|
||||
border: 1px solid ${props => getPrimaryColor(props.type)};
|
||||
transition: ${TRANSITION.HOVER};
|
||||
|
||||
${props => props.type === 'info' && css`
|
||||
border: 1px solid ${colors.INFO_PRIMARY};
|
||||
color: ${colors.INFO_PRIMARY};
|
||||
|
||||
&:hover {
|
||||
color: ${colors.WHITE};
|
||||
background: ${colors.INFO_PRIMARY};
|
||||
}
|
||||
`}
|
||||
|
||||
${props => props.type === 'success' && css`
|
||||
border: 1px solid ${colors.SUCCESS_PRIMARY};
|
||||
color: ${colors.SUCCESS_PRIMARY};
|
||||
|
||||
&:hover {
|
||||
color: ${colors.WHITE};
|
||||
background: ${colors.SUCCESS_PRIMARY};
|
||||
}
|
||||
`}
|
||||
|
||||
${props => props.type === 'error' && css`
|
||||
border: 1px solid ${colors.ERROR_PRIMARY};
|
||||
color: ${colors.ERROR_PRIMARY};
|
||||
|
||||
&:hover {
|
||||
color: ${colors.WHITE};
|
||||
background: ${colors.ERROR_PRIMARY};
|
||||
}
|
||||
`}
|
||||
|
||||
${props => props.type === 'warning' && css`
|
||||
border: 1px solid ${colors.WARNING_PRIMARY};
|
||||
color: ${colors.WARNING_PRIMARY};
|
||||
|
||||
&:hover {
|
||||
color: ${colors.WHITE};
|
||||
background: ${colors.WARNING_PRIMARY};
|
||||
}
|
||||
`}
|
||||
&:hover {
|
||||
color: ${colors.WHITE};
|
||||
background: ${props => getPrimaryColor(props.type)};
|
||||
}
|
||||
`;
|
||||
|
||||
const IconWrapper = styled.span`
|
||||
@ -75,13 +57,18 @@ const IconWrapper = styled.span`
|
||||
`;
|
||||
|
||||
const NotificationButton = ({
|
||||
type, icon, onClick, children,
|
||||
type, icon, onClick, children, isLoading,
|
||||
}: Props) => (
|
||||
<Wrapper
|
||||
icon={icon}
|
||||
onClick={onClick}
|
||||
type={type}
|
||||
>
|
||||
{isLoading && (
|
||||
<LoaderContent type={type}>
|
||||
<Loader size={30} />
|
||||
</LoaderContent>
|
||||
)}
|
||||
{icon && (
|
||||
<IconWrapper>
|
||||
<Icon
|
||||
@ -102,6 +89,7 @@ NotificationButton.propTypes = {
|
||||
color: PropTypes.string,
|
||||
size: PropTypes.number,
|
||||
}),
|
||||
isLoading: PropTypes.bool,
|
||||
onClick: PropTypes.func,
|
||||
children: PropTypes.node.isRequired,
|
||||
};
|
||||
|
@ -1,9 +1,7 @@
|
||||
/* @flow */
|
||||
|
||||
import * as React from 'react';
|
||||
import styled, { css } from 'styled-components';
|
||||
import colors from 'config/colors';
|
||||
import { getColor, getIcon } from 'utils/notification';
|
||||
import styled from 'styled-components';
|
||||
import { getPrimaryColor, getSecondaryColor, getIcon } from 'utils/notification';
|
||||
import Icon from 'components/Icon';
|
||||
import icons from 'config/icons';
|
||||
import { FONT_WEIGHT, FONT_SIZE } from 'config/variables';
|
||||
@ -28,34 +26,14 @@ type Props = {
|
||||
const Wrapper = styled.div`
|
||||
width: 100%;
|
||||
position: relative;
|
||||
color: ${colors.TEXT_PRIMARY};
|
||||
background: ${colors.TEXT_SECONDARY};
|
||||
padding: 24px 48px 9px 24px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
text-align: left;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
${props => props.type === 'info' && css`
|
||||
color: ${colors.INFO_PRIMARY};
|
||||
background: ${colors.INFO_SECONDARY};
|
||||
`}
|
||||
|
||||
${props => props.type === 'success' && css`
|
||||
color: ${colors.SUCCESS_PRIMARY};
|
||||
background: ${colors.SUCCESS_SECONDARY};
|
||||
`}
|
||||
|
||||
${props => props.type === 'warning' && css`
|
||||
color: ${colors.WARNING_PRIMARY};
|
||||
background: ${colors.WARNING_SECONDARY};
|
||||
`}
|
||||
|
||||
${props => props.type === 'error' && css`
|
||||
color: ${colors.ERROR_PRIMARY};
|
||||
background: ${colors.ERROR_SECONDARY};
|
||||
`}
|
||||
color: ${props => getPrimaryColor(props.type)};
|
||||
background: ${props => getSecondaryColor(props.type)};
|
||||
`;
|
||||
|
||||
const Body = styled.div`
|
||||
@ -119,7 +97,7 @@ const Notification = (props: Props): React$Element<string> => {
|
||||
{props.cancelable && (
|
||||
<CloseClick onClick={() => close()}>
|
||||
<Icon
|
||||
color={getColor(props.type)}
|
||||
color={getPrimaryColor(props.type)}
|
||||
icon={icons.CLOSE}
|
||||
size={20}
|
||||
/>
|
||||
@ -128,7 +106,7 @@ const Notification = (props: Props): React$Element<string> => {
|
||||
<Body>
|
||||
<IconWrapper>
|
||||
<StyledIcon
|
||||
color={getColor(props.type)}
|
||||
color={getPrimaryColor(props.type)}
|
||||
icon={getIcon(props.type)}
|
||||
/>
|
||||
</IconWrapper>
|
||||
|
@ -25,6 +25,7 @@ const InputIconWrapper = styled.div`
|
||||
flex: 1;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
background: white;
|
||||
`;
|
||||
|
||||
const TopLabel = styled.span`
|
||||
@ -43,10 +44,12 @@ const StyledInput = styled.input`
|
||||
color: ${props => (props.color ? props.color : colors.TEXT)};
|
||||
|
||||
border-radius: 2px;
|
||||
|
||||
${props => props.hasAddon && css`
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
`}
|
||||
|
||||
border: 1px solid ${colors.DIVIDER};
|
||||
border-color: ${props => props.borderColor};
|
||||
|
||||
@ -58,6 +61,15 @@ const StyledInput = styled.input`
|
||||
background: ${colors.GRAY_LIGHT};
|
||||
color: ${colors.TEXT_SECONDARY};
|
||||
}
|
||||
|
||||
${props => props.trezorAction && css`
|
||||
z-index: 10001;
|
||||
position: relative; /* bigger than modal container */
|
||||
border-color: ${colors.WHITE};
|
||||
border-width: 2px;
|
||||
transform: translate(-1px, -1px);
|
||||
background: ${colors.DIVIDER};
|
||||
`};
|
||||
`;
|
||||
|
||||
const StyledIcon = styled(Icon)`
|
||||
@ -73,6 +85,49 @@ const BottomText = styled.span`
|
||||
color: ${props => (props.color ? props.color : colors.TEXT_SECONDARY)};
|
||||
`;
|
||||
|
||||
const Overlay = styled.div`
|
||||
${props => props.isPartiallyHidden && css`
|
||||
bottom: 0;
|
||||
border: 1px solid ${colors.DIVIDER};
|
||||
border-radius: 2px;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: linear-gradient(to right,
|
||||
rgba(0,0,0, 0) 0%,
|
||||
rgba(255,255,255, 1) 220px
|
||||
);
|
||||
`}
|
||||
`;
|
||||
|
||||
const TrezorAction = styled.div`
|
||||
display: ${props => (props.action ? 'flex' : 'none')};
|
||||
align-items: center;
|
||||
height: 37px;
|
||||
margin: 0px 10px;
|
||||
padding: 0 14px 0 5px;
|
||||
position: absolute;
|
||||
top: 45px;
|
||||
background: black;
|
||||
color: ${colors.WHITE};
|
||||
border-radius: 5px;
|
||||
line-height: 37px;
|
||||
z-index: 10001;
|
||||
transform: translate(-1px, -1px);
|
||||
`;
|
||||
|
||||
const ArrowUp = styled.div`
|
||||
position: absolute;
|
||||
top: -9px;
|
||||
left: 12px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 9px solid transparent;
|
||||
border-right: 9px solid transparent;
|
||||
border-bottom: 9px solid black;
|
||||
z-index: 10001;
|
||||
`;
|
||||
|
||||
class Input extends PureComponent {
|
||||
getIcon(inputState) {
|
||||
let icon = [];
|
||||
@ -114,8 +169,11 @@ class Input extends PureComponent {
|
||||
color={this.getColor(this.props.state)}
|
||||
/>
|
||||
)}
|
||||
<Overlay isPartiallyHidden={this.props.isPartiallyHidden} />
|
||||
{this.props.icon}
|
||||
<StyledInput
|
||||
isSmallText={this.props.isSmallText}
|
||||
trezorAction={this.props.trezorAction}
|
||||
hasIcon={this.getIcon(this.props.state).length > 0}
|
||||
innerRef={this.props.innerRef}
|
||||
hasAddon={!!this.props.sideAddons}
|
||||
@ -133,6 +191,9 @@ class Input extends PureComponent {
|
||||
name={this.props.name}
|
||||
data-lpignore="true"
|
||||
/>
|
||||
<TrezorAction action={this.props.trezorAction}>
|
||||
<ArrowUp />{this.props.trezorAction}
|
||||
</TrezorAction>
|
||||
</InputIconWrapper>
|
||||
{this.props.sideAddons && this.props.sideAddons.map(sideAddon => sideAddon)}
|
||||
</InputWrapper>
|
||||
@ -156,16 +217,19 @@ Input.propTypes = {
|
||||
autocomplete: PropTypes.string,
|
||||
autocorrect: PropTypes.string,
|
||||
autocapitalize: PropTypes.string,
|
||||
icon: PropTypes.node,
|
||||
spellCheck: PropTypes.string,
|
||||
value: PropTypes.string,
|
||||
onChange: PropTypes.func,
|
||||
state: PropTypes.string,
|
||||
bottomText: PropTypes.string,
|
||||
topLabel: PropTypes.node,
|
||||
trezorAction: PropTypes.node,
|
||||
sideAddons: PropTypes.arrayOf(PropTypes.node),
|
||||
isDisabled: PropTypes.bool,
|
||||
name: PropTypes.string,
|
||||
isSmallText: PropTypes.string,
|
||||
isPartiallyHidden: PropTypes.bool,
|
||||
};
|
||||
|
||||
Input.defaultProps = {
|
||||
|
@ -91,18 +91,14 @@ class WalletType extends PureComponent<Props> {
|
||||
keyboardHandler(event: KeyboardEvent): void {
|
||||
if (event.keyCode === 13) {
|
||||
event.preventDefault();
|
||||
this.changeType(false);
|
||||
this.props.onWalletTypeRequest(false);
|
||||
}
|
||||
}
|
||||
|
||||
keyboardHandler: (event: KeyboardEvent) => void;
|
||||
|
||||
changeType(hidden: boolean, state: ?string) {
|
||||
this.props.onWalletTypeRequest(this.props.device, hidden, state);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { device, onCancel } = this.props;
|
||||
const { device, onCancel, onWalletTypeRequest } = this.props;
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
@ -122,7 +118,7 @@ class WalletType extends PureComponent<Props> {
|
||||
Standard Wallet
|
||||
</Header>
|
||||
<P isSmaller>Continue to access your standard wallet.</P>
|
||||
<StyledButton onClick={() => this.changeType(false, device.state)}>Go to your standard wallet</StyledButton>
|
||||
<StyledButton onClick={() => onWalletTypeRequest(false)}>Go to your standard wallet</StyledButton>
|
||||
</Content>
|
||||
<Content>
|
||||
<Tooltip
|
||||
@ -146,7 +142,7 @@ class WalletType extends PureComponent<Props> {
|
||||
Hidden Wallet
|
||||
</Header>
|
||||
<P isSmaller>You will be asked to enter your passphrase to unlock your hidden wallet.</P>
|
||||
<StyledButton isWhite onClick={() => this.changeType(true, device.state)}>Go to your hidden wallet</StyledButton>
|
||||
<StyledButton isWhite onClick={() => onWalletTypeRequest(true)}>Go to your hidden wallet</StyledButton>
|
||||
</Content>
|
||||
</Wrapper>
|
||||
);
|
||||
|
@ -161,24 +161,18 @@ class Passphrase extends PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
handleCheckboxClick() {
|
||||
// If passphrase was visible and now shouldn't be --> delete the value of passphraseCheckInputValue
|
||||
// doPassphraseInputsMatch
|
||||
// - if passphrase was visible and now shouldn't be --> doPassphraseInputsMatch = false
|
||||
// - because passphraseCheckInputValue will be empty string
|
||||
// - if passphrase wasn't visibe and now should be --> doPassphraseInputsMatch = true
|
||||
// - because passphraseCheckInputValue will be same as passphraseInputValue
|
||||
let doInputsMatch = false;
|
||||
let match = false;
|
||||
if (this.state.shouldShowSingleInput || this.state.passphraseInputValue === this.state.passphraseCheckInputValue) {
|
||||
doInputsMatch = true;
|
||||
match = true;
|
||||
} else {
|
||||
doInputsMatch = !!this.state.isPassphraseHidden;
|
||||
match = !!this.state.isPassphraseHidden;
|
||||
}
|
||||
|
||||
this.setState(previousState => ({
|
||||
isPassphraseHidden: !previousState.isPassphraseHidden,
|
||||
passphraseInputValue: previousState.isPassphraseHidden ? previousState.passphraseInputValue : '',
|
||||
passphraseCheckInputValue: previousState.isPassphraseHidden ? previousState.passphraseInputValue : '',
|
||||
doPassphraseInputsMatch: doInputsMatch,
|
||||
passphraseInputValue: previousState.passphraseInputValue,
|
||||
passphraseCheckInputValue: previousState.passphraseCheckInputValue,
|
||||
doPassphraseInputsMatch: match,
|
||||
}));
|
||||
}
|
||||
|
||||
@ -239,11 +233,9 @@ class Passphrase extends PureComponent<Props, State> {
|
||||
/>
|
||||
</Row>
|
||||
)}
|
||||
|
||||
{!this.state.doPassphraseInputsMatch && (
|
||||
<PassphraseError>Passphrases do not match</PassphraseError>
|
||||
)}
|
||||
|
||||
<Row>
|
||||
<Checkbox
|
||||
isChecked={!this.state.isPassphraseHidden}
|
||||
@ -259,10 +251,8 @@ class Passphrase extends PureComponent<Props, State> {
|
||||
>Enter
|
||||
</Button>
|
||||
</Row>
|
||||
|
||||
<Footer>
|
||||
<P isSmaller>
|
||||
Changed your mind?
|
||||
<P isSmaller>Changed your mind?
|
||||
<LinkButton
|
||||
isGreen
|
||||
onClick={() => this.submitPassphrase(true)}
|
||||
|
@ -5,7 +5,7 @@ import Icon from 'components/Icon';
|
||||
import ICONS from 'config/icons';
|
||||
import colors from 'config/colors';
|
||||
import Notification from 'components/Notification';
|
||||
import { getIcon, getColor } from 'utils/notification';
|
||||
import { getIcon, getPrimaryColor } from 'utils/notification';
|
||||
|
||||
const Wrapper = styled.div``;
|
||||
|
||||
@ -65,7 +65,7 @@ class Group extends PureComponent {
|
||||
|
||||
render() {
|
||||
const { type, groupNotifications, close } = this.props;
|
||||
const color = getColor(type);
|
||||
const color = getPrimaryColor(type);
|
||||
return (
|
||||
<Wrapper>
|
||||
{groupNotifications.length > 1 && (
|
||||
|
@ -54,7 +54,6 @@ class NotificationsGroup extends PureComponent {
|
||||
// key: 5,
|
||||
// title: 'this is a title of warning notification as',
|
||||
// type: 'success',
|
||||
// message: <Link href="link" isGreen>See transaction detail</Link>,
|
||||
// },
|
||||
// {
|
||||
// key: 6,
|
||||
|
70
src/components/trezorActions/Confirm/idnex.js
Normal file
70
src/components/trezorActions/Confirm/idnex.js
Normal file
@ -0,0 +1,70 @@
|
||||
import React from 'react';
|
||||
import RcTooltip from 'rc-tooltip';
|
||||
import colors from 'config/colors';
|
||||
import Link from 'components/Link';
|
||||
import styled from 'styled-components';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const Wrapper = styled.div``;
|
||||
|
||||
const Content = styled.div`
|
||||
max-width: ${props => `${props.maxWidth}px` || 'auto'};
|
||||
`;
|
||||
|
||||
const ContentWrapper = styled.div`
|
||||
display: block;
|
||||
`;
|
||||
|
||||
const ReadMore = styled.div`
|
||||
margin-top: 15px;
|
||||
padding: 10px 0 5px 0;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
color: ${colors.WHITE};
|
||||
border-top: 1px solid ${colors.TEXT_SECONDARY};
|
||||
`;
|
||||
|
||||
const Tooltip = ({
|
||||
maxWidth,
|
||||
className,
|
||||
placement,
|
||||
content,
|
||||
readMoreLink,
|
||||
children,
|
||||
}) => (
|
||||
<Wrapper className={className}>
|
||||
<RcTooltip
|
||||
arrowContent={<div className="rc-tooltip-arrow-inner" />}
|
||||
placement={placement}
|
||||
overlay={() => (
|
||||
<ContentWrapper>
|
||||
<Content maxWidth={maxWidth}>{content}</Content>
|
||||
{readMoreLink && (
|
||||
<Link href={readMoreLink}>
|
||||
<ReadMore>Read more</ReadMore>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
</ContentWrapper>)}
|
||||
>
|
||||
{children}
|
||||
</RcTooltip>
|
||||
</Wrapper>
|
||||
);
|
||||
|
||||
Tooltip.propTypes = {
|
||||
className: PropTypes.string,
|
||||
placement: PropTypes.string,
|
||||
children: PropTypes.oneOfType([
|
||||
PropTypes.element,
|
||||
PropTypes.string,
|
||||
]),
|
||||
maxWidth: PropTypes.number,
|
||||
content: PropTypes.oneOfType([
|
||||
PropTypes.element,
|
||||
PropTypes.string,
|
||||
]),
|
||||
readMoreLink: PropTypes.string,
|
||||
};
|
||||
|
||||
export default Tooltip;
|
@ -17,7 +17,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<!--[if lt IE 8]>
|
||||
<div class="unsupported-browsers">
|
||||
<div class="unsupported-browsers">
|
||||
<div class="header"></div>
|
||||
<h1>Your browser is not supported</h1>
|
||||
<p>Please choose one of the supported browsers</p>
|
||||
@ -33,6 +33,6 @@
|
||||
</div>
|
||||
</div>
|
||||
<![endif]-->
|
||||
<div id="root"></div>
|
||||
<div id="trezor-wallet-root"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -4,7 +4,7 @@ import { render } from 'react-dom';
|
||||
import baseStyles from 'support/styles';
|
||||
import App from 'views/index';
|
||||
|
||||
const root: ?HTMLElement = document.getElementById('root');
|
||||
const root: ?HTMLElement = document.getElementById('trezor-wallet-root');
|
||||
if (root) {
|
||||
baseStyles();
|
||||
render(<App />, root);
|
||||
|
@ -317,6 +317,7 @@ export default function devices(state: State = initialState, action: Action): St
|
||||
return onSelectedDevice(state, action.device);
|
||||
|
||||
case CONNECT.RECEIVE_WALLET_TYPE:
|
||||
case CONNECT.UPDATE_WALLET_TYPE:
|
||||
return onChangeWalletType(state, action.device, action.hidden);
|
||||
|
||||
default:
|
||||
|
@ -26,6 +26,12 @@ export default (state: State = initialState, action: Action): State => {
|
||||
signature: action.signature,
|
||||
};
|
||||
|
||||
case SIGN_VERIFY.VERIFY_PROGRESS:
|
||||
return {
|
||||
...state,
|
||||
isVerifyProgress: action.isVerifyProgress,
|
||||
};
|
||||
|
||||
case SIGN_VERIFY.CLEAR:
|
||||
return {
|
||||
...initialState,
|
||||
|
@ -105,22 +105,22 @@ const WalletService: Middleware = (api: MiddlewareAPI) => (next: MiddlewareDispa
|
||||
api.dispatch(SendFormActionActions.observe(prevState, action));
|
||||
}
|
||||
} else {
|
||||
switch (action.type) {
|
||||
case CONNECT.AUTH_DEVICE:
|
||||
// selected device did changed
|
||||
// try to restore discovery after device authentication
|
||||
api.dispatch(DiscoveryActions.restore());
|
||||
break;
|
||||
case CONNECT.RECEIVE_WALLET_TYPE:
|
||||
if (action.state) {
|
||||
api.dispatch(RouterActions.selectFirstAvailableDevice(true));
|
||||
}
|
||||
api.dispatch(TrezorConnectActions.authorizeDevice());
|
||||
break;
|
||||
default: break;
|
||||
// no changes in common values
|
||||
if (action.type === CONNECT.RECEIVE_WALLET_TYPE) {
|
||||
if (action.device.state) {
|
||||
// redirect to root view (Dashboard) if device was authenticated before
|
||||
api.dispatch(RouterActions.selectFirstAvailableDevice(true));
|
||||
}
|
||||
api.dispatch(TrezorConnectActions.authorizeDevice());
|
||||
}
|
||||
if (action.type === CONNECT.AUTH_DEVICE) {
|
||||
// selected device did changed
|
||||
// try to restore discovery after device authentication
|
||||
api.dispatch(DiscoveryActions.restore());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// even if "selectedDevice" didn't change because it was updated on DEVICE.CHANGED before DEVICE.CONNECT action
|
||||
// try to restore discovery
|
||||
if (action.type === DEVICE.CONNECT) {
|
||||
|
@ -47,6 +47,11 @@ export const routes: Array<Route> = [
|
||||
pattern: '/device/:device/initialize',
|
||||
fields: ['device', 'initialize'],
|
||||
},
|
||||
{
|
||||
name: 'wallet-seedless',
|
||||
pattern: '/device/:device/seedless',
|
||||
fields: ['device', 'seedless'],
|
||||
},
|
||||
{
|
||||
name: 'wallet-firmware-update',
|
||||
pattern: '/device/:device/firmware-update',
|
||||
|
@ -44,7 +44,7 @@ const baseStyles = () => injectGlobal`
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
#root {
|
||||
#trezor-wallet-root {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,9 @@ export const getStatus = (device: TrezorDevice): string => {
|
||||
if (device.mode === 'initialize') {
|
||||
return 'initialize';
|
||||
}
|
||||
if (device.mode === 'seedless') {
|
||||
return 'seedless';
|
||||
}
|
||||
if (device.firmware === 'required') {
|
||||
return 'firmware-required';
|
||||
}
|
||||
@ -57,6 +60,8 @@ export const getStatusName = (deviceStatus: string): string => {
|
||||
return 'Connected (bootloader mode)';
|
||||
case 'initialize':
|
||||
return 'Connected (not initialized)';
|
||||
case 'seedless':
|
||||
return 'Connected (seedless mode)';
|
||||
case 'firmware-required':
|
||||
return 'Connected (update required)';
|
||||
case 'firmware-recommended':
|
||||
@ -81,8 +86,8 @@ export const isDisabled = (selectedDevice: TrezorDevice, devices: Array<TrezorDe
|
||||
if (devices.length < 1) return true; // no devices
|
||||
if (devices.length === 1) {
|
||||
if (!selectedDevice.features) return true; // unacquired, unreadable
|
||||
if (selectedDevice.mode !== 'normal') return true; // bootloader, not initialized
|
||||
if (selectedDevice.firmware === 'required') return true; // bootloader, not initialized
|
||||
if (selectedDevice.mode !== 'normal') return true; // bootloader, not initialized, seedless
|
||||
if (selectedDevice.firmware === 'required') return true;
|
||||
}
|
||||
return false; // default
|
||||
};
|
||||
@ -112,6 +117,7 @@ export const getStatusColor = (deviceStatus: string): string => {
|
||||
return colors.ERROR_PRIMARY;
|
||||
case 'bootloader':
|
||||
case 'initialize':
|
||||
case 'seedless':
|
||||
case 'firmware-recommended':
|
||||
case 'used-in-other-window':
|
||||
case 'unacquired':
|
||||
|
@ -1,7 +1,7 @@
|
||||
import colors from 'config/colors';
|
||||
import icons from 'config/icons';
|
||||
|
||||
const getColor = (type) => {
|
||||
const getPrimaryColor = (type) => {
|
||||
let color;
|
||||
switch (type) {
|
||||
case 'info':
|
||||
@ -23,9 +23,32 @@ const getColor = (type) => {
|
||||
return color;
|
||||
};
|
||||
|
||||
const getSecondaryColor = (type) => {
|
||||
let color;
|
||||
switch (type) {
|
||||
case 'info':
|
||||
color = colors.INFO_SECONDARY;
|
||||
break;
|
||||
case 'error':
|
||||
color = colors.ERROR_SECONDARY;
|
||||
break;
|
||||
case 'warning':
|
||||
color = colors.WARNING_SECONDARY;
|
||||
break;
|
||||
case 'success':
|
||||
color = colors.SUCCESS_SECONDARY;
|
||||
break;
|
||||
default:
|
||||
color = null;
|
||||
}
|
||||
|
||||
return color;
|
||||
};
|
||||
|
||||
const getIcon = type => icons[type.toUpperCase()];
|
||||
|
||||
export {
|
||||
getColor,
|
||||
getPrimaryColor,
|
||||
getSecondaryColor,
|
||||
getIcon,
|
||||
};
|
@ -1,14 +1,21 @@
|
||||
/* @flow */
|
||||
import React from 'react';
|
||||
import { QRCode } from 'react-qr-svg';
|
||||
<<<<<<< HEAD
|
||||
import styled, { css } from 'styled-components';
|
||||
=======
|
||||
import styled from 'styled-components';
|
||||
import media from 'styled-media-query';
|
||||
|
||||
import { H2 } from 'components/Heading';
|
||||
>>>>>>> master
|
||||
import Button from 'components/Button';
|
||||
import Icon from 'components/Icon';
|
||||
import Tooltip from 'components/Tooltip';
|
||||
import Input from 'components/inputs/Input';
|
||||
|
||||
import ICONS from 'config/icons';
|
||||
import colors from 'config/colors';
|
||||
import { FONT_SIZE, FONT_WEIGHT, FONT_FAMILY } from 'config/variables';
|
||||
import { CONTEXT_DEVICE } from 'actions/constants/modal';
|
||||
|
||||
import Content from 'views/Wallet/components/Content';
|
||||
@ -23,10 +30,9 @@ const Label = styled.div`
|
||||
`;
|
||||
|
||||
const AddressWrapper = styled.div`
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: ${props => (props.isShowingQrCode ? 'column' : 'row')};
|
||||
flex-direction: row;
|
||||
`;
|
||||
|
||||
const StyledQRCode = styled(QRCode)`
|
||||
@ -35,87 +41,21 @@ const StyledQRCode = styled(QRCode)`
|
||||
border: 1px solid ${colors.BODY};
|
||||
`;
|
||||
|
||||
const ValueWrapper = styled.div`
|
||||
font-size: ${FONT_SIZE.SMALL};
|
||||
height: 40px;
|
||||
font-weight: ${FONT_WEIGHT.SMALLEST};
|
||||
line-height: 1.42857143;
|
||||
font-family: ${FONT_FAMILY.MONOSPACE};
|
||||
color: ${colors.TEXT_PRIMARY};
|
||||
border: 1px solid ${colors.DIVIDER};
|
||||
border-radius: 3px;
|
||||
padding: 10px 12px;
|
||||
padding-right: 38px;
|
||||
position: relative;
|
||||
flex: 1;
|
||||
user-select: all;
|
||||
|
||||
${props => props.isHidden && css`
|
||||
padding-right: 6px;
|
||||
user-select: none;
|
||||
border-radius: 3px 0px 0px 3px;
|
||||
&:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: linear-gradient(to right,
|
||||
rgba(255,255,255, 0) 0%,
|
||||
rgba(255,255,255, 1) 220px
|
||||
);
|
||||
pointer-events: none; /* so the text is still selectable */
|
||||
}
|
||||
`};
|
||||
|
||||
${props => props.isVerifying && css`
|
||||
z-index: 10001; /* bigger than modal container */
|
||||
border-color: ${colors.WHITE};
|
||||
border-width: 2px;
|
||||
transform: translate(-1px, -1px);
|
||||
background: ${colors.DIVIDER};
|
||||
`};
|
||||
`;
|
||||
|
||||
const ArrowUp = styled.div`
|
||||
position: absolute;
|
||||
top: 35px;
|
||||
left: 70px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 9px solid transparent;
|
||||
border-right: 9px solid transparent;
|
||||
border-bottom: 9px solid black;
|
||||
z-index: 10001;
|
||||
`;
|
||||
|
||||
const AddressInfoText = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 37px;
|
||||
margin: 0px 2px;
|
||||
padding: 0 14px 0 5px;
|
||||
position: absolute;
|
||||
top: 45px;
|
||||
background: black;
|
||||
color: ${colors.WHITE};
|
||||
border-radius: 5px;
|
||||
line-height: 37px;
|
||||
z-index: 10001;
|
||||
transform: translate(-1px, -1px);
|
||||
`;
|
||||
|
||||
const ShowAddressButton = styled(Button)`
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 10px;
|
||||
|
||||
min-width: 195px;
|
||||
padding: 0;
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
height: 40px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
|
||||
${media.lessThan('795px')`
|
||||
margin-top: 10px;
|
||||
`}
|
||||
`;
|
||||
|
||||
const ShowAddressIcon = styled(Icon)`
|
||||
@ -128,9 +68,28 @@ const EyeButton = styled(Button)`
|
||||
z-index: 10001;
|
||||
padding: 0;
|
||||
width: 30px;
|
||||
background: white;
|
||||
top: 5px;
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
|
||||
&:hover {
|
||||
background: white;
|
||||
}
|
||||
`;
|
||||
|
||||
const Row = styled.div`
|
||||
display: flex;
|
||||
width: 100%;
|
||||
|
||||
${media.lessThan('795px')`
|
||||
flex-direction: column;
|
||||
`}
|
||||
`;
|
||||
|
||||
const QrWrapper = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
`;
|
||||
|
||||
const AccountReceive = (props: Props) => {
|
||||
@ -159,57 +118,51 @@ const AccountReceive = (props: Props) => {
|
||||
return (
|
||||
<Content>
|
||||
<React.Fragment>
|
||||
<Title>Receive Ethereum or tokens</Title>
|
||||
<AddressWrapper
|
||||
isShowingQrCode={addressVerified || addressUnverified}
|
||||
>
|
||||
{isAddressVerifying && (
|
||||
<AddressInfoText>Confirm address on Trezor</AddressInfoText>
|
||||
)}
|
||||
{((addressVerified || addressUnverified) && !isAddressVerifying) && (
|
||||
<Tooltip
|
||||
placement="left"
|
||||
content={(
|
||||
<VerifyAddressTooltip
|
||||
isConnected={device.connected}
|
||||
isAvailable={device.available}
|
||||
addressUnverified={addressUnverified}
|
||||
/>
|
||||
)}
|
||||
>
|
||||
<EyeButton
|
||||
isTransparent
|
||||
onClick={() => props.showAddress(account.addressPath)}
|
||||
>
|
||||
|
||||
<Icon
|
||||
icon={addressUnverified ? ICONS.EYE_CROSSED : ICONS.EYE}
|
||||
color={addressUnverified ? colors.ERROR_PRIMARY : colors.TEXT_PRIMARY}
|
||||
/>
|
||||
|
||||
</EyeButton>
|
||||
</Tooltip>
|
||||
)}
|
||||
<ValueWrapper
|
||||
isHidden={isAddressHidden}
|
||||
isVerifying={isAddressVerifying}
|
||||
>
|
||||
{address}
|
||||
</ValueWrapper>
|
||||
{isAddressVerifying && (
|
||||
<React.Fragment>
|
||||
<ArrowUp />
|
||||
<AddressInfoText>
|
||||
<Icon
|
||||
icon={ICONS.T1}
|
||||
color={colors.WHITE}
|
||||
/>
|
||||
<H2>Receive Ethereum or tokens</H2>
|
||||
<AddressWrapper isShowingQrCode={addressVerified || addressUnverified}>
|
||||
<Label>Address</Label>
|
||||
<Row>
|
||||
<Input
|
||||
type="text"
|
||||
value={address}
|
||||
isPartiallyHidden={isAddressHidden}
|
||||
trezorAction={isAddressVerifying ? (
|
||||
<React.Fragment>
|
||||
<Icon
|
||||
icon={ICONS.T1}
|
||||
color={colors.WHITE}
|
||||
/>
|
||||
Check address on your Trezor
|
||||
</AddressInfoText>
|
||||
</React.Fragment>
|
||||
)}
|
||||
{(addressVerified || addressUnverified) && (
|
||||
<React.Fragment>
|
||||
</React.Fragment>
|
||||
) : null}
|
||||
icon={((addressVerified || addressUnverified) && !isAddressVerifying) && (
|
||||
<Tooltip
|
||||
placement="left"
|
||||
content={(
|
||||
<VerifyAddressTooltip
|
||||
isConnected={device.connected}
|
||||
isAvailable={device.available}
|
||||
addressUnverified={addressUnverified}
|
||||
/>
|
||||
)}
|
||||
>
|
||||
<EyeButton onClick={() => props.showAddress(account.addressPath)}>
|
||||
<Icon
|
||||
icon={addressUnverified ? ICONS.EYE_CROSSED : ICONS.EYE}
|
||||
color={addressUnverified ? colors.ERROR_PRIMARY : colors.TEXT_PRIMARY}
|
||||
/>
|
||||
</EyeButton>
|
||||
</Tooltip>
|
||||
)}
|
||||
/>
|
||||
{!(addressVerified || addressUnverified) && (
|
||||
<ShowAddressButton onClick={() => props.showAddress(account.addressPath)} isDisabled={device.connected && !discovery.completed}>
|
||||
<ShowAddressIcon icon={ICONS.EYE} color={colors.WHITE} />Show full address
|
||||
</ShowAddressButton>
|
||||
)}
|
||||
</Row>
|
||||
{(addressVerified || addressUnverified) && !isAddressVerifying && (
|
||||
<QrWrapper>
|
||||
<Label>QR code</Label>
|
||||
<StyledQRCode
|
||||
bgColor="#FFFFFF"
|
||||
@ -218,12 +171,7 @@ const AccountReceive = (props: Props) => {
|
||||
style={{ width: 150 }}
|
||||
value={account.address}
|
||||
/>
|
||||
</React.Fragment>
|
||||
)}
|
||||
{!(addressVerified || addressUnverified) && (
|
||||
<ShowAddressButton onClick={() => props.showAddress(account.addressPath)} isDisabled={device.connected && !discovery.completed}>
|
||||
<ShowAddressIcon icon={ICONS.EYE} color={colors.WHITE} />Show full address
|
||||
</ShowAddressButton>
|
||||
</QrWrapper>
|
||||
)}
|
||||
</AddressWrapper>
|
||||
</React.Fragment>
|
||||
|
@ -13,7 +13,8 @@ type OwnProps = {}
|
||||
export type StateProps = {
|
||||
selectedAccount: $ElementType<State, 'selectedAccount'>,
|
||||
signature: string,
|
||||
isSignProgress: boolean
|
||||
isSignProgress: boolean,
|
||||
isVerifyProgress: boolean
|
||||
}
|
||||
|
||||
export type DispatchProps = {
|
||||
@ -26,6 +27,7 @@ const mapStateToProps: MapStateToProps<State, OwnProps, StateProps> = (state: St
|
||||
selectedAccount: state.selectedAccount,
|
||||
signature: state.signVerifyReducer.signature,
|
||||
isSignProgress: state.signVerifyReducer.isSignProgress,
|
||||
isVerifyProgress: state.signVerifyReducer.isVerifyProgress,
|
||||
});
|
||||
|
||||
const mapDispatchToProps: MapDispatchToProps<Dispatch, OwnProps, DispatchProps> = (dispatch: Dispatch): DispatchProps => ({
|
||||
|
37
src/views/Wallet/views/Seedless/index.js
Normal file
37
src/views/Wallet/views/Seedless/index.js
Normal file
@ -0,0 +1,37 @@
|
||||
import styled from 'styled-components';
|
||||
import { H2 } from 'components/Heading';
|
||||
import Button from 'components/Button';
|
||||
import Paragraph from 'components/Paragraph';
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
display: flex;
|
||||
flex: 1;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
`;
|
||||
|
||||
const Row = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
`;
|
||||
|
||||
const StyledParagraph = styled(Paragraph)`
|
||||
margin: 10px 50px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
`;
|
||||
|
||||
const Seedless = () => (
|
||||
<Wrapper>
|
||||
<Row>
|
||||
<H2>Device is in seedless mode</H2>
|
||||
<StyledParagraph>It's not suitable to use this service.</StyledParagraph>
|
||||
</Row>
|
||||
</Wrapper>
|
||||
);
|
||||
|
||||
export default connect(null, null)(Seedless);
|
@ -26,6 +26,7 @@ import WalletSettings from 'views/Wallet/views/WalletSettings';
|
||||
import WalletBootloader from 'views/Wallet/views/Bootloader';
|
||||
import WalletFirmwareUpdate from 'views/Wallet/views/FirmwareUpdate';
|
||||
import WalletInitialize from 'views/Wallet/views/Initialize';
|
||||
import WalletSeedless from 'views/Wallet/views/Seedless';
|
||||
import WalletAcquire from 'views/Wallet/views/Acquire';
|
||||
import WalletUnreadableDevice from 'views/Wallet/views/UnreadableDevice';
|
||||
|
||||
@ -47,6 +48,7 @@ const App = () => (
|
||||
<Route exact path={getPattern('wallet-unreadable')} component={WalletUnreadableDevice} />
|
||||
<Route exact path={getPattern('wallet-bootloader')} component={WalletBootloader} />
|
||||
<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-device-settings')} component={WalletDeviceSettings} />
|
||||
<Route exact path={getPattern('wallet-account-summary')} component={AccountSummary} />
|
||||
|
77
yarn.lock
77
yarn.lock
@ -1690,6 +1690,10 @@ balanced-match@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
||||
|
||||
base16@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/base16/-/base16-1.0.0.tgz#e297f60d7ec1014a7a971a39ebc8a98c0b681e70"
|
||||
|
||||
base64-js@0.0.8:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-0.0.8.tgz#1101e9544f4a76b1bc3b26d452ca96d7a35e7978"
|
||||
@ -4149,6 +4153,24 @@ fb-watchman@^2.0.0:
|
||||
dependencies:
|
||||
bser "^2.0.0"
|
||||
|
||||
fbemitter@^2.0.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/fbemitter/-/fbemitter-2.1.1.tgz#523e14fdaf5248805bb02f62efc33be703f51865"
|
||||
dependencies:
|
||||
fbjs "^0.8.4"
|
||||
|
||||
fbjs@^0.8.0, fbjs@^0.8.4, fbjs@^0.8.5:
|
||||
version "0.8.17"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd"
|
||||
dependencies:
|
||||
core-js "^1.0.0"
|
||||
isomorphic-fetch "^2.1.1"
|
||||
loose-envify "^1.0.0"
|
||||
object-assign "^4.1.0"
|
||||
promise "^7.1.1"
|
||||
setimmediate "^1.0.5"
|
||||
ua-parser-js "^0.7.18"
|
||||
|
||||
fbjs@^0.8.16:
|
||||
version "0.8.16"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
|
||||
@ -4161,18 +4183,6 @@ fbjs@^0.8.16:
|
||||
setimmediate "^1.0.5"
|
||||
ua-parser-js "^0.7.9"
|
||||
|
||||
fbjs@^0.8.5:
|
||||
version "0.8.17"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd"
|
||||
dependencies:
|
||||
core-js "^1.0.0"
|
||||
isomorphic-fetch "^2.1.1"
|
||||
loose-envify "^1.0.0"
|
||||
object-assign "^4.1.0"
|
||||
promise "^7.1.1"
|
||||
setimmediate "^1.0.5"
|
||||
ua-parser-js "^0.7.18"
|
||||
|
||||
fd-slicer@~1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
|
||||
@ -4342,6 +4352,13 @@ flush-write-stream@^1.0.0:
|
||||
inherits "^2.0.1"
|
||||
readable-stream "^2.0.4"
|
||||
|
||||
flux@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/flux/-/flux-3.1.3.tgz#d23bed515a79a22d933ab53ab4ada19d05b2f08a"
|
||||
dependencies:
|
||||
fbemitter "^2.0.0"
|
||||
fbjs "^0.8.0"
|
||||
|
||||
follow-redirects@^1.0.0:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.4.1.tgz#d8120f4518190f55aac65bb6fc7b85fcd666d6aa"
|
||||
@ -6390,10 +6407,18 @@ lodash.camelcase@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
|
||||
|
||||
lodash.curry@^4.0.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.curry/-/lodash.curry-4.1.1.tgz#248e36072ede906501d75966200a86dab8b23170"
|
||||
|
||||
lodash.debounce@^4.0.8:
|
||||
version "4.0.8"
|
||||
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
|
||||
|
||||
lodash.flow@^3.3.0:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.flow/-/lodash.flow-3.5.0.tgz#87bf40292b8cf83e4e8ce1a3ae4209e20071675a"
|
||||
|
||||
lodash.isarguments@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a"
|
||||
@ -8183,6 +8208,10 @@ punycode@^2.1.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
||||
|
||||
pure-color@^1.2.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/pure-color/-/pure-color-1.3.0.tgz#1fe064fb0ac851f0de61320a8bf796836422f33e"
|
||||
|
||||
q@^1.1.2:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
|
||||
@ -8347,6 +8376,15 @@ rc@^1.1.7:
|
||||
minimist "^1.2.0"
|
||||
strip-json-comments "~2.0.1"
|
||||
|
||||
react-base16-styling@^0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/react-base16-styling/-/react-base16-styling-0.6.0.tgz#ef2156d66cf4139695c8a167886cb69ea660792c"
|
||||
dependencies:
|
||||
base16 "^1.0.0"
|
||||
lodash.curry "^4.0.1"
|
||||
lodash.flow "^3.3.0"
|
||||
pure-color "^1.2.0"
|
||||
|
||||
"react-dom@^15.4.2 || ^16.0.0", react-dom@^16.2.0:
|
||||
version "16.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.2.0.tgz#69003178601c0ca19b709b33a83369fe6124c044"
|
||||
@ -8377,6 +8415,15 @@ react-is@^16.3.1:
|
||||
version "16.4.1"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.4.1.tgz#d624c4650d2c65dbd52c72622bbf389435d9776e"
|
||||
|
||||
react-json-view@^1.19.1:
|
||||
version "1.19.1"
|
||||
resolved "https://registry.yarnpkg.com/react-json-view/-/react-json-view-1.19.1.tgz#95d8e59e024f08a25e5dc8f076ae304eed97cf5c"
|
||||
dependencies:
|
||||
flux "^3.1.3"
|
||||
react-base16-styling "^0.6.0"
|
||||
react-lifecycles-compat "^3.0.4"
|
||||
react-textarea-autosize "^6.1.0"
|
||||
|
||||
react-lifecycles-compat@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
||||
@ -8453,9 +8500,15 @@ react-select@2.0.0:
|
||||
react-input-autosize "^2.2.1"
|
||||
react-transition-group "^2.2.1"
|
||||
|
||||
<<<<<<< HEAD
|
||||
react-textarea-autosize@^7.0.4:
|
||||
version "7.0.4"
|
||||
resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-7.0.4.tgz#4e4be649b544a88713e7b5043f76950f35d3d503"
|
||||
=======
|
||||
react-textarea-autosize@^6.1.0:
|
||||
version "6.1.0"
|
||||
resolved "http://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-6.1.0.tgz#df91387f8a8f22020b77e3833c09829d706a09a5"
|
||||
>>>>>>> master
|
||||
dependencies:
|
||||
prop-types "^15.6.0"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user