Commit 63440fd8 authored by Chi Kei Chan's avatar Chi Kei Chan Committed by GitHub

Update Addresses for Main Net; Update TokenLogo; Connect Web3Status (#86)

parent 3e299ff2
[
{
"constant": true,
"inputs": [],
"name": "name",
"outputs": [
{
"name": "",
"type": "string"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_spender",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "approve",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_from",
"type": "address"
},
{
"name": "_to",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "decimals",
"outputs": [
{
"name": "",
"type": "uint8"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_owner",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"name": "balance",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "symbol",
"outputs": [
{
"name": "",
"type": "bytes32"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_to",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_owner",
"type": "address"
},
{
"name": "_spender",
"type": "address"
}
],
"name": "allowance",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"payable": true,
"stateMutability": "payable",
"type": "fallback"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "owner",
"type": "address"
},
{
"indexed": true,
"name": "spender",
"type": "address"
},
{
"indexed": false,
"name": "value",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "from",
"type": "address"
},
{
"indexed": true,
"name": "to",
"type": "address"
},
{
"indexed": false,
"name": "value",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
}
]
...@@ -97,36 +97,36 @@ class CurrencyInputPanel extends Component { ...@@ -97,36 +97,36 @@ class CurrencyInputPanel extends Component {
this.props.onCurrencySelected(address); this.props.onCurrencySelected(address);
if (address && address !== 'ETH') { // if (address && address !== 'ETH') {
const { drizzle } = this.context; // const { drizzle } = this.context;
const { fromToken } = this.props.exchangeAddresses; // const { fromToken } = this.props.exchangeAddresses;
const { web3 } = drizzle; // const { web3 } = drizzle;
//
// Add Token Contract // // Add Token Contract
if (!this.props.contracts[address]) { // if (!this.props.contracts[address]) {
const tokenConfig = { // const tokenConfig = {
contractName: address, // contractName: address,
web3Contract: new web3.eth.Contract(ERC20_ABI, address), // web3Contract: new web3.eth.Contract(ERC20_ABI, address),
}; // };
const tokenEvents = ['Approval', 'Transfer']; // const tokenEvents = ['Approval', 'Transfer'];
this.context.drizzle.addContract(tokenConfig, tokenEvents, { from: this.props.account }); // this.context.drizzle.addContract(tokenConfig, tokenEvents, { from: this.props.account });
} // }
//
// Add Exchange Contract // // Add Exchange Contract
const exchangeAddress = fromToken[address]; // const exchangeAddress = fromToken[address];
if (!exchangeAddress) { // if (!exchangeAddress) {
return; // return;
} // }
//
if (!this.props.contracts[exchangeAddress]) { // if (!this.props.contracts[exchangeAddress]) {
const exchangeConfig = { // const exchangeConfig = {
contractName: exchangeAddress, // contractName: exchangeAddress,
web3Contract: new web3.eth.Contract(EXCHANGE_ABI, exchangeAddress), // web3Contract: new web3.eth.Contract(EXCHANGE_ABI, exchangeAddress),
}; // };
const exchangeEvents = ['Approval', 'Transfer', 'TokenPurchase', 'EthPurchase', 'AddLiquidity', 'RemoveLiquidity']; // const exchangeEvents = ['Approval', 'Transfer', 'TokenPurchase', 'EthPurchase', 'AddLiquidity', 'RemoveLiquidity'];
this.context.drizzle.addContract(exchangeConfig, exchangeEvents , { from: this.props.account }); // this.context.drizzle.addContract(exchangeConfig, exchangeEvents , { from: this.props.account });
} // }
} // }
}; };
renderTokenList() { renderTokenList() {
......
...@@ -80,7 +80,7 @@ function Header (props) { ...@@ -80,7 +80,7 @@ function Header (props) {
<div className="header"> <div className="header">
<div <div
className={classnames('header__dialog', { className={classnames('header__dialog', {
'header__dialog--disconnected': !props.isConnected, 'header__dialog--disconnected': !props.isConnected && props.initialized,
})} })}
> >
<div>No Ethereum wallet found</div> <div>No Ethereum wallet found</div>
...@@ -133,8 +133,8 @@ Header.propTypes = { ...@@ -133,8 +133,8 @@ Header.propTypes = {
export default drizzleConnect( export default drizzleConnect(
Header, Header,
state => ({ state => ({
// web3: console.log(state) || state.web3, currentAddress: state.web3connect.account,
currentAddress: state.accounts[0], initialized: state.web3connect.initialized,
isConnected: !!(state.drizzleStatus.initialized && state.accounts[0]), isConnected: !!state.web3connect.web3 && !!state.web3connect.account,
}), }),
); );
...@@ -40,7 +40,7 @@ export default class TokenLogo extends Component { ...@@ -40,7 +40,7 @@ export default class TokenLogo extends Component {
} }
if (!this.state.error && !BAD_IMAGES[mainAddress] && mainAddress !== 'ETH') { if (!this.state.error && !BAD_IMAGES[mainAddress] && mainAddress !== 'ETH') {
path = `${TOKEN_ICON_API}/${mainAddress}.png`; path = `${TOKEN_ICON_API}/${mainAddress.toLowerCase()}.png`;
} }
return ( return (
......
...@@ -153,8 +153,8 @@ export default drizzleConnect( ...@@ -153,8 +153,8 @@ export default drizzleConnect(
}); });
return { return {
address: state.accounts[0], address: state.web3connect.account,
isConnected: !!(state.drizzleStatus.initialized && state.accounts[0]), isConnected: !!(state.web3connect.web3 && state.web3connect.account),
pendingTransactions, pendingTransactions,
hasPendingTransactions: pendingTransactions.length > 0, hasPendingTransactions: pendingTransactions.length > 0,
}; };
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
flex: 1 1 auto; flex: 1 1 auto;
width: 0; width: 0;
overflow: hidden; overflow: hidden;
text-align: right;
margin-left: 1rem; margin-left: 1rem;
font-size: .85rem; font-size: .85rem;
} }
......
const initialState = { const RINKEBY = {
currentAddress: '',
balance: {},
exchangeAddresses: { exchangeAddresses: {
addresses: [ addresses: [
['BAT','0x9B913956036a3462330B0642B20D3879ce68b450'], ['BAT','0x9B913956036a3462330B0642B20D3879ce68b450'],
...@@ -28,8 +26,68 @@ const initialState = { ...@@ -28,8 +26,68 @@ const initialState = {
}, },
}; };
export default (state = initialState, { type }) => { const MAIN = {
exchangeAddresses: {
addresses: [
['BAT', '0x31684EB08E0d86AE970F4C2f9110afBce9C4C984'],
['DAI', '0xB23601D1E65002fA3173A0982b8E4AD5B46C7863'],
['MKR', '0x405f6187BeE030B1DF486968C673907F0fd58BE1'],
['ANT', '0x264B884Df87fBB97997994181d054e8657eB5c78'],
['REP', '0x997C2c6b08E33313C5512Fd3C6eF235BF0139Ca3'],
['ZRX', '0xE9674e73887bDCCd8fd46861a4f5b1E6485789BE'],
['SNT', '0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2'],
],
fromToken: {
'0x0D8775F648430679A709E98d2b0Cb6250d2887EF': '0x31684EB08E0d86AE970F4C2f9110afBce9C4C984',
'0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359': '0xB23601D1E65002fA3173A0982b8E4AD5B46C7863',
'0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2': '0x405f6187BeE030B1DF486968C673907F0fd58BE1',
'0x960b236A07cf122663c4303350609A66A7B288C0': '0x264B884Df87fBB97997994181d054e8657eB5c78',
'0x1985365e9f78359a9B6AD760e32412f4a445E862': '0x997C2c6b08E33313C5512Fd3C6eF235BF0139Ca3',
'0xE41d2489571d322189246DaFA5ebDe1F4699F498': '0xE9674e73887bDCCd8fd46861a4f5b1E6485789BE',
'0x744d70FDBE2Ba4CF95131626614a1763DF805B9E': '0x63d4b39137dF65ebEad4E15456c291284fCB537C',
},
},
tokenAddresses: {
addresses: [
['BAT', '0x0D8775F648430679A709E98d2b0Cb6250d2887EF'],
['DAI', '0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359'],
['MKR', '0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2'],
['ANT', '0x960b236A07cf122663c4303350609A66A7B288C0'],
['REP', '0x1985365e9f78359a9B6AD760e32412f4a445E862'],
['ZRX', '0xE41d2489571d322189246DaFA5ebDe1F4699F498'],
['SNT', '0x744d70FDBE2Ba4CF95131626614a1763DF805B9E'],
],
},
};
const SET_ADDRESSES = 'app/addresses/setAddresses';
const initialState = RINKEBY;
export const setAddresses = networkId => {
switch(networkId) {
// Main Net
case 1:
case '1':
return {
type: SET_ADDRESSES,
payload: MAIN,
};
// Rinkeby
case 4:
case '4':
return {
type: SET_ADDRESSES,
payload: RINKEBY,
};
}
};
export default (state = initialState, { type, payload }) => {
switch (type) { switch (type) {
default: return state; case SET_ADDRESSES:
return payload;
default:
return state;
} }
} }
...@@ -5,6 +5,7 @@ import { drizzleConnect } from 'drizzle-react'; ...@@ -5,6 +5,7 @@ import { drizzleConnect } from 'drizzle-react';
import {BigNumber as BN} from 'bignumber.js'; import {BigNumber as BN} from 'bignumber.js';
import Web3 from 'web3'; import Web3 from 'web3';
import ERC20_ABI from "../abi/erc20"; import ERC20_ABI from "../abi/erc20";
import ERC20_WITH_BYTES_ABI from "../abi/erc20_symbol_bytes32";
export const INITIALIZE = 'we3connect/initialize'; export const INITIALIZE = 'we3connect/initialize';
export const UPDATE_ACCOUNT = 'we3connect/updateAccount'; export const UPDATE_ACCOUNT = 'we3connect/updateAccount';
...@@ -16,7 +17,6 @@ export const WATCH_APPROVALS = 'web3connect/watchApprovals'; ...@@ -16,7 +17,6 @@ export const WATCH_APPROVALS = 'web3connect/watchApprovals';
export const UPDATE_APPROVALS = 'web3connect/updateApprovals'; export const UPDATE_APPROVALS = 'web3connect/updateApprovals';
export const ADD_CONTRACT = 'web3connect/addContract'; export const ADD_CONTRACT = 'web3connect/addContract';
const initialState = { const initialState = {
web3: null, web3: null,
initialized: false, initialized: false,
...@@ -33,7 +33,6 @@ const initialState = { ...@@ -33,7 +33,6 @@ const initialState = {
}, },
pendingTransactions: [], pendingTransactions: [],
transactions: {}, transactions: {},
errorMessage: '',
watched: { watched: {
balances: { balances: {
ethereum: [], ethereum: [],
...@@ -43,18 +42,17 @@ const initialState = { ...@@ -43,18 +42,17 @@ const initialState = {
contracts: {}, contracts: {},
}; };
const TOKEN_LABEL_FALLBACK = {
'0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359': 'DAI',
'0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2': 'MKR',
};
// selectors // selectors
export const selectors = () => (dispatch, getState) => { export const selectors = () => (dispatch, getState) => {
const state = getState().web3connect; const state = getState().web3connect;
const getTokenBalance = (tokenAddress, address) => { const getTokenBalance = (tokenAddress, address) => {
const tokenBalances = state.balances[tokenAddress]; const tokenBalances = state.balances[tokenAddress] || {};
if (!tokenBalances) {
dispatch(watchBalance({ balanceOf: address, tokenAddress }));
return Balance(0);
}
const balance = tokenBalances[address]; const balance = tokenBalances[address];
if (!balance) { if (!balance) {
dispatch(watchBalance({ balanceOf: address, tokenAddress })); dispatch(watchBalance({ balanceOf: address, tokenAddress }));
...@@ -70,7 +68,6 @@ export const selectors = () => (dispatch, getState) => { ...@@ -70,7 +68,6 @@ export const selectors = () => (dispatch, getState) => {
if (!tokenAddress || tokenAddress === 'ETH') { if (!tokenAddress || tokenAddress === 'ETH') {
const balance = state.balances.ethereum[address]; const balance = state.balances.ethereum[address];
if (!balance) { if (!balance) {
dispatch(watchBalance({ balanceOf: address })); dispatch(watchBalance({ balanceOf: address }));
return Balance(0, 'ETH'); return Balance(0, 'ETH');
...@@ -204,7 +201,7 @@ export const updateApprovals = ({ tokenAddress, tokenOwner, spender, balance }) ...@@ -204,7 +201,7 @@ export const updateApprovals = ({ tokenAddress, tokenOwner, spender, balance })
}); });
export const sync = () => async (dispatch, getState) => { export const sync = () => async (dispatch, getState) => {
const { getBalance, getTokenBalance, getApprovals } = dispatch(selectors()); const { getBalance, getApprovals } = dispatch(selectors());
const web3 = await dispatch(initialize()); const web3 = await dispatch(initialize());
const { const {
account, account,
...@@ -224,10 +221,10 @@ export const sync = () => async (dispatch, getState) => { ...@@ -224,10 +221,10 @@ export const sync = () => async (dispatch, getState) => {
const balance = await web3.eth.getBalance(address); const balance = await web3.eth.getBalance(address);
const { value } = getBalance(address); const { value } = getBalance(address);
if (value.isEqualTo(BN(balance))) { if (value.isEqualTo(BN(balance))) {
return; return;
} }
dispatch({ dispatch({
type: UPDATE_ETH_BALANCE, type: UPDATE_ETH_BALANCE,
payload: { payload: {
...@@ -245,6 +242,7 @@ export const sync = () => async (dispatch, getState) => { ...@@ -245,6 +242,7 @@ export const sync = () => async (dispatch, getState) => {
} }
const contract = contracts[tokenAddress] || new web3.eth.Contract(ERC20_ABI, tokenAddress); const contract = contracts[tokenAddress] || new web3.eth.Contract(ERC20_ABI, tokenAddress);
if (!contracts[tokenAddress]) { if (!contracts[tokenAddress]) {
dispatch({ dispatch({
type: ADD_CONTRACT, type: ADD_CONTRACT,
...@@ -257,10 +255,10 @@ export const sync = () => async (dispatch, getState) => { ...@@ -257,10 +255,10 @@ export const sync = () => async (dispatch, getState) => {
const watchlist = watched.balances[tokenAddress] || []; const watchlist = watched.balances[tokenAddress] || [];
watchlist.forEach(async address => { watchlist.forEach(async address => {
const tokenBalance = getTokenBalance(tokenAddress, address); const tokenBalance = getBalance(address, tokenAddress);
const balance = await contract.methods.balanceOf(address).call(); const balance = await contract.methods.balanceOf(address).call();
const decimals = tokenBalance.decimals || await contract.methods.decimals().call(); const decimals = tokenBalance.decimals || await contract.methods.decimals().call();
const symbol = tokenBalance.label || await contract.methods.symbol().call(); const symbol = TOKEN_LABEL_FALLBACK[tokenAddress] || tokenBalance.label || await contract.methods.symbol().call();
if (tokenBalance.value.isEqualTo(BN(balance))) { if (tokenBalance.value.isEqualTo(BN(balance))) {
return; return;
...@@ -287,7 +285,7 @@ export const sync = () => async (dispatch, getState) => { ...@@ -287,7 +285,7 @@ export const sync = () => async (dispatch, getState) => {
const approvalBalance = getApprovals(tokenAddress, tokenOwnerAddress, spenderAddress); const approvalBalance = getApprovals(tokenAddress, tokenOwnerAddress, spenderAddress);
const balance = await contract.methods.allowance(tokenOwnerAddress, spenderAddress).call(); const balance = await contract.methods.allowance(tokenOwnerAddress, spenderAddress).call();
const decimals = approvalBalance.decimals || await contract.methods.decimals().call(); const decimals = approvalBalance.decimals || await contract.methods.decimals().call();
const symbol = approvalBalance.label || await contract.methods.symbol().call(); const symbol = TOKEN_LABEL_FALLBACK[tokenAddress] || approvalBalance.label || await contract.methods.symbol().call();
if (approvalBalance.label && approvalBalance.value.isEqualTo(BN(balance))) { if (approvalBalance.label && approvalBalance.value.isEqualTo(BN(balance))) {
return; return;
...@@ -318,7 +316,11 @@ export const startWatching = () => async (dispatch, getState) => { ...@@ -318,7 +316,11 @@ export const startWatching = () => async (dispatch, getState) => {
export default function web3connectReducer(state = initialState, { type, payload }) { export default function web3connectReducer(state = initialState, { type, payload }) {
switch (type) { switch (type) {
case INITIALIZE: case INITIALIZE:
return { ...state, web3: payload }; return {
...state,
web3: payload,
initialized: true,
};
case UPDATE_ACCOUNT: case UPDATE_ACCOUNT:
return { return {
...state, ...state,
......
...@@ -2,7 +2,8 @@ import React, { Component } from 'react'; ...@@ -2,7 +2,8 @@ import React, { Component } from 'react';
import { drizzleConnect } from 'drizzle-react' import { drizzleConnect } from 'drizzle-react'
import { BrowserRouter, Switch, Redirect, Route } from 'react-router-dom'; import { BrowserRouter, Switch, Redirect, Route } from 'react-router-dom';
import { AnimatedSwitch } from 'react-router-transition'; import { AnimatedSwitch } from 'react-router-transition';
import { Web3Connect } from '../ducks/web3connect'; import { Web3Connect, startWatching, initialize } from '../ducks/web3connect';
import { setAddresses } from '../ducks/addresses';
import Swap from './Swap'; import Swap from './Swap';
import Send from './Send'; import Send from './Send';
import Pool from './Pool'; import Pool from './Pool';
...@@ -10,6 +11,29 @@ import Pool from './Pool'; ...@@ -10,6 +11,29 @@ import Pool from './Pool';
import './App.scss'; import './App.scss';
class App extends Component { class App extends Component {
shouldComponentUpdate() {
return true;
}
componentWillMount() {
const { initialize, startWatching} = this.props;
initialize().then(startWatching);
};
componentWillUpdate() {
const { web3, setAddresses } = this.props;
if (this.hasSetNetworkId || !web3 || !web3.eth || !web3.eth.net || !web3.eth.net.getId) {
return;
}
web3.eth.net.getId((err, networkId) => {
if (!err && !this.hasSetNetworkId) {
setAddresses(networkId);
this.hasSetNetworkId = true;
}
});
}
render() { render() {
if (!this.props.initialized) { if (!this.props.initialized) {
return <noscript />; return <noscript />;
...@@ -39,6 +63,13 @@ class App extends Component { ...@@ -39,6 +63,13 @@ class App extends Component {
export default drizzleConnect( export default drizzleConnect(
App, App,
state => ({ state => ({
initialized: state.drizzleStatus.initialized, account: state.web3connect.account,
initialized: !!state.web3connect.web3,
web3: state.web3connect.web3,
}),
dispatch => ({
setAddresses: networkId => dispatch(setAddresses(networkId)),
initialize: () => dispatch(initialize()),
startWatching: () => dispatch(startWatching()),
}), }),
); );
...@@ -103,7 +103,7 @@ class Swap extends Component { ...@@ -103,7 +103,7 @@ class Swap extends Component {
return false; return false;
} }
const { value: allowance, label, decmals } = selectors().getApprovals( const { value: allowance, label, decimals } = selectors().getApprovals(
inputCurrency, inputCurrency,
account, account,
exchangeAddresses.fromToken[inputCurrency] exchangeAddresses.fromToken[inputCurrency]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment