diff --git a/js/scripts/test.js b/js/scripts/test.js
index e426642db..e60e3cb6c 100644
--- a/js/scripts/test.js
+++ b/js/scripts/test.js
@@ -1 +1 @@
-// test script 10
+// test script 11
diff --git a/js/src/contracts/abi/index.js b/js/src/contracts/abi/index.js
index f475cce07..eac825820 100644
--- a/js/src/contracts/abi/index.js
+++ b/js/src/contracts/abi/index.js
@@ -29,3 +29,4 @@ export signaturereg from './signaturereg.json';
export smsverification from './sms-verification.json';
export tokenreg from './tokenreg.json';
export foundationWallet from './foundation-multisig-wallet.json';
+export vouchfor from './vouchfor.json';
diff --git a/js/src/contracts/abi/vouchfor.json b/js/src/contracts/abi/vouchfor.json
new file mode 100644
index 000000000..362eb0c8b
--- /dev/null
+++ b/js/src/contracts/abi/vouchfor.json
@@ -0,0 +1 @@
+[{"constant":true,"inputs":[],"name":"certifier","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_what","type":"bytes32"}],"name":"vouch","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_what","type":"bytes32"},{"name":"_index","type":"uint256"}],"name":"vouched","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_what","type":"bytes32"},{"name":"_index","type":"uint256"}],"name":"unvouch","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"},{"name":"","type":"uint256"}],"name":"vouchers","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_certifier","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"who","type":"address"},{"indexed":false,"name":"what","type":"bytes32"}],"name":"Vouched","type":"event"}]
diff --git a/js/src/ui/DappCard/dappCard.js b/js/src/ui/DappCard/dappCard.js
index cc0faf47d..0e3f65fcc 100644
--- a/js/src/ui/DappCard/dappCard.js
+++ b/js/src/ui/DappCard/dappCard.js
@@ -19,6 +19,7 @@ import React, { Component, PropTypes } from 'react';
import Container, { Title as ContainerTitle } from '~/ui/Container';
import DappIcon from '~/ui/DappIcon';
import Tags from '~/ui/Tags';
+import DappVouchFor from '../DappVouchFor';
import styles from './dappCard.css';
@@ -61,6 +62,7 @@ export default class DappCard extends Component {
app={ app }
className={ styles.image }
/>
+
.
+*/
+
+.tag {
+ color: inherit;
+ position: absolute;
+ top: 1em;
+ right: 1em;
+
+ .image {
+ position: absolute;
+ right: 0;
+ top: 0;
+ width: 32px;
+ height: 32px;
+ }
+
+ .bubble {
+ background: red;
+ border-radius: 0.25em;
+ color: white;
+ font-size: 0.75em;
+ padding: 0.1em 0.5em;
+ position: absolute;
+ right: 0;
+ top: 0;
+ z-index: 100;
+ }
+}
diff --git a/js/src/ui/DappVouchFor/dappVouchFor.js b/js/src/ui/DappVouchFor/dappVouchFor.js
new file mode 100644
index 000000000..426c881cd
--- /dev/null
+++ b/js/src/ui/DappVouchFor/dappVouchFor.js
@@ -0,0 +1,57 @@
+// Copyright 2015-2017 Parity Technologies (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 { observer } from 'mobx-react';
+
+import IdentityIcon from '../IdentityIcon';
+
+import Store from './store';
+import styles from './dappVouchFor.css';
+
+@observer
+export default class DappVouchFor extends Component {
+ static contextTypes = {
+ api: PropTypes.object.isRequired
+ };
+
+ static propTypes = {
+ app: PropTypes.object.isRequired
+ };
+
+ store = new Store(this.context.api, this.props.app);
+
+ render () {
+ const count = this.store.vouchers.length;
+
+ if (!count) {
+ return null;
+ }
+
+ return (
+
+ );
+ }
+}
diff --git a/js/src/ui/DappVouchFor/index.js b/js/src/ui/DappVouchFor/index.js
new file mode 100644
index 000000000..be61d5029
--- /dev/null
+++ b/js/src/ui/DappVouchFor/index.js
@@ -0,0 +1,17 @@
+// Copyright 2015-2017 Parity Technologies (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 './dappVouchFor';
diff --git a/js/src/ui/DappVouchFor/store.js b/js/src/ui/DappVouchFor/store.js
new file mode 100644
index 000000000..cee44749d
--- /dev/null
+++ b/js/src/ui/DappVouchFor/store.js
@@ -0,0 +1,74 @@
+// Copyright 2015-2017 Parity Technologies (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 { action, observable } from 'mobx';
+import { uniq } from 'lodash';
+
+import Contracts from '~/contracts';
+import { vouchfor as vouchForAbi } from '~/contracts/abi';
+
+export default class Store {
+ @observable vouchers = [];
+
+ constructor (api, app) {
+ this._api = api;
+
+ const { contentHash } = app;
+
+ if (contentHash) {
+ this.lookupVouchers(contentHash);
+ }
+ }
+
+ lookupVouchers (contentHash) {
+ Contracts
+ .get().registry
+ .lookupAddress('vouchfor')
+ .then((address) => {
+ if (!address || /^0x0*$/.test(address)) {
+ return;
+ }
+
+ return this._api.newContract(vouchForAbi, address);
+ })
+ .then(async (contract) => {
+ if (!contract) {
+ return;
+ }
+
+ let lastItem = false;
+
+ for (let index = 0; !lastItem; index++) {
+ const voucher = await contract.instance.vouched.call({}, [`0x${contentHash}`, index]);
+
+ if (/^0x0*$/.test(voucher)) {
+ lastItem = true;
+ } else {
+ this.addVoucher(voucher);
+ }
+ }
+ })
+ .catch((error) => {
+ console.error('vouchFor', error);
+
+ return;
+ });
+ }
+
+ @action addVoucher = (voucher) => {
+ this.vouchers = uniq([].concat(this.vouchers.peek(), [voucher]));
+ }
+}
diff --git a/js/src/ui/IdentityIcon/identityIcon.js b/js/src/ui/IdentityIcon/identityIcon.js
index 3db1bc763..0d31b6bb5 100644
--- a/js/src/ui/IdentityIcon/identityIcon.js
+++ b/js/src/ui/IdentityIcon/identityIcon.js
@@ -30,6 +30,7 @@ class IdentityIcon extends Component {
static propTypes = {
address: PropTypes.string,
+ alt: PropTypes.string,
button: PropTypes.bool,
center: PropTypes.bool,
className: PropTypes.string,
@@ -84,7 +85,7 @@ class IdentityIcon extends Component {
}
render () {
- const { address, button, className, center, disabled, inline, padded, tiny } = this.props;
+ const { address, alt, button, className, center, disabled, inline, padded, tiny } = this.props;
const { iconsrc } = this.state;
const classes = [
styles.icon,
@@ -135,6 +136,7 @@ class IdentityIcon extends Component {
return (
{
expect(component).to.be.ok;
});
- describe.only('isMarkdown', () => {
+ describe('isMarkdown', () => {
it('returns true for markdown', () => {
const testMd = '# this is some\n\n*markdown*';
const encodedMd = asciiToHex(unescape(encodeURIComponent(testMd)));
@@ -99,7 +99,7 @@ describe('views/Signer/components/SignRequest', () => {
expect(isMarkdown(encodedMd)).to.be.true;
});
- it('returns false for randow data', () => {
+ it('returns false for random data', () => {
expect(isMarkdown('0x1234')).to.be.false;
});
});