Commit df23a526 authored by haydenadams's avatar haydenadams Committed by GitHub

Merge pull request #1 from uvilchis/uvDevBranch

Redux refactor
parents 81f6ead0 3000f70e
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -4,13 +4,18 @@ ...@@ -4,13 +4,18 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"dependencies": { "dependencies": {
"axios": "^0.18.0",
"d3": "^4.13.0",
"react": "^16.2.0", "react": "^16.2.0",
"react-cookies": "^0.1.0", "react-cookies": "^0.1.0",
"react-dom": "^16.2.0", "react-dom": "^16.2.0",
"react-helmet": "^5.2.0", "react-helmet": "^5.2.0",
"react-redux": "^5.0.7",
"react-scripts": "1.1.0", "react-scripts": "1.1.0",
"react-scroll-to-component": "^1.0.2", "react-scroll-to-component": "^1.0.2",
"react-select": "^1.2.1", "react-select": "^1.2.1",
"redux": "^3.7.2",
"redux-thunk": "^2.2.0",
"web3": "1.0.0-beta.22" "web3": "1.0.0-beta.22"
}, },
"scripts": { "scripts": {
......
...@@ -10,11 +10,58 @@ import Transactions from './components/Transactions' ...@@ -10,11 +10,58 @@ import Transactions from './components/Transactions'
import SelectToken from './components/SelectToken' import SelectToken from './components/SelectToken'
import './App.css'; import './App.css';
import {exchangeABI} from './helpers/exchangeABI.js' import { exchangeABI } from './helpers/exchangeABI.js'
import {tokenABI} from './helpers/tokenABI.js' import { tokenABI } from './helpers/tokenABI.js'
import {factoryABI} from './helpers/factoryABI.js' import { factoryABI } from './helpers/factoryABI.js'
var localweb3; // enter redux
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux';
import {
web3ConnectionSuccessful,
web3ConnectionUnsuccessful,
setCurrentMaskAddress,
metamaskLocked,
metamaskUnlocked,
setInteractionState,
factoryContractReady,
setNetworkMessage,
setBlockTimestamp,
setExchangeType
} from './actions/web3-actions';
import {
uniExchangeContractReady,
swtExchangeContractReady
} from './actions/exchangeContract-actions';
import {
uniTokenContractReady,
swtTokenContractReady
} from './actions/tokenContract-actions';
import {
setInputBalance,
setOutputBalance,
setInputToken,
setOutputToken,
setInvariant1,
setInvariant2,
setMarketEth1,
setMarketEth2,
setMarketTokens1,
setMarketTokens2,
setAllowanceApprovalState,
setExchangeInputValue,
setExchangeOutputValue,
setExchangeRate,
setExchangeFee
} from './actions/exchange-actions';
// enter d3
import Candlesticks from './components/Candlesticks'
var localweb3; // this isn't even in state
class App extends Component { class App extends Component {
constructor (props) { constructor (props) {
...@@ -26,58 +73,19 @@ class App extends Component { ...@@ -26,58 +73,19 @@ class App extends Component {
} }
this.state = { this.state = {
uniExchangeAddress: '', uniAdded: false, // cookie stuff,
swapExchangeAddress: '', swapAdded: false, // cookie stuff
uniTokenAddress: '', firstRun: true, // cookie stuff
swapTokenAddress: '', transactions: [], // cookie stuff
currentMaskAddress: '',
factoryAddress: '',
uniExchange: {},
uniToken: {},
swapExchange: {},
swapToken: {},
factory: {},
blockTimestamp: 0,
inputBalance: 0,
outputBalance: 0,
tokenAllowance: null,
invariant1: 0,
marketEth1: 0,
marketTokens1: 0,
invariant2: 0,
marketEth2: 0,
marketTokens2: 0,
rate: 0,
fee: 0,
cost: 0,
networkMessage: '',
locked: true,
connected: false,
approved: true,
uniAdded: false,
swapAdded: false,
firstRun: true,
about: false, about: false,
interaction: 'disconnected',
exchangeType: 'ETH to Token',
input: 0,
output: 0,
transactionStatus: 'waiting',
transactions: [],
inputToken: { value: 'ETH',
label: 'ETH',
clearableValue: false
},
outputToken: { value: 'UNI',
label: 'UNI',
clearableValue: false
}
} }
} }
// lets start with what's in the componentDidMount
componentWillMount(){ componentWillMount(){
if(localweb3 === 'undefined'){ console.log('props', this.props)
this.setState({connected: false}) if(localweb3 === 'undefined') {
this.props.web3ConnectionUnsuccessful();
} else { } else {
this.setState({ this.setState({
firstRun: cookie.load('firstRun') || true, firstRun: cookie.load('firstRun') || true,
...@@ -87,16 +95,18 @@ class App extends Component { ...@@ -87,16 +95,18 @@ class App extends Component {
}) })
this.getInfoFirstTime(); this.getInfoFirstTime();
// this.getContracts(); // this.getContracts();
this.getUserAddress(); this.getUserAddress();
this.checkNetwork(); this.checkNetwork();
this.getBlock(); this.getBlock();
} }
} }
componentDidMount(){ componentDidMount(){
if(localweb3 === 'undefined'){ if(localweb3 === 'undefined') {
this.setState({connected: false}) this.props.web3ConnectionUnsuccessful();
} else if(this.state.connected === true) { console.log('props here', this.props)
} else if(this.props.web3.connected === true) {
console.log('successfully connected to metamask')
setInterval(this.getBlock, 10000); setInterval(this.getBlock, 10000);
setInterval(this.getMarketInfo, 15000); setInterval(this.getMarketInfo, 15000);
setInterval(this.getAccountInfo, 15000); setInterval(this.getAccountInfo, 15000);
...@@ -107,48 +117,68 @@ class App extends Component { ...@@ -107,48 +117,68 @@ class App extends Component {
} }
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
console.log(nextProps) console.log('nextProps', nextProps)
} }
getInfoFirstTime = () => { getInfoFirstTime = () => {
localweb3.eth.getAccounts((error, result) => { localweb3.eth.getAccounts((error, result) => {
if(result.length > 0) console.log('getInfoFirstTime result', result)
this.setState({currentMaskAddress: result[0], locked: false, connected: true}, this.getContracts) if(result.length > 0){
else // REEEEDUUUUUUXXX
this.setState({locked: true, connected: false, interaction: 'locked'}) this.props.setCurrentMaskAddress(result[0]);
this.props.metamaskUnlocked();
this.props.web3ConnectionSuccessful();
this.getContracts();
}
else {
this.props.metamaskLocked();
this.props.web3ConnectionUnsuccessful();
this.props.setInteractionState('locked');
}
})
}
getUserAddress = () => {
// kind of redundant
// only difference is getInfoFirstTime fires getContracts too
// THIS FIRES EVERY TEN SECONDS, NEEDS A REFACTOR
localweb3.eth.getAccounts((error, result) => {
if(result.length > 0) {
this.props.setCurrentMaskAddress(result[0]);
this.props.metamaskUnlocked();
this.props.web3ConnectionSuccessful();
}
else {
this.props.metamaskLocked();
this.props.web3ConnectionUnsuccessful();
this.props.setInteractionState('locked');
}
}) })
} }
getContracts() { getContracts() {
const uniExchangeAddress = '0xcDc30C3b02c5776495298198377D2Fc0fd6B1F1C'; const uniExchangeAddress = this.props.web3.exchangeAddresses.UNI;
const uniExchangeContract = new localweb3.eth.Contract(exchangeABI, uniExchangeAddress); const uniExchangeContract = new localweb3.eth.Contract(exchangeABI, uniExchangeAddress);
this.props.uniExchangeContractReady(uniExchangeContract);
const swapExchangeAddress = '0x4632a7Cd732c625dcc48d75E289c209422e1D2B7';
const swapExchangeAddress = this.props.web3.exchangeAddresses.SWT;
const swapExchangeContract = new localweb3.eth.Contract(exchangeABI, swapExchangeAddress); const swapExchangeContract = new localweb3.eth.Contract(exchangeABI, swapExchangeAddress);
this.props.swtExchangeContractReady(swapExchangeContract);
const uniTokenAddress = '0x350E5DD084ecF271e8d3531D4324443952F47756'; const uniTokenAddress = this.props.web3.tokenAddresses.UNI;
const uniTokenContract = new localweb3.eth.Contract(tokenABI, uniTokenAddress); const uniTokenContract = new localweb3.eth.Contract(tokenABI, uniTokenAddress);
this.props.uniTokenContractReady(uniTokenContract);
const swapTokenAddress = '0x8B2A87F8243f23C33fb97E23a21Ae8EDB3b71AcA'; const swapTokenAddress = this.props.web3.tokenAddresses.SWT;
const swapTokenContract = new localweb3.eth.Contract(tokenABI, swapTokenAddress); const swapTokenContract = new localweb3.eth.Contract(tokenABI, swapTokenAddress);
this.props.swtTokenContractReady(swapTokenContract);
const factoryAddress = '0xD6D22d102A4237F3D35361BC022a78789E6174Aa'; const factoryAddress = this.props.web3.factoryAddress;
const factoryContract = new localweb3.eth.Contract(factoryABI, factoryAddress); const factoryContract = new localweb3.eth.Contract(factoryABI, factoryAddress);
this.props.factoryContractReady(factoryContract);
this.setState({ this.getInfo();
uniExchangeAddress: uniExchangeAddress,
swapExchangeAddress: swapExchangeAddress,
uniTokenAddress: uniTokenAddress,
swapTokenAddress: swapTokenAddress,
factoryAddress: factoryAddress,
uniExchange: uniExchangeContract,
uniToken: uniTokenContract,
swapExchange: swapExchangeContract,
swapToken: swapTokenContract,
factory: factoryContract,
}, this.getInfo)
} }
checkNetwork() { checkNetwork() {
...@@ -156,70 +186,73 @@ class App extends Component { ...@@ -156,70 +186,73 @@ class App extends Component {
console.log("Connected to " + networkId) console.log("Connected to " + networkId)
switch (networkId) { switch (networkId) {
case "main": case "main":
this.setState({networkMessage: 'Ethereum Mainet', connected: false, interaction: 'disconnected'}); this.props.setNetworkMessage('Ethereum Mainet');
this.props.web3ConnectionUnsuccessful();
this.props.setInteractionState('disconnected');
break; break;
case "morden": case "morden":
this.setState({networkMessage: 'Morden testnet', connected: false, interaction: 'disconnected'}); this.props.setNetworkMessage('Morden testnet');
break; this.props.web3ConnectionUnsuccessful();
this.props.setInteractionState('disconnected');
break;
case "ropsten": case "ropsten":
this.setState({networkMessage: 'Ropsten testnet', connected: false, interaction: 'disconnected'}); this.props.setNetworkMessage('Ropsten testnet');
this.props.web3ConnectionUnsuccessful();
this.props.setInteractionState('disconnected');
break; break;
case "rinkeby": case "rinkeby":
this.setState({networkMessage: 'Rinkeby testnet', connected: true, interaction: 'connected'}); this.props.setNetworkMessage('Rinkeby testnet');
this.props.web3ConnectionSuccessful();
this.props.setInteractionState('connected');
break; break;
case "kovan": case "kovan":
this.setState({networkMessage: 'Kovan testnet', connected: false, interaction: 'disconnected'}); this.props.setNetworkMessage('Kovan testnet');
this.props.web3ConnectionUnsuccessful();
this.props.setInteractionState('disconnected');
break; break;
default: default:
this.setState({networkMessage: 'an unknown network', connected: false, interaction: 'disconnected'}); this.props.setNetworkMessage('an unknown network');
this.props.web3ConnectionUnsuccessful();
this.props.setInteractionState('disconnected');
} }
}) })
} }
getBlock = () => { getBlock = () => {
localweb3.eth.getBlock('latest', (error, blockInfo) => { localweb3.eth.getBlock('latest', (error, blockInfo) => {
this.setState({blockTimestamp: blockInfo.timestamp}) this.props.setBlockTimestamp(blockInfo.timestamp);
}); });
} }
getUserAddress = () => {
localweb3.eth.getAccounts((error, result) => {
if(result.length > 0)
this.setState({currentMaskAddress: result[0], locked: false, connected: true})
else
this.setState({locked: true, connected: false, interaction: 'locked'})
})
}
symbolToTokenAddress = (symbol) => { symbolToTokenAddress = (symbol) => {
if(symbol === 'UNI') { if(symbol === 'UNI') {
return this.state.uniTokenAddress; return this.props.web3.exchangeAddresses.UNI;
} else if(symbol === 'SWAP') { } else if (symbol === 'SWAP') {
return this.state.swapTokenAddress; return this.props.web3.exchangeAddresses.SWT;
} }
} }
symbolToTokenContract = (symbol) => { symbolToTokenContract = (symbol) => {
if(symbol === 'UNI') { if(symbol === 'UNI') {
return this.state.uniToken; return this.props.tokenContracts.UNI;
} else if(symbol === 'SWAP') { } else if(symbol === 'SWAP') {
return this.state.swapToken; return this.props.tokenContracts.SWT;
} }
} }
symbolToExchangeAddress = (symbol) => { symbolToExchangeAddress = (symbol) => {
if(symbol === 'UNI') { if(symbol === 'UNI') {
return this.state.uniExchangeAddress; return this.props.web3.exchangeAddresses.UNI;
} else if(symbol === 'SWAP') { } else if(symbol === 'SWAP') {
return this.state.swapExchangeAddress; return this.props.web3.exchangeAddresses.SWT;
} }
} }
symbolToExchangeContract = (symbol) => { symbolToExchangeContract = (symbol) => {
if(symbol === 'UNI') { if(symbol === 'UNI') {
return this.state.uniExchange; return this.props.exchangeContracts.UNI;
} else if(symbol === 'SWAP') { } else if(symbol === 'SWAP') {
return this.state.swapExchange; return this.props.exchangeContracts.SWT;
} }
} }
...@@ -227,9 +260,9 @@ class App extends Component { ...@@ -227,9 +260,9 @@ class App extends Component {
this.getMarketInfo(); this.getMarketInfo();
this.getAccountInfo(); this.getAccountInfo();
} }
getMarketInfo = () => { getMarketInfo = () => {
switch (this.state.exchangeType) { switch (this.props.web3.exchangeType) {
case 'ETH to Token': case 'ETH to Token':
this.getExchangeState('output'); this.getExchangeState('output');
break; break;
...@@ -245,7 +278,7 @@ class App extends Component { ...@@ -245,7 +278,7 @@ class App extends Component {
} }
getAccountInfo = () => { getAccountInfo = () => {
switch (this.state.exchangeType) { switch (this.props.web3.exchangeType) {
case 'ETH to Token': case 'ETH to Token':
this.getEthBalance('input'); this.getEthBalance('input');
this.getTokenBalance('output'); this.getTokenBalance('output');
...@@ -267,51 +300,50 @@ class App extends Component { ...@@ -267,51 +300,50 @@ class App extends Component {
getExchangeState = (type) => { getExchangeState = (type) => {
var exchange; var exchange;
if (type === 'input') { if (type === 'input') {
exchange = this.symbolToExchangeContract(this.state.inputToken.value); exchange = this.symbolToExchangeContract(this.props.exchange.inputToken.value);
exchange.methods.invariant().call().then((result, error) => { exchange.methods.invariant().call().then((result, error) => {
this.setState({invariant1: result}); this.props.setInvariant1(result);
// console.log('Input Invariant: ' + result); // console.log('Input Invariant: ' + result);
}); });
exchange.methods.ethInMarket().call().then((result, error) => { exchange.methods.ethInMarket().call().then((result, error) => {
this.setState({marketEth1: result}); this.props.setMarketEth1(result);
// console.log('Input Market ETH: ' + result); // console.log('Input Market ETH: ' + result);
}); });
exchange.methods.tokensInMarket().call().then((result, error) => { exchange.methods.tokensInMarket().call().then((result, error) => {
this.setState({marketTokens1: result}); this.props.setMarketTokens1(result);
// console.log('Input Market Tokens: ' + result); // console.log('Input Market Tokens: ' + result);
}); });
} else if (type === 'output') { } else if (type === 'output') {
exchange = this.symbolToExchangeContract(this.state.outputToken.value); exchange = this.symbolToExchangeContract(this.props.exchange.outputToken.value);
exchange.methods.invariant().call().then((result, error) => { exchange.methods.invariant().call().then((result, error) => {
this.setState({invariant2: result}); this.props.setInvariant2(result);
// console.log('Output Invariant: ' + result); // console.log('Output Invariant: ' + result);
}); });
exchange.methods.ethInMarket().call().then((result, error) => { exchange.methods.ethInMarket().call().then((result, error) => {
this.setState({marketEth2: result}); this.props.setMarketEth2(result);
// console.log('Output Market ETH: ' + result); // console.log('Output Market ETH: ' + result);
}); });
exchange.methods.tokensInMarket().call().then((result, error) => { exchange.methods.tokensInMarket().call().then((result, error) => {
this.setState({marketTokens2: result}) this.props.setMarketTokens2(result);
// console.log('Output Market Tokens: ' + result); // console.log('Output Market Tokens: ' + result);
}); });
} }
} }
getEthBalance = (type) => { getEthBalance = (type) => {
if (type === 'input') { if (type === 'input') {
localweb3.eth.getBalance(this.state.currentMaskAddress, (error, balance) => { localweb3.eth.getBalance(this.props.web3.currentMaskAddress, (error, balance) => {
this.setState({inputBalance: balance}); this.props.setInputBalance(balance);
// console.log('ETH Balance: ' + balance); // console.log('ETH Balance: ' + balance);
}); });
} else if (type === 'output') { } else if (type === 'output') {
localweb3.eth.getBalance(this.state.currentMaskAddress, (error, balance) => { localweb3.eth.getBalance(this.props.web3.currentMaskAddress, (error, balance) => {
this.setState({outputBalance: balance}); this.props.setOutputBalance(balance);
// console.log('ETH Balance: ' + balance); // console.log('ETH Balance: ' + balance);
}); });
} }
...@@ -320,48 +352,48 @@ class App extends Component { ...@@ -320,48 +352,48 @@ class App extends Component {
getTokenBalance = (type) => { getTokenBalance = (type) => {
var token; var token;
if (type === 'input') { if (type === 'input') {
token = this.symbolToTokenContract(this.state.inputToken.value); token = this.symbolToTokenContract(this.props.exchange.inputToken.value);
token.methods.balanceOf(this.state.currentMaskAddress).call((error, balance) => { token.methods.balanceOf(this.props.web3.currentMaskAddress).call((error, balance) => {
this.setState({inputBalance: balance}); this.props.setInputBalance(balance);
// console.log(this.state.inputToken.value + ' Balance: ' + balance); // console.log(this.props.exchange.inputToken.value + ' Balance: ' + balance);
}); });
} else if (type === 'output') { } else if (type === 'output') {
token = this.symbolToTokenContract(this.state.outputToken.value); token = this.symbolToTokenContract(this.props.exchange.outputToken.value);
token.methods.balanceOf(this.state.currentMaskAddress).call((error, balance) => { token.methods.balanceOf(this.props.web3.currentMaskAddress).call((error, balance) => {
this.setState({outputBalance: balance}); this.props.setOutputBalance(balance);
// console.log(this.state.outputToken.value + ' Balance: ' + balance); // console.log(this.props.exchange.outputToken.value + ' Balance: ' + balance);
}); });
} }
} }
getAllowance = () => { getAllowance = () => {
var type = this.state.exchangeType; var type = this.props.web3.exchangeType;
if(type === 'Token to ETH' || type === 'Token to Token') { if(type === 'Token to ETH' || type === 'Token to Token') {
var token = this.symbolToTokenContract(this.state.inputToken.value); var token = this.symbolToTokenContract(this.props.exchange.inputToken.value);
var exchangeAddress = this.symbolToExchangeAddress(this.state.inputToken.value); var exchangeAddress = this.symbolToExchangeAddress(this.props.exchange.inputToken.value);
token.methods.allowance(this.state.currentMaskAddress, exchangeAddress).call().then((result, error) => { token.methods.allowance(this.props.web3.currentMaskAddress, exchangeAddress).call().then((result, error) => {
console.log(this.state.inputToken.value + ' allowance: ' + result); console.log(this.props.exchange.inputToken.value + ' allowance: ' + result);
if(result === '0'){ if(result === '0'){
this.setState({approved: false}) this.props.setAllowanceApprovalState(false)
console.log(this.state.approved) console.log(this.props.exchange.allowanceApproved)
} }
}) })
} }
} }
approveAllowance = () => { approveAllowance = () => {
var type = this.state.exchangeType; var type = this.props.web3.exchangeType;
if(type === 'Token to ETH' || type === 'Token to Token') { if(type === 'Token to ETH' || type === 'Token to Token') {
var token = this.symbolToTokenContract(this.state.inputToken.value); var token = this.symbolToTokenContract(this.props.exchange.inputToken.value);
var exchangeAddress = this.symbolToExchangeAddress(this.state.inputToken.value); var exchangeAddress = this.symbolToExchangeAddress(this.props.exchange.inputToken.value);
var amount = localweb3.utils.toWei('100000'); var amount = localweb3.utils.toWei('100000');
token.methods.approve(exchangeAddress, amount).send({from: this.state.currentMaskAddress}) token.methods.approve(exchangeAddress, amount).send({from: this.props.web3.currentMaskAddress})
.on('transactionHash', console.log('Transaction Hash created')) .on('transactionHash', console.log('Transaction Hash created'))
.on('receipt', (receipt) => { .on('receipt', (receipt) => {
console.log(receipt) console.log(receipt)
this.setState({approved: true}) this.props.setAllowanceApprovalState(true);
}) //Transaction Submitted to blockchain }) //Transaction Submitted to blockchain
.on('confirmation', (confirmationNumber, receipt) => {console.log("Block Confirmations: " + confirmationNumber)}) //Transaction Mined .on('confirmation', (confirmationNumber, receipt) => {console.log("Block Confirmations: " + confirmationNumber)}) //Transaction Mined
.on('error', console.error); .on('error', console.error);
...@@ -369,85 +401,97 @@ class App extends Component { ...@@ -369,85 +401,97 @@ class App extends Component {
} }
tokenToExchangeFactoryLookup = (tokenAddress) => { tokenToExchangeFactoryLookup = (tokenAddress) => {
this.state.factory.methods.tokenToExchangeLookup(tokenAddress).call((error, exchangeAddress) => { this.props.web3.factoryContract.methods.tokenToExchangeLookup(tokenAddress).call((error, exchangeAddress) => {
console.log(exchangeAddress) console.log(exchangeAddress)
}); });
} }
onSelectToken = (selected, type) => { onSelectToken = (selected, type) => {
this.setState({input: 0, output:0, rate:0, fee: 0, interaction: 'connected', firstRun: true}) this.props.setExchangeInputValue(0);
this.props.setExchangeOutputValue(0);
this.props.setExchangeRate(0);
this.props.setExchangeFee(0);
this.props.setInteractionState('connected');
this.setState({ firstRun: true })
var marketType = ''; var marketType = '';
if (type === 'input') { if (type === 'input') {
this.setState({inputToken: selected}); this.props.setInputToken(selected);
if (selected.value === this.state.outputToken.value) { if (selected.value === this.props.exchange.outputToken.value) {
marketType = 'Invalid'; marketType = 'Invalid';
this.setState({interaction: 'error1'}); this.props.setInteractionState('error1');
} else if (selected.value === 'ETH'){ } else if (selected.value === 'ETH'){
marketType = 'ETH to Token'; marketType = 'ETH to Token';
} else if (this.state.outputToken.value === 'ETH'){ } else if (this.props.exchange.outputToken.value === 'ETH'){
marketType = 'Token to ETH'; marketType = 'Token to ETH';
} else{ } else{
marketType = 'Token to Token'; marketType = 'Token to Token';
} }
} else if (type === 'output'){ } else if (type === 'output'){
this.setState({outputToken: selected}); this.props.setOutputToken(selected);
if (selected.value === this.state.inputToken.value) { if (selected.value === this.props.exchange.inputToken.value) {
marketType = 'Invalid'; marketType = 'Invalid';
this.setState({interaction: 'error1'}); this.props.setInteractionState('error1');
} else if (selected.value === 'ETH'){ } else if (selected.value === 'ETH'){
marketType = 'Token to ETH'; marketType = 'Token to ETH';
} else if (this.state.inputToken.value === 'ETH'){ } else if (this.props.exchange.inputToken.value === 'ETH'){
marketType = 'ETH to Token'; marketType = 'ETH to Token';
} else{ } else {
marketType = 'Token to Token'; marketType = 'Token to Token';
} }
} }
console.log(type + ': ' + selected.value); console.log(type + ': ' + selected.value);
this.setState({exchangeType: marketType}, this.getInfo); this.props.setExchangeType(marketType);
this.getInfo();
} }
onInputChange = (event) => { onInputChange = (event) => {
var inputValue = event.target.value; var inputValue = event.target.value;
var marketType = this.state.exchangeType; var marketType = this.props.web3.exchangeType;
if (marketType === 'Invalid'){ if (marketType === 'Invalid'){
this.setState({input: inputValue, output: 0, interaction: 'error1'}); this.props.setExchangeInputValue(inputValue);
this.props.setExchangeOutputValue(0);
this.props.setInteractionState('error1');
} else if(inputValue && inputValue !== 0 && inputValue !== '0'){ } else if(inputValue && inputValue !== 0 && inputValue !== '0'){
this.setState({input: inputValue, interaction: 'input'}); this.props.setExchangeInputValue(inputValue);
console.log('input something') this.props.setInteractionState('input');
console.log('input something');
this.getExchangeRate(inputValue); this.getExchangeRate(inputValue);
} else { } else {
this.setState({input: inputValue, output: 0, interaction: 'connected'}); this.props.setExchangeInputValue(inputValue);
this.props.setExchangeOutputValue(0);
this.props.setInteractionState('connected');
} }
} }
getExchangeRate = (input) => { getExchangeRate = (input) => {
if (this.state.exchangeType === 'ETH to Token') { if (this.props.web3.exchangeType === 'ETH to Token') {
console.log('Getting Rate: ETH to ' + this.state.outputToken.value); console.log('Getting Rate: ETH to ' + this.props.exchange.outputToken.value);
this.ethToTokenRate(input); this.ethToTokenRate(input);
} else if (this.state.exchangeType === 'Token to ETH') { } else if (this.props.web3.exchangeType === 'Token to ETH') {
console.log('Getting Rate: ' + this.state.inputToken.value + ' to ETH'); console.log('Getting Rate: ' + this.props.exchange.inputToken.value + ' to ETH');
this.tokenToEthRate(input); this.tokenToEthRate(input);
} else if (this.state.exchangeType === 'Token to Token') { } else if (this.props.web3.exchangeType === 'Token to Token') {
console.log('Getting Rate: ' + this.state.inputToken.value + ' to ' + this.state.outputToken.value); console.log('Getting Rate: ' + this.props.exchange.inputToken.value + ' to ' + this.props.exchange.outputToken.value);
this.tokenToTokenRate(input); this.tokenToTokenRate(input);
} }
} }
purchaseTokens = () => { purchaseTokens = () => {
if (this.state.exchangeType === 'ETH to Token') { if (this.props.web3.exchangeType === 'ETH to Token') {
this.ethToTokenPurchase(); this.ethToTokenPurchase();
} else if (this.state.exchangeType === 'Token to ETH') { } else if (this.props.web3.exchangeType === 'Token to ETH') {
this.tokenToEthPurchase(); this.tokenToEthPurchase();
} else if (this.state.exchangeType === 'Token to Token') { } else if (this.props.web3.exchangeType=== 'Token to Token') {
this.tokenToTokenPurchase(); this.tokenToTokenPurchase();
} }
} }
ethToTokenRate = (ethInput) => { ethToTokenRate = (ethInput) => {
var ethInMarket = +this.state.marketEth2; var ethInMarket = +this.props.exchange.marketEth2;
var tokensInMarket = +this.state.marketTokens2; var tokensInMarket = +this.props.exchange.marketTokens2;
var invar = +this.state.invariant2; var invar = +this.props.exchange.invariant2;
var ethIn = ethInput*10**18; var ethIn = ethInput*10**18;
var exchangeFee = ethIn/500; var exchangeFee = ethIn/500;
var ethSold = ethIn - exchangeFee; var ethSold = ethIn - exchangeFee;
...@@ -456,16 +500,15 @@ class App extends Component { ...@@ -456,16 +500,15 @@ class App extends Component {
var tokensOut = tokensInMarket - newTokensInMarket; var tokensOut = tokensInMarket - newTokensInMarket;
var adjustedTokensOut = tokensOut * 0.98; var adjustedTokensOut = tokensOut * 0.98;
var buyRate = adjustedTokensOut/ethIn; var buyRate = adjustedTokensOut/ethIn;
this.setState({rate: buyRate, this.props.setExchangeRate(buyRate);
fee: exchangeFee, this.props.setExchangeFee(exchangeFee);
output: adjustedTokensOut this.props.setExchangeOutputValue(adjustedTokensOut);
});
} }
tokenToEthRate = (tokenInput) => { tokenToEthRate = (tokenInput) => {
var ethInMarket = +this.state.marketEth1; var ethInMarket = +this.props.exchange.marketEth1;
var tokensInMarket = +this.state.marketTokens1; var tokensInMarket = +this.props.exchange.marketTokens1;
var invar = +this.state.invariant1; var invar = +this.props.exchange.invariant1;
var tokensIn = tokenInput*10**18; var tokensIn = tokenInput*10**18;
var exchangeFee = tokensIn/500; var exchangeFee = tokensIn/500;
var tokensSold = tokensIn - exchangeFee; var tokensSold = tokensIn - exchangeFee;
...@@ -474,17 +517,16 @@ class App extends Component { ...@@ -474,17 +517,16 @@ class App extends Component {
var ethOut = ethInMarket - newEthInMarket; var ethOut = ethInMarket - newEthInMarket;
var adjustedEthOut = ethOut * 0.98; var adjustedEthOut = ethOut * 0.98;
var buyRate = adjustedEthOut/tokensIn; var buyRate = adjustedEthOut/tokensIn;
this.setState({rate: buyRate, this.props.setExchangeRate(buyRate);
fee: exchangeFee, this.props.setExchangeFee(exchangeFee);
output: adjustedEthOut this.props.setExchangeOutputValue(adjustedEthOut);
});
} }
tokenToTokenRate = (tokenInput) => { tokenToTokenRate = (tokenInput) => {
// Token to ETH on Exchange 1 // Token to ETH on Exchange 1
var ethInMarket1 = +this.state.marketEth1; var ethInMarket1 = +this.props.exchange.marketEth1;
var tokensInMarket1 = +this.state.marketTokens1; var tokensInMarket1 = +this.props.exchange.marketTokens1;
var invar1 = +this.state.invariant1; var invar1 = +this.props.exchange.invariant1;
var tokensIn = tokenInput*10**18; var tokensIn = tokenInput*10**18;
var exchangeFee1 = tokensIn/500; var exchangeFee1 = tokensIn/500;
var tokensSold = tokensIn - exchangeFee1; var tokensSold = tokensIn - exchangeFee1;
...@@ -492,9 +534,9 @@ class App extends Component { ...@@ -492,9 +534,9 @@ class App extends Component {
var newEthInMarket1 = invar1/newTokensInMarket1; var newEthInMarket1 = invar1/newTokensInMarket1;
var ethToExchange2 = ethInMarket1 - newEthInMarket1; var ethToExchange2 = ethInMarket1 - newEthInMarket1;
// ETH to Token on Exchange 2 // ETH to Token on Exchange 2
var ethInMarket2 = +this.state.marketEth2; var ethInMarket2 = +this.props.exchange.marketEth2;
var tokensInMarket2 = +this.state.marketTokens2; var tokensInMarket2 = +this.props.exchange.marketTokens2;
var invar2 = +this.state.invariant2; var invar2 = +this.props.exchange.invariant2;
var exchangeFee2 = ethToExchange2/500; var exchangeFee2 = ethToExchange2/500;
var ethSold = ethToExchange2 - exchangeFee2; var ethSold = ethToExchange2 - exchangeFee2;
var newEthInMarket2 = ethInMarket2 + ethSold; var newEthInMarket2 = ethInMarket2 + ethSold;
...@@ -502,27 +544,31 @@ class App extends Component { ...@@ -502,27 +544,31 @@ class App extends Component {
var tokensOut = tokensInMarket2 - newTokensInMarket2; var tokensOut = tokensInMarket2 - newTokensInMarket2;
var adjustedTokensOut = tokensOut * 0.98; var adjustedTokensOut = tokensOut * 0.98;
var buyRate = adjustedTokensOut/tokensIn; var buyRate = adjustedTokensOut/tokensIn;
this.setState({rate: buyRate, this.props.setExchangeRate(buyRate);
fee: exchangeFee1, this.props.setExchangeFee(exchangeFee1);
output: adjustedTokensOut this.props.setExchangeOutputValue(adjustedTokensOut);
});
} }
// YOU ARE HERE NOW
ethToTokenPurchase = () => { ethToTokenPurchase = () => {
var exchange = this.symbolToExchangeContract(this.state.outputToken.value); var exchange = this.symbolToExchangeContract(this.props.exchange.outputToken.value);
var minTokens = (this.state.output/10**18).toString(); var minTokens = (this.props.exchange.outputValue/10**18).toString();
var minTokensInt = localweb3.utils.toWei(minTokens); var minTokensInt = localweb3.utils.toWei(minTokens);
var ethSold = this.state.input; var ethSold = this.props.exchange.inputValue;
var weiSold = localweb3.utils.toWei(ethSold); var weiSold = localweb3.utils.toWei(ethSold);
var timeout = this.state.blockTimestamp + 300; //current block time + 5mins var timeout = this.props.web3.blockTimestamp + 300; //current block time + 5mins
console.log(minTokensInt, weiSold, timeout); console.log(minTokensInt, weiSold, timeout);
exchange.methods.ethToTokenSwap(minTokensInt, timeout).send({from: this.state.currentMaskAddress, value: weiSold}) exchange.methods.ethToTokenSwap(minTokensInt, timeout).send({from: this.props.web3.currentMaskAddress, value: weiSold})
.on('transactionHash', (result) => { .on('transactionHash', (result) => {
console.log('Transaction Hash created') console.log('Transaction Hash created')
let transactions = this.state.transactions let transactions = this.state.transactions
transactions.push(result) transactions.push(result);
this.setState({transactions: transactions, input: '', output: '', interaction: 'submitted'}) // transactions is cookie stuff, we'll keep that in state
this.setState({ transactions: transactions })
// any particular reason why there are initialized as 0, but get turned to empty strings after the transaction is over?
this.props.setExchangeInputValue('');
this.props.setExchangeOutputValue('');
this.props.setInteractionState('submitted');
cookie.save('transactions', transactions, { path: '/' }) cookie.save('transactions', transactions, { path: '/' })
}) })
.on('receipt', (receipt) => { .on('receipt', (receipt) => {
...@@ -533,21 +579,25 @@ class App extends Component { ...@@ -533,21 +579,25 @@ class App extends Component {
}) //Transaction Mined }) //Transaction Mined
.on('error', console.error); .on('error', console.error);
} }
// tokenToEth and EthToToken purchase functions are very similar structurally
// maybe we can make this more DRY in refactor
tokenToEthPurchase = () => { tokenToEthPurchase = () => {
var exchange = this.symbolToExchangeContract(this.state.inputToken.value); var exchange = this.symbolToExchangeContract(this.props.exchange.inputToken.value);
var minEth = (this.state.output/10**18).toString(); var minEth = (this.props.exchange.outputValue/10**18).toString();
var minEthInt = localweb3.utils.toWei(minEth); var minEthInt = localweb3.utils.toWei(minEth);
var tokensSold = this.state.input; var tokensSold = this.props.exchange.inputValue;
var tokensSoldInt = localweb3.utils.toWei(tokensSold); var tokensSoldInt = localweb3.utils.toWei(tokensSold);
var timeout = this.state.blockTimestamp + 300; //current block time + 5mins var timeout = this.props.web3.blockTimestamp + 300; //current block time + 5mins
exchange.methods.tokenToEthSwap(tokensSoldInt, minEthInt, timeout).send({from: this.state.currentMaskAddress}) exchange.methods.tokenToEthSwap(tokensSoldInt, minEthInt, timeout).send({from: this.props.web3.currentMaskAddress})
.on('transactionHash', (result) => { .on('transactionHash', (result) => {
console.log('Transaction Hash created') console.log('Transaction Hash created')
let transactions = this.state.transactions let transactions = this.state.transactions
transactions.push(result) transactions.push(result)
this.setState({transactions: transactions, input: '', output: '', interaction: 'submitted'}) this.setState({ transactions: transactions });
this.props.setExchangeInputValue('');
this.props.setExchangeOutputValue('');
this.props.setInteractionState('submitted');
cookie.save('transactions', transactions, { path: '/' }) cookie.save('transactions', transactions, { path: '/' })
}) })
.on('receipt', (receipt) => {console.log(receipt)}) //Transaction Submitted to blockchain .on('receipt', (receipt) => {console.log(receipt)}) //Transaction Submitted to blockchain
...@@ -556,20 +606,23 @@ class App extends Component { ...@@ -556,20 +606,23 @@ class App extends Component {
} }
tokenToTokenPurchase = () => { tokenToTokenPurchase = () => {
var exchange = this.symbolToExchangeContract(this.state.inputToken.value); var exchange = this.symbolToExchangeContract(this.props.exchange.inputToken.value);
var tokenOutAddress = this.symbolToTokenAddress(this.state.outputToken.value); var tokenOutAddress = this.symbolToTokenAddress(this.props.exchange.outputToken.value);
var minTokens = (this.state.output/10**18).toString(); var minTokens = (this.props.exchange.outputValue/10**18).toString();
var minTokensInt = localweb3.utils.toWei(minTokens); var minTokensInt = localweb3.utils.toWei(minTokens);
var tokensSold = this.state.input; var tokensSold = this.props.exchange.inputValue;
var tokensSoldInt = localweb3.utils.toWei(tokensSold); var tokensSoldInt = localweb3.utils.toWei(tokensSold);
var timeout = this.state.blockTimestamp + 300; //current block time + 5mins var timeout = this.props.web3.blockTimestamp + 300; //current block time + 5mins
exchange.methods.tokenToTokenSwap(tokenOutAddress, tokensSoldInt, minTokensInt, timeout).send({from: this.state.currentMaskAddress}) exchange.methods.tokenToTokenSwap(tokenOutAddress, tokensSoldInt, minTokensInt, timeout).send({from: this.props.web3.currentMaskAddress})
.on('transactionHash', (result) => { .on('transactionHash', (result) => {
console.log('Transaction Hash created') console.log('Transaction Hash created')
let transactions = this.state.transactions let transactions = this.state.transactions
transactions.push(result) transactions.push(result)
this.setState({transactions: transactions, input: '', output: '', interaction: 'submitted'}) this.setState({ transactions: transactions });
this.props.setExchangeInputValue('');
this.props.setExchangeOutputValue('');
this.props.setInteractionState('submitted');
cookie.save('transactions', transactions, { path: '/' }) cookie.save('transactions', transactions, { path: '/' })
}) })
.on('receipt', (receipt) => {console.log(receipt)}) //Transaction Submitted to blockchain .on('receipt', (receipt) => {console.log(receipt)}) //Transaction Submitted to blockchain
...@@ -578,96 +631,100 @@ class App extends Component { ...@@ -578,96 +631,100 @@ class App extends Component {
} }
onCloseHelper = () => { onCloseHelper = () => {
if(this.state.outputToken.value === 'UNI'){ if(this.props.exchange.outputToken.value === 'UNI'){
this.setState({uniAdded: true}) this.setState({ uniAdded: true }) // cookie stuff
cookie.save('uniAdded', true, { path: '/' }) cookie.save('uniAdded', true, { path: '/' })
} else if(this.state.outputToken.value === 'SWAP'){ } else if(this.props.exchange.outputToken.value === 'SWAP'){
this.setState({swapAdded: true}) this.setState({ swapAdded: true }) // more cookie stuff
cookie.save('swapAdded', true, { path: '/' }) cookie.save('swapAdded', true, { path: '/' })
} else { } else {
this.setState({firstRun: !this.state.firstRun}) this.setState({ firstRun: !this.state.firstRun }) // also cookie stuff
cookie.save('firstRun', !this.state.firstRun, { path: '/' }) cookie.save('firstRun', !this.state.firstRun, { path: '/' })
} }
} }
toggleAbout = () => { toggleAbout = () => {
this.setState({about: !this.state.about}) this.setState({about: !this.state.about})
setTimeout(this.scrollToAbout, 300) setTimeout(this.scrollToAbout, 300);
} }
scrollToAbout = () => { scrollToAbout = () => {
scrollToComponent(this.About, { offset: 0, align: 'top', duration: 500}) scrollToComponent(this.About, { offset: 0, align: 'top', duration: 500})
} }
render() { render() {
return ( return (
<div className={this.state.connected && !this.state.locked && this.state.interaction !== 'disconnected' ? "App" : "App dim"}> <div className={this.props.web3.connected && !this.props.web3.metamaskLocked && this.props.web3.interaction !== 'disconnected' ? "App" : "App dim"}>
<Head /> <Head />
<section className="title"> <section className="title">
<div className="logo border pa2"> <div className="logo border pa2">
<span role="img" aria-label="Unicorn">🦄</span> <span role="img" aria-label="Unicorn">🦄</span>
</div> </div>
<NetworkStatus <NetworkStatus
network={this.state.networkMessage} network={this.props.web3.networkMessage}
connected={this.state.connected} connected={this.props.web3.connected}
metamask={this.props.metamask} metamask={this.props.metamask}
interaction={this.state.interaction} interaction={this.props.web3.interaction}
address={this.state.currentMaskAddress} address={this.props.web3.currentMaskAddress}
locked={this.state.locked} locked={this.props.web3.metamaskLocked}
balance={this.state.inputBalance}/> balance={this.props.exchange.inputBalance}/>
</section> </section>
<ConnectionHelper <ConnectionHelper
network={this.state.networkMessage} network={this.props.web3.networkMessage}
connected={this.state.connected} connected={this.props.web3.connected}
metamask={this.props.metamask} metamask={this.props.metamask}
address={this.state.currentMaskAddress} address={this.props.web3.currentMaskAddress}
locked={this.state.locked} locked={this.props.web3.metamaskLocked}
approved={this.state.approved} approved={this.props.exchange.allowanceApproved}
tokenAdded={this.state.tokenAdded} tokenAdded={this.state.tokenAdded}
approveAllowance={this.approveAllowance} approveAllowance={this.approveAllowance}
interaction={this.state.interaction} interaction={this.props.web3.interaction}
exchangeType={this.state.exchangeType} exchangeType={this.props.web3.exchangeType}
firstRun={this.state.firstRun} firstRun={this.state.firstRun}
uniAdded={this.state.uniAdded} uniAdded={this.state.uniAdded}
swapAdded={this.state.swapAdded} swapAdded={this.state.swapAdded}
onCloseHelper={this.onCloseHelper} onCloseHelper={this.onCloseHelper}
input={this.state.input} input={this.props.exchange.inputValue}
balance={this.state.inputBalance} balance={this.props.exchange.inputBalance}
toggleAbout={this.toggleAbout} toggleAbout={this.toggleAbout}
inputToken={this.state.inputToken} inputToken={this.props.exchange.inputToken}
outputToken={this.state.outputToken} outputToken={this.props.exchange.outputToken}
about={this.state.about} about={this.state.about}
/> />
<section className="candlestick">
<Candlesticks />
</section>
<section className="order"> <section className="order">
<div className="value border pa2"> <div className="value border pa2">
<input type="number" value={this.state.input} placeholder="0" onChange={this.onInputChange} /> <input type="number" value={this.props.exchange.inputValue} placeholder="0" onChange={this.onInputChange} />
<SelectToken token={this.state.inputToken} onSelectToken={this.onSelectToken} type="input" /> <SelectToken token={this.props.exchange.inputToken} onSelectToken={this.onSelectToken} type="input" />
<p className="dropdown">{'<'}</p> <p className="dropdown">{'<'}</p>
</div> </div>
<div className="arrow border pa2"> <div className="arrow border pa2">
<p></p> <p></p>
</div> </div>
<div className="value border pa2"> <div className="value border pa2">
<input type="number" readOnly={true} value={(this.state.output/10**18).toFixed(5)} placeholder="0"/> <input type="number" readOnly={true} value={(this.props.exchange.outputValue/10**18).toFixed(5)} placeholder="0"/>
<SelectToken token={this.state.outputToken} onSelectToken={this.onSelectToken} type="output"/> <SelectToken token={this.props.exchange.outputToken} onSelectToken={this.onSelectToken} type="output"/>
<p className="dropdown">{'<'}</p> <p className="dropdown">{'<'}</p>
</div> </div>
</section> </section>
<section className="rate border pa2"> <section className="rate border pa2">
<span className="rate-info"> <span className="rate-info">
<p>Rate</p> <p>Rate</p>
<p>{(this.state.rate).toFixed(5)} {this.state.outputToken.value + "/" + this.state.inputToken.value}</p> <p>{(this.props.exchange.rate).toFixed(5)} {this.props.exchange.outputToken.value + "/" + this.props.exchange.inputToken.value}</p>
</span> </span>
<span className="rate-info"> <span className="rate-info">
<p>Fee</p> <p>Fee</p>
<p>{(this.state.fee/10**18).toFixed(5)} {this.state.inputToken.value}</p> <p>{(this.props.exchange.fee/10**18).toFixed(5)} {this.props.exchange.inputToken.value}</p>
</span> </span>
</section> </section>
{this.state.interaction === 'input' ? {this.props.web3.interaction === 'input' ?
<a className="swap border pa2" role="button" onClick={() => {this.purchaseTokens()}}> <a className="swap border pa2" role="button" onClick={() => {this.purchaseTokens()}}>
<b>{"I want to swap " + this.state.input + " " + this.state.inputToken.value + " for " + this.state.output/10**18 + " " + this.state.outputToken.value}</b> <b>{"I want to swap " + this.props.exchange.inputValue + " " + this.props.exchange.inputToken.value + " for " + this.props.exchange.outputValue/10**18 + " " + this.props.exchange.outputToken.value}</b>
{/* <button> Approve </button> */} {/* <button> Approve </button> */}
</a> </a>
: <a className="swap grey-bg hidden border pa2"></a>} : <a className="swap grey-bg hidden border pa2"></a>}
...@@ -701,7 +758,7 @@ class App extends Component { ...@@ -701,7 +758,7 @@ class App extends Component {
</a> </a>
</section> </section>
{this.state.transactions.length > 0 && this.state.interaction !== 'disconnected' ? {this.state.transactions.length > 0 && this.props.web3.interaction !== 'disconnected' ?
<section className="transaction border pa2"> <section className="transaction border pa2">
<p className="underline">Past Transactions:</p> <p className="underline">Past Transactions:</p>
<Transactions transactions={this.state.transactions}/> <Transactions transactions={this.state.transactions}/>
...@@ -712,4 +769,45 @@ class App extends Component { ...@@ -712,4 +769,45 @@ class App extends Component {
} }
} }
export default App; const mapStateToProps = state => ({
web3: state.web3,
exchangeContracts: state.exchangeContracts,
tokenContracts: state.tokenContracts,
exchange: state.exchange
});
const mapDispatchToProps = (dispatch) => {
return bindActionCreators({
web3ConnectionSuccessful,
web3ConnectionUnsuccessful,
setCurrentMaskAddress,
metamaskLocked,
metamaskUnlocked,
setInteractionState,
factoryContractReady,
uniExchangeContractReady,
swtExchangeContractReady,
uniTokenContractReady,
swtTokenContractReady,
setNetworkMessage,
setBlockTimestamp,
setExchangeType,
setInputBalance,
setOutputBalance,
setInputToken,
setOutputToken,
setInvariant1,
setInvariant2,
setMarketEth1,
setMarketEth2,
setMarketTokens1,
setMarketTokens2,
setAllowanceApprovalState,
setExchangeInputValue,
setExchangeOutputValue,
setExchangeRate,
setExchangeFee
}, dispatch)
}
export default connect(mapStateToProps, mapDispatchToProps)(App);
import {
SET_INPUT_BALANCE,
SET_OUTPUT_BALANCE,
SET_INPUT_TOKEN,
SET_OUTPUT_TOKEN,
SET_INVARIANT_1,
SET_INVARIANT_2,
SET_MARKET_ETH_1,
SET_MARKET_ETH_2,
SET_MARKET_TOKENS_1,
SET_MARKET_TOKENS_2,
SET_ALLOWANCE_APPROVAL_STATE,
SET_EXCHANGE_INPUT_VALUE,
SET_EXCHANGE_OUTPUT_VALUE,
SET_EXCHANGE_RATE,
SET_EXCHANGE_FEE
} from '../constants';
export const setInputBalance = (inputBalance) => ({
type: SET_INPUT_BALANCE,
inputBalance
});
export const setOutputBalance = (outputBalance) => ({
type: SET_OUTPUT_BALANCE,
outputBalance
})
export const setInputToken = (inputToken) => ({
type: SET_INPUT_TOKEN,
inputToken
});
export const setOutputToken = (outputToken) => ({
type: SET_OUTPUT_TOKEN,
outputToken
});
export const setInvariant1 = (invariant1) => ({
type: SET_INVARIANT_1,
invariant1
});
export const setInvariant2 = (invariant2) => ({
type: SET_INVARIANT_2,
invariant2
});
export const setMarketEth1 = (marketEth1) => ({
type: SET_MARKET_ETH_1,
marketEth1
});
export const setMarketEth2 = (marketEth2) => ({
type: SET_MARKET_ETH_2,
marketEth2
});
export const setMarketTokens1 = (marketTokens1) => ({
type: SET_MARKET_TOKENS_1,
marketTokens1
});
export const setMarketTokens2 = (marketTokens2) => ({
type: SET_MARKET_TOKENS_2,
marketTokens2
});
export const setAllowanceApprovalState = (allowanceApproved) => ({
type: SET_ALLOWANCE_APPROVAL_STATE,
allowanceApproved
});
export const setExchangeInputValue = (inputValue) => ({
type: SET_EXCHANGE_INPUT_VALUE,
inputValue
});
export const setExchangeOutputValue = (outputValue) => ({
type: SET_EXCHANGE_OUTPUT_VALUE,
outputValue
});
export const setExchangeRate = (rate) => ({
type: SET_EXCHANGE_RATE,
rate
})
export const setExchangeFee = (fee) => ({
type: SET_EXCHANGE_FEE,
fee
})
\ No newline at end of file
import {
UNI_EXCHANGE_CONTRACT_READY,
SWT_EXCHANGE_CONTRACT_READY
} from '../constants';
export const uniExchangeContractReady = (contract) => ({
type: UNI_EXCHANGE_CONTRACT_READY,
contract
});
export const swtExchangeContractReady = (contract) => ({
type: SWT_EXCHANGE_CONTRACT_READY,
contract
});
\ No newline at end of file
import {
UNI_TOKEN_CONTRACT_READY,
SWT_TOKEN_CONTRACT_READY
} from '../constants';
export const uniTokenContractReady = (contract) => ({
type: UNI_TOKEN_CONTRACT_READY,
contract
});
export const swtTokenContractReady = (contract) => ({
type: SWT_TOKEN_CONTRACT_READY,
contract
});
\ No newline at end of file
import {
WEB3_CONNECTION_SUCCESSFUL,
WEB3_CONNECTION_UNSUCCESSFUL,
SET_CURRENT_MASK_ADDRESS,
METAMASK_LOCKED,
METAMASK_UNLOCKED,
SET_INTERACTION_STATE,
FACTORY_CONTRACT_READY,
SET_NETWORK_MESSAGE,
SET_BLOCK_TIMESTAMP,
SET_EXCHANGE_TYPE
} from '../constants';
// this actions folder is actually full of action creators
// your asynchronous calls are going to be in redux-thunk style action creators
export const web3ConnectionSuccessful = () => ({
type: WEB3_CONNECTION_SUCCESSFUL,
connected: true
});
export const web3ConnectionUnsuccessful = () => ({
type: WEB3_CONNECTION_UNSUCCESSFUL,
connected: false
});
export const setCurrentMaskAddress = (currentMaskAddress) => ({
type: SET_CURRENT_MASK_ADDRESS,
currentMaskAddress
});
export const metamaskLocked = () => ({
type: METAMASK_LOCKED,
metamaskLocked: true
});
export const metamaskUnlocked = () => ({
type: METAMASK_UNLOCKED,
metamaskLocked: false
});
export const setInteractionState = (interaction) => ({
type: SET_INTERACTION_STATE,
interaction
});
export const factoryContractReady = (factoryContract) => ({
type: FACTORY_CONTRACT_READY,
factoryContract
});
export const setNetworkMessage = (networkMessage) => ({
type: SET_NETWORK_MESSAGE,
networkMessage
});
export const setBlockTimestamp = (timestamp) => ({
type: SET_BLOCK_TIMESTAMP,
timestamp
});
export const setExchangeType = (exchangeType) => ({
type: SET_EXCHANGE_TYPE,
exchangeType
});
import React, { Component } from 'react';
import * as d3 from 'd3';
import axios from 'axios';
class Candlesticks extends Component {
constructor (props) {
super(props);
this.state = {
data: null
}
this.visualizeData.bind(this)
}
// note, this url is being used for development
// the actual url will be wherever the API is hosted
componentDidMount() {
let query = `{
Event(input:"UNI") {
ethValueOfToken
createdAt
}
}`;
axios.get('http://localhost:3000/graphql', { params: { query: query } })
.then(data => this.setState({data: data.data.data.Event}))
.then(()=> this.visualizeData())
.catch(err => console.error(err));
}
visualizeData() {
let svg = d3.select('svg');
let coeff = 1000 * 60 * 15
let nested_date = d3.nest()
.key((d) => new Date (Math.round(new Date(d.createdAt).getTime() / coeff) * coeff))
.sortValues()
.entries(this.state.data)
console.log(nested_date, 'something better happen here')
// var enter = svg.selectAll('rect')
// .data(this.state.data)
// .enter()
// .append('rect')
}
render() {
return (
<svg>
</svg>
)
}
}
export default Candlesticks;
\ No newline at end of file
// here is where we put the string literals for the actions
// maybe there's an action to see if you've been connected to web3
// web3 actions, all set from action creator to reducer to app
export const CHECK_WEB3_CONNECTION = 'CHECK_WEB3_CONNECTION';
export const WEB3_CONNECTION_SUCCESSFUL = 'WEB3_CONNECTION_SUCCESSFUL';
export const WEB3_CONNECTION_UNSUCCESSFUL = 'WEB3_CONNECTION_UNSUCCESSFUL';
export const SET_CURRENT_MASK_ADDRESS = 'SET_CURRENT_MASK_ADDRESS';
export const METAMASK_LOCKED = 'METAMASK_LOCKED';
export const METAMASK_UNLOCKED = 'METAMASK_UNLOCKED';
export const SET_INTERACTION_STATE = 'SET_INTERACTION_STATE';
export const SET_NETWORK_MESSAGE = 'SET_NETWORK_MESSAGE';
export const SET_BLOCK_TIMESTAMP = 'SET_BLOCK_TIMESTAMP';
export const SET_EXCHANGE_TYPE = 'SET_EXCHANGE_TYPE';
// factory contract action, also set
export const FACTORY_CONTRACT_READY = 'FACTORY_CONTRACT_READY';
// token EXCHANGE contract actions, in action creator, reducer, and app
export const UNI_EXCHANGE_CONTRACT_READY = 'UNI_EXCHANGE_CONTRACT_READY';
export const SWT_EXCHANGE_CONTRACT_READY = 'SWT_EXCHANGE_CONTRACT_READY';
// token CONTRACT actions in actions, action creator, reducer
export const UNI_TOKEN_CONTRACT_READY = 'UNI_TOKEN_CONTRACT_READY';
export const SWT_TOKEN_CONTRACT_READY = 'SWT_TOKEN_CONTRACT_READY';
// actions for the exchange, all in one place
export const SET_INPUT_BALANCE = 'SET_INPUT_BALANCE';
export const SET_OUTPUT_BALANCE = 'SET_OUTPUT_BALANCE';
export const SET_INPUT_TOKEN = 'SET_INPUT_TOKEN';
export const SET_OUTPUT_TOKEN = 'SET_OUTPUT_TOKEN';
export const SET_INVARIANT_1 = 'SET_INVARIANT_1';
export const SET_INVARIANT_2 = 'SET_INVARIANT_2';
export const SET_MARKET_ETH_1 = 'SET_MARKET_ETH_1';
export const SET_MARKET_ETH_2 = 'SET_MARKET_ETH_2';
export const SET_MARKET_TOKENS_1 = 'SET_MARKET_TOKENS_1';
export const SET_MARKET_TOKENS_2 = 'SET_MARKET_TOKENS_2';
export const SET_ALLOWANCE_APPROVAL_STATE = 'SET_ALLOWANCE_APPROVAL_STATE';
export const SET_EXCHANGE_INPUT_VALUE = 'SET_EXCHANGE_INPUT_VALUE';
export const SET_EXCHANGE_OUTPUT_VALUE = 'SET_EXCHANGE_OUTPUT_VALUE';
export const SET_EXCHANGE_RATE = 'SET_EXCHANGE_RATE';
export const SET_EXCHANGE_FEE = 'SET_EXCHANGE_FEE';
\ No newline at end of file
import React from 'react'; import React from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import './index.css';
import App from './App'; import App from './App';
import { Provider } from 'react-redux';
import store from './store';
import './index.css';
import registerServiceWorker from './registerServiceWorker'; import registerServiceWorker from './registerServiceWorker';
// provider is going to need a store object passed into it
ReactDOM.render(
<Provider store={store}>
<App metamask={window.web3} />
</Provider>
, document.getElementById('root')
);
ReactDOM.render(<App metamask={window.web3} />, document.getElementById('root'));
registerServiceWorker(); registerServiceWorker();
import {
SET_INPUT_BALANCE,
SET_OUTPUT_BALANCE,
SET_INPUT_TOKEN,
SET_OUTPUT_TOKEN,
SET_INVARIANT_1,
SET_INVARIANT_2,
SET_MARKET_ETH_1,
SET_MARKET_ETH_2,
SET_MARKET_TOKENS_1,
SET_MARKET_TOKENS_2,
SET_ALLOWANCE_APPROVAL_STATE,
SET_EXCHANGE_INPUT_VALUE,
SET_EXCHANGE_OUTPUT_VALUE,
SET_EXCHANGE_RATE,
SET_EXCHANGE_FEE
} from '../constants';
export default (state = {}, action) => {
const {
inputBalance,
outputBalance,
inputToken,
outputToken,
invariant1,
invariant2,
marketEth1,
marketEth2,
marketTokens1,
marketTokens2,
allowanceApproved,
inputValue,
outputValue,
rate,
fee
} = action;
switch(action.type) {
case SET_INPUT_BALANCE:
return Object.assign({}, state, { inputBalance: inputBalance });
case SET_OUTPUT_BALANCE:
return Object.assign({}, state, { outputBalance: outputBalance });
case SET_INPUT_TOKEN:
return Object.assign({}, state, { inputToken: inputToken });
case SET_OUTPUT_TOKEN:
return Object.assign({}, state, { outputToken: outputToken });
case SET_INVARIANT_1:
return Object.assign({}, state, { invariant1: invariant1 });
case SET_INVARIANT_2:
return Object.assign({}, state, { invariant2: invariant2 });
case SET_MARKET_ETH_1:
return Object.assign({}, state, { marketEth1: marketEth1 });
case SET_MARKET_ETH_2:
return Object.assign({}, state, { marketEth2: marketEth2 });
case SET_MARKET_TOKENS_1:
return Object.assign({}, state, { marketTokens1: marketTokens1 });
case SET_MARKET_TOKENS_2:
return Object.assign({}, state, { marketTokens2: marketTokens2 });
case SET_ALLOWANCE_APPROVAL_STATE:
return Object.assign({}, state, { allowanceApproved: allowanceApproved });
case SET_EXCHANGE_INPUT_VALUE:
return Object.assign({}, state, { inputValue: inputValue });
case SET_EXCHANGE_OUTPUT_VALUE:
return Object.assign({}, state, { outputValue: outputValue });
case SET_EXCHANGE_RATE:
return Object.assign({}, state, { rate: rate });
case SET_EXCHANGE_FEE:
return Object.assign({}, state, { fee: fee });
default: return state;
}
}
\ No newline at end of file
import {
UNI_EXCHANGE_CONTRACT_READY,
SWT_EXCHANGE_CONTRACT_READY
} from '../constants'
export default (state = {}, action) => {
const { contract } = action;
switch(action.type) {
case UNI_EXCHANGE_CONTRACT_READY:
return Object.assign({}, state, { UNI: contract });
case SWT_EXCHANGE_CONTRACT_READY:
return Object.assign({}, state, { SWT: contract });
default: return state;
}
}
\ No newline at end of file
import { combineReducers } from 'redux';
import web3 from './web3-reducer';
import exchangeContracts from './exchangeContract-reducer';
import tokenContracts from './tokenContract-reducer';
import exchange from './exchange-reducer';
export default combineReducers({
web3,
exchangeContracts,
tokenContracts,
exchange
});
\ No newline at end of file
import {
UNI_TOKEN_CONTRACT_READY,
SWT_TOKEN_CONTRACT_READY
} from '../constants';
export default (state = {}, action) => {
const { contract } = action;
switch(action.type) {
case UNI_TOKEN_CONTRACT_READY:
return Object.assign({}, state, { UNI: contract });
case SWT_TOKEN_CONTRACT_READY:
return Object.assign({}, state, { SWT: contract });
default: return state;
}
}
\ No newline at end of file
// these will take in an action, have a default state set in the arguments and return a new state
import {
WEB3_CONNECTION_SUCCESSFUL,
WEB3_CONNECTION_UNSUCCESSFUL,
SET_CURRENT_MASK_ADDRESS,
METAMASK_LOCKED,
METAMASK_UNLOCKED,
SET_INTERACTION_STATE,
FACTORY_CONTRACT_READY,
SET_NETWORK_MESSAGE,
SET_BLOCK_TIMESTAMP,
SET_EXCHANGE_TYPE
} from '../constants';
export default (state = {}, action) => {
const { connected, currentMaskAddress, metamaskLocked, interaction, factoryContract, networkMessage, timestamp, exchangeType } = action
switch (action.type) {
case WEB3_CONNECTION_SUCCESSFUL:
return Object.assign({}, state, { connected: connected });
case WEB3_CONNECTION_UNSUCCESSFUL:
return Object.assign({}, state, { connected: connected });
case SET_CURRENT_MASK_ADDRESS:
return Object.assign({}, state, { currentMaskAddress: currentMaskAddress });
case METAMASK_LOCKED:
return Object.assign({}, state, { metamaskLocked: metamaskLocked });
case METAMASK_UNLOCKED:
return Object.assign({}, state, { metamaskLocked: metamaskLocked });
case SET_INTERACTION_STATE:
return Object.assign({}, state, { interaction: interaction });
case FACTORY_CONTRACT_READY:
return Object.assign({}, state, { factoryContract: factoryContract});
case SET_NETWORK_MESSAGE:
return Object.assign({}, state, { networkMessage: networkMessage });
case SET_BLOCK_TIMESTAMP:
return Object.assign({}, state, { blockTimestamp: timestamp });
case SET_EXCHANGE_TYPE:
return Object.assign({}, state, { exchangeType: exchangeType });
default: return state;
}
}
import store from './store.dev';
export default store;
\ No newline at end of file
// what states do you need upon initialization?
// connected: are you connnected? default state = false
// props.metamask --> maybe we should keep this in global state too?
// both of these are set to false in the default state
// fire dispatch functions to check for installation and connection in the default store
// you are probably going to be storing stuff like invariants and all that jazz here
export default {
// lets check if metamask is installed
// also, lets assume that we're disconnected initially
// we're going to need to include a seperate nest for exchange actions
web3: {
connected: false,
currentMaskAddress: '',
metamaskLocked: true,
interaction: '',
networkMessage: '',
factoryAddress: '0xD6D22d102A4237F3D35361BC022a78789E6174Aa',
factoryContract: '',
blockTimestamp: '',
exchangeType: 'ETH to Token',
exchangeAddresses: {
UNI: '0xcDc30C3b02c5776495298198377D2Fc0fd6B1F1C',
SWT: '0x4632a7Cd732c625dcc48d75E289c209422e1D2B7'
},
tokenAddresses: {
UNI: '0x350E5DD084ecF271e8d3531D4324443952F47756',
SWT: '0x8B2A87F8243f23C33fb97E23a21Ae8EDB3b71AcA'
}
},
exchangeContracts: {
UNI: '',
SWT: ''
},
tokenContracts: {
UNI: '',
SWT: ''
},
exchange: {
inputBalance: 0,
outputBalance: 0,
inputToken: { value: 'ETH', label: 'ETH', clearableValue: false },
outputToken: { value: 'UNI', label: 'UNI', clearableValue: false },
invariant1: 0,
invariant2: 0,
marketEth1: 0,
marketEth2: 0,
marketTokens1: 0,
marketTokens2: 0,
allowanceApproved: true,
inputValue: 0,
outputValue: 0,
rate: 0,
fee: 0,
}
}
\ No newline at end of file
import { applyMiddleware, compose, createStore } from 'redux';
import reducer from '../reducers';
import thunk from 'redux-thunk'
import initialState from './initial-state';
const middleware = [thunk];
const enhancers = [];
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
reducer,
initialState,
composeEnhancers(applyMiddleware(...middleware), ...enhancers)
)
export default store;
\ No newline at end of file
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