refactor etherscan.io links (#2896)

* use proper querystring builder

* etherscan.txLink helper

* refactor to etherscan.txLink

* etherscan.addressLink helper

* refactor to etherscan.addressLink

* move txLink & addressLink into common file
This commit is contained in:
Jannis Redmann 2016-10-30 09:37:15 +01:00 committed by Jaco Greeff
parent 222b2b70ea
commit 86c0dbeedc
12 changed files with 44 additions and 90 deletions

View File

@ -125,6 +125,7 @@
"material-ui": "^0.16.1",
"material-ui-chip-input": "^0.8.0",
"moment": "^2.14.1",
"qs": "^6.3.0",
"react": "^15.2.1",
"react-addons-css-transition-group": "^15.2.1",
"react-dom": "^15.2.1",

View File

@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { stringify } from 'qs';
const options = {
method: 'GET',
headers: {
@ -23,19 +25,14 @@ const options = {
export function call (module, action, _params, test) {
const host = test ? 'testnet.etherscan.io' : 'api.etherscan.io';
let params = '';
if (_params) {
Object.keys(_params).map((param) => {
const value = _params[param];
const query = stringify(Object.assign({
module, action
}, _params || {}));
params = `${params}&${param}=${value}`;
});
}
return fetch(`http://${host}/api?module=${module}&action=${action}${params}`, options)
return fetch(`https://${host}/api?${query}`, options)
.then((response) => {
if (response.status !== 200) {
if (!response.ok) {
throw { code: response.status, message: response.statusText }; // eslint-disable-line
}

View File

@ -16,10 +16,13 @@
import { account } from './account';
import { stats } from './stats';
import { txLink, addressLink } from './links';
const etherscan = {
account: account,
stats: stats
stats: stats,
txLink: txLink,
addressLink: addressLink
};
export default etherscan;

View File

@ -14,8 +14,10 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
// 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/';
export const txLink = (hash, isTestnet = false) => {
return `https://${isTestnet ? 'testnet.' : ''}etherscan.io/tx/${hash}`;
};
export const addressLink = (address, isTestnet = false) => {
return `https://${isTestnet ? 'testnet.' : ''}etherscan.io/address/${address}`;
};

View File

@ -19,6 +19,7 @@ import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { LinearProgress } from 'material-ui';
import { txLink } from '../../3rdparty/etherscan/links';
import styles from './txHash.css';
@ -55,7 +56,6 @@ class TxHash extends Component {
render () {
const { hash, isTest } = this.props;
const link = `https://${isTest ? 'testnet.' : ''}etherscan.io/tx/${hash}`;
return (
<div className={ styles.details }>
@ -63,7 +63,7 @@ class TxHash extends Component {
The transaction has been posted to the network with a transaction hash of
</div>
<div className={ styles.hash }>
<a href={ link } target='_blank'>{ hash }</a>
<a href={ txLink(hash, isTest) } target='_blank'>{ hash }</a>
</div>
{ this.renderConfirmations() }
</div>

View File

@ -23,6 +23,7 @@ import { bindActionCreators } from 'redux';
import { fetchBlock, fetchTransaction } from '../../../../redux/providers/blockchainActions';
import { IdentityIcon, IdentityName, MethodDecoding } from '../../../../ui';
import { txLink, addressLink } from '../../../../3rdparty/etherscan/links';
import styles from '../transactions.css';
@ -55,9 +56,7 @@ class Transaction extends Component {
}
render () {
const { block, transaction, isTest } = this.props;
const prefix = `https://${isTest ? 'testnet.' : ''}etherscan.io/`;
const { block, transaction } = this.props;
return (
<tr>
@ -65,9 +64,9 @@ class Transaction extends Component {
<div>{ this.formatBlockTimestamp(block) }</div>
<div>{ this.formatNumber(transaction.blockNumber) }</div>
</td>
{ this.renderAddress(prefix, transaction.from) }
{ this.renderAddress(transaction.from) }
{ this.renderTransaction() }
{ this.renderAddress(prefix, transaction.to) }
{ this.renderAddress(transaction.to) }
<td className={ styles.method }>
{ this.renderMethod() }
</td>
@ -93,15 +92,16 @@ class Transaction extends Component {
renderTransaction () {
const { transaction, isTest } = this.props;
const prefix = `https://${isTest ? 'testnet.' : ''}etherscan.io/`;
const hashLink = `${prefix}tx/${transaction.hash}`;
return (
<td className={ styles.transaction }>
{ this.renderEtherValue() }
<div></div>
<div>
<a href={ hashLink } target='_blank' className={ styles.link }>
<a
className={ styles.link }
href={ txLink(transaction.hash, isTest) }
target='_blank'
>
{ this.formatHash(transaction.hash) }
</a>
</div>
@ -109,10 +109,12 @@ class Transaction extends Component {
);
}
renderAddress (prefix, address) {
renderAddress (address) {
const { isTest } = this.props;
const eslink = address ? (
<a
href={ `${prefix}address/${address}` }
href={ addressLink(address, isTest) }
target='_blank'
className={ styles.link }>
<IdentityName address={ address } shorten />

View File

@ -22,6 +22,7 @@ import { bindActionCreators } from 'redux';
import { fetchBlock, fetchTransaction } from '../../../../redux/providers/blockchainActions';
import { IdentityIcon, IdentityName, Input, InputAddress } from '../../../../ui';
import { txLink } from '../../../../3rdparty/etherscan/links';
import styles from '../../contract.css';
@ -49,7 +50,7 @@ class Event extends Component {
const block = blocks[event.blockNumber.toString()];
const transaction = transactions[event.transactionHash] || {};
const classes = `${styles.event} ${styles[event.state]}`;
const url = `https://${isTest ? 'testnet.' : ''}etherscan.io/tx/${event.transactionHash}`;
const url = txLink(event.transactionHash, isTest);
const keys = Object.keys(event.params).join(', ');
const values = Object.keys(event.params).map((name, index) => {
const param = event.params[name];

View File

@ -16,7 +16,7 @@
import React, { Component, PropTypes } from 'react';
import { getAccountLink } from '../../util/account';
import { addressLink } from '../../../../../3rdparty/etherscan/links';
import styles from './AccountLink.css';
export default class AccountLink extends Component {
@ -57,7 +57,7 @@ export default class AccountLink extends Component {
}
updateLink (address, chain) {
const link = getAccountLink(address, chain);
const link = addressLink(address, chain === 'morden' || chain === 'testnet');
this.setState({
link

View File

@ -120,8 +120,9 @@ export default class TransactionFinished extends Component {
}
renderTxHash () {
const { txHash, chain } = this.props;
if (!txHash) {
const { txHash } = this.props;
const { chain } = this.state;
if (!txHash || !chain) {
return;
}

View File

@ -16,7 +16,7 @@
import React, { Component, PropTypes } from 'react';
import { getTxLink } from '../util/transaction';
import { txLink } from '../../../../3rdparty/etherscan/links';
export default class TxHashLink extends Component {
@ -27,27 +27,12 @@ export default class TxHashLink extends Component {
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;
const { children, txHash, className, chain } = this.props;
return (
<a
href={ link }
href={ txLink(txHash, chain === 'morden' || chain === 'testnet') }
target='_blank'
className={ className }>
{ children || txHash }
@ -55,9 +40,4 @@ export default class TxHashLink extends Component {
);
}
updateLink (txHash, chain) {
const link = getTxLink(txHash, chain);
this.setState({ link });
}
}

View File

@ -1,25 +0,0 @@
// 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

@ -18,7 +18,6 @@ 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
@ -33,8 +32,6 @@ 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) {
@ -111,11 +108,6 @@ function _getEthmFromWeiDisplay (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);
}