From 1630c5ea731ccfb1499ec258487f58623b84f99e Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Fri, 7 Oct 2016 23:58:33 +0200 Subject: [PATCH 1/5] basic githubhint layout --- js/src/dapps/githubhint.html | 18 ++++ js/src/dapps/githubhint.js | 31 ++++++ .../githubhint/Application/application.css | 82 ++++++++++++++++ .../githubhint/Application/application.js | 98 +++++++++++++++++++ js/src/dapps/githubhint/Application/index.js | 17 ++++ js/src/dapps/githubhint/Button/button.css | 57 +++++++++++ js/src/dapps/githubhint/Button/button.js | 53 ++++++++++ js/src/dapps/githubhint/Button/index.js | 17 ++++ .../githubhint/IdentityIcon/identityIcon.css | 23 +++++ .../githubhint/IdentityIcon/identityIcon.js | 36 +++++++ js/src/dapps/githubhint/IdentityIcon/index.js | 17 ++++ js/src/dapps/githubhint/Loading/index.js | 17 ++++ js/src/dapps/githubhint/Loading/loading.css | 24 +++++ js/src/dapps/githubhint/Loading/loading.js | 29 ++++++ js/src/dapps/githubhint/parity.js | 21 ++++ js/src/dapps/githubhint/services.js | 64 ++++++++++++ js/src/views/Dapps/dapps.js | 5 + js/webpack.config.js | 1 + 18 files changed, 610 insertions(+) create mode 100644 js/src/dapps/githubhint.html create mode 100644 js/src/dapps/githubhint.js create mode 100644 js/src/dapps/githubhint/Application/application.css create mode 100644 js/src/dapps/githubhint/Application/application.js create mode 100644 js/src/dapps/githubhint/Application/index.js create mode 100644 js/src/dapps/githubhint/Button/button.css create mode 100644 js/src/dapps/githubhint/Button/button.js create mode 100644 js/src/dapps/githubhint/Button/index.js create mode 100644 js/src/dapps/githubhint/IdentityIcon/identityIcon.css create mode 100644 js/src/dapps/githubhint/IdentityIcon/identityIcon.js create mode 100644 js/src/dapps/githubhint/IdentityIcon/index.js create mode 100644 js/src/dapps/githubhint/Loading/index.js create mode 100644 js/src/dapps/githubhint/Loading/loading.css create mode 100644 js/src/dapps/githubhint/Loading/loading.js create mode 100644 js/src/dapps/githubhint/parity.js create mode 100644 js/src/dapps/githubhint/services.js diff --git a/js/src/dapps/githubhint.html b/js/src/dapps/githubhint.html new file mode 100644 index 00000000000..5776cbde5dd --- /dev/null +++ b/js/src/dapps/githubhint.html @@ -0,0 +1,18 @@ + + + + + + + GitHub Hint + + + + +
+ + + + + + diff --git a/js/src/dapps/githubhint.js b/js/src/dapps/githubhint.js new file mode 100644 index 00000000000..fdbd13a6dee --- /dev/null +++ b/js/src/dapps/githubhint.js @@ -0,0 +1,31 @@ +// 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 ReactDOM from 'react-dom'; +import React from 'react'; + +import injectTapEventPlugin from 'react-tap-event-plugin'; +injectTapEventPlugin(); + +import Application from './githubhint/Application'; + +import './style.css'; +import './githubhint.html'; + +ReactDOM.render( + , + document.querySelector('#container') +); diff --git a/js/src/dapps/githubhint/Application/application.css b/js/src/dapps/githubhint/Application/application.css new file mode 100644 index 00000000000..476ee0e5668 --- /dev/null +++ b/js/src/dapps/githubhint/Application/application.css @@ -0,0 +1,82 @@ +/* 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 . +*/ + +.container { + background: #333; + font-family: 'Roboto'; + vertical-align: middle; + padding: 4em 0; + text-align: center; +} + +.form { + text-align: right; + margin: 0 auto; + border-radius: 5px; + width: 44em; + color: #eee; +} + +.box { + padding: 2em; + background: rgba(255, 255, 255, 0.1); + border-radius: 5px; +} + +.buttons { + text-align: center; + margin: 0 auto 2em auto; +} + +.box .buttons { + text-align: right; + margin: 2em 0 0 0; +} + +.box .description { + margin: 0 0 2em 0; + text-align: center; + opacity: 0.75; +} + +.capture { +} + +.capture+.capture { + margin-top: 1em; +} + +.capture * { + display: inline-block; + padding: 0.5em 0.5em; + vertical-align: middle; + box-sizing: border-box; + width: 20em; +} + +.capture input { + color: #333; + background: #eee; + border: none; + border-radius: 5px; + width: 20em; + font-size: 1em; +} + +.capture[disabled] { + opacity: 0.15; +} diff --git a/js/src/dapps/githubhint/Application/application.js b/js/src/dapps/githubhint/Application/application.js new file mode 100644 index 00000000000..6ed3633be8b --- /dev/null +++ b/js/src/dapps/githubhint/Application/application.js @@ -0,0 +1,98 @@ +// 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 } from 'react'; + +import { attachInterface } from '../services'; +import Button from '../Button'; +import Loading from '../Loading'; + +import styles from './application.css'; + +export default class Application extends Component { + state = { + loading: true, + fileHash: false + } + + componentDidMount () { + attachInterface() + .then((accounts, address, accountsInfo, contract, instance, fromAddress) => { + this.setState({ + accounts, + address, + accountsInfo, + contract, + instance, + fromAddress, + loading: false + }); + }); + } + + render () { + const { loading } = this.state; + + return loading + ? this.renderLoading() + : this.renderPage(); + } + + renderLoading () { + return ( + + ); + } + + renderPage () { + const { fileHash } = this.state; + + return ( +
+
+ + +
+
+
+
+ Provide a valid GitHub account, repo and { fileHash ? 'filename' : 'commit' } to register. The content information can be used in other contracts that allows for reverse lookups, e.g. image registries, dapp registries, etc. +
+
+
https://github.com/
+ +
+
+
commit #
+ +
+
+ +
+
+
+
+ ); + } + + onClickContentHash = () => { + this.setState({ fileHash: false }); + } + + onClickFileHash = () => { + this.setState({ fileHash: true }); + } +} diff --git a/js/src/dapps/githubhint/Application/index.js b/js/src/dapps/githubhint/Application/index.js new file mode 100644 index 00000000000..236578226a8 --- /dev/null +++ b/js/src/dapps/githubhint/Application/index.js @@ -0,0 +1,17 @@ +// 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 from './application'; diff --git a/js/src/dapps/githubhint/Button/button.css b/js/src/dapps/githubhint/Button/button.css new file mode 100644 index 00000000000..e4d16f9491c --- /dev/null +++ b/js/src/dapps/githubhint/Button/button.css @@ -0,0 +1,57 @@ +/* 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 . +*/ + +.button { + background: #08a; + color: white; + border-radius: 5px; + font-size: 1em; + line-height: 24px; + height: 24px; + padding: 0.75em 1.5em; + cursor: pointer; + display: inline-block; + width: 7.5em; + text-align: center; +} + +.button.first { + border-radius: 5px 0 0 5px; +} + +.button.middle { + border-radius: 0; +} + +.button.last { + border-radius: 0 5px 5px 0; +} + +.button.disabled { + opacity: 0.25; + cursor: default; +} + +.button.inverse { + color: #08a; + background: white; +} + +.button * { + display: inline-block; + vertical-align: top; +} diff --git a/js/src/dapps/githubhint/Button/button.js b/js/src/dapps/githubhint/Button/button.js new file mode 100644 index 00000000000..42fca1af7d4 --- /dev/null +++ b/js/src/dapps/githubhint/Button/button.js @@ -0,0 +1,53 @@ +// 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 styles from './button.css'; + +export default class Button extends Component { + static propTypes = { + children: PropTypes.node.isRequired, + className: PropTypes.string, + disabled: PropTypes.bool, + invert: PropTypes.bool, + first: PropTypes.bool, + last: PropTypes.bool, + middle: PropTypes.bool, + onClick: PropTypes.func.isRequired + } + + render () { + const { children, className, disabled, invert, first, last, middle } = this.props; + const classes = `${styles.button} ${disabled ? styles.disabled : ''} ${invert ? styles.inverse : ''} ${first ? styles.first : ''} ${last ? styles.last : ''} ${middle ? styles.middle : ''} ${className}`; + + return ( +
+ { children } +
+ ); + } + + onClick = (event) => { + const { disabled, onClick } = this.props; + + if (disabled) { + return; + } + + onClick(event); + } +} diff --git a/js/src/dapps/githubhint/Button/index.js b/js/src/dapps/githubhint/Button/index.js new file mode 100644 index 00000000000..f69a65e3d53 --- /dev/null +++ b/js/src/dapps/githubhint/Button/index.js @@ -0,0 +1,17 @@ +// 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 from './button'; diff --git a/js/src/dapps/githubhint/IdentityIcon/identityIcon.css b/js/src/dapps/githubhint/IdentityIcon/identityIcon.css new file mode 100644 index 00000000000..3fa1df99e4d --- /dev/null +++ b/js/src/dapps/githubhint/IdentityIcon/identityIcon.css @@ -0,0 +1,23 @@ +/* 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 . +*/ + +.icon { + width: 24px; + height: 24px; + border-radius: 50%; + margin-right: 0.5em; +} diff --git a/js/src/dapps/githubhint/IdentityIcon/identityIcon.js b/js/src/dapps/githubhint/IdentityIcon/identityIcon.js new file mode 100644 index 00000000000..0bc86731d45 --- /dev/null +++ b/js/src/dapps/githubhint/IdentityIcon/identityIcon.js @@ -0,0 +1,36 @@ +// 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 { api } from '../parity'; +import styles from './identityIcon.css'; + +export default class IdentityIcon extends Component { + static propTypes = { + address: PropTypes.string.isRequired + } + + render () { + const { address } = this.props; + + return ( + + ); + } +} diff --git a/js/src/dapps/githubhint/IdentityIcon/index.js b/js/src/dapps/githubhint/IdentityIcon/index.js new file mode 100644 index 00000000000..76c107bfb75 --- /dev/null +++ b/js/src/dapps/githubhint/IdentityIcon/index.js @@ -0,0 +1,17 @@ +// 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 from './identityIcon'; diff --git a/js/src/dapps/githubhint/Loading/index.js b/js/src/dapps/githubhint/Loading/index.js new file mode 100644 index 00000000000..0468cab37df --- /dev/null +++ b/js/src/dapps/githubhint/Loading/index.js @@ -0,0 +1,17 @@ +// 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 from './loading'; diff --git a/js/src/dapps/githubhint/Loading/loading.css b/js/src/dapps/githubhint/Loading/loading.css new file mode 100644 index 00000000000..b77d1a23725 --- /dev/null +++ b/js/src/dapps/githubhint/Loading/loading.css @@ -0,0 +1,24 @@ +/* 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 . +*/ + +.loading { + width: 100%; + text-align: center; + padding-top: 5em; + font-size: 2em; + color: #999; +} diff --git a/js/src/dapps/githubhint/Loading/loading.js b/js/src/dapps/githubhint/Loading/loading.js new file mode 100644 index 00000000000..b884597d763 --- /dev/null +++ b/js/src/dapps/githubhint/Loading/loading.js @@ -0,0 +1,29 @@ +// 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 } from 'react'; + +import styles from './loading.css'; + +export default class Loading extends Component { + render () { + return ( +
+ Attaching to contract ... +
+ ); + } +} diff --git a/js/src/dapps/githubhint/parity.js b/js/src/dapps/githubhint/parity.js new file mode 100644 index 00000000000..f6d59f44d57 --- /dev/null +++ b/js/src/dapps/githubhint/parity.js @@ -0,0 +1,21 @@ +// 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 . + +const { api } = window.parity; + +export { + api +}; diff --git a/js/src/dapps/githubhint/services.js b/js/src/dapps/githubhint/services.js new file mode 100644 index 00000000000..ee198ff6dfa --- /dev/null +++ b/js/src/dapps/githubhint/services.js @@ -0,0 +1,64 @@ +// 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 * as abis from '../../contracts/abi'; +import { api } from './parity'; + +export function attachInterface () { + return api.ethcore + .registryAddress() + .then((registryAddress) => { + console.log(`the registry was found at ${registryAddress}`); + + const registry = api.newContract(abis.registry, registryAddress).instance; + + return Promise + .all([ + registry.getAddress.call({}, [api.util.sha3('githubhint'), 'A']), + api.personal.listAccounts(), + api.personal.accountsInfo() + ]); + }) + .then(([address, addresses, accountsInfo]) => { + console.log(`githubhint was found at ${address}`); + + const contract = api.newContract(abis.githubhint, address); + const accounts = addresses.reduce((obj, address) => { + const info = accountsInfo[address]; + + return Object.assign(obj, { + [address]: { + address, + name: info.name || 'Unnamed', + uuid: info.uuid + } + }); + }, {}); + const fromAddress = Object.keys(accounts)[0]; + + return { + accounts, + address, + accountsInfo, + contract, + instance: contract.instance, + fromAddress + }; + }) + .catch((error) => { + console.error('attachInterface', error); + }); +} diff --git a/js/src/views/Dapps/dapps.js b/js/src/views/Dapps/dapps.js index f341b3fa42c..f975d8c8243 100644 --- a/js/src/views/Dapps/dapps.js +++ b/js/src/views/Dapps/dapps.js @@ -59,6 +59,11 @@ class Dapps extends Component { name: 'Method Registry', description: 'A registry of method signatures for lookups on transactions', url: 'signaturereg' + }, + { + name: 'GitHub Hint', + description: 'A mapping of GitHub URLs to hashes for use in contracts as references', + url: 'githubhint' } ] } diff --git a/js/webpack.config.js b/js/webpack.config.js index 178578bbcfe..fbd454e0700 100644 --- a/js/webpack.config.js +++ b/js/webpack.config.js @@ -34,6 +34,7 @@ module.exports = { // dapps 'basiccoin': ['./dapps/basiccoin.js'], 'gavcoin': ['./dapps/gavcoin.js'], + 'githubhint': ['./dapps/githubhint.js'], 'registry': ['./dapps/registry.js'], 'signaturereg': ['./dapps/signaturereg.js'], 'tokenreg': ['./dapps/tokenreg.js'], From 6ced51d2db8c624fff0df1ae0ee495747e69cc0d Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Sat, 8 Oct 2016 00:09:33 +0200 Subject: [PATCH 2/5] single input for commit/filename --- js/src/dapps/githubhint/Application/application.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/js/src/dapps/githubhint/Application/application.js b/js/src/dapps/githubhint/Application/application.js index 6ed3633be8b..92232a83005 100644 --- a/js/src/dapps/githubhint/Application/application.js +++ b/js/src/dapps/githubhint/Application/application.js @@ -73,11 +73,11 @@ export default class Application extends Component {
https://github.com/
- +
-
-
commit #
- +
+
{ fileHash ? '/' : 'commit #' }
+
From 25debcfe166d1545890e409fdc055bb76db5a4ce Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Sat, 8 Oct 2016 09:02:21 +0200 Subject: [PATCH 3/5] ethcore_hashContent call --- js/src/api/rpc/ethcore/ethcore.js | 5 +++++ js/src/jsonrpc/interfaces/ethcore.js | 16 +++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/js/src/api/rpc/ethcore/ethcore.js b/js/src/api/rpc/ethcore/ethcore.js index 8efdb7a3615..1ccc95bbadc 100644 --- a/js/src/api/rpc/ethcore/ethcore.js +++ b/js/src/api/rpc/ethcore/ethcore.js @@ -68,6 +68,11 @@ export default class Ethcore { .execute('ethcore_generateSecretPhrase'); } + hashContent (url) { + return this._transport + .execute('ethcore_hashContent', url); + } + minGasPrice () { return this._transport .execute('ethcore_minGasPrice') diff --git a/js/src/jsonrpc/interfaces/ethcore.js b/js/src/jsonrpc/interfaces/ethcore.js index 735b08ff9f6..7cea0473d83 100644 --- a/js/src/jsonrpc/interfaces/ethcore.js +++ b/js/src/jsonrpc/interfaces/ethcore.js @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -import { Address, Data, Quantity } from '../types'; +import { Address, Data, Hash, Quantity } from '../types'; export default { acceptNonReservedPeers: { @@ -104,6 +104,20 @@ export default { } }, + hashContent: { + desc: 'Creates a hash of the file as retrieved', + params: [ + { + type: String, + desc: 'The url of the content' + } + ], + returns: { + types: Hash, + desc: 'The hash of the content' + } + }, + minGasPrice: { desc: 'Returns currently set minimal gas price', params: [], From 87af4738c6fd83737495494f80a802669923571a Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Sat, 8 Oct 2016 10:19:16 +0200 Subject: [PATCH 4/5] lookup hash --- .../githubhint/Application/application.css | 27 ++++-- .../githubhint/Application/application.js | 87 ++++++++++++++----- js/src/dapps/githubhint/Button/button.css | 1 - 3 files changed, 84 insertions(+), 31 deletions(-) diff --git a/js/src/dapps/githubhint/Application/application.css b/js/src/dapps/githubhint/Application/application.css index 476ee0e5668..0a73597dd40 100644 --- a/js/src/dapps/githubhint/Application/application.css +++ b/js/src/dapps/githubhint/Application/application.css @@ -35,6 +35,7 @@ padding: 2em; background: rgba(255, 255, 255, 0.1); border-radius: 5px; + margin-bottom: 2em; } .buttons { @@ -56,13 +57,9 @@ .capture { } -.capture+.capture { - margin-top: 1em; -} - .capture * { display: inline-block; - padding: 0.5em 0.5em; + padding: 0.75em; vertical-align: middle; box-sizing: border-box; width: 20em; @@ -73,10 +70,28 @@ background: #eee; border: none; border-radius: 5px; - width: 20em; + width: 100%; font-size: 1em; } +.capture input.error { + background: #fcc; +} + .capture[disabled] { opacity: 0.15; } + +.hashError { + padding-top: 0.5em; + color: #f66; + text-align: center; + font-size: 0.75em; +} + +.hashOk { + padding-top: 0.5em; + opacity: 0.5; + text-align: center; + font-size: 0.75em; +} diff --git a/js/src/dapps/githubhint/Application/application.js b/js/src/dapps/githubhint/Application/application.js index 92232a83005..a28f60e62a0 100644 --- a/js/src/dapps/githubhint/Application/application.js +++ b/js/src/dapps/githubhint/Application/application.js @@ -16,29 +16,29 @@ import React, { Component } from 'react'; +import { api } from '../parity'; import { attachInterface } from '../services'; import Button from '../Button'; import Loading from '../Loading'; import styles from './application.css'; +const INVALID_URL_HASH = '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470'; + export default class Application extends Component { state = { loading: true, - fileHash: false + url: '', + urlError: null, + contentHash: null, + contentHashError: null } componentDidMount () { attachInterface() - .then((accounts, address, accountsInfo, contract, instance, fromAddress) => { - this.setState({ - accounts, - address, - accountsInfo, - contract, - instance, - fromAddress, - loading: false + .then((state) => { + this.setState(state, () => { + this.setState({ loading: false }); }); }); } @@ -58,29 +58,30 @@ export default class Application extends Component { } renderPage () { - const { fileHash } = this.state; + const { url, urlError, contentHash, contentHashError } = this.state; return (
-
- - -
- Provide a valid GitHub account, repo and { fileHash ? 'filename' : 'commit' } to register. The content information can be used in other contracts that allows for reverse lookups, e.g. image registries, dapp registries, etc. + Provide a valid URL to register. The content information can be used in other contracts that allows for reverse lookups, e.g. image registries, dapp registries, etc.
-
https://github.com/
- +
-
-
{ fileHash ? '/' : 'commit #' }
- +
+ { contentHashError || contentHash }
- +
@@ -89,10 +90,48 @@ export default class Application extends Component { } onClickContentHash = () => { - this.setState({ fileHash: false }); + this.setState({ fileHash: false, commit: '' }); } onClickFileHash = () => { - this.setState({ fileHash: true }); + this.setState({ fileHash: true, commit: 0 }); + } + + onChangeUrl = (event) => { + const url = event.target.value; + let urlError = null; + + if (url && url.length) { + var re = /^https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}/g; + urlError = re.test(url) + ? null + : 'not matching rexex'; + } + + this.setState({ url, urlError, contentHashError: 'hash lookup in progress' }, () => { + this.lookupHash(); + }); + } + + onClickRegister = (event) => { + } + + lookupHash () { + const { url } = this.state; + + api.ethcore + .hashContent(url) + .then((contentHash) => { + console.log('lookupHash', contentHash); + if (contentHash === INVALID_URL_HASH) { + this.setState({ contentHashError: 'invalid url endpoint', contentHash }); + } else { + this.setState({ contentHashError: null, contentHash }); + } + }) + .catch((error) => { + console.error('lookupHash', error); + this.setState({ contentHashError: error.message, contentHash: null }); + }); } } diff --git a/js/src/dapps/githubhint/Button/button.css b/js/src/dapps/githubhint/Button/button.css index e4d16f9491c..28519094b2e 100644 --- a/js/src/dapps/githubhint/Button/button.css +++ b/js/src/dapps/githubhint/Button/button.css @@ -25,7 +25,6 @@ padding: 0.75em 1.5em; cursor: pointer; display: inline-block; - width: 7.5em; text-align: center; } From 58b1fb73a66c621ae994cb1dc792c4415f9dd87c Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Sat, 8 Oct 2016 11:03:29 +0200 Subject: [PATCH 5/5] registration in place --- .../githubhint/Application/application.css | 36 ++++- .../githubhint/Application/application.js | 148 ++++++++++++++++-- 2 files changed, 165 insertions(+), 19 deletions(-) diff --git a/js/src/dapps/githubhint/Application/application.css b/js/src/dapps/githubhint/Application/application.css index 0a73597dd40..aa4a68dc697 100644 --- a/js/src/dapps/githubhint/Application/application.css +++ b/js/src/dapps/githubhint/Application/application.css @@ -46,6 +46,13 @@ .box .buttons { text-align: right; margin: 2em 0 0 0; + position: relative; +} + +.box .buttons .addressSelect { + position: absolute; + top: 0; + left: 0; } .box .description { @@ -54,6 +61,24 @@ opacity: 0.75; } +.progress { + margin: 2em 0 0 0; + opacity: 0.75; + text-align: center; +} + +.statusHeader { + font-size: 1em; +} + +.statusState, .statusError { + padding: 1em 0 0 0; +} + +.statusError { + color: #f66; +} + .capture { } @@ -72,26 +97,25 @@ border-radius: 5px; width: 100%; font-size: 1em; + text-align: center; } -.capture input.error { - background: #fcc; +.capture input[disabled] { + opacity: 0.5; } -.capture[disabled] { - opacity: 0.15; +.capture input.error { + background: #fcc; } .hashError { padding-top: 0.5em; color: #f66; text-align: center; - font-size: 0.75em; } .hashOk { padding-top: 0.5em; opacity: 0.5; text-align: center; - font-size: 0.75em; } diff --git a/js/src/dapps/githubhint/Application/application.js b/js/src/dapps/githubhint/Application/application.js index a28f60e62a0..37b7a817654 100644 --- a/js/src/dapps/githubhint/Application/application.js +++ b/js/src/dapps/githubhint/Application/application.js @@ -19,19 +19,24 @@ import React, { Component } from 'react'; import { api } from '../parity'; import { attachInterface } from '../services'; import Button from '../Button'; +import IdentityIcon from '../IdentityIcon'; import Loading from '../Loading'; import styles from './application.css'; const INVALID_URL_HASH = '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470'; +const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; export default class Application extends Component { state = { loading: true, url: '', urlError: null, - contentHash: null, - contentHashError: null + contentHash: '', + contentHashError: null, + registerBusy: false, + registerError: null, + registerState: '' } componentDidMount () { @@ -58,7 +63,7 @@ export default class Application extends Component { } renderPage () { - const { url, urlError, contentHash, contentHashError } = this.state; + const { registerBusy, url, urlError, contentHash, contentHashError } = this.state; return (
@@ -71,6 +76,7 @@ export default class Application extends Component { @@ -78,17 +84,60 @@ export default class Application extends Component {
{ contentHashError || contentHash }
-
- -
+ { registerBusy ? this.renderProgress() : this.renderButtons() }
); } + renderButtons () { + const { accounts, fromAddress, url, urlError, contentHashError } = this.state; + const account = accounts[fromAddress]; + + return ( +
+
+ +
+ +
+ ); + } + + renderProgress () { + const { registerError, registerState } = this.state; + + if (registerError) { + return ( +
+
+ Your registration has encountered an error +
+
+ { registerError } +
+
+ ); + } + + return ( +
+
+ Your URL is being registered +
+
+ { registerState } +
+
+ ); + } + onClickContentHash = () => { this.setState({ fileHash: false, commit: '' }); } @@ -113,21 +162,94 @@ export default class Application extends Component { }); } - onClickRegister = (event) => { + onClickRegister = () => { + const { url, urlError, contentHash, contentHashError, fromAddress, instance } = this.state; + + if (!!contentHashError || !!urlError || url.length === 0) { + return; + } + + this.setState({ registerBusy: true, registerState: 'Estimating gas for the transaction' }); + + const values = [contentHash, url]; + const options = { from: fromAddress }; + + instance + .hintURL.estimateGas(options, values) + .then((gas) => { + this.setState({ registerState: 'Gas estimated, Posting transaction to the network' }); + + const gasPassed = gas.mul(1.2); + options.gas = gasPassed.toFixed(0); + console.log(`gas estimated at ${gas.toFormat(0)}, passing ${gasPassed.toFormat(0)}`); + + return instance.hintURL.postTransaction(options, values); + }) + .then((signerRequestId) => { + this.setState({ signerRequestId, registerState: 'Transaction posted, Waiting for transaction authorization' }); + + return api.pollMethod('eth_checkRequest', signerRequestId); + }) + .then((txHash) => { + this.setState({ txHash, registerState: 'Transaction authorized, Waiting for network confirmations' }); + + return api.pollMethod('eth_getTransactionReceipt', txHash, (receipt) => { + if (!receipt || !receipt.blockNumber || receipt.blockNumber.eq(0)) { + return false; + } + + return true; + }); + }) + .then((txReceipt) => { + this.setState({ txReceipt, registerBusy: false, registerState: 'Network confirmed, Received transaction receipt', url: '', contentHash: '' }); + }) + .catch((error) => { + console.error('onSend', error); + this.setState({ registerError: error.message }); + }); + } + + onSelectFromAddress = () => { + const { accounts, fromAddress } = this.state; + const addresses = Object.keys(accounts); + let index = 0; + + addresses.forEach((address, _index) => { + if (address === fromAddress) { + index = _index; + } + }); + + index++; + if (index >= addresses.length) { + index = 0; + } + + this.setState({ fromAddress: addresses[index] }); } lookupHash () { - const { url } = this.state; + const { url, instance } = this.state; api.ethcore .hashContent(url) .then((contentHash) => { console.log('lookupHash', contentHash); if (contentHash === INVALID_URL_HASH) { - this.setState({ contentHashError: 'invalid url endpoint', contentHash }); - } else { - this.setState({ contentHashError: null, contentHash }); + this.setState({ contentHashError: 'invalid url endpoint', contentHash: null }); + return; } + + instance.entries + .call({}, [contentHash]) + .then(([accountSlashRepo, commit, owner]) => { + if (owner !== ZERO_ADDRESS) { + this.setState({ contentHashError: contentHash, contentHash: null }); + } else { + this.setState({ contentHashError: null, contentHash }); + } + }); }) .catch((error) => { console.error('lookupHash', error);