Emulate signer pubsub on public node

This commit is contained in:
maciejhirsz 2017-10-11 16:21:44 +02:00
parent 0bb845a05c
commit 0c86357187
8 changed files with 107 additions and 29 deletions

View File

@ -47,13 +47,6 @@ export default class Api extends EventEmitter {
this._trace = new Trace(transport);
this._web3 = new Web3(transport);
if (isFunction(transport.subscribe)) {
this._pubsub = new Pubsub(transport);
}
if (allowSubscriptions) {
this._subscriptions = new Subscriptions(this);
}
// Doing a request here in test env would cause an error
if (LocalAccountsMiddleware && process.env.NODE_ENV !== 'test') {
const middleware = this.parity
@ -69,6 +62,14 @@ export default class Api extends EventEmitter {
transport.addMiddleware(middleware);
}
if (isFunction(transport.subscribe)) {
this._pubsub = new Pubsub(transport);
}
if (allowSubscriptions) {
this._subscriptions = new Subscriptions(this);
}
}
get isPubSub () {

View File

@ -18,11 +18,12 @@ import Account from './account';
import localStore from 'store';
import { debounce } from 'lodash';
import { decryptPrivateKey } from '../ethkey';
import EventEmitter from 'eventemitter3';
const NULL_ADDRESS = '0x0000000000000000000000000000000000000000';
const LS_STORE_KEY = '_parity::localAccounts';
export default class Accounts {
export default class Accounts extends EventEmitter {
persist = debounce(() => {
this._lastState = JSON.stringify(this);
@ -30,6 +31,8 @@ export default class Accounts {
}, 100);
constructor (data = localStore.get(LS_STORE_KEY) || {}) {
super();
this._lastState = JSON.stringify(data);
window.addEventListener('storage', ({ key, newValue }) => {
@ -130,6 +133,8 @@ export default class Accounts {
set dappsDefaultAddress (value) {
this._dappsDefaultAddress = value.toLowerCase();
this.emit('dappsDefaultAddressChange', this._dappsDefaultAddress);
this.persist();
}

View File

@ -26,7 +26,9 @@ export default class LocalAccountsMiddleware extends Middleware {
constructor (transport) {
super(transport);
const NOOP = () => {};
const register = this.register.bind(this);
const registerSubscribe = this.registerSubscribe.bind(this);
register('eth_accounts', () => {
return accounts.accountAddresses();
@ -76,6 +78,14 @@ export default class LocalAccountsMiddleware extends Middleware {
return accounts.dappsDefaultAddress;
});
registerSubscribe('parity_defaultAccount', (_, callback) => {
callback(null, accounts.dappsDefaultAddress);
accounts.on('dappsDefaultAddressChange', (address) => {
callback(null, accounts.dappsDefaultAddress);
});
});
register('parity_exportAccount', ([address, password]) => {
const account = accounts.get(address);
@ -109,6 +119,8 @@ export default class LocalAccountsMiddleware extends Middleware {
return {};
});
registerSubscribe('parity_hardwareAccountsInfo', NOOP);
register('parity_newAccountFromPhrase', ([phrase, password]) => {
return phraseToWallet(phrase)
.then((wallet) => {
@ -278,5 +290,15 @@ export default class LocalAccountsMiddleware extends Middleware {
register('signer_requestsToConfirm', () => {
return transactions.requestsToConfirm();
});
registerSubscribe('signer_subscribePending', (_, callback) => {
callback(null, transactions.requestsToConfirm());
transactions.on('update', () => {
callback(null, transactions.requestsToConfirm());
});
return false;
});
}
}

View File

@ -16,14 +16,17 @@
import { toHex } from '../util/format';
import { TransportError } from '../transport';
import EventEmitter from 'eventemitter3';
const AWAITING = Symbol('awaiting');
const LOCKED = Symbol('locked');
const CONFIRMED = Symbol('confirmed');
const REJECTED = Symbol('rejected');
class Transactions {
class Transactions extends EventEmitter {
constructor () {
super();
this.reset();
}
@ -45,6 +48,8 @@ class Transactions {
transaction: tx
};
this.emit('update');
return id;
}
@ -66,6 +71,8 @@ class Transactions {
}
state.status = LOCKED;
this.emit('update');
}
unlock (id) {
@ -76,6 +83,8 @@ class Transactions {
}
state.status = AWAITING;
this.emit('update');
}
hash (id) {
@ -107,6 +116,8 @@ class Transactions {
state.hash = hash;
state.status = CONFIRMED;
this.emit('update');
}
reject (id) {
@ -118,6 +129,8 @@ class Transactions {
state.status = REJECTED;
this.emit('update');
return true;
}

View File

@ -17,7 +17,7 @@ import PubsubBase from '../pubsubBase';
import { outSignerRequest } from '../../format/output';
export default class Net extends PubsubBase {
export default class Signer extends PubsubBase {
constructor (transport) {
super(transport);
this._api = {

View File

@ -38,26 +38,32 @@ export default class Signer {
start () {
this._started = true;
if (this._api.isPubSub) {
const subscription = this._api.pubsub
.subscribeAndGetResult(
callback => this._api.pubsub.signer.pendingRequests(callback),
requests => {
this.updateSubscriptions(requests);
return requests;
}
);
return this
._api
.transport
.ready
.then(() => {
if (this._api.isPubSub) {
const subscription = this._api.pubsub
.subscribeAndGetResult(
callback => this._api.pubsub.signer.pendingRequests(callback),
requests => {
this.updateSubscriptions(requests);
return requests;
}
);
return Promise.all([
this._listRequests(false),
subscription
]);
}
return Promise.all([
this._listRequests(false),
subscription
]);
}
return Promise.all([
this._listRequests(true),
this._loggingSubscribe()
]);
return Promise.all([
this._listRequests(true),
this._loggingSubscribe()
]);
});
}
updateSubscriptions (requests) {

View File

@ -31,6 +31,10 @@ export default class JsonRpcBase extends EventEmitter {
this._middlewareList = Promise.resolve([]);
}
get ready () {
return this._middlewareList.then(() => true);
}
encode (method, params) {
const json = JSON.stringify({
jsonrpc: '2.0',

View File

@ -17,7 +17,20 @@
export default class Middleware {
constructor (transport) {
this._transport = transport;
this._subscribe = transport.subscribe;
transport.subscribe = this.handleSubscribe.bind(this);
this._handlers = {};
this._subHandlers = {};
}
registerSubscribe (method, handler) {
if (method in this._subHandlers) {
throw new Error(`${method} is already defined in the middleware!`);
}
this._subHandlers[method] = handler;
}
register (method, handler) {
@ -28,10 +41,24 @@ export default class Middleware {
this._handlers[method] = handler;
}
handleSubscribe (api, callback, event) {
// Don't ask
const method = api.subscribe ? api.subscribe : event[0];
const params = event.length === 2 ? event[1] : event;
const handler = this._subHandlers[method];
if (handler) {
return handler(params, callback);
}
this._subscribe.call(this._transport, api, callback, event);
}
handle (method, params) {
const handler = this._handlers[method];
if (handler != null) {
if (handler) {
return handler(params);
}