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 {
this.props.onCurrencySelected(address);
if (address && address !== 'ETH') {
const { drizzle } = this.context;
const { fromToken } = this.props.exchangeAddresses;
const { web3 } = drizzle;
// Add Token Contract
if (!this.props.contracts[address]) {
const tokenConfig = {
contractName: address,
web3Contract: new web3.eth.Contract(ERC20_ABI, address),
};
const tokenEvents = ['Approval', 'Transfer'];
this.context.drizzle.addContract(tokenConfig, tokenEvents, { from: this.props.account });
}
// Add Exchange Contract
const exchangeAddress = fromToken[address];
if (!exchangeAddress) {
return;
}
if (!this.props.contracts[exchangeAddress]) {
const exchangeConfig = {
contractName: exchangeAddress,
web3Contract: new web3.eth.Contract(EXCHANGE_ABI, exchangeAddress),
};
const exchangeEvents = ['Approval', 'Transfer', 'TokenPurchase', 'EthPurchase', 'AddLiquidity', 'RemoveLiquidity'];
this.context.drizzle.addContract(exchangeConfig, exchangeEvents , { from: this.props.account });
}
}
// if (address && address !== 'ETH') {
// const { drizzle } = this.context;
// const { fromToken } = this.props.exchangeAddresses;
// const { web3 } = drizzle;
//
// // Add Token Contract
// if (!this.props.contracts[address]) {
// const tokenConfig = {
// contractName: address,
// web3Contract: new web3.eth.Contract(ERC20_ABI, address),
// };
// const tokenEvents = ['Approval', 'Transfer'];
// this.context.drizzle.addContract(tokenConfig, tokenEvents, { from: this.props.account });
// }
//
// // Add Exchange Contract
// const exchangeAddress = fromToken[address];
// if (!exchangeAddress) {
// return;
// }
//
// if (!this.props.contracts[exchangeAddress]) {
// const exchangeConfig = {
// contractName: exchangeAddress,
// web3Contract: new web3.eth.Contract(EXCHANGE_ABI, exchangeAddress),
// };
// const exchangeEvents = ['Approval', 'Transfer', 'TokenPurchase', 'EthPurchase', 'AddLiquidity', 'RemoveLiquidity'];
// this.context.drizzle.addContract(exchangeConfig, exchangeEvents , { from: this.props.account });
// }
// }
};
renderTokenList() {
......
......@@ -80,7 +80,7 @@ function Header (props) {
<div className="header">
<div
className={classnames('header__dialog', {
'header__dialog--disconnected': !props.isConnected,
'header__dialog--disconnected': !props.isConnected && props.initialized,
})}
>
<div>No Ethereum wallet found</div>
......@@ -133,8 +133,8 @@ Header.propTypes = {
export default drizzleConnect(
Header,
state => ({
// web3: console.log(state) || state.web3,
currentAddress: state.accounts[0],
isConnected: !!(state.drizzleStatus.initialized && state.accounts[0]),
currentAddress: state.web3connect.account,
initialized: state.web3connect.initialized,
isConnected: !!state.web3connect.web3 && !!state.web3connect.account,
}),
);
......@@ -40,7 +40,7 @@ export default class TokenLogo extends Component {
}
if (!this.state.error && !BAD_IMAGES[mainAddress] && mainAddress !== 'ETH') {
path = `${TOKEN_ICON_API}/${mainAddress}.png`;
path = `${TOKEN_ICON_API}/${mainAddress.toLowerCase()}.png`;
}
return (
......
......@@ -153,8 +153,8 @@ export default drizzleConnect(
});
return {
address: state.accounts[0],
isConnected: !!(state.drizzleStatus.initialized && state.accounts[0]),
address: state.web3connect.account,
isConnected: !!(state.web3connect.web3 && state.web3connect.account),
pendingTransactions,
hasPendingTransactions: pendingTransactions.length > 0,
};
......
......@@ -24,7 +24,6 @@
flex: 1 1 auto;
width: 0;
overflow: hidden;
text-align: right;
margin-left: 1rem;
font-size: .85rem;
}
......
const initialState = {
currentAddress: '',
balance: {},
const RINKEBY = {
exchangeAddresses: {
addresses: [
['BAT','0x9B913956036a3462330B0642B20D3879ce68b450'],
......@@ -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) {
default: return state;
case SET_ADDRESSES:
return payload;
default:
return state;
}
}
......@@ -5,6 +5,7 @@ import { drizzleConnect } from 'drizzle-react';
import {BigNumber as BN} from 'bignumber.js';
import Web3 from 'web3';
import ERC20_ABI from "../abi/erc20";
import ERC20_WITH_BYTES_ABI from "../abi/erc20_symbol_bytes32";
export const INITIALIZE = 'we3connect/initialize';
export const UPDATE_ACCOUNT = 'we3connect/updateAccount';
......@@ -16,7 +17,6 @@ export const WATCH_APPROVALS = 'web3connect/watchApprovals';
export const UPDATE_APPROVALS = 'web3connect/updateApprovals';
export const ADD_CONTRACT = 'web3connect/addContract';
const initialState = {
web3: null,
initialized: false,
......@@ -33,7 +33,6 @@ const initialState = {
},
pendingTransactions: [],
transactions: {},
errorMessage: '',
watched: {
balances: {
ethereum: [],
......@@ -43,18 +42,17 @@ const initialState = {
contracts: {},
};
const TOKEN_LABEL_FALLBACK = {
'0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359': 'DAI',
'0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2': 'MKR',
};
// selectors
export const selectors = () => (dispatch, getState) => {
const state = getState().web3connect;
const getTokenBalance = (tokenAddress, address) => {
const tokenBalances = state.balances[tokenAddress];
if (!tokenBalances) {
dispatch(watchBalance({ balanceOf: address, tokenAddress }));
return Balance(0);
}
const tokenBalances = state.balances[tokenAddress] || {};
const balance = tokenBalances[address];
if (!balance) {
dispatch(watchBalance({ balanceOf: address, tokenAddress }));
......@@ -70,7 +68,6 @@ export const selectors = () => (dispatch, getState) => {
if (!tokenAddress || tokenAddress === 'ETH') {
const balance = state.balances.ethereum[address];
if (!balance) {
dispatch(watchBalance({ balanceOf: address }));
return Balance(0, 'ETH');
......@@ -204,7 +201,7 @@ export const updateApprovals = ({ tokenAddress, tokenOwner, spender, balance })
});
export const sync = () => async (dispatch, getState) => {
const { getBalance, getTokenBalance, getApprovals } = dispatch(selectors());
const { getBalance, getApprovals } = dispatch(selectors());
const web3 = await dispatch(initialize());
const {
account,
......@@ -224,10 +221,10 @@ export const sync = () => async (dispatch, getState) => {
const balance = await web3.eth.getBalance(address);
const { value } = getBalance(address);
if (value.isEqualTo(BN(balance))) {
return;
}
dispatch({
type: UPDATE_ETH_BALANCE,
payload: {
......@@ -245,6 +242,7 @@ export const sync = () => async (dispatch, getState) => {
}
const contract = contracts[tokenAddress] || new web3.eth.Contract(ERC20_ABI, tokenAddress);
if (!contracts[tokenAddress]) {
dispatch({
type: ADD_CONTRACT,
......@@ -257,10 +255,10 @@ export const sync = () => async (dispatch, getState) => {
const watchlist = watched.balances[tokenAddress] || [];
watchlist.forEach(async address => {
const tokenBalance = getTokenBalance(tokenAddress, address);
const tokenBalance = getBalance(address, tokenAddress);
const balance = await contract.methods.balanceOf(address).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))) {
return;
......@@ -287,7 +285,7 @@ export const sync = () => async (dispatch, getState) => {
const approvalBalance = getApprovals(tokenAddress, tokenOwnerAddress, spenderAddress);
const balance = await contract.methods.allowance(tokenOwnerAddress, spenderAddress).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))) {
return;
......@@ -318,7 +316,11 @@ export const startWatching = () => async (dispatch, getState) => {
export default function web3connectReducer(state = initialState, { type, payload }) {
switch (type) {
case INITIALIZE:
return { ...state, web3: payload };
return {
...state,
web3: payload,
initialized: true,
};
case UPDATE_ACCOUNT:
return {
...state,
......
......@@ -2,7 +2,8 @@ import React, { Component } from 'react';
import { drizzleConnect } from 'drizzle-react'
import { BrowserRouter, Switch, Redirect, Route } from 'react-router-dom';
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 Send from './Send';
import Pool from './Pool';
......@@ -10,6 +11,29 @@ import Pool from './Pool';
import './App.scss';
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() {
if (!this.props.initialized) {
return <noscript />;
......@@ -39,6 +63,13 @@ class App extends Component {
export default drizzleConnect(
App,
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 {
return false;
}
const { value: allowance, label, decmals } = selectors().getApprovals(
const { value: allowance, label, decimals } = selectors().getApprovals(
inputCurrency,
account,
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