Add Token image from URL (#4916)
This commit is contained in:
parent
f8aec7571f
commit
a25d935a1d
@ -19,7 +19,7 @@ import { Dialog, RaisedButton, FlatButton, SelectField, MenuItem } from 'materia
|
||||
import AddIcon from 'material-ui/svg-icons/content/add';
|
||||
|
||||
import InputText from '../../Inputs/Text';
|
||||
import { ADDRESS_TYPE } from '../../Inputs/validation';
|
||||
import { ADDRESS_TYPE, URL_TYPE } from '../../Inputs/validation';
|
||||
|
||||
import styles from './token.css';
|
||||
|
||||
@ -128,6 +128,22 @@ export default class AddMeta extends Component {
|
||||
|
||||
renderForm () {
|
||||
const selectedMeta = metaDataKeys[this.state.metaKeyIndex];
|
||||
const metaLabel = selectedMeta.label.toLowerCase();
|
||||
let metaType;
|
||||
|
||||
switch (selectedMeta.validation) {
|
||||
case ADDRESS_TYPE:
|
||||
metaType = 'Address';
|
||||
break;
|
||||
|
||||
case URL_TYPE:
|
||||
metaType = 'URL';
|
||||
break;
|
||||
|
||||
default:
|
||||
metaType = 'URL Hint';
|
||||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
@ -145,7 +161,7 @@ export default class AddMeta extends Component {
|
||||
<InputText
|
||||
key={ selectedMeta.value }
|
||||
floatingLabelText={ `${selectedMeta.label} value` }
|
||||
hintText={ `The value of the ${selectedMeta.label.toLowerCase()} (${selectedMeta.validation === ADDRESS_TYPE ? 'Address' : 'Url Hint'})` }
|
||||
hintText={ `The value of the ${metaLabel} (${metaType})` }
|
||||
|
||||
validationType={ selectedMeta.validation }
|
||||
onChange={ this.onChange }
|
||||
@ -174,14 +190,20 @@ export default class AddMeta extends Component {
|
||||
|
||||
onAdd = () => {
|
||||
const { index } = this.props;
|
||||
const { form, metaKeyIndex } = this.state;
|
||||
|
||||
const selectedMeta = metaDataKeys[metaKeyIndex];
|
||||
|
||||
const keyIndex = this.state.metaKeyIndex;
|
||||
const key = metaDataKeys[keyIndex].value;
|
||||
const value = form.value;
|
||||
const validationType = selectedMeta.validation;
|
||||
|
||||
this.props.handleAddMeta(
|
||||
index,
|
||||
key,
|
||||
this.state.form.value
|
||||
value,
|
||||
validationType
|
||||
);
|
||||
|
||||
this.setState({ complete: true });
|
||||
|
@ -61,8 +61,8 @@ const mapDispatchToProps = (dispatch) => {
|
||||
dispatch(unregisterToken(index));
|
||||
},
|
||||
|
||||
handleAddMeta: (index, key, value) => {
|
||||
dispatch(addTokenMeta(index, key, value));
|
||||
handleAddMeta: (index, key, value, validationType) => {
|
||||
dispatch(addTokenMeta(index, key, value, validationType));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -14,7 +14,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { getTokenTotalSupply } from '../utils';
|
||||
import { URL_TYPE } from '../Inputs/validation';
|
||||
import { getTokenTotalSupply, urlToHash } from '../utils';
|
||||
|
||||
const { bytesToHex } = window.parity.api.util;
|
||||
|
||||
@ -178,40 +179,63 @@ export const queryTokenMeta = (index, query) => (dispatch, getState) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const addTokenMeta = (index, key, value) => (dispatch, getState) => {
|
||||
export const addTokenMeta = (index, key, value, validationType) => (dispatch, getState) => {
|
||||
const state = getState();
|
||||
|
||||
const contractInstance = state.status.contract.instance;
|
||||
const ghhInstance = state.status.githubhint.instance;
|
||||
|
||||
const token = state.tokens.tokens.find(t => t.index === index);
|
||||
const options = { from: token.owner };
|
||||
const values = [ index, key, value ];
|
||||
let valuesPromise;
|
||||
|
||||
contractInstance
|
||||
// Get the right values (could be a hashed URL from GHH)
|
||||
if (validationType === URL_TYPE) {
|
||||
valuesPromise = addGithubhintURL(ghhInstance, options, value)
|
||||
.then((hash) => [ index, key, hash ]);
|
||||
} else {
|
||||
valuesPromise = Promise.resolve([ index, key, value ]);
|
||||
}
|
||||
|
||||
return valuesPromise
|
||||
.then((values) => {
|
||||
return contractInstance
|
||||
.setMeta
|
||||
.estimateGas(options, values)
|
||||
.then((gasEstimate) => {
|
||||
options.gas = gasEstimate.mul(1.2).toFixed(0);
|
||||
return contractInstance.setMeta.postTransaction(options, values);
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(`addTokenMeta: #${index} error`, e);
|
||||
});
|
||||
};
|
||||
|
||||
export const addGithubhintURL = (from, key, url) => (dispatch, getState) => {
|
||||
const state = getState();
|
||||
const contractInstance = state.status.githubhint.instance;
|
||||
const options = { from };
|
||||
const values = [ key, url ];
|
||||
export const addGithubhintURL = (ghhInstance, _options, url) => {
|
||||
return urlToHash(ghhInstance, url)
|
||||
.then((result) => {
|
||||
const { hash, registered } = result;
|
||||
|
||||
contractInstance
|
||||
if (registered) {
|
||||
return hash;
|
||||
}
|
||||
|
||||
const options = { from: _options.from };
|
||||
const values = [ hash, url ];
|
||||
|
||||
ghhInstance
|
||||
.hintURL
|
||||
.estimateGas(options, values)
|
||||
.then((gasEstimate) => {
|
||||
options.gas = gasEstimate.mul(1.2).toFixed(0);
|
||||
return contractInstance.hintURL.postTransaction(options, values);
|
||||
return ghhInstance.hintURL.postTransaction(options, values);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error('addGithubhintURL error', e);
|
||||
.catch((error) => {
|
||||
console.error(`registering "${url}" to GHH`, error);
|
||||
});
|
||||
|
||||
return hash;
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -14,13 +14,13 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { HEX_TYPE, ADDRESS_TYPE } from './Inputs/validation';
|
||||
import { URL_TYPE, ADDRESS_TYPE } from './Inputs/validation';
|
||||
|
||||
export const metaDataKeys = [
|
||||
{
|
||||
label: 'Image',
|
||||
value: 'IMG',
|
||||
validation: HEX_TYPE
|
||||
validation: URL_TYPE
|
||||
},
|
||||
{
|
||||
label: 'Address',
|
||||
|
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
const { api } = window.parity;
|
||||
const api = window.parent.secureApi;
|
||||
|
||||
export {
|
||||
api
|
||||
|
@ -18,6 +18,45 @@ import { api } from './parity';
|
||||
|
||||
import { eip20 as eip20Abi } from '~/contracts/abi';
|
||||
|
||||
export const INVALID_URL_HASH = '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470';
|
||||
export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
|
||||
|
||||
/**
|
||||
* Convert the given URL to a content hash,
|
||||
* and checks if it is already registered in GHH
|
||||
*/
|
||||
export const urlToHash = (ghhInstance, url) => {
|
||||
if (!url || !url.length) {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
return api.parity
|
||||
.hashContent(url)
|
||||
.catch((error) => {
|
||||
const message = error.text || error.message || error.toString();
|
||||
|
||||
throw new Error(`${message} (${url})`);
|
||||
})
|
||||
.then((contentHash) => {
|
||||
console.log('lookupHash', url, contentHash);
|
||||
|
||||
if (contentHash === INVALID_URL_HASH) {
|
||||
throw new Error(`"${url}" is not a valid URL`);
|
||||
}
|
||||
|
||||
return ghhInstance.entries
|
||||
.call({}, [contentHash])
|
||||
.then(([accountSlashRepo, commit, contentHashOwner]) => {
|
||||
const registered = (contentHashOwner !== ZERO_ADDRESS);
|
||||
|
||||
return {
|
||||
hash: contentHash,
|
||||
registered
|
||||
};
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const getTokenTotalSupply = (tokenAddress) => {
|
||||
return api
|
||||
.eth
|
||||
|
@ -32,7 +32,8 @@
|
||||
"description": "A registry of transactable tokens on the network",
|
||||
"author": "Parity Team <admin@ethcore.io>",
|
||||
"version": "1.0.0",
|
||||
"visible": true
|
||||
"visible": true,
|
||||
"secure": true
|
||||
},
|
||||
{
|
||||
"id": "0xf49089046f53f5d2e5f3513c1c32f5ff57d986e46309a42d2b249070e4e72c46",
|
||||
|
Loading…
Reference in New Issue
Block a user