diff --git a/js/src/contracts/contracts.js b/js/src/contracts/contracts.js index c9d1c2390..a04321c7b 100644 --- a/js/src/contracts/contracts.js +++ b/js/src/contracts/contracts.js @@ -18,6 +18,7 @@ import DappReg from './dappreg'; import Registry from './registry'; import SignatureReg from './signaturereg'; import TokenReg from './tokenreg'; +import GithubHint from './githubhint'; let instance = null; @@ -30,6 +31,7 @@ export default class Contracts { this._dappreg = new DappReg(api, this._registry); this._signaturereg = new SignatureReg(api, this._registry); this._tokenreg = new TokenReg(api, this._registry); + this._githubhint = new GithubHint(api, this._registry); } get registry () { @@ -48,6 +50,10 @@ export default class Contracts { return this._tokenreg; } + get githubHint () { + return this._githubhint; + } + static create (api) { return new Contracts(api); } diff --git a/js/src/contracts/githubhint.js b/js/src/contracts/githubhint.js new file mode 100644 index 000000000..47d7eca6e --- /dev/null +++ b/js/src/contracts/githubhint.js @@ -0,0 +1,32 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default class GithubHint { + constructor (api, registry) { + this._api = api; + this._registry = registry; + + this.getInstance(); + } + + getContract () { + return this._registry.getContract('githubhint'); + } + + getInstance () { + return this.getContract().instance; + } +} diff --git a/js/src/contracts/registry.js b/js/src/contracts/registry.js index 9853c0df9..d52b20718 100644 --- a/js/src/contracts/registry.js +++ b/js/src/contracts/registry.js @@ -42,7 +42,7 @@ export default class Registry { }); } - getContractInstance (_name) { + getContract (_name) { const name = _name.toLowerCase(); return new Promise((resolve, reject) => { @@ -54,13 +54,19 @@ export default class Registry { this .lookupAddress(name) .then((address) => { - this._contracts[name] = this._api.newContract(abis[name], address).instance; + this._contracts[name] = this._api.newContract(abis[name], address); resolve(this._contracts[name]); }) .catch(reject); }); } + getContractInstance (_name) { + return this + .getContract(_name) + .then((contract) => contract.instance); + } + lookupAddress (_name) { const name = _name.toLowerCase(); const sha3 = this._api.util.sha3(name); diff --git a/js/src/contracts/tokenreg.js b/js/src/contracts/tokenreg.js index 78bd5e4d9..5e317880b 100644 --- a/js/src/contracts/tokenreg.js +++ b/js/src/contracts/tokenreg.js @@ -22,8 +22,12 @@ export default class TokenReg { this.getInstance(); } + getContract () { + return this._registry.getContract('tokenreg'); + } + getInstance () { - return this._registry.getContractInstance('tokenreg'); + return this.getContract().instance; } tokenCount () { diff --git a/js/src/dapps/tokenreg/Accounts/actions.js b/js/src/dapps/tokenreg/Accounts/actions.js index a310baf7d..5f92280be 100644 --- a/js/src/dapps/tokenreg/Accounts/actions.js +++ b/js/src/dapps/tokenreg/Accounts/actions.js @@ -46,8 +46,6 @@ export const loadAccounts = () => (dispatch) => { address })); - console.log('accounts', accountsList); - dispatch(setAccounts(accountsList)); dispatch(setAccountsInfo(accountsInfo)); dispatch(setSelectedAccount(accountsList[0].address)); diff --git a/js/src/dapps/tokenreg/Actions/Query/query.js b/js/src/dapps/tokenreg/Actions/Query/query.js index 16d13f2f0..5a3c7d5f6 100644 --- a/js/src/dapps/tokenreg/Actions/Query/query.js +++ b/js/src/dapps/tokenreg/Actions/Query/query.js @@ -42,12 +42,9 @@ export default class QueryAction extends Component { onClose: PropTypes.func.isRequired, handleQueryToken: PropTypes.func.isRequired, - handleQueryMetaLookup: PropTypes.func.isRequired, data: PropTypes.object, - notFound: PropTypes.bool, - metaLoading: PropTypes.bool, - metaData: PropTypes.object + notFound: PropTypes.bool } state = initState; @@ -131,11 +128,8 @@ export default class QueryAction extends Component { return ( + tla={ data.tla } + /> ); } diff --git a/js/src/dapps/tokenreg/Actions/actions.js b/js/src/dapps/tokenreg/Actions/actions.js index 1c6703f77..df5b41e6b 100644 --- a/js/src/dapps/tokenreg/Actions/actions.js +++ b/js/src/dapps/tokenreg/Actions/actions.js @@ -16,8 +16,6 @@ import { getTokenTotalSupply } from '../utils'; -const { sha3, bytesToHex } = window.parity.api.util; - export const SET_REGISTER_SENDING = 'SET_REGISTER_SENDING'; export const setRegisterSending = (isSending) => ({ type: SET_REGISTER_SENDING, @@ -41,8 +39,6 @@ export const registerCompleted = () => ({ }); export const registerToken = (tokenData) => (dispatch, getState) => { - console.log('registering token', tokenData); - const state = getState(); const contractInstance = state.status.contract.instance; const fee = state.status.contract.fee; @@ -83,8 +79,6 @@ export const registerToken = (tokenData) => (dispatch, getState) => { }) .then((gasEstimate) => { options.gas = gasEstimate.mul(1.2).toFixed(0); - console.log(`transfer: gas estimated as ${gasEstimate.toFixed(0)} setting to ${options.gas}`); - return contractInstance.register.postTransaction(options, values); }) .then((result) => { @@ -183,34 +177,3 @@ export const queryToken = (key, query) => (dispatch, getState) => { dispatch(setQueryLoading(false)); }); }; - -export const queryTokenMeta = (id, query) => (dispatch, getState) => { - console.log('loading token meta', query); - - const state = getState(); - const contractInstance = state.status.contract.instance; - - const key = sha3(query); - - const startDate = Date.now(); - dispatch(setQueryMetaLoading(true)); - - contractInstance - .meta - .call({}, [ id, key ]) - .then((value) => { - const meta = { - key, query, - value: value.find(v => v !== 0) ? bytesToHex(value) : null - }; - - dispatch(setQueryMeta(meta)); - - setTimeout(() => { - dispatch(setQueryMetaLoading(false)); - }, 500 - (Date.now() - startDate)); - }) - .catch((e) => { - console.error('load meta query error', e); - }); -}; diff --git a/js/src/dapps/tokenreg/Actions/component.js b/js/src/dapps/tokenreg/Actions/component.js index 3e7ef0d64..43acc27ab 100644 --- a/js/src/dapps/tokenreg/Actions/component.js +++ b/js/src/dapps/tokenreg/Actions/component.js @@ -37,7 +37,6 @@ export default class Actions extends Component { handleQueryToken: PropTypes.func.isRequired, handleQueryClose: PropTypes.func.isRequired, - handleQueryMetaLookup: PropTypes.func.isRequired, query: PropTypes.object.isRequired }; @@ -82,7 +81,6 @@ export default class Actions extends Component { show={ this.state.show[ QUERY_ACTION ] } onClose={ this.onQueryClose } handleQueryToken={ this.props.handleQueryToken } - handleQueryMetaLookup={ this.props.handleQueryMetaLookup } { ...this.props.query } /> ); diff --git a/js/src/dapps/tokenreg/Actions/container.js b/js/src/dapps/tokenreg/Actions/container.js index 2c3773122..1d3d8fe31 100644 --- a/js/src/dapps/tokenreg/Actions/container.js +++ b/js/src/dapps/tokenreg/Actions/container.js @@ -19,7 +19,7 @@ import { connect } from 'react-redux'; import Actions from './component'; -import { registerToken, registerReset, queryToken, queryReset, queryTokenMeta } from './actions'; +import { registerToken, registerReset, queryToken, queryReset } from './actions'; class TokensContainer extends Component { @@ -49,9 +49,6 @@ const mapDispatchToProps = (dispatch) => { }, handleQueryClose: () => { dispatch(queryReset()); - }, - handleQueryMetaLookup: (id, query) => { - dispatch(queryTokenMeta(id, query)); } }; }; diff --git a/js/src/dapps/tokenreg/Application/application.css b/js/src/dapps/tokenreg/Application/application.css index 033147ae3..94ca6302e 100644 --- a/js/src/dapps/tokenreg/Application/application.css +++ b/js/src/dapps/tokenreg/Application/application.css @@ -19,6 +19,7 @@ display: flex; flex-direction: column; align-items: center; + padding-bottom: 10em; } .warning { diff --git a/js/src/dapps/tokenreg/Status/actions.js b/js/src/dapps/tokenreg/Status/actions.js index e9e217d6a..b07949a28 100644 --- a/js/src/dapps/tokenreg/Status/actions.js +++ b/js/src/dapps/tokenreg/Status/actions.js @@ -14,11 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -import { - registry as registryAbi, - tokenreg as tokenregAbi, - githubhint as githubhintAbi -} from '../../../contracts/abi'; +import Contracts from '../../../contracts'; import { loadToken, setTokenPending, deleteToken, setTokenData } from '../Tokens/actions'; @@ -34,43 +30,31 @@ export const FIND_CONTRACT = 'FIND_CONTRACT'; export const loadContract = () => (dispatch) => { dispatch(setLoading(true)); - api.parity - .registryAddress() - .then((registryAddress) => { - console.log(`registry found at ${registryAddress}`); - const registry = api.newContract(registryAbi, registryAddress).instance; - - return Promise.all([ - registry.getAddress.call({}, [api.util.sha3('tokenreg'), 'A']), - registry.getAddress.call({}, [api.util.sha3('githubhint'), 'A']) - ]); - }) - .then(([ tokenregAddress, githubhintAddress ]) => { - console.log(`tokenreg was found at ${tokenregAddress}`); - - const tokenregContract = api - .newContract(tokenregAbi, tokenregAddress); - - const githubhintContract = api - .newContract(githubhintAbi, githubhintAddress); + const { tokenReg, githubHint } = new Contracts(api); + return Promise + .all([ + tokenReg.getContract(), + githubHint.getContract() + ]) + .then(([ tokenRegContract, githubHintContract ]) => { dispatch(setContractDetails({ - address: tokenregAddress, - instance: tokenregContract.instance, - raw: tokenregContract + address: tokenRegContract.address, + instance: tokenRegContract.instance, + raw: tokenRegContract })); dispatch(setGithubhintDetails({ - address: githubhintAddress, - instance: githubhintContract.instance, - raw: githubhintContract + address: githubHintContract.address, + instance: githubHintContract.instance, + raw: githubHintContract })); dispatch(loadContractDetails()); dispatch(subscribeEvents()); }) .catch((error) => { - console.error('loadContract error', error); + throw error; }); }; @@ -78,7 +62,7 @@ export const LOAD_CONTRACT_DETAILS = 'LOAD_CONTRACT_DETAILS'; export const loadContractDetails = () => (dispatch, getState) => { const state = getState(); - const instance = state.status.contract.instance; + const { instance } = state.status.contract; Promise .all([ @@ -87,8 +71,6 @@ export const loadContractDetails = () => (dispatch, getState) => { instance.fee.call() ]) .then(([accounts, owner, fee]) => { - console.log(`owner as ${owner}, fee set at ${fee.toFormat()}`); - const isOwner = accounts.filter(a => a === owner).length > 0; dispatch(setContractDetails({ @@ -119,14 +101,14 @@ export const setGithubhintDetails = (details) => ({ export const subscribeEvents = () => (dispatch, getState) => { const state = getState(); - const contract = state.status.contract.raw; + const { raw } = state.status.contract; const previousSubscriptionId = state.status.subscriptionId; if (previousSubscriptionId) { - contract.unsubscribe(previousSubscriptionId); + raw.unsubscribe(previousSubscriptionId); } - contract + raw .subscribe(null, { fromBlock: 'latest', toBlock: 'pending', @@ -187,7 +169,7 @@ export const subscribeEvents = () => (dispatch, getState) => { )); } - console.log('new log event', log); + console.warn('unknown log event', log); }); }) .then((subscriptionId) => { diff --git a/js/src/dapps/tokenreg/Status/reducer.js b/js/src/dapps/tokenreg/Status/reducer.js index 357cb2244..aee16fbe7 100644 --- a/js/src/dapps/tokenreg/Status/reducer.js +++ b/js/src/dapps/tokenreg/Status/reducer.js @@ -27,15 +27,13 @@ const initialState = { contract: { address: null, instance: null, - raw: null, owner: null, isOwner: false, fee: null }, githubhint: { address: null, - instance: null, - raw: null + instance: null } }; diff --git a/js/src/dapps/tokenreg/Tokens/Token/index.js b/js/src/dapps/tokenreg/Tokens/Token/index.js index 4b822b4bd..30ad8896f 100644 --- a/js/src/dapps/tokenreg/Tokens/Token/index.js +++ b/js/src/dapps/tokenreg/Tokens/Token/index.js @@ -14,4 +14,4 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -export default from './token'; +export default from './tokenContainer'; diff --git a/js/src/dapps/tokenreg/Tokens/Token/token.js b/js/src/dapps/tokenreg/Tokens/Token/token.js index 660b21b97..be14cec84 100644 --- a/js/src/dapps/tokenreg/Tokens/Token/token.js +++ b/js/src/dapps/tokenreg/Tokens/Token/token.js @@ -57,15 +57,28 @@ export default class Token extends Component { isLoading: PropTypes.bool, isPending: PropTypes.bool, isTokenOwner: PropTypes.bool.isRequired, - isContractOwner: PropTypes.bool.isRequired, + isContractOwner: PropTypes.bool, fullWidth: PropTypes.bool }; - state = { - metaKeyIndex: 0 + static defaultProps = { + isContractOwner: false }; + state = { + metaKeyIndex: 0, + showMeta: false + }; + + shouldComponentUpdate (nextProps) { + if (nextProps.isLoading && this.props.isLoading) { + return false; + } + + return true; + } + render () { const { isLoading, fullWidth } = this.props; @@ -237,7 +250,12 @@ export default class Token extends Component { } renderMeta (meta) { - const isMetaLoading = this.props.isMetaLoading; + const { isMetaLoading } = this.props; + const { showMeta } = this.state; + + if (!showMeta) { + return null; + } if (isMetaLoading) { return (
@@ -331,6 +349,7 @@ export default class Token extends Component { const key = metaDataKeys[keyIndex].value; const index = this.props.index; + this.setState({ showMeta: true }); this.props.handleMetaLookup(index, key); } diff --git a/js/src/dapps/tokenreg/Tokens/Token/tokenContainer.js b/js/src/dapps/tokenreg/Tokens/Token/tokenContainer.js new file mode 100644 index 000000000..7351da524 --- /dev/null +++ b/js/src/dapps/tokenreg/Tokens/Token/tokenContainer.js @@ -0,0 +1,73 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +import React, { Component, PropTypes } from 'react'; +import { connect } from 'react-redux'; + +import Token from './token'; + +import { queryTokenMeta, unregisterToken, addTokenMeta } from '../actions'; + +class TokenContainer extends Component { + static propTypes = { + handleMetaLookup: PropTypes.func.isRequired, + handleUnregister: PropTypes.func.isRequired, + handleAddMeta: PropTypes.func.isRequired, + + tla: PropTypes.string.isRequired + }; + + render () { + return ( + + ); + } +} + +const mapStateToProps = (_, initProps) => { + const { tla } = initProps; + + return (state) => { + const { isOwner } = state.status.contract; + const { tokens } = state.tokens; + const token = tokens.find((t) => t.tla === tla); + + return { ...token, isContractOwner: isOwner }; + }; +}; + +const mapDispatchToProps = (dispatch) => { + return { + handleMetaLookup: (index, query) => { + dispatch(queryTokenMeta(index, query)); + }, + + handleUnregister: (index) => { + dispatch(unregisterToken(index)); + }, + + handleAddMeta: (index, key, value) => { + dispatch(addTokenMeta(index, key, value)); + } + }; +}; + +export default connect( + mapStateToProps, + mapDispatchToProps +)(TokenContainer); diff --git a/js/src/dapps/tokenreg/Tokens/actions.js b/js/src/dapps/tokenreg/Tokens/actions.js index bd4413163..d1e13c1dc 100644 --- a/js/src/dapps/tokenreg/Tokens/actions.js +++ b/js/src/dapps/tokenreg/Tokens/actions.js @@ -67,8 +67,6 @@ export const deleteToken = (index) => ({ }); export const loadTokens = () => (dispatch, getState) => { - console.log('loading tokens...'); - const state = getState(); const contractInstance = state.status.contract.instance; @@ -79,7 +77,6 @@ export const loadTokens = () => (dispatch, getState) => { .call() .then((count) => { const tokenCount = parseInt(count); - console.log(`token count: ${tokenCount}`); dispatch(setTokenCount(tokenCount)); for (let i = 0; i < tokenCount; i++) { @@ -94,8 +91,6 @@ export const loadTokens = () => (dispatch, getState) => { }; export const loadToken = (index) => (dispatch, getState) => { - console.log('loading token', index); - const state = getState(); const contractInstance = state.status.contract.instance; @@ -144,7 +139,7 @@ export const loadToken = (index) => (dispatch, getState) => { } data.totalSupply = data.totalSupply.toNumber(); - console.log(`token loaded: #${index}`, data); + dispatch(setTokenData(index, data)); dispatch(setTokenLoading(index, false)); }) @@ -159,8 +154,6 @@ export const loadToken = (index) => (dispatch, getState) => { }; export const queryTokenMeta = (index, query) => (dispatch, getState) => { - console.log('loading token meta', index, query); - const state = getState(); const contractInstance = state.status.contract.instance; @@ -176,7 +169,6 @@ export const queryTokenMeta = (index, query) => (dispatch, getState) => { value: value.find(v => v !== 0) ? bytesToHex(value) : null }; - console.log(`token meta loaded: #${index}`, value); dispatch(setTokenMeta(index, meta)); setTimeout(() => { @@ -189,8 +181,6 @@ export const queryTokenMeta = (index, query) => (dispatch, getState) => { }; export const addTokenMeta = (index, key, value) => (dispatch, getState) => { - console.log('add token meta', index, key, value); - const state = getState(); const contractInstance = state.status.contract.instance; const token = state.tokens.tokens.find(t => t.index === index); @@ -203,8 +193,6 @@ export const addTokenMeta = (index, key, value) => (dispatch, getState) => { .estimateGas(options, values) .then((gasEstimate) => { options.gas = gasEstimate.mul(1.2).toFixed(0); - console.log(`addTokenMeta: gas estimated as ${gasEstimate.toFixed(0)} setting to ${options.gas}`); - return contractInstance.setMeta.postTransaction(options, values); }) .catch((e) => { @@ -213,8 +201,6 @@ export const addTokenMeta = (index, key, value) => (dispatch, getState) => { }; export const addGithubhintURL = (from, key, url) => (dispatch, getState) => { - console.log('add githubhint url', key, url); - const state = getState(); const contractInstance = state.status.githubhint.instance; @@ -227,8 +213,6 @@ export const addGithubhintURL = (from, key, url) => (dispatch, getState) => { .estimateGas(options, values) .then((gasEstimate) => { options.gas = gasEstimate.mul(1.2).toFixed(0); - console.log(`transfer: gas estimated as ${gasEstimate.toFixed(0)} setting to ${options.gas}`); - return contractInstance.hintURL.postTransaction(options, values); }) .catch((e) => { @@ -237,8 +221,6 @@ export const addGithubhintURL = (from, key, url) => (dispatch, getState) => { }; export const unregisterToken = (index) => (dispatch, getState) => { - console.log('unregistering token', index); - const { contract } = getState().status; const { instance, owner } = contract; @@ -252,8 +234,6 @@ export const unregisterToken = (index) => (dispatch, getState) => { .estimateGas(options, values) .then((gasEstimate) => { options.gas = gasEstimate.mul(1.2).toFixed(0); - console.log(`transfer: gas estimated as ${gasEstimate.toFixed(0)} setting to ${options.gas}`); - return instance.unregister.postTransaction(options, values); }) .catch((e) => { diff --git a/js/src/dapps/tokenreg/Tokens/container.js b/js/src/dapps/tokenreg/Tokens/container.js index b6171c2cc..33b2de659 100644 --- a/js/src/dapps/tokenreg/Tokens/container.js +++ b/js/src/dapps/tokenreg/Tokens/container.js @@ -19,16 +19,13 @@ import { connect } from 'react-redux'; import Tokens from './tokens'; -import { loadTokens, queryTokenMeta, unregisterToken, addTokenMeta } from './actions'; +import { loadTokens } from './actions'; class TokensContainer extends Component { static propTypes = { - isOwner: PropTypes.bool, isLoading: PropTypes.bool, tokens: PropTypes.array, - tokenCount: PropTypes.number, - onLoadTokens: PropTypes.func, - accounts: PropTypes.array + onLoadTokens: PropTypes.func }; componentDidMount () { @@ -36,7 +33,6 @@ class TokensContainer extends Component { } render () { - console.log(this.props); return ( { - const { list } = state.accounts; - const { isLoading, tokens, tokenCount } = state.tokens; + const { isLoading, tokens } = state.tokens; - const { isOwner } = state.status.contract; + const filteredTokens = tokens + .filter((token) => token && token.tla) + .map((token) => ({ tla: token.tla, owner: token.owner })); - return { isLoading, tokens, tokenCount, isOwner, accounts: list }; + return { isLoading, tokens: filteredTokens }; }; const mapDispatchToProps = (dispatch) => { return { onLoadTokens: () => { dispatch(loadTokens()); - }, - - handleMetaLookup: (index, query) => { - dispatch(queryTokenMeta(index, query)); - }, - - handleUnregister: (index) => { - dispatch(unregisterToken(index)); - }, - - handleAddMeta: (index, key, value) => { - dispatch(addTokenMeta(index, key, value)); } }; }; diff --git a/js/src/dapps/tokenreg/Tokens/tokens.js b/js/src/dapps/tokenreg/Tokens/tokens.js index 43766a8a8..48bc88a74 100644 --- a/js/src/dapps/tokenreg/Tokens/tokens.js +++ b/js/src/dapps/tokenreg/Tokens/tokens.js @@ -23,13 +23,8 @@ import styles from './tokens.css'; export default class Tokens extends Component { static propTypes = { - handleAddMeta: PropTypes.func.isRequired, - handleUnregister: PropTypes.func.isRequired, - handleMetaLookup: PropTypes.func.isRequired, - isOwner: PropTypes.bool.isRequired, isLoading: PropTypes.bool.isRequired, - tokens: PropTypes.array, - accounts: PropTypes.array + tokens: PropTypes.array }; render () { @@ -45,24 +40,12 @@ export default class Tokens extends Component { } renderTokens (tokens) { - const { accounts, isOwner } = this.props; - - return tokens.map((token, index) => { - if (!token || !token.tla) { - return null; - } - - const isTokenOwner = !!accounts.find((account) => account.address === token.owner); - + return tokens.map((token) => { return ( + key={ token.tla } + tla={ token.tla } + /> ); }); }