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:
Jaco Greeff
2016-10-18 11:52:56 +02:00
committed by Gav Wood
parent 6c7af57529
commit 1e6a2cb378
969 changed files with 57315 additions and 0 deletions

View 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;
}

View 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);
}
}

View File

@@ -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;
}

View File

@@ -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
});
}
}

View 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';

View 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';

View File

@@ -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;
}
}

View 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';

View File

@@ -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;
}
}

View 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';

View 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;
}

View 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);
}
}

View 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';

View File

@@ -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);
});
}
}

View 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';

View File

@@ -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;
}

View File

@@ -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>
);
}
}

View 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';

View File

@@ -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);
});
}
}

View 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 './TransactionFinishedWeb3';

View File

@@ -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;
}

View File

@@ -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>&rArr;</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>&rArr;</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>
);
}
}

View 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 './TransactionMainDetails';

View 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/>.
*/
.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 */
}

View File

@@ -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);
}
}

View 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';

View File

@@ -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;
}

View File

@@ -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 });
}
}

View File

@@ -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;
}

View File

@@ -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);

View 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 './TransactionPendingFormConfirm';

View 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/>.
*/
/* the rejection button itself, once .reject has been pressed */
.rejectButton {
display: block !important;
margin-bottom: 5px;
}
.rejectText {
margin-bottom: 10px;
}

View File

@@ -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
});
}
}

View 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 './TransactionPendingFormReject';

View 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 './TransactionPendingForm';

View File

@@ -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);
});
}
}

View 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 './TransactionPendingWeb3';

View File

@@ -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;
}

View File

@@ -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
});
}
}

View File

@@ -0,0 +1 @@
export default from './TransactionSecondaryDetails';

View 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 });
}
}

View 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';

View 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/';

View 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';

View 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;
}

View 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 () {}

View 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';
}

View 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);
}

View 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
});
});
});

View 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();
}