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
This commit is contained in:
Tomasz Drwięga
2016-11-06 12:51:53 +01:00
committed by Gav Wood
parent 78f2d88182
commit 9c4979681c
101 changed files with 1899 additions and 1466 deletions

View File

@@ -135,10 +135,11 @@ APIs implement the calls as exposed in the [Ethcore JSON Ethereum RPC](https://g
- [ethapi.db](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#db)
- [ethapi.eth](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#eth)
- [ethapi.ethcore](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#ethcore)
- [ethapi.parity](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#parity)
- [ethapi.net](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#net)
- [ethapi.personal](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#personal)
- [ethapi.shh](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#shh)
- [ethapi.signer](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#signer)
- [ethapi.trace](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#trace)
- [ethapi.web3](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#web3)

View File

@@ -17,7 +17,7 @@
import { Http, Ws } from './transport';
import Contract from './contract';
import { Db, Eth, Ethcore, Net, Personal, Shh, Trace, Web3 } from './rpc';
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';
@@ -32,10 +32,11 @@ export default class Api {
this._db = new Db(transport);
this._eth = new Eth(transport);
this._ethcore = new Ethcore(transport);
this._net = new Net(transport);
this._parity = new Parity(transport);
this._personal = new Personal(transport);
this._shh = new Shh(transport);
this._signer = new Signer(transport);
this._trace = new Trace(transport);
this._web3 = new Web3(transport);
@@ -50,8 +51,8 @@ export default class Api {
return this._eth;
}
get ethcore () {
return this._ethcore;
get parity () {
return this._parity;
}
get net () {
@@ -66,6 +67,10 @@ export default class Api {
return this._shh;
}
get signer () {
return this._signer;
}
get trace () {
return this._trace;
}

View File

@@ -102,7 +102,7 @@ export default class Contract {
options.gas = gas.toFixed(0);
setState({ state: 'postTransaction', gas });
return this._api.eth.postTransaction(this._encodeOptions(this.constructors[0], options, values));
return this._api.parity.postTransaction(this._encodeOptions(this.constructors[0], options, values));
})
.then((requestId) => {
setState({ state: 'checkRequest', requestId });
@@ -166,7 +166,7 @@ export default class Contract {
}
_pollCheckRequest = (requestId) => {
return this._api.pollMethod('eth_checkRequest', requestId);
return this._api.pollMethod('parity_checkRequest', requestId);
}
_pollTransactionReceipt = (txhash, gas) => {
@@ -208,7 +208,7 @@ export default class Contract {
if (!func.constant) {
func.postTransaction = (options, values = []) => {
return this._api.eth
return this._api.parity
.postTransaction(this._encodeOptions(func, this._addOptionsTo(options), values));
};

View File

@@ -249,9 +249,9 @@ describe('api/contract/Contract', () => {
before(() => {
scope = mockHttp([
{ method: 'eth_estimateGas', reply: { result: 1000 } },
{ method: 'eth_postTransaction', reply: { result: '0x678' } },
{ method: 'eth_checkRequest', reply: { result: null } },
{ method: 'eth_checkRequest', reply: { result: '0x890' } },
{ method: 'parity_postTransaction', reply: { result: '0x678' } },
{ method: 'parity_checkRequest', reply: { result: null } },
{ method: 'parity_checkRequest', reply: { result: '0x890' } },
{ method: 'eth_getTransactionReceipt', reply: { result: null } },
{ method: 'eth_getTransactionReceipt', reply: { result: RECEIPT_PEND } },
{ method: 'eth_getTransactionReceipt', reply: { result: RECEIPT_DONE } },
@@ -266,7 +266,7 @@ describe('api/contract/Contract', () => {
});
it('passes the options through to postTransaction (incl. gas calculation)', () => {
expect(scope.body.eth_postTransaction.params).to.deep.equal([
expect(scope.body.parity_postTransaction.params).to.deep.equal([
{ data: '0x123', gas: '0x4b0' }
]);
});
@@ -280,8 +280,8 @@ describe('api/contract/Contract', () => {
it('fails when gasUsed == gas', () => {
mockHttp([
{ method: 'eth_estimateGas', reply: { result: 1000 } },
{ method: 'eth_postTransaction', reply: { result: '0x678' } },
{ method: 'eth_checkRequest', reply: { result: '0x789' } },
{ method: 'parity_postTransaction', reply: { result: '0x678' } },
{ method: 'parity_checkRequest', reply: { result: '0x789' } },
{ method: 'eth_getTransactionReceipt', reply: { result: RECEIPT_EXCP } }
]);
@@ -295,8 +295,8 @@ describe('api/contract/Contract', () => {
it('fails when no code was deployed', () => {
mockHttp([
{ method: 'eth_estimateGas', reply: { result: 1000 } },
{ method: 'eth_postTransaction', reply: { result: '0x678' } },
{ method: 'eth_checkRequest', reply: { result: '0x789' } },
{ method: 'parity_postTransaction', reply: { result: '0x678' } },
{ method: 'parity_checkRequest', reply: { result: '0x789' } },
{ method: 'eth_getTransactionReceipt', reply: { result: RECEIPT_DONE } },
{ method: 'eth_getCode', reply: { result: '0x' } }
]);
@@ -360,15 +360,15 @@ describe('api/contract/Contract', () => {
describe('postTransaction', () => {
beforeEach(() => {
scope = mockHttp([{ method: 'eth_postTransaction', reply: { result: ['hashId'] } }]);
scope = mockHttp([{ method: 'parity_postTransaction', reply: { result: ['hashId'] } }]);
});
it('encodes options and mades an eth_postTransaction call', () => {
it('encodes options and mades an parity_postTransaction call', () => {
return func
.postTransaction({ someExtras: 'foo' }, VALUES)
.then(() => {
expect(scope.isDone()).to.be.true;
expect(scope.body.eth_postTransaction.params[0]).to.deep.equal({
expect(scope.body.parity_postTransaction.params[0]).to.deep.equal({
someExtras: 'foo',
to: ADDR,
data: ENCODED

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');
}
}

View File

@@ -24,9 +24,9 @@ import Signer from './signer';
const events = {
'logging': { module: 'logging' },
'eth_blockNumber': { module: 'eth' },
'personal_accountsInfo': { module: 'personal' },
'personal_listAccounts': { module: 'personal' },
'personal_requestsToConfirm': { module: 'signer' }
'parity_accountsInfo': { module: 'personal' },
'eth_accounts': { module: 'personal' },
'signer_requestsToConfirm': { module: 'signer' }
};
export default class Manager {

View File

@@ -37,18 +37,18 @@ export default class Personal {
}
_listAccounts = () => {
return this._api.personal
.listAccounts()
return this._api.eth
.accounts()
.then((accounts) => {
this._updateSubscriptions('personal_listAccounts', null, accounts);
this._updateSubscriptions('eth_accounts', null, accounts);
});
}
_accountsInfo = () => {
return this._api.personal
return this._api.parity
.accountsInfo()
.then((info) => {
this._updateSubscriptions('personal_accountsInfo', null, info);
this._updateSubscriptions('parity_accountsInfo', null, info);
});
}
@@ -59,16 +59,16 @@ export default class Personal {
}
switch (data.method) {
case 'personal_importGethAccounts':
case 'parity_importGethAccounts':
case 'personal_newAccount':
case 'personal_newAccountFromPhrase':
case 'personal_newAccountFromWallet':
case 'parity_newAccountFromPhrase':
case 'parity_newAccountFromWallet':
this._listAccounts();
this._accountsInfo();
return;
case 'personal_setAccountName':
case 'personal_setAccountMeta':
case 'parity_setAccountName':
case 'parity_setAccountMeta':
this._accountsInfo();
return;
}

View File

@@ -34,14 +34,15 @@ function stubApi (accounts, info) {
return {
_calls,
personal: {
parity: {
accountsInfo: () => {
const stub = sinon.stub().resolves(info || TEST_INFO)();
_calls.accountsInfo.push(stub);
return stub;
},
listAccounts: () => {
}
},
eth: {
accounts: () => {
const stub = sinon.stub().resolves(accounts || TEST_LIST)();
_calls.listAccounts.push(stub);
return stub;
@@ -85,17 +86,17 @@ describe('api/subscriptions/personal', () => {
expect(personal.isStarted).to.be.true;
});
it('calls personal_accountsInfo', () => {
it('calls parity_accountsInfo', () => {
expect(api._calls.accountsInfo.length).to.be.ok;
});
it('calls personal_listAccounts', () => {
it('calls eth_accounts', () => {
expect(api._calls.listAccounts.length).to.be.ok;
});
it('updates subscribers', () => {
expect(cb.firstCall).to.have.been.calledWith('personal_listAccounts', null, TEST_LIST);
expect(cb.secondCall).to.have.been.calledWith('personal_accountsInfo', null, TEST_INFO);
expect(cb.firstCall).to.have.been.calledWith('eth_accounts', null, TEST_LIST);
expect(cb.secondCall).to.have.been.calledWith('parity_accountsInfo', null, TEST_INFO);
});
});

View File

@@ -49,10 +49,10 @@ export default class Signer {
return;
}
return this._api.personal
return this._api.signer
.requestsToConfirm()
.then((requests) => {
this._updateSubscriptions('personal_requestsToConfirm', null, requests);
this._updateSubscriptions('signer_requestsToConfirm', null, requests);
nextTimeout();
})
.catch(nextTimeout);
@@ -65,7 +65,7 @@ export default class Signer {
}
switch (data.method) {
case 'eth_postTransaction':
case 'parity_postTransaction':
case 'eth_sendTranasction':
case 'eth_sendRawTransaction':
this._listRequests(false);

View File

@@ -56,6 +56,8 @@ export default class Http extends JsonRpcBase {
if (response.status !== 200) {
this._connected = false;
this.error(JSON.stringify({ status: response.status, statusText: response.statusText }));
console.error(`${method}(${JSON.stringify(params)}): ${response.status}: ${response.statusText}`);
throw new Error(`${response.status}: ${response.statusText}`);
}
@@ -66,7 +68,9 @@ export default class Http extends JsonRpcBase {
if (response.error) {
this.error(JSON.stringify(response));
throw new Error(`${response.error.code}: ${response.error.message}`);
console.error(`${method}(${JSON.stringify(params)}): ${response.error.code}: ${response.error.message}`);
throw new Error(`${method}: ${response.error.code}: ${response.error.message}`);
}
this.log(JSON.stringify(response));

View File

@@ -107,7 +107,9 @@ export default class Ws extends JsonRpcBase {
if (result.error) {
this.error(event.data);
reject(new Error(`${result.error.code}: ${result.error.message}`));
console.error(`${method}(${JSON.stringify(params)}): ${result.error.code}: ${result.error.message}`);
reject(new Error(`${method}: ${result.error.code}: ${result.error.message}`));
delete this._messages[result.id];
return;
}

View File

@@ -32,7 +32,7 @@ export default class Registry {
return;
}
this._api.ethcore
this._api.parity
.registryAddress()
.then((address) => {
this._instance = this._api.newContract(abis.registry, address).instance;

View File

@@ -83,7 +83,7 @@ export default class Application extends Component {
Promise
.all([
attachInstances(),
api.personal.accountsInfo()
api.parity.accounts()
])
.then(([{ managerInstance, registryInstance, tokenregInstance }, accountsInfo]) => {
accountsInfo = accountsInfo || {};

View File

@@ -296,7 +296,7 @@ export default class Deployment extends Component {
.then((signerRequestId) => {
this.setState({ signerRequestId, deployState: 'Transaction posted, Waiting for transaction authorization' });
return api.pollMethod('eth_checkRequest', signerRequestId);
return api.pollMethod('parity_checkRequest', signerRequestId);
})
.then((txHash) => {
this.setState({ txHash, deployState: 'Transaction authorized, Waiting for network confirmations' });

View File

@@ -279,7 +279,7 @@ export default class Send extends Component {
.then((signerRequestId) => {
this.setState({ signerRequestId, sendState: 'Transaction posted, Waiting for transaction authorization' });
return api.pollMethod('eth_checkRequest', signerRequestId);
return api.pollMethod('parity_checkRequest', signerRequestId);
})
.then((txHash) => {
this.setState({ txHash, sendState: 'Transaction authorized, Waiting for network confirmations' });

View File

@@ -100,8 +100,8 @@ export function attachInstances () {
return Promise
.all([
api.ethcore.registryAddress(),
api.ethcore.netChain()
api.parity.registryAddress(),
api.parity.netChain()
])
.then(([registryAddress, netChain]) => {
const registry = api.newContract(abis.registry, registryAddress).instance;

View File

@@ -11,7 +11,6 @@
<div id="container"></div>
<script src="vendor.js"></script>
<script src="commons.js"></script>
<script src="/parity-utils/parity.js"></script>
<script src="githubhint.js"></script>
</body>
</html>

View File

@@ -41,7 +41,9 @@ export default class Application extends Component {
registerBusy: false,
registerError: null,
registerState: '',
registerType: 'file'
registerType: 'file',
repo: '',
repoError: null
}
componentDidMount () {
@@ -206,47 +208,64 @@ export default class Application extends Component {
}
onChangeCommit = (event) => {
const commit = event.target.value;
let commit = event.target.value;
const commitError = null;
let hasContent = false;
// TODO: field validation
this.setState({ commit, commitError, contentHashError: null }, () => {
const { repo } = this.state || '';
const parts = repo.split('/');
this.setState({ commit, commitError, contentHashError: 'hash lookup in progress' }, () => {
const { repo } = this.state;
this.lookupHash(`https://codeload.github.com/${repo}/zip/${commit}`);
hasContent = commit.length !== 0 && parts.length === 2 && parts[0].length !== 0 && parts[1].length !== 0;
if (!commitError && hasContent) {
this.setState({ contentHashError: 'hash lookup in progress' });
this.lookupHash(`https://codeload.github.com/${repo}/zip/${commit}`);
}
});
}
onChangeRepo = (event) => {
let repo = event.target.value;
const repoError = null;
let hasContent = false;
// TODO: field validation
if (!repoError) {
repo = repo.replace('https://github.com/', '');
}
this.setState({ repo, repoError, contentHashError: 'hash lookup in progress' }, () => {
const { commit } = this.state;
this.lookupHash(`https://codeload.github.com/${repo}/zip/${commit}`);
this.setState({ repo, repoError, contentHashError: null }, () => {
const { commit } = this.state || '';
const parts = repo.split('/');
hasContent = commit.length !== 0 && parts.length === 2 && parts[0].length !== 0 && parts[1].length !== 0;
if (!repoError && hasContent) {
this.setState({ contentHashError: 'hash lookup in progress' });
this.lookupHash(`https://codeload.github.com/${repo}/zip/${commit}`);
}
});
}
onChangeUrl = (event) => {
let url = event.target.value;
const urlError = null;
let hasContent = false;
// TODO: field validation
if (!urlError) {
const parts = url.split('/');
hasContent = parts.length !== 0;
if (parts[2] === 'github.com' || parts[2] === 'raw.githubusercontent.com') {
url = `https://raw.githubusercontent.com/${parts.slice(3).join('/')}`.replace('/blob/', '/');
}
}
this.setState({ url, urlError, contentHashError: 'hash lookup in progress' }, () => {
this.lookupHash(url);
this.setState({ url, urlError, contentHashError: null }, () => {
if (!urlError && hasContent) {
this.setState({ contentHashError: 'hash lookup in progress' });
this.lookupHash(url);
}
});
}
@@ -271,7 +290,7 @@ export default class Application extends Component {
.then((signerRequestId) => {
this.setState({ signerRequestId, registerState: 'Transaction posted, Waiting for transaction authorization' });
return api.pollMethod('eth_checkRequest', signerRequestId);
return api.pollMethod('parity_checkRequest', signerRequestId);
})
.then((txHash) => {
this.setState({ txHash, registerState: 'Transaction authorized, Waiting for network confirmations' });
@@ -285,7 +304,7 @@ export default class Application extends Component {
});
})
.then((txReceipt) => {
this.setState({ txReceipt, registerBusy: false, registerState: 'Network confirmed, Received transaction receipt', url: '', commit: '', commitError: null, contentHash: '', contentHashOwner: null, contentHashError: null });
this.setState({ txReceipt, registerBusy: false, registerState: 'Network confirmed, Received transaction receipt', url: '', commit: '', repo: '', commitError: null, contentHash: '', contentHashOwner: null, contentHashError: null });
})
.catch((error) => {
console.error('onSend', error);
@@ -298,7 +317,7 @@ export default class Application extends Component {
this.setState({ registerBusy: true, registerState: 'Estimating gas for the transaction' });
const values = [contentHash, repo, commit];
const values = [contentHash, repo, commit.substr(0, 2) === '0x' ? commit : `0x${commit}`];
const options = { from: fromAddress };
this.trackRequest(
@@ -367,7 +386,7 @@ export default class Application extends Component {
console.log(`lookupHash ${url}`);
api.ethcore
api.parity
.hashContent(url)
.then((contentHash) => {
console.log('lookupHash', contentHash);

View File

@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
const { api } = window.parity;
const api = window.parent.secureApi;
export {
api

View File

@@ -18,7 +18,7 @@ import * as abis from '../../contracts/abi';
import { api } from './parity';
export function attachInterface () {
return api.ethcore
return api.parity
.registryAddress()
.then((registryAddress) => {
console.log(`the registry was found at ${registryAddress}`);
@@ -29,7 +29,7 @@ export function attachInterface () {
.all([
registry.getAddress.call({}, [api.util.sha3('githubhint'), 'A']),
api.eth.accounts(),
api.personal.accountsInfo()
api.parity.accounts()
]);
})
.then(([address, addresses, accountsInfo]) => {

View File

@@ -29,7 +29,7 @@ export { addresses, accounts, lookup, events, names, records };
export const setContract = (contract) => ({ type: 'set contract', contract });
export const fetchContract = () => (dispatch) =>
api.ethcore.registryAddress()
api.parity.registryAddress()
.then((address) => {
const contract = api.newContract(registryAbi, address);
dispatch(setContract(contract));

View File

@@ -22,7 +22,7 @@ export const fetch = () => (dispatch) => {
return Promise
.all([
api.eth.accounts(),
api.personal.accountsInfo()
api.parity.accounts()
])
.then(([ accounts, data ]) => {
data = data || {};

View File

@@ -39,7 +39,7 @@ const logToEvent = (log) => {
};
export function attachInterface (callback) {
return api.ethcore
return api.parity
.registryAddress()
.then((registryAddress) => {
console.log(`the registry was found at ${registryAddress}`);
@@ -50,7 +50,7 @@ export function attachInterface (callback) {
.all([
registry.getAddress.call({}, [api.util.sha3('signaturereg'), 'A']),
api.eth.accounts(),
api.personal.accountsInfo()
api.parity.accounts()
]);
})
.then(([address, addresses, accountsInfo]) => {

View File

@@ -38,7 +38,7 @@ export const loadAccounts = () => (dispatch) => {
Promise
.all([
api.eth.accounts(),
api.personal.accountsInfo()
api.parity.accounts()
])
.then(([ accounts, accountsInfo ]) => {
accountsInfo = accountsInfo || {};

View File

@@ -34,7 +34,7 @@ export const FIND_CONTRACT = 'FIND_CONTRACT';
export const loadContract = () => (dispatch) => {
dispatch(setLoading(true));
api.ethcore
api.parity
.registryAddress()
.then((registryAddress) => {
console.log(`registry found at ${registryAddress}`);

View File

@@ -74,7 +74,7 @@ ReactDOM.render(
<Route path='addresses' component={ Addresses } />
<Route path='address/:address' component={ Address } />
<Route path='apps' component={ Dapps } />
<Route path='app/:type/:name' component={ Dapp } />
<Route path='app/:id' component={ Dapp } />
<Route path='contracts' component={ Contracts } />
<Route path='contract/:address' component={ Contract } />
<Route path='settings' component={ Settings }>

View File

@@ -16,20 +16,22 @@
import db from './interfaces/db';
import eth from './interfaces/eth';
import ethcore from './interfaces/ethcore';
import net from './interfaces/net';
import parity from './interfaces/parity';
import personal from './interfaces/personal';
import shh from './interfaces/shh';
import signer from './interfaces/signer';
import trace from './interfaces/trace';
import web3 from './interfaces/web3';
export default {
db: db,
eth: eth,
ethcore: ethcore,
net: net,
personal: personal,
shh: shh,
trace: trace,
web3: web3
db,
eth,
parity,
net,
personal,
shh,
signer,
trace,
web3
};

View File

@@ -86,20 +86,6 @@ export default {
}
},
checkRequest: {
desc: 'Returns the transactionhash of the requestId (received from eth_postTransaction) if the request was confirmed',
params: [
{
type: Quantity,
desc: 'The requestId to check for'
}
],
returns: {
type: Hash,
desc: '32 Bytes - the transaction hash, or the zero hash if the transaction is not yet available'
}
},
coinbase: {
desc: 'Returns the client coinbase address.',
params: [],
@@ -823,22 +809,6 @@ export default {
}
},
postTransaction: {
desc: 'Posts a transaction to the Signer.',
params: [
{
type: Object,
desc: 'see [eth_sendTransaction](#eth_sendTransaction)',
format: 'inputCallFormatter'
}
],
returns: {
type: Quantity,
desc: 'The id of the actual transaction',
format: 'utils.toDecimal'
}
},
protocolVersion: {
desc: 'Returns the current ethereum protocol version.',
params: [],

View File

@@ -26,6 +26,52 @@ export default {
}
},
accounts: {
desc: 'returns a map of accounts as an object',
params: [],
returns: {
type: Array,
desc: 'Account metadata',
details: {
name: {
type: String,
desc: 'Account name'
},
meta: {
type: String,
desc: 'Encoded JSON string the defines additional account metadata'
},
uuid: {
type: String,
desc: 'The account UUID, or null if not available/unknown/not applicable.'
}
}
}
},
accountsInfo: {
desc: 'returns a map of accounts as an object',
params: [],
returns: {
type: Array,
desc: 'Account metadata',
details: {
name: {
type: String,
desc: 'Account name'
},
meta: {
type: String,
desc: 'Encoded JSON string the defines additional account metadata'
},
uuid: {
type: String,
desc: 'The account UUID, or null if not available/unknown/not applicable.'
}
}
}
},
addReservedPeer: {
desc: '?',
params: [
@@ -40,6 +86,20 @@ export default {
}
},
checkRequest: {
desc: 'Returns the transactionhash of the requestId (received from parity_postTransaction) if the request was confirmed',
params: [
{
type: Quantity,
desc: 'The requestId to check for'
}
],
returns: {
type: Hash,
desc: '32 Bytes - the transaction hash, or the zero hash if the transaction is not yet available'
}
},
dappsPort: {
desc: 'Returns the port the dapps are running on, error if not enabled',
params: [],
@@ -155,6 +215,29 @@ export default {
}
},
listGethAccounts: {
desc: 'Returns a list of the accounts available from Geth',
params: [],
returns: {
type: Array,
desc: '20 Bytes addresses owned by the client.'
}
},
importGethAccounts: {
desc: 'Imports a list of accounts from geth',
params: [
{
type: Array,
desc: 'List of the geth addresses to import'
}
],
returns: {
type: Array,
desc: 'Array of the imported addresses'
}
},
minGasPrice: {
desc: 'Returns currently set minimal gas price',
params: [],
@@ -210,6 +293,60 @@ export default {
}
},
newAccountFromPhrase: {
desc: 'Creates a new account from a recovery passphrase',
params: [
{
type: String,
desc: 'Phrase'
},
{
type: String,
desc: 'Password'
}
],
returns: {
type: Address,
desc: 'The created address'
}
},
newAccountFromSecret: {
desc: 'Creates a new account from a private ethstore secret key',
params: [
{
type: Data,
desc: 'Secret, 32-byte hex'
},
{
type: String,
desc: 'Password'
}
],
returns: {
type: Address,
desc: 'The created address'
}
},
newAccountFromWallet: {
desc: 'Creates a new account from a JSON import',
params: [
{
type: String,
desc: 'JSON'
},
{
type: String,
desc: 'Password'
}
],
returns: {
type: Address,
desc: 'The created address'
}
},
nodeName: {
desc: 'Returns node name (identity)',
params: [],
@@ -233,6 +370,22 @@ export default {
}
},
postTransaction: {
desc: 'Posts a transaction to the Signer.',
params: [
{
type: Object,
desc: 'see [eth_sendTransaction](#eth_sendTransaction)',
format: 'inputCallFormatter'
}
],
returns: {
type: Quantity,
desc: 'The id of the actual transaction',
format: 'utils.toDecimal'
}
},
removeReservedPeer: {
desc: '?',
params: [
@@ -265,6 +418,42 @@ export default {
}
},
setAccountName: {
desc: 'Sets a name for the account',
params: [
{
type: Address,
desc: 'Address'
},
{
type: String,
desc: 'Name'
}
],
returns: {
type: Object,
desc: 'Returns null in all cases'
}
},
setAccountMeta: {
desc: 'Sets metadata for the account',
params: [
{
type: Address,
desc: 'Address'
},
{
type: String,
desc: 'Metadata (JSON encoded)'
}
],
returns: {
type: Object,
desc: 'Returns null in all cases'
}
},
setAuthor: {
desc: 'Changes author (coinbase) for mined blocks.',
params: [

View File

@@ -17,83 +17,6 @@
import { Address, Data, Quantity } from '../types';
export default {
accountsInfo: {
desc: 'returns a map of accounts as an object',
params: [],
returns: {
type: Array,
desc: 'Account metadata',
details: {
name: {
type: String,
desc: 'Account name'
},
meta: {
type: String,
desc: 'Encoded JSON string the defines additional account metadata'
},
uuid: {
type: String,
desc: 'The account UUID, or null if not available/unknown/not applicable.'
}
}
}
},
generateAuthorizationToken: {
desc: 'Generates a new authorization token',
params: [],
returns: {
type: String,
desc: 'The new authorization token'
}
},
requestsToConfirm: {
desc: 'Returns a list of the transactions requiring authorization',
params: [],
returns: {
type: Array,
desc: 'A list of the outstanding transactions'
}
},
confirmRequest: {
desc: 'Confirm a request in the signer queue',
params: [
{
type: Quantity,
desc: 'The request id'
},
{
type: Object,
desc: 'The request options'
},
{
type: String,
desc: 'The account password'
}
],
returns: {
type: Boolean,
desc: 'The status of the confirmation'
}
},
rejectRequest: {
desc: 'Rejects a request in the signer queue',
params: [
{
type: Quantity,
desc: 'The request id'
}
],
returns: {
type: Boolean,
desc: 'The status of the rejection'
}
},
listAccounts: {
desc: 'Returns a list of addresses owned by client.',
params: [],
@@ -103,29 +26,6 @@ export default {
}
},
listGethAccounts: {
desc: 'Returns a list of the accounts available from Geth',
params: [],
returns: {
type: Array,
desc: '20 Bytes addresses owned by the client.'
}
},
importGethAccounts: {
desc: 'Imports a list of accounts from geth',
params: [
{
type: Array,
desc: 'List of the geth addresses to import'
}
],
returns: {
type: Array,
desc: 'Array of the imported addresses'
}
},
newAccount: {
desc: 'Creates new account',
params: [
@@ -140,96 +40,6 @@ export default {
}
},
newAccountFromPhrase: {
desc: 'Creates a new account from a recovery passphrase',
params: [
{
type: String,
desc: 'Phrase'
},
{
type: String,
desc: 'Password'
}
],
returns: {
type: Address,
desc: 'The created address'
}
},
newAccountFromSecret: {
desc: 'Creates a new account from a private ethstore secret key',
params: [
{
type: Data,
desc: 'Secret, 32-byte hex'
},
{
type: String,
desc: 'Password'
}
],
returns: {
type: Address,
desc: 'The created address'
}
},
newAccountFromWallet: {
desc: 'Creates a new account from a JSON import',
params: [
{
type: String,
desc: 'JSON'
},
{
type: String,
desc: 'Password'
}
],
returns: {
type: Address,
desc: 'The created address'
}
},
setAccountName: {
desc: 'Sets a name for the account',
params: [
{
type: Address,
desc: 'Address'
},
{
type: String,
desc: 'Name'
}
],
returns: {
type: Object,
desc: 'Returns null in all cases'
}
},
setAccountMeta: {
desc: 'Sets metadata for the account',
params: [
{
type: Address,
desc: 'Address'
},
{
type: String,
desc: 'Metadata (JSON encoded)'
}
],
returns: {
type: Object,
desc: 'Returns null in all cases'
}
},
signAndSendTransaction: {
desc: 'Sends and signs a transaction given account passphrase. Does not require the account to be unlocked nor unlocks the account for future transactions. ',
params: [
@@ -284,15 +94,6 @@ export default {
}
},
signerEnabled: {
desc: 'Returns whether signer is enabled/disabled.',
params: [],
returns: {
type: Boolean,
desc: 'true when enabled, false when disabled'
}
},
unlockAccount: {
desc: '?',
params: [

View File

@@ -0,0 +1,82 @@
// 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 { Quantity } from '../types';
export default {
generateAuthorizationToken: {
desc: 'Generates a new authorization token',
params: [],
returns: {
type: String,
desc: 'The new authorization token'
}
},
requestsToConfirm: {
desc: 'Returns a list of the transactions requiring authorization',
params: [],
returns: {
type: Array,
desc: 'A list of the outstanding transactions'
}
},
confirmRequest: {
desc: 'Confirm a request in the signer queue',
params: [
{
type: Quantity,
desc: 'The request id'
},
{
type: Object,
desc: 'The request options'
},
{
type: String,
desc: 'The account password'
}
],
returns: {
type: Boolean,
desc: 'The status of the confirmation'
}
},
rejectRequest: {
desc: 'Rejects a request in the signer queue',
params: [
{
type: Quantity,
desc: 'The request id'
}
],
returns: {
type: Boolean,
desc: 'The status of the rejection'
}
},
signerEnabled: {
desc: 'Returns whether signer is enabled/disabled.',
params: [],
returns: {
type: Boolean,
desc: 'true when enabled, false when disabled'
}
}
};

View File

@@ -133,8 +133,8 @@ export default class AddAddress extends Component {
const { address, name, description } = this.state;
Promise.all([
api.personal.setAccountName(address, name),
api.personal.setAccountMeta(address, {
api.parity.setAccountName(address, name),
api.parity.setAccountMeta(address, {
description,
timestamp: Date.now(),
deleted: false

View File

@@ -141,8 +141,8 @@ export default class AddContract extends Component {
const { abiParsed, address, name, description } = this.state;
Promise.all([
api.personal.setAccountName(address, name),
api.personal.setAccountMeta(address, {
api.parity.setAccountName(address, name),
api.parity.setAccountMeta(address, {
contract: true,
deleted: false,
timestamp: Date.now(),

View File

@@ -173,15 +173,15 @@ export default class CreateAccount extends Component {
Promise
.all([
api.ethcore.generateSecretPhrase(),
api.ethcore.generateSecretPhrase(),
api.ethcore.generateSecretPhrase(),
api.ethcore.generateSecretPhrase(),
api.ethcore.generateSecretPhrase()
api.parity.generateSecretPhrase(),
api.parity.generateSecretPhrase(),
api.parity.generateSecretPhrase(),
api.parity.generateSecretPhrase(),
api.parity.generateSecretPhrase()
])
.then((phrases) => {
return Promise
.all(phrases.map((phrase) => api.ethcore.phraseToAddress(phrase)))
.all(phrases.map((phrase) => api.parity.phraseToAddress(phrase)))
.then((addresses) => {
const accounts = {};

View File

@@ -102,7 +102,7 @@ export default class NewGeth extends Component {
const { api } = this.context;
const { accounts } = this.props;
api.personal
api.parity
.listGethAccounts()
.then((_addresses) => {
const addresses = (addresses || []).filter((address) => !accounts[address]);

View File

@@ -208,13 +208,13 @@ export default class CreateAccount extends Component {
});
if (createType === 'fromNew' || createType === 'fromPhrase') {
return api.personal
return api.parity
.newAccountFromPhrase(this.state.phrase, this.state.password)
.then((address) => {
this.setState({ address });
return api.personal
return api.parity
.setAccountName(address, this.state.name)
.then(() => api.personal.setAccountMeta(address, {
.then(() => api.parity.setAccountMeta(address, {
timestamp: Date.now(),
passwordHint: this.state.passwordHint
}));
@@ -233,13 +233,13 @@ export default class CreateAccount extends Component {
this.newError(error);
});
} else if (createType === 'fromRaw') {
return api.personal
return api.parity
.newAccountFromSecret(this.state.rawKey, this.state.password)
.then((address) => {
this.setState({ address });
return api.personal
return api.parity
.setAccountName(address, this.state.name)
.then(() => api.personal.setAccountMeta(address, {
.then(() => api.parity.setAccountMeta(address, {
timestamp: Date.now(),
passwordHint: this.state.passwordHint
}));
@@ -258,13 +258,13 @@ export default class CreateAccount extends Component {
this.newError(error);
});
} else if (createType === 'fromGeth') {
return api.personal
return api.parity
.importGethAccounts(this.state.gethAddresses)
.then((result) => {
console.log('result', result);
return Promise.all(this.state.gethAddresses.map((address) => {
return api.personal.setAccountName(address, 'Geth Import');
return api.parity.setAccountName(address, 'Geth Import');
}));
})
.then(() => {
@@ -282,16 +282,16 @@ export default class CreateAccount extends Component {
});
}
return api.personal
return api.parity
.newAccountFromWallet(this.state.json, this.state.password)
.then((address) => {
this.setState({
address: address
});
return api.personal
return api.parity
.setAccountName(address, this.state.name)
.then(() => api.personal.setAccountMeta(address, {
.then(() => api.parity.setAccountMeta(address, {
timestamp: Date.now(),
passwordHint: this.state.passwordHint
}));

View File

@@ -213,8 +213,8 @@ export default class DeployContract extends Component {
.deploy(options, params, this.onDeploymentState)
.then((address) => {
return Promise.all([
api.personal.setAccountName(address, name),
api.personal.setAccountMeta(address, {
api.parity.setAccountName(address, name),
api.parity.setAccountMeta(address, {
abi: abiParsed,
contract: true,
timestamp: Date.now(),

View File

@@ -139,8 +139,8 @@ export default class EditMeta extends Component {
Promise
.all([
api.personal.setAccountName(account.address, name),
api.personal.setAccountMeta(account.address, Object.assign({}, account.meta, meta))
api.parity.setAccountName(account.address, name),
api.parity.setAccountMeta(account.address, Object.assign({}, account.meta, meta))
])
.then(() => this.props.onClose())
.catch((error) => {

View File

@@ -221,7 +221,7 @@ export default class ExecuteContract extends Component {
})
.then((requestId) => {
this.setState({ busyState: 'Waiting for authorization in the Parity Signer' });
return api.pollMethod('eth_checkRequest', requestId);
return api.pollMethod('parity_checkRequest', requestId);
})
.then((txhash) => {
this.setState({ sending: false, step: 2, txhash, busyState: 'Your transaction has been posted to the network' });

View File

@@ -183,9 +183,9 @@ export default class FirstRun extends Component {
canCreate: false
});
return api.personal
return api.parity
.newAccountFromPhrase(phrase, password)
.then((address) => api.personal.setAccountName(address, name))
.then((address) => api.parity.setAccountName(address, name))
.then(() => {
this.onNext();
})

View File

@@ -317,7 +317,7 @@ export default class PasswordManager extends Component {
this.setState({ waiting: true, showMessage: false });
this.context
.api.personal
.api.parity
.testPassword(account.address, currentPass)
.then(correct => {
const message = correct
@@ -343,7 +343,7 @@ export default class PasswordManager extends Component {
this.setState({ waiting: true, showMessage: false });
this.context
.api.personal
.api.parity
.testPassword(account.address, currentPass)
.then(correct => {
if (!correct) {
@@ -363,11 +363,11 @@ export default class PasswordManager extends Component {
return Promise.all([
this.context
.api.personal
.api.parity
.setAccountMeta(account.address, meta),
this.context
.api.personal
.api.parity
.changePassword(account.address, currentPass, newPass)
])
.then(() => {

View File

@@ -424,7 +424,7 @@ export default class Transfer extends Component {
options.data = data;
}
return api.eth.postTransaction(options);
return api.parity.postTransaction(options);
}
_sendToken () {
@@ -455,7 +455,7 @@ export default class Transfer extends Component {
: this._sendToken()
).then((requestId) => {
this.setState({ busyState: 'Waiting for authorization in the Parity Signer' });
return api.pollMethod('eth_checkRequest', requestId);
return api.pollMethod('parity_checkRequest', requestId);
})
.then((txhash) => {
this.onNext();
@@ -592,7 +592,7 @@ export default class Transfer extends Component {
Promise
.all([
api.ethcore.gasPriceHistogram(),
api.parity.gasPriceHistogram(),
api.eth.gasPrice()
])
.then(([gasPriceHistogram, gasPrice]) => {

View File

@@ -42,7 +42,7 @@ export default class Balances {
_subscribeAccountsInfo () {
this._api
.subscribe('personal_accountsInfo', (error, accountsInfo) => {
.subscribe('parity_accountsInfo', (error, accountsInfo) => {
if (error) {
return;
}
@@ -76,7 +76,7 @@ export default class Balances {
}
_retrieveTokens () {
this._api.ethcore
this._api.parity
.registryAddress()
.then((registryAddress) => {
const registry = this._api.newContract(abis.registry, registryAddress);

View File

@@ -28,9 +28,9 @@ export default class Personal {
_subscribeAccountsInfo () {
this._api
.subscribe('personal_accountsInfo', (error, accountsInfo) => {
.subscribe('parity_accountsInfo', (error, accountsInfo) => {
if (error) {
console.error('personal_accountsInfo', error);
console.error('parity_accountsInfo', error);
return;
}

View File

@@ -14,22 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
// 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 { signerRequestsToConfirm } from './signerActions';
export default class Signer {
@@ -44,7 +28,7 @@ export default class Signer {
_subscribeRequestsToConfirm () {
this._api
.subscribe('personal_requestsToConfirm', (error, pending) => {
.subscribe('signer_requestsToConfirm', (error, pending) => {
if (error) {
return;
}

View File

@@ -51,7 +51,7 @@ export default class SignerMiddleware {
onConfirmStart = (store, action) => {
const { id, password } = action.payload;
this._api.personal
this._api.signer
.confirmRequest(id, {}, password)
.then((txHash) => {
console.log('confirmRequest', id, txHash);
@@ -71,7 +71,7 @@ export default class SignerMiddleware {
onRejectStart = (store, action) => {
const id = action.payload;
this._api.personal
this._api.signer
.rejectRequest(id)
.then(() => {
store.dispatch(actions.successRejectRequest({ id }));

View File

@@ -31,8 +31,8 @@ export default class Status {
}
_fetchEnode () {
this._api
.ethcore.enode()
this._api.parity
.enode()
.then((enode) => {
this._store.dispatch(statusCollection({ enode }));
})
@@ -101,16 +101,16 @@ export default class Status {
.all([
this._api.web3.clientVersion(),
this._api.eth.coinbase(),
this._api.ethcore.defaultExtraData(),
this._api.ethcore.extraData(),
this._api.ethcore.gasFloorTarget(),
this._api.parity.defaultExtraData(),
this._api.parity.extraData(),
this._api.parity.gasFloorTarget(),
this._api.eth.hashrate(),
this._api.ethcore.minGasPrice(),
this._api.ethcore.netChain(),
this._api.ethcore.netPeers(),
this._api.ethcore.netPort(),
this._api.ethcore.nodeName(),
this._api.ethcore.rpcSettings(),
this._api.parity.minGasPrice(),
this._api.parity.netChain(),
this._api.parity.netPeers(),
this._api.parity.netPort(),
this._api.parity.nodeName(),
this._api.parity.rpcSettings(),
this._api.eth.syncing(),
this._pollTraceMode()
])
@@ -153,8 +153,8 @@ export default class Status {
Promise
.all([
this._api.ethcore.devLogs(),
this._api.ethcore.devLogsLevels()
this._api.parity.devLogs(),
this._api.parity.devLogsLevels()
])
.then(([devLogs, devLogsLevels]) => {
this._store.dispatch(statusLogs({

View File

@@ -62,7 +62,7 @@ export default class SecureApi extends Api {
case 1:
if (isConnected) {
this._connectState = 2;
this.personal
this.parity
.generateAuthorizationToken()
.then((token) => {
this.updateToken(token, 2);
@@ -96,8 +96,8 @@ export default class SecureApi extends Api {
Promise
.all([
this.ethcore.dappsPort(),
this.ethcore.signerPort()
this.parity.dappsPort(),
this.parity.signerPort()
])
.then(([dappsPort, signerPort]) => {
this._dappsPort = dappsPort.toNumber();

View File

@@ -149,7 +149,7 @@ export default class Header extends Component {
const { account } = this.props;
this.setState({ name }, () => {
api.personal
api.parity
.setAccountName(account.address, name)
.catch((error) => {
console.error(error);

View File

@@ -81,7 +81,7 @@ class Delete extends Component {
account.meta.deleted = true;
api.personal
api.parity
.setAccountMeta(account.address, account.meta)
.then(() => {
router.push(route);

View File

@@ -104,8 +104,8 @@ class Application extends Component {
checkAccounts () {
const { api } = this.context;
api.personal
.listAccounts()
api.eth
.accounts()
.then((accounts) => {
this.setState({
showFirstRun: showFirstRun || accounts.length === 0

View File

@@ -16,6 +16,9 @@
import React, { Component, PropTypes } from 'react';
import Contracts from '../../contracts';
import { fetchAvailable } from '../Dapps/registry';
import styles from './dapp.css';
export default class Dapp extends Component {
@@ -27,16 +30,39 @@ export default class Dapp extends Component {
params: PropTypes.object
};
state = {
app: null
}
componentWillMount () {
this.lookup();
}
render () {
const { name, type } = this.props.params;
const { app } = this.state;
const { dappsUrl } = this.context.api;
let src = `${dappsUrl}/${name}/`;
if (type === 'builtin') {
const dapphost = process.env.NODE_ENV === 'production'
? `${dappsUrl}/ui`
: '';
src = `${dapphost}/${name}.html`;
if (!app) {
return null;
}
let src = null;
switch (app.type) {
case 'builtin':
const dapphost = process.env.NODE_ENV === 'production' && !app.secure
? `${dappsUrl}/ui`
: '';
src = `${dapphost}/${app.url}.html`;
break;
case 'local':
src = `${dappsUrl}/${app.id}/`;
break;
case 'network':
src = `${dappsUrl}/${app.contentHash}/`;
break;
default:
console.error('unknown type', app.type);
break;
}
return (
@@ -50,4 +76,30 @@ export default class Dapp extends Component {
</iframe>
);
}
lookup () {
const { api } = this.context;
const { id } = this.props.params;
const { dappReg } = Contracts.get();
fetchAvailable(api)
.then((available) => {
return available.find((app) => app.id === id);
})
.then((app) => {
if (app.type !== 'network') {
return app;
}
return dappReg
.getContent(app.id)
.then((contentHash) => {
app.contentHash = api.util.bytesToHex(contentHash).substr(2);
return app;
});
})
.then((app) => {
this.setState({ app });
});
}
}

View File

@@ -39,16 +39,7 @@ export default class Summary extends Component {
return null;
}
let type = 'builtin';
if (app.network) {
type = 'network';
} else if (app.local) {
type = 'local';
}
const url = `/app/${type}/${app.url || app.contentHash || app.id}`;
let image = <div className={ styles.image }>&nbsp;</div>;
if (app.image) {
image = <img src={ `http://127.0.0.1:${dappsPort}${app.image}` } className={ styles.image } />;
} else if (app.iconUrl) {
@@ -61,7 +52,7 @@ export default class Summary extends Component {
<div className={ styles.description }>
<ContainerTitle
className={ styles.title }
title={ <Link to={ url }>{ app.name }</Link> }
title={ <Link to={ `/app/${app.id}` }>{ app.name }</Link> }
byline={ app.description } />
<div className={ styles.author }>{ app.author }, v{ app.version }</div>
{ this.props.children }

View File

@@ -55,7 +55,8 @@ const builtinApps = [
name: 'GitHub Hint',
description: 'A mapping of GitHub URLs to hashes for use in contracts as references',
author: 'Parity Team <admin@ethcore.io>',
version: '1.0.0'
version: '1.0.0',
secure: true
}
];
@@ -81,13 +82,6 @@ function getHost (api) {
}
export function fetchAvailable (api) {
// TODO: Since we don't have an extensive GithubHint app, get the value somehow
// RESULT: 0x22cd66e1b05882c0fa17a16d252d3b3ee2238ccbac8153f69a35c83f02ca76ee
// api.ethcore
// .hashContent('https://codeload.github.com/gavofyork/gavcoin/zip/5a9f11ff2ad0d05c565a938ceffdfa0d23af9981')
// .then((sha3) => {
// console.log('archive', sha3);
// });
return fetch(`${getHost(api)}/api/apps`)
.then((response) => {
return response.ok
@@ -102,11 +96,11 @@ export function fetchAvailable (api) {
const localApps = _localApps
.filter((app) => !['ui'].includes(app.id))
.map((app) => {
app.local = true;
app.type = 'local';
return app;
});
return api.ethcore
return api.parity
.registryAddress()
.then((registryAddress) => {
if (new BigNumber(registryAddress).eq(0)) {
@@ -115,13 +109,13 @@ export function fetchAvailable (api) {
const _builtinApps = builtinApps
.map((app) => {
app.builtin = true;
app.type = 'builtin';
return app;
});
return networkApps
.map((app) => {
app.network = true;
app.type = 'network';
return app;
})
.concat(_builtinApps);

View File

@@ -89,7 +89,7 @@ export default class Parity extends Component {
onChangeMode = (event, index, mode) => {
const { api } = this.context;
api.ethcore
api.parity
.setMode(mode)
.then((result) => {
if (result) {
@@ -104,7 +104,7 @@ export default class Parity extends Component {
loadMode () {
const { api } = this.context;
api.ethcore
api.parity
.mode()
.then((mode) => {
this.setState({ mode });

View File

@@ -50,7 +50,7 @@ export default class SignRequest extends Component {
}
componentWillMount () {
this.context.api.ethcore.netChain()
this.context.api.parity.netChain()
.then((chain) => {
this.setState({ chain });
})

View File

@@ -65,7 +65,7 @@ export default class TransactionFinished extends Component {
const totalValue = tUtil.getTotalValue(fee, value);
this.setState({ totalValue });
this.context.api.ethcore.netChain()
this.context.api.parity.netChain()
.then((chain) => {
this.setState({ chain });
})

View File

@@ -64,7 +64,7 @@ export default class TransactionPending extends Component {
const gasToDisplay = tUtil.getGasDisplay(gas);
this.setState({ gasPriceEthmDisplay, totalValue, gasToDisplay });
this.context.api.ethcore.netChain()
this.context.api.parity.netChain()
.then((chain) => {
this.setState({ chain });
})

View File

@@ -87,7 +87,7 @@ export default class MiningSettings extends Component {
onMinGasPriceChange = (newVal) => {
const { api } = this.context;
api.ethcore.setMinGasPrice(numberFromString(newVal));
api.parity.setMinGasPrice(numberFromString(newVal));
};
onExtraDataChange = (newVal, isResetToDefault) => {
@@ -97,18 +97,18 @@ export default class MiningSettings extends Component {
// In case of resetting to default we are just using raw bytes from defaultExtraData
// When user sets new value we can safely send a string that will be converted to hex by formatter.
const val = isResetToDefault ? nodeStatus.defaultExtraData : newVal;
api.ethcore.setExtraData(val);
api.parity.setExtraData(val);
};
onAuthorChange = (newVal) => {
const { api } = this.context;
api.ethcore.setAuthor(newVal);
api.parity.setAuthor(newVal);
};
onGasFloorTargetChange = (newVal) => {
const { api } = this.context;
api.ethcore.setGasFloorTarget(numberFromString(newVal));
api.parity.setGasFloorTarget(numberFromString(newVal));
};
}