All v3 Nodes & Networks (#202)
* Add all v3s nodes, create node libs for etherscan and infura. * Add all network configs for alternatives. * Color and animate nav border on network selection. * Address PR comments. * Persist network selection to local storage. * Modifiy TransactionSucceeded to link to network-specific explorer. * - Reload on Node Change to reset state. Should be refactored in the future so that we are not forcing clients to reload.
This commit is contained in:
parent
ef1c321ada
commit
e80d0a68a9
|
@ -1,13 +1,18 @@
|
|||
import React from 'react';
|
||||
import { ETHTxExplorer } from 'config/data';
|
||||
import type { BlockExplorerConfig } from 'config.data';
|
||||
import translate from 'translations';
|
||||
|
||||
export type TransactionSucceededProps = {
|
||||
txHash: string
|
||||
txHash: string,
|
||||
blockExplorer: BlockExplorerConfig
|
||||
};
|
||||
|
||||
const TransactionSucceeded = ({ txHash }: TransactionSucceededProps) => {
|
||||
const TransactionSucceeded = ({
|
||||
txHash,
|
||||
blockExplorer
|
||||
}: TransactionSucceededProps) => {
|
||||
// const checkTxLink = `https://www.myetherwallet.com?txHash=${txHash}/#check-tx-status`;
|
||||
const txHashLink = ETHTxExplorer(txHash);
|
||||
const txHashLink = blockExplorer.tx(txHash);
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
|
|
@ -39,7 +39,7 @@ const tabs = [
|
|||
}
|
||||
];
|
||||
|
||||
export default class TabsOptions extends Component {
|
||||
export default class Navigation extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
|
@ -49,7 +49,8 @@ export default class TabsOptions extends Component {
|
|||
}
|
||||
|
||||
static propTypes = {
|
||||
location: PropTypes.object
|
||||
location: PropTypes.object,
|
||||
color: PropTypes.string
|
||||
};
|
||||
|
||||
scrollLeft() {}
|
||||
|
@ -57,12 +58,19 @@ export default class TabsOptions extends Component {
|
|||
scrollRight() {}
|
||||
|
||||
render() {
|
||||
const { location } = this.props;
|
||||
const { location, color } = this.props;
|
||||
const borderStyle = {};
|
||||
|
||||
if (color) {
|
||||
borderStyle.borderTopColor = color;
|
||||
}
|
||||
|
||||
return (
|
||||
<nav
|
||||
role="navigation"
|
||||
aria-label="main navigation"
|
||||
className="Navigation"
|
||||
style={borderStyle}
|
||||
>
|
||||
{this.state.showLeftArrow &&
|
||||
<a
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
position: relative;
|
||||
overflow-y: hidden;
|
||||
border-top: .25rem solid $brand-primary;
|
||||
transition: border 300ms ease;
|
||||
|
||||
&-scroll {
|
||||
-ms-overflow-style: -ms-autohiding-scrollbar;
|
||||
|
|
|
@ -7,6 +7,7 @@ import { Dropdown } from 'components/ui';
|
|||
import {
|
||||
languages,
|
||||
NODES,
|
||||
NETWORKS,
|
||||
VERSION,
|
||||
ANNOUNCEMENT_TYPE,
|
||||
ANNOUNCEMENT_MESSAGE
|
||||
|
@ -32,6 +33,7 @@ export default class Header extends Component {
|
|||
const selectedLanguage =
|
||||
languages.find(l => l.sign === languageSelection) || languages[0];
|
||||
const selectedNode = NODES[nodeSelection];
|
||||
const selectedNetwork = NETWORKS[selectedNode.network];
|
||||
|
||||
return (
|
||||
<div className="Header">
|
||||
|
@ -107,7 +109,10 @@ export default class Header extends Component {
|
|||
</section>
|
||||
</section>
|
||||
|
||||
<Navigation location={this.props.location} />
|
||||
<Navigation
|
||||
location={this.props.location}
|
||||
color={selectedNetwork.color}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
[]
|
|
@ -0,0 +1 @@
|
|||
[]
|
|
@ -0,0 +1 @@
|
|||
[]
|
|
@ -1,5 +1,5 @@
|
|||
// @flow
|
||||
import { RPCNode } from 'libs/nodes';
|
||||
import { RPCNode, InfuraNode, EtherscanNode } from 'libs/nodes';
|
||||
|
||||
// Displays in the header
|
||||
export const VERSION = '4.0.0 (Alpha 0.0.2)';
|
||||
|
@ -19,6 +19,7 @@ const etherScan = 'https://etherscan.io';
|
|||
const blockChainInfo = 'https://blockchain.info';
|
||||
const ethPlorer = 'https://ethplorer.io';
|
||||
|
||||
// TODO: Stop exporting these! Everything should use active node config.
|
||||
export const ETHTxExplorer = (txHash: string): string =>
|
||||
`${etherScan}/tx/${txHash}`;
|
||||
export const BTCTxExplorer = (txHash: string): string =>
|
||||
|
@ -148,14 +149,17 @@ export type NetworkContract = {
|
|||
abi: string
|
||||
};
|
||||
|
||||
type BlockExplorerConfig = {
|
||||
name: string,
|
||||
tx: Function,
|
||||
address: Function
|
||||
};
|
||||
|
||||
export type NetworkConfig = {
|
||||
name: string,
|
||||
unit: string,
|
||||
blockExplorer?: {
|
||||
name: string,
|
||||
tx: Function,
|
||||
address: Function
|
||||
},
|
||||
color: string,
|
||||
blockExplorer?: BlockExplorerConfig,
|
||||
tokenExplorer?: {
|
||||
name: string,
|
||||
address: Function
|
||||
|
@ -172,22 +176,92 @@ export type NodeConfig = {
|
|||
estimateGas: ?boolean
|
||||
};
|
||||
|
||||
// Must be a website that follows the ethplorer convention of /tx/[hash] and
|
||||
// address/[address] to generate the correct functions.
|
||||
function makeExplorer(url): BlockExplorerConfig {
|
||||
return {
|
||||
name: url,
|
||||
tx: hash => `${url}/tx/${hash}`,
|
||||
address: address => `${url}/address/${address}`
|
||||
};
|
||||
}
|
||||
|
||||
export const NETWORKS: { [key: string]: NetworkConfig } = {
|
||||
ETH: {
|
||||
name: 'ETH',
|
||||
unit: 'ETH',
|
||||
chainId: 1,
|
||||
blockExplorer: {
|
||||
name: etherScan,
|
||||
tx: ETHTxExplorer,
|
||||
address: ETHAddressExplorer
|
||||
},
|
||||
color: '#0e97c0',
|
||||
blockExplorer: makeExplorer('https://etherscan.io'),
|
||||
tokenExplorer: {
|
||||
name: ethPlorer,
|
||||
address: ETHTokenExplorer
|
||||
},
|
||||
tokens: require('./tokens/eth').default,
|
||||
tokens: require('./tokens/eth.json'),
|
||||
contracts: require('./contracts/eth.json')
|
||||
},
|
||||
ETC: {
|
||||
name: 'ETC',
|
||||
unit: 'ETC',
|
||||
chainId: 61,
|
||||
color: '#669073',
|
||||
blockExplorer: makeExplorer('https://gastracker.io'),
|
||||
tokens: require('./tokens/etc.json'),
|
||||
contracts: require('./contracts/etc.json')
|
||||
},
|
||||
Ropsten: {
|
||||
name: 'Ropsten',
|
||||
unit: 'ETH',
|
||||
chainId: 3,
|
||||
color: '#adc101',
|
||||
blockExplorer: makeExplorer('https://ropsten.etherscan.io'),
|
||||
tokens: require('./tokens/ropsten.json'),
|
||||
contracts: require('./contracts/ropsten.json')
|
||||
},
|
||||
Kovan: {
|
||||
name: 'Kovan',
|
||||
unit: 'ETH',
|
||||
chainId: 42,
|
||||
color: '#adc101',
|
||||
blockExplorer: makeExplorer('https://kovan.etherscan.io'),
|
||||
tokens: require('./tokens/ropsten.json'),
|
||||
contracts: require('./contracts/ropsten.json')
|
||||
},
|
||||
Rinkeby: {
|
||||
name: 'Rinkeby',
|
||||
unit: 'ETH',
|
||||
chainId: 4,
|
||||
color: '#adc101',
|
||||
blockExplorer: makeExplorer('https://rinkeby.etherscan.io'),
|
||||
tokens: require('./tokens/rinkeby.json'),
|
||||
contracts: require('./contracts/rinkeby.json')
|
||||
},
|
||||
RSK: {
|
||||
name: 'RSK',
|
||||
unit: 'RSK',
|
||||
chainId: 31,
|
||||
color: '#ff794f',
|
||||
blockExplorer: makeExplorer('https://explorer.rsk.co'),
|
||||
tokens: require('./tokens/rsk.json'),
|
||||
contracts: require('./contracts/rsk.json')
|
||||
},
|
||||
EXP: {
|
||||
name: 'EXP',
|
||||
unit: 'EXP',
|
||||
chainId: 2,
|
||||
color: '#673ab7',
|
||||
blockExplorer: makeExplorer('http://www.gander.tech'),
|
||||
tokens: require('./tokens/exp.json'),
|
||||
contracts: require('./contracts/exp.json')
|
||||
},
|
||||
UBQ: {
|
||||
name: 'UBQ',
|
||||
unit: 'UBQ',
|
||||
chainId: 8,
|
||||
color: '#b37aff',
|
||||
blockExplorer: makeExplorer('https://ubiqscan.io/en'),
|
||||
tokens: require('./tokens/ubq.json'),
|
||||
contracts: require('./contracts/ubq.json')
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -197,5 +271,71 @@ export const NODES: { [key: string]: NodeConfig } = {
|
|||
lib: new RPCNode('https://api.myetherapi.com/eth'),
|
||||
service: 'MyEtherWallet',
|
||||
estimateGas: true
|
||||
},
|
||||
eth_ethscan: {
|
||||
network: 'ETH',
|
||||
service: 'Etherscan.io',
|
||||
lib: new EtherscanNode('https://api.etherscan.io/api'),
|
||||
estimateGas: false
|
||||
},
|
||||
eth_infura: {
|
||||
network: 'ETH',
|
||||
service: 'infura.io',
|
||||
lib: new InfuraNode('https://mainnet.infura.io/mew'),
|
||||
estimateGas: false
|
||||
},
|
||||
etc_epool: {
|
||||
network: 'ETC',
|
||||
service: 'Epool.io',
|
||||
lib: new RPCNode('https://mewapi.epool.io'),
|
||||
estimateGas: false
|
||||
},
|
||||
rop_mew: {
|
||||
network: 'Ropsten',
|
||||
service: 'MyEtherWallet',
|
||||
lib: new RPCNode('https://api.myetherapi.com/rop'),
|
||||
estimateGas: false
|
||||
},
|
||||
rop_infura: {
|
||||
network: 'Ropsten',
|
||||
service: 'infura.io',
|
||||
lib: new InfuraNode('https://ropsten.infura.io/mew'),
|
||||
estimateGas: false
|
||||
},
|
||||
kov_ethscan: {
|
||||
network: 'Kovan',
|
||||
service: 'Etherscan.io',
|
||||
lib: new EtherscanNode('https://kovan.etherscan.io/api'),
|
||||
estimateGas: false
|
||||
},
|
||||
rin_ethscan: {
|
||||
network: 'Rinkeby',
|
||||
service: 'Etherscan.io',
|
||||
lib: new EtherscanNode('https://rinkeby.etherscan.io/api'),
|
||||
estimateGas: false
|
||||
},
|
||||
rin_infura: {
|
||||
network: 'Rinkeby',
|
||||
service: 'infura.io',
|
||||
lib: new InfuraNode('https://rinkeby.infura.io/mew'),
|
||||
estimateGas: false
|
||||
},
|
||||
rsk: {
|
||||
network: 'RSK',
|
||||
service: 'GK2.sk',
|
||||
lib: new RPCNode('https://rsk-test.gk2.sk/'),
|
||||
estimateGas: true
|
||||
},
|
||||
exp: {
|
||||
network: 'EXP',
|
||||
service: 'Expanse.tech',
|
||||
lib: new RPCNode('https://node.expanse.tech/'),
|
||||
estimateGas: true
|
||||
},
|
||||
ubq: {
|
||||
network: 'UBQ',
|
||||
service: 'ubiqscan.io',
|
||||
lib: new RPCNode('https://pyrus2.ubiqscan.io'),
|
||||
estimateGas: true
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
[
|
||||
{
|
||||
"address": "0x085fb4f24031eaedbc2b611aa528f22343eb52db",
|
||||
"symbol": "BEC",
|
||||
"decimal": 8,
|
||||
"type": "default"
|
||||
}
|
||||
]
|
|
@ -1,439 +0,0 @@
|
|||
export default [
|
||||
{
|
||||
address: '0xAf30D2a7E90d7DC361c8C4585e9BB7D2F6f15bc7',
|
||||
symbol: '1ST',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0x422866a8F0b032c5cf1DfBDEf31A20F4509562b0',
|
||||
symbol: 'ADST',
|
||||
decimal: 0
|
||||
},
|
||||
{
|
||||
address: '0xD0D6D6C5Fe4a677D343cC433536BB717bAe167dD',
|
||||
symbol: 'ADT',
|
||||
decimal: 9
|
||||
},
|
||||
{
|
||||
address: '0x4470bb87d77b963a013db939be332f927f2b992e',
|
||||
symbol: 'ADX',
|
||||
decimal: 4
|
||||
},
|
||||
{
|
||||
address: '0x960b236A07cf122663c4303350609A66A7B288C0',
|
||||
symbol: 'ANT',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0xAc709FcB44a43c35F0DA4e3163b117A17F3770f5',
|
||||
symbol: 'ARC',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0x0D8775F648430679A709E98d2b0Cb6250d2887EF',
|
||||
symbol: 'BAT',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0x74C1E4b8caE59269ec1D85D3D4F324396048F4ac',
|
||||
symbol: 'BeerCoin 🍺 ',
|
||||
decimal: 0
|
||||
},
|
||||
{
|
||||
address: '0x1e797Ce986C3CFF4472F7D38d5C4aba55DfEFE40',
|
||||
symbol: 'BCDN',
|
||||
decimal: 15
|
||||
},
|
||||
{
|
||||
address: '0xdD6Bf56CA2ada24c683FAC50E37783e55B57AF9F',
|
||||
symbol: 'BNC',
|
||||
decimal: 12
|
||||
},
|
||||
{
|
||||
address: '0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C',
|
||||
symbol: 'BNT',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0x5af2be193a6abca9c8817001f45744777db30756',
|
||||
symbol: 'BQX',
|
||||
decimal: 8
|
||||
},
|
||||
{
|
||||
address: '0x12FEF5e57bF45873Cd9B62E9DBd7BFb99e32D73e',
|
||||
symbol: 'CFI',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0xAef38fBFBF932D1AeF3B808Bc8fBd8Cd8E1f8BC5',
|
||||
symbol: 'CRB',
|
||||
decimal: 8
|
||||
},
|
||||
{
|
||||
address: '0xbf4cfd7d1edeeea5f6600827411b41a21eb08abd',
|
||||
symbol: 'CTL',
|
||||
decimal: 2
|
||||
},
|
||||
{
|
||||
address: '0xE4c94d45f7Aef7018a5D66f44aF780ec6023378e',
|
||||
symbol: 'CryptoCarbon',
|
||||
decimal: 6
|
||||
},
|
||||
{
|
||||
address: '0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413',
|
||||
symbol: 'DAO',
|
||||
decimal: 16
|
||||
},
|
||||
{
|
||||
address: '0x5c40eF6f527f4FbA68368774E6130cE6515123f2',
|
||||
symbol: 'DAO_extraBalance',
|
||||
decimal: 0
|
||||
},
|
||||
{
|
||||
address: '0xcC4eF9EEAF656aC1a2Ab886743E98e97E090ed38',
|
||||
symbol: 'DDF',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0xE0B7927c4aF23765Cb51314A0E0521A9645F0E2A',
|
||||
symbol: 'DGD',
|
||||
decimal: 9
|
||||
},
|
||||
{
|
||||
address: '0x55b9a11c2e8351b4Ffc7b11561148bfaC9977855',
|
||||
symbol: 'DGX 1.0',
|
||||
decimal: 9
|
||||
},
|
||||
{
|
||||
address: '0x2e071D2966Aa7D8dECB1005885bA1977D6038A65',
|
||||
symbol: 'DICE',
|
||||
decimal: 16
|
||||
},
|
||||
{
|
||||
address: '0x621d78f2ef2fd937bfca696cabaf9a779f59b3ed',
|
||||
symbol: 'DRP',
|
||||
decimal: 2
|
||||
},
|
||||
{
|
||||
address: '0x08711D3B02C8758F2FB3ab4e80228418a7F8e39c',
|
||||
symbol: 'EDG',
|
||||
decimal: 0
|
||||
},
|
||||
{
|
||||
address: '0xB802b24E0637c2B87D2E8b7784C055BBE921011a',
|
||||
symbol: 'EMV',
|
||||
decimal: 2
|
||||
},
|
||||
{
|
||||
address: '0x190e569bE071F40c704e15825F285481CB74B6cC',
|
||||
symbol: 'FAM',
|
||||
decimal: 12
|
||||
},
|
||||
{
|
||||
address: '0xBbB1BD2D741F05E144E6C4517676a15554fD4B8D',
|
||||
symbol: 'FUN',
|
||||
decimal: 8
|
||||
},
|
||||
{
|
||||
address: '0x6810e776880C02933D47DB1b9fc05908e5386b96',
|
||||
symbol: 'GNO',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0xa74476443119A942dE498590Fe1f2454d7D4aC0d',
|
||||
symbol: 'GNT',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0xf7B098298f7C69Fc14610bf71d5e02c60792894C',
|
||||
symbol: 'GUP',
|
||||
decimal: 3
|
||||
},
|
||||
{
|
||||
address: '0x1D921EeD55a6a9ccaA9C79B1A4f7B25556e44365',
|
||||
symbol: 'GT',
|
||||
decimal: 0
|
||||
},
|
||||
{
|
||||
address: '0x14F37B574242D366558dB61f3335289a5035c506',
|
||||
symbol: 'HKG',
|
||||
decimal: 3
|
||||
},
|
||||
{
|
||||
address: '0xcbCC0F036ED4788F63FC0fEE32873d6A7487b908',
|
||||
symbol: 'HMQ',
|
||||
decimal: 8
|
||||
},
|
||||
{
|
||||
address: '0x888666CA69E0f178DED6D75b5726Cee99A87D698',
|
||||
symbol: 'ICN',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0xc1E6C6C681B286Fb503B36a9dD6c1dbFF85E73CF',
|
||||
symbol: 'JET',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0x773450335eD4ec3DB45aF74f34F2c85348645D39',
|
||||
symbol: 'JetCoins',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0xfa05A73FfE78ef8f1a739473e462c54bae6567D9',
|
||||
symbol: 'LUN',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0x93E682107d1E9defB0b5ee701C71707a4B2E46Bc',
|
||||
symbol: 'MCAP',
|
||||
decimal: 8
|
||||
},
|
||||
{
|
||||
address: '0xB63B606Ac810a52cCa15e44bB630fd42D8d1d83d',
|
||||
symbol: 'MCO',
|
||||
decimal: 8
|
||||
},
|
||||
{
|
||||
address: '0x40395044ac3c0c57051906da938b54bd6557f212',
|
||||
symbol: 'MGO',
|
||||
decimal: 8
|
||||
},
|
||||
{
|
||||
address: '0xd0b171Eb0b0F2CbD35cCD97cDC5EDC3ffe4871aa',
|
||||
symbol: 'MDA',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0xe23cd160761f63FC3a1cF78Aa034b6cdF97d3E0C',
|
||||
symbol: 'MIT',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0xC66eA802717bFb9833400264Dd12c2bCeAa34a6d',
|
||||
symbol: 'MKR',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0xBEB9eF514a379B997e0798FDcC901Ee474B6D9A1',
|
||||
symbol: 'MLN',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0x1a95B271B0535D15fa49932Daba31BA612b52946',
|
||||
symbol: 'MNE',
|
||||
decimal: 8
|
||||
},
|
||||
{
|
||||
address: '0x68AA3F232dA9bdC2343465545794ef3eEa5209BD',
|
||||
symbol: 'MSP',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0xf433089366899d83a9f26a773d59ec7ecf30355e',
|
||||
symbol: 'MTL',
|
||||
decimal: 8
|
||||
},
|
||||
{
|
||||
address: '0xa645264C5603E96c3b0B078cdab68733794B0A71',
|
||||
symbol: 'MYST',
|
||||
decimal: 8
|
||||
},
|
||||
{
|
||||
address: '0xcfb98637bcae43C13323EAa1731cED2B716962fD',
|
||||
symbol: 'NET',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0x1776e1F26f98b1A5dF9cD347953a26dd3Cb46671',
|
||||
symbol: 'NMR',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0x45e42D659D9f9466cD5DF622506033145a9b89Bc',
|
||||
symbol: 'NxC',
|
||||
decimal: 3
|
||||
},
|
||||
{
|
||||
address: '0x701C244b988a513c945973dEFA05de933b23Fe1D',
|
||||
symbol: 'OAX',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07',
|
||||
symbol: 'OMG',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0xB97048628DB6B661D4C2aA833e95Dbe1A905B280',
|
||||
symbol: 'PAY',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0x8Ae4BF2C33a8e667de34B54938B0ccD03Eb8CC06',
|
||||
symbol: 'PTOY',
|
||||
decimal: 8
|
||||
},
|
||||
{
|
||||
address: '0xD8912C10681D8B21Fd3742244f44658dBA12264E',
|
||||
symbol: 'PLU',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0x671AbBe5CE652491985342e85428EB1b07bC6c64',
|
||||
symbol: 'QAU',
|
||||
decimal: 8
|
||||
},
|
||||
{
|
||||
address: '0x697beac28B09E122C4332D163985e8a73121b97F',
|
||||
symbol: 'QRL',
|
||||
decimal: 8
|
||||
},
|
||||
{
|
||||
address: '0x48c80F1f4D53D5951e5D5438B54Cba84f29F32a5',
|
||||
symbol: 'REP',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0x607F4C5BB672230e8672085532f7e901544a7375',
|
||||
symbol: 'RLC',
|
||||
decimal: 9
|
||||
},
|
||||
{
|
||||
address: '0xcCeD5B8288086BE8c38E23567e684C3740be4D48',
|
||||
symbol: 'RLT',
|
||||
decimal: 10
|
||||
},
|
||||
{
|
||||
address: '0x4993CB95c7443bdC06155c5f5688Be9D8f6999a5',
|
||||
symbol: 'ROUND',
|
||||
decimal: 18
|
||||
},
|
||||
|
||||
{
|
||||
address: '0xa1ccc166faf0e998b3e33225a1a0301b1c86119d',
|
||||
symbol: 'SGEL',
|
||||
decimal: 18
|
||||
},
|
||||
|
||||
{
|
||||
address: '0xd248B0D48E44aaF9c49aea0312be7E13a6dc1468',
|
||||
symbol: 'SGT',
|
||||
decimal: 1
|
||||
},
|
||||
{
|
||||
address: '0xef2e9966eb61bb494e5375d5df8d67b7db8a780d',
|
||||
symbol: 'SHIT',
|
||||
decimal: 0
|
||||
},
|
||||
{
|
||||
address: '0x2bDC0D42996017fCe214b21607a515DA41A9E0C5',
|
||||
symbol: 'SKIN',
|
||||
decimal: 6
|
||||
},
|
||||
{
|
||||
address: '0x4994e81897a920c0FEA235eb8CEdEEd3c6fFF697',
|
||||
symbol: 'SKO1',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0xaeC2E87E0A235266D9C5ADc9DEb4b2E29b54D009',
|
||||
symbol: 'SNGLS',
|
||||
decimal: 0
|
||||
},
|
||||
{
|
||||
address: '0x983f6d60db79ea8ca4eb9968c6aff8cfa04b3c63',
|
||||
symbol: 'SNM',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0x744d70fdbe2ba4cf95131626614a1763df805b9e',
|
||||
symbol: 'SNT',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0x1dCE4Fa03639B7F0C38ee5bB6065045EdCf9819a',
|
||||
symbol: 'SRC',
|
||||
decimal: 8
|
||||
},
|
||||
{
|
||||
address: '0xb64ef51c888972c908cfacf59b47c1afbc0ab8ac',
|
||||
symbol: 'STORJ',
|
||||
decimal: 8
|
||||
},
|
||||
{
|
||||
address: '0xB9e7F8568e08d5659f5D29C4997173d84CdF2607',
|
||||
symbol: 'SWT',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0xf4134146af2d511dd5ea8cdb1c4ac88c57d60404',
|
||||
symbol: 'SNC',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0xE7775A6e9Bcf904eb39DA2b68c5efb4F9360e08C',
|
||||
symbol: 'TaaS',
|
||||
decimal: 6
|
||||
},
|
||||
{
|
||||
address: '0xa7f976C360ebBeD4465c2855684D1AAE5271eFa9',
|
||||
symbol: 'TFL',
|
||||
decimal: 8
|
||||
},
|
||||
{
|
||||
address: '0x6531f133e6DeeBe7F2dcE5A0441aA7ef330B4e53',
|
||||
symbol: 'TIME',
|
||||
decimal: 8
|
||||
},
|
||||
{
|
||||
address: '0xaAAf91D9b90dF800Df4F55c205fd6989c977E73a',
|
||||
symbol: 'TKN',
|
||||
decimal: 8
|
||||
},
|
||||
{
|
||||
address: '0xCb94be6f13A1182E4A4B6140cb7bf2025d28e41B',
|
||||
symbol: 'TRST',
|
||||
decimal: 6
|
||||
},
|
||||
{
|
||||
address: '0x89205A3A3b2A69De6Dbf7f01ED13B2108B2c43e7',
|
||||
symbol: 'Unicorn 🦄 ',
|
||||
decimal: 0
|
||||
},
|
||||
{
|
||||
address: '0x5c543e7AE0A1104f78406C340E9C64FD9fCE5170',
|
||||
symbol: 'VSL',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0x82665764ea0b58157E1e5E9bab32F68c76Ec0CdF',
|
||||
symbol: 'VSM',
|
||||
decimal: 0
|
||||
},
|
||||
{
|
||||
address: '0x8f3470A7388c05eE4e7AF3d01D8C722b0FF52374',
|
||||
symbol: 'VERI',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0xeDBaF3c5100302dCddA53269322f3730b1F0416d',
|
||||
symbol: 'VRS',
|
||||
decimal: 5
|
||||
},
|
||||
{
|
||||
address: '0x667088b212ce3d06a1b553a7221E1fD19000d9aF',
|
||||
symbol: 'WINGS',
|
||||
decimal: 18
|
||||
},
|
||||
{
|
||||
address: '0x4DF812F6064def1e5e029f1ca858777CC98D2D81',
|
||||
symbol: 'XAUR',
|
||||
decimal: 8
|
||||
},
|
||||
{
|
||||
address: '0xb110ec7b1dcb8fab8dedbf28f53bc63ea5bedd84',
|
||||
symbol: 'XID',
|
||||
decimal: 8
|
||||
}
|
||||
];
|
|
@ -0,0 +1,437 @@
|
|||
[
|
||||
{
|
||||
"address": "0xAf30D2a7E90d7DC361c8C4585e9BB7D2F6f15bc7",
|
||||
"symbol": "1ST",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0x422866a8F0b032c5cf1DfBDEf31A20F4509562b0",
|
||||
"symbol": "ADST",
|
||||
"decimal": 0
|
||||
},
|
||||
{
|
||||
"address": "0xD0D6D6C5Fe4a677D343cC433536BB717bAe167dD",
|
||||
"symbol": "ADT",
|
||||
"decimal": 9
|
||||
},
|
||||
{
|
||||
"address": "0x4470bb87d77b963a013db939be332f927f2b992e",
|
||||
"symbol": "ADX",
|
||||
"decimal": 4
|
||||
},
|
||||
{
|
||||
"address": "0x960b236A07cf122663c4303350609A66A7B288C0",
|
||||
"symbol": "ANT",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0xAc709FcB44a43c35F0DA4e3163b117A17F3770f5",
|
||||
"symbol": "ARC",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0x0D8775F648430679A709E98d2b0Cb6250d2887EF",
|
||||
"symbol": "BAT",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0x74C1E4b8caE59269ec1D85D3D4F324396048F4ac",
|
||||
"symbol": "BeerCoin 🍺 ",
|
||||
"decimal": 0
|
||||
},
|
||||
{
|
||||
"address": "0x1e797Ce986C3CFF4472F7D38d5C4aba55DfEFE40",
|
||||
"symbol": "BCDN",
|
||||
"decimal": 15
|
||||
},
|
||||
{
|
||||
"address": "0xdD6Bf56CA2ada24c683FAC50E37783e55B57AF9F",
|
||||
"symbol": "BNC",
|
||||
"decimal": 12
|
||||
},
|
||||
{
|
||||
"address": "0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C",
|
||||
"symbol": "BNT",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0x5af2be193a6abca9c8817001f45744777db30756",
|
||||
"symbol": "BQX",
|
||||
"decimal": 8
|
||||
},
|
||||
{
|
||||
"address": "0x12FEF5e57bF45873Cd9B62E9DBd7BFb99e32D73e",
|
||||
"symbol": "CFI",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0xAef38fBFBF932D1AeF3B808Bc8fBd8Cd8E1f8BC5",
|
||||
"symbol": "CRB",
|
||||
"decimal": 8
|
||||
},
|
||||
{
|
||||
"address": "0xbf4cfd7d1edeeea5f6600827411b41a21eb08abd",
|
||||
"symbol": "CTL",
|
||||
"decimal": 2
|
||||
},
|
||||
{
|
||||
"address": "0xE4c94d45f7Aef7018a5D66f44aF780ec6023378e",
|
||||
"symbol": "CryptoCarbon",
|
||||
"decimal": 6
|
||||
},
|
||||
{
|
||||
"address": "0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413",
|
||||
"symbol": "DAO",
|
||||
"decimal": 16
|
||||
},
|
||||
{
|
||||
"address": "0x5c40eF6f527f4FbA68368774E6130cE6515123f2",
|
||||
"symbol": "DAO_extraBalance",
|
||||
"decimal": 0
|
||||
},
|
||||
{
|
||||
"address": "0xcC4eF9EEAF656aC1a2Ab886743E98e97E090ed38",
|
||||
"symbol": "DDF",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0xE0B7927c4aF23765Cb51314A0E0521A9645F0E2A",
|
||||
"symbol": "DGD",
|
||||
"decimal": 9
|
||||
},
|
||||
{
|
||||
"address": "0x55b9a11c2e8351b4Ffc7b11561148bfaC9977855",
|
||||
"symbol": "DGX 1.0",
|
||||
"decimal": 9
|
||||
},
|
||||
{
|
||||
"address": "0x2e071D2966Aa7D8dECB1005885bA1977D6038A65",
|
||||
"symbol": "DICE",
|
||||
"decimal": 16
|
||||
},
|
||||
{
|
||||
"address": "0x621d78f2ef2fd937bfca696cabaf9a779f59b3ed",
|
||||
"symbol": "DRP",
|
||||
"decimal": 2
|
||||
},
|
||||
{
|
||||
"address": "0x08711D3B02C8758F2FB3ab4e80228418a7F8e39c",
|
||||
"symbol": "EDG",
|
||||
"decimal": 0
|
||||
},
|
||||
{
|
||||
"address": "0xB802b24E0637c2B87D2E8b7784C055BBE921011a",
|
||||
"symbol": "EMV",
|
||||
"decimal": 2
|
||||
},
|
||||
{
|
||||
"address": "0x190e569bE071F40c704e15825F285481CB74B6cC",
|
||||
"symbol": "FAM",
|
||||
"decimal": 12
|
||||
},
|
||||
{
|
||||
"address": "0xBbB1BD2D741F05E144E6C4517676a15554fD4B8D",
|
||||
"symbol": "FUN",
|
||||
"decimal": 8
|
||||
},
|
||||
{
|
||||
"address": "0x6810e776880C02933D47DB1b9fc05908e5386b96",
|
||||
"symbol": "GNO",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0xa74476443119A942dE498590Fe1f2454d7D4aC0d",
|
||||
"symbol": "GNT",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0xf7B098298f7C69Fc14610bf71d5e02c60792894C",
|
||||
"symbol": "GUP",
|
||||
"decimal": 3
|
||||
},
|
||||
{
|
||||
"address": "0x1D921EeD55a6a9ccaA9C79B1A4f7B25556e44365",
|
||||
"symbol": "GT",
|
||||
"decimal": 0
|
||||
},
|
||||
{
|
||||
"address": "0x14F37B574242D366558dB61f3335289a5035c506",
|
||||
"symbol": "HKG",
|
||||
"decimal": 3
|
||||
},
|
||||
{
|
||||
"address": "0xcbCC0F036ED4788F63FC0fEE32873d6A7487b908",
|
||||
"symbol": "HMQ",
|
||||
"decimal": 8
|
||||
},
|
||||
{
|
||||
"address": "0x888666CA69E0f178DED6D75b5726Cee99A87D698",
|
||||
"symbol": "ICN",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0xc1E6C6C681B286Fb503B36a9dD6c1dbFF85E73CF",
|
||||
"symbol": "JET",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0x773450335eD4ec3DB45aF74f34F2c85348645D39",
|
||||
"symbol": "JetCoins",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0xfa05A73FfE78ef8f1a739473e462c54bae6567D9",
|
||||
"symbol": "LUN",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0x93E682107d1E9defB0b5ee701C71707a4B2E46Bc",
|
||||
"symbol": "MCAP",
|
||||
"decimal": 8
|
||||
},
|
||||
{
|
||||
"address": "0xB63B606Ac810a52cCa15e44bB630fd42D8d1d83d",
|
||||
"symbol": "MCO",
|
||||
"decimal": 8
|
||||
},
|
||||
{
|
||||
"address": "0x40395044ac3c0c57051906da938b54bd6557f212",
|
||||
"symbol": "MGO",
|
||||
"decimal": 8
|
||||
},
|
||||
{
|
||||
"address": "0xd0b171Eb0b0F2CbD35cCD97cDC5EDC3ffe4871aa",
|
||||
"symbol": "MDA",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0xe23cd160761f63FC3a1cF78Aa034b6cdF97d3E0C",
|
||||
"symbol": "MIT",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0xC66eA802717bFb9833400264Dd12c2bCeAa34a6d",
|
||||
"symbol": "MKR",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0xBEB9eF514a379B997e0798FDcC901Ee474B6D9A1",
|
||||
"symbol": "MLN",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0x1a95B271B0535D15fa49932Daba31BA612b52946",
|
||||
"symbol": "MNE",
|
||||
"decimal": 8
|
||||
},
|
||||
{
|
||||
"address": "0x68AA3F232dA9bdC2343465545794ef3eEa5209BD",
|
||||
"symbol": "MSP",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0xf433089366899d83a9f26a773d59ec7ecf30355e",
|
||||
"symbol": "MTL",
|
||||
"decimal": 8
|
||||
},
|
||||
{
|
||||
"address": "0xa645264C5603E96c3b0B078cdab68733794B0A71",
|
||||
"symbol": "MYST",
|
||||
"decimal": 8
|
||||
},
|
||||
{
|
||||
"address": "0xcfb98637bcae43C13323EAa1731cED2B716962fD",
|
||||
"symbol": "NET",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0x1776e1F26f98b1A5dF9cD347953a26dd3Cb46671",
|
||||
"symbol": "NMR",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0x45e42D659D9f9466cD5DF622506033145a9b89Bc",
|
||||
"symbol": "NxC",
|
||||
"decimal": 3
|
||||
},
|
||||
{
|
||||
"address": "0x701C244b988a513c945973dEFA05de933b23Fe1D",
|
||||
"symbol": "OAX",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0xd26114cd6EE289AccF82350c8d8487fedB8A0C07",
|
||||
"symbol": "OMG",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0xB97048628DB6B661D4C2aA833e95Dbe1A905B280",
|
||||
"symbol": "PAY",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0x8Ae4BF2C33a8e667de34B54938B0ccD03Eb8CC06",
|
||||
"symbol": "PTOY",
|
||||
"decimal": 8
|
||||
},
|
||||
{
|
||||
"address": "0xD8912C10681D8B21Fd3742244f44658dBA12264E",
|
||||
"symbol": "PLU",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0x671AbBe5CE652491985342e85428EB1b07bC6c64",
|
||||
"symbol": "QAU",
|
||||
"decimal": 8
|
||||
},
|
||||
{
|
||||
"address": "0x697beac28B09E122C4332D163985e8a73121b97F",
|
||||
"symbol": "QRL",
|
||||
"decimal": 8
|
||||
},
|
||||
{
|
||||
"address": "0x48c80F1f4D53D5951e5D5438B54Cba84f29F32a5",
|
||||
"symbol": "REP",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0x607F4C5BB672230e8672085532f7e901544a7375",
|
||||
"symbol": "RLC",
|
||||
"decimal": 9
|
||||
},
|
||||
{
|
||||
"address": "0xcCeD5B8288086BE8c38E23567e684C3740be4D48",
|
||||
"symbol": "RLT",
|
||||
"decimal": 10
|
||||
},
|
||||
{
|
||||
"address": "0x4993CB95c7443bdC06155c5f5688Be9D8f6999a5",
|
||||
"symbol": "ROUND",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0xa1ccc166faf0e998b3e33225a1a0301b1c86119d",
|
||||
"symbol": "SGEL",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0xd248B0D48E44aaF9c49aea0312be7E13a6dc1468",
|
||||
"symbol": "SGT",
|
||||
"decimal": 1
|
||||
},
|
||||
{
|
||||
"address": "0xef2e9966eb61bb494e5375d5df8d67b7db8a780d",
|
||||
"symbol": "SHIT",
|
||||
"decimal": 0
|
||||
},
|
||||
{
|
||||
"address": "0x2bDC0D42996017fCe214b21607a515DA41A9E0C5",
|
||||
"symbol": "SKIN",
|
||||
"decimal": 6
|
||||
},
|
||||
{
|
||||
"address": "0x4994e81897a920c0FEA235eb8CEdEEd3c6fFF697",
|
||||
"symbol": "SKO1",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0xaeC2E87E0A235266D9C5ADc9DEb4b2E29b54D009",
|
||||
"symbol": "SNGLS",
|
||||
"decimal": 0
|
||||
},
|
||||
{
|
||||
"address": "0x983f6d60db79ea8ca4eb9968c6aff8cfa04b3c63",
|
||||
"symbol": "SNM",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0x744d70fdbe2ba4cf95131626614a1763df805b9e",
|
||||
"symbol": "SNT",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0x1dCE4Fa03639B7F0C38ee5bB6065045EdCf9819a",
|
||||
"symbol": "SRC",
|
||||
"decimal": 8
|
||||
},
|
||||
{
|
||||
"address": "0xb64ef51c888972c908cfacf59b47c1afbc0ab8ac",
|
||||
"symbol": "STORJ",
|
||||
"decimal": 8
|
||||
},
|
||||
{
|
||||
"address": "0xB9e7F8568e08d5659f5D29C4997173d84CdF2607",
|
||||
"symbol": "SWT",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0xf4134146af2d511dd5ea8cdb1c4ac88c57d60404",
|
||||
"symbol": "SNC",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0xE7775A6e9Bcf904eb39DA2b68c5efb4F9360e08C",
|
||||
"symbol": "TaaS",
|
||||
"decimal": 6
|
||||
},
|
||||
{
|
||||
"address": "0xa7f976C360ebBeD4465c2855684D1AAE5271eFa9",
|
||||
"symbol": "TFL",
|
||||
"decimal": 8
|
||||
},
|
||||
{
|
||||
"address": "0x6531f133e6DeeBe7F2dcE5A0441aA7ef330B4e53",
|
||||
"symbol": "TIME",
|
||||
"decimal": 8
|
||||
},
|
||||
{
|
||||
"address": "0xaAAf91D9b90dF800Df4F55c205fd6989c977E73a",
|
||||
"symbol": "TKN",
|
||||
"decimal": 8
|
||||
},
|
||||
{
|
||||
"address": "0xCb94be6f13A1182E4A4B6140cb7bf2025d28e41B",
|
||||
"symbol": "TRST",
|
||||
"decimal": 6
|
||||
},
|
||||
{
|
||||
"address": "0x89205A3A3b2A69De6Dbf7f01ED13B2108B2c43e7",
|
||||
"symbol": "Unicorn 🦄 ",
|
||||
"decimal": 0
|
||||
},
|
||||
{
|
||||
"address": "0x5c543e7AE0A1104f78406C340E9C64FD9fCE5170",
|
||||
"symbol": "VSL",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0x82665764ea0b58157E1e5E9bab32F68c76Ec0CdF",
|
||||
"symbol": "VSM",
|
||||
"decimal": 0
|
||||
},
|
||||
{
|
||||
"address": "0x8f3470A7388c05eE4e7AF3d01D8C722b0FF52374",
|
||||
"symbol": "VERI",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0xeDBaF3c5100302dCddA53269322f3730b1F0416d",
|
||||
"symbol": "VRS",
|
||||
"decimal": 5
|
||||
},
|
||||
{
|
||||
"address": "0x667088b212ce3d06a1b553a7221E1fD19000d9aF",
|
||||
"symbol": "WINGS",
|
||||
"decimal": 18
|
||||
},
|
||||
{
|
||||
"address": "0x4DF812F6064def1e5e029f1ca858777CC98D2D81",
|
||||
"symbol": "XAUR",
|
||||
"decimal": 8
|
||||
},
|
||||
{
|
||||
"address": "0xb110ec7b1dcb8fab8dedbf28f53bc63ea5bedd84",
|
||||
"symbol": "XID",
|
||||
"decimal": 8
|
||||
}
|
||||
]
|
|
@ -0,0 +1 @@
|
|||
[]
|
|
@ -0,0 +1,14 @@
|
|||
[
|
||||
{
|
||||
"address": "0x3C67f7D4decF7795225f51b54134F81137385f83",
|
||||
"symbol": "GUP",
|
||||
"decimal": 3,
|
||||
"type": "default"
|
||||
},
|
||||
{
|
||||
"address": "0x8667559254241ddeD4d11392f868d72092765367",
|
||||
"symbol": "Aeternity",
|
||||
"decimal": 18,
|
||||
"type": "default"
|
||||
}
|
||||
]
|
|
@ -0,0 +1 @@
|
|||
[]
|
|
@ -0,0 +1 @@
|
|||
[]
|
|
@ -0,0 +1 @@
|
|||
[]
|
|
@ -0,0 +1,14 @@
|
|||
[
|
||||
{
|
||||
"address": "0xd245207cfbf6eb6f34970db2a807ab1d178fde6c",
|
||||
"symbol": "APX",
|
||||
"decimal": 8,
|
||||
"type": "default"
|
||||
},
|
||||
{
|
||||
"address": "0x4b4899a10f3e507db207b0ee2426029efa168a67",
|
||||
"symbol": "QWARK",
|
||||
"decimal": 8,
|
||||
"type": "default"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,29 @@
|
|||
// @flow
|
||||
import RPCClient from '../rpc/client';
|
||||
import type { EtherscanRequest } from './types';
|
||||
import type { JsonRpcResponse } from '../rpc/types';
|
||||
|
||||
export default class EtherscanClient extends RPCClient {
|
||||
encodeRequest(request: EtherscanRequest): string {
|
||||
const encoded = new URLSearchParams();
|
||||
Object.keys(request).forEach(key => {
|
||||
encoded.set(key, request[key]);
|
||||
});
|
||||
return encoded.toString();
|
||||
}
|
||||
|
||||
async call(request: EtherscanRequest): Promise<JsonRpcResponse> {
|
||||
return fetch(this.endpoint, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
|
||||
},
|
||||
body: this.encodeRequest(request)
|
||||
}).then(r => r.json());
|
||||
}
|
||||
|
||||
async batch(requests: EtherscanRequest[]): Promise<JsonRpcResponse[]> {
|
||||
const promises = requests.map(req => this.call(req));
|
||||
return Promise.all(promises);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
import RPCNode from '../rpc';
|
||||
import EtherscanClient from './client';
|
||||
import EtherscanRequests from './requests';
|
||||
|
||||
export default class EtherscanNode extends RPCNode {
|
||||
client: EtherscanClient;
|
||||
requests: EtherscanRequests;
|
||||
|
||||
constructor(endpoint: string) {
|
||||
super(endpoint);
|
||||
this.client = new EtherscanClient(endpoint);
|
||||
this.requests = new EtherscanRequests();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
// @flow
|
||||
import ERC20 from 'libs/erc20';
|
||||
import RPCRequests from '../rpc/requests';
|
||||
import type {
|
||||
CallRequest,
|
||||
GetBalanceRequest,
|
||||
GetTokenBalanceRequest,
|
||||
EstimateGasRequest,
|
||||
GetTransactionCountRequest,
|
||||
SendRawTxRequest
|
||||
} from './types';
|
||||
import type { Token } from 'config/data';
|
||||
|
||||
export default class EtherscanRequests extends RPCRequests {
|
||||
sendRawTx(signedTx: string): SendRawTxRequest {
|
||||
return {
|
||||
module: 'proxy',
|
||||
method: 'eth_sendRawTransaction',
|
||||
hex: signedTx
|
||||
};
|
||||
}
|
||||
|
||||
estimateGas<T: *>(transaction: T): EstimateGasRequest {
|
||||
return {
|
||||
module: 'proxy',
|
||||
method: 'eth_estimateGas',
|
||||
to: transaction.to,
|
||||
value: transaction.value,
|
||||
data: transaction.data,
|
||||
from: transaction.from
|
||||
};
|
||||
}
|
||||
|
||||
getBalance(address: string): GetBalanceRequest {
|
||||
return {
|
||||
module: 'account',
|
||||
action: 'balance',
|
||||
tag: 'latest',
|
||||
address
|
||||
};
|
||||
}
|
||||
|
||||
ethCall<T: *>(transaction: T): CallRequest {
|
||||
return {
|
||||
module: 'proxy',
|
||||
action: 'eth_call',
|
||||
to: transaction.to,
|
||||
data: transaction.data
|
||||
};
|
||||
}
|
||||
|
||||
getTransactionCount(address: string): GetTransactionCountRequest {
|
||||
return {
|
||||
module: 'proxy',
|
||||
action: 'eth_getTransactionCount',
|
||||
tag: 'latest',
|
||||
address
|
||||
};
|
||||
}
|
||||
|
||||
getTokenBalance(address: string, token: Token): GetTokenBalanceRequest {
|
||||
return this.ethCall({
|
||||
to: token.address,
|
||||
data: ERC20.balanceOf(address)
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
export type EtherscanReqBase = {
|
||||
module: string,
|
||||
action: string
|
||||
};
|
||||
|
||||
export type SendRawTxRequest = EtherscanReqBase & {
|
||||
module: 'proxy',
|
||||
method: 'eth_sendRawTransaction',
|
||||
hex: string
|
||||
};
|
||||
|
||||
export type GetBalanceRequest = EtherscanReqBase & {
|
||||
module: 'account',
|
||||
action: 'balance',
|
||||
address: string,
|
||||
tag: 'latest'
|
||||
};
|
||||
|
||||
export type CallRequest = EtherscanReqBase & {
|
||||
module: 'proxy',
|
||||
action: 'eth_call',
|
||||
to: string,
|
||||
data: string
|
||||
};
|
||||
|
||||
export type GetTokenBalanceRequest = CallRequest;
|
||||
|
||||
export type EstimateGasRequest = EtherscanReqBase & {
|
||||
module: 'proxy',
|
||||
method: 'eth_estimateGas',
|
||||
to: string,
|
||||
value: string | number,
|
||||
data: string,
|
||||
from: string
|
||||
};
|
||||
|
||||
export type GetTransactionCountRequest = EtherscanReqBase & {
|
||||
module: 'proxy',
|
||||
action: 'eth_getTransactionCount',
|
||||
address: string,
|
||||
tag: 'latest'
|
||||
};
|
|
@ -1,2 +1,4 @@
|
|||
// @flow
|
||||
export { default as RPCNode } from './rpc';
|
||||
export { default as InfuraNode } from './infura';
|
||||
export { default as EtherscanNode } from './etherscan';
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
import RPCClient from '../rpc/client';
|
||||
import Big from 'bignumber.js';
|
||||
import { randomBytes } from 'crypto';
|
||||
|
||||
export default class InfuraClient extends RPCClient {
|
||||
id(): string {
|
||||
return new Big('0x' + randomBytes(5).toString('hex')).toNumber();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import RPCNode from '../rpc';
|
||||
import InfuraClient from './client';
|
||||
|
||||
export default class InfuraNode extends RPCNode {
|
||||
client: InfuraClient;
|
||||
|
||||
constructor(endpoint: string) {
|
||||
super(endpoint);
|
||||
this.client = new InfuraClient(endpoint);
|
||||
}
|
||||
}
|
|
@ -1,88 +1,6 @@
|
|||
// @flow
|
||||
import { randomBytes } from 'crypto';
|
||||
import ERC20 from 'libs/erc20';
|
||||
import { hexEncodeData } from './utils';
|
||||
import type {
|
||||
RPCRequest,
|
||||
JsonRpcResponse,
|
||||
CallRequest,
|
||||
GetBalanceRequest,
|
||||
GetTokenBalanceRequest,
|
||||
EstimateGasRequest,
|
||||
GetTransactionCountRequest,
|
||||
SendRawTxRequest
|
||||
} from './types';
|
||||
import type { Token } from 'config/data';
|
||||
|
||||
// FIXME is it safe to generate that much entropy?
|
||||
function id(): string {
|
||||
return randomBytes(16).toString('hex');
|
||||
}
|
||||
|
||||
export function sendRawTx(signedTx: string): SendRawTxRequest {
|
||||
return {
|
||||
id: id(),
|
||||
jsonrpc: '2.0',
|
||||
method: 'eth_sendRawTransaction',
|
||||
params: [signedTx]
|
||||
};
|
||||
}
|
||||
|
||||
export function estimateGas<T: *>(transaction: T): EstimateGasRequest {
|
||||
return {
|
||||
id: id(),
|
||||
jsonrpc: '2.0',
|
||||
method: 'eth_estimateGas',
|
||||
params: [transaction]
|
||||
};
|
||||
}
|
||||
|
||||
export function getBalance(address: string): GetBalanceRequest {
|
||||
return {
|
||||
id: id(),
|
||||
jsonrpc: '2.0',
|
||||
method: 'eth_getBalance',
|
||||
params: [hexEncodeData(address), 'pending']
|
||||
};
|
||||
}
|
||||
|
||||
export function ethCall<T: *>(transaction: T): CallRequest {
|
||||
return {
|
||||
id: id(),
|
||||
jsonrpc: '2.0',
|
||||
method: 'eth_call',
|
||||
params: [transaction, 'pending']
|
||||
};
|
||||
}
|
||||
|
||||
export function getTransactionCount(
|
||||
address: string
|
||||
): GetTransactionCountRequest {
|
||||
return {
|
||||
id: id(),
|
||||
jsonrpc: '2.0',
|
||||
method: 'eth_getTransactionCount',
|
||||
params: [address, 'pending']
|
||||
};
|
||||
}
|
||||
|
||||
export function getTokenBalance(
|
||||
address: string,
|
||||
token: Token
|
||||
): GetTokenBalanceRequest {
|
||||
return {
|
||||
id: id(),
|
||||
jsonrpc: '2.0',
|
||||
method: 'eth_call',
|
||||
params: [
|
||||
{
|
||||
to: token.address,
|
||||
data: ERC20.balanceOf(address)
|
||||
},
|
||||
'pending'
|
||||
]
|
||||
};
|
||||
}
|
||||
import type { RPCRequest, JsonRpcResponse } from './types';
|
||||
|
||||
export default class RPCClient {
|
||||
endpoint: string;
|
||||
|
@ -90,13 +8,25 @@ export default class RPCClient {
|
|||
this.endpoint = endpoint;
|
||||
}
|
||||
|
||||
id(): string {
|
||||
return randomBytes(16).toString('hex');
|
||||
}
|
||||
|
||||
decorateRequest(req: RPCRequest) {
|
||||
return {
|
||||
...req,
|
||||
id: this.id(),
|
||||
jsonrpc: '2.0'
|
||||
};
|
||||
}
|
||||
|
||||
async call(request: RPCRequest): Promise<JsonRpcResponse> {
|
||||
return fetch(this.endpoint, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(request)
|
||||
body: JSON.stringify(this.decorateRequest(request))
|
||||
}).then(r => r.json());
|
||||
}
|
||||
|
||||
|
@ -106,7 +36,7 @@ export default class RPCClient {
|
|||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(requests)
|
||||
body: JSON.stringify(requests.map(this.decorateRequest))
|
||||
}).then(r => r.json());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,55 +2,58 @@
|
|||
import Big from 'bignumber.js';
|
||||
import type { INode } from '../INode';
|
||||
import type { TransactionWithoutGas } from 'libs/messages';
|
||||
import RPCClient, {
|
||||
getBalance,
|
||||
estimateGas,
|
||||
getTransactionCount,
|
||||
getTokenBalance,
|
||||
sendRawTx
|
||||
} from './client';
|
||||
import type { Token } from 'config/data';
|
||||
import RPCClient from './client';
|
||||
import RPCRequests from './requests';
|
||||
import { Wei } from 'libs/units';
|
||||
import type { Token } from 'config/data';
|
||||
|
||||
export default class RpcNode implements INode {
|
||||
client: RPCClient;
|
||||
requests: RPCRequests;
|
||||
constructor(endpoint: string) {
|
||||
this.client = new RPCClient(endpoint);
|
||||
this.requests = new RPCRequests();
|
||||
}
|
||||
|
||||
getBalance(address: string): Promise<Wei> {
|
||||
return this.client.call(getBalance(address)).then(response => {
|
||||
if (response.error) {
|
||||
throw new Error(response.error.message);
|
||||
}
|
||||
return new Wei(String(response.result));
|
||||
});
|
||||
return this.client
|
||||
.call(this.requests.getBalance(address))
|
||||
.then(response => {
|
||||
if (response.error) {
|
||||
throw new Error(response.error.message);
|
||||
}
|
||||
return new Wei(String(response.result));
|
||||
});
|
||||
}
|
||||
|
||||
estimateGas(transaction: TransactionWithoutGas): Promise<Big> {
|
||||
return this.client.call(estimateGas(transaction)).then(response => {
|
||||
if (response.error) {
|
||||
throw new Error(response.error.message);
|
||||
}
|
||||
return new Big(String(response.result));
|
||||
});
|
||||
return this.client
|
||||
.call(this.requests.estimateGas(transaction))
|
||||
.then(response => {
|
||||
if (response.error) {
|
||||
throw new Error(response.error.message);
|
||||
}
|
||||
return new Big(String(response.result));
|
||||
});
|
||||
}
|
||||
|
||||
getTokenBalance(address: string, token: Token): Promise<Big> {
|
||||
return this.client.call(getTokenBalance(address, token)).then(response => {
|
||||
if (response.error) {
|
||||
// TODO - Error handling
|
||||
return new Big(0);
|
||||
}
|
||||
return new Big(String(response.result)).div(
|
||||
new Big(10).pow(token.decimal)
|
||||
);
|
||||
});
|
||||
return this.client
|
||||
.call(this.requests.getTokenBalance(address, token))
|
||||
.then(response => {
|
||||
if (response.error) {
|
||||
// TODO - Error handling
|
||||
return new Big(0);
|
||||
}
|
||||
return new Big(String(response.result)).div(
|
||||
new Big(10).pow(token.decimal)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
getTokenBalances(address: string, tokens: Token[]): Promise<Big[]> {
|
||||
return this.client
|
||||
.batch(tokens.map(t => getTokenBalance(address, t)))
|
||||
.batch(tokens.map(t => this.requests.getTokenBalance(address, t)))
|
||||
.then(response => {
|
||||
return response.map((item, idx) => {
|
||||
// FIXME wrap in maybe-like
|
||||
|
@ -66,23 +69,27 @@ export default class RpcNode implements INode {
|
|||
}
|
||||
|
||||
getTransactionCount(address: string): Promise<string> {
|
||||
return this.client.call(getTransactionCount(address)).then(response => {
|
||||
if (response.error) {
|
||||
throw new Error(response.error.message);
|
||||
}
|
||||
return response.result;
|
||||
});
|
||||
return this.client
|
||||
.call(this.requests.getTransactionCount(address))
|
||||
.then(response => {
|
||||
if (response.error) {
|
||||
throw new Error(response.error.message);
|
||||
}
|
||||
return response.result;
|
||||
});
|
||||
}
|
||||
|
||||
sendRawTx(signedTx: string): Promise<string> {
|
||||
return this.client.call(sendRawTx(signedTx)).then(response => {
|
||||
if (response.error) {
|
||||
throw new Error(response.error.message);
|
||||
}
|
||||
if (response.errorMessage) {
|
||||
throw new Error(response.errorMessage);
|
||||
}
|
||||
return response.result;
|
||||
});
|
||||
return this.client
|
||||
.call(this.requests.sendRawTx(signedTx))
|
||||
.then(response => {
|
||||
if (response.error) {
|
||||
throw new Error(response.error.message);
|
||||
}
|
||||
if (response.errorMessage) {
|
||||
throw new Error(response.errorMessage);
|
||||
}
|
||||
return response.result;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
// @flow
|
||||
import ERC20 from 'libs/erc20';
|
||||
import { hexEncodeData } from './utils';
|
||||
import type {
|
||||
CallRequest,
|
||||
GetBalanceRequest,
|
||||
GetTokenBalanceRequest,
|
||||
EstimateGasRequest,
|
||||
GetTransactionCountRequest,
|
||||
SendRawTxRequest
|
||||
} from './types';
|
||||
import type { Token } from 'config/data';
|
||||
|
||||
export default class RPCRequests {
|
||||
sendRawTx(signedTx: string): SendRawTxRequest {
|
||||
return {
|
||||
method: 'eth_sendRawTransaction',
|
||||
params: [signedTx]
|
||||
};
|
||||
}
|
||||
|
||||
estimateGas<T: *>(transaction: T): EstimateGasRequest {
|
||||
return {
|
||||
method: 'eth_estimateGas',
|
||||
params: [transaction]
|
||||
};
|
||||
}
|
||||
|
||||
getBalance(address: string): GetBalanceRequest {
|
||||
return {
|
||||
method: 'eth_getBalance',
|
||||
params: [hexEncodeData(address), 'pending']
|
||||
};
|
||||
}
|
||||
|
||||
ethCall<T: *>(transaction: T): CallRequest {
|
||||
return {
|
||||
method: 'eth_call',
|
||||
params: [transaction, 'pending']
|
||||
};
|
||||
}
|
||||
|
||||
getTransactionCount(address: string): GetTransactionCountRequest {
|
||||
return {
|
||||
method: 'eth_getTransactionCount',
|
||||
params: [address, 'pending']
|
||||
};
|
||||
}
|
||||
|
||||
getTokenBalance(address: string, token: Token): GetTokenBalanceRequest {
|
||||
return {
|
||||
method: 'eth_call',
|
||||
params: [
|
||||
{
|
||||
to: token.address,
|
||||
data: ERC20.balanceOf(address)
|
||||
},
|
||||
'pending'
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
|
@ -25,8 +25,6 @@ export type JSONRPC2 = '2.0';
|
|||
export type JsonRpcResponse = JsonRpcSuccess | JsonRpcError;
|
||||
|
||||
type RPCRequestBase = {
|
||||
id: string,
|
||||
jsonrpc: JSONRPC2,
|
||||
method: string
|
||||
};
|
||||
|
||||
|
|
|
@ -4,10 +4,11 @@ import type { Yield, Return, Next } from 'sagas/types';
|
|||
|
||||
// @HACK For now we reload the app when doing a language swap to force non-connected
|
||||
// data to reload. Also the use of timeout to avoid using additional actions for now.
|
||||
function* handleLanguageChange(): Generator<Yield, Return, Next> {
|
||||
function* reload(): Generator<Yield, Return, Next> {
|
||||
yield setTimeout(() => location.reload(), 250);
|
||||
}
|
||||
|
||||
export default function* handleConfigChanges(): Generator<Yield, Return, Next> {
|
||||
yield takeEvery('CONFIG_LANGUAGE_CHANGE', handleLanguageChange);
|
||||
yield takeEvery('CONFIG_NODE_CHANGE', reload);
|
||||
yield takeEvery('CONFIG_LANGUAGE_CHANGE', reload);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ import {
|
|||
import { INode } from 'libs/nodes/INode';
|
||||
import { determineKeystoreType } from 'libs/keystore';
|
||||
import type { Wei } from 'libs/units';
|
||||
import { getNodeLib } from 'selectors/config';
|
||||
import { getNodeLib, getNetworkConfig } from 'selectors/config';
|
||||
import { getWalletInst, getTokens } from 'selectors/wallet';
|
||||
|
||||
import TransactionSucceeded from 'components/ExtendedNotifications/TransactionSucceeded';
|
||||
|
@ -168,9 +168,17 @@ function* broadcastTx(
|
|||
const signedTx = action.payload.signedTx;
|
||||
try {
|
||||
const node: INode = yield select(getNodeLib);
|
||||
const network = yield select(getNetworkConfig);
|
||||
const txHash = yield apply(node, node.sendRawTx, [signedTx]);
|
||||
yield put(
|
||||
showNotification('success', <TransactionSucceeded txHash={txHash} />, 0)
|
||||
showNotification(
|
||||
'success',
|
||||
<TransactionSucceeded
|
||||
txHash={txHash}
|
||||
blockExplorer={network.blockExplorer}
|
||||
/>,
|
||||
0
|
||||
)
|
||||
);
|
||||
yield put({
|
||||
type: 'WALLET_BROADCAST_TX_SUCCEEDED',
|
||||
|
|
|
@ -60,6 +60,7 @@ const configureStore = () => {
|
|||
throttle(() => {
|
||||
saveState({
|
||||
config: {
|
||||
nodeSelection: store.getState().config.nodeSelection,
|
||||
languageSelection: store.getState().config.languageSelection
|
||||
},
|
||||
swap: store.getState().swap,
|
||||
|
|
|
@ -1641,6 +1641,18 @@
|
|||
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz",
|
||||
"integrity": "sha1-FK1hE4EtLTfXLme0ystLtyZQXxE="
|
||||
},
|
||||
"bip39": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/bip39/-/bip39-2.4.0.tgz",
|
||||
"integrity": "sha512-1++HywqIyPtWDo7gm4v0ylYbwkLvHkuwVSKbBlZBbTCP/mnkyrlARBny906VLAwxJbC5xw9EvuJasHFIZaIFMQ==",
|
||||
"requires": {
|
||||
"create-hash": "1.1.3",
|
||||
"pbkdf2": "3.0.12",
|
||||
"randombytes": "2.0.5",
|
||||
"safe-buffer": "5.1.1",
|
||||
"unorm": "1.4.1"
|
||||
}
|
||||
},
|
||||
"bip66": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz",
|
||||
|
@ -10139,7 +10151,6 @@
|
|||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.5.tgz",
|
||||
"integrity": "sha512-8T7Zn1AhMsQ/HI1SjcCfT/t4ii3eAqco3yOcSzS4mozsOz69lHLsoMXmF9nZgnFanYscnSlUSgs8uZyKzpE6kg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "5.1.1"
|
||||
}
|
||||
|
@ -12232,6 +12243,11 @@
|
|||
"through2-filter": "2.0.0"
|
||||
}
|
||||
},
|
||||
"unorm": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/unorm/-/unorm-1.4.1.tgz",
|
||||
"integrity": "sha1-NkIA1fE2RsqLzURJAnEzVhR5IwA="
|
||||
},
|
||||
"unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
|
|
Loading…
Reference in New Issue