Files
openethereum/js/src/api/subscriptions/manager.js
Arkadiy Paronyan 043ca21863 Backporting to beta (#3229)
* Use ethcore_dappsPort when constructing URLs (#3139)

* Upon connect, retrieve the available api ports

* Update dapps to load from dappsPort

* Update dapps summary with dappsPort

* Allow proxy to use dappsPort

* Replace /api/ping with HEAD /

* Dynamic port for available apps

* Retrieve content images with dappsPort

* Fix /

* Transfer token dropdown image fix

* IdentityIcon loads images via contentHash

* Update apps fetch to cater for dev & prod

* DRY up 127.0.0.1:${dappsPort} with ${dappsUrl}

* Cleaning up polluted namespaces (#3143)

* Renaming ethcore_ to parity_

* Renaming files

* Renaming poluted EthSigning

* Tidy up the namespaces

* Renaming files to match new structure

* Splitting EthSigning into separate traits

* jsapi move ethcore.* -> parity.*

* Move jsonrpc parity definitions

* Update UI API calls for parity interfaces

* Move jsapi signer interfaces from personal to signer

* Update UI to use signer.* where applicable

* Updsate jsapi subscriptions for signer

* Fix dodgy merge.

* Update README.

* Fix some tests.

* Move parity-only personal.* to parity.*

* Update UI for personal -> parity API moves

* Update subscription APIs after personal -> parity move

* personal. generateAuthorizationToken -> parity. generateAuthorizationToken (UI)

* enode, dappsPort & signerPort (UI)

* Update subscription tests (accountsInfo)

* subscription update

* personal -> parity

* Additional error logging on method failures

* move postTransaction to parity

* Additional debug info with method failures

* Fix personal tests.

* Console wrning shows parameters, error object does not

* Include parity_ signing methods.

* Console log http transport info

* Fix failing tests

* Add RPC stubs for parity_accounts.

* Allow some secure built-in dapps

* Use parity_accounts in place of accountsInfo

* Improve error reporting

* Cleanup GHH error handling


Former-commit-id: 5a094ccb9f0596d0e07abc23504b80dc099ad584
2016-11-07 14:46:41 +01:00

130 lines
3.6 KiB
JavaScript

// 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 <http://www.gnu.org/licenses/>.
import { isError } from '../util/types';
import Eth from './eth';
import Logging from './logging';
import Personal from './personal';
import Signer from './signer';
const events = {
'logging': { module: 'logging' },
'eth_blockNumber': { module: 'eth' },
'parity_accountsInfo': { module: 'personal' },
'eth_accounts': { module: 'personal' },
'signer_requestsToConfirm': { module: 'signer' }
};
export default class Manager {
constructor (api) {
this._api = api;
this.subscriptions = [];
this.values = {};
Object.keys(events).forEach((subscriptionName) => {
this.values[subscriptionName] = {
error: null,
data: null
};
});
this._logging = new Logging(this._updateSubscriptions);
this._eth = new Eth(this._updateSubscriptions, api);
this._personal = new Personal(this._updateSubscriptions, api, this);
this._signer = new Signer(this._updateSubscriptions, api, this);
}
_validateType (subscriptionName) {
const subscription = events[subscriptionName];
if (!subscription) {
return new Error(`${subscriptionName} is not a valid interface, subscribe using one of ${Object.keys(events).join(', ')}`);
}
return subscription;
}
subscribe (subscriptionName, callback) {
return new Promise((resolve, reject) => {
const subscription = this._validateType(subscriptionName);
if (isError(subscription)) {
reject(subscription);
return;
}
const subscriptionId = this.subscriptions.length;
const { error, data } = this.values[subscriptionName];
const engine = this[`_${subscription.module}`];
this.subscriptions[subscriptionId] = {
name: subscriptionName,
id: subscriptionId,
callback
};
if (!engine.isStarted) {
engine.start();
} else {
this._sendData(subscriptionId, error, data);
}
resolve(subscriptionId);
});
}
unsubscribe (subscriptionId) {
return new Promise((resolve, reject) => {
if (!this.subscriptions[subscriptionId]) {
reject(new Error(`Cannot find subscription ${subscriptionId}`));
return;
}
delete this.subscriptions[subscriptionId];
resolve();
});
}
_sendData (subscriptionId, error, data) {
const { callback } = this.subscriptions[subscriptionId];
try {
callback(error, data);
} catch (error) {
console.error(`Unable to update callback for subscriptionId ${subscriptionId}`, error);
this.unsubscribe(subscriptionId);
}
}
_updateSubscriptions = (subscriptionName, error, data) => {
const subscriptions = this.subscriptions
.filter(subscription => subscription.name === subscriptionName);
this.values[subscriptionName] = { error, data };
subscriptions
.forEach((subscription) => {
this._sendData(subscription.id, error, data);
});
}
}
export {
events
};