Trezor integration

This commit is contained in:
Victor Baranov 2018-11-02 17:37:19 +03:00
parent c6d30a01bc
commit 9b13f23119
4 changed files with 137 additions and 74 deletions

View File

@ -1 +1,21 @@
<svg height="22" viewBox="0 0 22 22" width="22" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><mask id="a" fill="#fff"><path d="m-.00035 0h11.00025v10.9997h-11.00025z" fill="none"/></mask><g fill="#4a4a4a" fill-rule="evenodd"><path d="m10.9229.6177c-.102-.244-.296-.439-.541-.541-.122-.05-.251-.077-.382-.077h-6c-.552 0-1 .448-1 1 0 .553.448 1 1 1h3.586l-7.293 7.293c-.391.391-.391 1.024 0 1.414.195.196.451.293.707.293s.512-.097.707-.293l7.293-7.293v3.586c0 .553.448 1 1 1s1-.447 1-1v-6c0-.13-.026-.259-.077-.382" mask="url(#a)" transform="translate(11)"/><path d="m19 10c-.552 0-1 .448-1 1v8c0 .551-.449 1-1 1h-14c-.551 0-1-.449-1-1v-14c0-.551.449-1 1-1h8c.552 0 1-.448 1-1s-.448-1-1-1h-8c-1.654 0-3 1.346-3 3v14c0 1.654 1.346 3 3 3h14c1.654 0 3-1.346 3-3v-8c0-.552-.448-1-1-1"/></g></svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg width="22px" height="22px" viewBox="0 0 22 22" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 48.2 (47327) - http://www.bohemiancoding.com/sketch -->
<title>popout</title>
<desc>Created with Sketch.</desc>
<defs>
<polygon id="path-1" points="-0.00035 0 10.9999 0 10.9999 10.9997 -0.00035 10.9997"></polygon>
</defs>
<g id="MetaMascara-Mobile---structured-TOKEN" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" transform="translate(-327.000000, -96.000000)">
<g id="popout" transform="translate(327.000000, 96.000000)">
<g id="Group-3" transform="translate(11.000000, 0.000000)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="Clip-2"></g>
<path d="M10.9229,0.6177 C10.8209,0.3737 10.6269,0.1787 10.3819,0.0767 C10.2599,0.0267 10.1309,-0.0003 9.9999,-0.0003 L3.9999,-0.0003 C3.4479,-0.0003 2.9999,0.4477 2.9999,0.9997 C2.9999,1.5527 3.4479,1.9997 3.9999,1.9997 L7.5859,1.9997 L0.2929,9.2927 C-0.0981,9.6837 -0.0981,10.3167 0.2929,10.7067 C0.4879,10.9027 0.7439,10.9997 0.9999,10.9997 C1.2559,10.9997 1.5119,10.9027 1.7069,10.7067 L8.9999,3.4137 L8.9999,6.9997 C8.9999,7.5527 9.4479,7.9997 9.9999,7.9997 C10.5519,7.9997 10.9999,7.5527 10.9999,6.9997 L10.9999,0.9997 C10.9999,0.8697 10.9739,0.7407 10.9229,0.6177" id="Fill-1" fill="#4A4A4A" mask="url(#mask-2)"></path>
</g>
<path d="M19,10 C18.448,10 18,10.448 18,11 L18,19 C18,19.551 17.551,20 17,20 L3,20 C2.449,20 2,19.551 2,19 L2,5 C2,4.449 2.449,4 3,4 L11,4 C11.552,4 12,3.552 12,3 C12,2.448 11.552,2 11,2 L3,2 C1.346,2 0,3.346 0,5 L0,19 C0,20.654 1.346,22 3,22 L17,22 C18.654,22 20,20.654 20,19 L20,11 C20,10.448 19.552,10 19,10" id="Fill-4" fill="#4A4A4A"></path>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 823 B

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -9,7 +9,7 @@ class AccountList extends Component {
super(props)
}
getHdPaths () {
getHdPaths = () => {
return [
{
label: `Ledger Live`,
@ -35,21 +35,21 @@ class AccountList extends Component {
this.props.getPage(this.props.device, -1, this.props.selectedPath)
}
renderHdPathSelector () {
renderHdPathSelector = () => {
const { onPathChange, selectedPath } = this.props
const options = this.getHdPaths()
return (
<div>
<h3 className='hw-connect__hdPath__title'>this.context.t('selectHdPath')</h3>
<p className='hw-connect__msg'>this.context.t('selectPathHelp')</p>
<div className='hw-connect__hdPath'>
<h3 className="hw-connect__hdPath__title">Select HD Path</h3>
<p className="hw-connect__msg">{`If you don't see your existing Ledger accounts below, try switching paths to "Legacy (MEW / MyCrypto)"`}</p>
<div className="hw-connect__hdPath">
<Select
className='hw-connect__hdPath__select'
name='hd-path-select'
className="hw-connect__hdPath__select"
name="hd-path-select"
clearable={false}
value={selectedPath}
options
options={options}
onChange={(opt) => {
onPathChange(opt.value)
}}
@ -59,76 +59,76 @@ class AccountList extends Component {
)
}
capitalizeDevice (device) {
capitalizeDevice = (device) => {
return device.slice(0, 1).toUpperCase() + device.slice(1)
}
renderHeader () {
renderHeader = () => {
const { device } = this.props
return (
<div className='hw-connect'>
<h3 className='hw-connect'>
<h3 className='hw-connect__unlock-title'>`${this.context.t('unlock')} ${this.capitalizeDevice(device)}`</h3>
<div className="hw-connect">
<h3 className="hw-connect">
<h3 className="hw-connect__unlock-title">{`Unlock ${this.capitalizeDevice(device)}`}</h3>
{device.toLowerCase() === 'ledger' ? this.renderHdPathSelector() : null}
<h3 className='hw-connect__hdPath__title'>{this.context.t('selectAnAccount')}</h3>
<p className='hw-connect__msg'>{this.context.t('selectAnAccountHelp')}</p>
<p className="hw-connect__msg">Select the account to view in Nifty Wallet</p>
</h3>
</div>
)
}
renderAccounts () {
renderAccounts = () => {
const rows = []
this.props.accounts.map((a, i) => {
rows.push(
<div className='hw-account-list__item' key={a.address}>
<div className='hw-account-list__item__radio'>
<div className="hw-account-list__item" key={a.address}>
<div className="hw-account-list__item__radio">
<input
type='radio'
name='selectedAccount'
type="radio"
name="selectedAccount"
id={`address-${i}`}
value={a.index}
onChange={(e) => this.props.onAccountChange(e.target.value)}
checked={this.props.selectedAccount === a.index.toString()}
/>
<label className='hw-account-list__item__label' htmlFor={`address-${i}`}>
<span className='hw-account-list__item__index'>{a.index + 1}</span>
<label className="hw-account-list__item__label" htmlFor={`address-${i}`}>
<span className="hw-account-list__item__index">{a.index + 1}</span>
{`${a.address.slice(0, 4)}...${a.address.slice(-4)}`}
<span className='hw-account-list__item__balance'>{`${a.balance}`}</span>
<span className="hw-account-list__item__balance">{`${a.balance}`}</span>
</label>
</div>
<a
className='hw-account-list__item__link'
className="hw-account-list__item__link"
href={ethNetProps.explorerLinks.getExplorerAccountLinkFor(a.address, this.props.network)}
target='_blank'
title={this.context.t('etherscanView')}
/>
<img src='images/popout.svg' />
target="_blank"
title="View account on Etherscan"
>
<img src="images/popout.svg" />
</a>
</div>
)
})
return (
<div className='hw-account-list'>{rows}</div>
<div className="hw-account-list">{rows}</div>
)
}
renderPagination () {
renderPagination = () => {
return (
<div className='hw-list-pagination'>
<div className="hw-list-pagination">
<button
className='hw-list-pagination__button'
onClick={this.goToPreviousPage}
>{`< ${this.context.t('prev')}`}</button>
<button
className='hw-list-pagination__button'
className="hw-list-pagination__button"
onClick={this.goToNextPage}
>{`${this.context.t('next')} >`}</button>
>{`Next >`}</button>
<button
className="hw-list-pagination__button"
onClick={this.goToPreviousPage}
>{`< Prev`}</button>
</div>
)
}
renderButtons () {
renderButtons = () => {
const disabled = this.props.selectedAccount === null
const buttonProps = {}
if (disabled) {
@ -136,35 +136,35 @@ class AccountList extends Component {
}
return (
<div className='new-account-connect-form__buttons'>
<div className="new-account-connect-form__buttons">
<Button
type='default'
type="default"
large={true}
className='new-account-connect-form__button'
className="new-account-connect-form__button btn-violet"
onClick={this.props.onCancel.bind(this)}
>{this.context.t('cancel')}</Button>
>Cancel</Button>
<Button
type='primary'
type="primary"
large={true}
className='new-account-connect-form__button unlock'
className="new-account-connect-form__button unlock"
disabled={disabled}
onClick={this.props.onUnlockAccount.bind(this, this.props.device)}
>{this.context.t('unlock')}</Button>
>Unlock</Button>
</div>
)
}
renderForgetDevice () {
renderForgetDevice = () => {
return (
<div className='hw-forget-device-container'>
<a onClick={this.props.onForgetDevice.bind(this, this.props.device)}>{this.context.t('forgetDevice')}</a>
<div className="hw-forget-device-container">
<a onClick={this.props.onForgetDevice.bind(this, this.props.device)}>Forget this device</a>
</div>
)
}
render () {
render = () => {
return (
<div className='new-account-connect-form.account-list'>
<div className="new-account-connect-form.account-list">
{this.renderHeader()}
{this.renderAccounts()}
{this.renderPagination()}
@ -176,7 +176,6 @@ class AccountList extends Component {
}
AccountList.propTypes = {
onPathChange: PropTypes.func.isRequired,
selectedPath: PropTypes.string.isRequired,
@ -193,8 +192,4 @@ AccountList.propTypes = {
onAccountRestriction: PropTypes.func,
}
AccountList.contextTypes = {
t: PropTypes.func,
}
module.exports = AccountList

View File

@ -4,7 +4,6 @@ import { connect } from 'react-redux'
import actions from '../../../../ui/app/actions'
import ConnectScreen from './connect-screen'
import AccountList from './account-list'
import { DEFAULT_ROUTE } from '../../../../ui/app/routes'
import { formatBalance } from '../../../../ui/app/util'
import { getPlatform } from '../../../../app/scripts/lib/util'
import { PLATFORM_FIREFOX } from '../../../../app/scripts/lib/enums'
@ -153,14 +152,14 @@ class ConnectHardwareForm extends Component {
this.props.unlockHardwareWalletAccount(this.state.selectedAccount, device)
.then(_ => {
this.props.history.push(DEFAULT_ROUTE)
this.props.goHome()
}).catch(e => {
this.setState({ error: e.toString() })
})
}
onCancel = () => {
this.props.history.push(DEFAULT_ROUTE)
this.props.goHome()
}
renderError () {
@ -235,7 +234,6 @@ ConnectHardwareForm.propTypes = {
goHome: PropTypes.func,
numberOfExistingAccounts: PropTypes.number,
history: PropTypes.object,
t: PropTypes.func,
network: PropTypes.string,
accounts: PropTypes.object,
address: PropTypes.string,

View File

@ -176,7 +176,7 @@ width: 100%;
margin-bottom: 23px;
align-self: flex-start;
color: #5d5d5d;
font-family: Roboto;
font-family: Nunito Regular;
font-size: 16px;
line-height: 21px;
font-weight: bold;
@ -187,7 +187,7 @@ width: 100%;
margin-bottom: 23px;
align-self: flex-end;
color: #5d5d5d;
font-family: Roboto;
font-family: Nunito Regular;
font-size: 16px;
line-height: 21px;
font-weight: normal;
@ -242,21 +242,71 @@ width: 100%;
height: 15px;
}
.hw-list-pagination {
display: flex;
align-self: flex-end;
margin-top: 10px;
margin-top: 10px;
}
.hw-list-pagination__button {
height: 19px;
display: flex;
color: #33a4e7;
float: right;
color: #6729a8;
font-size: 14px;
line-height: 19px;
border: none;
min-width: 46px;
margin-right: 0px;
margin-left: 16px;
padding: 0px;
text-transform: uppercase;
font-family: Roboto;
font-family: Nunito Regular;
background: transparent;
}
.hw-forget-device-container {
display: flex;
flex-flow: column;
align-items: center;
padding: 22px;
}
.hw-forget-device-container a {
color: #60db97;
font-size: 14px;
cursor: pointer;
}
.new-account-connect-form {
/*display: flex;*/
flex-flow: column;
align-items: center;
/*padding: 15px 30px 0;*/
height: 710px;
/*overflow: auto;*/
}
.new-account-connect-form.unsupported-browser {
height: 210px;
}
.new-account-connect-form.account-list {
height: auto;
padding-left: 20px;
padding-right: 20px;
}
.new-account-connect-form__buttons {
margin-top: 39px;
display: flex;
width: 100%;
justify-content: space-between;
}
.new-account-connect-form__button {
width: 150px;
min-width: initial;
}
.new-account-connect-form .btn-primary {
background-color: #259DE5;
color: #FFFFFF;
border: none;
width: 100%;
min-height: 54px;
font-weight: 300;
font-size: 14px;
margin-bottom: 20px;
}
.new-account-connect-form__button.unlock {
width: 50%;
}
.new-account-connect-form__button.btn-primary--disabled {
cursor: not-allowed;
opacity: .5;
}