mirror of
https://github.com/trezor/trezor-wallet
synced 2024-11-24 09:18:09 +00:00
Merge branch 'master' into fix/router
This commit is contained in:
commit
3a783ce38b
@ -4,6 +4,9 @@
|
|||||||
"plugin:flowtype/recommended",
|
"plugin:flowtype/recommended",
|
||||||
"plugin:jest/recommended"
|
"plugin:jest/recommended"
|
||||||
],
|
],
|
||||||
|
"globals": {
|
||||||
|
"COMMITHASH": true
|
||||||
|
},
|
||||||
"env": {
|
"env": {
|
||||||
"browser": true,
|
"browser": true,
|
||||||
"jest": true
|
"jest": true
|
||||||
|
@ -1,11 +1,19 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
rootDir: './src',
|
rootDir: './src',
|
||||||
|
automock: false,
|
||||||
|
coverageDirectory: 'coverage/',
|
||||||
collectCoverage: true,
|
collectCoverage: true,
|
||||||
testURL: 'http://localhost',
|
testURL: 'http://localhost',
|
||||||
modulePathIgnorePatterns: [
|
modulePathIgnorePatterns: [
|
||||||
'node_modules',
|
'node_modules',
|
||||||
|
'utils/windowUtils.js',
|
||||||
|
'utils/promiseUtils.js',
|
||||||
|
'utils/networkUtils.js',
|
||||||
],
|
],
|
||||||
collectCoverageFrom: [
|
collectCoverageFrom: [
|
||||||
'utils/**.js',
|
'utils/**.js',
|
||||||
],
|
],
|
||||||
|
setupFiles: [
|
||||||
|
'./support/setupJest.js',
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
@ -31,8 +31,11 @@
|
|||||||
"ethereumjs-tx": "^1.3.3",
|
"ethereumjs-tx": "^1.3.3",
|
||||||
"ethereumjs-units": "^0.2.0",
|
"ethereumjs-units": "^0.2.0",
|
||||||
"ethereumjs-util": "^5.1.4",
|
"ethereumjs-util": "^5.1.4",
|
||||||
|
"git-revision-webpack-plugin": "^3.0.3",
|
||||||
|
"flow-webpack-plugin": "^1.2.0",
|
||||||
"hdkey": "^0.8.0",
|
"hdkey": "^0.8.0",
|
||||||
"html-webpack-plugin": "^3.2.0",
|
"html-webpack-plugin": "^3.2.0",
|
||||||
|
"jest-fetch-mock": "^1.6.5",
|
||||||
"npm-run-all": "^4.1.3",
|
"npm-run-all": "^4.1.3",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"raf": "^3.4.0",
|
"raf": "^3.4.0",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import styled from 'styled-components';
|
import styled, { css } from 'styled-components';
|
||||||
import colors from 'config/colors';
|
import colors from 'config/colors';
|
||||||
import Icon from 'components/Icon';
|
import Icon from 'components/Icon';
|
||||||
import icons from 'config/icons';
|
import icons from 'config/icons';
|
||||||
@ -34,8 +34,10 @@ const IconWrapper = styled.div`
|
|||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&:focus {
|
&:focus {
|
||||||
border: 1px solid ${colors.TEXT_PRIMARY};
|
${props => !props.checked && css`
|
||||||
background: ${props => (props.checked ? colors.TEXT_PRIMARY : colors.WHITE)};
|
border: 1px solid ${colors.GREEN_PRIMARY};
|
||||||
|
`}
|
||||||
|
background: ${props => (props.checked ? colors.GREEN_PRIMARY : colors.WHITE)};
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ const Copy = styled.div`
|
|||||||
|
|
||||||
const Footer = ({ toggle }) => (
|
const Footer = ({ toggle }) => (
|
||||||
<Wrapper>
|
<Wrapper>
|
||||||
<Copy>© {getYear(new Date())}</Copy>
|
<Copy title={COMMITHASH}>© {getYear(new Date())}</Copy>
|
||||||
<StyledLink href="http://satoshilabs.com" target="_blank" rel="noreferrer noopener" isGreen>SatoshiLabs</StyledLink>
|
<StyledLink href="http://satoshilabs.com" target="_blank" rel="noreferrer noopener" isGreen>SatoshiLabs</StyledLink>
|
||||||
<StyledLink href="/assets/tos.pdf" target="_blank" rel="noreferrer noopener" isGreen>Terms</StyledLink>
|
<StyledLink href="/assets/tos.pdf" target="_blank" rel="noreferrer noopener" isGreen>Terms</StyledLink>
|
||||||
<StyledLink onClick={toggle} isGreen>Show Log</StyledLink>
|
<StyledLink onClick={toggle} isGreen>Show Log</StyledLink>
|
||||||
|
@ -27,7 +27,7 @@ const SvgWrapper = styled.svg`
|
|||||||
|
|
||||||
:hover {
|
:hover {
|
||||||
path {
|
path {
|
||||||
fill: ${props => props.hoverColor || colors.TEXT_SECONDARY}
|
fill: ${props => props.hoverColor}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -26,10 +26,7 @@ const P = ({ children, className, isSmaller = false }) => (
|
|||||||
P.propTypes = {
|
P.propTypes = {
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
isSmaller: PropTypes.bool,
|
isSmaller: PropTypes.bool,
|
||||||
children: PropTypes.oneOfType([
|
children: PropTypes.node,
|
||||||
PropTypes.array,
|
|
||||||
PropTypes.string,
|
|
||||||
]),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default P;
|
export default P;
|
||||||
|
@ -114,6 +114,7 @@ class Input extends Component {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<StyledInput
|
<StyledInput
|
||||||
|
innerRef={this.props.innerRef}
|
||||||
hasAddon={!!this.props.sideAddons}
|
hasAddon={!!this.props.sideAddons}
|
||||||
type={this.props.type}
|
type={this.props.type}
|
||||||
placeholder={this.props.placeholder}
|
placeholder={this.props.placeholder}
|
||||||
@ -143,13 +144,14 @@ class Input extends Component {
|
|||||||
|
|
||||||
Input.propTypes = {
|
Input.propTypes = {
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
|
innerRef: PropTypes.func,
|
||||||
placeholder: PropTypes.string,
|
placeholder: PropTypes.string,
|
||||||
type: PropTypes.string,
|
type: PropTypes.string,
|
||||||
autoComplete: PropTypes.string,
|
autoComplete: PropTypes.string,
|
||||||
autoCorrect: PropTypes.string,
|
autoCorrect: PropTypes.string,
|
||||||
autoCapitalize: PropTypes.string,
|
autoCapitalize: PropTypes.string,
|
||||||
spellCheck: PropTypes.string,
|
spellCheck: PropTypes.string,
|
||||||
value: PropTypes.string.isRequired,
|
value: PropTypes.string,
|
||||||
onChange: PropTypes.func,
|
onChange: PropTypes.func,
|
||||||
state: PropTypes.string,
|
state: PropTypes.string,
|
||||||
bottomText: PropTypes.string,
|
bottomText: PropTypes.string,
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import raf from 'raf';
|
import raf from 'raf';
|
||||||
import colors from 'config/colors';
|
import colors from 'config/colors';
|
||||||
|
import { H2 } from 'components/Heading';
|
||||||
import P from 'components/Paragraph';
|
import P from 'components/Paragraph';
|
||||||
import { FONT_SIZE } from 'config/variables';
|
import { FONT_SIZE } from 'config/variables';
|
||||||
import Link from 'components/Link';
|
import Link from 'components/Link';
|
||||||
@ -23,7 +24,10 @@ const Label = styled.div`
|
|||||||
padding-bottom: 5px;
|
padding-bottom: 5px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const PassphraseError = styled.div``;
|
const PassphraseError = styled.div`
|
||||||
|
margin-top: 8px;
|
||||||
|
color: ${colors.ERROR_PRIMARY};
|
||||||
|
`;
|
||||||
|
|
||||||
const Row = styled.div`
|
const Row = styled.div`
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -137,22 +141,25 @@ export default class PinModal extends Component<Props, State> {
|
|||||||
} = this.state;
|
} = this.state;
|
||||||
// } = this.props.modal;
|
// } = this.props.modal;
|
||||||
|
|
||||||
let passphraseInputValue: string = passphrase;
|
const passphraseInputValue: string = passphrase;
|
||||||
let passphraseRevisionInputValue: string = passphraseRevision;
|
const passphraseRevisionInputValue: string = passphraseRevision;
|
||||||
if (!visible && !passphraseFocused) {
|
// if (!visible && !passphraseFocused) {
|
||||||
passphraseInputValue = passphrase.replace(/./g, '•');
|
// passphraseInputValue = passphrase.replace(/./g, '•');
|
||||||
}
|
// }
|
||||||
if (!visible && !passphraseRevisionFocused) {
|
// if (!visible && !passphraseRevisionFocused) {
|
||||||
passphraseRevisionInputValue = passphraseRevision.replace(/./g, '•');
|
// passphraseRevisionInputValue = passphraseRevision.replace(/./g, '•');
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
if (this.passphraseInput) {
|
if (this.passphraseInput) {
|
||||||
this.passphraseInput.value = passphraseInputValue;
|
// this.passphraseInput.value = passphraseInputValue;
|
||||||
this.passphraseInput.setAttribute('type', visible || (!visible && !passphraseFocused) ? 'text' : 'password');
|
// this.passphraseInput.setAttribute('type', visible || (!visible && !passphraseFocused) ? 'text' : 'password');
|
||||||
|
this.passphraseInput.setAttribute('type', visible ? 'text' : 'password');
|
||||||
}
|
}
|
||||||
if (this.passphraseRevisionInput) {
|
if (this.passphraseRevisionInput) {
|
||||||
this.passphraseRevisionInput.value = passphraseRevisionInputValue;
|
// this.passphraseRevisionInput.value = passphraseRevisionInputValue;
|
||||||
this.passphraseRevisionInput.setAttribute('type', visible || (!visible && !passphraseRevisionFocused) ? 'text' : 'password');
|
// this.passphraseRevisionInput.setAttribute('type', visible || (!visible && !passphraseRevisionFocused) ? 'text' : 'password');
|
||||||
|
this.passphraseRevisionInput.setAttribute('type', visible ? 'text' : 'password');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,6 +181,14 @@ export default class PinModal extends Component<Props, State> {
|
|||||||
match: previousState.singleInput || previousState.passphraseRevision === value,
|
match: previousState.singleInput || previousState.passphraseRevision === value,
|
||||||
passphrase: value,
|
passphrase: value,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
if (this.state.visible && this.passphraseRevisionInput) {
|
||||||
|
this.setState({
|
||||||
|
match: true,
|
||||||
|
passphraseRevision: value,
|
||||||
|
});
|
||||||
|
this.passphraseRevisionInput.value = value;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.setState(previousState => ({
|
this.setState(previousState => ({
|
||||||
match: previousState.passphrase === value,
|
match: previousState.passphrase === value,
|
||||||
@ -211,12 +226,29 @@ export default class PinModal extends Component<Props, State> {
|
|||||||
this.setState({
|
this.setState({
|
||||||
visible: true,
|
visible: true,
|
||||||
});
|
});
|
||||||
|
if (this.passphraseRevisionInput) {
|
||||||
|
this.passphraseRevisionInput.disabled = true;
|
||||||
|
this.passphraseRevisionInput.value = this.state.passphrase;
|
||||||
|
this.setState(previousState => ({
|
||||||
|
passphraseRevision: previousState.passphrase,
|
||||||
|
match: true,
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onPassphraseHide = (): void => {
|
onPassphraseHide = (): void => {
|
||||||
this.setState({
|
this.setState({
|
||||||
visible: false,
|
visible: false,
|
||||||
});
|
});
|
||||||
|
if (this.passphraseRevisionInput) {
|
||||||
|
const emptyPassphraseRevisionValue = '';
|
||||||
|
this.passphraseRevisionInput.value = emptyPassphraseRevisionValue;
|
||||||
|
this.setState(previousState => ({
|
||||||
|
passphraseRevision: emptyPassphraseRevisionValue,
|
||||||
|
match: emptyPassphraseRevisionValue === previousState.passphrase,
|
||||||
|
}));
|
||||||
|
this.passphraseRevisionInput.disabled = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
submit = (empty: boolean = false): void => {
|
submit = (empty: boolean = false): void => {
|
||||||
@ -232,7 +264,7 @@ export default class PinModal extends Component<Props, State> {
|
|||||||
//this.passphraseRevisionInput.style.display = 'none';
|
//this.passphraseRevisionInput.style.display = 'none';
|
||||||
//this.passphraseRevisionInput.setAttribute('readonly', 'readonly');
|
//this.passphraseRevisionInput.setAttribute('readonly', 'readonly');
|
||||||
|
|
||||||
const p = passphrase;
|
// const p = passphrase;
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
passphrase: '',
|
passphrase: '',
|
||||||
@ -271,11 +303,10 @@ export default class PinModal extends Component<Props, State> {
|
|||||||
//let passphraseRevisionInputType: string = visible || passphraseRevisionFocused ? "text" : "password";
|
//let passphraseRevisionInputType: string = visible || passphraseRevisionFocused ? "text" : "password";
|
||||||
|
|
||||||
const showPassphraseCheckboxFn: Function = visible ? this.onPassphraseHide : this.onPassphraseShow;
|
const showPassphraseCheckboxFn: Function = visible ? this.onPassphraseHide : this.onPassphraseShow;
|
||||||
console.log('passphraseInputType', passphraseInputType);
|
|
||||||
return (
|
return (
|
||||||
<Wrapper>
|
<Wrapper>
|
||||||
{/* ?<H2>Enter { deviceLabel } passphrase</H2> */}
|
<H2>Enter { deviceLabel } passphrase</H2>
|
||||||
{/* <P isSmaller>Note that passphrase is case-sensitive.</P> */}
|
<P isSmaller>Note that passphrase is case-sensitive.</P>
|
||||||
<Row>
|
<Row>
|
||||||
<Label>Passphrase</Label>
|
<Label>Passphrase</Label>
|
||||||
<Input
|
<Input
|
||||||
@ -289,7 +320,7 @@ export default class PinModal extends Component<Props, State> {
|
|||||||
data-lpignore="true"
|
data-lpignore="true"
|
||||||
onFocus={() => this.onPassphraseFocus('passphrase')}
|
onFocus={() => this.onPassphraseFocus('passphrase')}
|
||||||
onBlur={() => this.onPassphraseBlur('passphrase')}
|
onBlur={() => this.onPassphraseBlur('passphrase')}
|
||||||
tabIndex="1"
|
tabIndex="0"
|
||||||
/>
|
/>
|
||||||
</Row>
|
</Row>
|
||||||
{!singleInput && (
|
{!singleInput && (
|
||||||
@ -306,7 +337,6 @@ export default class PinModal extends Component<Props, State> {
|
|||||||
data-lpignore="true"
|
data-lpignore="true"
|
||||||
onFocus={() => this.onPassphraseFocus('revision')}
|
onFocus={() => this.onPassphraseFocus('revision')}
|
||||||
onBlur={() => this.onPassphraseBlur('revision')}
|
onBlur={() => this.onPassphraseBlur('revision')}
|
||||||
tabIndex="2"
|
|
||||||
/>
|
/>
|
||||||
{!match && passphraseRevisionTouched && <PassphraseError>Passphrases do not match</PassphraseError> }
|
{!match && passphraseRevisionTouched && <PassphraseError>Passphrases do not match</PassphraseError> }
|
||||||
</Row>
|
</Row>
|
||||||
@ -315,7 +345,7 @@ export default class PinModal extends Component<Props, State> {
|
|||||||
<Checkbox onClick={showPassphraseCheckboxFn} checked={visible}>Show passphrase</Checkbox>
|
<Checkbox onClick={showPassphraseCheckboxFn} checked={visible}>Show passphrase</Checkbox>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
<Button type="button" tabIndex="4" disabled={!match} onClick={event => this.submit()}>Enter</Button>
|
<Button type="button" disabled={!match} onClick={() => this.submit()}>Enter</Button>
|
||||||
</Row>
|
</Row>
|
||||||
<Footer>
|
<Footer>
|
||||||
<P isSmaller>If you want to access your default account</P>
|
<P isSmaller>If you want to access your default account</P>
|
||||||
|
@ -57,6 +57,7 @@ export default function modal(state: State = initialState, action: Action): Stat
|
|||||||
if (state.opened && action.device.path === state.device.path && action.device.status === 'occupied') {
|
if (state.opened && action.device.path === state.device.path && action.device.status === 'occupied') {
|
||||||
return initialState;
|
return initialState;
|
||||||
}
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
|
|
||||||
case DEVICE.DISCONNECT:
|
case DEVICE.DISCONNECT:
|
||||||
|
1
src/support/setupJest.js
Normal file
1
src/support/setupJest.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
global.fetch = require('jest-fetch-mock');
|
@ -55,3 +55,13 @@ exports[`device utils get version 4`] = `"1"`;
|
|||||||
exports[`device utils get version 5`] = `"1"`;
|
exports[`device utils get version 5`] = `"1"`;
|
||||||
|
|
||||||
exports[`device utils get version 6`] = `"T"`;
|
exports[`device utils get version 6`] = `"T"`;
|
||||||
|
|
||||||
|
exports[`device utils isDisabled 1`] = `false`;
|
||||||
|
|
||||||
|
exports[`device utils isDisabled 2`] = `true`;
|
||||||
|
|
||||||
|
exports[`device utils isWebUSB 1`] = `true`;
|
||||||
|
|
||||||
|
exports[`device utils isWebUSB 2`] = `false`;
|
||||||
|
|
||||||
|
exports[`device utils isWebUSB 3`] = `true`;
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`eth utils calcGasPrice 1`] = `"89090990901"`;
|
||||||
|
|
||||||
exports[`eth utils decimalToHex 1`] = `"0"`;
|
exports[`eth utils decimalToHex 1`] = `"0"`;
|
||||||
|
|
||||||
exports[`eth utils decimalToHex 2`] = `"1"`;
|
exports[`eth utils decimalToHex 2`] = `"1"`;
|
||||||
@ -8,4 +10,36 @@ exports[`eth utils decimalToHex 3`] = `"2"`;
|
|||||||
|
|
||||||
exports[`eth utils decimalToHex 4`] = `"64"`;
|
exports[`eth utils decimalToHex 4`] = `"64"`;
|
||||||
|
|
||||||
exports[`eth utils decimalToHex 5`] = `"3e7"`;
|
exports[`eth utils decimalToHex 5`] = `"2540be3ff"`;
|
||||||
|
|
||||||
|
exports[`eth utils hexToDecimal 1`] = `"9999999999"`;
|
||||||
|
|
||||||
|
exports[`eth utils hexToDecimal 2`] = `"100"`;
|
||||||
|
|
||||||
|
exports[`eth utils hexToDecimal 3`] = `"2"`;
|
||||||
|
|
||||||
|
exports[`eth utils hexToDecimal 4`] = `"1"`;
|
||||||
|
|
||||||
|
exports[`eth utils hexToDecimal 5`] = `"0"`;
|
||||||
|
|
||||||
|
exports[`eth utils hexToDecimal 6`] = `"null"`;
|
||||||
|
|
||||||
|
exports[`eth utils padLeftEven 1`] = `"02540be3ff"`;
|
||||||
|
|
||||||
|
exports[`eth utils sanitizeHex 1`] = `"0x02540be3ff"`;
|
||||||
|
|
||||||
|
exports[`eth utils sanitizeHex 2`] = `"0x01"`;
|
||||||
|
|
||||||
|
exports[`eth utils sanitizeHex 3`] = `"0x02"`;
|
||||||
|
|
||||||
|
exports[`eth utils sanitizeHex 4`] = `"0x0100"`;
|
||||||
|
|
||||||
|
exports[`eth utils sanitizeHex 5`] = `null`;
|
||||||
|
|
||||||
|
exports[`eth utils sanitizeHex 6`] = `""`;
|
||||||
|
|
||||||
|
exports[`eth utils strip 1`] = `""`;
|
||||||
|
|
||||||
|
exports[`eth utils strip 2`] = `"02540be3ff"`;
|
||||||
|
|
||||||
|
exports[`eth utils strip 3`] = `"02540be3ff"`;
|
||||||
|
45
src/utils/__tests__/__snapshots__/formatUtils.test.js.snap
Normal file
45
src/utils/__tests__/__snapshots__/formatUtils.test.js.snap
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`format utils btckb2satoshib 1`] = `0`;
|
||||||
|
|
||||||
|
exports[`format utils btckb2satoshib 2`] = `100000`;
|
||||||
|
|
||||||
|
exports[`format utils btckb2satoshib 3`] = `200000`;
|
||||||
|
|
||||||
|
exports[`format utils btckb2satoshib 4`] = `10000000`;
|
||||||
|
|
||||||
|
exports[`format utils btckb2satoshib 5`] = `99900000`;
|
||||||
|
|
||||||
|
exports[`format utils formatAmount 1`] = `"0 btc"`;
|
||||||
|
|
||||||
|
exports[`format utils formatAmount 2`] = `"10 mBTC"`;
|
||||||
|
|
||||||
|
exports[`format utils formatAmount 3`] = `"0.000005 mBTC"`;
|
||||||
|
|
||||||
|
exports[`format utils formatAmount 4`] = `"1e-8 eth"`;
|
||||||
|
|
||||||
|
exports[`format utils formatAmount 5`] = `"0.00099999 tau"`;
|
||||||
|
|
||||||
|
exports[`format utils formatTime 1`] = `"No time estimate"`;
|
||||||
|
|
||||||
|
exports[`format utils formatTime 2`] = `"1 minutes"`;
|
||||||
|
|
||||||
|
exports[`format utils formatTime 3`] = `"2 minutes"`;
|
||||||
|
|
||||||
|
exports[`format utils formatTime 4`] = `"1 hour 40 minutes"`;
|
||||||
|
|
||||||
|
exports[`format utils formatTime 5`] = `"16 hours 39 minutes"`;
|
||||||
|
|
||||||
|
exports[`format utils formatTime 6`] = `"45 minutes"`;
|
||||||
|
|
||||||
|
exports[`format utils hexToString 1`] = `"test"`;
|
||||||
|
|
||||||
|
exports[`format utils hexToString 2`] = `"0001"`;
|
||||||
|
|
||||||
|
exports[`format utils hexToString 3`] = `"test99999"`;
|
||||||
|
|
||||||
|
exports[`format utils stringToHex 1`] = `"0074006500730074"`;
|
||||||
|
|
||||||
|
exports[`format utils stringToHex 2`] = `"0030003000300031"`;
|
||||||
|
|
||||||
|
exports[`format utils stringToHex 3`] = `"007400650073007400390039003900390039"`;
|
@ -38,6 +38,29 @@ describe('device utils', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('isWebUSB', () => {
|
||||||
|
const data = [
|
||||||
|
{ transport: { version: ['webusb'] } },
|
||||||
|
{ transport: { version: ['aaaaaa'] } },
|
||||||
|
{ transport: { version: ['webusb', 'test'] } },
|
||||||
|
];
|
||||||
|
|
||||||
|
data.forEach((item) => {
|
||||||
|
expect(dUtils.isWebUSB(item.transport)).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('isDisabled', () => {
|
||||||
|
const data = [
|
||||||
|
{ selectedDevice: { features: null }, devices: [1, 2, 3], transport: { version: ['webusb', 'test'] } },
|
||||||
|
{ selectedDevice: { features: null }, devices: [], transport: { version: ['test'] } },
|
||||||
|
];
|
||||||
|
|
||||||
|
data.forEach((item) => {
|
||||||
|
expect(dUtils.isDisabled(item.selectedDevice, item.devices, item.transport)).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('get version', () => {
|
it('get version', () => {
|
||||||
const deviceMock = [
|
const deviceMock = [
|
||||||
{ },
|
{ },
|
||||||
|
@ -1,11 +1,53 @@
|
|||||||
|
import BigNumber from 'bignumber.js';
|
||||||
import * as ethUtils from '../ethUtils';
|
import * as ethUtils from '../ethUtils';
|
||||||
|
|
||||||
describe('eth utils', () => {
|
describe('eth utils', () => {
|
||||||
it('decimalToHex', () => {
|
it('decimalToHex', () => {
|
||||||
const input = [0, 1, 2, 100, 999];
|
const input = [0, 1, 2, 100, 9999999999];
|
||||||
|
|
||||||
input.forEach((entry) => {
|
input.forEach((entry) => {
|
||||||
expect(ethUtils.decimalToHex(entry)).toMatchSnapshot();
|
expect(ethUtils.decimalToHex(entry)).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('hexToDecimal', () => {
|
||||||
|
const input = ['2540be3ff', '64', '2', '1', '0', ''];
|
||||||
|
|
||||||
|
input.forEach((entry) => {
|
||||||
|
expect(ethUtils.hexToDecimal(entry)).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('padLeftEven', () => {
|
||||||
|
const input = ['2540be3ff'];
|
||||||
|
|
||||||
|
input.forEach((entry) => {
|
||||||
|
expect(ethUtils.padLeftEven(entry)).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sanitizeHex', () => {
|
||||||
|
const input = ['0x2540be3ff', '1', '2', '100', 999, ''];
|
||||||
|
|
||||||
|
input.forEach((entry) => {
|
||||||
|
expect(ethUtils.sanitizeHex(entry)).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('strip', () => {
|
||||||
|
const input = ['0x', '0x2540be3ff', '2540be3ff'];
|
||||||
|
|
||||||
|
input.forEach((entry) => {
|
||||||
|
expect(ethUtils.strip(entry)).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calcGasPrice', () => {
|
||||||
|
const input = [{ price: new BigNumber(9898998989), limit: '9' }];
|
||||||
|
|
||||||
|
input.forEach((entry) => {
|
||||||
|
expect(ethUtils.calcGasPrice(entry.price, entry.limit)).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
49
src/utils/__tests__/formatUtils.test.js
Normal file
49
src/utils/__tests__/formatUtils.test.js
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import * as formatUtils from '../formatUtils';
|
||||||
|
|
||||||
|
describe('format utils', () => {
|
||||||
|
it('formatAmount', () => {
|
||||||
|
const input = [
|
||||||
|
{ amount: 0, coinInfo: { isBitcoin: true, currencyUnits: 'mbtc', shortcut: 'btc' } },
|
||||||
|
{ amount: 1000000, coinInfo: { isBitcoin: true, currencyUnits: 'mbtc', shortcut: 'btc' } },
|
||||||
|
{ amount: 0.5, coinInfo: { isBitcoin: true, currencyUnits: 'mbtc', shortcut: 'btc' } },
|
||||||
|
{ amount: 1, coinInfo: { isBitcoin: false, shortcut: 'eth' } },
|
||||||
|
{ amount: 99999, coinInfo: { isBitcoin: false, shortcut: 'tau' } },
|
||||||
|
];
|
||||||
|
|
||||||
|
input.forEach((entry) => {
|
||||||
|
expect(formatUtils.formatAmount(entry.amount, entry.coinInfo, entry.coinInfo.currencyUnits)).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('formatTime', () => {
|
||||||
|
const input = [0, 1, 2, 100, 999, 45];
|
||||||
|
|
||||||
|
input.forEach((entry) => {
|
||||||
|
expect(formatUtils.formatTime(entry)).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('btckb2satoshib', () => {
|
||||||
|
const input = [0, 1, 2, 100, 999];
|
||||||
|
|
||||||
|
input.forEach((entry) => {
|
||||||
|
expect(formatUtils.btckb2satoshib(entry)).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('stringToHex', () => {
|
||||||
|
const input = ['test', '0001', 'test99999'];
|
||||||
|
|
||||||
|
input.forEach((entry) => {
|
||||||
|
expect(formatUtils.stringToHex(entry)).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('hexToString', () => {
|
||||||
|
const input = ['0074006500730074', '0030003000300031', '007400650073007400390039003900390039'];
|
||||||
|
|
||||||
|
input.forEach((entry) => {
|
||||||
|
expect(formatUtils.hexToString(entry)).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -1,11 +1,9 @@
|
|||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
|
|
||||||
const currencyUnits: string = 'mbtc2';
|
|
||||||
|
|
||||||
// TODO: chagne currency units
|
// TODO: chagne currency units
|
||||||
|
const currencyUnitsConstant: string = 'mbtc2';
|
||||||
|
|
||||||
export const formatAmount = (n: number, coinInfo: any): string => {
|
export const formatAmount = (n: number, coinInfo: any, currencyUnits: string = currencyUnitsConstant): string => {
|
||||||
const amount = (n / 1e8);
|
const amount = (n / 1e8);
|
||||||
if (coinInfo.isBitcoin && currencyUnits === 'mbtc' && amount <= 0.1 && n !== 0) {
|
if (coinInfo.isBitcoin && currencyUnits === 'mbtc' && amount <= 0.1 && n !== 0) {
|
||||||
const s = (n / 1e5).toString();
|
const s = (n / 1e5).toString();
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
|
|
||||||
import 'whatwg-fetch';
|
import 'whatwg-fetch';
|
||||||
|
|
||||||
export const httpRequest = async (url: string, type: string = 'text'): any => {
|
export const httpRequest = async (url: string, type: string = 'text'): any => {
|
||||||
@ -15,16 +14,6 @@ export const httpRequest = async (url: string, type: string = 'text'): any => {
|
|||||||
await response.text();
|
await response.text();
|
||||||
}
|
}
|
||||||
throw new Error(`${url} ${response.statusText}`);
|
throw new Error(`${url} ${response.statusText}`);
|
||||||
|
|
||||||
|
|
||||||
// return fetch(url, { credentials: 'same-origin' }).then((response) => {
|
|
||||||
// if (response.status === 200) {
|
|
||||||
|
|
||||||
// return response.text().then(result => (json ? JSON.parse(result) : result));
|
|
||||||
// } else {
|
|
||||||
// throw new Error(response.statusText);
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const JSONRequest = async (url: string): Promise<JSON> => {
|
export const JSONRequest = async (url: string): Promise<JSON> => {
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
import webpack from 'webpack';
|
import webpack from 'webpack';
|
||||||
|
import GitRevisionPlugin from 'git-revision-webpack-plugin';
|
||||||
import HtmlWebpackPlugin from 'html-webpack-plugin';
|
import HtmlWebpackPlugin from 'html-webpack-plugin';
|
||||||
|
import FlowWebpackPlugin from 'flow-webpack-plugin';
|
||||||
|
|
||||||
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
|
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
SRC, BUILD, PORT, PUBLIC,
|
SRC, BUILD, PORT, PUBLIC,
|
||||||
} from './constants';
|
} from './constants';
|
||||||
|
|
||||||
|
const gitRevisionPlugin = new GitRevisionPlugin();
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
watch: true,
|
watch: true,
|
||||||
@ -46,6 +49,7 @@ module.exports = {
|
|||||||
{
|
{
|
||||||
loader: 'stylelint-custom-processor-loader',
|
loader: 'stylelint-custom-processor-loader',
|
||||||
options: {
|
options: {
|
||||||
|
emitWarning: true,
|
||||||
configPath: '.stylelintrc',
|
configPath: '.stylelintrc',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -89,6 +93,10 @@ module.exports = {
|
|||||||
hints: false,
|
hints: false,
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
COMMITHASH: JSON.stringify(gitRevisionPlugin.commithash()),
|
||||||
|
}),
|
||||||
|
new FlowWebpackPlugin(),
|
||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
chunks: ['index'],
|
chunks: ['index'],
|
||||||
template: `${SRC}index.html`,
|
template: `${SRC}index.html`,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import webpack from 'webpack';
|
import webpack from 'webpack';
|
||||||
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
|
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
|
||||||
|
import GitRevisionPlugin from 'git-revision-webpack-plugin';
|
||||||
import HtmlWebpackPlugin from 'html-webpack-plugin';
|
import HtmlWebpackPlugin from 'html-webpack-plugin';
|
||||||
import CopyWebpackPlugin from 'copy-webpack-plugin';
|
import CopyWebpackPlugin from 'copy-webpack-plugin';
|
||||||
import MiniCssExtractPlugin from '../../trezor-connect/node_modules/mini-css-extract-plugin';
|
import MiniCssExtractPlugin from '../../trezor-connect/node_modules/mini-css-extract-plugin';
|
||||||
@ -15,6 +16,8 @@ import {
|
|||||||
PORT,
|
PORT,
|
||||||
} from './constants';
|
} from './constants';
|
||||||
|
|
||||||
|
const gitRevisionPlugin = new GitRevisionPlugin();
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
watch: true,
|
watch: true,
|
||||||
mode: 'development',
|
mode: 'development',
|
||||||
@ -115,7 +118,6 @@ module.exports = {
|
|||||||
filename: '[name].css',
|
filename: '[name].css',
|
||||||
chunkFilename: '[id].css',
|
chunkFilename: '[id].css',
|
||||||
}),
|
}),
|
||||||
|
|
||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
chunks: ['index'],
|
chunks: ['index'],
|
||||||
template: `${SRC}index.html`,
|
template: `${SRC}index.html`,
|
||||||
@ -164,6 +166,7 @@ module.exports = {
|
|||||||
|
|
||||||
new webpack.DefinePlugin({
|
new webpack.DefinePlugin({
|
||||||
LOCAL: JSON.stringify(`http://localhost:${PORT}/`),
|
LOCAL: JSON.stringify(`http://localhost:${PORT}/`),
|
||||||
|
COMMITHASH: JSON.stringify(gitRevisionPlugin.commithash()),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// ignore node lib from trezor-link
|
// ignore node lib from trezor-link
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
|
|
||||||
import webpack from 'webpack';
|
import webpack from 'webpack';
|
||||||
|
import GitRevisionPlugin from 'git-revision-webpack-plugin';
|
||||||
import HtmlWebpackPlugin from 'html-webpack-plugin';
|
import HtmlWebpackPlugin from 'html-webpack-plugin';
|
||||||
import CopyWebpackPlugin from 'copy-webpack-plugin';
|
import CopyWebpackPlugin from 'copy-webpack-plugin';
|
||||||
|
import FlowWebpackPlugin from 'flow-webpack-plugin';
|
||||||
import { SRC, BUILD, PUBLIC } from './constants';
|
import { SRC, BUILD, PUBLIC } from './constants';
|
||||||
|
|
||||||
|
const gitRevisionPlugin = new GitRevisionPlugin();
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mode: 'production',
|
mode: 'production',
|
||||||
entry: {
|
entry: {
|
||||||
@ -60,6 +64,10 @@ module.exports = {
|
|||||||
hints: false,
|
hints: false,
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
COMMITHASH: JSON.stringify(gitRevisionPlugin.commithash()),
|
||||||
|
}),
|
||||||
|
new FlowWebpackPlugin(),
|
||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
chunks: ['index'],
|
chunks: ['index'],
|
||||||
template: `${SRC}index.html`,
|
template: `${SRC}index.html`,
|
||||||
|
26
yarn.lock
26
yarn.lock
@ -255,6 +255,10 @@
|
|||||||
version "0.7.0"
|
version "0.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd"
|
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd"
|
||||||
|
|
||||||
|
"@types/jest@^23.0.0":
|
||||||
|
version "23.3.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-23.3.2.tgz#07b90f6adf75d42c34230c026a2529e56c249dbb"
|
||||||
|
|
||||||
"@webassemblyjs/ast@1.5.13":
|
"@webassemblyjs/ast@1.5.13":
|
||||||
version "1.5.13"
|
version "1.5.13"
|
||||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.5.13.tgz#81155a570bd5803a30ec31436bc2c9c0ede38f25"
|
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.5.13.tgz#81155a570bd5803a30ec31436bc2c9c0ede38f25"
|
||||||
@ -4306,6 +4310,10 @@ flow-parser@^0.*:
|
|||||||
version "0.72.0"
|
version "0.72.0"
|
||||||
resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.72.0.tgz#6c8041e76ac7d0be1a71ce29c00cd1435fb6013c"
|
resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.72.0.tgz#6c8041e76ac7d0be1a71ce29c00cd1435fb6013c"
|
||||||
|
|
||||||
|
flow-webpack-plugin@^1.2.0:
|
||||||
|
version "1.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/flow-webpack-plugin/-/flow-webpack-plugin-1.2.0.tgz#1958821d16135028e391cad5ee2f3a4fa78197ec"
|
||||||
|
|
||||||
flush-write-stream@^1.0.0:
|
flush-write-stream@^1.0.0:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.2.tgz#c81b90d8746766f1a609a46809946c45dd8ae417"
|
resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.2.tgz#c81b90d8746766f1a609a46809946c45dd8ae417"
|
||||||
@ -4519,6 +4527,10 @@ gh-got@^6.0.0:
|
|||||||
got "^7.0.0"
|
got "^7.0.0"
|
||||||
is-plain-obj "^1.1.0"
|
is-plain-obj "^1.1.0"
|
||||||
|
|
||||||
|
git-revision-webpack-plugin@^3.0.3:
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/git-revision-webpack-plugin/-/git-revision-webpack-plugin-3.0.3.tgz#f909949d7851d1039ed530518f73f5d46594e66f"
|
||||||
|
|
||||||
github-username@^4.0.0:
|
github-username@^4.0.0:
|
||||||
version "4.1.0"
|
version "4.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/github-username/-/github-username-4.1.0.tgz#cbe280041883206da4212ae9e4b5f169c30bf417"
|
resolved "https://registry.yarnpkg.com/github-username/-/github-username-4.1.0.tgz#cbe280041883206da4212ae9e4b5f169c30bf417"
|
||||||
@ -5589,7 +5601,7 @@ isobject@^3.0.0, isobject@^3.0.1:
|
|||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
|
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
|
||||||
|
|
||||||
isomorphic-fetch@^2.1.1:
|
isomorphic-fetch@^2.1.1, isomorphic-fetch@^2.2.1:
|
||||||
version "2.2.1"
|
version "2.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
|
resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -5781,6 +5793,14 @@ jest-environment-node@^23.4.0:
|
|||||||
jest-mock "^23.2.0"
|
jest-mock "^23.2.0"
|
||||||
jest-util "^23.4.0"
|
jest-util "^23.4.0"
|
||||||
|
|
||||||
|
jest-fetch-mock@^1.6.5:
|
||||||
|
version "1.6.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/jest-fetch-mock/-/jest-fetch-mock-1.6.5.tgz#178fa1a937ef6f61fb8e8483b6d4602b17e0d96d"
|
||||||
|
dependencies:
|
||||||
|
"@types/jest" "^23.0.0"
|
||||||
|
isomorphic-fetch "^2.2.1"
|
||||||
|
promise-polyfill "^7.1.1"
|
||||||
|
|
||||||
jest-get-type@^22.1.0:
|
jest-get-type@^22.1.0:
|
||||||
version "22.4.3"
|
version "22.4.3"
|
||||||
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4"
|
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4"
|
||||||
@ -8030,6 +8050,10 @@ promise-inflight@^1.0.1:
|
|||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
|
resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
|
||||||
|
|
||||||
|
promise-polyfill@^7.1.1:
|
||||||
|
version "7.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-7.1.2.tgz#ab05301d8c28536301622d69227632269a70ca3b"
|
||||||
|
|
||||||
promise@^7.1.1:
|
promise@^7.1.1:
|
||||||
version "7.3.1"
|
version "7.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
|
resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
|
||||||
|
Loading…
Reference in New Issue
Block a user