Emulate signer pubsub on public node
This commit is contained in:
parent
0bb845a05c
commit
0c86357187
@ -47,13 +47,6 @@ export default class Api extends EventEmitter {
|
|||||||
this._trace = new Trace(transport);
|
this._trace = new Trace(transport);
|
||||||
this._web3 = new Web3(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
|
// Doing a request here in test env would cause an error
|
||||||
if (LocalAccountsMiddleware && process.env.NODE_ENV !== 'test') {
|
if (LocalAccountsMiddleware && process.env.NODE_ENV !== 'test') {
|
||||||
const middleware = this.parity
|
const middleware = this.parity
|
||||||
@ -69,6 +62,14 @@ export default class Api extends EventEmitter {
|
|||||||
|
|
||||||
transport.addMiddleware(middleware);
|
transport.addMiddleware(middleware);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isFunction(transport.subscribe)) {
|
||||||
|
this._pubsub = new Pubsub(transport);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allowSubscriptions) {
|
||||||
|
this._subscriptions = new Subscriptions(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get isPubSub () {
|
get isPubSub () {
|
||||||
|
@ -18,11 +18,12 @@ import Account from './account';
|
|||||||
import localStore from 'store';
|
import localStore from 'store';
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from 'lodash';
|
||||||
import { decryptPrivateKey } from '../ethkey';
|
import { decryptPrivateKey } from '../ethkey';
|
||||||
|
import EventEmitter from 'eventemitter3';
|
||||||
|
|
||||||
const NULL_ADDRESS = '0x0000000000000000000000000000000000000000';
|
const NULL_ADDRESS = '0x0000000000000000000000000000000000000000';
|
||||||
const LS_STORE_KEY = '_parity::localAccounts';
|
const LS_STORE_KEY = '_parity::localAccounts';
|
||||||
|
|
||||||
export default class Accounts {
|
export default class Accounts extends EventEmitter {
|
||||||
persist = debounce(() => {
|
persist = debounce(() => {
|
||||||
this._lastState = JSON.stringify(this);
|
this._lastState = JSON.stringify(this);
|
||||||
|
|
||||||
@ -30,6 +31,8 @@ export default class Accounts {
|
|||||||
}, 100);
|
}, 100);
|
||||||
|
|
||||||
constructor (data = localStore.get(LS_STORE_KEY) || {}) {
|
constructor (data = localStore.get(LS_STORE_KEY) || {}) {
|
||||||
|
super();
|
||||||
|
|
||||||
this._lastState = JSON.stringify(data);
|
this._lastState = JSON.stringify(data);
|
||||||
|
|
||||||
window.addEventListener('storage', ({ key, newValue }) => {
|
window.addEventListener('storage', ({ key, newValue }) => {
|
||||||
@ -130,6 +133,8 @@ export default class Accounts {
|
|||||||
set dappsDefaultAddress (value) {
|
set dappsDefaultAddress (value) {
|
||||||
this._dappsDefaultAddress = value.toLowerCase();
|
this._dappsDefaultAddress = value.toLowerCase();
|
||||||
|
|
||||||
|
this.emit('dappsDefaultAddressChange', this._dappsDefaultAddress);
|
||||||
|
|
||||||
this.persist();
|
this.persist();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,9 @@ export default class LocalAccountsMiddleware extends Middleware {
|
|||||||
constructor (transport) {
|
constructor (transport) {
|
||||||
super(transport);
|
super(transport);
|
||||||
|
|
||||||
|
const NOOP = () => {};
|
||||||
const register = this.register.bind(this);
|
const register = this.register.bind(this);
|
||||||
|
const registerSubscribe = this.registerSubscribe.bind(this);
|
||||||
|
|
||||||
register('eth_accounts', () => {
|
register('eth_accounts', () => {
|
||||||
return accounts.accountAddresses();
|
return accounts.accountAddresses();
|
||||||
@ -76,6 +78,14 @@ export default class LocalAccountsMiddleware extends Middleware {
|
|||||||
return accounts.dappsDefaultAddress;
|
return accounts.dappsDefaultAddress;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
registerSubscribe('parity_defaultAccount', (_, callback) => {
|
||||||
|
callback(null, accounts.dappsDefaultAddress);
|
||||||
|
|
||||||
|
accounts.on('dappsDefaultAddressChange', (address) => {
|
||||||
|
callback(null, accounts.dappsDefaultAddress);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
register('parity_exportAccount', ([address, password]) => {
|
register('parity_exportAccount', ([address, password]) => {
|
||||||
const account = accounts.get(address);
|
const account = accounts.get(address);
|
||||||
|
|
||||||
@ -109,6 +119,8 @@ export default class LocalAccountsMiddleware extends Middleware {
|
|||||||
return {};
|
return {};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
registerSubscribe('parity_hardwareAccountsInfo', NOOP);
|
||||||
|
|
||||||
register('parity_newAccountFromPhrase', ([phrase, password]) => {
|
register('parity_newAccountFromPhrase', ([phrase, password]) => {
|
||||||
return phraseToWallet(phrase)
|
return phraseToWallet(phrase)
|
||||||
.then((wallet) => {
|
.then((wallet) => {
|
||||||
@ -278,5 +290,15 @@ export default class LocalAccountsMiddleware extends Middleware {
|
|||||||
register('signer_requestsToConfirm', () => {
|
register('signer_requestsToConfirm', () => {
|
||||||
return transactions.requestsToConfirm();
|
return transactions.requestsToConfirm();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
registerSubscribe('signer_subscribePending', (_, callback) => {
|
||||||
|
callback(null, transactions.requestsToConfirm());
|
||||||
|
|
||||||
|
transactions.on('update', () => {
|
||||||
|
callback(null, transactions.requestsToConfirm());
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,14 +16,17 @@
|
|||||||
|
|
||||||
import { toHex } from '../util/format';
|
import { toHex } from '../util/format';
|
||||||
import { TransportError } from '../transport';
|
import { TransportError } from '../transport';
|
||||||
|
import EventEmitter from 'eventemitter3';
|
||||||
|
|
||||||
const AWAITING = Symbol('awaiting');
|
const AWAITING = Symbol('awaiting');
|
||||||
const LOCKED = Symbol('locked');
|
const LOCKED = Symbol('locked');
|
||||||
const CONFIRMED = Symbol('confirmed');
|
const CONFIRMED = Symbol('confirmed');
|
||||||
const REJECTED = Symbol('rejected');
|
const REJECTED = Symbol('rejected');
|
||||||
|
|
||||||
class Transactions {
|
class Transactions extends EventEmitter {
|
||||||
constructor () {
|
constructor () {
|
||||||
|
super();
|
||||||
|
|
||||||
this.reset();
|
this.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,6 +48,8 @@ class Transactions {
|
|||||||
transaction: tx
|
transaction: tx
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.emit('update');
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,6 +71,8 @@ class Transactions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
state.status = LOCKED;
|
state.status = LOCKED;
|
||||||
|
|
||||||
|
this.emit('update');
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock (id) {
|
unlock (id) {
|
||||||
@ -76,6 +83,8 @@ class Transactions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
state.status = AWAITING;
|
state.status = AWAITING;
|
||||||
|
|
||||||
|
this.emit('update');
|
||||||
}
|
}
|
||||||
|
|
||||||
hash (id) {
|
hash (id) {
|
||||||
@ -107,6 +116,8 @@ class Transactions {
|
|||||||
|
|
||||||
state.hash = hash;
|
state.hash = hash;
|
||||||
state.status = CONFIRMED;
|
state.status = CONFIRMED;
|
||||||
|
|
||||||
|
this.emit('update');
|
||||||
}
|
}
|
||||||
|
|
||||||
reject (id) {
|
reject (id) {
|
||||||
@ -118,6 +129,8 @@ class Transactions {
|
|||||||
|
|
||||||
state.status = REJECTED;
|
state.status = REJECTED;
|
||||||
|
|
||||||
|
this.emit('update');
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ import PubsubBase from '../pubsubBase';
|
|||||||
|
|
||||||
import { outSignerRequest } from '../../format/output';
|
import { outSignerRequest } from '../../format/output';
|
||||||
|
|
||||||
export default class Net extends PubsubBase {
|
export default class Signer extends PubsubBase {
|
||||||
constructor (transport) {
|
constructor (transport) {
|
||||||
super(transport);
|
super(transport);
|
||||||
this._api = {
|
this._api = {
|
||||||
|
@ -38,26 +38,32 @@ export default class Signer {
|
|||||||
start () {
|
start () {
|
||||||
this._started = true;
|
this._started = true;
|
||||||
|
|
||||||
if (this._api.isPubSub) {
|
return this
|
||||||
const subscription = this._api.pubsub
|
._api
|
||||||
.subscribeAndGetResult(
|
.transport
|
||||||
callback => this._api.pubsub.signer.pendingRequests(callback),
|
.ready
|
||||||
requests => {
|
.then(() => {
|
||||||
this.updateSubscriptions(requests);
|
if (this._api.isPubSub) {
|
||||||
return requests;
|
const subscription = this._api.pubsub
|
||||||
}
|
.subscribeAndGetResult(
|
||||||
);
|
callback => this._api.pubsub.signer.pendingRequests(callback),
|
||||||
|
requests => {
|
||||||
|
this.updateSubscriptions(requests);
|
||||||
|
return requests;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
this._listRequests(false),
|
this._listRequests(false),
|
||||||
subscription
|
subscription
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
this._listRequests(true),
|
this._listRequests(true),
|
||||||
this._loggingSubscribe()
|
this._loggingSubscribe()
|
||||||
]);
|
]);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSubscriptions (requests) {
|
updateSubscriptions (requests) {
|
||||||
|
@ -31,6 +31,10 @@ export default class JsonRpcBase extends EventEmitter {
|
|||||||
this._middlewareList = Promise.resolve([]);
|
this._middlewareList = Promise.resolve([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get ready () {
|
||||||
|
return this._middlewareList.then(() => true);
|
||||||
|
}
|
||||||
|
|
||||||
encode (method, params) {
|
encode (method, params) {
|
||||||
const json = JSON.stringify({
|
const json = JSON.stringify({
|
||||||
jsonrpc: '2.0',
|
jsonrpc: '2.0',
|
||||||
|
@ -17,7 +17,20 @@
|
|||||||
export default class Middleware {
|
export default class Middleware {
|
||||||
constructor (transport) {
|
constructor (transport) {
|
||||||
this._transport = transport;
|
this._transport = transport;
|
||||||
|
this._subscribe = transport.subscribe;
|
||||||
|
|
||||||
|
transport.subscribe = this.handleSubscribe.bind(this);
|
||||||
|
|
||||||
this._handlers = {};
|
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) {
|
register (method, handler) {
|
||||||
@ -28,10 +41,24 @@ export default class Middleware {
|
|||||||
this._handlers[method] = handler;
|
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) {
|
handle (method, params) {
|
||||||
const handler = this._handlers[method];
|
const handler = this._handlers[method];
|
||||||
|
|
||||||
if (handler != null) {
|
if (handler) {
|
||||||
return handler(params);
|
return handler(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user