Skip to content
This repository was archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
Merge pull request #5304 from paritytech/mh-webserver
Browse files Browse the repository at this point in the history
Public node with accounts and signing in Frontend
  • Loading branch information
maciejhirsz authored Mar 29, 2017
2 parents 93ee2a9 + 54196a8 commit ab2c346
Show file tree
Hide file tree
Showing 45 changed files with 9,060 additions and 89 deletions.
2 changes: 1 addition & 1 deletion ethkey/src/brain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ impl Brain {
impl Generator for Brain {
fn generate(self) -> Result<KeyPair, Error> {
let seed = self.0;
let mut secret = seed.bytes().collect::<Vec<u8>>().keccak256();
let mut secret = seed.into_bytes().keccak256();

let mut i = 0;
loop {
Expand Down
2 changes: 2 additions & 0 deletions js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@
"geopattern": "1.2.3",
"isomorphic-fetch": "2.2.1",
"js-sha3": "0.5.5",
"keythereum": "0.4.3",
"lodash": "4.17.2",
"loglevel": "1.4.1",
"marked": "0.3.6",
Expand Down Expand Up @@ -207,6 +208,7 @@
"redux-thunk": "2.1.0",
"rlp": "2.0.0",
"scryptsy": "2.0.0",
"secp256k1": "3.2.5",
"solc": "ngotchac/solc-js",
"store": "1.3.20",
"sw-toolbox": "^3.6.0",
Expand Down
16 changes: 16 additions & 0 deletions js/src/api/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { Db, Eth, Parity, Net, Personal, Shh, Signer, Trace, Web3 } from './rpc'
import Subscriptions from './subscriptions';
import util from './util';
import { isFunction } from './util/types';
import { LocalAccountsMiddleware } from './local';

export default class Api extends EventEmitter {
constructor (transport) {
Expand All @@ -45,6 +46,21 @@ export default class Api extends EventEmitter {
this._web3 = new Web3(transport);

this._subscriptions = new Subscriptions(this);

// Doing a request here in test env would cause an error
if (process.env.NODE_ENV !== 'test') {
const middleware = this.parity
.nodeKind()
.then((nodeKind) => {
if (nodeKind.availability === 'public') {
return new LocalAccountsMiddleware(transport);
}

return null;
});

transport.addMiddleware(middleware);
}
}

get db () {
Expand Down
95 changes: 95 additions & 0 deletions js/src/api/local/accounts/account.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// 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 <http://www.gnu.org/licenses/>.

import { keythereum } from '../ethkey';

export default class Account {
constructor (persist, data) {
const {
keyObject,
meta = {},
name = ''
} = data;

this._persist = persist;
this._keyObject = keyObject;
this._name = name;
this._meta = meta;
}

isValidPassword (password) {
try {
keythereum.recover(Buffer.from(password), this._keyObject);
return true;
} catch (e) {
return false;
}
}

get address () {
return `0x${this._keyObject.address.toLowerCase()}`;
}

get name () {
return this._name;
}

set name (name) {
this._name = name;

this._persist();
}

get meta () {
return JSON.stringify(this._meta);
}

set meta (meta) {
this._meta = JSON.parse(meta);

this._persist();
}

get uuid () {
return this._keyObject.id;
}

decryptPrivateKey (password) {
return keythereum.recover(Buffer.from(password), this._keyObject);
}

static fromPrivateKey (persist, key, password) {
const iv = keythereum.crypto.randomBytes(16);
const salt = keythereum.crypto.randomBytes(32);

// Keythereum will fail if `password` is an empty string
password = Buffer.from(password);

const keyObject = keythereum.dump(password, key, salt, iv);

const account = new Account(persist, { keyObject });

return account;
}

toJSON () {
return {
keyObject: this._keyObject,
name: this._name,
meta: this._meta
};
}
}
120 changes: 120 additions & 0 deletions js/src/api/local/accounts/accounts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// 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 <http://www.gnu.org/licenses/>.

import Account from './account';
import localStore from 'store';
import { debounce } from 'lodash';

const NULL_ADDRESS = '0x0000000000000000000000000000000000000000';
const LS_STORE_KEY = '_parity::localAccounts';

export default class Accounts {
constructor (data = localStore.get(LS_STORE_KEY) || {}) {
const {
last = NULL_ADDRESS,
store = []
} = data;

this.persist = debounce(() => {
localStore.set(LS_STORE_KEY, this);
}, 100);

this._last = last;
this._store = store.map((data) => new Account(this.persist, data));
}

create (secret, password) {
const privateKey = Buffer.from(secret.slice(2), 'hex');
const account = Account.fromPrivateKey(this.persist, privateKey, password);

this._store.push(account);
this.lastAddress = account.address;

this.persist();

return account.address;
}

set lastAddress (value) {
this._last = value.toLowerCase();
}

get lastAddress () {
return this._last;
}

get (address) {
address = address.toLowerCase();

this.lastAddress = address;

const account = this._store.find((account) => account.address === address);

if (!account) {
throw new Error(`Account not found: ${address}`);
}

return account;
}

remove (address, password) {
address = address.toLowerCase();

const index = this._store.findIndex((account) => account.address === address);

if (index === -1) {
return false;
}

const account = this._store[index];

if (!account.isValidPassword(password)) {
console.log('invalid password');
return false;
}

if (address === this.lastAddress) {
this.lastAddress = NULL_ADDRESS;
}

this._store.splice(index, 1);

this.persist();

return true;
}

mapArray (mapper) {
return this._store.map(mapper);
}

mapObject (mapper) {
const result = {};

this._store.forEach((account) => {
result[account.address] = mapper(account);
});

return result;
}

toJSON () {
return {
last: this._last,
store: this._store
};
}
}
21 changes: 21 additions & 0 deletions js/src/api/local/accounts/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// 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 <http://www.gnu.org/licenses/>.

import Accounts from './accounts';

const accounts = new Accounts();

export default accounts;
Loading

0 comments on commit ab2c346

Please sign in to comment.