Initial new UI source code import (#2607)
* address -> name mappings * expanding, loading all coin details * send use only actual BasicCoin tokens registered (any reg) * sending token & accounts * form styling updates * send form layout in place * coin send working as expected * api subscriptions on multiple addresses * bring in events * simplify * basic events display in-place, functionally complete * basic functionality in-place * fix horrible event address issue * rwork display of events slightly * test TLA availability * table for owner -> tokens * fix signature lookup address * fix signature lookup address * basic overview styling * txhash links * page layout adjustments * background import * adjust colors * no global registration, simplify color selection * updated styling * connection dialog for "busy connecting" * initial token connection - WIP * init token updates take place * basic test for manual token * rework connection display * allow updates of the secure token * first stab at making the build build * update runner tags * fix linting issues * skip tests requiring network (should be e2e, TODO) * re-enable javascript tag/runner * release push does the trick * push to any branch, CI name * javscript-test runner as well * swap dependencies build requires test * revert stages swap * retrieve images associated with tokens * remove js build deps order * null image when hash = 0x0 * 6x64 images (hashes for registries) * don't pass tokens as prop to IdentityIcon * check images against content hash pictures * cleanup signer after connection changes * fix naming typo * display unknownImages for balances (not available as content hash) * unknownImage for transfer dialog * basic githubhint layout * single input for commit/filename * ethcore_hashContent call * lookup hash * registration in place * fixes * events is using a proper table * pass value through as-is * stop wrongly using main app IdentityIcon * NEVER export class instance functions * alignment back to normal * typo in definition * set & get images working (mostly) * show content retrieval info * set exitcode via || * use javascript:latest images * disable npm progress bar * rename phase I * rename phase II * only send build output to GitHub on major branches * also run the build step as part of the test (until comprehensive) * ci-specific build (no webpack progress) * allow for account creation via recovery phrase * display account uuid (where available), closes #2546 * connection dialog now shows up in dapps as well, closes #2538 * token images show up as expected * IdentityName component added and deployed * fix padding tests * adjust tests to map to stricter 0x-prefixed hex * render names via common component for the address -> name * split lint into seperate script (early exit) * test phases changed to lint, test & pack * pack part of test phase * remove files marked for deletion (cleanup) * Signer cleanups, start moving in the direction of the rest * add personal signer methods * basic signer request subscription * don't poll blockNumber when not connected * missing return, creating massive ws queue backlogs * ΞTH -> ETH * fix failing tests * registry uses setAddress to actually set addresses now * bytes mapping operates on lowerCase hex strings * sha3 ids for each application * add dappreg to list of contracts * adjust alignment of queries * show gas estimation log * abi with payable for register function * add key as required * image retrieval from dappreg * use proper Image urls * embed and link apps from Parity, retrieved via /api/apps * filter apps that has been replaced * proxy entry for parity-utils * add basiccoin abi * add support for fallback abi type * capture constructor paramaters * merge master into js * move images to assets/images/ * add font assets * import fonts as part of build * don't inline woff files * Revert "merge master into js" This reverts commit cfcfa81bd26f1b3cbc748d3afa1eb5c670b363fe. * remove unused npm packages * information on gas estimates (like almost everywhere else) * don't pass gas & gasPrice to estimation * display account passwordhint when available * signer subscriptions based on polling & function trapping * pending requests retrieved via jsapi * update signer middleware * remove all web3 instances * remove web3 package * last web3 dependencies removed * no need to toChecksumAddress - api takes care of it * expand description for personal_confirmRequest * Signer conversion from web3 -> parity.js completed * explicit in no return * green circle background * remove generated background * convert /api/* paths to localhost:8080/api/* paths (hard-coded, temporary) * change dapps to load from localhost:8080/ui/* * remove dangling web3 files * update manager test for signer * /api/ping -> / * additional token images * additional token images * add missing styles.css for 8180 error pages * cater for txhash returning null/empty object * adjust output directories * Release merge with origin with ours strategy * additional token images * cater for development server * s/localhost/127.0.0.1/ (cater for origin) * Fix address selection for contract deployment * Adjust z-index for error overlay * better text on unique background pattern * fix signer rejections * Don't allow gavcoin transfer with no balance * fix txhash rendering in signer * remove unnecessary ParityBackground * script to update js-precompiled * Redirect from :8080 to :8180 * Remove extra return * Dapp logo images
This commit is contained in:
44
js/src/views/Signer/components/Account/Account.css
Normal file
44
js/src/views/Signer/components/Account/Account.css
Normal file
@@ -0,0 +1,44 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.acc {
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.acc > * {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.address {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.acc img {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
vertical-align: middle;
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
.name {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
display: lock;
|
||||
vertical-align: middle;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
109
js/src/views/Signer/components/Account/Account.js
Normal file
109
js/src/views/Signer/components/Account/Account.js
Normal file
@@ -0,0 +1,109 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import { IdentityIcon, IdentityName } from '../../../../ui';
|
||||
import AccountLink from './AccountLink';
|
||||
|
||||
import styles from './Account.css';
|
||||
|
||||
export default class Account extends Component {
|
||||
static propTypes = {
|
||||
className: PropTypes.string,
|
||||
address: PropTypes.string.isRequired,
|
||||
chain: PropTypes.string.isRequired,
|
||||
balance: PropTypes.object // eth BigNumber, not required since it mght take time to fetch
|
||||
};
|
||||
|
||||
state = {
|
||||
balanceDisplay: '?'
|
||||
};
|
||||
|
||||
componentWillMount () {
|
||||
this.updateBalanceDisplay(this.props.balance);
|
||||
}
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
if (nextProps.balance === this.props.balance) {
|
||||
return;
|
||||
}
|
||||
this.updateBalanceDisplay(nextProps.balance);
|
||||
}
|
||||
|
||||
updateBalanceDisplay (balance) {
|
||||
this.setState({
|
||||
balanceDisplay: balance ? balance.div(1e18).toFormat(3) : '?'
|
||||
});
|
||||
}
|
||||
|
||||
render () {
|
||||
const { address, chain, className } = this.props;
|
||||
|
||||
return (
|
||||
<div className={ `${styles.acc} ${className}` }>
|
||||
<AccountLink address={ address } chain={ chain }>
|
||||
<IdentityIcon
|
||||
center
|
||||
address={ address } />
|
||||
</AccountLink>
|
||||
{ this.renderName() }
|
||||
{ this.renderBalance() }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderBalance () {
|
||||
const { balanceDisplay } = this.state;
|
||||
return (
|
||||
<span> <strong>{ balanceDisplay }</strong> <small>ETH</small></span>
|
||||
);
|
||||
}
|
||||
|
||||
renderName () {
|
||||
const { address } = this.props;
|
||||
const name = <IdentityName address={ address } empty />;
|
||||
|
||||
if (!name) {
|
||||
return (
|
||||
<AccountLink address={ address } chain={ this.props.chain }>
|
||||
[{ this.shortAddress(address) }]
|
||||
</AccountLink>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<AccountLink address={ address } chain={ this.props.chain } >
|
||||
<span>
|
||||
<span className={ styles.name }>{ name }</span>
|
||||
<span className={ styles.address }>[{ this.tinyAddress(address) }]</span>
|
||||
</span>
|
||||
</AccountLink>
|
||||
);
|
||||
}
|
||||
|
||||
tinyAddress () {
|
||||
const { address } = this.props;
|
||||
const len = address.length;
|
||||
return address.slice(2, 4) + '..' + address.slice(len - 2);
|
||||
}
|
||||
|
||||
shortAddress () {
|
||||
const { address } = this.props;
|
||||
const len = address.length;
|
||||
return address.slice(2, 8) + '..' + address.slice(len - 7);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.container {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import { getAccountLink } from '../../util/account';
|
||||
import styles from './AccountLink.css';
|
||||
|
||||
export default class AccountLink extends Component {
|
||||
static propTypes = {
|
||||
chain: PropTypes.string.isRequired,
|
||||
address: PropTypes.string.isRequired,
|
||||
className: PropTypes.string,
|
||||
children: PropTypes.node
|
||||
}
|
||||
|
||||
state = {
|
||||
link: null
|
||||
};
|
||||
|
||||
componentWillMount () {
|
||||
const { address, chain } = this.props;
|
||||
|
||||
this.updateLink(address, chain);
|
||||
}
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
const { address, chain } = nextProps;
|
||||
|
||||
this.updateLink(address, chain);
|
||||
}
|
||||
|
||||
render () {
|
||||
const { children, address, className } = this.props;
|
||||
return (
|
||||
<a
|
||||
href={ this.state.link }
|
||||
target='_blank'
|
||||
className={ `${styles.container} ${className}` }
|
||||
>
|
||||
{ children || address }
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
updateLink (address, chain) {
|
||||
const link = getAccountLink(address, chain);
|
||||
|
||||
this.setState({
|
||||
link
|
||||
});
|
||||
}
|
||||
}
|
||||
17
js/src/views/Signer/components/Account/AccountLink/index.js
Normal file
17
js/src/views/Signer/components/Account/AccountLink/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './AccountLink';
|
||||
17
js/src/views/Signer/components/Account/index.js
Normal file
17
js/src/views/Signer/components/Account/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './Account';
|
||||
@@ -0,0 +1,80 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import TransactionFinishedWeb3 from '../TransactionFinishedWeb3';
|
||||
import SignWeb3 from '../SignRequestWeb3';
|
||||
|
||||
export default class RequestFinishedWeb3 extends Component {
|
||||
static propTypes = {
|
||||
id: PropTypes.object.isRequired,
|
||||
result: PropTypes.any.isRequired,
|
||||
date: PropTypes.instanceOf(Date).isRequired,
|
||||
payload: PropTypes.oneOfType([
|
||||
PropTypes.shape({ transaction: PropTypes.object.isRequired }),
|
||||
PropTypes.shape({ sign: PropTypes.object.isRequired })
|
||||
]).isRequired,
|
||||
msg: PropTypes.string,
|
||||
status: PropTypes.string,
|
||||
error: PropTypes.string,
|
||||
className: PropTypes.string
|
||||
}
|
||||
|
||||
render () {
|
||||
const { payload, id, result, msg, status, error, date, className } = this.props;
|
||||
|
||||
if (payload.sign) {
|
||||
const { sign } = payload;
|
||||
return (
|
||||
<SignWeb3
|
||||
className={ className }
|
||||
isFinished
|
||||
id={ id }
|
||||
address={ sign.address }
|
||||
hash={ sign.hash }
|
||||
result={ result }
|
||||
msg={ msg }
|
||||
status={ status }
|
||||
error={ error }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (payload.transaction) {
|
||||
const { transaction } = payload;
|
||||
return (
|
||||
<TransactionFinishedWeb3
|
||||
className={ className }
|
||||
txHash={ result }
|
||||
id={ id }
|
||||
gasPrice={ transaction.gasPrice }
|
||||
gas={ transaction.gas }
|
||||
from={ transaction.from }
|
||||
to={ transaction.to }
|
||||
value={ transaction.value }
|
||||
msg={ msg }
|
||||
date={ date }
|
||||
status={ status }
|
||||
error={ error }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Unknown payload
|
||||
return null;
|
||||
}
|
||||
}
|
||||
17
js/src/views/Signer/components/RequestFinishedWeb3/index.js
Normal file
17
js/src/views/Signer/components/RequestFinishedWeb3/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './RequestFinishedWeb3';
|
||||
@@ -0,0 +1,78 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import TransactionPendingWeb3 from '../TransactionPendingWeb3';
|
||||
import SignRequestWeb3 from '../SignRequestWeb3';
|
||||
|
||||
export default class RequestPendingWeb3 extends Component {
|
||||
static propTypes = {
|
||||
id: PropTypes.object.isRequired,
|
||||
onConfirm: PropTypes.func.isRequired,
|
||||
onReject: PropTypes.func.isRequired,
|
||||
isSending: PropTypes.bool.isRequired,
|
||||
date: PropTypes.instanceOf(Date).isRequired,
|
||||
payload: PropTypes.oneOfType([
|
||||
PropTypes.shape({ transaction: PropTypes.object.isRequired }),
|
||||
PropTypes.shape({ sign: PropTypes.object.isRequired })
|
||||
]).isRequired,
|
||||
className: PropTypes.string
|
||||
};
|
||||
|
||||
render () {
|
||||
const { payload, id, className, isSending, date, onConfirm, onReject } = this.props;
|
||||
|
||||
if (payload.sign) {
|
||||
const { sign } = payload;
|
||||
return (
|
||||
<SignRequestWeb3
|
||||
className={ className }
|
||||
onConfirm={ onConfirm }
|
||||
onReject={ onReject }
|
||||
isSending={ isSending }
|
||||
isFinished={ false }
|
||||
id={ id }
|
||||
address={ sign.address }
|
||||
hash={ sign.hash }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (payload.transaction) {
|
||||
const { transaction } = payload;
|
||||
return (
|
||||
<TransactionPendingWeb3
|
||||
className={ className }
|
||||
onConfirm={ onConfirm }
|
||||
onReject={ onReject }
|
||||
isSending={ isSending }
|
||||
id={ id }
|
||||
gasPrice={ transaction.gasPrice }
|
||||
gas={ transaction.gas }
|
||||
data={ transaction.data }
|
||||
from={ transaction.from }
|
||||
to={ transaction.to }
|
||||
value={ transaction.value }
|
||||
date={ date }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Unknown payload
|
||||
return null;
|
||||
}
|
||||
}
|
||||
17
js/src/views/Signer/components/RequestPendingWeb3/index.js
Normal file
17
js/src/views/Signer/components/RequestPendingWeb3/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './RequestPendingWeb3';
|
||||
74
js/src/views/Signer/components/SignRequest/SignRequest.css
Normal file
74
js/src/views/Signer/components/SignRequest/SignRequest.css
Normal file
@@ -0,0 +1,74 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.container {
|
||||
padding: 25px 0 15px;
|
||||
}
|
||||
|
||||
.actions, .signDetails {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
min-height: 120px;
|
||||
}
|
||||
|
||||
.signDetails {
|
||||
border-right: 1px solid #eee;
|
||||
margin-right: 2rem;
|
||||
/* TODO [todr] mess - just to align with transaction */
|
||||
width: 430px;
|
||||
}
|
||||
|
||||
.address, .info {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.info {
|
||||
padding: 0 30px;
|
||||
width: 250px;
|
||||
color: #E53935;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.info p:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
/* TODO [todr] copy&paste from transactions */
|
||||
.isConfirmed {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.isRejected {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.txHash {
|
||||
display: block;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.actions {
|
||||
width: 180px;
|
||||
display: inline-block;
|
||||
min-height: 120px;
|
||||
}
|
||||
|
||||
.signDetails img {
|
||||
display: inline-block;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin: 5px;
|
||||
}
|
||||
113
js/src/views/Signer/components/SignRequest/SignRequest.js
Normal file
113
js/src/views/Signer/components/SignRequest/SignRequest.js
Normal file
@@ -0,0 +1,113 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import Account from '../Account';
|
||||
import TransactionPendingForm from '../TransactionPendingForm';
|
||||
import TxHashLink from '../TxHashLink';
|
||||
|
||||
import styles from './SignRequest.css';
|
||||
|
||||
export default class SignRequest extends Component {
|
||||
|
||||
// TODO [todr] re-use proptypes?
|
||||
static propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
address: PropTypes.string.isRequired,
|
||||
hash: PropTypes.string.isRequired,
|
||||
isFinished: PropTypes.bool.isRequired,
|
||||
chain: PropTypes.string.isRequired,
|
||||
balance: PropTypes.object,
|
||||
isSending: PropTypes.bool,
|
||||
onConfirm: PropTypes.func,
|
||||
onReject: PropTypes.func,
|
||||
status: PropTypes.string,
|
||||
className: PropTypes.string
|
||||
};
|
||||
|
||||
render () {
|
||||
const className = this.props.className || '';
|
||||
return (
|
||||
<div className={ `${styles.container} ${className}` }>
|
||||
{ this.renderDetails() }
|
||||
{ this.renderActions() }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderDetails () {
|
||||
const { address, balance, chain, hash } = this.props;
|
||||
|
||||
return (
|
||||
<div className={ styles.signDetails }>
|
||||
<div className={ styles.address }>
|
||||
<Account address={ address } balance={ balance } chain={ chain } />
|
||||
</div>
|
||||
<div className={ styles.info } title={ hash }>
|
||||
<p>Dapp is requesting to sign arbitrary transaction using this account.</p>
|
||||
<p><strong>Confirm the transaction only if you trust the app.</strong></p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderActions () {
|
||||
const { address, isFinished, status } = this.props;
|
||||
|
||||
if (isFinished) {
|
||||
if (status === 'confirmed') {
|
||||
const { chain, hash } = this.props;
|
||||
|
||||
return (
|
||||
<div className={ styles.actions }>
|
||||
<span className={ styles.isConfirmed }>Confirmed</span>
|
||||
<div>
|
||||
Transaction hash:
|
||||
<TxHashLink chain={ chain } txHash={ hash } className={ styles.txHash } />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={ styles.actions }>
|
||||
<span className={ styles.isRejected }>Rejected</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<TransactionPendingForm
|
||||
address={ address }
|
||||
isSending={ this.props.isSending }
|
||||
onConfirm={ this.onConfirm }
|
||||
onReject={ this.onReject }
|
||||
className={ styles.actions }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
onConfirm = password => {
|
||||
const { id } = this.props;
|
||||
this.props.onConfirm({ id, password });
|
||||
}
|
||||
|
||||
onReject = () => {
|
||||
this.props.onReject(this.props.id);
|
||||
}
|
||||
|
||||
}
|
||||
17
js/src/views/Signer/components/SignRequest/index.js
Normal file
17
js/src/views/Signer/components/SignRequest/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './SignRequest';
|
||||
@@ -0,0 +1,95 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import SignRequest from '../SignRequest';
|
||||
|
||||
export default class SignRequestWeb3 extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
address: PropTypes.string.isRequired,
|
||||
hash: PropTypes.string.isRequired,
|
||||
isFinished: PropTypes.bool.isRequired,
|
||||
isSending: PropTypes.bool,
|
||||
onConfirm: PropTypes.func,
|
||||
onReject: PropTypes.func,
|
||||
status: PropTypes.string,
|
||||
className: PropTypes.string
|
||||
};
|
||||
|
||||
state = {
|
||||
chain: 'homestead',
|
||||
balance: null // avoid required prop loading warning
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.fetchChain();
|
||||
this.fetchBalance();
|
||||
}
|
||||
|
||||
render () {
|
||||
const { balance, chain } = this.state;
|
||||
const { address, onConfirm, onReject, isSending, isFinished, hash, className, id, status } = this.props;
|
||||
|
||||
return (
|
||||
<SignRequest
|
||||
address={ address }
|
||||
hash={ hash }
|
||||
balance={ balance }
|
||||
onConfirm={ onConfirm }
|
||||
onReject={ onReject }
|
||||
isSending={ isSending }
|
||||
isFinished={ isFinished }
|
||||
id={ id }
|
||||
chain={ chain }
|
||||
status={ status }
|
||||
className={ className }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
fetchChain () {
|
||||
const { api } = this.context;
|
||||
|
||||
api.ethcore
|
||||
.getNetChain()
|
||||
.then((chain) => {
|
||||
this.setState({ chain });
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('fetchChain', error);
|
||||
});
|
||||
}
|
||||
|
||||
fetchBalance () {
|
||||
const { api } = this.context;
|
||||
const { address } = this.props;
|
||||
|
||||
api.eth
|
||||
.getBalance(address)
|
||||
.then((balance) => {
|
||||
this.setState({ balance });
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('fetchBalance', error);
|
||||
});
|
||||
}
|
||||
}
|
||||
17
js/src/views/Signer/components/SignRequestWeb3/index.js
Normal file
17
js/src/views/Signer/components/SignRequestWeb3/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './SignRequestWeb3';
|
||||
@@ -0,0 +1,55 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.container {
|
||||
padding: 25px 0 15px;
|
||||
}
|
||||
|
||||
.mainContainer {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mainContainer > * {
|
||||
vertical-align: middle;
|
||||
min-height: 120px;
|
||||
}
|
||||
|
||||
.statusContainer {
|
||||
width: 220px;
|
||||
padding: 20px 40px 0 40px;
|
||||
/*border-left: 1px solid #aaa;*/
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.transactionDetails {
|
||||
margin-right: 321px;
|
||||
}
|
||||
|
||||
.isConfirmed {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.isRejected {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.txHash {
|
||||
display: block;
|
||||
word-break: break-all;
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import TransactionMainDetails from '../TransactionMainDetails';
|
||||
import TxHashLink from '../TxHashLink';
|
||||
import TransactionSecondaryDetails from '../TransactionSecondaryDetails';
|
||||
|
||||
import styles from './TransactionFinished.css';
|
||||
|
||||
import * as tUtil from '../util/transaction';
|
||||
import { capitalize } from '../util/util';
|
||||
|
||||
export default class TransactionFinished extends Component {
|
||||
static propTypes = {
|
||||
id: PropTypes.object.isRequired,
|
||||
from: PropTypes.string.isRequired,
|
||||
fromBalance: PropTypes.object, // eth BigNumber, not required since it might take time to fetch
|
||||
value: PropTypes.object.isRequired, // wei hex
|
||||
chain: PropTypes.string.isRequired,
|
||||
gasPrice: PropTypes.object.isRequired, // wei hex
|
||||
gas: PropTypes.object.isRequired, // hex
|
||||
status: PropTypes.string.isRequired, // rejected, confirmed
|
||||
date: PropTypes.instanceOf(Date).isRequired,
|
||||
to: PropTypes.string, // undefined if it's a contract
|
||||
toBalance: PropTypes.object, // eth BigNumber - undefined if it's a contract or until it's fetched
|
||||
txHash: PropTypes.string, // undefined if transacation is rejected
|
||||
className: PropTypes.string,
|
||||
data: PropTypes.string
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
value: '0x0' // todo [adgo] - remove after resolving https://github.com/ethcore/parity/issues/1458
|
||||
};
|
||||
|
||||
componentWillMount () {
|
||||
const { gas, gasPrice, value } = this.props;
|
||||
const fee = tUtil.getFee(gas, gasPrice); // BigNumber object
|
||||
const totalValue = tUtil.getTotalValue(fee, value);
|
||||
this.setState({ totalValue });
|
||||
}
|
||||
|
||||
render () {
|
||||
const { className, date, id } = this.props;
|
||||
const { totalValue } = this.state;
|
||||
|
||||
return (
|
||||
<div className={ `${styles.container} ${className || ''}` }>
|
||||
<div className={ styles.mainContainer }>
|
||||
<TransactionMainDetails
|
||||
{ ...this.props }
|
||||
totalValue={ totalValue }
|
||||
className={ styles.transactionDetails }
|
||||
>
|
||||
<TransactionSecondaryDetails
|
||||
id={ id }
|
||||
date={ date }
|
||||
/>
|
||||
</TransactionMainDetails>
|
||||
<div className={ styles.statusContainer }>
|
||||
{ this.renderStatus() }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderStatus () {
|
||||
const { status } = this.props;
|
||||
const klass = status === 'confirmed' ? styles.isConfirmed : styles.isRejected;
|
||||
return (
|
||||
<div>
|
||||
<span className={ klass }>{ capitalize(status) }</span>
|
||||
{ this.renderTxHash() }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderTxHash () {
|
||||
const { txHash, chain } = this.props;
|
||||
if (!txHash) {
|
||||
return;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
Transaction hash:
|
||||
<TxHashLink chain={ chain } txHash={ txHash } className={ styles.txHash } />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
17
js/src/views/Signer/components/TransactionFinished/index.js
Normal file
17
js/src/views/Signer/components/TransactionFinished/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './TransactionFinished';
|
||||
@@ -0,0 +1,92 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import TransactionFinished from '../TransactionFinished';
|
||||
|
||||
export default class TransactionFinishedWeb3 extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
from: PropTypes.string.isRequired,
|
||||
to: PropTypes.string // undefined if it's a contract
|
||||
}
|
||||
|
||||
state = {
|
||||
chain: 'homestead'
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.fetchChain();
|
||||
this.fetchBalances();
|
||||
}
|
||||
|
||||
render () {
|
||||
const { fromBalance, toBalance, chain } = this.state;
|
||||
const { from, to } = this.props;
|
||||
|
||||
return (
|
||||
<TransactionFinished
|
||||
{ ...this.props }
|
||||
from={ from }
|
||||
fromBalance={ fromBalance }
|
||||
to={ to }
|
||||
toBalance={ toBalance }
|
||||
chain={ chain }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
fetchChain () {
|
||||
const { api } = this.context;
|
||||
|
||||
api.ethcore
|
||||
.netChain()
|
||||
.then((chain) => {
|
||||
this.setState({ chain });
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('fetchChain', error);
|
||||
});
|
||||
}
|
||||
|
||||
fetchBalances () {
|
||||
const { from, to } = this.props;
|
||||
this.fetchBalance(from, 'from');
|
||||
|
||||
if (!to) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.fetchBalance(to, 'to');
|
||||
}
|
||||
|
||||
fetchBalance (address, owner) {
|
||||
const { api } = this.context;
|
||||
|
||||
api.eth
|
||||
.getBalance(address)
|
||||
.then((balance) => {
|
||||
this.setState({ [owner + 'Balance']: balance });
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('fetchBalance', error);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './TransactionFinishedWeb3';
|
||||
@@ -0,0 +1,72 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.transaction {
|
||||
}
|
||||
|
||||
.transaction > * {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.account {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.from, .to {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.from .account {
|
||||
padding-right: 75px;
|
||||
}
|
||||
|
||||
.to .account {
|
||||
padding-left: 75px;
|
||||
}
|
||||
|
||||
.from img, .to img {
|
||||
display: inline-block;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.from span, .to span {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tx {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
margin: 0 -75px;
|
||||
width: 150px;
|
||||
top: -20px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.total {
|
||||
font-size: 0.6em;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
.contractIcon {
|
||||
background: #eee;
|
||||
width: 50px !important;
|
||||
height: 50px !important;
|
||||
box-sizing: border-box;
|
||||
border-radius: 50%;
|
||||
padding: 13px;
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import ContractIcon from 'material-ui/svg-icons/action/code';
|
||||
import ReactTooltip from 'react-tooltip';
|
||||
|
||||
import * as tUtil from '../util/transaction';
|
||||
import Account from '../Account';
|
||||
import styles from './TransactionMainDetails.css';
|
||||
|
||||
export default class TransactionMainDetails extends Component {
|
||||
static propTypes = {
|
||||
id: PropTypes.object.isRequired,
|
||||
from: PropTypes.string.isRequired,
|
||||
fromBalance: PropTypes.object, // eth BigNumber, not required since it might take time to fetch
|
||||
value: PropTypes.object.isRequired, // wei hex
|
||||
totalValue: PropTypes.object.isRequired, // wei BigNumber
|
||||
chain: PropTypes.string.isRequired,
|
||||
to: PropTypes.string, // undefined if it's a contract
|
||||
toBalance: PropTypes.object, // eth BigNumber - undefined if it's a contract or until it's fetched
|
||||
className: PropTypes.string,
|
||||
children: PropTypes.node
|
||||
};
|
||||
|
||||
componentWillMount () {
|
||||
const { value, totalValue } = this.props;
|
||||
this.updateDisplayValues(value, totalValue);
|
||||
}
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
const { value, totalValue } = nextProps;
|
||||
this.updateDisplayValues(value, totalValue);
|
||||
}
|
||||
|
||||
updateDisplayValues (value, totalValue) {
|
||||
this.setState({
|
||||
feeEth: tUtil.calcFeeInEth(totalValue, value),
|
||||
valueDisplay: tUtil.getValueDisplay(value),
|
||||
valueDisplayWei: tUtil.getValueDisplayWei(value),
|
||||
totalValueDisplay: tUtil.getTotalValueDisplay(totalValue),
|
||||
totalValueDisplayWei: tUtil.getTotalValueDisplayWei(totalValue)
|
||||
});
|
||||
}
|
||||
|
||||
render () {
|
||||
const { className, children } = this.props;
|
||||
return (
|
||||
<div className={ className }>
|
||||
{ this.renderTransfer() }
|
||||
{ this.renderContract() }
|
||||
{ children }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderTransfer () {
|
||||
const { from, fromBalance, to, toBalance, chain } = this.props;
|
||||
if (!to) {
|
||||
return;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={ styles.transaction }>
|
||||
<div className={ styles.from }>
|
||||
<div className={ styles.account }>
|
||||
<Account address={ from } balance={ fromBalance } chain={ chain } />
|
||||
</div>
|
||||
</div>
|
||||
<div className={ styles.tx }>
|
||||
{ this.renderValue() }
|
||||
<div>⇒</div>
|
||||
{ this.renderTotalValue() }
|
||||
</div>
|
||||
<div className={ styles.to }>
|
||||
<div className={ styles.account }>
|
||||
<Account address={ to } balance={ toBalance } chain={ chain } />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderContract () {
|
||||
const { from, fromBalance, to, chain } = this.props;
|
||||
if (to) {
|
||||
return;
|
||||
}
|
||||
return (
|
||||
<div className={ styles.transaction }>
|
||||
<div className={ styles.from }>
|
||||
<div className={ styles.account }>
|
||||
<Account address={ from } balance={ fromBalance } chain={ chain } />
|
||||
</div>
|
||||
</div>
|
||||
<div className={ styles.tx }>
|
||||
{ this.renderValue() }
|
||||
<div>⇒</div>
|
||||
{ this.renderTotalValue() }
|
||||
</div>
|
||||
<div className={ styles.to }>
|
||||
<div className={ styles.account }>
|
||||
<ContractIcon className={ styles.contractIcon } />
|
||||
<br />
|
||||
Contract
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderValue () {
|
||||
const { id } = this.props;
|
||||
const { valueDisplay, valueDisplayWei } = this.state;
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
data-tip
|
||||
data-for={ 'value' + id }
|
||||
data-effect='solid'
|
||||
>
|
||||
<strong>{ valueDisplay } </strong>
|
||||
<small>ETH</small>
|
||||
</div>
|
||||
<ReactTooltip id={ 'value' + id }>
|
||||
The value of the transaction.<br />
|
||||
<strong>{ valueDisplayWei }</strong> <small>WEI</small>
|
||||
</ReactTooltip>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderTotalValue () {
|
||||
const { id } = this.props;
|
||||
const { totalValueDisplay, totalValueDisplayWei, feeEth } = this.state;
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
data-tip
|
||||
data-for={ 'totalValue' + id }
|
||||
data-effect='solid'
|
||||
data-place='bottom'
|
||||
className={ styles.total }>
|
||||
{ totalValueDisplay } <small>ETH</small>
|
||||
</div>
|
||||
<ReactTooltip id={ 'totalValue' + id }>
|
||||
The value of the transaction including the mining fee is <strong>{ totalValueDisplayWei }</strong> <small>WEI</small>. <br />
|
||||
(This includes a mining fee of <strong>{ feeEth }</strong> <small>ETH</small>)
|
||||
</ReactTooltip>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './TransactionMainDetails';
|
||||
@@ -0,0 +1,44 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.container {
|
||||
padding: 25px 0 15px;
|
||||
}
|
||||
|
||||
.transactionDetails {
|
||||
margin-right: 321px;
|
||||
}
|
||||
|
||||
.mainContainer {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mainContainer:after {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.mainContainer > * {
|
||||
vertical-align: middle;
|
||||
min-height: 120px;
|
||||
}
|
||||
|
||||
.inputs {
|
||||
margin-right: 30px;
|
||||
margin-left: 30px;
|
||||
width: 180px;
|
||||
position: relative;
|
||||
top: -15px; /* due to material ui weird styling */
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import TransactionMainDetails from '../TransactionMainDetails';
|
||||
import TransactionPendingForm from '../TransactionPendingForm';
|
||||
import TransactionSecondaryDetails from '../TransactionSecondaryDetails';
|
||||
|
||||
import styles from './TransactionPending.css';
|
||||
|
||||
import * as tUtil from '../util/transaction';
|
||||
|
||||
export default class TransactionPending extends Component {
|
||||
static propTypes = {
|
||||
id: PropTypes.object.isRequired,
|
||||
chain: PropTypes.string.isRequired,
|
||||
from: PropTypes.string.isRequired,
|
||||
fromBalance: PropTypes.object, // eth BigNumber, not required since it mght take time to fetch
|
||||
value: PropTypes.object.isRequired, // wei hex
|
||||
gasPrice: PropTypes.object.isRequired, // wei hex
|
||||
gas: PropTypes.object.isRequired, // hex
|
||||
date: PropTypes.instanceOf(Date).isRequired,
|
||||
to: PropTypes.string, // undefined if it's a contract
|
||||
toBalance: PropTypes.object, // eth BigNumber - undefined if it's a contract or until it's fetched
|
||||
data: PropTypes.string, // hex
|
||||
nonce: PropTypes.number,
|
||||
onConfirm: PropTypes.func.isRequired,
|
||||
onReject: PropTypes.func.isRequired,
|
||||
isSending: PropTypes.bool.isRequired,
|
||||
className: PropTypes.string
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
isSending: false
|
||||
};
|
||||
|
||||
state = {
|
||||
isDataExpanded: false
|
||||
};
|
||||
|
||||
componentWillMount () {
|
||||
const { gas, gasPrice, value } = this.props;
|
||||
const fee = tUtil.getFee(gas, gasPrice); // BigNumber object
|
||||
const totalValue = tUtil.getTotalValue(fee, value);
|
||||
const gasPriceEthmDisplay = tUtil.getEthmFromWeiDisplay(gasPrice);
|
||||
const gasToDisplay = tUtil.getGasDisplay(gas);
|
||||
this.setState({ gasPriceEthmDisplay, totalValue, gasToDisplay });
|
||||
}
|
||||
|
||||
render () {
|
||||
const { totalValue } = this.state;
|
||||
const className = this.props.className || '';
|
||||
|
||||
const { gasPriceEthmDisplay, gasToDisplay } = this.state;
|
||||
const { id, date, data, from } = this.props;
|
||||
|
||||
return (
|
||||
<div className={ `${styles.container} ${className}` }>
|
||||
<div className={ styles.mainContainer }>
|
||||
<TransactionMainDetails
|
||||
{ ...this.props }
|
||||
className={ styles.transactionDetails }
|
||||
totalValue={ totalValue }>
|
||||
<TransactionSecondaryDetails
|
||||
id={ id }
|
||||
date={ date }
|
||||
data={ data }
|
||||
gasPriceEthmDisplay={ gasPriceEthmDisplay }
|
||||
gasToDisplay={ gasToDisplay }
|
||||
/>
|
||||
</TransactionMainDetails>
|
||||
<TransactionPendingForm
|
||||
address={ from }
|
||||
isSending={ this.props.isSending }
|
||||
onConfirm={ this.onConfirm }
|
||||
onReject={ this.onReject }
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
onConfirm = password => {
|
||||
const { id, gasPrice } = this.props;
|
||||
this.props.onConfirm({ id, password, gasPrice });
|
||||
}
|
||||
|
||||
onReject = () => {
|
||||
this.props.onReject(this.props.id);
|
||||
}
|
||||
|
||||
}
|
||||
17
js/src/views/Signer/components/TransactionPending/index.js
Normal file
17
js/src/views/Signer/components/TransactionPending/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './TransactionPending';
|
||||
@@ -0,0 +1,45 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.container {
|
||||
width: 220px;
|
||||
padding: 20px 40px 0 40px;
|
||||
/*border-left: 1px solid #aaa;*/
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.rejectToggle {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
color: #00e;
|
||||
opacity: .7;
|
||||
transition: opacity .5s;
|
||||
}
|
||||
|
||||
.rejectToggle:hover {
|
||||
opacity: 1;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.rejectToggle svg {
|
||||
position: relative;
|
||||
width: 18px !important;
|
||||
height: 18px !important;
|
||||
top: 3px;
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import BackIcon from 'material-ui/svg-icons/navigation/arrow-back';
|
||||
|
||||
import TransactionPendingFormConfirm from './TransactionPendingFormConfirm';
|
||||
import TransactionPendingFormReject from './TransactionPendingFormReject';
|
||||
import styles from './TransactionPendingForm.css';
|
||||
|
||||
export default class TransactionPendingForm extends Component {
|
||||
|
||||
static propTypes = {
|
||||
address: PropTypes.string.isRequired,
|
||||
isSending: PropTypes.bool.isRequired,
|
||||
onConfirm: PropTypes.func.isRequired,
|
||||
onReject: PropTypes.func.isRequired,
|
||||
className: PropTypes.string
|
||||
};
|
||||
|
||||
state = {
|
||||
isRejectOpen: false
|
||||
};
|
||||
|
||||
render () {
|
||||
const { className } = this.props;
|
||||
|
||||
return (
|
||||
<div className={ `${styles.container} ${className}` }>
|
||||
{ this.renderForm() }
|
||||
{ this.renderRejectToggle() }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderForm () {
|
||||
const { address, isSending, onConfirm, onReject } = this.props;
|
||||
|
||||
if (this.state.isRejectOpen) {
|
||||
return (
|
||||
<TransactionPendingFormReject
|
||||
onReject={ onReject } />
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<TransactionPendingFormConfirm
|
||||
address={ address }
|
||||
onConfirm={ onConfirm }
|
||||
isSending={ isSending } />
|
||||
);
|
||||
}
|
||||
|
||||
renderRejectToggle () {
|
||||
const { isRejectOpen } = this.state;
|
||||
let html;
|
||||
|
||||
if (!isRejectOpen) {
|
||||
html = <span>reject transaction</span>;
|
||||
} else {
|
||||
html = <span><BackIcon />I've changed my mind</span>;
|
||||
}
|
||||
|
||||
return (
|
||||
<a
|
||||
onClick={ this.onToggleReject }
|
||||
className={ styles.rejectToggle }
|
||||
>
|
||||
{ html }
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
onToggleReject = () => {
|
||||
const { isRejectOpen } = this.state;
|
||||
this.setState({ isRejectOpen: !isRejectOpen });
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.confirmForm {
|
||||
margin-top: -45px;
|
||||
}
|
||||
|
||||
.confirmButton {
|
||||
display: block !important;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.signerIcon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
vertical-align: middle;
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
.passwordHint {
|
||||
font-size: 0.75em;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
|
||||
.passwordHint span {
|
||||
opacity: 0.85;
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import RaisedButton from 'material-ui/RaisedButton';
|
||||
import ReactTooltip from 'react-tooltip';
|
||||
|
||||
import { Form, Input, SignerIcon } from '../../../../../ui';
|
||||
|
||||
import styles from './TransactionPendingFormConfirm.css';
|
||||
|
||||
class TransactionPendingFormConfirm extends Component {
|
||||
static propTypes = {
|
||||
accounts: PropTypes.object.isRequired,
|
||||
address: PropTypes.string.isRequired,
|
||||
isSending: PropTypes.bool.isRequired,
|
||||
onConfirm: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
id = Math.random(); // for tooltip
|
||||
|
||||
state = {
|
||||
password: ''
|
||||
}
|
||||
|
||||
render () {
|
||||
const { accounts, address, isSending } = this.props;
|
||||
const { password } = this.state;
|
||||
const account = accounts[address] || {};
|
||||
|
||||
const passwordHint = account.meta && account.meta.passwordHint
|
||||
? (<div><span>(hint) </span>{ account.meta.passwordHint }</div>)
|
||||
: null;
|
||||
|
||||
return (
|
||||
<div className={ styles.confirmForm }>
|
||||
<Form>
|
||||
<Input
|
||||
onChange={ this.onModifyPassword }
|
||||
onKeyDown={ this.onKeyDown }
|
||||
label='Account Password'
|
||||
hint='unlock the account'
|
||||
type='password'
|
||||
value={ password } />
|
||||
<div className={ styles.passwordHint }>
|
||||
{ passwordHint }
|
||||
</div>
|
||||
<div
|
||||
data-tip
|
||||
data-place='bottom'
|
||||
data-for={ 'transactionConfirmForm' + this.id }
|
||||
data-effect='solid'
|
||||
>
|
||||
<RaisedButton
|
||||
onClick={ this.onConfirm }
|
||||
className={ styles.confirmButton }
|
||||
fullWidth
|
||||
primary
|
||||
disabled={ isSending }
|
||||
icon={ <SignerIcon className={ styles.signerIcon } /> }
|
||||
label={ isSending ? 'Confirming...' : 'Confirm Transaction' }
|
||||
/>
|
||||
</div>
|
||||
{ this.renderTooltip() }
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderTooltip () {
|
||||
if (this.state.password.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
return (
|
||||
<ReactTooltip id={ 'transactionConfirmForm' + this.id }>
|
||||
Please provide a password for this account
|
||||
</ReactTooltip>
|
||||
);
|
||||
}
|
||||
|
||||
onModifyPassword = evt => {
|
||||
const password = evt.target.value;
|
||||
this.setState({
|
||||
password
|
||||
});
|
||||
}
|
||||
|
||||
onConfirm = () => {
|
||||
const { password } = this.state;
|
||||
this.props.onConfirm(password);
|
||||
}
|
||||
|
||||
onKeyDown = evt => {
|
||||
if (evt.which !== 13) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.onConfirm();
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
const { accounts } = state.personal;
|
||||
|
||||
return {
|
||||
accounts
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return bindActionCreators({}, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(TransactionPendingFormConfirm);
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './TransactionPendingFormConfirm';
|
||||
@@ -0,0 +1,25 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/* the rejection button itself, once .reject has been pressed */
|
||||
.rejectButton {
|
||||
display: block !important;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.rejectText {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import RaisedButton from 'material-ui/RaisedButton';
|
||||
|
||||
import { REJECT_COUNTER_TIME } from '../../constants/constants';
|
||||
import styles from './TransactionPendingFormReject.css';
|
||||
|
||||
export default class TransactionPendingFormReject extends Component {
|
||||
|
||||
static propTypes = {
|
||||
onReject: PropTypes.func.isRequired,
|
||||
className: PropTypes.string,
|
||||
rejectCounterTime: PropTypes.number
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
rejectCounterTime: REJECT_COUNTER_TIME
|
||||
};
|
||||
|
||||
state = {
|
||||
rejectCounter: this.props.rejectCounterTime
|
||||
}
|
||||
|
||||
componentWillMount () {
|
||||
this.onInitCounter();
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
this.onResetCounter();
|
||||
}
|
||||
|
||||
render () {
|
||||
const { rejectCounter } = this.state;
|
||||
const { onReject } = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={ styles.rejectText }>
|
||||
Are you sure you want to reject transaction? <br />
|
||||
<strong>This cannot be undone</strong>
|
||||
</div>
|
||||
<RaisedButton
|
||||
onClick={ onReject }
|
||||
className={ styles.rejectButton }
|
||||
disabled={ rejectCounter > 0 }
|
||||
fullWidth
|
||||
label={ `Reject Transaction ${this.renderCounter()}` }
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderCounter () {
|
||||
const { rejectCounter } = this.state;
|
||||
if (!rejectCounter) {
|
||||
return '';
|
||||
}
|
||||
return `(${rejectCounter})`;
|
||||
}
|
||||
|
||||
onInitCounter () {
|
||||
this.rejectInterval = setInterval(() => {
|
||||
let { rejectCounter } = this.state;
|
||||
if (rejectCounter === 0) {
|
||||
return clearInterval(this.rejectInterval);
|
||||
}
|
||||
this.setState({ rejectCounter: rejectCounter - 1 });
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
onResetCounter () {
|
||||
clearInterval(this.rejectInterval);
|
||||
this.setState({
|
||||
rejectCounter: this.props.rejectCounterTime
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './TransactionPendingFormReject';
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './TransactionPendingForm';
|
||||
@@ -0,0 +1,106 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import TransactionPending from '../TransactionPending';
|
||||
|
||||
export default class TransactionPendingWeb3 extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
id: PropTypes.object.isRequired,
|
||||
from: PropTypes.string.isRequired,
|
||||
value: PropTypes.object.isRequired, // wei hex
|
||||
gasPrice: PropTypes.object.isRequired, // wei hex
|
||||
gas: PropTypes.object.isRequired, // hex
|
||||
onConfirm: PropTypes.func.isRequired,
|
||||
onReject: PropTypes.func.isRequired,
|
||||
isSending: PropTypes.bool.isRequired,
|
||||
date: PropTypes.instanceOf(Date).isRequired,
|
||||
to: PropTypes.string, // undefined if it's a contract
|
||||
data: PropTypes.string, // hex
|
||||
nonce: PropTypes.number,
|
||||
className: PropTypes.string
|
||||
};
|
||||
|
||||
state = {
|
||||
chain: 'homestead',
|
||||
fromBalance: null, // avoid required prop loading warning
|
||||
toBalance: null // avoid required prop loading warning in case there's a to address
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.fetchChain();
|
||||
this.fetchBalances();
|
||||
}
|
||||
|
||||
render () {
|
||||
const { fromBalance, toBalance, chain } = this.state;
|
||||
const { from, to, date } = this.props;
|
||||
|
||||
return (
|
||||
<TransactionPending
|
||||
{ ...this.props }
|
||||
from={ from }
|
||||
to={ to }
|
||||
fromBalance={ fromBalance }
|
||||
toBalance={ toBalance }
|
||||
chain={ chain }
|
||||
date={ date }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
fetchChain () {
|
||||
const { api } = this.context;
|
||||
|
||||
api.ethcore
|
||||
.netChain()
|
||||
.then((chain) => {
|
||||
this.setState({ chain });
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('fetchChain', error);
|
||||
});
|
||||
}
|
||||
|
||||
fetchBalances () {
|
||||
const { from, to } = this.props;
|
||||
this.fetchBalance(from, 'from');
|
||||
|
||||
if (!to) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.fetchBalance(to, 'to');
|
||||
}
|
||||
|
||||
fetchBalance (address, owner) {
|
||||
const { api } = this.context;
|
||||
|
||||
api.eth
|
||||
.getBalance(address)
|
||||
.then((balance) => {
|
||||
this.setState({ [owner + 'Balance']: balance });
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('fetchBalance', error);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './TransactionPendingWeb3';
|
||||
@@ -0,0 +1,70 @@
|
||||
.iconsContainer {
|
||||
display: block;
|
||||
text-align: center;
|
||||
font-size: .8em;
|
||||
opacity: 0.5;
|
||||
padding: 1em 0 0 0;
|
||||
}
|
||||
|
||||
.iconsContainer > * {
|
||||
margin-right: 3px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.iconsContainer:after {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.hasInfoIcon svg,
|
||||
.miningTime svg,
|
||||
.gasPrice svg,
|
||||
.data svg,
|
||||
.date svg {
|
||||
width: 16px !important;
|
||||
height: 16px !important;
|
||||
position: relative;
|
||||
bottom: -3px;
|
||||
margin: 0 0.25rem 0 0.75rem;
|
||||
}
|
||||
|
||||
/* TODO [ToDr] composes was handling weird errors when linking from other app */
|
||||
.miningTime {
|
||||
/* composes: hasInfoIcon; */
|
||||
}
|
||||
|
||||
.gasPrice {
|
||||
/* composes: hasInfoIcon; */
|
||||
}
|
||||
|
||||
.data {
|
||||
/* composes: hasInfoIcon; */
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.data.noData {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
|
||||
.dataTooltip {
|
||||
word-wrap: break-word;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.expandedData {
|
||||
display: block;
|
||||
padding: 15px;
|
||||
background: gray;
|
||||
word-wrap: break-word;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.expandedContainer {
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.expandedContainer:empty {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import ReactTooltip from 'react-tooltip';
|
||||
import DescriptionIcon from 'material-ui/svg-icons/action/description';
|
||||
import GasIcon from 'material-ui/svg-icons/maps/local-gas-station';
|
||||
import TimeIcon from 'material-ui/svg-icons/device/access-time';
|
||||
import moment from 'moment';
|
||||
|
||||
import styles from './TransactionSecondaryDetails.css';
|
||||
|
||||
import * as tUtil from '../util/transaction';
|
||||
|
||||
export default class TransactionSecondaryDetails extends Component {
|
||||
|
||||
static propTypes = {
|
||||
id: PropTypes.object.isRequired,
|
||||
date: PropTypes.instanceOf(Date),
|
||||
data: PropTypes.string, // hex
|
||||
gasPriceEthmDisplay: PropTypes.string,
|
||||
gasToDisplay: PropTypes.string,
|
||||
className: PropTypes.string
|
||||
};
|
||||
|
||||
state = {
|
||||
isDataExpanded: false
|
||||
};
|
||||
|
||||
render () {
|
||||
const className = this.props.className || '';
|
||||
|
||||
return (
|
||||
<div className={ className }>
|
||||
<div className={ styles.iconsContainer }>
|
||||
{ this.renderGasPrice() }
|
||||
{ this.renderData() }
|
||||
{ this.renderDate() }
|
||||
</div>
|
||||
<div className={ styles.expandedContainer }>
|
||||
{ this.renderDataExpanded() }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderGasPrice () {
|
||||
if (!this.props.gasPriceEthmDisplay && !this.props.gasToDisplay) return null;
|
||||
|
||||
const { id } = this.props;
|
||||
const { gasPriceEthmDisplay, gasToDisplay } = this.props;
|
||||
return (
|
||||
<div
|
||||
data-tip
|
||||
data-place='right'
|
||||
data-for={ 'gasPrice' + id }
|
||||
data-effect='solid'
|
||||
>
|
||||
<span className={ styles.gasPrice }>
|
||||
<GasIcon />
|
||||
{ gasPriceEthmDisplay } <small>ETH/MGAS</small>
|
||||
</span>
|
||||
{ /* dynamic id required in case there are multple transactions in page */ }
|
||||
<ReactTooltip id={ 'gasPrice' + id }>
|
||||
Cost of 1,000,000 units of gas. This transaction will use up to <strong>{ gasToDisplay }</strong> <small>MGAS</small>.
|
||||
</ReactTooltip>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderData () {
|
||||
if (!this.props.data) return null;
|
||||
|
||||
const { data, id } = this.props;
|
||||
let dataToDisplay = this.noData() ? 'no data' : tUtil.getShortData(data);
|
||||
const noDataClass = this.noData() ? styles.noData : '';
|
||||
return (
|
||||
<div
|
||||
className={ `${styles.data} ${noDataClass}` }
|
||||
onClick={ this.toggleDataExpanded }
|
||||
data-tip
|
||||
data-place='right'
|
||||
data-for={ 'data' + id }
|
||||
data-class={ styles.dataTooltip }
|
||||
data-effect='solid'
|
||||
>
|
||||
<DescriptionIcon />
|
||||
{ dataToDisplay }
|
||||
{ /* dynamic id required in case there are multple transactions in page */ }
|
||||
<ReactTooltip id={ 'data' + id }>
|
||||
<strong>Extra data for the transaction: </strong>
|
||||
<br />
|
||||
{ dataToDisplay }.
|
||||
<br />
|
||||
{ this.noData() ? '' : <strong>Click to expand.</strong> }
|
||||
</ReactTooltip>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderDate () {
|
||||
const { date, id } = this.props;
|
||||
|
||||
const dateToDisplay = moment(date).fromNow();
|
||||
const fullDate = moment(date).format('LL LTS');
|
||||
|
||||
return (
|
||||
<div
|
||||
className={ styles.date }
|
||||
data-tip
|
||||
data-place='right'
|
||||
data-for={ 'date' + id }
|
||||
data-class={ styles.dataTooltip }
|
||||
data-effect='solid'
|
||||
>
|
||||
<TimeIcon />
|
||||
{ dateToDisplay }
|
||||
{ /* dynamic id required in case there are multple transactions in page */ }
|
||||
<ReactTooltip id={ 'date' + id }>
|
||||
<strong>Date of the request: </strong>
|
||||
<br />
|
||||
{ fullDate }
|
||||
</ReactTooltip>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderDataExpanded () {
|
||||
if (!this.props.data) return null;
|
||||
|
||||
const { isDataExpanded } = this.state;
|
||||
const { data } = this.props;
|
||||
|
||||
if (!isDataExpanded) {
|
||||
return;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={ styles.expandedHelper }>
|
||||
<h3>Transaction's Data</h3>
|
||||
<code className={ styles.expandedData }>{ data }</code>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
noData () {
|
||||
return this.props.data === '0x';
|
||||
}
|
||||
|
||||
toggleDataExpanded = () => {
|
||||
if (this.noData()) {
|
||||
return;
|
||||
}
|
||||
this.setState({
|
||||
isDataExpanded: !this.state.isDataExpanded
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export default from './TransactionSecondaryDetails';
|
||||
63
js/src/views/Signer/components/TxHashLink/TxHashLink.js
Normal file
63
js/src/views/Signer/components/TxHashLink/TxHashLink.js
Normal file
@@ -0,0 +1,63 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import { getTxLink } from '../util/transaction';
|
||||
|
||||
export default class TxHashLink extends Component {
|
||||
|
||||
static propTypes = {
|
||||
txHash: PropTypes.string.isRequired,
|
||||
chain: PropTypes.string.isRequired,
|
||||
children: PropTypes.node,
|
||||
className: PropTypes.string
|
||||
}
|
||||
|
||||
state = {
|
||||
link: null
|
||||
};
|
||||
|
||||
componentWillMount () {
|
||||
const { txHash, chain } = this.props;
|
||||
this.updateLink(txHash, chain);
|
||||
}
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
const { txHash, chain } = nextProps;
|
||||
this.updateLink(txHash, chain);
|
||||
}
|
||||
|
||||
render () {
|
||||
const { children, txHash, className } = this.props;
|
||||
const { link } = this.state;
|
||||
|
||||
return (
|
||||
<a
|
||||
href={ link }
|
||||
target='_blank'
|
||||
className={ className }>
|
||||
{ children || txHash }
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
updateLink (txHash, chain) {
|
||||
const link = getTxLink(txHash, chain);
|
||||
this.setState({ link });
|
||||
}
|
||||
|
||||
}
|
||||
17
js/src/views/Signer/components/TxHashLink/index.js
Normal file
17
js/src/views/Signer/components/TxHashLink/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './TxHashLink';
|
||||
26
js/src/views/Signer/components/constants/constants.js
Normal file
26
js/src/views/Signer/components/constants/constants.js
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// after user clicks 'reject' for the first time,
|
||||
// a second reject button is rendered and disabled
|
||||
// for a few seconds to avoid accidential double clicks
|
||||
export const REJECT_COUNTER_TIME = 3;
|
||||
|
||||
// links to chain explorers
|
||||
export const BASE_LINK_ACCOUNT_MORDEN = 'https://testnet.etherscan.io/address/';
|
||||
export const BASE_LINK_ACCOUNT_HOMESTEAD = 'https://etherscan.io/address/';
|
||||
export const BASE_LINK_TX_MORDEN = 'https://testnet.etherscan.io/tx/';
|
||||
export const BASE_LINK_TX_HOMESTEAD = 'https://etherscan.io/tx/';
|
||||
18
js/src/views/Signer/components/index.js
Normal file
18
js/src/views/Signer/components/index.js
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export RequestFinishedWeb3 from './RequestFinishedWeb3';
|
||||
export RequestPendingWeb3 from './RequestPendingWeb3';
|
||||
25
js/src/views/Signer/components/util/account.js
Normal file
25
js/src/views/Signer/components/util/account.js
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { BASE_LINK_ACCOUNT_MORDEN, BASE_LINK_ACCOUNT_HOMESTEAD } from '../constants/constants';
|
||||
|
||||
export const getAccountLink = _getAccountLink;
|
||||
|
||||
function _getAccountLink (address, chain) {
|
||||
const isTestNet = chain === 'morden' || chain === 'testnet';
|
||||
const base = isTestNet ? BASE_LINK_ACCOUNT_MORDEN : BASE_LINK_ACCOUNT_HOMESTEAD;
|
||||
return base + address;
|
||||
}
|
||||
38
js/src/views/Signer/components/util/logger.js
Normal file
38
js/src/views/Signer/components/util/logger.js
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
const isLogging = process.env.LOGGING;
|
||||
|
||||
export default logger();
|
||||
|
||||
function logger () {
|
||||
return isLogging ? devLogger() : prodLogger();
|
||||
}
|
||||
|
||||
function prodLogger () {
|
||||
return {
|
||||
log: noop,
|
||||
info: noop,
|
||||
error: noop,
|
||||
warn: noop
|
||||
};
|
||||
}
|
||||
|
||||
function devLogger () {
|
||||
return console;
|
||||
}
|
||||
|
||||
function noop () {}
|
||||
21
js/src/views/Signer/components/util/react.js
vendored
Normal file
21
js/src/views/Signer/components/util/react.js
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { isValidElement } from 'react';
|
||||
|
||||
export function isReactComponent (componentOrElem) {
|
||||
return isValidElement(componentOrElem) && typeof componentOrElem.type === 'function';
|
||||
}
|
||||
121
js/src/views/Signer/components/util/transaction.js
Normal file
121
js/src/views/Signer/components/util/transaction.js
Normal file
@@ -0,0 +1,121 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import BigNumber from 'bignumber.js';
|
||||
|
||||
const WEI_TO_ETH_MULTIPLIER = 0.000000000000000001;
|
||||
const WEI_TO_SZABU_MULTIPLIER = 0.000000000001;
|
||||
import { BASE_LINK_TX_MORDEN, BASE_LINK_TX_HOMESTEAD } from '../constants/constants';
|
||||
|
||||
export const getShortData = _getShortData;
|
||||
// calculations
|
||||
export const getFee = _getFee;
|
||||
export const calcFeeInEth = _calcFeeInEth;
|
||||
export const getTotalValue = _getTotalValue;
|
||||
// displays
|
||||
export const getSzaboFromWeiDisplay = _getSzaboFromWeiDisplay;
|
||||
export const getValueDisplay = _getValueDisplay;
|
||||
export const getValueDisplayWei = _getValueDisplayWei;
|
||||
export const getTotalValueDisplay = _getTotalValueDisplay;
|
||||
export const getTotalValueDisplayWei = _getTotalValueDisplayWei;
|
||||
export const getEthmFromWeiDisplay = _getEthmFromWeiDisplay;
|
||||
export const getGasDisplay = _getGasDisplay;
|
||||
// links
|
||||
export const getTxLink = _getTxLink;
|
||||
|
||||
function _getShortData (data) {
|
||||
if (data.length <= 3) {
|
||||
return data;
|
||||
}
|
||||
return data.substr(0, 3) + '...';
|
||||
}
|
||||
|
||||
/*
|
||||
* @param {hex string} gas
|
||||
* @param {wei hex string} gasPrice
|
||||
* @return {BigNumber} fee in wei
|
||||
*/
|
||||
function _getFee (gas, gasPrice) {
|
||||
gas = new BigNumber(gas);
|
||||
gasPrice = new BigNumber(gasPrice);
|
||||
return gasPrice.times(gas);
|
||||
}
|
||||
|
||||
function _calcFeeInEth (totalValue, value) {
|
||||
let fee = new BigNumber(totalValue).sub(new BigNumber(value));
|
||||
return fee.times(WEI_TO_ETH_MULTIPLIER).toFormat(7);
|
||||
}
|
||||
|
||||
/*
|
||||
* @param {wei BigNumber} fee
|
||||
* @param {wei hex string} value
|
||||
* @return {BigNumber} total value in wei
|
||||
*/
|
||||
function _getTotalValue (fee, value) {
|
||||
value = new BigNumber(value);
|
||||
return fee.plus(value);
|
||||
}
|
||||
|
||||
/*
|
||||
* @param {wei hex string} gasPrice
|
||||
* @return {string} szabo gas price with unit [szabo] i.e. 21,423 [szabo]
|
||||
*/
|
||||
function _getSzaboFromWeiDisplay (gasPrice) {
|
||||
gasPrice = new BigNumber(gasPrice);
|
||||
return gasPrice.times(WEI_TO_SZABU_MULTIPLIER).toPrecision(5);
|
||||
}
|
||||
|
||||
/*
|
||||
* @param {wei hex string} value
|
||||
* @return {string} value in WEI nicely formatted
|
||||
*/
|
||||
function _getValueDisplay (value) {
|
||||
value = new BigNumber(value);
|
||||
return value.times(WEI_TO_ETH_MULTIPLIER).toFormat(5);
|
||||
}
|
||||
|
||||
function _getValueDisplayWei (value) {
|
||||
value = new BigNumber(value);
|
||||
return value.toFormat(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* @param {wei hex string} totalValue
|
||||
* @return {string} total value (including fee) with units i.e. 1.32 [eth]
|
||||
*/
|
||||
function _getTotalValueDisplay (totalValue) {
|
||||
totalValue = new BigNumber(totalValue);
|
||||
return totalValue.times(WEI_TO_ETH_MULTIPLIER).toFormat(5);
|
||||
}
|
||||
|
||||
function _getTotalValueDisplayWei (totalValue) {
|
||||
totalValue = new BigNumber(totalValue);
|
||||
return totalValue.toFormat(0);
|
||||
}
|
||||
|
||||
function _getEthmFromWeiDisplay (weiHexString) {
|
||||
const value = new BigNumber(weiHexString);
|
||||
return value.times(WEI_TO_ETH_MULTIPLIER).times(1e7).toFixed(5);
|
||||
}
|
||||
|
||||
function _getTxLink (txHash, chain) {
|
||||
const base = chain === 'morden' || chain === 'testnet' ? BASE_LINK_TX_MORDEN : BASE_LINK_TX_HOMESTEAD;
|
||||
return base + txHash;
|
||||
}
|
||||
|
||||
function _getGasDisplay (gas) {
|
||||
return new BigNumber(gas).times(1e-7).toFormat(4);
|
||||
}
|
||||
79
js/src/views/Signer/components/util/transaction.spec.js
Normal file
79
js/src/views/Signer/components/util/transaction.spec.js
Normal file
@@ -0,0 +1,79 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import BigNumber from 'bignumber.js';
|
||||
import { getShortData, getFee, getTotalValue } from './transaction';
|
||||
|
||||
describe('util/transaction', () => {
|
||||
describe('getEstimatedMiningTime', () => {
|
||||
it('should return estimated mining time', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getShortData', () => {
|
||||
it('should return short data', () => {
|
||||
// given
|
||||
const data = '0xh87dY78';
|
||||
|
||||
// when
|
||||
const res = getShortData(data);
|
||||
|
||||
// then
|
||||
expect(res).to.equal('0xh...');
|
||||
});
|
||||
|
||||
it('should return data as is', () => {
|
||||
// given
|
||||
const data = '0x0';
|
||||
|
||||
// when
|
||||
const shortData = getShortData(data);
|
||||
|
||||
// then
|
||||
expect(shortData).to.equal('0x0');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getFee', () => {
|
||||
it('should return wei BigNumber object equals to gas * gasPrice', () => {
|
||||
// given
|
||||
const gas = '0x76c0'; // 30400
|
||||
const gasPrice = '0x9184e72a000'; // 10000000000000 wei
|
||||
|
||||
// when
|
||||
const fee = getFee(gas, gasPrice);
|
||||
|
||||
// then
|
||||
expect(fee).to.be.an.instanceOf(BigNumber);
|
||||
expect(fee.toString()).to.be.equal('304000000000000000'); // converting to string due to https://github.com/MikeMcl/bignumber.js/issues/11
|
||||
});
|
||||
});
|
||||
|
||||
describe('getTotalValue', () => {
|
||||
it('should return wei BigNumber totalValue equals to value + fee', () => {
|
||||
// given
|
||||
const fee = new BigNumber(304000000000000000); // wei
|
||||
const value = '0x9184e72a'; // 2441406250 wei
|
||||
|
||||
// when
|
||||
const totalValue = getTotalValue(fee, value);
|
||||
|
||||
// then
|
||||
expect(totalValue).to.be.an.instanceOf(BigNumber);
|
||||
expect(totalValue.toString()).to.be.equal('304000002441406250'); // converting to string due to https://github.com/MikeMcl/bignumber.js/issues/11
|
||||
});
|
||||
});
|
||||
});
|
||||
35
js/src/views/Signer/components/util/util.js
Normal file
35
js/src/views/Signer/components/util/util.js
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export function toPromise (fn) {
|
||||
return new Promise((resolve, reject) => {
|
||||
fn((err, res) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(res);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function identity (x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
export function capitalize (str) {
|
||||
return str[0].toUpperCase() + str.slice(1).toLowerCase();
|
||||
}
|
||||
Reference in New Issue
Block a user