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
This commit is contained in:
Arkadiy Paronyan
2016-11-07 14:46:41 +01:00
committed by GitHub
parent aea995cf55
commit 043ca21863
106 changed files with 1974 additions and 1485 deletions

View File

@@ -39,11 +39,6 @@ export default class Eth {
.execute('eth_call', inOptions(options), inBlockNumber(blockNumber));
}
checkRequest (requestId) {
return this._transport
.execute('eth_checkRequest', inNumber16(requestId));
}
coinbase () {
return this._transport
.execute('eth_coinbase')
@@ -267,11 +262,6 @@ export default class Eth {
.execute('eth_pendingTransactions');
}
postTransaction (options) {
return this._transport
.execute('eth_postTransaction', inOptions(options));
}
protocolVersion () {
return this._transport
.execute('eth_protocolVersion');

View File

@@ -1,201 +0,0 @@
// 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 { inAddress, inData, inNumber16 } from '../../format/input';
import { outAddress, outHistogram, outNumber, outPeers } from '../../format/output';
export default class Ethcore {
constructor (transport) {
this._transport = transport;
}
acceptNonReservedPeers () {
return this._transport
.execute('ethcore_acceptNonReservedPeers');
}
addReservedPeer (encode) {
return this._transport
.execute('ethcore_addReservedPeer', encode);
}
dappsPort () {
return this._transport
.execute('ethcore_dappsPort')
.then(outNumber);
}
defaultExtraData () {
return this._transport
.execute('ethcore_defaultExtraData');
}
devLogs () {
return this._transport
.execute('ethcore_devLogs');
}
devLogsLevels () {
return this._transport
.execute('ethcore_devLogsLevels');
}
dropNonReservedPeers () {
return this._transport
.execute('ethcore_dropNonReservedPeers');
}
enode () {
return this._transport
.execute('ethcore_enode');
}
extraData () {
return this._transport
.execute('ethcore_extraData');
}
gasFloorTarget () {
return this._transport
.execute('ethcore_gasFloorTarget')
.then(outNumber);
}
gasPriceHistogram () {
return this._transport
.execute('ethcore_gasPriceHistogram')
.then(outHistogram);
}
generateSecretPhrase () {
return this._transport
.execute('ethcore_generateSecretPhrase');
}
hashContent (url) {
return this._transport
.execute('ethcore_hashContent', url);
}
minGasPrice () {
return this._transport
.execute('ethcore_minGasPrice')
.then(outNumber);
}
mode () {
return this._transport
.execute('ethcore_mode');
}
netChain () {
return this._transport
.execute('ethcore_netChain');
}
netPeers () {
return this._transport
.execute('ethcore_netPeers')
.then(outPeers);
}
netMaxPeers () {
return this._transport
.execute('ethcore_netMaxPeers')
.then(outNumber);
}
netPort () {
return this._transport
.execute('ethcore_netPort')
.then(outNumber);
}
nodeName () {
return this._transport
.execute('ethcore_nodeName');
}
phraseToAddress (phrase) {
return this._transport
.execute('ethcore_phraseToAddress', phrase)
.then(outAddress);
}
registryAddress () {
return this._transport
.execute('ethcore_registryAddress')
.then(outAddress);
}
removeReservedPeer (encode) {
return this._transport
.execute('ethcore_removeReservedPeer', encode);
}
rpcSettings () {
return this._transport
.execute('ethcore_rpcSettings');
}
setAuthor (address) {
return this._transport
.execute('ethcore_setAuthor', inAddress(address));
}
setExtraData (data) {
return this._transport
.execute('ethcore_setExtraData', inData(data));
}
setGasFloorTarget (quantity) {
return this._transport
.execute('ethcore_setGasFloorTarget', inNumber16(quantity));
}
setMinGasPrice (quantity) {
return this._transport
.execute('ethcore_setMinGasPrice', inNumber16(quantity));
}
setMode (mode) {
return this._transport
.execute('ethcore_setMode', mode);
}
setTransactionsLimit (quantity) {
return this._transport
.execute('ethcore_setTransactionsLimit', inNumber16(quantity));
}
signerPort () {
return this._transport
.execute('ethcore_signerPort')
.then(outNumber);
}
transactionsLimit () {
return this._transport
.execute('ethcore_transactionsLimit')
.then(outNumber);
}
unsignedTransactionsCount () {
return this._transport
.execute('ethcore_unsignedTransactionsCount')
.then(outNumber);
}
}

View File

@@ -16,9 +16,10 @@
export Db from './db';
export Eth from './eth';
export Ethcore from './ethcore';
export Parity from './parity';
export Net from './net';
export Personal from './personal';
export Shh from './shh';
export Signer from './signer';
export Trace from './trace';
export Web3 from './web3';

View File

@@ -14,4 +14,4 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
export default from './ethcore';
export default from './parity';

View File

@@ -16,12 +16,12 @@
import { createHttpApi } from '../../../../test/e2e/ethapi';
describe('ethapi.ethcore', () => {
describe('ethapi.parity', () => {
const ethapi = createHttpApi();
describe('gasFloorTarget', () => {
it('returns and translates the target', () => {
return ethapi.ethcore.gasFloorTarget().then((value) => {
return ethapi.parity.gasFloorTarget().then((value) => {
expect(value.gt(0)).to.be.true;
});
});
@@ -29,7 +29,7 @@ describe('ethapi.ethcore', () => {
describe('gasPriceHistogram', () => {
it('returns and translates the target', () => {
return ethapi.ethcore.gasPriceHistogram().then((result) => {
return ethapi.parity.gasPriceHistogram().then((result) => {
expect(Object.keys(result)).to.deep.equal(['bucketBounds', 'counts']);
expect(result.bucketBounds.length > 0).to.be.true;
expect(result.counts.length > 0).to.be.true;
@@ -39,7 +39,7 @@ describe('ethapi.ethcore', () => {
describe('netChain', () => {
it('returns and the chain', () => {
return ethapi.ethcore.netChain().then((value) => {
return ethapi.parity.netChain().then((value) => {
expect(value).to.equal('morden');
});
});
@@ -47,7 +47,7 @@ describe('ethapi.ethcore', () => {
describe('netPort', () => {
it('returns and translates the port', () => {
return ethapi.ethcore.netPort().then((value) => {
return ethapi.parity.netPort().then((value) => {
expect(value.gt(0)).to.be.true;
});
});
@@ -55,7 +55,7 @@ describe('ethapi.ethcore', () => {
describe('transactionsLimit', () => {
it('returns and translates the limit', () => {
return ethapi.ethcore.transactionsLimit().then((value) => {
return ethapi.parity.transactionsLimit().then((value) => {
expect(value.gt(0)).to.be.true;
});
});
@@ -63,7 +63,7 @@ describe('ethapi.ethcore', () => {
describe('rpcSettings', () => {
it('returns and translates the settings', () => {
return ethapi.ethcore.rpcSettings().then((value) => {
return ethapi.parity.rpcSettings().then((value) => {
expect(value).to.be.ok;
});
});

View File

@@ -0,0 +1,273 @@
// 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 { inAddress, inData, inHex, inNumber16, inOptions } from '../../format/input';
import { outAccountInfo, outAddress, outHistogram, outNumber, outPeers } from '../../format/output';
export default class Parity {
constructor (transport) {
this._transport = transport;
}
acceptNonReservedPeers () {
return this._transport
.execute('parity_acceptNonReservedPeers');
}
accounts () {
return this._transport
.execute('parity_accounts')
.then(outAccountInfo);
}
accountsInfo () {
return this._transport
.execute('parity_accountsInfo')
.then(outAccountInfo);
}
addReservedPeer (encode) {
return this._transport
.execute('parity_addReservedPeer', encode);
}
changePassword (account, password, newPassword) {
return this._transport
.execute('parity_changePassword', inAddress(account), password, newPassword);
}
checkRequest (requestId) {
return this._transport
.execute('parity_checkRequest', inNumber16(requestId));
}
dappsPort () {
return this._transport
.execute('parity_dappsPort')
.then(outNumber);
}
defaultExtraData () {
return this._transport
.execute('parity_defaultExtraData');
}
devLogs () {
return this._transport
.execute('parity_devLogs');
}
devLogsLevels () {
return this._transport
.execute('parity_devLogsLevels');
}
dropNonReservedPeers () {
return this._transport
.execute('parity_dropNonReservedPeers');
}
enode () {
return this._transport
.execute('parity_enode');
}
extraData () {
return this._transport
.execute('parity_extraData');
}
gasFloorTarget () {
return this._transport
.execute('parity_gasFloorTarget')
.then(outNumber);
}
gasPriceHistogram () {
return this._transport
.execute('parity_gasPriceHistogram')
.then(outHistogram);
}
generateSecretPhrase () {
return this._transport
.execute('parity_generateSecretPhrase');
}
hashContent (url) {
return this._transport
.execute('parity_hashContent', url);
}
listGethAccounts () {
return this._transport
.execute('parity_listGethAccounts')
.then((accounts) => (accounts || []).map(outAddress));
}
importGethAccounts (accounts) {
return this._transport
.execute('parity_importGethAccounts', (accounts || []).map(inAddress))
.then((accounts) => (accounts || []).map(outAddress));
}
minGasPrice () {
return this._transport
.execute('parity_minGasPrice')
.then(outNumber);
}
mode () {
return this._transport
.execute('parity_mode');
}
netChain () {
return this._transport
.execute('parity_netChain');
}
netPeers () {
return this._transport
.execute('parity_netPeers')
.then(outPeers);
}
netMaxPeers () {
return this._transport
.execute('parity_netMaxPeers')
.then(outNumber);
}
netPort () {
return this._transport
.execute('parity_netPort')
.then(outNumber);
}
newAccountFromPhrase (phrase, password) {
return this._transport
.execute('parity_newAccountFromPhrase', phrase, password)
.then(outAddress);
}
newAccountFromSecret (secret, password) {
return this._transport
.execute('parity_newAccountFromSecret', inHex(secret), password)
.then(outAddress);
}
newAccountFromWallet (json, password) {
return this._transport
.execute('parity_newAccountFromWallet', json, password)
.then(outAddress);
}
nodeName () {
return this._transport
.execute('parity_nodeName');
}
phraseToAddress (phrase) {
return this._transport
.execute('parity_phraseToAddress', phrase)
.then(outAddress);
}
postTransaction (options) {
return this._transport
.execute('parity_postTransaction', inOptions(options));
}
registryAddress () {
return this._transport
.execute('parity_registryAddress')
.then(outAddress);
}
removeReservedPeer (encode) {
return this._transport
.execute('parity_removeReservedPeer', encode);
}
rpcSettings () {
return this._transport
.execute('parity_rpcSettings');
}
setAccountName (address, name) {
return this._transport
.execute('parity_setAccountName', inAddress(address), name);
}
setAccountMeta (address, meta) {
return this._transport
.execute('parity_setAccountMeta', inAddress(address), JSON.stringify(meta));
}
setAuthor (address) {
return this._transport
.execute('parity_setAuthor', inAddress(address));
}
setExtraData (data) {
return this._transport
.execute('parity_setExtraData', inData(data));
}
setGasFloorTarget (quantity) {
return this._transport
.execute('parity_setGasFloorTarget', inNumber16(quantity));
}
setMinGasPrice (quantity) {
return this._transport
.execute('parity_setMinGasPrice', inNumber16(quantity));
}
setMode (mode) {
return this._transport
.execute('parity_setMode', mode);
}
setTransactionsLimit (quantity) {
return this._transport
.execute('parity_setTransactionsLimit', inNumber16(quantity));
}
signerPort () {
return this._transport
.execute('parity_signerPort')
.then(outNumber);
}
testPassword (account, password) {
return this._transport
.execute('parity_testPassword', inAddress(account), password);
}
transactionsLimit () {
return this._transport
.execute('parity_transactionsLimit')
.then(outNumber);
}
unsignedTransactionsCount () {
return this._transport
.execute('parity_unsignedTransactionsCount')
.then(outNumber);
}
}

View File

@@ -18,14 +18,36 @@ import { TEST_HTTP_URL, mockHttp } from '../../../../test/mockRpc';
import { isBigNumber } from '../../../../test/types';
import Http from '../../transport/http';
import Ethcore from './ethcore';
import Parity from './parity';
const instance = new Ethcore(new Http(TEST_HTTP_URL));
const instance = new Parity(new Http(TEST_HTTP_URL));
describe('api/rpc/parity', () => {
describe('accountsInfo', () => {
it('retrieves the available account info', () => {
mockHttp([{ method: 'parity_accountsInfo', reply: {
result: {
'0x63cf90d3f0410092fc0fca41846f596223979195': {
name: 'name', uuid: 'uuid', meta: '{"data":"data"}'
}
}
} }]);
return instance.accountsInfo().then((result) => {
expect(result).to.deep.equal({
'0x63Cf90D3f0410092FC0fca41846f596223979195': {
name: 'name', uuid: 'uuid', meta: {
data: 'data'
}
}
});
});
});
});
describe('api/rpc/Ethcore', () => {
describe('gasFloorTarget', () => {
it('returns the gasfloor, formatted', () => {
mockHttp([{ method: 'ethcore_gasFloorTarget', reply: { result: '0x123456' } }]);
mockHttp([{ method: 'parity_gasFloorTarget', reply: { result: '0x123456' } }]);
return instance.gasFloorTarget().then((count) => {
expect(isBigNumber(count)).to.be.true;
@@ -36,7 +58,7 @@ describe('api/rpc/Ethcore', () => {
describe('minGasPrice', () => {
it('returns the min gasprice, formatted', () => {
mockHttp([{ method: 'ethcore_minGasPrice', reply: { result: '0x123456' } }]);
mockHttp([{ method: 'parity_minGasPrice', reply: { result: '0x123456' } }]);
return instance.minGasPrice().then((count) => {
expect(isBigNumber(count)).to.be.true;
@@ -47,7 +69,7 @@ describe('api/rpc/Ethcore', () => {
describe('netMaxPeers', () => {
it('returns the max peers, formatted', () => {
mockHttp([{ method: 'ethcore_netMaxPeers', reply: { result: 25 } }]);
mockHttp([{ method: 'parity_netMaxPeers', reply: { result: 25 } }]);
return instance.netMaxPeers().then((count) => {
expect(isBigNumber(count)).to.be.true;
@@ -58,7 +80,7 @@ describe('api/rpc/Ethcore', () => {
describe('newPeers', () => {
it('returns the peer structure, formatted', () => {
mockHttp([{ method: 'ethcore_netPeers', reply: { result: { active: 123, connected: 456, max: 789 } } }]);
mockHttp([{ method: 'parity_netPeers', reply: { result: { active: 123, connected: 456, max: 789 } } }]);
return instance.netPeers().then((peers) => {
expect(peers.active.eq(123)).to.be.true;
@@ -70,7 +92,7 @@ describe('api/rpc/Ethcore', () => {
describe('netPort', () => {
it('returns the connected port, formatted', () => {
mockHttp([{ method: 'ethcore_netPort', reply: { result: 33030 } }]);
mockHttp([{ method: 'parity_netPort', reply: { result: 33030 } }]);
return instance.netPort().then((count) => {
expect(isBigNumber(count)).to.be.true;
@@ -81,7 +103,7 @@ describe('api/rpc/Ethcore', () => {
describe('transactionsLimit', () => {
it('returns the tx limit, formatted', () => {
mockHttp([{ method: 'ethcore_transactionsLimit', reply: { result: 1024 } }]);
mockHttp([{ method: 'parity_transactionsLimit', reply: { result: 1024 } }]);
return instance.transactionsLimit().then((count) => {
expect(isBigNumber(count)).to.be.true;

View File

@@ -14,113 +14,31 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { inAddress, inHex, inNumber10, inNumber16, inOptions } from '../../format/input';
import { outAccountInfo, outAddress, outSignerRequest } from '../../format/output';
import { inAddress, inNumber10, inOptions } from '../../format/input';
import { outAddress } from '../../format/output';
export default class Personal {
constructor (transport) {
this._transport = transport;
}
accountsInfo () {
return this._transport
.execute('personal_accountsInfo')
.then(outAccountInfo);
}
confirmRequest (requestId, options, password) {
return this._transport
.execute('personal_confirmRequest', inNumber16(requestId), options, password);
}
changePassword (account, password, newPassword) {
return this._transport
.execute('personal_changePassword', inAddress(account), password, newPassword);
}
generateAuthorizationToken () {
return this._transport
.execute('personal_generateAuthorizationToken');
}
listAccounts () {
return this._transport
.execute('personal_listAccounts')
.then((accounts) => (accounts || []).map(outAddress));
}
listGethAccounts () {
return this._transport
.execute('personal_listGethAccounts')
.then((accounts) => (accounts || []).map(outAddress));
}
importGethAccounts (accounts) {
return this._transport
.execute('personal_importGethAccounts', (accounts || []).map(inAddress))
.then((accounts) => (accounts || []).map(outAddress));
}
newAccount (password) {
return this._transport
.execute('personal_newAccount', password)
.then(outAddress);
}
newAccountFromPhrase (phrase, password) {
return this._transport
.execute('personal_newAccountFromPhrase', phrase, password)
.then(outAddress);
}
newAccountFromSecret (secret, password) {
return this._transport
.execute('personal_newAccountFromSecret', inHex(secret), password)
.then(outAddress);
}
newAccountFromWallet (json, password) {
return this._transport
.execute('personal_newAccountFromWallet', json, password)
.then(outAddress);
}
rejectRequest (requestId) {
return this._transport
.execute('personal_rejectRequest', inNumber16(requestId));
}
requestsToConfirm () {
return this._transport
.execute('personal_requestsToConfirm')
.then((requests) => (requests || []).map(outSignerRequest));
}
setAccountName (address, name) {
return this._transport
.execute('personal_setAccountName', inAddress(address), name);
}
setAccountMeta (address, meta) {
return this._transport
.execute('personal_setAccountMeta', inAddress(address), JSON.stringify(meta));
}
signAndSendTransaction (options, password) {
return this._transport
.execute('personal_signAndSendTransaction', inOptions(options), password);
}
signerEnabled () {
return this._transport
.execute('personal_signerEnabled');
}
testPassword (account, password) {
return this._transport
.execute('personal_testPassword', inAddress(account), password);
}
unlockAccount (account, password, duration = 1) {
return this._transport
.execute('personal_unlockAccount', inAddress(account), password, inNumber10(duration));

View File

@@ -26,28 +26,6 @@ describe('rpc/Personal', () => {
const checksum = '0x63Cf90D3f0410092FC0fca41846f596223979195';
let scope;
describe('accountsInfo', () => {
it('retrieves the available account info', () => {
scope = mockHttp([{ method: 'personal_accountsInfo', reply: {
result: {
'0x63cf90d3f0410092fc0fca41846f596223979195': {
name: 'name', uuid: 'uuid', meta: '{"data":"data"}'
}
}
} }]);
return instance.accountsInfo().then((result) => {
expect(result).to.deep.equal({
'0x63Cf90D3f0410092FC0fca41846f596223979195': {
name: 'name', uuid: 'uuid', meta: {
data: 'data'
}
}
});
});
});
});
describe('listAccounts', () => {
it('retrieves a list of available accounts', () => {
scope = mockHttp([{ method: 'personal_listAccounts', reply: { result: [account] } }]);

View File

@@ -0,0 +1,17 @@
// 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/>.
export default from './signer';

View File

@@ -0,0 +1,50 @@
// 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 { inNumber16 } from '../../format/input';
import { outSignerRequest } from '../../format/output';
export default class Signer {
constructor (transport) {
this._transport = transport;
}
confirmRequest (requestId, options, password) {
return this._transport
.execute('signer_confirmRequest', inNumber16(requestId), options, password);
}
generateAuthorizationToken () {
return this._transport
.execute('signer_generateAuthorizationToken');
}
rejectRequest (requestId) {
return this._transport
.execute('signer_rejectRequest', inNumber16(requestId));
}
requestsToConfirm () {
return this._transport
.execute('signer_requestsToConfirm')
.then((requests) => (requests || []).map(outSignerRequest));
}
signerEnabled () {
return this._transport
.execute('signer_signerEnabled');
}
}