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:
parent
78f2d88182
commit
9c4979681c
22
README.md
22
README.md
@ -1,9 +1,12 @@
|
|||||||
# [Parity](https://ethcore.io/parity.html)
|
# [Parity](https://ethcore.io/parity.html)
|
||||||
### Fast, light, and robust Ethereum implementation
|
### Fast, light, and robust Ethereum implementation
|
||||||
|
|
||||||
[![Join the chat at https://gitter.im/ethcore/parity.js](https://badges.gitter.im/ethcore/parity.js.svg)](https://gitter.im/ethcore/parity.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[![Build Status][travis-image]][travis-url] [![build status](https://gitlab.ethcore.io/Mirrors/ethcore-parity/badges/master/build.svg)](https://gitlab.ethcore.io/Mirrors/ethcore-parity/commits/master) [![Coverage Status][coveralls-image]][coveralls-url] [![GPLv3][license-image]][license-url]
|
||||||
|
|
||||||
[![Build Status][travis-image]][travis-url] [![build status](https://gitlab.ethcore.io/Mirrors/ethcore-parity/badges/master/build.svg)](https://gitlab.ethcore.io/Mirrors/ethcore-parity/commits/master) [![Coverage Status][coveralls-image]][coveralls-url] [![Join the chat at https://gitter.im/ethcore/parity][gitter-image]][gitter-url] [![GPLv3][license-image]][license-url]
|
### Join the chat!
|
||||||
|
|
||||||
|
Parity [![Join the chat at https://gitter.im/ethcore/parity][gitter-image]][gitter-url] and
|
||||||
|
parity.js [![Join the chat at https://gitter.im/ethcore/parity.js](https://badges.gitter.im/ethcore/parity.js.svg)](https://gitter.im/ethcore/parity.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
|
|
||||||
[Internal Documentation][doc-url]
|
[Internal Documentation][doc-url]
|
||||||
|
|
||||||
@ -21,7 +24,7 @@ Be sure to check out [our wiki][wiki-url] for more information.
|
|||||||
[doc-url]: https://ethcore.github.io/parity/ethcore/index.html
|
[doc-url]: https://ethcore.github.io/parity/ethcore/index.html
|
||||||
[wiki-url]: https://github.com/ethcore/parity/wiki
|
[wiki-url]: https://github.com/ethcore/parity/wiki
|
||||||
|
|
||||||
**Requires Rust version 1.12.0 to build**
|
**Parity requires Rust version 1.12.0 to build**
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
@ -31,12 +34,15 @@ Be sure to check out [our wiki][wiki-url] for more information.
|
|||||||
Parity's goal is to be the fastest, lightest, and most secure Ethereum client. We are developing Parity using the sophisticated and
|
Parity's goal is to be the fastest, lightest, and most secure Ethereum client. We are developing Parity using the sophisticated and
|
||||||
cutting-edge Rust programming language. Parity is licensed under the GPLv3, and can be used for all your Ethereum needs.
|
cutting-edge Rust programming language. Parity is licensed under the GPLv3, and can be used for all your Ethereum needs.
|
||||||
|
|
||||||
By default, Parity will run a JSONRPC server on `127.0.0.1:8545`. This is fully configurable and supports a number
|
Parity comes with a built-in wallet. To access [Parity Wallet](http://127.0.0.1:8080/) this simply go to http://127.0.0.1:8080/. It
|
||||||
of RPC APIs.
|
includes various functionality allowing you to:
|
||||||
|
- create and manage your Ethereum accounts;
|
||||||
|
- manage your Ether and any Ethereum tokens;
|
||||||
|
- create and register your own tokens;
|
||||||
|
- and much more.
|
||||||
|
|
||||||
Parity also runs a server for running decentralized apps, or "Dapps", on `http://127.0.0.1:8080`.
|
By default, Parity will also run a JSONRPC server on `127.0.0.1:8545`. This is fully configurable and supports a number
|
||||||
This includes a few useful Dapps, including Ethereum Wallet, Maker OTC, and a node status page.
|
of RPC APIs.
|
||||||
In a near-future release, it will be easy to install Dapps and use them through this web interface.
|
|
||||||
|
|
||||||
If you run into an issue while using parity, feel free to file one in this repository
|
If you run into an issue while using parity, feel free to file one in this repository
|
||||||
or hop on our [gitter chat room][gitter-url] to ask a question. We are glad to help!
|
or hop on our [gitter chat room][gitter-url] to ask a question. We are glad to help!
|
||||||
|
@ -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.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.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.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.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.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.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)
|
- [ethapi.web3](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#web3)
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
import { Http, Ws } from './transport';
|
import { Http, Ws } from './transport';
|
||||||
import Contract from './contract';
|
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 Subscriptions from './subscriptions';
|
||||||
import util from './util';
|
import util from './util';
|
||||||
import { isFunction } from './util/types';
|
import { isFunction } from './util/types';
|
||||||
@ -32,10 +32,11 @@ export default class Api {
|
|||||||
|
|
||||||
this._db = new Db(transport);
|
this._db = new Db(transport);
|
||||||
this._eth = new Eth(transport);
|
this._eth = new Eth(transport);
|
||||||
this._ethcore = new Ethcore(transport);
|
|
||||||
this._net = new Net(transport);
|
this._net = new Net(transport);
|
||||||
|
this._parity = new Parity(transport);
|
||||||
this._personal = new Personal(transport);
|
this._personal = new Personal(transport);
|
||||||
this._shh = new Shh(transport);
|
this._shh = new Shh(transport);
|
||||||
|
this._signer = new Signer(transport);
|
||||||
this._trace = new Trace(transport);
|
this._trace = new Trace(transport);
|
||||||
this._web3 = new Web3(transport);
|
this._web3 = new Web3(transport);
|
||||||
|
|
||||||
@ -50,8 +51,8 @@ export default class Api {
|
|||||||
return this._eth;
|
return this._eth;
|
||||||
}
|
}
|
||||||
|
|
||||||
get ethcore () {
|
get parity () {
|
||||||
return this._ethcore;
|
return this._parity;
|
||||||
}
|
}
|
||||||
|
|
||||||
get net () {
|
get net () {
|
||||||
@ -66,6 +67,10 @@ export default class Api {
|
|||||||
return this._shh;
|
return this._shh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get signer () {
|
||||||
|
return this._signer;
|
||||||
|
}
|
||||||
|
|
||||||
get trace () {
|
get trace () {
|
||||||
return this._trace;
|
return this._trace;
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ export default class Contract {
|
|||||||
options.gas = gas.toFixed(0);
|
options.gas = gas.toFixed(0);
|
||||||
|
|
||||||
setState({ state: 'postTransaction', gas });
|
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) => {
|
.then((requestId) => {
|
||||||
setState({ state: 'checkRequest', requestId });
|
setState({ state: 'checkRequest', requestId });
|
||||||
@ -166,7 +166,7 @@ export default class Contract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_pollCheckRequest = (requestId) => {
|
_pollCheckRequest = (requestId) => {
|
||||||
return this._api.pollMethod('eth_checkRequest', requestId);
|
return this._api.pollMethod('parity_checkRequest', requestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
_pollTransactionReceipt = (txhash, gas) => {
|
_pollTransactionReceipt = (txhash, gas) => {
|
||||||
@ -208,7 +208,7 @@ export default class Contract {
|
|||||||
|
|
||||||
if (!func.constant) {
|
if (!func.constant) {
|
||||||
func.postTransaction = (options, values = []) => {
|
func.postTransaction = (options, values = []) => {
|
||||||
return this._api.eth
|
return this._api.parity
|
||||||
.postTransaction(this._encodeOptions(func, this._addOptionsTo(options), values));
|
.postTransaction(this._encodeOptions(func, this._addOptionsTo(options), values));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -249,9 +249,9 @@ describe('api/contract/Contract', () => {
|
|||||||
before(() => {
|
before(() => {
|
||||||
scope = mockHttp([
|
scope = mockHttp([
|
||||||
{ method: 'eth_estimateGas', reply: { result: 1000 } },
|
{ method: 'eth_estimateGas', reply: { result: 1000 } },
|
||||||
{ method: 'eth_postTransaction', reply: { result: '0x678' } },
|
{ method: 'parity_postTransaction', reply: { result: '0x678' } },
|
||||||
{ method: 'eth_checkRequest', reply: { result: null } },
|
{ method: 'parity_checkRequest', reply: { result: null } },
|
||||||
{ method: 'eth_checkRequest', reply: { result: '0x890' } },
|
{ method: 'parity_checkRequest', reply: { result: '0x890' } },
|
||||||
{ method: 'eth_getTransactionReceipt', reply: { result: null } },
|
{ method: 'eth_getTransactionReceipt', reply: { result: null } },
|
||||||
{ method: 'eth_getTransactionReceipt', reply: { result: RECEIPT_PEND } },
|
{ method: 'eth_getTransactionReceipt', reply: { result: RECEIPT_PEND } },
|
||||||
{ method: 'eth_getTransactionReceipt', reply: { result: RECEIPT_DONE } },
|
{ 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)', () => {
|
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' }
|
{ data: '0x123', gas: '0x4b0' }
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
@ -280,8 +280,8 @@ describe('api/contract/Contract', () => {
|
|||||||
it('fails when gasUsed == gas', () => {
|
it('fails when gasUsed == gas', () => {
|
||||||
mockHttp([
|
mockHttp([
|
||||||
{ method: 'eth_estimateGas', reply: { result: 1000 } },
|
{ method: 'eth_estimateGas', reply: { result: 1000 } },
|
||||||
{ method: 'eth_postTransaction', reply: { result: '0x678' } },
|
{ method: 'parity_postTransaction', reply: { result: '0x678' } },
|
||||||
{ method: 'eth_checkRequest', reply: { result: '0x789' } },
|
{ method: 'parity_checkRequest', reply: { result: '0x789' } },
|
||||||
{ method: 'eth_getTransactionReceipt', reply: { result: RECEIPT_EXCP } }
|
{ method: 'eth_getTransactionReceipt', reply: { result: RECEIPT_EXCP } }
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -295,8 +295,8 @@ describe('api/contract/Contract', () => {
|
|||||||
it('fails when no code was deployed', () => {
|
it('fails when no code was deployed', () => {
|
||||||
mockHttp([
|
mockHttp([
|
||||||
{ method: 'eth_estimateGas', reply: { result: 1000 } },
|
{ method: 'eth_estimateGas', reply: { result: 1000 } },
|
||||||
{ method: 'eth_postTransaction', reply: { result: '0x678' } },
|
{ method: 'parity_postTransaction', reply: { result: '0x678' } },
|
||||||
{ method: 'eth_checkRequest', reply: { result: '0x789' } },
|
{ method: 'parity_checkRequest', reply: { result: '0x789' } },
|
||||||
{ method: 'eth_getTransactionReceipt', reply: { result: RECEIPT_DONE } },
|
{ method: 'eth_getTransactionReceipt', reply: { result: RECEIPT_DONE } },
|
||||||
{ method: 'eth_getCode', reply: { result: '0x' } }
|
{ method: 'eth_getCode', reply: { result: '0x' } }
|
||||||
]);
|
]);
|
||||||
@ -360,15 +360,15 @@ describe('api/contract/Contract', () => {
|
|||||||
|
|
||||||
describe('postTransaction', () => {
|
describe('postTransaction', () => {
|
||||||
beforeEach(() => {
|
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
|
return func
|
||||||
.postTransaction({ someExtras: 'foo' }, VALUES)
|
.postTransaction({ someExtras: 'foo' }, VALUES)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
expect(scope.isDone()).to.be.true;
|
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',
|
someExtras: 'foo',
|
||||||
to: ADDR,
|
to: ADDR,
|
||||||
data: ENCODED
|
data: ENCODED
|
||||||
|
@ -39,11 +39,6 @@ export default class Eth {
|
|||||||
.execute('eth_call', inOptions(options), inBlockNumber(blockNumber));
|
.execute('eth_call', inOptions(options), inBlockNumber(blockNumber));
|
||||||
}
|
}
|
||||||
|
|
||||||
checkRequest (requestId) {
|
|
||||||
return this._transport
|
|
||||||
.execute('eth_checkRequest', inNumber16(requestId));
|
|
||||||
}
|
|
||||||
|
|
||||||
coinbase () {
|
coinbase () {
|
||||||
return this._transport
|
return this._transport
|
||||||
.execute('eth_coinbase')
|
.execute('eth_coinbase')
|
||||||
@ -267,11 +262,6 @@ export default class Eth {
|
|||||||
.execute('eth_pendingTransactions');
|
.execute('eth_pendingTransactions');
|
||||||
}
|
}
|
||||||
|
|
||||||
postTransaction (options) {
|
|
||||||
return this._transport
|
|
||||||
.execute('eth_postTransaction', inOptions(options));
|
|
||||||
}
|
|
||||||
|
|
||||||
protocolVersion () {
|
protocolVersion () {
|
||||||
return this._transport
|
return this._transport
|
||||||
.execute('eth_protocolVersion');
|
.execute('eth_protocolVersion');
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,9 +16,10 @@
|
|||||||
|
|
||||||
export Db from './db';
|
export Db from './db';
|
||||||
export Eth from './eth';
|
export Eth from './eth';
|
||||||
export Ethcore from './ethcore';
|
export Parity from './parity';
|
||||||
export Net from './net';
|
export Net from './net';
|
||||||
export Personal from './personal';
|
export Personal from './personal';
|
||||||
export Shh from './shh';
|
export Shh from './shh';
|
||||||
|
export Signer from './signer';
|
||||||
export Trace from './trace';
|
export Trace from './trace';
|
||||||
export Web3 from './web3';
|
export Web3 from './web3';
|
||||||
|
@ -14,4 +14,4 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
export default from './ethcore';
|
export default from './parity';
|
@ -16,12 +16,12 @@
|
|||||||
|
|
||||||
import { createHttpApi } from '../../../../test/e2e/ethapi';
|
import { createHttpApi } from '../../../../test/e2e/ethapi';
|
||||||
|
|
||||||
describe('ethapi.ethcore', () => {
|
describe('ethapi.parity', () => {
|
||||||
const ethapi = createHttpApi();
|
const ethapi = createHttpApi();
|
||||||
|
|
||||||
describe('gasFloorTarget', () => {
|
describe('gasFloorTarget', () => {
|
||||||
it('returns and translates the target', () => {
|
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;
|
expect(value.gt(0)).to.be.true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -29,7 +29,7 @@ describe('ethapi.ethcore', () => {
|
|||||||
|
|
||||||
describe('gasPriceHistogram', () => {
|
describe('gasPriceHistogram', () => {
|
||||||
it('returns and translates the target', () => {
|
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(Object.keys(result)).to.deep.equal(['bucketBounds', 'counts']);
|
||||||
expect(result.bucketBounds.length > 0).to.be.true;
|
expect(result.bucketBounds.length > 0).to.be.true;
|
||||||
expect(result.counts.length > 0).to.be.true;
|
expect(result.counts.length > 0).to.be.true;
|
||||||
@ -39,7 +39,7 @@ describe('ethapi.ethcore', () => {
|
|||||||
|
|
||||||
describe('netChain', () => {
|
describe('netChain', () => {
|
||||||
it('returns and the chain', () => {
|
it('returns and the chain', () => {
|
||||||
return ethapi.ethcore.netChain().then((value) => {
|
return ethapi.parity.netChain().then((value) => {
|
||||||
expect(value).to.equal('morden');
|
expect(value).to.equal('morden');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -47,7 +47,7 @@ describe('ethapi.ethcore', () => {
|
|||||||
|
|
||||||
describe('netPort', () => {
|
describe('netPort', () => {
|
||||||
it('returns and translates the port', () => {
|
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;
|
expect(value.gt(0)).to.be.true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -55,7 +55,7 @@ describe('ethapi.ethcore', () => {
|
|||||||
|
|
||||||
describe('transactionsLimit', () => {
|
describe('transactionsLimit', () => {
|
||||||
it('returns and translates the limit', () => {
|
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;
|
expect(value.gt(0)).to.be.true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -63,7 +63,7 @@ describe('ethapi.ethcore', () => {
|
|||||||
|
|
||||||
describe('rpcSettings', () => {
|
describe('rpcSettings', () => {
|
||||||
it('returns and translates the settings', () => {
|
it('returns and translates the settings', () => {
|
||||||
return ethapi.ethcore.rpcSettings().then((value) => {
|
return ethapi.parity.rpcSettings().then((value) => {
|
||||||
expect(value).to.be.ok;
|
expect(value).to.be.ok;
|
||||||
});
|
});
|
||||||
});
|
});
|
273
js/src/api/rpc/parity/parity.js
Normal file
273
js/src/api/rpc/parity/parity.js
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
@ -18,14 +18,36 @@ import { TEST_HTTP_URL, mockHttp } from '../../../../test/mockRpc';
|
|||||||
import { isBigNumber } from '../../../../test/types';
|
import { isBigNumber } from '../../../../test/types';
|
||||||
|
|
||||||
import Http from '../../transport/http';
|
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', () => {
|
describe('gasFloorTarget', () => {
|
||||||
it('returns the gasfloor, formatted', () => {
|
it('returns the gasfloor, formatted', () => {
|
||||||
mockHttp([{ method: 'ethcore_gasFloorTarget', reply: { result: '0x123456' } }]);
|
mockHttp([{ method: 'parity_gasFloorTarget', reply: { result: '0x123456' } }]);
|
||||||
|
|
||||||
return instance.gasFloorTarget().then((count) => {
|
return instance.gasFloorTarget().then((count) => {
|
||||||
expect(isBigNumber(count)).to.be.true;
|
expect(isBigNumber(count)).to.be.true;
|
||||||
@ -36,7 +58,7 @@ describe('api/rpc/Ethcore', () => {
|
|||||||
|
|
||||||
describe('minGasPrice', () => {
|
describe('minGasPrice', () => {
|
||||||
it('returns the min gasprice, formatted', () => {
|
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) => {
|
return instance.minGasPrice().then((count) => {
|
||||||
expect(isBigNumber(count)).to.be.true;
|
expect(isBigNumber(count)).to.be.true;
|
||||||
@ -47,7 +69,7 @@ describe('api/rpc/Ethcore', () => {
|
|||||||
|
|
||||||
describe('netMaxPeers', () => {
|
describe('netMaxPeers', () => {
|
||||||
it('returns the max peers, formatted', () => {
|
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) => {
|
return instance.netMaxPeers().then((count) => {
|
||||||
expect(isBigNumber(count)).to.be.true;
|
expect(isBigNumber(count)).to.be.true;
|
||||||
@ -58,7 +80,7 @@ describe('api/rpc/Ethcore', () => {
|
|||||||
|
|
||||||
describe('newPeers', () => {
|
describe('newPeers', () => {
|
||||||
it('returns the peer structure, formatted', () => {
|
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) => {
|
return instance.netPeers().then((peers) => {
|
||||||
expect(peers.active.eq(123)).to.be.true;
|
expect(peers.active.eq(123)).to.be.true;
|
||||||
@ -70,7 +92,7 @@ describe('api/rpc/Ethcore', () => {
|
|||||||
|
|
||||||
describe('netPort', () => {
|
describe('netPort', () => {
|
||||||
it('returns the connected port, formatted', () => {
|
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) => {
|
return instance.netPort().then((count) => {
|
||||||
expect(isBigNumber(count)).to.be.true;
|
expect(isBigNumber(count)).to.be.true;
|
||||||
@ -81,7 +103,7 @@ describe('api/rpc/Ethcore', () => {
|
|||||||
|
|
||||||
describe('transactionsLimit', () => {
|
describe('transactionsLimit', () => {
|
||||||
it('returns the tx limit, formatted', () => {
|
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) => {
|
return instance.transactionsLimit().then((count) => {
|
||||||
expect(isBigNumber(count)).to.be.true;
|
expect(isBigNumber(count)).to.be.true;
|
@ -14,113 +14,31 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import { inAddress, inHex, inNumber10, inNumber16, inOptions } from '../../format/input';
|
import { inAddress, inNumber10, inOptions } from '../../format/input';
|
||||||
import { outAccountInfo, outAddress, outSignerRequest } from '../../format/output';
|
import { outAddress } from '../../format/output';
|
||||||
|
|
||||||
export default class Personal {
|
export default class Personal {
|
||||||
constructor (transport) {
|
constructor (transport) {
|
||||||
this._transport = 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 () {
|
listAccounts () {
|
||||||
return this._transport
|
return this._transport
|
||||||
.execute('personal_listAccounts')
|
.execute('personal_listAccounts')
|
||||||
.then((accounts) => (accounts || []).map(outAddress));
|
.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) {
|
newAccount (password) {
|
||||||
return this._transport
|
return this._transport
|
||||||
.execute('personal_newAccount', password)
|
.execute('personal_newAccount', password)
|
||||||
.then(outAddress);
|
.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) {
|
signAndSendTransaction (options, password) {
|
||||||
return this._transport
|
return this._transport
|
||||||
.execute('personal_signAndSendTransaction', inOptions(options), password);
|
.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) {
|
unlockAccount (account, password, duration = 1) {
|
||||||
return this._transport
|
return this._transport
|
||||||
.execute('personal_unlockAccount', inAddress(account), password, inNumber10(duration));
|
.execute('personal_unlockAccount', inAddress(account), password, inNumber10(duration));
|
||||||
|
@ -26,28 +26,6 @@ describe('rpc/Personal', () => {
|
|||||||
const checksum = '0x63Cf90D3f0410092FC0fca41846f596223979195';
|
const checksum = '0x63Cf90D3f0410092FC0fca41846f596223979195';
|
||||||
let scope;
|
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', () => {
|
describe('listAccounts', () => {
|
||||||
it('retrieves a list of available accounts', () => {
|
it('retrieves a list of available accounts', () => {
|
||||||
scope = mockHttp([{ method: 'personal_listAccounts', reply: { result: [account] } }]);
|
scope = mockHttp([{ method: 'personal_listAccounts', reply: { result: [account] } }]);
|
||||||
|
17
js/src/api/rpc/signer/index.js
Normal file
17
js/src/api/rpc/signer/index.js
Normal 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';
|
50
js/src/api/rpc/signer/signer.js
Normal file
50
js/src/api/rpc/signer/signer.js
Normal 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');
|
||||||
|
}
|
||||||
|
}
|
@ -24,9 +24,9 @@ import Signer from './signer';
|
|||||||
const events = {
|
const events = {
|
||||||
'logging': { module: 'logging' },
|
'logging': { module: 'logging' },
|
||||||
'eth_blockNumber': { module: 'eth' },
|
'eth_blockNumber': { module: 'eth' },
|
||||||
'personal_accountsInfo': { module: 'personal' },
|
'parity_accountsInfo': { module: 'personal' },
|
||||||
'personal_listAccounts': { module: 'personal' },
|
'eth_accounts': { module: 'personal' },
|
||||||
'personal_requestsToConfirm': { module: 'signer' }
|
'signer_requestsToConfirm': { module: 'signer' }
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class Manager {
|
export default class Manager {
|
||||||
|
@ -37,18 +37,18 @@ export default class Personal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_listAccounts = () => {
|
_listAccounts = () => {
|
||||||
return this._api.personal
|
return this._api.eth
|
||||||
.listAccounts()
|
.accounts()
|
||||||
.then((accounts) => {
|
.then((accounts) => {
|
||||||
this._updateSubscriptions('personal_listAccounts', null, accounts);
|
this._updateSubscriptions('eth_accounts', null, accounts);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_accountsInfo = () => {
|
_accountsInfo = () => {
|
||||||
return this._api.personal
|
return this._api.parity
|
||||||
.accountsInfo()
|
.accountsInfo()
|
||||||
.then((info) => {
|
.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) {
|
switch (data.method) {
|
||||||
case 'personal_importGethAccounts':
|
case 'parity_importGethAccounts':
|
||||||
case 'personal_newAccount':
|
case 'personal_newAccount':
|
||||||
case 'personal_newAccountFromPhrase':
|
case 'parity_newAccountFromPhrase':
|
||||||
case 'personal_newAccountFromWallet':
|
case 'parity_newAccountFromWallet':
|
||||||
this._listAccounts();
|
this._listAccounts();
|
||||||
this._accountsInfo();
|
this._accountsInfo();
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 'personal_setAccountName':
|
case 'parity_setAccountName':
|
||||||
case 'personal_setAccountMeta':
|
case 'parity_setAccountMeta':
|
||||||
this._accountsInfo();
|
this._accountsInfo();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -34,14 +34,15 @@ function stubApi (accounts, info) {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
_calls,
|
_calls,
|
||||||
personal: {
|
parity: {
|
||||||
accountsInfo: () => {
|
accountsInfo: () => {
|
||||||
const stub = sinon.stub().resolves(info || TEST_INFO)();
|
const stub = sinon.stub().resolves(info || TEST_INFO)();
|
||||||
_calls.accountsInfo.push(stub);
|
_calls.accountsInfo.push(stub);
|
||||||
return stub;
|
return stub;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
eth: {
|
||||||
listAccounts: () => {
|
accounts: () => {
|
||||||
const stub = sinon.stub().resolves(accounts || TEST_LIST)();
|
const stub = sinon.stub().resolves(accounts || TEST_LIST)();
|
||||||
_calls.listAccounts.push(stub);
|
_calls.listAccounts.push(stub);
|
||||||
return stub;
|
return stub;
|
||||||
@ -85,17 +86,17 @@ describe('api/subscriptions/personal', () => {
|
|||||||
expect(personal.isStarted).to.be.true;
|
expect(personal.isStarted).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('calls personal_accountsInfo', () => {
|
it('calls parity_accountsInfo', () => {
|
||||||
expect(api._calls.accountsInfo.length).to.be.ok;
|
expect(api._calls.accountsInfo.length).to.be.ok;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('calls personal_listAccounts', () => {
|
it('calls eth_accounts', () => {
|
||||||
expect(api._calls.listAccounts.length).to.be.ok;
|
expect(api._calls.listAccounts.length).to.be.ok;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('updates subscribers', () => {
|
it('updates subscribers', () => {
|
||||||
expect(cb.firstCall).to.have.been.calledWith('personal_listAccounts', null, TEST_LIST);
|
expect(cb.firstCall).to.have.been.calledWith('eth_accounts', null, TEST_LIST);
|
||||||
expect(cb.secondCall).to.have.been.calledWith('personal_accountsInfo', null, TEST_INFO);
|
expect(cb.secondCall).to.have.been.calledWith('parity_accountsInfo', null, TEST_INFO);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -49,10 +49,10 @@ export default class Signer {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._api.personal
|
return this._api.signer
|
||||||
.requestsToConfirm()
|
.requestsToConfirm()
|
||||||
.then((requests) => {
|
.then((requests) => {
|
||||||
this._updateSubscriptions('personal_requestsToConfirm', null, requests);
|
this._updateSubscriptions('signer_requestsToConfirm', null, requests);
|
||||||
nextTimeout();
|
nextTimeout();
|
||||||
})
|
})
|
||||||
.catch(nextTimeout);
|
.catch(nextTimeout);
|
||||||
@ -65,7 +65,7 @@ export default class Signer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (data.method) {
|
switch (data.method) {
|
||||||
case 'eth_postTransaction':
|
case 'parity_postTransaction':
|
||||||
case 'eth_sendTranasction':
|
case 'eth_sendTranasction':
|
||||||
case 'eth_sendRawTransaction':
|
case 'eth_sendRawTransaction':
|
||||||
this._listRequests(false);
|
this._listRequests(false);
|
||||||
|
@ -56,6 +56,8 @@ export default class Http extends JsonRpcBase {
|
|||||||
if (response.status !== 200) {
|
if (response.status !== 200) {
|
||||||
this._connected = false;
|
this._connected = false;
|
||||||
this.error(JSON.stringify({ status: response.status, statusText: response.statusText }));
|
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}`);
|
throw new Error(`${response.status}: ${response.statusText}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +68,9 @@ export default class Http extends JsonRpcBase {
|
|||||||
|
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
this.error(JSON.stringify(response));
|
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));
|
this.log(JSON.stringify(response));
|
||||||
|
@ -107,7 +107,9 @@ export default class Ws extends JsonRpcBase {
|
|||||||
if (result.error) {
|
if (result.error) {
|
||||||
this.error(event.data);
|
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];
|
delete this._messages[result.id];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ export default class Registry {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._api.ethcore
|
this._api.parity
|
||||||
.registryAddress()
|
.registryAddress()
|
||||||
.then((address) => {
|
.then((address) => {
|
||||||
this._instance = this._api.newContract(abis.registry, address).instance;
|
this._instance = this._api.newContract(abis.registry, address).instance;
|
||||||
|
@ -83,7 +83,7 @@ export default class Application extends Component {
|
|||||||
Promise
|
Promise
|
||||||
.all([
|
.all([
|
||||||
attachInstances(),
|
attachInstances(),
|
||||||
api.personal.accountsInfo()
|
api.parity.accounts()
|
||||||
])
|
])
|
||||||
.then(([{ managerInstance, registryInstance, tokenregInstance }, accountsInfo]) => {
|
.then(([{ managerInstance, registryInstance, tokenregInstance }, accountsInfo]) => {
|
||||||
accountsInfo = accountsInfo || {};
|
accountsInfo = accountsInfo || {};
|
||||||
|
@ -296,7 +296,7 @@ export default class Deployment extends Component {
|
|||||||
.then((signerRequestId) => {
|
.then((signerRequestId) => {
|
||||||
this.setState({ signerRequestId, deployState: 'Transaction posted, Waiting for transaction authorization' });
|
this.setState({ signerRequestId, deployState: 'Transaction posted, Waiting for transaction authorization' });
|
||||||
|
|
||||||
return api.pollMethod('eth_checkRequest', signerRequestId);
|
return api.pollMethod('parity_checkRequest', signerRequestId);
|
||||||
})
|
})
|
||||||
.then((txHash) => {
|
.then((txHash) => {
|
||||||
this.setState({ txHash, deployState: 'Transaction authorized, Waiting for network confirmations' });
|
this.setState({ txHash, deployState: 'Transaction authorized, Waiting for network confirmations' });
|
||||||
|
@ -279,7 +279,7 @@ export default class Send extends Component {
|
|||||||
.then((signerRequestId) => {
|
.then((signerRequestId) => {
|
||||||
this.setState({ signerRequestId, sendState: 'Transaction posted, Waiting for transaction authorization' });
|
this.setState({ signerRequestId, sendState: 'Transaction posted, Waiting for transaction authorization' });
|
||||||
|
|
||||||
return api.pollMethod('eth_checkRequest', signerRequestId);
|
return api.pollMethod('parity_checkRequest', signerRequestId);
|
||||||
})
|
})
|
||||||
.then((txHash) => {
|
.then((txHash) => {
|
||||||
this.setState({ txHash, sendState: 'Transaction authorized, Waiting for network confirmations' });
|
this.setState({ txHash, sendState: 'Transaction authorized, Waiting for network confirmations' });
|
||||||
|
@ -100,8 +100,8 @@ export function attachInstances () {
|
|||||||
|
|
||||||
return Promise
|
return Promise
|
||||||
.all([
|
.all([
|
||||||
api.ethcore.registryAddress(),
|
api.parity.registryAddress(),
|
||||||
api.ethcore.netChain()
|
api.parity.netChain()
|
||||||
])
|
])
|
||||||
.then(([registryAddress, netChain]) => {
|
.then(([registryAddress, netChain]) => {
|
||||||
const registry = api.newContract(abis.registry, registryAddress).instance;
|
const registry = api.newContract(abis.registry, registryAddress).instance;
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
<div id="container"></div>
|
<div id="container"></div>
|
||||||
<script src="vendor.js"></script>
|
<script src="vendor.js"></script>
|
||||||
<script src="commons.js"></script>
|
<script src="commons.js"></script>
|
||||||
<script src="/parity-utils/parity.js"></script>
|
|
||||||
<script src="githubhint.js"></script>
|
<script src="githubhint.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -41,7 +41,9 @@ export default class Application extends Component {
|
|||||||
registerBusy: false,
|
registerBusy: false,
|
||||||
registerError: null,
|
registerError: null,
|
||||||
registerState: '',
|
registerState: '',
|
||||||
registerType: 'file'
|
registerType: 'file',
|
||||||
|
repo: '',
|
||||||
|
repoError: null
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
@ -206,47 +208,64 @@ export default class Application extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onChangeCommit = (event) => {
|
onChangeCommit = (event) => {
|
||||||
const commit = event.target.value;
|
let commit = event.target.value;
|
||||||
const commitError = null;
|
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' }, () => {
|
hasContent = commit.length !== 0 && parts.length === 2 && parts[0].length !== 0 && parts[1].length !== 0;
|
||||||
const { repo } = this.state;
|
if (!commitError && hasContent) {
|
||||||
|
this.setState({ contentHashError: 'hash lookup in progress' });
|
||||||
this.lookupHash(`https://codeload.github.com/${repo}/zip/${commit}`);
|
this.lookupHash(`https://codeload.github.com/${repo}/zip/${commit}`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onChangeRepo = (event) => {
|
onChangeRepo = (event) => {
|
||||||
let repo = event.target.value;
|
let repo = event.target.value;
|
||||||
const repoError = null;
|
const repoError = null;
|
||||||
|
let hasContent = false;
|
||||||
|
|
||||||
// TODO: field validation
|
// TODO: field validation
|
||||||
if (!repoError) {
|
if (!repoError) {
|
||||||
repo = repo.replace('https://github.com/', '');
|
repo = repo.replace('https://github.com/', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({ repo, repoError, contentHashError: 'hash lookup in progress' }, () => {
|
this.setState({ repo, repoError, contentHashError: null }, () => {
|
||||||
const { commit } = this.state;
|
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}`);
|
this.lookupHash(`https://codeload.github.com/${repo}/zip/${commit}`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onChangeUrl = (event) => {
|
onChangeUrl = (event) => {
|
||||||
let url = event.target.value;
|
let url = event.target.value;
|
||||||
const urlError = null;
|
const urlError = null;
|
||||||
|
let hasContent = false;
|
||||||
|
|
||||||
// TODO: field validation
|
// TODO: field validation
|
||||||
if (!urlError) {
|
if (!urlError) {
|
||||||
const parts = url.split('/');
|
const parts = url.split('/');
|
||||||
|
hasContent = parts.length !== 0;
|
||||||
|
|
||||||
if (parts[2] === 'github.com' || parts[2] === 'raw.githubusercontent.com') {
|
if (parts[2] === 'github.com' || parts[2] === 'raw.githubusercontent.com') {
|
||||||
url = `https://raw.githubusercontent.com/${parts.slice(3).join('/')}`.replace('/blob/', '/');
|
url = `https://raw.githubusercontent.com/${parts.slice(3).join('/')}`.replace('/blob/', '/');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({ url, urlError, contentHashError: 'hash lookup in progress' }, () => {
|
this.setState({ url, urlError, contentHashError: null }, () => {
|
||||||
|
if (!urlError && hasContent) {
|
||||||
|
this.setState({ contentHashError: 'hash lookup in progress' });
|
||||||
this.lookupHash(url);
|
this.lookupHash(url);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,7 +290,7 @@ export default class Application extends Component {
|
|||||||
.then((signerRequestId) => {
|
.then((signerRequestId) => {
|
||||||
this.setState({ signerRequestId, registerState: 'Transaction posted, Waiting for transaction authorization' });
|
this.setState({ signerRequestId, registerState: 'Transaction posted, Waiting for transaction authorization' });
|
||||||
|
|
||||||
return api.pollMethod('eth_checkRequest', signerRequestId);
|
return api.pollMethod('parity_checkRequest', signerRequestId);
|
||||||
})
|
})
|
||||||
.then((txHash) => {
|
.then((txHash) => {
|
||||||
this.setState({ txHash, registerState: 'Transaction authorized, Waiting for network confirmations' });
|
this.setState({ txHash, registerState: 'Transaction authorized, Waiting for network confirmations' });
|
||||||
@ -285,7 +304,7 @@ export default class Application extends Component {
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
.then((txReceipt) => {
|
.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) => {
|
.catch((error) => {
|
||||||
console.error('onSend', 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' });
|
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 };
|
const options = { from: fromAddress };
|
||||||
|
|
||||||
this.trackRequest(
|
this.trackRequest(
|
||||||
@ -367,7 +386,7 @@ export default class Application extends Component {
|
|||||||
|
|
||||||
console.log(`lookupHash ${url}`);
|
console.log(`lookupHash ${url}`);
|
||||||
|
|
||||||
api.ethcore
|
api.parity
|
||||||
.hashContent(url)
|
.hashContent(url)
|
||||||
.then((contentHash) => {
|
.then((contentHash) => {
|
||||||
console.log('lookupHash', contentHash);
|
console.log('lookupHash', contentHash);
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
const { api } = window.parity;
|
const api = window.parent.secureApi;
|
||||||
|
|
||||||
export {
|
export {
|
||||||
api
|
api
|
||||||
|
@ -18,7 +18,7 @@ import * as abis from '../../contracts/abi';
|
|||||||
import { api } from './parity';
|
import { api } from './parity';
|
||||||
|
|
||||||
export function attachInterface () {
|
export function attachInterface () {
|
||||||
return api.ethcore
|
return api.parity
|
||||||
.registryAddress()
|
.registryAddress()
|
||||||
.then((registryAddress) => {
|
.then((registryAddress) => {
|
||||||
console.log(`the registry was found at ${registryAddress}`);
|
console.log(`the registry was found at ${registryAddress}`);
|
||||||
@ -29,7 +29,7 @@ export function attachInterface () {
|
|||||||
.all([
|
.all([
|
||||||
registry.getAddress.call({}, [api.util.sha3('githubhint'), 'A']),
|
registry.getAddress.call({}, [api.util.sha3('githubhint'), 'A']),
|
||||||
api.eth.accounts(),
|
api.eth.accounts(),
|
||||||
api.personal.accountsInfo()
|
api.parity.accounts()
|
||||||
]);
|
]);
|
||||||
})
|
})
|
||||||
.then(([address, addresses, accountsInfo]) => {
|
.then(([address, addresses, accountsInfo]) => {
|
||||||
|
@ -29,7 +29,7 @@ export { addresses, accounts, lookup, events, names, records };
|
|||||||
export const setContract = (contract) => ({ type: 'set contract', contract });
|
export const setContract = (contract) => ({ type: 'set contract', contract });
|
||||||
|
|
||||||
export const fetchContract = () => (dispatch) =>
|
export const fetchContract = () => (dispatch) =>
|
||||||
api.ethcore.registryAddress()
|
api.parity.registryAddress()
|
||||||
.then((address) => {
|
.then((address) => {
|
||||||
const contract = api.newContract(registryAbi, address);
|
const contract = api.newContract(registryAbi, address);
|
||||||
dispatch(setContract(contract));
|
dispatch(setContract(contract));
|
||||||
|
@ -22,7 +22,7 @@ export const fetch = () => (dispatch) => {
|
|||||||
return Promise
|
return Promise
|
||||||
.all([
|
.all([
|
||||||
api.eth.accounts(),
|
api.eth.accounts(),
|
||||||
api.personal.accountsInfo()
|
api.parity.accounts()
|
||||||
])
|
])
|
||||||
.then(([ accounts, data ]) => {
|
.then(([ accounts, data ]) => {
|
||||||
data = data || {};
|
data = data || {};
|
||||||
|
@ -39,7 +39,7 @@ const logToEvent = (log) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function attachInterface (callback) {
|
export function attachInterface (callback) {
|
||||||
return api.ethcore
|
return api.parity
|
||||||
.registryAddress()
|
.registryAddress()
|
||||||
.then((registryAddress) => {
|
.then((registryAddress) => {
|
||||||
console.log(`the registry was found at ${registryAddress}`);
|
console.log(`the registry was found at ${registryAddress}`);
|
||||||
@ -50,7 +50,7 @@ export function attachInterface (callback) {
|
|||||||
.all([
|
.all([
|
||||||
registry.getAddress.call({}, [api.util.sha3('signaturereg'), 'A']),
|
registry.getAddress.call({}, [api.util.sha3('signaturereg'), 'A']),
|
||||||
api.eth.accounts(),
|
api.eth.accounts(),
|
||||||
api.personal.accountsInfo()
|
api.parity.accounts()
|
||||||
]);
|
]);
|
||||||
})
|
})
|
||||||
.then(([address, addresses, accountsInfo]) => {
|
.then(([address, addresses, accountsInfo]) => {
|
||||||
|
@ -38,7 +38,7 @@ export const loadAccounts = () => (dispatch) => {
|
|||||||
Promise
|
Promise
|
||||||
.all([
|
.all([
|
||||||
api.eth.accounts(),
|
api.eth.accounts(),
|
||||||
api.personal.accountsInfo()
|
api.parity.accounts()
|
||||||
])
|
])
|
||||||
.then(([ accounts, accountsInfo ]) => {
|
.then(([ accounts, accountsInfo ]) => {
|
||||||
accountsInfo = accountsInfo || {};
|
accountsInfo = accountsInfo || {};
|
||||||
|
@ -34,7 +34,7 @@ export const FIND_CONTRACT = 'FIND_CONTRACT';
|
|||||||
export const loadContract = () => (dispatch) => {
|
export const loadContract = () => (dispatch) => {
|
||||||
dispatch(setLoading(true));
|
dispatch(setLoading(true));
|
||||||
|
|
||||||
api.ethcore
|
api.parity
|
||||||
.registryAddress()
|
.registryAddress()
|
||||||
.then((registryAddress) => {
|
.then((registryAddress) => {
|
||||||
console.log(`registry found at ${registryAddress}`);
|
console.log(`registry found at ${registryAddress}`);
|
||||||
|
@ -74,7 +74,7 @@ ReactDOM.render(
|
|||||||
<Route path='addresses' component={ Addresses } />
|
<Route path='addresses' component={ Addresses } />
|
||||||
<Route path='address/:address' component={ Address } />
|
<Route path='address/:address' component={ Address } />
|
||||||
<Route path='apps' component={ Dapps } />
|
<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='contracts' component={ Contracts } />
|
||||||
<Route path='contract/:address' component={ Contract } />
|
<Route path='contract/:address' component={ Contract } />
|
||||||
<Route path='settings' component={ Settings }>
|
<Route path='settings' component={ Settings }>
|
||||||
|
@ -16,20 +16,22 @@
|
|||||||
|
|
||||||
import db from './interfaces/db';
|
import db from './interfaces/db';
|
||||||
import eth from './interfaces/eth';
|
import eth from './interfaces/eth';
|
||||||
import ethcore from './interfaces/ethcore';
|
|
||||||
import net from './interfaces/net';
|
import net from './interfaces/net';
|
||||||
|
import parity from './interfaces/parity';
|
||||||
import personal from './interfaces/personal';
|
import personal from './interfaces/personal';
|
||||||
import shh from './interfaces/shh';
|
import shh from './interfaces/shh';
|
||||||
|
import signer from './interfaces/signer';
|
||||||
import trace from './interfaces/trace';
|
import trace from './interfaces/trace';
|
||||||
import web3 from './interfaces/web3';
|
import web3 from './interfaces/web3';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
db: db,
|
db,
|
||||||
eth: eth,
|
eth,
|
||||||
ethcore: ethcore,
|
parity,
|
||||||
net: net,
|
net,
|
||||||
personal: personal,
|
personal,
|
||||||
shh: shh,
|
shh,
|
||||||
trace: trace,
|
signer,
|
||||||
web3: web3
|
trace,
|
||||||
|
web3
|
||||||
};
|
};
|
||||||
|
@ -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: {
|
coinbase: {
|
||||||
desc: 'Returns the client coinbase address.',
|
desc: 'Returns the client coinbase address.',
|
||||||
params: [],
|
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: {
|
protocolVersion: {
|
||||||
desc: 'Returns the current ethereum protocol version.',
|
desc: 'Returns the current ethereum protocol version.',
|
||||||
params: [],
|
params: [],
|
||||||
|
@ -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: {
|
addReservedPeer: {
|
||||||
desc: '?',
|
desc: '?',
|
||||||
params: [
|
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: {
|
dappsPort: {
|
||||||
desc: 'Returns the port the dapps are running on, error if not enabled',
|
desc: 'Returns the port the dapps are running on, error if not enabled',
|
||||||
params: [],
|
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: {
|
minGasPrice: {
|
||||||
desc: 'Returns currently set minimal gas price',
|
desc: 'Returns currently set minimal gas price',
|
||||||
params: [],
|
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: {
|
nodeName: {
|
||||||
desc: 'Returns node name (identity)',
|
desc: 'Returns node name (identity)',
|
||||||
params: [],
|
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: {
|
removeReservedPeer: {
|
||||||
desc: '?',
|
desc: '?',
|
||||||
params: [
|
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: {
|
setAuthor: {
|
||||||
desc: 'Changes author (coinbase) for mined blocks.',
|
desc: 'Changes author (coinbase) for mined blocks.',
|
||||||
params: [
|
params: [
|
@ -17,83 +17,6 @@
|
|||||||
import { Address, Data, Quantity } from '../types';
|
import { Address, Data, Quantity } from '../types';
|
||||||
|
|
||||||
export default {
|
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: {
|
listAccounts: {
|
||||||
desc: 'Returns a list of addresses owned by client.',
|
desc: 'Returns a list of addresses owned by client.',
|
||||||
params: [],
|
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: {
|
newAccount: {
|
||||||
desc: 'Creates new account',
|
desc: 'Creates new account',
|
||||||
params: [
|
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: {
|
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. ',
|
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: [
|
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: {
|
unlockAccount: {
|
||||||
desc: '?',
|
desc: '?',
|
||||||
params: [
|
params: [
|
||||||
|
82
js/src/jsonrpc/interfaces/signer.js
Normal file
82
js/src/jsonrpc/interfaces/signer.js
Normal 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'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
@ -133,8 +133,8 @@ export default class AddAddress extends Component {
|
|||||||
const { address, name, description } = this.state;
|
const { address, name, description } = this.state;
|
||||||
|
|
||||||
Promise.all([
|
Promise.all([
|
||||||
api.personal.setAccountName(address, name),
|
api.parity.setAccountName(address, name),
|
||||||
api.personal.setAccountMeta(address, {
|
api.parity.setAccountMeta(address, {
|
||||||
description,
|
description,
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
deleted: false
|
deleted: false
|
||||||
|
@ -141,8 +141,8 @@ export default class AddContract extends Component {
|
|||||||
const { abiParsed, address, name, description } = this.state;
|
const { abiParsed, address, name, description } = this.state;
|
||||||
|
|
||||||
Promise.all([
|
Promise.all([
|
||||||
api.personal.setAccountName(address, name),
|
api.parity.setAccountName(address, name),
|
||||||
api.personal.setAccountMeta(address, {
|
api.parity.setAccountMeta(address, {
|
||||||
contract: true,
|
contract: true,
|
||||||
deleted: false,
|
deleted: false,
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
|
@ -173,15 +173,15 @@ export default class CreateAccount extends Component {
|
|||||||
|
|
||||||
Promise
|
Promise
|
||||||
.all([
|
.all([
|
||||||
api.ethcore.generateSecretPhrase(),
|
api.parity.generateSecretPhrase(),
|
||||||
api.ethcore.generateSecretPhrase(),
|
api.parity.generateSecretPhrase(),
|
||||||
api.ethcore.generateSecretPhrase(),
|
api.parity.generateSecretPhrase(),
|
||||||
api.ethcore.generateSecretPhrase(),
|
api.parity.generateSecretPhrase(),
|
||||||
api.ethcore.generateSecretPhrase()
|
api.parity.generateSecretPhrase()
|
||||||
])
|
])
|
||||||
.then((phrases) => {
|
.then((phrases) => {
|
||||||
return Promise
|
return Promise
|
||||||
.all(phrases.map((phrase) => api.ethcore.phraseToAddress(phrase)))
|
.all(phrases.map((phrase) => api.parity.phraseToAddress(phrase)))
|
||||||
.then((addresses) => {
|
.then((addresses) => {
|
||||||
const accounts = {};
|
const accounts = {};
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ export default class NewGeth extends Component {
|
|||||||
const { api } = this.context;
|
const { api } = this.context;
|
||||||
const { accounts } = this.props;
|
const { accounts } = this.props;
|
||||||
|
|
||||||
api.personal
|
api.parity
|
||||||
.listGethAccounts()
|
.listGethAccounts()
|
||||||
.then((_addresses) => {
|
.then((_addresses) => {
|
||||||
const addresses = (addresses || []).filter((address) => !accounts[address]);
|
const addresses = (addresses || []).filter((address) => !accounts[address]);
|
||||||
|
@ -208,13 +208,13 @@ export default class CreateAccount extends Component {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (createType === 'fromNew' || createType === 'fromPhrase') {
|
if (createType === 'fromNew' || createType === 'fromPhrase') {
|
||||||
return api.personal
|
return api.parity
|
||||||
.newAccountFromPhrase(this.state.phrase, this.state.password)
|
.newAccountFromPhrase(this.state.phrase, this.state.password)
|
||||||
.then((address) => {
|
.then((address) => {
|
||||||
this.setState({ address });
|
this.setState({ address });
|
||||||
return api.personal
|
return api.parity
|
||||||
.setAccountName(address, this.state.name)
|
.setAccountName(address, this.state.name)
|
||||||
.then(() => api.personal.setAccountMeta(address, {
|
.then(() => api.parity.setAccountMeta(address, {
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
passwordHint: this.state.passwordHint
|
passwordHint: this.state.passwordHint
|
||||||
}));
|
}));
|
||||||
@ -233,13 +233,13 @@ export default class CreateAccount extends Component {
|
|||||||
this.newError(error);
|
this.newError(error);
|
||||||
});
|
});
|
||||||
} else if (createType === 'fromRaw') {
|
} else if (createType === 'fromRaw') {
|
||||||
return api.personal
|
return api.parity
|
||||||
.newAccountFromSecret(this.state.rawKey, this.state.password)
|
.newAccountFromSecret(this.state.rawKey, this.state.password)
|
||||||
.then((address) => {
|
.then((address) => {
|
||||||
this.setState({ address });
|
this.setState({ address });
|
||||||
return api.personal
|
return api.parity
|
||||||
.setAccountName(address, this.state.name)
|
.setAccountName(address, this.state.name)
|
||||||
.then(() => api.personal.setAccountMeta(address, {
|
.then(() => api.parity.setAccountMeta(address, {
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
passwordHint: this.state.passwordHint
|
passwordHint: this.state.passwordHint
|
||||||
}));
|
}));
|
||||||
@ -258,13 +258,13 @@ export default class CreateAccount extends Component {
|
|||||||
this.newError(error);
|
this.newError(error);
|
||||||
});
|
});
|
||||||
} else if (createType === 'fromGeth') {
|
} else if (createType === 'fromGeth') {
|
||||||
return api.personal
|
return api.parity
|
||||||
.importGethAccounts(this.state.gethAddresses)
|
.importGethAccounts(this.state.gethAddresses)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
console.log('result', result);
|
console.log('result', result);
|
||||||
|
|
||||||
return Promise.all(this.state.gethAddresses.map((address) => {
|
return Promise.all(this.state.gethAddresses.map((address) => {
|
||||||
return api.personal.setAccountName(address, 'Geth Import');
|
return api.parity.setAccountName(address, 'Geth Import');
|
||||||
}));
|
}));
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -282,16 +282,16 @@ export default class CreateAccount extends Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return api.personal
|
return api.parity
|
||||||
.newAccountFromWallet(this.state.json, this.state.password)
|
.newAccountFromWallet(this.state.json, this.state.password)
|
||||||
.then((address) => {
|
.then((address) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
address: address
|
address: address
|
||||||
});
|
});
|
||||||
|
|
||||||
return api.personal
|
return api.parity
|
||||||
.setAccountName(address, this.state.name)
|
.setAccountName(address, this.state.name)
|
||||||
.then(() => api.personal.setAccountMeta(address, {
|
.then(() => api.parity.setAccountMeta(address, {
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
passwordHint: this.state.passwordHint
|
passwordHint: this.state.passwordHint
|
||||||
}));
|
}));
|
||||||
|
@ -213,8 +213,8 @@ export default class DeployContract extends Component {
|
|||||||
.deploy(options, params, this.onDeploymentState)
|
.deploy(options, params, this.onDeploymentState)
|
||||||
.then((address) => {
|
.then((address) => {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
api.personal.setAccountName(address, name),
|
api.parity.setAccountName(address, name),
|
||||||
api.personal.setAccountMeta(address, {
|
api.parity.setAccountMeta(address, {
|
||||||
abi: abiParsed,
|
abi: abiParsed,
|
||||||
contract: true,
|
contract: true,
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
|
@ -139,8 +139,8 @@ export default class EditMeta extends Component {
|
|||||||
|
|
||||||
Promise
|
Promise
|
||||||
.all([
|
.all([
|
||||||
api.personal.setAccountName(account.address, name),
|
api.parity.setAccountName(account.address, name),
|
||||||
api.personal.setAccountMeta(account.address, Object.assign({}, account.meta, meta))
|
api.parity.setAccountMeta(account.address, Object.assign({}, account.meta, meta))
|
||||||
])
|
])
|
||||||
.then(() => this.props.onClose())
|
.then(() => this.props.onClose())
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
@ -221,7 +221,7 @@ export default class ExecuteContract extends Component {
|
|||||||
})
|
})
|
||||||
.then((requestId) => {
|
.then((requestId) => {
|
||||||
this.setState({ busyState: 'Waiting for authorization in the Parity Signer' });
|
this.setState({ busyState: 'Waiting for authorization in the Parity Signer' });
|
||||||
return api.pollMethod('eth_checkRequest', requestId);
|
return api.pollMethod('parity_checkRequest', requestId);
|
||||||
})
|
})
|
||||||
.then((txhash) => {
|
.then((txhash) => {
|
||||||
this.setState({ sending: false, step: 2, txhash, busyState: 'Your transaction has been posted to the network' });
|
this.setState({ sending: false, step: 2, txhash, busyState: 'Your transaction has been posted to the network' });
|
||||||
|
@ -183,9 +183,9 @@ export default class FirstRun extends Component {
|
|||||||
canCreate: false
|
canCreate: false
|
||||||
});
|
});
|
||||||
|
|
||||||
return api.personal
|
return api.parity
|
||||||
.newAccountFromPhrase(phrase, password)
|
.newAccountFromPhrase(phrase, password)
|
||||||
.then((address) => api.personal.setAccountName(address, name))
|
.then((address) => api.parity.setAccountName(address, name))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.onNext();
|
this.onNext();
|
||||||
})
|
})
|
||||||
|
@ -317,7 +317,7 @@ export default class PasswordManager extends Component {
|
|||||||
this.setState({ waiting: true, showMessage: false });
|
this.setState({ waiting: true, showMessage: false });
|
||||||
|
|
||||||
this.context
|
this.context
|
||||||
.api.personal
|
.api.parity
|
||||||
.testPassword(account.address, currentPass)
|
.testPassword(account.address, currentPass)
|
||||||
.then(correct => {
|
.then(correct => {
|
||||||
const message = correct
|
const message = correct
|
||||||
@ -343,7 +343,7 @@ export default class PasswordManager extends Component {
|
|||||||
this.setState({ waiting: true, showMessage: false });
|
this.setState({ waiting: true, showMessage: false });
|
||||||
|
|
||||||
this.context
|
this.context
|
||||||
.api.personal
|
.api.parity
|
||||||
.testPassword(account.address, currentPass)
|
.testPassword(account.address, currentPass)
|
||||||
.then(correct => {
|
.then(correct => {
|
||||||
if (!correct) {
|
if (!correct) {
|
||||||
@ -363,11 +363,11 @@ export default class PasswordManager extends Component {
|
|||||||
|
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
this.context
|
this.context
|
||||||
.api.personal
|
.api.parity
|
||||||
.setAccountMeta(account.address, meta),
|
.setAccountMeta(account.address, meta),
|
||||||
|
|
||||||
this.context
|
this.context
|
||||||
.api.personal
|
.api.parity
|
||||||
.changePassword(account.address, currentPass, newPass)
|
.changePassword(account.address, currentPass, newPass)
|
||||||
])
|
])
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
@ -424,7 +424,7 @@ export default class Transfer extends Component {
|
|||||||
options.data = data;
|
options.data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
return api.eth.postTransaction(options);
|
return api.parity.postTransaction(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
_sendToken () {
|
_sendToken () {
|
||||||
@ -455,7 +455,7 @@ export default class Transfer extends Component {
|
|||||||
: this._sendToken()
|
: this._sendToken()
|
||||||
).then((requestId) => {
|
).then((requestId) => {
|
||||||
this.setState({ busyState: 'Waiting for authorization in the Parity Signer' });
|
this.setState({ busyState: 'Waiting for authorization in the Parity Signer' });
|
||||||
return api.pollMethod('eth_checkRequest', requestId);
|
return api.pollMethod('parity_checkRequest', requestId);
|
||||||
})
|
})
|
||||||
.then((txhash) => {
|
.then((txhash) => {
|
||||||
this.onNext();
|
this.onNext();
|
||||||
@ -592,7 +592,7 @@ export default class Transfer extends Component {
|
|||||||
|
|
||||||
Promise
|
Promise
|
||||||
.all([
|
.all([
|
||||||
api.ethcore.gasPriceHistogram(),
|
api.parity.gasPriceHistogram(),
|
||||||
api.eth.gasPrice()
|
api.eth.gasPrice()
|
||||||
])
|
])
|
||||||
.then(([gasPriceHistogram, gasPrice]) => {
|
.then(([gasPriceHistogram, gasPrice]) => {
|
||||||
|
@ -42,7 +42,7 @@ export default class Balances {
|
|||||||
|
|
||||||
_subscribeAccountsInfo () {
|
_subscribeAccountsInfo () {
|
||||||
this._api
|
this._api
|
||||||
.subscribe('personal_accountsInfo', (error, accountsInfo) => {
|
.subscribe('parity_accountsInfo', (error, accountsInfo) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -76,7 +76,7 @@ export default class Balances {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_retrieveTokens () {
|
_retrieveTokens () {
|
||||||
this._api.ethcore
|
this._api.parity
|
||||||
.registryAddress()
|
.registryAddress()
|
||||||
.then((registryAddress) => {
|
.then((registryAddress) => {
|
||||||
const registry = this._api.newContract(abis.registry, registryAddress);
|
const registry = this._api.newContract(abis.registry, registryAddress);
|
||||||
|
@ -28,9 +28,9 @@ export default class Personal {
|
|||||||
|
|
||||||
_subscribeAccountsInfo () {
|
_subscribeAccountsInfo () {
|
||||||
this._api
|
this._api
|
||||||
.subscribe('personal_accountsInfo', (error, accountsInfo) => {
|
.subscribe('parity_accountsInfo', (error, accountsInfo) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error('personal_accountsInfo', error);
|
console.error('parity_accountsInfo', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,22 +14,6 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// 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';
|
import { signerRequestsToConfirm } from './signerActions';
|
||||||
|
|
||||||
export default class Signer {
|
export default class Signer {
|
||||||
@ -44,7 +28,7 @@ export default class Signer {
|
|||||||
|
|
||||||
_subscribeRequestsToConfirm () {
|
_subscribeRequestsToConfirm () {
|
||||||
this._api
|
this._api
|
||||||
.subscribe('personal_requestsToConfirm', (error, pending) => {
|
.subscribe('signer_requestsToConfirm', (error, pending) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ export default class SignerMiddleware {
|
|||||||
onConfirmStart = (store, action) => {
|
onConfirmStart = (store, action) => {
|
||||||
const { id, password } = action.payload;
|
const { id, password } = action.payload;
|
||||||
|
|
||||||
this._api.personal
|
this._api.signer
|
||||||
.confirmRequest(id, {}, password)
|
.confirmRequest(id, {}, password)
|
||||||
.then((txHash) => {
|
.then((txHash) => {
|
||||||
console.log('confirmRequest', id, txHash);
|
console.log('confirmRequest', id, txHash);
|
||||||
@ -71,7 +71,7 @@ export default class SignerMiddleware {
|
|||||||
onRejectStart = (store, action) => {
|
onRejectStart = (store, action) => {
|
||||||
const id = action.payload;
|
const id = action.payload;
|
||||||
|
|
||||||
this._api.personal
|
this._api.signer
|
||||||
.rejectRequest(id)
|
.rejectRequest(id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
store.dispatch(actions.successRejectRequest({ id }));
|
store.dispatch(actions.successRejectRequest({ id }));
|
||||||
|
@ -31,8 +31,8 @@ export default class Status {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_fetchEnode () {
|
_fetchEnode () {
|
||||||
this._api
|
this._api.parity
|
||||||
.ethcore.enode()
|
.enode()
|
||||||
.then((enode) => {
|
.then((enode) => {
|
||||||
this._store.dispatch(statusCollection({ enode }));
|
this._store.dispatch(statusCollection({ enode }));
|
||||||
})
|
})
|
||||||
@ -101,16 +101,16 @@ export default class Status {
|
|||||||
.all([
|
.all([
|
||||||
this._api.web3.clientVersion(),
|
this._api.web3.clientVersion(),
|
||||||
this._api.eth.coinbase(),
|
this._api.eth.coinbase(),
|
||||||
this._api.ethcore.defaultExtraData(),
|
this._api.parity.defaultExtraData(),
|
||||||
this._api.ethcore.extraData(),
|
this._api.parity.extraData(),
|
||||||
this._api.ethcore.gasFloorTarget(),
|
this._api.parity.gasFloorTarget(),
|
||||||
this._api.eth.hashrate(),
|
this._api.eth.hashrate(),
|
||||||
this._api.ethcore.minGasPrice(),
|
this._api.parity.minGasPrice(),
|
||||||
this._api.ethcore.netChain(),
|
this._api.parity.netChain(),
|
||||||
this._api.ethcore.netPeers(),
|
this._api.parity.netPeers(),
|
||||||
this._api.ethcore.netPort(),
|
this._api.parity.netPort(),
|
||||||
this._api.ethcore.nodeName(),
|
this._api.parity.nodeName(),
|
||||||
this._api.ethcore.rpcSettings(),
|
this._api.parity.rpcSettings(),
|
||||||
this._api.eth.syncing(),
|
this._api.eth.syncing(),
|
||||||
this._pollTraceMode()
|
this._pollTraceMode()
|
||||||
])
|
])
|
||||||
@ -153,8 +153,8 @@ export default class Status {
|
|||||||
|
|
||||||
Promise
|
Promise
|
||||||
.all([
|
.all([
|
||||||
this._api.ethcore.devLogs(),
|
this._api.parity.devLogs(),
|
||||||
this._api.ethcore.devLogsLevels()
|
this._api.parity.devLogsLevels()
|
||||||
])
|
])
|
||||||
.then(([devLogs, devLogsLevels]) => {
|
.then(([devLogs, devLogsLevels]) => {
|
||||||
this._store.dispatch(statusLogs({
|
this._store.dispatch(statusLogs({
|
||||||
|
@ -62,7 +62,7 @@ export default class SecureApi extends Api {
|
|||||||
case 1:
|
case 1:
|
||||||
if (isConnected) {
|
if (isConnected) {
|
||||||
this._connectState = 2;
|
this._connectState = 2;
|
||||||
this.personal
|
this.parity
|
||||||
.generateAuthorizationToken()
|
.generateAuthorizationToken()
|
||||||
.then((token) => {
|
.then((token) => {
|
||||||
this.updateToken(token, 2);
|
this.updateToken(token, 2);
|
||||||
@ -96,8 +96,8 @@ export default class SecureApi extends Api {
|
|||||||
|
|
||||||
Promise
|
Promise
|
||||||
.all([
|
.all([
|
||||||
this.ethcore.dappsPort(),
|
this.parity.dappsPort(),
|
||||||
this.ethcore.signerPort()
|
this.parity.signerPort()
|
||||||
])
|
])
|
||||||
.then(([dappsPort, signerPort]) => {
|
.then(([dappsPort, signerPort]) => {
|
||||||
this._dappsPort = dappsPort.toNumber();
|
this._dappsPort = dappsPort.toNumber();
|
||||||
|
@ -149,7 +149,7 @@ export default class Header extends Component {
|
|||||||
const { account } = this.props;
|
const { account } = this.props;
|
||||||
|
|
||||||
this.setState({ name }, () => {
|
this.setState({ name }, () => {
|
||||||
api.personal
|
api.parity
|
||||||
.setAccountName(account.address, name)
|
.setAccountName(account.address, name)
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
|
@ -81,7 +81,7 @@ class Delete extends Component {
|
|||||||
|
|
||||||
account.meta.deleted = true;
|
account.meta.deleted = true;
|
||||||
|
|
||||||
api.personal
|
api.parity
|
||||||
.setAccountMeta(account.address, account.meta)
|
.setAccountMeta(account.address, account.meta)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
router.push(route);
|
router.push(route);
|
||||||
|
@ -104,8 +104,8 @@ class Application extends Component {
|
|||||||
checkAccounts () {
|
checkAccounts () {
|
||||||
const { api } = this.context;
|
const { api } = this.context;
|
||||||
|
|
||||||
api.personal
|
api.eth
|
||||||
.listAccounts()
|
.accounts()
|
||||||
.then((accounts) => {
|
.then((accounts) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
showFirstRun: showFirstRun || accounts.length === 0
|
showFirstRun: showFirstRun || accounts.length === 0
|
||||||
|
@ -16,6 +16,9 @@
|
|||||||
|
|
||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
|
||||||
|
import Contracts from '../../contracts';
|
||||||
|
import { fetchAvailable } from '../Dapps/registry';
|
||||||
|
|
||||||
import styles from './dapp.css';
|
import styles from './dapp.css';
|
||||||
|
|
||||||
export default class Dapp extends Component {
|
export default class Dapp extends Component {
|
||||||
@ -27,16 +30,39 @@ export default class Dapp extends Component {
|
|||||||
params: PropTypes.object
|
params: PropTypes.object
|
||||||
};
|
};
|
||||||
|
|
||||||
|
state = {
|
||||||
|
app: null
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillMount () {
|
||||||
|
this.lookup();
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { name, type } = this.props.params;
|
const { app } = this.state;
|
||||||
const { dappsUrl } = this.context.api;
|
const { dappsUrl } = this.context.api;
|
||||||
|
|
||||||
let src = `${dappsUrl}/${name}/`;
|
if (!app) {
|
||||||
if (type === 'builtin') {
|
return null;
|
||||||
const dapphost = process.env.NODE_ENV === 'production'
|
}
|
||||||
|
|
||||||
|
let src = null;
|
||||||
|
switch (app.type) {
|
||||||
|
case 'builtin':
|
||||||
|
const dapphost = process.env.NODE_ENV === 'production' && !app.secure
|
||||||
? `${dappsUrl}/ui`
|
? `${dappsUrl}/ui`
|
||||||
: '';
|
: '';
|
||||||
src = `${dapphost}/${name}.html`;
|
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 (
|
return (
|
||||||
@ -50,4 +76,30 @@ export default class Dapp extends Component {
|
|||||||
</iframe>
|
</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 });
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,16 +39,7 @@ export default class Summary extends Component {
|
|||||||
return null;
|
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 }> </div>;
|
let image = <div className={ styles.image }> </div>;
|
||||||
|
|
||||||
if (app.image) {
|
if (app.image) {
|
||||||
image = <img src={ `http://127.0.0.1:${dappsPort}${app.image}` } className={ styles.image } />;
|
image = <img src={ `http://127.0.0.1:${dappsPort}${app.image}` } className={ styles.image } />;
|
||||||
} else if (app.iconUrl) {
|
} else if (app.iconUrl) {
|
||||||
@ -61,7 +52,7 @@ export default class Summary extends Component {
|
|||||||
<div className={ styles.description }>
|
<div className={ styles.description }>
|
||||||
<ContainerTitle
|
<ContainerTitle
|
||||||
className={ styles.title }
|
className={ styles.title }
|
||||||
title={ <Link to={ url }>{ app.name }</Link> }
|
title={ <Link to={ `/app/${app.id}` }>{ app.name }</Link> }
|
||||||
byline={ app.description } />
|
byline={ app.description } />
|
||||||
<div className={ styles.author }>{ app.author }, v{ app.version }</div>
|
<div className={ styles.author }>{ app.author }, v{ app.version }</div>
|
||||||
{ this.props.children }
|
{ this.props.children }
|
||||||
|
@ -55,7 +55,8 @@ const builtinApps = [
|
|||||||
name: 'GitHub Hint',
|
name: 'GitHub Hint',
|
||||||
description: 'A mapping of GitHub URLs to hashes for use in contracts as references',
|
description: 'A mapping of GitHub URLs to hashes for use in contracts as references',
|
||||||
author: 'Parity Team <admin@ethcore.io>',
|
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) {
|
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`)
|
return fetch(`${getHost(api)}/api/apps`)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
return response.ok
|
return response.ok
|
||||||
@ -102,11 +96,11 @@ export function fetchAvailable (api) {
|
|||||||
const localApps = _localApps
|
const localApps = _localApps
|
||||||
.filter((app) => !['ui'].includes(app.id))
|
.filter((app) => !['ui'].includes(app.id))
|
||||||
.map((app) => {
|
.map((app) => {
|
||||||
app.local = true;
|
app.type = 'local';
|
||||||
return app;
|
return app;
|
||||||
});
|
});
|
||||||
|
|
||||||
return api.ethcore
|
return api.parity
|
||||||
.registryAddress()
|
.registryAddress()
|
||||||
.then((registryAddress) => {
|
.then((registryAddress) => {
|
||||||
if (new BigNumber(registryAddress).eq(0)) {
|
if (new BigNumber(registryAddress).eq(0)) {
|
||||||
@ -115,13 +109,13 @@ export function fetchAvailable (api) {
|
|||||||
|
|
||||||
const _builtinApps = builtinApps
|
const _builtinApps = builtinApps
|
||||||
.map((app) => {
|
.map((app) => {
|
||||||
app.builtin = true;
|
app.type = 'builtin';
|
||||||
return app;
|
return app;
|
||||||
});
|
});
|
||||||
|
|
||||||
return networkApps
|
return networkApps
|
||||||
.map((app) => {
|
.map((app) => {
|
||||||
app.network = true;
|
app.type = 'network';
|
||||||
return app;
|
return app;
|
||||||
})
|
})
|
||||||
.concat(_builtinApps);
|
.concat(_builtinApps);
|
||||||
|
@ -89,7 +89,7 @@ export default class Parity extends Component {
|
|||||||
onChangeMode = (event, index, mode) => {
|
onChangeMode = (event, index, mode) => {
|
||||||
const { api } = this.context;
|
const { api } = this.context;
|
||||||
|
|
||||||
api.ethcore
|
api.parity
|
||||||
.setMode(mode)
|
.setMode(mode)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
if (result) {
|
if (result) {
|
||||||
@ -104,7 +104,7 @@ export default class Parity extends Component {
|
|||||||
loadMode () {
|
loadMode () {
|
||||||
const { api } = this.context;
|
const { api } = this.context;
|
||||||
|
|
||||||
api.ethcore
|
api.parity
|
||||||
.mode()
|
.mode()
|
||||||
.then((mode) => {
|
.then((mode) => {
|
||||||
this.setState({ mode });
|
this.setState({ mode });
|
||||||
|
@ -50,7 +50,7 @@ export default class SignRequest extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentWillMount () {
|
componentWillMount () {
|
||||||
this.context.api.ethcore.netChain()
|
this.context.api.parity.netChain()
|
||||||
.then((chain) => {
|
.then((chain) => {
|
||||||
this.setState({ chain });
|
this.setState({ chain });
|
||||||
})
|
})
|
||||||
|
@ -65,7 +65,7 @@ export default class TransactionFinished extends Component {
|
|||||||
const totalValue = tUtil.getTotalValue(fee, value);
|
const totalValue = tUtil.getTotalValue(fee, value);
|
||||||
this.setState({ totalValue });
|
this.setState({ totalValue });
|
||||||
|
|
||||||
this.context.api.ethcore.netChain()
|
this.context.api.parity.netChain()
|
||||||
.then((chain) => {
|
.then((chain) => {
|
||||||
this.setState({ chain });
|
this.setState({ chain });
|
||||||
})
|
})
|
||||||
|
@ -64,7 +64,7 @@ export default class TransactionPending extends Component {
|
|||||||
const gasToDisplay = tUtil.getGasDisplay(gas);
|
const gasToDisplay = tUtil.getGasDisplay(gas);
|
||||||
this.setState({ gasPriceEthmDisplay, totalValue, gasToDisplay });
|
this.setState({ gasPriceEthmDisplay, totalValue, gasToDisplay });
|
||||||
|
|
||||||
this.context.api.ethcore.netChain()
|
this.context.api.parity.netChain()
|
||||||
.then((chain) => {
|
.then((chain) => {
|
||||||
this.setState({ chain });
|
this.setState({ chain });
|
||||||
})
|
})
|
||||||
|
@ -87,7 +87,7 @@ export default class MiningSettings extends Component {
|
|||||||
onMinGasPriceChange = (newVal) => {
|
onMinGasPriceChange = (newVal) => {
|
||||||
const { api } = this.context;
|
const { api } = this.context;
|
||||||
|
|
||||||
api.ethcore.setMinGasPrice(numberFromString(newVal));
|
api.parity.setMinGasPrice(numberFromString(newVal));
|
||||||
};
|
};
|
||||||
|
|
||||||
onExtraDataChange = (newVal, isResetToDefault) => {
|
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
|
// 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.
|
// 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;
|
const val = isResetToDefault ? nodeStatus.defaultExtraData : newVal;
|
||||||
api.ethcore.setExtraData(val);
|
api.parity.setExtraData(val);
|
||||||
};
|
};
|
||||||
|
|
||||||
onAuthorChange = (newVal) => {
|
onAuthorChange = (newVal) => {
|
||||||
const { api } = this.context;
|
const { api } = this.context;
|
||||||
|
|
||||||
api.ethcore.setAuthor(newVal);
|
api.parity.setAuthor(newVal);
|
||||||
};
|
};
|
||||||
|
|
||||||
onGasFloorTargetChange = (newVal) => {
|
onGasFloorTargetChange = (newVal) => {
|
||||||
const { api } = this.context;
|
const { api } = this.context;
|
||||||
|
|
||||||
api.ethcore.setGasFloorTarget(numberFromString(newVal));
|
api.parity.setGasFloorTarget(numberFromString(newVal));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -41,13 +41,13 @@ disable = false
|
|||||||
port = 8545
|
port = 8545
|
||||||
interface = "local"
|
interface = "local"
|
||||||
cors = "null"
|
cors = "null"
|
||||||
apis = ["web3", "eth", "net", "ethcore", "traces", "rpc", "personal_safe"]
|
apis = ["web3", "eth", "net", "parity", "traces", "rpc"]
|
||||||
hosts = ["none"]
|
hosts = ["none"]
|
||||||
|
|
||||||
[ipc]
|
[ipc]
|
||||||
disable = false
|
disable = false
|
||||||
path = "$HOME/.parity/jsonrpc.ipc"
|
path = "$HOME/.parity/jsonrpc.ipc"
|
||||||
apis = ["web3", "eth", "net", "ethcore", "traces", "rpc", "personal", "personal_safe"]
|
apis = ["web3", "eth", "net", "parity", "parity_accounts", "personal", "traces", "rpc"]
|
||||||
|
|
||||||
[dapps]
|
[dapps]
|
||||||
disable = false
|
disable = false
|
||||||
|
@ -143,7 +143,7 @@ usage! {
|
|||||||
or |c: &Config| otry!(c.rpc).interface.clone(),
|
or |c: &Config| otry!(c.rpc).interface.clone(),
|
||||||
flag_jsonrpc_cors: Option<String> = None,
|
flag_jsonrpc_cors: Option<String> = None,
|
||||||
or |c: &Config| otry!(c.rpc).cors.clone().map(Some),
|
or |c: &Config| otry!(c.rpc).cors.clone().map(Some),
|
||||||
flag_jsonrpc_apis: String = "web3,eth,net,ethcore,traces,rpc,personal_safe",
|
flag_jsonrpc_apis: String = "web3,eth,net,parity,traces,rpc",
|
||||||
or |c: &Config| otry!(c.rpc).apis.clone().map(|vec| vec.join(",")),
|
or |c: &Config| otry!(c.rpc).apis.clone().map(|vec| vec.join(",")),
|
||||||
flag_jsonrpc_hosts: String = "none",
|
flag_jsonrpc_hosts: String = "none",
|
||||||
or |c: &Config| otry!(c.rpc).hosts.clone().map(|vec| vec.join(",")),
|
or |c: &Config| otry!(c.rpc).hosts.clone().map(|vec| vec.join(",")),
|
||||||
@ -153,7 +153,7 @@ usage! {
|
|||||||
or |c: &Config| otry!(c.ipc).disable.clone(),
|
or |c: &Config| otry!(c.ipc).disable.clone(),
|
||||||
flag_ipc_path: String = "$HOME/.parity/jsonrpc.ipc",
|
flag_ipc_path: String = "$HOME/.parity/jsonrpc.ipc",
|
||||||
or |c: &Config| otry!(c.ipc).path.clone(),
|
or |c: &Config| otry!(c.ipc).path.clone(),
|
||||||
flag_ipc_apis: String = "web3,eth,net,ethcore,traces,rpc,personal,personal_safe",
|
flag_ipc_apis: String = "web3,eth,net,parity,parity_accounts,traces,rpc",
|
||||||
or |c: &Config| otry!(c.ipc).apis.clone().map(|vec| vec.join(",")),
|
or |c: &Config| otry!(c.ipc).apis.clone().map(|vec| vec.join(",")),
|
||||||
|
|
||||||
// DAPPS
|
// DAPPS
|
||||||
@ -540,13 +540,13 @@ mod tests {
|
|||||||
flag_jsonrpc_port: 8545u16,
|
flag_jsonrpc_port: 8545u16,
|
||||||
flag_jsonrpc_interface: "local".into(),
|
flag_jsonrpc_interface: "local".into(),
|
||||||
flag_jsonrpc_cors: Some("null".into()),
|
flag_jsonrpc_cors: Some("null".into()),
|
||||||
flag_jsonrpc_apis: "web3,eth,net,ethcore,traces,rpc,personal_safe".into(),
|
flag_jsonrpc_apis: "web3,eth,net,parity,traces,rpc".into(),
|
||||||
flag_jsonrpc_hosts: "none".into(),
|
flag_jsonrpc_hosts: "none".into(),
|
||||||
|
|
||||||
// IPC
|
// IPC
|
||||||
flag_no_ipc: false,
|
flag_no_ipc: false,
|
||||||
flag_ipc_path: "$HOME/.parity/jsonrpc.ipc".into(),
|
flag_ipc_path: "$HOME/.parity/jsonrpc.ipc".into(),
|
||||||
flag_ipc_apis: "web3,eth,net,ethcore,traces,rpc,personal,personal_safe".into(),
|
flag_ipc_apis: "web3,eth,net,parity,parity_accounts,personal,traces,rpc".into(),
|
||||||
|
|
||||||
// DAPPS
|
// DAPPS
|
||||||
flag_no_dapps: false,
|
flag_no_dapps: false,
|
||||||
|
@ -107,7 +107,7 @@ API and Console Options:
|
|||||||
--jsonrpc-apis APIS Specify the APIs available through the JSONRPC
|
--jsonrpc-apis APIS Specify the APIs available through the JSONRPC
|
||||||
interface. APIS is a comma-delimited list of API
|
interface. APIS is a comma-delimited list of API
|
||||||
name. Possible name are web3, eth, net, personal,
|
name. Possible name are web3, eth, net, personal,
|
||||||
ethcore, ethcore_set, traces, rpc, personal_safe.
|
parity, parity_set, traces, rpc, parity_accounts.
|
||||||
(default: {flag_jsonrpc_apis}).
|
(default: {flag_jsonrpc_apis}).
|
||||||
--jsonrpc-hosts HOSTS List of allowed Host header values. This option will
|
--jsonrpc-hosts HOSTS List of allowed Host header values. This option will
|
||||||
validate the Host header sent by the browser, it
|
validate the Host header sent by the browser, it
|
||||||
@ -284,7 +284,7 @@ Legacy Options:
|
|||||||
--geth Run in Geth-compatibility mode. Sets the IPC path
|
--geth Run in Geth-compatibility mode. Sets the IPC path
|
||||||
to be the same as Geth's. Overrides the --ipc-path
|
to be the same as Geth's. Overrides the --ipc-path
|
||||||
and --ipcpath options. Alters RPCs to reflect Geth
|
and --ipcpath options. Alters RPCs to reflect Geth
|
||||||
bugs.
|
bugs. Includes the personal_ RPC by default.
|
||||||
--testnet Geth-compatible testnet mode. Equivalent to --chain
|
--testnet Geth-compatible testnet mode. Equivalent to --chain
|
||||||
testnet --keys-path $HOME/parity/testnet-keys.
|
testnet --keys-path $HOME/parity/testnet-keys.
|
||||||
Overrides the --keys-path option.
|
Overrides the --keys-path option.
|
||||||
|
@ -509,7 +509,11 @@ impl Configuration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn rpc_apis(&self) -> String {
|
fn rpc_apis(&self) -> String {
|
||||||
self.args.flag_rpcapi.clone().unwrap_or(self.args.flag_jsonrpc_apis.clone())
|
let mut apis = self.args.flag_rpcapi.clone().unwrap_or(self.args.flag_jsonrpc_apis.clone());
|
||||||
|
if self.args.flag_geth {
|
||||||
|
apis.push_str(",personal");
|
||||||
|
}
|
||||||
|
apis
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rpc_cors(&self) -> Option<Vec<String>> {
|
fn rpc_cors(&self) -> Option<Vec<String>> {
|
||||||
@ -541,7 +545,13 @@ impl Configuration {
|
|||||||
let conf = IpcConfiguration {
|
let conf = IpcConfiguration {
|
||||||
enabled: !(self.args.flag_ipcdisable || self.args.flag_ipc_off || self.args.flag_no_ipc),
|
enabled: !(self.args.flag_ipcdisable || self.args.flag_ipc_off || self.args.flag_no_ipc),
|
||||||
socket_addr: self.ipc_path(),
|
socket_addr: self.ipc_path(),
|
||||||
apis: try!(self.args.flag_ipcapi.clone().unwrap_or(self.args.flag_ipc_apis.clone()).parse()),
|
apis: {
|
||||||
|
let mut apis = self.args.flag_ipcapi.clone().unwrap_or(self.args.flag_ipc_apis.clone());
|
||||||
|
if self.args.flag_geth {
|
||||||
|
apis.push_str("personal");
|
||||||
|
}
|
||||||
|
try!(apis.parse())
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(conf)
|
Ok(conf)
|
||||||
|
@ -31,15 +31,25 @@ pub use ethcore_rpc::SignerService;
|
|||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Eq, Hash)]
|
#[derive(Debug, PartialEq, Clone, Eq, Hash)]
|
||||||
pub enum Api {
|
pub enum Api {
|
||||||
|
/// Web3 (Safe)
|
||||||
Web3,
|
Web3,
|
||||||
|
/// Net (Safe)
|
||||||
Net,
|
Net,
|
||||||
|
/// Eth (Safe)
|
||||||
Eth,
|
Eth,
|
||||||
PersonalSafe,
|
/// Geth-compatible "personal" API (DEPRECATED; only used in `--geth` mode.)
|
||||||
PersonalAccounts,
|
Personal,
|
||||||
|
/// Signer - Confirm transactions in Signer (UNSAFE: Passwords, List of transactions)
|
||||||
Signer,
|
Signer,
|
||||||
Ethcore,
|
/// Parity - Custom extensions (Safe)
|
||||||
EthcoreSet,
|
Parity,
|
||||||
|
/// Parity Accounts extensions (UNSAFE: Passwords, Side Effects (new account))
|
||||||
|
ParityAccounts,
|
||||||
|
/// Parity - Set methods (UNSAFE: Side Effects affecting node operation)
|
||||||
|
ParitySet,
|
||||||
|
/// Traces (Safe)
|
||||||
Traces,
|
Traces,
|
||||||
|
/// Rpc (Safe)
|
||||||
Rpc,
|
Rpc,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,11 +63,11 @@ impl FromStr for Api {
|
|||||||
"web3" => Ok(Web3),
|
"web3" => Ok(Web3),
|
||||||
"net" => Ok(Net),
|
"net" => Ok(Net),
|
||||||
"eth" => Ok(Eth),
|
"eth" => Ok(Eth),
|
||||||
"personal" => Ok(PersonalAccounts),
|
"personal" => Ok(Personal),
|
||||||
"personal_safe" => Ok(PersonalSafe),
|
|
||||||
"signer" => Ok(Signer),
|
"signer" => Ok(Signer),
|
||||||
"ethcore" => Ok(Ethcore),
|
"parity" => Ok(Parity),
|
||||||
"ethcore_set" => Ok(EthcoreSet),
|
"parity_accounts" => Ok(ParityAccounts),
|
||||||
|
"parity_set" => Ok(ParitySet),
|
||||||
"traces" => Ok(Traces),
|
"traces" => Ok(Traces),
|
||||||
"rpc" => Ok(Rpc),
|
"rpc" => Ok(Rpc),
|
||||||
api => Err(format!("Unknown api: {}", api))
|
api => Err(format!("Unknown api: {}", api))
|
||||||
@ -119,11 +129,11 @@ fn to_modules(apis: &[Api]) -> BTreeMap<String, String> {
|
|||||||
Api::Web3 => ("web3", "1.0"),
|
Api::Web3 => ("web3", "1.0"),
|
||||||
Api::Net => ("net", "1.0"),
|
Api::Net => ("net", "1.0"),
|
||||||
Api::Eth => ("eth", "1.0"),
|
Api::Eth => ("eth", "1.0"),
|
||||||
Api::PersonalSafe => ("personal_safe", "1.0"),
|
Api::Personal => ("personal", "1.0"),
|
||||||
Api::PersonalAccounts => ("personal", "1.0"),
|
|
||||||
Api::Signer => ("signer", "1.0"),
|
Api::Signer => ("signer", "1.0"),
|
||||||
Api::Ethcore => ("ethcore", "1.0"),
|
Api::Parity => ("parity", "1.0"),
|
||||||
Api::EthcoreSet => ("ethcore_set", "1.0"),
|
Api::ParityAccounts => ("parity_accounts", "1.0"),
|
||||||
|
Api::ParitySet => ("parity_set", "1.0"),
|
||||||
Api::Traces => ("traces", "1.0"),
|
Api::Traces => ("traces", "1.0"),
|
||||||
Api::Rpc => ("rpc", "1.0"),
|
Api::Rpc => ("rpc", "1.0"),
|
||||||
};
|
};
|
||||||
@ -134,24 +144,37 @@ fn to_modules(apis: &[Api]) -> BTreeMap<String, String> {
|
|||||||
|
|
||||||
impl ApiSet {
|
impl ApiSet {
|
||||||
pub fn list_apis(&self) -> HashSet<Api> {
|
pub fn list_apis(&self) -> HashSet<Api> {
|
||||||
|
let mut safe_list = vec![Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Traces, Api::Rpc]
|
||||||
|
.into_iter().collect();
|
||||||
match *self {
|
match *self {
|
||||||
ApiSet::List(ref apis) => apis.clone(),
|
ApiSet::List(ref apis) => apis.clone(),
|
||||||
ApiSet::UnsafeContext => {
|
ApiSet::UnsafeContext => safe_list,
|
||||||
vec![Api::Web3, Api::Net, Api::Eth, Api::Ethcore, Api::Traces, Api::Rpc, Api::PersonalSafe]
|
|
||||||
.into_iter().collect()
|
|
||||||
},
|
|
||||||
ApiSet::IpcContext => {
|
ApiSet::IpcContext => {
|
||||||
vec![Api::Web3, Api::Net, Api::Eth, Api::Ethcore, Api::Traces, Api::Rpc, Api::PersonalAccounts, Api::PersonalSafe]
|
safe_list.insert(Api::ParityAccounts);
|
||||||
.into_iter().collect()
|
safe_list
|
||||||
},
|
},
|
||||||
ApiSet::SafeContext => {
|
ApiSet::SafeContext => {
|
||||||
vec![Api::Web3, Api::Net, Api::Eth, Api::PersonalAccounts, Api::PersonalSafe, Api::Signer, Api::Ethcore, Api::EthcoreSet, Api::Traces, Api::Rpc]
|
safe_list.insert(Api::ParityAccounts);
|
||||||
.into_iter().collect()
|
safe_list.insert(Api::ParitySet);
|
||||||
|
safe_list.insert(Api::Signer);
|
||||||
|
safe_list
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! add_signing_methods {
|
||||||
|
($namespace:ident, $server:expr, $deps:expr) => {
|
||||||
|
let server = &$server;
|
||||||
|
let deps = &$deps;
|
||||||
|
if deps.signer_service.is_enabled() {
|
||||||
|
server.add_delegate($namespace::to_delegate(SigningQueueClient::new(&deps.signer_service, &deps.client, &deps.miner, &deps.secret_store)))
|
||||||
|
} else {
|
||||||
|
server.add_delegate($namespace::to_delegate(SigningUnsafeClient::new(&deps.client, &deps.secret_store, &deps.miner)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn setup_rpc<T: Extendable>(server: T, deps: Arc<Dependencies>, apis: ApiSet) -> T {
|
pub fn setup_rpc<T: Extendable>(server: T, deps: Arc<Dependencies>, apis: ApiSet) -> T {
|
||||||
use ethcore_rpc::v1::*;
|
use ethcore_rpc::v1::*;
|
||||||
|
|
||||||
@ -183,39 +206,39 @@ pub fn setup_rpc<T: Extendable>(server: T, deps: Arc<Dependencies>, apis: ApiSet
|
|||||||
let filter_client = EthFilterClient::new(&deps.client, &deps.miner);
|
let filter_client = EthFilterClient::new(&deps.client, &deps.miner);
|
||||||
server.add_delegate(filter_client.to_delegate());
|
server.add_delegate(filter_client.to_delegate());
|
||||||
|
|
||||||
if deps.signer_service.is_enabled() {
|
add_signing_methods!(EthSigning, server, deps);
|
||||||
server.add_delegate(EthSigningQueueClient::new(&deps.signer_service, &deps.client, &deps.miner, &deps.secret_store).to_delegate());
|
|
||||||
} else {
|
|
||||||
server.add_delegate(EthSigningUnsafeClient::new(&deps.client, &deps.secret_store, &deps.miner).to_delegate());
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
Api::PersonalAccounts => {
|
Api::Personal => {
|
||||||
server.add_delegate(PersonalAccountsClient::new(&deps.secret_store, &deps.client, &deps.miner, deps.geth_compatibility).to_delegate());
|
server.add_delegate(PersonalClient::new(&deps.secret_store, &deps.client, &deps.miner, deps.geth_compatibility).to_delegate());
|
||||||
},
|
|
||||||
Api::PersonalSafe => {
|
|
||||||
server.add_delegate(PersonalClient::new(&deps.secret_store, &deps.client).to_delegate());
|
|
||||||
},
|
},
|
||||||
Api::Signer => {
|
Api::Signer => {
|
||||||
server.add_delegate(SignerClient::new(&deps.secret_store, &deps.client, &deps.miner, &deps.signer_service).to_delegate());
|
server.add_delegate(SignerClient::new(&deps.secret_store, &deps.client, &deps.miner, &deps.signer_service).to_delegate());
|
||||||
},
|
},
|
||||||
Api::Ethcore => {
|
Api::Parity => {
|
||||||
let signer = match deps.signer_service.is_enabled() {
|
let signer = match deps.signer_service.is_enabled() {
|
||||||
true => Some(deps.signer_service.clone()),
|
true => Some(deps.signer_service.clone()),
|
||||||
false => None,
|
false => None,
|
||||||
};
|
};
|
||||||
server.add_delegate(EthcoreClient::new(
|
server.add_delegate(ParityClient::new(
|
||||||
&deps.client,
|
&deps.client,
|
||||||
&deps.miner,
|
&deps.miner,
|
||||||
&deps.sync,
|
&deps.sync,
|
||||||
&deps.net_service,
|
&deps.net_service,
|
||||||
|
&deps.secret_store,
|
||||||
deps.logger.clone(),
|
deps.logger.clone(),
|
||||||
deps.settings.clone(),
|
deps.settings.clone(),
|
||||||
signer,
|
signer,
|
||||||
deps.dapps_port,
|
deps.dapps_port,
|
||||||
).to_delegate())
|
).to_delegate());
|
||||||
|
|
||||||
|
add_signing_methods!(EthSigning, server, deps);
|
||||||
|
add_signing_methods!(ParitySigning, server, deps);
|
||||||
},
|
},
|
||||||
Api::EthcoreSet => {
|
Api::ParityAccounts => {
|
||||||
server.add_delegate(EthcoreSetClient::new(&deps.client, &deps.miner, &deps.net_service).to_delegate())
|
server.add_delegate(ParityAccountsClient::new(&deps.secret_store, &deps.client).to_delegate());
|
||||||
|
},
|
||||||
|
Api::ParitySet => {
|
||||||
|
server.add_delegate(ParitySetClient::new(&deps.client, &deps.miner, &deps.net_service).to_delegate())
|
||||||
},
|
},
|
||||||
Api::Traces => {
|
Api::Traces => {
|
||||||
server.add_delegate(TracesClient::new(&deps.client, &deps.miner).to_delegate())
|
server.add_delegate(TracesClient::new(&deps.client, &deps.miner).to_delegate())
|
||||||
@ -238,11 +261,11 @@ mod test {
|
|||||||
assert_eq!(Api::Web3, "web3".parse().unwrap());
|
assert_eq!(Api::Web3, "web3".parse().unwrap());
|
||||||
assert_eq!(Api::Net, "net".parse().unwrap());
|
assert_eq!(Api::Net, "net".parse().unwrap());
|
||||||
assert_eq!(Api::Eth, "eth".parse().unwrap());
|
assert_eq!(Api::Eth, "eth".parse().unwrap());
|
||||||
assert_eq!(Api::PersonalAccounts, "personal".parse().unwrap());
|
assert_eq!(Api::Personal, "personal".parse().unwrap());
|
||||||
assert_eq!(Api::PersonalSafe, "personal_safe".parse().unwrap());
|
|
||||||
assert_eq!(Api::Signer, "signer".parse().unwrap());
|
assert_eq!(Api::Signer, "signer".parse().unwrap());
|
||||||
assert_eq!(Api::Ethcore, "ethcore".parse().unwrap());
|
assert_eq!(Api::Parity, "parity".parse().unwrap());
|
||||||
assert_eq!(Api::EthcoreSet, "ethcore_set".parse().unwrap());
|
assert_eq!(Api::ParityAccounts, "parity_accounts".parse().unwrap());
|
||||||
|
assert_eq!(Api::ParitySet, "parity_set".parse().unwrap());
|
||||||
assert_eq!(Api::Traces, "traces".parse().unwrap());
|
assert_eq!(Api::Traces, "traces".parse().unwrap());
|
||||||
assert_eq!(Api::Rpc, "rpc".parse().unwrap());
|
assert_eq!(Api::Rpc, "rpc".parse().unwrap());
|
||||||
assert!("rp".parse::<Api>().is_err());
|
assert!("rp".parse::<Api>().is_err());
|
||||||
@ -260,15 +283,34 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_api_set_unsafe_context() {
|
fn test_api_set_unsafe_context() {
|
||||||
let expected = vec![Api::Web3, Api::Net, Api::Eth, Api::Ethcore, Api::Traces, Api::Rpc, Api::PersonalSafe]
|
let expected = vec![
|
||||||
.into_iter().collect();
|
// make sure this list contains only SAFE methods
|
||||||
|
Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Traces, Api::Rpc
|
||||||
|
].into_iter().collect();
|
||||||
assert_eq!(ApiSet::UnsafeContext.list_apis(), expected);
|
assert_eq!(ApiSet::UnsafeContext.list_apis(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_api_set_ipc_context() {
|
||||||
|
let expected = vec![
|
||||||
|
// safe
|
||||||
|
Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Traces, Api::Rpc,
|
||||||
|
// semi-safe
|
||||||
|
Api::ParityAccounts
|
||||||
|
].into_iter().collect();
|
||||||
|
assert_eq!(ApiSet::IpcContext.list_apis(), expected);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_api_set_safe_context() {
|
fn test_api_set_safe_context() {
|
||||||
let expected = vec![Api::Web3, Api::Net, Api::Eth, Api::PersonalAccounts, Api::PersonalSafe, Api::Signer, Api::Ethcore, Api::EthcoreSet, Api::Traces, Api::Rpc]
|
let expected = vec![
|
||||||
.into_iter().collect();
|
// safe
|
||||||
|
Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Traces, Api::Rpc,
|
||||||
|
// semi-safe
|
||||||
|
Api::ParityAccounts,
|
||||||
|
// Unsafe
|
||||||
|
Api::ParitySet, Api::Signer,
|
||||||
|
].into_iter().collect();
|
||||||
assert_eq!(ApiSet::SafeContext.list_apis(), expected);
|
assert_eq!(ApiSet::SafeContext.list_apis(), expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,13 +27,14 @@ macro_rules! take_weak {
|
|||||||
|
|
||||||
mod eth;
|
mod eth;
|
||||||
mod eth_filter;
|
mod eth_filter;
|
||||||
mod eth_signing;
|
|
||||||
mod ethcore;
|
|
||||||
mod ethcore_set;
|
|
||||||
mod net;
|
mod net;
|
||||||
|
mod parity;
|
||||||
|
mod parity_accounts;
|
||||||
|
mod parity_set;
|
||||||
mod personal;
|
mod personal;
|
||||||
mod personal_accounts;
|
mod signer;
|
||||||
mod personal_signer;
|
mod signing;
|
||||||
|
mod signing_unsafe;
|
||||||
mod rpc;
|
mod rpc;
|
||||||
mod traces;
|
mod traces;
|
||||||
mod web3;
|
mod web3;
|
||||||
@ -41,12 +42,13 @@ mod web3;
|
|||||||
pub use self::web3::Web3Client;
|
pub use self::web3::Web3Client;
|
||||||
pub use self::eth::{EthClient, EthClientOptions};
|
pub use self::eth::{EthClient, EthClientOptions};
|
||||||
pub use self::eth_filter::EthFilterClient;
|
pub use self::eth_filter::EthFilterClient;
|
||||||
pub use self::eth_signing::{EthSigningUnsafeClient, EthSigningQueueClient};
|
|
||||||
pub use self::net::NetClient;
|
pub use self::net::NetClient;
|
||||||
|
pub use self::parity::ParityClient;
|
||||||
|
pub use self::parity_accounts::ParityAccountsClient;
|
||||||
|
pub use self::parity_set::ParitySetClient;
|
||||||
pub use self::personal::PersonalClient;
|
pub use self::personal::PersonalClient;
|
||||||
pub use self::personal_accounts::PersonalAccountsClient;
|
pub use self::signer::SignerClient;
|
||||||
pub use self::personal_signer::SignerClient;
|
pub use self::signing::SigningQueueClient;
|
||||||
pub use self::ethcore::EthcoreClient;
|
pub use self::signing_unsafe::SigningUnsafeClient;
|
||||||
pub use self::ethcore_set::EthcoreSetClient;
|
|
||||||
pub use self::traces::TracesClient;
|
pub use self::traces::TracesClient;
|
||||||
pub use self::rpc::RpcClient;
|
pub use self::rpc::RpcClient;
|
||||||
|
@ -14,16 +14,15 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//! Ethcore-specific rpc implementation.
|
//! Parity-specific rpc implementation.
|
||||||
use std::{fs, io};
|
use std::sync::{Arc, Weak};
|
||||||
use std::sync::{mpsc, Arc, Weak};
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use util::{RotatingLogger, Address, Mutex, sha3};
|
use util::{RotatingLogger, Address};
|
||||||
use util::misc::version_data;
|
use util::misc::version_data;
|
||||||
|
|
||||||
use crypto::ecies;
|
use crypto::ecies;
|
||||||
use fetch::{Client as FetchClient, Fetch};
|
|
||||||
use ethkey::{Brain, Generator};
|
use ethkey::{Brain, Generator};
|
||||||
use ethstore::random_phrase;
|
use ethstore::random_phrase;
|
||||||
use ethsync::{SyncProvider, ManageNetwork};
|
use ethsync::{SyncProvider, ManageNetwork};
|
||||||
@ -31,77 +30,57 @@ use ethcore::miner::MinerService;
|
|||||||
use ethcore::client::{MiningBlockChainClient};
|
use ethcore::client::{MiningBlockChainClient};
|
||||||
use ethcore::ids::BlockID;
|
use ethcore::ids::BlockID;
|
||||||
use ethcore::mode::Mode;
|
use ethcore::mode::Mode;
|
||||||
|
use ethcore::account_provider::AccountProvider;
|
||||||
|
|
||||||
use jsonrpc_core::Error;
|
use jsonrpc_core::Error;
|
||||||
use v1::traits::Ethcore;
|
use v1::traits::Parity;
|
||||||
use v1::types::{Bytes, U256, H160, H256, H512, Peers, Transaction, RpcSettings, Histogram};
|
use v1::types::{Bytes, U256, H160, H256, H512, Peers, Transaction, RpcSettings, Histogram};
|
||||||
use v1::helpers::{errors, SigningQueue, SignerService, NetworkSettings};
|
use v1::helpers::{errors, SigningQueue, SignerService, NetworkSettings};
|
||||||
use v1::helpers::dispatch::DEFAULT_MAC;
|
use v1::helpers::dispatch::DEFAULT_MAC;
|
||||||
use v1::helpers::auto_args::Ready;
|
|
||||||
|
|
||||||
/// Ethcore implementation.
|
/// Parity implementation.
|
||||||
pub struct EthcoreClient<C, M, S: ?Sized, F=FetchClient> where
|
pub struct ParityClient<C, M, S: ?Sized> where
|
||||||
C: MiningBlockChainClient,
|
C: MiningBlockChainClient,
|
||||||
M: MinerService,
|
M: MinerService,
|
||||||
S: SyncProvider,
|
S: SyncProvider,
|
||||||
F: Fetch {
|
{
|
||||||
|
|
||||||
client: Weak<C>,
|
client: Weak<C>,
|
||||||
miner: Weak<M>,
|
miner: Weak<M>,
|
||||||
sync: Weak<S>,
|
sync: Weak<S>,
|
||||||
net: Weak<ManageNetwork>,
|
net: Weak<ManageNetwork>,
|
||||||
|
accounts: Weak<AccountProvider>,
|
||||||
logger: Arc<RotatingLogger>,
|
logger: Arc<RotatingLogger>,
|
||||||
settings: Arc<NetworkSettings>,
|
settings: Arc<NetworkSettings>,
|
||||||
signer: Option<Arc<SignerService>>,
|
signer: Option<Arc<SignerService>>,
|
||||||
fetch: Mutex<F>,
|
|
||||||
dapps_port: Option<u16>,
|
dapps_port: Option<u16>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, M, S: ?Sized> EthcoreClient<C, M, S> where
|
impl<C, M, S: ?Sized> ParityClient<C, M, S> where
|
||||||
C: MiningBlockChainClient,
|
C: MiningBlockChainClient,
|
||||||
M: MinerService,
|
M: MinerService,
|
||||||
S: SyncProvider, {
|
S: SyncProvider,
|
||||||
/// Creates new `EthcoreClient` with default `Fetch`.
|
{
|
||||||
|
/// Creates new `ParityClient`.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
client: &Arc<C>,
|
client: &Arc<C>,
|
||||||
miner: &Arc<M>,
|
miner: &Arc<M>,
|
||||||
sync: &Arc<S>,
|
sync: &Arc<S>,
|
||||||
net: &Arc<ManageNetwork>,
|
net: &Arc<ManageNetwork>,
|
||||||
|
store: &Arc<AccountProvider>,
|
||||||
logger: Arc<RotatingLogger>,
|
logger: Arc<RotatingLogger>,
|
||||||
settings: Arc<NetworkSettings>,
|
settings: Arc<NetworkSettings>,
|
||||||
signer: Option<Arc<SignerService>>,
|
signer: Option<Arc<SignerService>>,
|
||||||
dapps_port: Option<u16>,
|
dapps_port: Option<u16>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::with_fetch(client, miner, sync, net, logger, settings, signer, dapps_port)
|
ParityClient {
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C, M, S: ?Sized, F> EthcoreClient<C, M, S, F> where
|
|
||||||
C: MiningBlockChainClient,
|
|
||||||
M: MinerService,
|
|
||||||
S: SyncProvider,
|
|
||||||
F: Fetch, {
|
|
||||||
|
|
||||||
/// Creates new `EthcoreClient` with customizable `Fetch`.
|
|
||||||
pub fn with_fetch(
|
|
||||||
client: &Arc<C>,
|
|
||||||
miner: &Arc<M>,
|
|
||||||
sync: &Arc<S>,
|
|
||||||
net: &Arc<ManageNetwork>,
|
|
||||||
logger: Arc<RotatingLogger>,
|
|
||||||
settings: Arc<NetworkSettings>,
|
|
||||||
signer: Option<Arc<SignerService>>,
|
|
||||||
dapps_port: Option<u16>,
|
|
||||||
) -> Self {
|
|
||||||
EthcoreClient {
|
|
||||||
client: Arc::downgrade(client),
|
client: Arc::downgrade(client),
|
||||||
miner: Arc::downgrade(miner),
|
miner: Arc::downgrade(miner),
|
||||||
sync: Arc::downgrade(sync),
|
sync: Arc::downgrade(sync),
|
||||||
net: Arc::downgrade(net),
|
net: Arc::downgrade(net),
|
||||||
|
accounts: Arc::downgrade(store),
|
||||||
logger: logger,
|
logger: logger,
|
||||||
settings: settings,
|
settings: settings,
|
||||||
signer: signer,
|
signer: signer,
|
||||||
fetch: Mutex::new(F::default()),
|
|
||||||
dapps_port: dapps_port,
|
dapps_port: dapps_port,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,11 +92,10 @@ impl<C, M, S: ?Sized, F> EthcoreClient<C, M, S, F> where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, M, S: ?Sized, F> Ethcore for EthcoreClient<C, M, S, F> where
|
impl<C, M, S: ?Sized> Parity for ParityClient<C, M, S> where
|
||||||
M: MinerService + 'static,
|
M: MinerService + 'static,
|
||||||
C: MiningBlockChainClient + 'static,
|
C: MiningBlockChainClient + 'static,
|
||||||
S: SyncProvider + 'static,
|
S: SyncProvider + 'static {
|
||||||
F: Fetch + 'static {
|
|
||||||
|
|
||||||
fn transactions_limit(&self) -> Result<usize, Error> {
|
fn transactions_limit(&self) -> Result<usize, Error> {
|
||||||
try!(self.active());
|
try!(self.active());
|
||||||
@ -278,48 +256,6 @@ impl<C, M, S: ?Sized, F> Ethcore for EthcoreClient<C, M, S, F> where
|
|||||||
Ok(take_weak!(self.miner).all_transactions().into_iter().map(Into::into).collect::<Vec<_>>())
|
Ok(take_weak!(self.miner).all_transactions().into_iter().map(Into::into).collect::<Vec<_>>())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hash_content(&self, ready: Ready<H256>, url: String) {
|
|
||||||
let res = self.active();
|
|
||||||
|
|
||||||
let hash_content = |result| {
|
|
||||||
let path = try!(result);
|
|
||||||
let mut file = io::BufReader::new(try!(fs::File::open(&path)));
|
|
||||||
// Try to hash
|
|
||||||
let result = sha3(&mut file);
|
|
||||||
// Remove file (always)
|
|
||||||
try!(fs::remove_file(&path));
|
|
||||||
// Return the result
|
|
||||||
Ok(try!(result))
|
|
||||||
};
|
|
||||||
|
|
||||||
match res {
|
|
||||||
Err(e) => ready.ready(Err(e)),
|
|
||||||
Ok(()) => {
|
|
||||||
let (tx, rx) = mpsc::channel();
|
|
||||||
let res = self.fetch.lock().request_async(&url, Default::default(), Box::new(move |result| {
|
|
||||||
let result = hash_content(result)
|
|
||||||
.map_err(errors::from_fetch_error)
|
|
||||||
.map(Into::into);
|
|
||||||
|
|
||||||
// Receive ready and invoke with result.
|
|
||||||
let ready: Ready<H256> = rx.recv().expect(
|
|
||||||
"recv() fails when `tx` has been dropped, if this closure is invoked `tx` is not dropped (`res == Ok()`); qed"
|
|
||||||
);
|
|
||||||
ready.ready(result);
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Either invoke ready right away or transfer it to the closure.
|
|
||||||
if let Err(e) = res {
|
|
||||||
ready.ready(Err(errors::from_fetch_error(e)));
|
|
||||||
} else {
|
|
||||||
tx.send(ready).expect(
|
|
||||||
"send() fails when `rx` end is dropped, if `res == Ok()`: `rx` is moved to the closure; qed"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn signer_port(&self) -> Result<u16, Error> {
|
fn signer_port(&self) -> Result<u16, Error> {
|
||||||
try!(self.active());
|
try!(self.active());
|
||||||
|
|
||||||
@ -361,4 +297,22 @@ impl<C, M, S: ?Sized, F> Ethcore for EthcoreClient<C, M, S, F> where
|
|||||||
fn enode(&self) -> Result<String, Error> {
|
fn enode(&self) -> Result<String, Error> {
|
||||||
take_weak!(self.sync).enode().ok_or_else(errors::network_disabled)
|
take_weak!(self.sync).enode().ok_or_else(errors::network_disabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn accounts(&self) -> Result<BTreeMap<String, BTreeMap<String, String>>, Error> {
|
||||||
|
try!(self.active());
|
||||||
|
let store = take_weak!(self.accounts);
|
||||||
|
let info = try!(store.accounts_info().map_err(|e| errors::account("Could not fetch account info.", e)));
|
||||||
|
let other = store.addresses_info().expect("addresses_info always returns Ok; qed");
|
||||||
|
|
||||||
|
Ok(info.into_iter().chain(other.into_iter()).map(|(a, v)| {
|
||||||
|
let mut m = map![
|
||||||
|
"name".to_owned() => v.name,
|
||||||
|
"meta".to_owned() => v.meta
|
||||||
|
];
|
||||||
|
if let &Some(ref uuid) = &v.uuid {
|
||||||
|
m.insert("uuid".to_owned(), format!("{}", uuid));
|
||||||
|
}
|
||||||
|
(format!("0x{}", a.hex()), m)
|
||||||
|
}).collect())
|
||||||
|
}
|
||||||
}
|
}
|
@ -16,33 +16,30 @@
|
|||||||
|
|
||||||
//! Account management (personal) rpc implementation
|
//! Account management (personal) rpc implementation
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
|
use std::collections::BTreeMap;
|
||||||
use util::{Address};
|
use util::{Address};
|
||||||
use jsonrpc_core::*;
|
|
||||||
use ethkey::{Brain, Generator};
|
use ethkey::{Brain, Generator};
|
||||||
use v1::traits::PersonalAccounts;
|
|
||||||
use v1::types::{H160 as RpcH160, H256 as RpcH256, TransactionRequest};
|
|
||||||
use v1::helpers::errors;
|
|
||||||
use v1::helpers::dispatch::sign_and_dispatch;
|
|
||||||
use ethcore::account_provider::AccountProvider;
|
use ethcore::account_provider::AccountProvider;
|
||||||
use ethcore::client::MiningBlockChainClient;
|
use ethcore::client::MiningBlockChainClient;
|
||||||
use ethcore::miner::MinerService;
|
|
||||||
|
use jsonrpc_core::{Value, Error, to_value};
|
||||||
|
use v1::traits::ParityAccounts;
|
||||||
|
use v1::types::{H160 as RpcH160, H256 as RpcH256};
|
||||||
|
use v1::helpers::errors;
|
||||||
|
|
||||||
/// Account management (personal) rpc implementation.
|
/// Account management (personal) rpc implementation.
|
||||||
pub struct PersonalAccountsClient<C, M> where C: MiningBlockChainClient, M: MinerService {
|
pub struct ParityAccountsClient<C> where C: MiningBlockChainClient {
|
||||||
accounts: Weak<AccountProvider>,
|
accounts: Weak<AccountProvider>,
|
||||||
client: Weak<C>,
|
client: Weak<C>,
|
||||||
miner: Weak<M>,
|
|
||||||
allow_perm_unlock: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, M> PersonalAccountsClient<C, M> where C: MiningBlockChainClient, M: MinerService {
|
impl<C> ParityAccountsClient<C> where C: MiningBlockChainClient {
|
||||||
/// Creates new PersonalClient
|
/// Creates new PersonalClient
|
||||||
pub fn new(store: &Arc<AccountProvider>, client: &Arc<C>, miner: &Arc<M>, allow_perm_unlock: bool) -> Self {
|
pub fn new(store: &Arc<AccountProvider>, client: &Arc<C>) -> Self {
|
||||||
PersonalAccountsClient {
|
ParityAccountsClient {
|
||||||
accounts: Arc::downgrade(store),
|
accounts: Arc::downgrade(store),
|
||||||
client: Arc::downgrade(client),
|
client: Arc::downgrade(client),
|
||||||
miner: Arc::downgrade(miner),
|
|
||||||
allow_perm_unlock: allow_perm_unlock,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,15 +50,25 @@ impl<C, M> PersonalAccountsClient<C, M> where C: MiningBlockChainClient, M: Mine
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: 'static, M: 'static> PersonalAccounts for PersonalAccountsClient<C, M> where C: MiningBlockChainClient, M: MinerService {
|
impl<C: 'static> ParityAccounts for ParityAccountsClient<C> where C: MiningBlockChainClient {
|
||||||
|
fn accounts_info(&self) -> Result<BTreeMap<String, Value>, Error> {
|
||||||
fn new_account(&self, pass: String) -> Result<RpcH160, Error> {
|
|
||||||
try!(self.active());
|
try!(self.active());
|
||||||
let store = take_weak!(self.accounts);
|
let store = take_weak!(self.accounts);
|
||||||
|
let info = try!(store.accounts_info().map_err(|e| errors::account("Could not fetch account info.", e)));
|
||||||
|
let other = store.addresses_info().expect("addresses_info always returns Ok; qed");
|
||||||
|
|
||||||
store.new_account(&pass)
|
Ok(info.into_iter().chain(other.into_iter()).map(|(a, v)| {
|
||||||
.map(Into::into)
|
let m = map![
|
||||||
.map_err(|e| errors::account("Could not create account.", e))
|
"name".to_owned() => to_value(&v.name),
|
||||||
|
"meta".to_owned() => to_value(&v.meta),
|
||||||
|
"uuid".to_owned() => if let &Some(ref uuid) = &v.uuid {
|
||||||
|
to_value(uuid)
|
||||||
|
} else {
|
||||||
|
Value::Null
|
||||||
|
}
|
||||||
|
];
|
||||||
|
(format!("0x{}", a.hex()), Value::Object(m))
|
||||||
|
}).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_account_from_phrase(&self, phrase: String, pass: String) -> Result<RpcH160, Error> {
|
fn new_account_from_phrase(&self, phrase: String, pass: String) -> Result<RpcH160, Error> {
|
||||||
@ -92,24 +99,6 @@ impl<C: 'static, M: 'static> PersonalAccounts for PersonalAccountsClient<C, M> w
|
|||||||
.map_err(|e| errors::account("Could not create account.", e))
|
.map_err(|e| errors::account("Could not create account.", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unlock_account(&self, account: RpcH160, account_pass: String, duration: Option<u64>) -> Result<bool, Error> {
|
|
||||||
try!(self.active());
|
|
||||||
let account: Address = account.into();
|
|
||||||
let store = take_weak!(self.accounts);
|
|
||||||
|
|
||||||
let r = match (self.allow_perm_unlock, duration) {
|
|
||||||
(false, _) => store.unlock_account_temporarily(account, account_pass),
|
|
||||||
(true, Some(0)) => store.unlock_account_permanently(account, account_pass),
|
|
||||||
(true, Some(d)) => store.unlock_account_timed(account, account_pass, d as u32 * 1000),
|
|
||||||
(true, None) => store.unlock_account_timed(account, account_pass, 300_000),
|
|
||||||
};
|
|
||||||
match r {
|
|
||||||
Ok(_) => Ok(true),
|
|
||||||
// TODO [ToDr] Proper error here?
|
|
||||||
Err(_) => Ok(false),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_password(&self, account: RpcH160, password: String) -> Result<bool, Error> {
|
fn test_password(&self, account: RpcH160, password: String) -> Result<bool, Error> {
|
||||||
try!(self.active());
|
try!(self.active());
|
||||||
let account: Address = account.into();
|
let account: Address = account.into();
|
||||||
@ -128,18 +117,6 @@ impl<C: 'static, M: 'static> PersonalAccounts for PersonalAccountsClient<C, M> w
|
|||||||
.map_err(|e| errors::account("Could not fetch account info.", e))
|
.map_err(|e| errors::account("Could not fetch account info.", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign_and_send_transaction(&self, request: TransactionRequest, password: String) -> Result<RpcH256, Error> {
|
|
||||||
try!(self.active());
|
|
||||||
|
|
||||||
sign_and_dispatch(
|
|
||||||
&*take_weak!(self.client),
|
|
||||||
&*take_weak!(self.miner),
|
|
||||||
&*take_weak!(self.accounts),
|
|
||||||
request.into(),
|
|
||||||
Some(password)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_account_name(&self, addr: RpcH160, name: String) -> Result<bool, Error> {
|
fn set_account_name(&self, addr: RpcH160, name: String) -> Result<bool, Error> {
|
||||||
try!(self.active());
|
try!(self.active());
|
||||||
let store = take_weak!(self.accounts);
|
let store = take_weak!(self.accounts);
|
||||||
@ -162,6 +139,10 @@ impl<C: 'static, M: 'static> PersonalAccounts for PersonalAccountsClient<C, M> w
|
|||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_account_visibility(&self, _address: RpcH160, _dapp: RpcH256, _visible: bool) -> Result<bool, Error> {
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
|
||||||
fn import_geth_accounts(&self, addresses: Vec<RpcH160>) -> Result<Vec<RpcH160>, Error> {
|
fn import_geth_accounts(&self, addresses: Vec<RpcH160>) -> Result<Vec<RpcH160>, Error> {
|
||||||
let store = take_weak!(self.accounts);
|
let store = take_weak!(self.accounts);
|
||||||
|
|
@ -14,36 +14,57 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
/// Ethcore-specific rpc interface for operations altering the settings.
|
/// Parity-specific rpc interface for operations altering the settings.
|
||||||
use std::sync::{Arc, Weak};
|
use std::{fs, io};
|
||||||
use jsonrpc_core::*;
|
use std::sync::{Arc, Weak, mpsc};
|
||||||
|
|
||||||
use ethcore::miner::MinerService;
|
use ethcore::miner::MinerService;
|
||||||
use ethcore::client::MiningBlockChainClient;
|
use ethcore::client::MiningBlockChainClient;
|
||||||
use ethcore::mode::Mode;
|
use ethcore::mode::Mode;
|
||||||
use ethsync::ManageNetwork;
|
use ethsync::ManageNetwork;
|
||||||
use v1::helpers::errors;
|
use fetch::{Client as FetchClient, Fetch};
|
||||||
use v1::traits::EthcoreSet;
|
use util::{Mutex, sha3};
|
||||||
use v1::types::{Bytes, H160, U256};
|
|
||||||
|
|
||||||
/// Ethcore-specific rpc interface for operations altering the settings.
|
use jsonrpc_core::Error;
|
||||||
pub struct EthcoreSetClient<C, M> where
|
use v1::helpers::auto_args::Ready;
|
||||||
|
use v1::helpers::errors;
|
||||||
|
use v1::traits::ParitySet;
|
||||||
|
use v1::types::{Bytes, H160, H256, U256};
|
||||||
|
|
||||||
|
/// Parity-specific rpc interface for operations altering the settings.
|
||||||
|
pub struct ParitySetClient<C, M, F=FetchClient> where
|
||||||
C: MiningBlockChainClient,
|
C: MiningBlockChainClient,
|
||||||
M: MinerService
|
M: MinerService,
|
||||||
|
F: Fetch,
|
||||||
{
|
{
|
||||||
client: Weak<C>,
|
client: Weak<C>,
|
||||||
miner: Weak<M>,
|
miner: Weak<M>,
|
||||||
net: Weak<ManageNetwork>,
|
net: Weak<ManageNetwork>,
|
||||||
|
fetch: Mutex<F>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, M> EthcoreSetClient<C, M> where
|
impl<C, M> ParitySetClient<C, M, FetchClient> where
|
||||||
C: MiningBlockChainClient,
|
C: MiningBlockChainClient,
|
||||||
M: MinerService {
|
M: MinerService
|
||||||
/// Creates new `EthcoreSetClient`.
|
{
|
||||||
|
/// Creates new `ParitySetClient` with default `FetchClient`.
|
||||||
pub fn new(client: &Arc<C>, miner: &Arc<M>, net: &Arc<ManageNetwork>) -> Self {
|
pub fn new(client: &Arc<C>, miner: &Arc<M>, net: &Arc<ManageNetwork>) -> Self {
|
||||||
EthcoreSetClient {
|
Self::with_fetch(client, miner, net)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C, M, F> ParitySetClient<C, M, F> where
|
||||||
|
C: MiningBlockChainClient,
|
||||||
|
M: MinerService,
|
||||||
|
F: Fetch,
|
||||||
|
{
|
||||||
|
/// Creates new `ParitySetClient` with default `FetchClient`.
|
||||||
|
pub fn with_fetch(client: &Arc<C>, miner: &Arc<M>, net: &Arc<ManageNetwork>) -> Self {
|
||||||
|
ParitySetClient {
|
||||||
client: Arc::downgrade(client),
|
client: Arc::downgrade(client),
|
||||||
miner: Arc::downgrade(miner),
|
miner: Arc::downgrade(miner),
|
||||||
net: Arc::downgrade(net),
|
net: Arc::downgrade(net),
|
||||||
|
fetch: Mutex::new(F::default()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,9 +75,11 @@ impl<C, M> EthcoreSetClient<C, M> where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, M> EthcoreSet for EthcoreSetClient<C, M> where
|
impl<C, M, F> ParitySet for ParitySetClient<C, M, F> where
|
||||||
C: MiningBlockChainClient + 'static,
|
C: MiningBlockChainClient + 'static,
|
||||||
M: MinerService + 'static {
|
M: MinerService + 'static,
|
||||||
|
F: Fetch + 'static,
|
||||||
|
{
|
||||||
|
|
||||||
fn set_min_gas_price(&self, gas_price: U256) -> Result<bool, Error> {
|
fn set_min_gas_price(&self, gas_price: U256) -> Result<bool, Error> {
|
||||||
try!(self.active());
|
try!(self.active());
|
||||||
@ -159,4 +182,46 @@ impl<C, M> EthcoreSet for EthcoreSetClient<C, M> where
|
|||||||
});
|
});
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn hash_content(&self, ready: Ready<H256>, url: String) {
|
||||||
|
let res = self.active();
|
||||||
|
|
||||||
|
let hash_content = |result| {
|
||||||
|
let path = try!(result);
|
||||||
|
let mut file = io::BufReader::new(try!(fs::File::open(&path)));
|
||||||
|
// Try to hash
|
||||||
|
let result = sha3(&mut file);
|
||||||
|
// Remove file (always)
|
||||||
|
try!(fs::remove_file(&path));
|
||||||
|
// Return the result
|
||||||
|
Ok(try!(result))
|
||||||
|
};
|
||||||
|
|
||||||
|
match res {
|
||||||
|
Err(e) => ready.ready(Err(e)),
|
||||||
|
Ok(()) => {
|
||||||
|
let (tx, rx) = mpsc::channel();
|
||||||
|
let res = self.fetch.lock().request_async(&url, Default::default(), Box::new(move |result| {
|
||||||
|
let result = hash_content(result)
|
||||||
|
.map_err(errors::from_fetch_error)
|
||||||
|
.map(Into::into);
|
||||||
|
|
||||||
|
// Receive ready and invoke with result.
|
||||||
|
let ready: Ready<H256> = rx.recv().expect(
|
||||||
|
"recv() fails when `tx` has been dropped, if this closure is invoked `tx` is not dropped (`res == Ok()`); qed"
|
||||||
|
);
|
||||||
|
ready.ready(result);
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Either invoke ready right away or transfer it to the closure.
|
||||||
|
if let Err(e) = res {
|
||||||
|
ready.ready(Err(errors::from_fetch_error(e)));
|
||||||
|
} else {
|
||||||
|
tx.send(ready).expect(
|
||||||
|
"send() fails when `rx` end is dropped, if `res == Ok()`: `rx` is moved to the closure; qed"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -16,26 +16,34 @@
|
|||||||
|
|
||||||
//! Account management (personal) rpc implementation
|
//! Account management (personal) rpc implementation
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use std::collections::{BTreeMap};
|
|
||||||
use jsonrpc_core::*;
|
|
||||||
use v1::traits::Personal;
|
|
||||||
use v1::types::{H160 as RpcH160};
|
|
||||||
use v1::helpers::errors;
|
|
||||||
use ethcore::account_provider::AccountProvider;
|
use ethcore::account_provider::AccountProvider;
|
||||||
use ethcore::client::MiningBlockChainClient;
|
use ethcore::client::MiningBlockChainClient;
|
||||||
|
use ethcore::miner::MinerService;
|
||||||
|
use util::Address;
|
||||||
|
|
||||||
|
use jsonrpc_core::Error;
|
||||||
|
use v1::traits::Personal;
|
||||||
|
use v1::types::{H160 as RpcH160, H256 as RpcH256, TransactionRequest};
|
||||||
|
use v1::helpers::errors;
|
||||||
|
use v1::helpers::dispatch::sign_and_dispatch;
|
||||||
|
|
||||||
/// Account management (personal) rpc implementation.
|
/// Account management (personal) rpc implementation.
|
||||||
pub struct PersonalClient<C> where C: MiningBlockChainClient {
|
pub struct PersonalClient<C, M> where C: MiningBlockChainClient, M: MinerService {
|
||||||
accounts: Weak<AccountProvider>,
|
accounts: Weak<AccountProvider>,
|
||||||
client: Weak<C>,
|
client: Weak<C>,
|
||||||
|
miner: Weak<M>,
|
||||||
|
allow_perm_unlock: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C> PersonalClient<C> where C: MiningBlockChainClient {
|
impl<C, M> PersonalClient<C, M> where C: MiningBlockChainClient, M: MinerService {
|
||||||
/// Creates new PersonalClient
|
/// Creates new PersonalClient
|
||||||
pub fn new(store: &Arc<AccountProvider>, client: &Arc<C>) -> Self {
|
pub fn new(store: &Arc<AccountProvider>, client: &Arc<C>, miner: &Arc<M>, allow_perm_unlock: bool) -> Self {
|
||||||
PersonalClient {
|
PersonalClient {
|
||||||
accounts: Arc::downgrade(store),
|
accounts: Arc::downgrade(store),
|
||||||
client: Arc::downgrade(client),
|
client: Arc::downgrade(client),
|
||||||
|
miner: Arc::downgrade(miner),
|
||||||
|
allow_perm_unlock: allow_perm_unlock,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,8 +54,7 @@ impl<C> PersonalClient<C> where C: MiningBlockChainClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: 'static> Personal for PersonalClient<C> where C: MiningBlockChainClient {
|
impl<C: 'static, M: 'static> Personal for PersonalClient<C, M> where C: MiningBlockChainClient, M: MinerService {
|
||||||
|
|
||||||
fn accounts(&self) -> Result<Vec<RpcH160>, Error> {
|
fn accounts(&self) -> Result<Vec<RpcH160>, Error> {
|
||||||
try!(self.active());
|
try!(self.active());
|
||||||
|
|
||||||
@ -56,23 +63,42 @@ impl<C: 'static> Personal for PersonalClient<C> where C: MiningBlockChainClient
|
|||||||
Ok(accounts.into_iter().map(Into::into).collect::<Vec<RpcH160>>())
|
Ok(accounts.into_iter().map(Into::into).collect::<Vec<RpcH160>>())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accounts_info(&self) -> Result<BTreeMap<String, Value>, Error> {
|
fn new_account(&self, pass: String) -> Result<RpcH160, Error> {
|
||||||
try!(self.active());
|
try!(self.active());
|
||||||
let store = take_weak!(self.accounts);
|
let store = take_weak!(self.accounts);
|
||||||
let info = try!(store.accounts_info().map_err(|e| errors::account("Could not fetch account info.", e)));
|
|
||||||
let other = store.addresses_info().expect("addresses_info always returns Ok; qed");
|
|
||||||
|
|
||||||
Ok(info.into_iter().chain(other.into_iter()).map(|(a, v)| {
|
store.new_account(&pass)
|
||||||
let m = map![
|
.map(Into::into)
|
||||||
"name".to_owned() => to_value(&v.name),
|
.map_err(|e| errors::account("Could not create account.", e))
|
||||||
"meta".to_owned() => to_value(&v.meta),
|
|
||||||
"uuid".to_owned() => if let &Some(ref uuid) = &v.uuid {
|
|
||||||
to_value(uuid)
|
|
||||||
} else {
|
|
||||||
Value::Null
|
|
||||||
}
|
}
|
||||||
];
|
|
||||||
(format!("0x{}", a.hex()), Value::Object(m))
|
fn unlock_account(&self, account: RpcH160, account_pass: String, duration: Option<u64>) -> Result<bool, Error> {
|
||||||
}).collect())
|
try!(self.active());
|
||||||
|
let account: Address = account.into();
|
||||||
|
let store = take_weak!(self.accounts);
|
||||||
|
|
||||||
|
let r = match (self.allow_perm_unlock, duration) {
|
||||||
|
(false, _) => store.unlock_account_temporarily(account, account_pass),
|
||||||
|
(true, Some(0)) => store.unlock_account_permanently(account, account_pass),
|
||||||
|
(true, Some(d)) => store.unlock_account_timed(account, account_pass, d as u32 * 1000),
|
||||||
|
(true, None) => store.unlock_account_timed(account, account_pass, 300_000),
|
||||||
|
};
|
||||||
|
match r {
|
||||||
|
Ok(_) => Ok(true),
|
||||||
|
// TODO [ToDr] Proper error here?
|
||||||
|
Err(_) => Ok(false),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sign_and_send_transaction(&self, request: TransactionRequest, password: String) -> Result<RpcH256, Error> {
|
||||||
|
try!(self.active());
|
||||||
|
|
||||||
|
sign_and_dispatch(
|
||||||
|
&*take_weak!(self.client),
|
||||||
|
&*take_weak!(self.miner),
|
||||||
|
&*take_weak!(self.accounts),
|
||||||
|
request.into(),
|
||||||
|
Some(password)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,14 +14,14 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//! Transactions Confirmations (personal) rpc implementation
|
//! Transactions Confirmations rpc implementation
|
||||||
|
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use jsonrpc_core::*;
|
use jsonrpc_core::*;
|
||||||
use ethcore::account_provider::AccountProvider;
|
use ethcore::account_provider::AccountProvider;
|
||||||
use ethcore::client::MiningBlockChainClient;
|
use ethcore::client::MiningBlockChainClient;
|
||||||
use ethcore::miner::MinerService;
|
use ethcore::miner::MinerService;
|
||||||
use v1::traits::PersonalSigner;
|
use v1::traits::Signer;
|
||||||
use v1::types::{TransactionModification, ConfirmationRequest, U256};
|
use v1::types::{TransactionModification, ConfirmationRequest, U256};
|
||||||
use v1::helpers::{errors, SignerService, SigningQueue, ConfirmationPayload};
|
use v1::helpers::{errors, SignerService, SigningQueue, ConfirmationPayload};
|
||||||
use v1::helpers::dispatch::{sign_and_dispatch, sign, decrypt};
|
use v1::helpers::dispatch::{sign_and_dispatch, sign, decrypt};
|
||||||
@ -58,7 +58,7 @@ impl<C: 'static, M: 'static> SignerClient<C, M> where C: MiningBlockChainClient,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: 'static, M: 'static> PersonalSigner for SignerClient<C, M> where C: MiningBlockChainClient, M: MinerService {
|
impl<C: 'static, M: 'static> Signer for SignerClient<C, M> where C: MiningBlockChainClient, M: MinerService {
|
||||||
|
|
||||||
fn requests_to_confirm(&self) -> Result<Vec<ConfirmationRequest>, Error> {
|
fn requests_to_confirm(&self) -> Result<Vec<ConfirmationRequest>, Error> {
|
||||||
try!(self.active());
|
try!(self.active());
|
@ -14,43 +14,22 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//! Eth Signing RPC implementation.
|
//! Signing RPC implementation.
|
||||||
|
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use jsonrpc_core::*;
|
|
||||||
|
use ethcore::account_provider::AccountProvider;
|
||||||
use ethcore::miner::MinerService;
|
use ethcore::miner::MinerService;
|
||||||
use ethcore::client::MiningBlockChainClient;
|
use ethcore::client::MiningBlockChainClient;
|
||||||
use util::{U256, Address, H256, Mutex};
|
|
||||||
use transient_hashmap::TransientHashMap;
|
use transient_hashmap::TransientHashMap;
|
||||||
use ethcore::account_provider::AccountProvider;
|
use util::{U256, Address, H256, Mutex};
|
||||||
|
|
||||||
|
use jsonrpc_core::*;
|
||||||
use v1::helpers::{errors, SigningQueue, ConfirmationPromise, ConfirmationResult, ConfirmationPayload, TransactionRequest as TRequest, FilledTransactionRequest as FilledRequest, SignerService};
|
use v1::helpers::{errors, SigningQueue, ConfirmationPromise, ConfirmationResult, ConfirmationPayload, TransactionRequest as TRequest, FilledTransactionRequest as FilledRequest, SignerService};
|
||||||
use v1::helpers::dispatch::{default_gas_price, sign_and_dispatch, sign, decrypt};
|
use v1::helpers::dispatch::{default_gas_price, sign_and_dispatch, sign, decrypt};
|
||||||
use v1::traits::EthSigning;
|
use v1::traits::{EthSigning, ParitySigning};
|
||||||
use v1::types::{TransactionRequest, H160 as RpcH160, H256 as RpcH256, U256 as RpcU256, Bytes as RpcBytes};
|
use v1::types::{TransactionRequest, H160 as RpcH160, H256 as RpcH256, U256 as RpcU256, Bytes as RpcBytes};
|
||||||
|
|
||||||
fn fill_optional_fields<C, M>(request: TRequest, client: &C, miner: &M) -> FilledRequest
|
|
||||||
where C: MiningBlockChainClient, M: MinerService {
|
|
||||||
FilledRequest {
|
|
||||||
from: request.from,
|
|
||||||
to: request.to,
|
|
||||||
nonce: request.nonce,
|
|
||||||
gas_price: request.gas_price.unwrap_or_else(|| default_gas_price(client, miner)),
|
|
||||||
gas: request.gas.unwrap_or_else(|| miner.sensible_gas_limit()),
|
|
||||||
value: request.value.unwrap_or_else(|| 0.into()),
|
|
||||||
data: request.data.unwrap_or_else(Vec::new),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implementation of functions that require signing when no trusted signer is used.
|
|
||||||
pub struct EthSigningQueueClient<C, M> where C: MiningBlockChainClient, M: MinerService {
|
|
||||||
signer: Weak<SignerService>,
|
|
||||||
accounts: Weak<AccountProvider>,
|
|
||||||
client: Weak<C>,
|
|
||||||
miner: Weak<M>,
|
|
||||||
|
|
||||||
pending: Mutex<TransientHashMap<U256, ConfirmationPromise>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
const MAX_PENDING_DURATION: u64 = 60 * 60;
|
const MAX_PENDING_DURATION: u64 = 60 * 60;
|
||||||
|
|
||||||
pub enum DispatchResult {
|
pub enum DispatchResult {
|
||||||
@ -58,10 +37,23 @@ pub enum DispatchResult {
|
|||||||
Value(Value),
|
Value(Value),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, M> EthSigningQueueClient<C, M> where C: MiningBlockChainClient, M: MinerService {
|
/// Implementation of functions that require signing when no trusted signer is used.
|
||||||
|
pub struct SigningQueueClient<C, M> where C: MiningBlockChainClient, M: MinerService {
|
||||||
|
signer: Weak<SignerService>,
|
||||||
|
accounts: Weak<AccountProvider>,
|
||||||
|
client: Weak<C>,
|
||||||
|
miner: Weak<M>,
|
||||||
|
|
||||||
|
pending: Mutex<TransientHashMap<U256, ConfirmationPromise>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C, M> SigningQueueClient<C, M> where
|
||||||
|
C: MiningBlockChainClient,
|
||||||
|
M: MinerService,
|
||||||
|
{
|
||||||
/// Creates a new signing queue client given shared signing queue.
|
/// Creates a new signing queue client given shared signing queue.
|
||||||
pub fn new(signer: &Arc<SignerService>, client: &Arc<C>, miner: &Arc<M>, accounts: &Arc<AccountProvider>) -> Self {
|
pub fn new(signer: &Arc<SignerService>, client: &Arc<C>, miner: &Arc<M>, accounts: &Arc<AccountProvider>) -> Self {
|
||||||
EthSigningQueueClient {
|
SigningQueueClient {
|
||||||
signer: Arc::downgrade(signer),
|
signer: Arc::downgrade(signer),
|
||||||
accounts: Arc::downgrade(accounts),
|
accounts: Arc::downgrade(accounts),
|
||||||
client: Arc::downgrade(client),
|
client: Arc::downgrade(client),
|
||||||
@ -132,10 +124,10 @@ impl<C, M> EthSigningQueueClient<C, M> where C: MiningBlockChainClient, M: Miner
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, M> EthSigning for EthSigningQueueClient<C, M>
|
impl<C: 'static, M: 'static> ParitySigning for SigningQueueClient<C, M> where
|
||||||
where C: MiningBlockChainClient + 'static, M: MinerService + 'static
|
C: MiningBlockChainClient,
|
||||||
|
M: MinerService,
|
||||||
{
|
{
|
||||||
|
|
||||||
fn post_sign(&self, params: Params) -> Result<Value, Error> {
|
fn post_sign(&self, params: Params) -> Result<Value, Error> {
|
||||||
try!(self.active());
|
try!(self.active());
|
||||||
self.dispatch_sign(params).map(|result| match result {
|
self.dispatch_sign(params).map(|result| match result {
|
||||||
@ -178,16 +170,6 @@ impl<C, M> EthSigning for EthSigningQueueClient<C, M>
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign(&self, params: Params, ready: Ready) {
|
|
||||||
let res = self.active().and_then(|_| self.dispatch_sign(params));
|
|
||||||
self.handle_dispatch(res, ready);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn send_transaction(&self, params: Params, ready: Ready) {
|
|
||||||
let res = self.active().and_then(|_| self.dispatch_transaction(params));
|
|
||||||
self.handle_dispatch(res, ready);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn decrypt_message(&self, params: Params, ready: Ready) {
|
fn decrypt_message(&self, params: Params, ready: Ready) {
|
||||||
let res = self.active()
|
let res = self.active()
|
||||||
.and_then(|_| from_params::<(RpcH160, RpcBytes)>(params))
|
.and_then(|_| from_params::<(RpcH160, RpcBytes)>(params))
|
||||||
@ -205,76 +187,30 @@ impl<C, M> EthSigning for EthSigningQueueClient<C, M>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implementation of functions that require signing when no trusted signer is used.
|
impl<C: 'static, M: 'static> EthSigning for SigningQueueClient<C, M> where
|
||||||
pub struct EthSigningUnsafeClient<C, M> where
|
|
||||||
C: MiningBlockChainClient,
|
C: MiningBlockChainClient,
|
||||||
M: MinerService {
|
M: MinerService,
|
||||||
client: Weak<C>,
|
{
|
||||||
accounts: Weak<AccountProvider>,
|
|
||||||
miner: Weak<M>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C, M> EthSigningUnsafeClient<C, M> where
|
|
||||||
C: MiningBlockChainClient,
|
|
||||||
M: MinerService {
|
|
||||||
|
|
||||||
/// Creates new EthClient.
|
|
||||||
pub fn new(client: &Arc<C>, accounts: &Arc<AccountProvider>, miner: &Arc<M>)
|
|
||||||
-> Self {
|
|
||||||
EthSigningUnsafeClient {
|
|
||||||
client: Arc::downgrade(client),
|
|
||||||
miner: Arc::downgrade(miner),
|
|
||||||
accounts: Arc::downgrade(accounts),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn active(&self) -> Result<(), Error> {
|
|
||||||
// TODO: only call every 30s at most.
|
|
||||||
take_weak!(self.client).keep_alive();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C, M> EthSigning for EthSigningUnsafeClient<C, M> where
|
|
||||||
C: MiningBlockChainClient + 'static,
|
|
||||||
M: MinerService + 'static {
|
|
||||||
|
|
||||||
fn sign(&self, params: Params, ready: Ready) {
|
fn sign(&self, params: Params, ready: Ready) {
|
||||||
ready.ready(self.active()
|
let res = self.active().and_then(|_| self.dispatch_sign(params));
|
||||||
.and_then(|_| from_params::<(RpcH160, RpcH256)>(params))
|
self.handle_dispatch(res, ready);
|
||||||
.and_then(|(address, msg)| {
|
|
||||||
sign(&*take_weak!(self.accounts), address.into(), None, msg.into())
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_transaction(&self, params: Params, ready: Ready) {
|
fn send_transaction(&self, params: Params, ready: Ready) {
|
||||||
ready.ready(self.active()
|
let res = self.active().and_then(|_| self.dispatch_transaction(params));
|
||||||
.and_then(|_| from_params::<(TransactionRequest, )>(params))
|
self.handle_dispatch(res, ready);
|
||||||
.and_then(|(request, )| {
|
}
|
||||||
sign_and_dispatch(&*take_weak!(self.client), &*take_weak!(self.miner), &*take_weak!(self.accounts), request.into(), None).map(to_value)
|
}
|
||||||
}))
|
|
||||||
}
|
fn fill_optional_fields<C, M>(request: TRequest, client: &C, miner: &M) -> FilledRequest
|
||||||
|
where C: MiningBlockChainClient, M: MinerService {
|
||||||
fn decrypt_message(&self, params: Params, ready: Ready) {
|
FilledRequest {
|
||||||
ready.ready(self.active()
|
from: request.from,
|
||||||
.and_then(|_| from_params::<(RpcH160, RpcBytes)>(params))
|
to: request.to,
|
||||||
.and_then(|(address, ciphertext)| {
|
nonce: request.nonce,
|
||||||
decrypt(&*take_weak!(self.accounts), address.into(), None, ciphertext.0)
|
gas_price: request.gas_price.unwrap_or_else(|| default_gas_price(client, miner)),
|
||||||
}))
|
gas: request.gas.unwrap_or_else(|| miner.sensible_gas_limit()),
|
||||||
}
|
value: request.value.unwrap_or_else(|| 0.into()),
|
||||||
|
data: request.data.unwrap_or_else(Vec::new),
|
||||||
fn post_sign(&self, _: Params) -> Result<Value, Error> {
|
|
||||||
// We don't support this in non-signer mode.
|
|
||||||
Err(errors::signer_disabled())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn post_transaction(&self, _: Params) -> Result<Value, Error> {
|
|
||||||
// We don't support this in non-signer mode.
|
|
||||||
Err(errors::signer_disabled())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_request(&self, _: Params) -> Result<Value, Error> {
|
|
||||||
// We don't support this in non-signer mode.
|
|
||||||
Err(errors::signer_disabled())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
110
rpc/src/v1/impls/signing_unsafe.rs
Normal file
110
rpc/src/v1/impls/signing_unsafe.rs
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
// 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/>.
|
||||||
|
|
||||||
|
//! Unsafe Signing RPC implementation.
|
||||||
|
|
||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use ethcore::account_provider::AccountProvider;
|
||||||
|
use ethcore::miner::MinerService;
|
||||||
|
use ethcore::client::MiningBlockChainClient;
|
||||||
|
|
||||||
|
use jsonrpc_core::*;
|
||||||
|
use v1::helpers::errors;
|
||||||
|
use v1::helpers::dispatch::{sign_and_dispatch, sign, decrypt};
|
||||||
|
use v1::traits::{EthSigning, ParitySigning};
|
||||||
|
use v1::types::{TransactionRequest, H160 as RpcH160, H256 as RpcH256, Bytes as RpcBytes};
|
||||||
|
|
||||||
|
/// Implementation of functions that require signing when no trusted signer is used.
|
||||||
|
pub struct SigningUnsafeClient<C, M> where
|
||||||
|
C: MiningBlockChainClient,
|
||||||
|
M: MinerService,
|
||||||
|
{
|
||||||
|
accounts: Weak<AccountProvider>,
|
||||||
|
client: Weak<C>,
|
||||||
|
miner: Weak<M>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C, M> SigningUnsafeClient<C, M> where
|
||||||
|
C: MiningBlockChainClient,
|
||||||
|
M: MinerService,
|
||||||
|
{
|
||||||
|
|
||||||
|
/// Creates new SigningUnsafeClient.
|
||||||
|
pub fn new(client: &Arc<C>, accounts: &Arc<AccountProvider>, miner: &Arc<M>)
|
||||||
|
-> Self {
|
||||||
|
SigningUnsafeClient {
|
||||||
|
client: Arc::downgrade(client),
|
||||||
|
miner: Arc::downgrade(miner),
|
||||||
|
accounts: Arc::downgrade(accounts),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn active(&self) -> Result<(), Error> {
|
||||||
|
// TODO: only call every 30s at most.
|
||||||
|
take_weak!(self.client).keep_alive();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: 'static, M: 'static> EthSigning for SigningUnsafeClient<C, M> where
|
||||||
|
C: MiningBlockChainClient,
|
||||||
|
M: MinerService,
|
||||||
|
{
|
||||||
|
fn sign(&self, params: Params, ready: Ready) {
|
||||||
|
ready.ready(self.active()
|
||||||
|
.and_then(|_| from_params::<(RpcH160, RpcH256)>(params))
|
||||||
|
.and_then(|(address, msg)| {
|
||||||
|
sign(&*take_weak!(self.accounts), address.into(), None, msg.into())
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_transaction(&self, params: Params, ready: Ready) {
|
||||||
|
ready.ready(self.active()
|
||||||
|
.and_then(|_| from_params::<(TransactionRequest, )>(params))
|
||||||
|
.and_then(|(request, )| {
|
||||||
|
sign_and_dispatch(&*take_weak!(self.client), &*take_weak!(self.miner), &*take_weak!(self.accounts), request.into(), None).map(to_value)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: 'static, M: 'static> ParitySigning for SigningUnsafeClient<C, M> where
|
||||||
|
C: MiningBlockChainClient,
|
||||||
|
M: MinerService,
|
||||||
|
{
|
||||||
|
fn decrypt_message(&self, params: Params, ready: Ready) {
|
||||||
|
ready.ready(self.active()
|
||||||
|
.and_then(|_| from_params::<(RpcH160, RpcBytes)>(params))
|
||||||
|
.and_then(|(address, ciphertext)| {
|
||||||
|
decrypt(&*take_weak!(self.accounts), address.into(), None, ciphertext.0)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn post_sign(&self, _: Params) -> Result<Value, Error> {
|
||||||
|
// We don't support this in non-signer mode.
|
||||||
|
Err(errors::signer_disabled())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn post_transaction(&self, _: Params) -> Result<Value, Error> {
|
||||||
|
// We don't support this in non-signer mode.
|
||||||
|
Err(errors::signer_disabled())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_request(&self, _: Params) -> Result<Value, Error> {
|
||||||
|
// We don't support this in non-signer mode.
|
||||||
|
Err(errors::signer_disabled())
|
||||||
|
}
|
||||||
|
}
|
@ -26,6 +26,6 @@ pub mod traits;
|
|||||||
pub mod tests;
|
pub mod tests;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
|
||||||
pub use self::traits::{Web3, Eth, EthFilter, EthSigning, Personal, PersonalAccounts, PersonalSigner, Net, Ethcore, EthcoreSet, Traces, Rpc};
|
pub use self::traits::{Web3, Eth, EthFilter, EthSigning, Net, Parity, ParityAccounts, ParitySet, ParitySigning, Signer, Personal, Traces, Rpc};
|
||||||
pub use self::impls::*;
|
pub use self::impls::*;
|
||||||
pub use self::helpers::{SigningQueue, SignerService, ConfirmationsQueue, NetworkSettings, block_import};
|
pub use self::helpers::{SigningQueue, SignerService, ConfirmationsQueue, NetworkSettings, block_import};
|
||||||
|
@ -33,7 +33,7 @@ use util::{U256, H256, Uint, Address};
|
|||||||
use jsonrpc_core::IoHandler;
|
use jsonrpc_core::IoHandler;
|
||||||
use ethjson::blockchain::BlockChain;
|
use ethjson::blockchain::BlockChain;
|
||||||
|
|
||||||
use v1::impls::{EthClient, EthSigningUnsafeClient};
|
use v1::impls::{EthClient, SigningUnsafeClient};
|
||||||
use v1::types::U256 as NU256;
|
use v1::types::U256 as NU256;
|
||||||
use v1::traits::eth::Eth;
|
use v1::traits::eth::Eth;
|
||||||
use v1::traits::eth_signing::EthSigning;
|
use v1::traits::eth_signing::EthSigning;
|
||||||
@ -140,7 +140,7 @@ impl EthTester {
|
|||||||
&external_miner,
|
&external_miner,
|
||||||
Default::default(),
|
Default::default(),
|
||||||
);
|
);
|
||||||
let eth_sign = EthSigningUnsafeClient::new(
|
let eth_sign = SigningUnsafeClient::new(
|
||||||
&client,
|
&client,
|
||||||
&account_provider,
|
&account_provider,
|
||||||
&miner_service
|
&miner_service
|
||||||
|
@ -27,7 +27,7 @@ use ethcore::receipt::LocalizedReceipt;
|
|||||||
use ethcore::transaction::{Transaction, Action};
|
use ethcore::transaction::{Transaction, Action};
|
||||||
use ethcore::miner::{ExternalMiner, MinerService};
|
use ethcore::miner::{ExternalMiner, MinerService};
|
||||||
use ethsync::SyncState;
|
use ethsync::SyncState;
|
||||||
use v1::{Eth, EthClient, EthClientOptions, EthFilter, EthFilterClient, EthSigning, EthSigningUnsafeClient};
|
use v1::{Eth, EthClient, EthClientOptions, EthFilter, EthFilterClient, EthSigning, SigningUnsafeClient};
|
||||||
use v1::tests::helpers::{TestSyncProvider, Config, TestMinerService, TestSnapshotService};
|
use v1::tests::helpers::{TestSyncProvider, Config, TestMinerService, TestSnapshotService};
|
||||||
use rustc_serialize::hex::ToHex;
|
use rustc_serialize::hex::ToHex;
|
||||||
use time::get_time;
|
use time::get_time;
|
||||||
@ -83,7 +83,7 @@ impl EthTester {
|
|||||||
let external_miner = Arc::new(ExternalMiner::new(hashrates.clone()));
|
let external_miner = Arc::new(ExternalMiner::new(hashrates.clone()));
|
||||||
let eth = EthClient::new(&client, &snapshot, &sync, &ap, &miner, &external_miner, options).to_delegate();
|
let eth = EthClient::new(&client, &snapshot, &sync, &ap, &miner, &external_miner, options).to_delegate();
|
||||||
let filter = EthFilterClient::new(&client, &miner).to_delegate();
|
let filter = EthFilterClient::new(&client, &miner).to_delegate();
|
||||||
let sign = EthSigningUnsafeClient::new(&client, &ap, &miner).to_delegate();
|
let sign = SigningUnsafeClient::new(&client, &ap, &miner).to_delegate();
|
||||||
let io = IoHandler::new();
|
let io = IoHandler::new();
|
||||||
io.add_delegate(eth);
|
io.add_delegate(eth);
|
||||||
io.add_delegate(sign);
|
io.add_delegate(sign);
|
||||||
|
@ -18,12 +18,13 @@
|
|||||||
//! method calls properly.
|
//! method calls properly.
|
||||||
|
|
||||||
mod eth;
|
mod eth;
|
||||||
mod eth_signing;
|
|
||||||
mod net;
|
mod net;
|
||||||
mod web3;
|
mod web3;
|
||||||
mod personal;
|
mod personal;
|
||||||
mod personal_signer;
|
mod parity;
|
||||||
mod ethcore;
|
mod parity_accounts;
|
||||||
mod ethcore_set;
|
mod parity_set;
|
||||||
mod rpc;
|
mod rpc;
|
||||||
|
mod signer;
|
||||||
|
mod signing;
|
||||||
mod manage_network;
|
mod manage_network;
|
||||||
|
@ -16,19 +16,19 @@
|
|||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use util::log::RotatingLogger;
|
use util::log::RotatingLogger;
|
||||||
use util::{Address};
|
use util::Address;
|
||||||
use ethsync::ManageNetwork;
|
use ethsync::ManageNetwork;
|
||||||
use ethcore::client::{TestBlockChainClient};
|
use ethcore::client::{TestBlockChainClient};
|
||||||
|
use ethcore::account_provider::AccountProvider;
|
||||||
use ethstore::ethkey::{Generator, Random};
|
use ethstore::ethkey::{Generator, Random};
|
||||||
|
|
||||||
use jsonrpc_core::IoHandler;
|
use jsonrpc_core::IoHandler;
|
||||||
use v1::{Ethcore, EthcoreClient};
|
use v1::{Parity, ParityClient};
|
||||||
use v1::helpers::{SignerService, NetworkSettings};
|
use v1::helpers::{SignerService, NetworkSettings};
|
||||||
use v1::tests::helpers::{TestSyncProvider, Config, TestMinerService, TestFetch};
|
use v1::tests::helpers::{TestSyncProvider, Config, TestMinerService};
|
||||||
use super::manage_network::TestManageNetwork;
|
use super::manage_network::TestManageNetwork;
|
||||||
|
|
||||||
|
pub type TestParityClient = ParityClient<TestBlockChainClient, TestMinerService, TestSyncProvider>;
|
||||||
pub type TestEthcoreClient = EthcoreClient<TestBlockChainClient, TestMinerService, TestSyncProvider, TestFetch>;
|
|
||||||
|
|
||||||
pub struct Dependencies {
|
pub struct Dependencies {
|
||||||
pub miner: Arc<TestMinerService>,
|
pub miner: Arc<TestMinerService>,
|
||||||
@ -37,6 +37,7 @@ pub struct Dependencies {
|
|||||||
pub logger: Arc<RotatingLogger>,
|
pub logger: Arc<RotatingLogger>,
|
||||||
pub settings: Arc<NetworkSettings>,
|
pub settings: Arc<NetworkSettings>,
|
||||||
pub network: Arc<ManageNetwork>,
|
pub network: Arc<ManageNetwork>,
|
||||||
|
pub accounts: Arc<AccountProvider>,
|
||||||
pub dapps_port: Option<u16>,
|
pub dapps_port: Option<u16>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,16 +60,18 @@ impl Dependencies {
|
|||||||
rpc_port: 8545,
|
rpc_port: 8545,
|
||||||
}),
|
}),
|
||||||
network: Arc::new(TestManageNetwork),
|
network: Arc::new(TestManageNetwork),
|
||||||
|
accounts: Arc::new(AccountProvider::transient_provider()),
|
||||||
dapps_port: Some(18080),
|
dapps_port: Some(18080),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn client(&self, signer: Option<Arc<SignerService>>) -> TestEthcoreClient {
|
pub fn client(&self, signer: Option<Arc<SignerService>>) -> TestParityClient {
|
||||||
EthcoreClient::with_fetch(
|
ParityClient::new(
|
||||||
&self.client,
|
&self.client,
|
||||||
&self.miner,
|
&self.miner,
|
||||||
&self.sync,
|
&self.sync,
|
||||||
&self.network,
|
&self.network,
|
||||||
|
&self.accounts,
|
||||||
self.logger.clone(),
|
self.logger.clone(),
|
||||||
self.settings.clone(),
|
self.settings.clone(),
|
||||||
signer,
|
signer,
|
||||||
@ -90,105 +93,105 @@ impl Dependencies {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_ethcore_extra_data() {
|
fn rpc_parity_extra_data() {
|
||||||
let deps = Dependencies::new();
|
let deps = Dependencies::new();
|
||||||
let io = deps.default_client();
|
let io = deps.default_client();
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_extraData", "params": [], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_extraData", "params": [], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":"0x01020304","id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":"0x01020304","id":1}"#;
|
||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_ethcore_default_extra_data() {
|
fn rpc_parity_default_extra_data() {
|
||||||
use util::misc;
|
use util::misc;
|
||||||
use util::ToPretty;
|
use util::ToPretty;
|
||||||
|
|
||||||
let deps = Dependencies::new();
|
let deps = Dependencies::new();
|
||||||
let io = deps.default_client();
|
let io = deps.default_client();
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_defaultExtraData", "params": [], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_defaultExtraData", "params": [], "id": 1}"#;
|
||||||
let response = format!(r#"{{"jsonrpc":"2.0","result":"0x{}","id":1}}"#, misc::version_data().to_hex());
|
let response = format!(r#"{{"jsonrpc":"2.0","result":"0x{}","id":1}}"#, misc::version_data().to_hex());
|
||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response));
|
assert_eq!(io.handle_request_sync(request), Some(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_ethcore_gas_floor_target() {
|
fn rpc_parity_gas_floor_target() {
|
||||||
let deps = Dependencies::new();
|
let deps = Dependencies::new();
|
||||||
let io = deps.default_client();
|
let io = deps.default_client();
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_gasFloorTarget", "params": [], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_gasFloorTarget", "params": [], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":"0x3039","id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":"0x3039","id":1}"#;
|
||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_ethcore_min_gas_price() {
|
fn rpc_parity_min_gas_price() {
|
||||||
let deps = Dependencies::new();
|
let deps = Dependencies::new();
|
||||||
let io = deps.default_client();
|
let io = deps.default_client();
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_minGasPrice", "params": [], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_minGasPrice", "params": [], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":"0x1312d00","id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":"0x1312d00","id":1}"#;
|
||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_ethcore_dev_logs() {
|
fn rpc_parity_dev_logs() {
|
||||||
let deps = Dependencies::new();
|
let deps = Dependencies::new();
|
||||||
deps.logger.append("a".to_owned());
|
deps.logger.append("a".to_owned());
|
||||||
deps.logger.append("b".to_owned());
|
deps.logger.append("b".to_owned());
|
||||||
|
|
||||||
let io = deps.default_client();
|
let io = deps.default_client();
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_devLogs", "params":[], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_devLogs", "params":[], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":["b","a"],"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":["b","a"],"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_ethcore_dev_logs_levels() {
|
fn rpc_parity_dev_logs_levels() {
|
||||||
let deps = Dependencies::new();
|
let deps = Dependencies::new();
|
||||||
let io = deps.default_client();
|
let io = deps.default_client();
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_devLogsLevels", "params":[], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_devLogsLevels", "params":[], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":"rpc=trace","id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":"rpc=trace","id":1}"#;
|
||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_ethcore_transactions_limit() {
|
fn rpc_parity_transactions_limit() {
|
||||||
let deps = Dependencies::new();
|
let deps = Dependencies::new();
|
||||||
let io = deps.default_client();
|
let io = deps.default_client();
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_transactionsLimit", "params":[], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_transactionsLimit", "params":[], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":1024,"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":1024,"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_ethcore_net_chain() {
|
fn rpc_parity_net_chain() {
|
||||||
let deps = Dependencies::new();
|
let deps = Dependencies::new();
|
||||||
let io = deps.default_client();
|
let io = deps.default_client();
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_netChain", "params":[], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_netChain", "params":[], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":"testchain","id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":"testchain","id":1}"#;
|
||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_ethcore_net_peers() {
|
fn rpc_parity_net_peers() {
|
||||||
let deps = Dependencies::new();
|
let deps = Dependencies::new();
|
||||||
let io = deps.default_client();
|
let io = deps.default_client();
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_netPeers", "params":[], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_netPeers", "params":[], "id": 1}"#;
|
||||||
let response = "{\"jsonrpc\":\"2.0\",\"result\":{\"active\":0,\"connected\":120,\"max\":50,\"peers\":[{\"caps\":[\"eth/62\",\"eth/63\"],\
|
let response = "{\"jsonrpc\":\"2.0\",\"result\":{\"active\":0,\"connected\":120,\"max\":50,\"peers\":[{\"caps\":[\"eth/62\",\"eth/63\"],\
|
||||||
\"id\":\"node1\",\"name\":\"Parity/1\",\"network\":{\"localAddress\":\"127.0.0.1:8888\",\"remoteAddress\":\"127.0.0.1:7777\"}\
|
\"id\":\"node1\",\"name\":\"Parity/1\",\"network\":{\"localAddress\":\"127.0.0.1:8888\",\"remoteAddress\":\"127.0.0.1:7777\"}\
|
||||||
,\"protocols\":{\"eth\":{\"difficulty\":\"0x28\",\"head\":\"0000000000000000000000000000000000000000000000000000000000000032\"\
|
,\"protocols\":{\"eth\":{\"difficulty\":\"0x28\",\"head\":\"0000000000000000000000000000000000000000000000000000000000000032\"\
|
||||||
@ -200,101 +203,90 @@ fn rpc_ethcore_net_peers() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_ethcore_net_port() {
|
fn rpc_parity_net_port() {
|
||||||
let deps = Dependencies::new();
|
let deps = Dependencies::new();
|
||||||
let io = deps.default_client();
|
let io = deps.default_client();
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_netPort", "params":[], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_netPort", "params":[], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":30303,"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":30303,"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_ethcore_rpc_settings() {
|
fn rpc_parity_rpc_settings() {
|
||||||
let deps = Dependencies::new();
|
let deps = Dependencies::new();
|
||||||
let io = deps.default_client();
|
let io = deps.default_client();
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_rpcSettings", "params":[], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_rpcSettings", "params":[], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":{"enabled":true,"interface":"all","port":8545},"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":{"enabled":true,"interface":"all","port":8545},"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_ethcore_node_name() {
|
fn rpc_parity_node_name() {
|
||||||
let deps = Dependencies::new();
|
let deps = Dependencies::new();
|
||||||
let io = deps.default_client();
|
let io = deps.default_client();
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_nodeName", "params":[], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_nodeName", "params":[], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":"mynode","id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":"mynode","id":1}"#;
|
||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_ethcore_unsigned_transactions_count() {
|
fn rpc_parity_unsigned_transactions_count() {
|
||||||
let deps = Dependencies::new();
|
let deps = Dependencies::new();
|
||||||
let io = deps.with_signer(SignerService::new_test(Some(18180)));
|
let io = deps.with_signer(SignerService::new_test(Some(18180)));
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_unsignedTransactionsCount", "params":[], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_unsignedTransactionsCount", "params":[], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":0,"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":0,"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_ethcore_unsigned_transactions_count_when_signer_disabled() {
|
fn rpc_parity_unsigned_transactions_count_when_signer_disabled() {
|
||||||
let deps = Dependencies::new();
|
let deps = Dependencies::new();
|
||||||
let io = deps.default_client();
|
let io = deps.default_client();
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_unsignedTransactionsCount", "params":[], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_unsignedTransactionsCount", "params":[], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","error":{"code":-32030,"message":"Trusted Signer is disabled. This API is not available.","data":null},"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","error":{"code":-32030,"message":"Trusted Signer is disabled. This API is not available.","data":null},"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_ethcore_hash_content() {
|
fn rpc_parity_pending_transactions() {
|
||||||
let deps = Dependencies::new();
|
let deps = Dependencies::new();
|
||||||
let io = deps.default_client();
|
let io = deps.default_client();
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_hashContent", "params":["https://ethcore.io/assets/images/ethcore-black-horizontal.png"], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_pendingTransactions", "params":[], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":"0x2be00befcf008bc0e7d9cdefc194db9c75352e8632f48498b5a6bfce9f02c88e","id":1}"#;
|
|
||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn rpc_ethcore_pending_transactions() {
|
|
||||||
let deps = Dependencies::new();
|
|
||||||
let io = deps.default_client();
|
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_pendingTransactions", "params":[], "id": 1}"#;
|
|
||||||
let response = r#"{"jsonrpc":"2.0","result":[],"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":[],"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_ethcore_encrypt() {
|
fn rpc_parity_encrypt() {
|
||||||
let deps = Dependencies::new();
|
let deps = Dependencies::new();
|
||||||
let io = deps.default_client();
|
let io = deps.default_client();
|
||||||
let key = format!("{:?}", Random.generate().unwrap().public());
|
let key = format!("{:?}", Random.generate().unwrap().public());
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_encryptMessage", "params":["0x"#.to_owned() + &key + r#"", "0x01"], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_encryptMessage", "params":["0x"#.to_owned() + &key + r#"", "0x01"], "id": 1}"#;
|
||||||
assert!(io.handle_request_sync(&request).unwrap().contains("result"), "Should return success.");
|
assert!(io.handle_request_sync(&request).unwrap().contains("result"), "Should return success.");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_ethcore_signer_port() {
|
fn rpc_parity_signer_port() {
|
||||||
// given
|
// given
|
||||||
let deps = Dependencies::new();
|
let deps = Dependencies::new();
|
||||||
let io1 = deps.with_signer(SignerService::new_test(Some(18180)));
|
let io1 = deps.with_signer(SignerService::new_test(Some(18180)));
|
||||||
let io2 = deps.default_client();
|
let io2 = deps.default_client();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_signerPort", "params": [], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_signerPort", "params": [], "id": 1}"#;
|
||||||
let response1 = r#"{"jsonrpc":"2.0","result":18180,"id":1}"#;
|
let response1 = r#"{"jsonrpc":"2.0","result":18180,"id":1}"#;
|
||||||
let response2 = r#"{"jsonrpc":"2.0","error":{"code":-32030,"message":"Trusted Signer is disabled. This API is not available.","data":null},"id":1}"#;
|
let response2 = r#"{"jsonrpc":"2.0","error":{"code":-32030,"message":"Trusted Signer is disabled. This API is not available.","data":null},"id":1}"#;
|
||||||
|
|
||||||
@ -304,7 +296,7 @@ fn rpc_ethcore_signer_port() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_ethcore_dapps_port() {
|
fn rpc_parity_dapps_port() {
|
||||||
// given
|
// given
|
||||||
let mut deps = Dependencies::new();
|
let mut deps = Dependencies::new();
|
||||||
let io1 = deps.default_client();
|
let io1 = deps.default_client();
|
||||||
@ -312,7 +304,7 @@ fn rpc_ethcore_dapps_port() {
|
|||||||
let io2 = deps.default_client();
|
let io2 = deps.default_client();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_dappsPort", "params": [], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_dappsPort", "params": [], "id": 1}"#;
|
||||||
let response1 = r#"{"jsonrpc":"2.0","result":18080,"id":1}"#;
|
let response1 = r#"{"jsonrpc":"2.0","result":18080,"id":1}"#;
|
||||||
let response2 = r#"{"jsonrpc":"2.0","error":{"code":-32031,"message":"Dapps Server is disabled. This API is not available.","data":null},"id":1}"#;
|
let response2 = r#"{"jsonrpc":"2.0","error":{"code":-32031,"message":"Dapps Server is disabled. This API is not available.","data":null},"id":1}"#;
|
||||||
|
|
||||||
@ -322,7 +314,7 @@ fn rpc_ethcore_dapps_port() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_ethcore_next_nonce() {
|
fn rpc_parity_next_nonce() {
|
||||||
let deps = Dependencies::new();
|
let deps = Dependencies::new();
|
||||||
let address = Address::default();
|
let address = Address::default();
|
||||||
let io1 = deps.default_client();
|
let io1 = deps.default_client();
|
||||||
@ -332,7 +324,7 @@ fn rpc_ethcore_next_nonce() {
|
|||||||
|
|
||||||
let request = r#"{
|
let request = r#"{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"method": "ethcore_nextNonce",
|
"method": "parity_nextNonce",
|
||||||
"params": [""#.to_owned() + &format!("0x{:?}", address) + r#""],
|
"params": [""#.to_owned() + &format!("0x{:?}", address) + r#""],
|
||||||
"id": 1
|
"id": 1
|
||||||
}"#;
|
}"#;
|
118
rpc/src/v1/tests/mocked/parity_accounts.rs
Normal file
118
rpc/src/v1/tests/mocked/parity_accounts.rs
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
// 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/>.
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use ethcore::account_provider::AccountProvider;
|
||||||
|
use ethcore::client::TestBlockChainClient;
|
||||||
|
|
||||||
|
use jsonrpc_core::IoHandler;
|
||||||
|
use v1::{ParityAccounts, ParityAccountsClient};
|
||||||
|
|
||||||
|
struct ParityAccountsTester {
|
||||||
|
accounts: Arc<AccountProvider>,
|
||||||
|
io: IoHandler,
|
||||||
|
// these unused fields are necessary to keep the data alive
|
||||||
|
// as the handler has only weak pointers.
|
||||||
|
_client: Arc<TestBlockChainClient>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn blockchain_client() -> Arc<TestBlockChainClient> {
|
||||||
|
let client = TestBlockChainClient::new();
|
||||||
|
Arc::new(client)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn accounts_provider() -> Arc<AccountProvider> {
|
||||||
|
Arc::new(AccountProvider::transient_provider())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup() -> ParityAccountsTester {
|
||||||
|
let accounts = accounts_provider();
|
||||||
|
let client = blockchain_client();
|
||||||
|
let parity_accounts = ParityAccountsClient::new(&accounts, &client);
|
||||||
|
|
||||||
|
let io = IoHandler::new();
|
||||||
|
io.add_delegate(parity_accounts.to_delegate());
|
||||||
|
|
||||||
|
let tester = ParityAccountsTester {
|
||||||
|
accounts: accounts,
|
||||||
|
io: io,
|
||||||
|
_client: client,
|
||||||
|
};
|
||||||
|
|
||||||
|
tester
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_be_able_to_get_account_info() {
|
||||||
|
let tester = setup();
|
||||||
|
tester.accounts.new_account("").unwrap();
|
||||||
|
let accounts = tester.accounts.accounts().unwrap();
|
||||||
|
assert_eq!(accounts.len(), 1);
|
||||||
|
let address = accounts[0];
|
||||||
|
|
||||||
|
let uuid = tester.accounts.accounts_info().unwrap().get(&address).unwrap().uuid.as_ref().unwrap().clone();
|
||||||
|
tester.accounts.set_account_name(address.clone(), "Test".to_owned()).unwrap();
|
||||||
|
tester.accounts.set_account_meta(address.clone(), "{foo: 69}".to_owned()).unwrap();
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_accountsInfo", "params": [], "id": 1}"#;
|
||||||
|
let res = tester.io.handle_request_sync(request);
|
||||||
|
let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":{{\"0x{}\":{{\"meta\":\"{{foo: 69}}\",\"name\":\"Test\",\"uuid\":\"{}\"}}}},\"id\":1}}", address.hex(), uuid);
|
||||||
|
assert_eq!(res, Some(response));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_be_able_to_set_name() {
|
||||||
|
let tester = setup();
|
||||||
|
tester.accounts.new_account("").unwrap();
|
||||||
|
let accounts = tester.accounts.accounts().unwrap();
|
||||||
|
assert_eq!(accounts.len(), 1);
|
||||||
|
let address = accounts[0];
|
||||||
|
|
||||||
|
let request = format!(r#"{{"jsonrpc": "2.0", "method": "parity_setAccountName", "params": ["0x{}", "Test"], "id": 1}}"#, address.hex());
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
|
let res = tester.io.handle_request_sync(&request);
|
||||||
|
assert_eq!(res, Some(response.into()));
|
||||||
|
|
||||||
|
let uuid = tester.accounts.accounts_info().unwrap().get(&address).unwrap().uuid.as_ref().unwrap().clone();
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_accountsInfo", "params": [], "id": 1}"#;
|
||||||
|
let res = tester.io.handle_request_sync(request);
|
||||||
|
let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":{{\"0x{}\":{{\"meta\":\"{{}}\",\"name\":\"Test\",\"uuid\":\"{}\"}}}},\"id\":1}}", address.hex(), uuid);
|
||||||
|
assert_eq!(res, Some(response));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_be_able_to_set_meta() {
|
||||||
|
let tester = setup();
|
||||||
|
tester.accounts.new_account("").unwrap();
|
||||||
|
let accounts = tester.accounts.accounts().unwrap();
|
||||||
|
assert_eq!(accounts.len(), 1);
|
||||||
|
let address = accounts[0];
|
||||||
|
|
||||||
|
let request = format!(r#"{{"jsonrpc": "2.0", "method": "parity_setAccountMeta", "params": ["0x{}", "{{foo: 69}}"], "id": 1}}"#, address.hex());
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
|
let res = tester.io.handle_request_sync(&request);
|
||||||
|
assert_eq!(res, Some(response.into()));
|
||||||
|
|
||||||
|
let uuid = tester.accounts.accounts_info().unwrap().get(&address).unwrap().uuid.as_ref().unwrap().clone();
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_accountsInfo", "params": [], "id": 1}"#;
|
||||||
|
let res = tester.io.handle_request_sync(request);
|
||||||
|
let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":{{\"0x{}\":{{\"meta\":\"{{foo: 69}}\",\"name\":\"{}\",\"uuid\":\"{}\"}}}},\"id\":1}}", address.hex(), uuid, uuid);
|
||||||
|
assert_eq!(res, Some(response));
|
||||||
|
}
|
||||||
|
|
@ -16,16 +16,18 @@
|
|||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use jsonrpc_core::IoHandler;
|
use rustc_serialize::hex::FromHex;
|
||||||
use v1::{EthcoreSet, EthcoreSetClient};
|
use util::{U256, Address};
|
||||||
|
|
||||||
use ethcore::miner::MinerService;
|
use ethcore::miner::MinerService;
|
||||||
use ethcore::client::TestBlockChainClient;
|
use ethcore::client::TestBlockChainClient;
|
||||||
use v1::tests::helpers::TestMinerService;
|
|
||||||
use util::{U256, Address};
|
|
||||||
use rustc_serialize::hex::FromHex;
|
|
||||||
use super::manage_network::TestManageNetwork;
|
|
||||||
use ethsync::ManageNetwork;
|
use ethsync::ManageNetwork;
|
||||||
|
|
||||||
|
use jsonrpc_core::IoHandler;
|
||||||
|
use v1::{ParitySet, ParitySetClient};
|
||||||
|
use v1::tests::helpers::{TestMinerService, TestFetch};
|
||||||
|
use super::manage_network::TestManageNetwork;
|
||||||
|
|
||||||
fn miner_service() -> Arc<TestMinerService> {
|
fn miner_service() -> Arc<TestMinerService> {
|
||||||
Arc::new(TestMinerService::default())
|
Arc::new(TestMinerService::default())
|
||||||
}
|
}
|
||||||
@ -38,19 +40,21 @@ fn network_service() -> Arc<TestManageNetwork> {
|
|||||||
Arc::new(TestManageNetwork)
|
Arc::new(TestManageNetwork)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ethcore_set_client(client: &Arc<TestBlockChainClient>, miner: &Arc<TestMinerService>, net: &Arc<TestManageNetwork>) -> EthcoreSetClient<TestBlockChainClient, TestMinerService> {
|
pub type TestParitySetClient = ParitySetClient<TestBlockChainClient, TestMinerService, TestFetch>;
|
||||||
EthcoreSetClient::new(client, miner, &(net.clone() as Arc<ManageNetwork>))
|
|
||||||
|
fn parity_set_client(client: &Arc<TestBlockChainClient>, miner: &Arc<TestMinerService>, net: &Arc<TestManageNetwork>) -> TestParitySetClient {
|
||||||
|
ParitySetClient::with_fetch(client, miner, &(net.clone() as Arc<ManageNetwork>))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_ethcore_set_min_gas_price() {
|
fn rpc_parity_set_min_gas_price() {
|
||||||
let miner = miner_service();
|
let miner = miner_service();
|
||||||
let client = client_service();
|
let client = client_service();
|
||||||
let network = network_service();
|
let network = network_service();
|
||||||
let io = IoHandler::new();
|
let io = IoHandler::new();
|
||||||
io.add_delegate(ethcore_set_client(&client, &miner, &network).to_delegate());
|
io.add_delegate(parity_set_client(&client, &miner, &network).to_delegate());
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setMinGasPrice", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_setMinGasPrice", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
@ -58,14 +62,14 @@ fn rpc_ethcore_set_min_gas_price() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_ethcore_set_gas_floor_target() {
|
fn rpc_parity_set_gas_floor_target() {
|
||||||
let miner = miner_service();
|
let miner = miner_service();
|
||||||
let client = client_service();
|
let client = client_service();
|
||||||
let network = network_service();
|
let network = network_service();
|
||||||
let io = IoHandler::new();
|
let io = IoHandler::new();
|
||||||
io.add_delegate(ethcore_set_client(&client, &miner, &network).to_delegate());
|
io.add_delegate(parity_set_client(&client, &miner, &network).to_delegate());
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setGasFloorTarget", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_setGasFloorTarget", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
@ -73,14 +77,14 @@ fn rpc_ethcore_set_gas_floor_target() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_ethcore_set_extra_data() {
|
fn rpc_parity_set_extra_data() {
|
||||||
let miner = miner_service();
|
let miner = miner_service();
|
||||||
let client = client_service();
|
let client = client_service();
|
||||||
let network = network_service();
|
let network = network_service();
|
||||||
let io = IoHandler::new();
|
let io = IoHandler::new();
|
||||||
io.add_delegate(ethcore_set_client(&client, &miner, &network).to_delegate());
|
io.add_delegate(parity_set_client(&client, &miner, &network).to_delegate());
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setExtraData", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_setExtraData", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
@ -88,14 +92,14 @@ fn rpc_ethcore_set_extra_data() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_ethcore_set_author() {
|
fn rpc_parity_set_author() {
|
||||||
let miner = miner_service();
|
let miner = miner_service();
|
||||||
let client = client_service();
|
let client = client_service();
|
||||||
let network = network_service();
|
let network = network_service();
|
||||||
let io = IoHandler::new();
|
let io = IoHandler::new();
|
||||||
io.add_delegate(ethcore_set_client(&client, &miner, &network).to_delegate());
|
io.add_delegate(parity_set_client(&client, &miner, &network).to_delegate());
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setAuthor", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_setAuthor", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
@ -103,16 +107,31 @@ fn rpc_ethcore_set_author() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_ethcore_set_transactions_limit() {
|
fn rpc_parity_set_transactions_limit() {
|
||||||
let miner = miner_service();
|
let miner = miner_service();
|
||||||
let client = client_service();
|
let client = client_service();
|
||||||
let network = network_service();
|
let network = network_service();
|
||||||
let io = IoHandler::new();
|
let io = IoHandler::new();
|
||||||
io.add_delegate(ethcore_set_client(&client, &miner, &network).to_delegate());
|
io.add_delegate(parity_set_client(&client, &miner, &network).to_delegate());
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setTransactionsLimit", "params":[10240240], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_setTransactionsLimit", "params":[10240240], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
assert_eq!(miner.transactions_limit(), 10_240_240);
|
assert_eq!(miner.transactions_limit(), 10_240_240);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_parity_set_hash_content() {
|
||||||
|
let miner = miner_service();
|
||||||
|
let client = client_service();
|
||||||
|
let network = network_service();
|
||||||
|
let io = IoHandler::new();
|
||||||
|
io.add_delegate(parity_set_client(&client, &miner, &network).to_delegate());
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_hashContent", "params":["https://ethcore.io/assets/images/ethcore-black-horizontal.png"], "id": 1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":"0x2be00befcf008bc0e7d9cdefc194db9c75352e8632f48498b5a6bfce9f02c88e","id":1}"#;
|
||||||
|
|
||||||
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
}
|
||||||
|
|
@ -19,7 +19,7 @@ use std::str::FromStr;
|
|||||||
use jsonrpc_core::IoHandler;
|
use jsonrpc_core::IoHandler;
|
||||||
use util::{U256, Uint, Address};
|
use util::{U256, Uint, Address};
|
||||||
use ethcore::account_provider::AccountProvider;
|
use ethcore::account_provider::AccountProvider;
|
||||||
use v1::{PersonalClient, PersonalAccountsClient, PersonalAccounts, Personal};
|
use v1::{PersonalClient, Personal};
|
||||||
use v1::tests::helpers::TestMinerService;
|
use v1::tests::helpers::TestMinerService;
|
||||||
use ethcore::client::TestBlockChainClient;
|
use ethcore::client::TestBlockChainClient;
|
||||||
use ethcore::transaction::{Action, Transaction};
|
use ethcore::transaction::{Action, Transaction};
|
||||||
@ -50,12 +50,10 @@ fn setup() -> PersonalTester {
|
|||||||
let accounts = accounts_provider();
|
let accounts = accounts_provider();
|
||||||
let client = blockchain_client();
|
let client = blockchain_client();
|
||||||
let miner = miner_service();
|
let miner = miner_service();
|
||||||
let personal = PersonalClient::new(&accounts, &client);
|
let personal = PersonalClient::new(&accounts, &client, &miner, false);
|
||||||
let personal_accounts = PersonalAccountsClient::new(&accounts, &client, &miner, false);
|
|
||||||
|
|
||||||
let io = IoHandler::new();
|
let io = IoHandler::new();
|
||||||
io.add_delegate(personal.to_delegate());
|
io.add_delegate(personal.to_delegate());
|
||||||
io.add_delegate(personal_accounts.to_delegate());
|
|
||||||
|
|
||||||
let tester = PersonalTester {
|
let tester = PersonalTester {
|
||||||
accounts: accounts,
|
accounts: accounts,
|
||||||
@ -92,66 +90,6 @@ fn new_account() {
|
|||||||
assert_eq!(res, Some(response));
|
assert_eq!(res, Some(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_be_able_to_get_account_info() {
|
|
||||||
let tester = setup();
|
|
||||||
tester.accounts.new_account("").unwrap();
|
|
||||||
let accounts = tester.accounts.accounts().unwrap();
|
|
||||||
assert_eq!(accounts.len(), 1);
|
|
||||||
let address = accounts[0];
|
|
||||||
|
|
||||||
let uuid = tester.accounts.accounts_info().unwrap().get(&address).unwrap().uuid.as_ref().unwrap().clone();
|
|
||||||
tester.accounts.set_account_name(address.clone(), "Test".to_owned()).unwrap();
|
|
||||||
tester.accounts.set_account_meta(address.clone(), "{foo: 69}".to_owned()).unwrap();
|
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "personal_accountsInfo", "params": [], "id": 1}"#;
|
|
||||||
let res = tester.io.handle_request_sync(request);
|
|
||||||
let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":{{\"0x{}\":{{\"meta\":\"{{foo: 69}}\",\"name\":\"Test\",\"uuid\":\"{}\"}}}},\"id\":1}}", address.hex(), uuid);
|
|
||||||
assert_eq!(res, Some(response));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_be_able_to_set_name() {
|
|
||||||
let tester = setup();
|
|
||||||
tester.accounts.new_account("").unwrap();
|
|
||||||
let accounts = tester.accounts.accounts().unwrap();
|
|
||||||
assert_eq!(accounts.len(), 1);
|
|
||||||
let address = accounts[0];
|
|
||||||
|
|
||||||
let request = format!(r#"{{"jsonrpc": "2.0", "method": "personal_setAccountName", "params": ["0x{}", "Test"], "id": 1}}"#, address.hex());
|
|
||||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
|
||||||
let res = tester.io.handle_request_sync(&request);
|
|
||||||
assert_eq!(res, Some(response.into()));
|
|
||||||
|
|
||||||
let uuid = tester.accounts.accounts_info().unwrap().get(&address).unwrap().uuid.as_ref().unwrap().clone();
|
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "personal_accountsInfo", "params": [], "id": 1}"#;
|
|
||||||
let res = tester.io.handle_request_sync(request);
|
|
||||||
let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":{{\"0x{}\":{{\"meta\":\"{{}}\",\"name\":\"Test\",\"uuid\":\"{}\"}}}},\"id\":1}}", address.hex(), uuid);
|
|
||||||
assert_eq!(res, Some(response));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_be_able_to_set_meta() {
|
|
||||||
let tester = setup();
|
|
||||||
tester.accounts.new_account("").unwrap();
|
|
||||||
let accounts = tester.accounts.accounts().unwrap();
|
|
||||||
assert_eq!(accounts.len(), 1);
|
|
||||||
let address = accounts[0];
|
|
||||||
|
|
||||||
let request = format!(r#"{{"jsonrpc": "2.0", "method": "personal_setAccountMeta", "params": ["0x{}", "{{foo: 69}}"], "id": 1}}"#, address.hex());
|
|
||||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
|
||||||
let res = tester.io.handle_request_sync(&request);
|
|
||||||
assert_eq!(res, Some(response.into()));
|
|
||||||
|
|
||||||
let uuid = tester.accounts.accounts_info().unwrap().get(&address).unwrap().uuid.as_ref().unwrap().clone();
|
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "personal_accountsInfo", "params": [], "id": 1}"#;
|
|
||||||
let res = tester.io.handle_request_sync(request);
|
|
||||||
let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":{{\"0x{}\":{{\"meta\":\"{{foo: 69}}\",\"name\":\"{}\",\"uuid\":\"{}\"}}}},\"id\":1}}", address.hex(), uuid, uuid);
|
|
||||||
assert_eq!(res, Some(response));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sign_and_send_transaction_with_invalid_password() {
|
fn sign_and_send_transaction_with_invalid_password() {
|
||||||
let tester = setup();
|
let tester = setup();
|
||||||
|
@ -21,11 +21,11 @@ use util::{U256, Uint, Address};
|
|||||||
use ethcore::account_provider::AccountProvider;
|
use ethcore::account_provider::AccountProvider;
|
||||||
use ethcore::client::TestBlockChainClient;
|
use ethcore::client::TestBlockChainClient;
|
||||||
use ethcore::transaction::{Transaction, Action};
|
use ethcore::transaction::{Transaction, Action};
|
||||||
use v1::{SignerClient, PersonalSigner};
|
use v1::{SignerClient, Signer};
|
||||||
use v1::tests::helpers::TestMinerService;
|
use v1::tests::helpers::TestMinerService;
|
||||||
use v1::helpers::{SigningQueue, SignerService, FilledTransactionRequest, ConfirmationPayload};
|
use v1::helpers::{SigningQueue, SignerService, FilledTransactionRequest, ConfirmationPayload};
|
||||||
|
|
||||||
struct PersonalSignerTester {
|
struct SignerTester {
|
||||||
signer: Arc<SignerService>,
|
signer: Arc<SignerService>,
|
||||||
accounts: Arc<AccountProvider>,
|
accounts: Arc<AccountProvider>,
|
||||||
io: IoHandler,
|
io: IoHandler,
|
||||||
@ -48,7 +48,7 @@ fn miner_service() -> Arc<TestMinerService> {
|
|||||||
Arc::new(TestMinerService::default())
|
Arc::new(TestMinerService::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn signer_tester() -> PersonalSignerTester {
|
fn signer_tester() -> SignerTester {
|
||||||
let signer = Arc::new(SignerService::new_test(None));
|
let signer = Arc::new(SignerService::new_test(None));
|
||||||
let accounts = accounts_provider();
|
let accounts = accounts_provider();
|
||||||
let client = blockchain_client();
|
let client = blockchain_client();
|
||||||
@ -57,7 +57,7 @@ fn signer_tester() -> PersonalSignerTester {
|
|||||||
let io = IoHandler::new();
|
let io = IoHandler::new();
|
||||||
io.add_delegate(SignerClient::new(&accounts, &client, &miner, &signer).to_delegate());
|
io.add_delegate(SignerClient::new(&accounts, &client, &miner, &signer).to_delegate());
|
||||||
|
|
||||||
PersonalSignerTester {
|
SignerTester {
|
||||||
signer: signer,
|
signer: signer,
|
||||||
accounts: accounts,
|
accounts: accounts,
|
||||||
io: io,
|
io: io,
|
||||||
@ -83,7 +83,7 @@ fn should_return_list_of_items_to_confirm() {
|
|||||||
tester.signer.add_request(ConfirmationPayload::Sign(1.into(), 5.into())).unwrap();
|
tester.signer.add_request(ConfirmationPayload::Sign(1.into(), 5.into())).unwrap();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let request = r#"{"jsonrpc":"2.0","method":"personal_requestsToConfirm","params":[],"id":1}"#;
|
let request = r#"{"jsonrpc":"2.0","method":"signer_requestsToConfirm","params":[],"id":1}"#;
|
||||||
let response = concat!(
|
let response = concat!(
|
||||||
r#"{"jsonrpc":"2.0","result":["#,
|
r#"{"jsonrpc":"2.0","result":["#,
|
||||||
r#"{"id":"0x1","payload":{"transaction":{"data":"0x","from":"0x0000000000000000000000000000000000000001","gas":"0x989680","gasPrice":"0x2710","nonce":null,"to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","value":"0x1"}}},"#,
|
r#"{"id":"0x1","payload":{"transaction":{"data":"0x","from":"0x0000000000000000000000000000000000000001","gas":"0x989680","gasPrice":"0x2710","nonce":null,"to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","value":"0x1"}}},"#,
|
||||||
@ -112,7 +112,7 @@ fn should_reject_transaction_from_queue_without_dispatching() {
|
|||||||
assert_eq!(tester.signer.requests().len(), 1);
|
assert_eq!(tester.signer.requests().len(), 1);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let request = r#"{"jsonrpc":"2.0","method":"personal_rejectRequest","params":["0x1"],"id":1}"#;
|
let request = r#"{"jsonrpc":"2.0","method":"signer_rejectRequest","params":["0x1"],"id":1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
|
|
||||||
// then
|
// then
|
||||||
@ -137,7 +137,7 @@ fn should_not_remove_transaction_if_password_is_invalid() {
|
|||||||
assert_eq!(tester.signer.requests().len(), 1);
|
assert_eq!(tester.signer.requests().len(), 1);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let request = r#"{"jsonrpc":"2.0","method":"personal_confirmRequest","params":["0x1",{},"xxx"],"id":1}"#;
|
let request = r#"{"jsonrpc":"2.0","method":"signer_confirmRequest","params":["0x1",{},"xxx"],"id":1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","error":{"code":-32021,"message":"Account password is invalid or account does not exist.","data":"SStore(InvalidAccount)"},"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","error":{"code":-32021,"message":"Account password is invalid or account does not exist.","data":"SStore(InvalidAccount)"},"id":1}"#;
|
||||||
|
|
||||||
// then
|
// then
|
||||||
@ -153,7 +153,7 @@ fn should_not_remove_sign_if_password_is_invalid() {
|
|||||||
assert_eq!(tester.signer.requests().len(), 1);
|
assert_eq!(tester.signer.requests().len(), 1);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let request = r#"{"jsonrpc":"2.0","method":"personal_confirmRequest","params":["0x1",{},"xxx"],"id":1}"#;
|
let request = r#"{"jsonrpc":"2.0","method":"signer_confirmRequest","params":["0x1",{},"xxx"],"id":1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","error":{"code":-32021,"message":"Account password is invalid or account does not exist.","data":"SStore(InvalidAccount)"},"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","error":{"code":-32021,"message":"Account password is invalid or account does not exist.","data":"SStore(InvalidAccount)"},"id":1}"#;
|
||||||
|
|
||||||
// then
|
// then
|
||||||
@ -194,7 +194,7 @@ fn should_confirm_transaction_and_dispatch() {
|
|||||||
// when
|
// when
|
||||||
let request = r#"{
|
let request = r#"{
|
||||||
"jsonrpc":"2.0",
|
"jsonrpc":"2.0",
|
||||||
"method":"personal_confirmRequest",
|
"method":"signer_confirmRequest",
|
||||||
"params":["0x1", {"gasPrice":"0x1000"}, "test"],
|
"params":["0x1", {"gasPrice":"0x1000"}, "test"],
|
||||||
"id":1
|
"id":1
|
||||||
}"#;
|
}"#;
|
||||||
@ -214,7 +214,7 @@ fn should_generate_new_token() {
|
|||||||
// when
|
// when
|
||||||
let request = r#"{
|
let request = r#"{
|
||||||
"jsonrpc":"2.0",
|
"jsonrpc":"2.0",
|
||||||
"method":"personal_generateAuthorizationToken",
|
"method":"signer_generateAuthorizationToken",
|
||||||
"params":[],
|
"params":[],
|
||||||
"id":1
|
"id":1
|
||||||
}"#;
|
}"#;
|
@ -17,12 +17,12 @@
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use jsonrpc_core::{IoHandler, to_value, Success};
|
use jsonrpc_core::{IoHandler, to_value, Success};
|
||||||
use v1::impls::EthSigningQueueClient;
|
use v1::impls::SigningQueueClient;
|
||||||
use v1::traits::{EthSigning, Ethcore};
|
use v1::traits::{EthSigning, ParitySigning, Parity};
|
||||||
use v1::helpers::{SignerService, SigningQueue};
|
use v1::helpers::{SignerService, SigningQueue};
|
||||||
use v1::types::{H256 as RpcH256, H520 as RpcH520, Bytes};
|
use v1::types::{H256 as RpcH256, H520 as RpcH520, Bytes};
|
||||||
use v1::tests::helpers::TestMinerService;
|
use v1::tests::helpers::TestMinerService;
|
||||||
use v1::tests::mocked::ethcore;
|
use v1::tests::mocked::parity;
|
||||||
|
|
||||||
use util::{Address, FixedHash, Uint, U256, H256, H520};
|
use util::{Address, FixedHash, Uint, U256, H256, H520};
|
||||||
use ethcore::account_provider::AccountProvider;
|
use ethcore::account_provider::AccountProvider;
|
||||||
@ -31,7 +31,7 @@ use ethcore::transaction::{Transaction, Action};
|
|||||||
use ethstore::ethkey::{Generator, Random};
|
use ethstore::ethkey::{Generator, Random};
|
||||||
use serde_json;
|
use serde_json;
|
||||||
|
|
||||||
struct EthSigningTester {
|
struct SigningTester {
|
||||||
pub signer: Arc<SignerService>,
|
pub signer: Arc<SignerService>,
|
||||||
pub client: Arc<TestBlockChainClient>,
|
pub client: Arc<TestBlockChainClient>,
|
||||||
pub miner: Arc<TestMinerService>,
|
pub miner: Arc<TestMinerService>,
|
||||||
@ -39,16 +39,19 @@ struct EthSigningTester {
|
|||||||
pub io: IoHandler,
|
pub io: IoHandler,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for EthSigningTester {
|
impl Default for SigningTester {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let signer = Arc::new(SignerService::new_test(None));
|
let signer = Arc::new(SignerService::new_test(None));
|
||||||
let client = Arc::new(TestBlockChainClient::default());
|
let client = Arc::new(TestBlockChainClient::default());
|
||||||
let miner = Arc::new(TestMinerService::default());
|
let miner = Arc::new(TestMinerService::default());
|
||||||
let accounts = Arc::new(AccountProvider::transient_provider());
|
let accounts = Arc::new(AccountProvider::transient_provider());
|
||||||
let io = IoHandler::new();
|
let io = IoHandler::new();
|
||||||
io.add_delegate(EthSigningQueueClient::new(&signer, &client, &miner, &accounts).to_delegate());
|
let rpc = SigningQueueClient::new(&signer, &client, &miner, &accounts);
|
||||||
|
io.add_delegate(EthSigning::to_delegate(rpc));
|
||||||
|
let rpc = SigningQueueClient::new(&signer, &client, &miner, &accounts);
|
||||||
|
io.add_delegate(ParitySigning::to_delegate(rpc));
|
||||||
|
|
||||||
EthSigningTester {
|
SigningTester {
|
||||||
signer: signer,
|
signer: signer,
|
||||||
client: client,
|
client: client,
|
||||||
miner: miner,
|
miner: miner,
|
||||||
@ -58,8 +61,8 @@ impl Default for EthSigningTester {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eth_signing() -> EthSigningTester {
|
fn eth_signing() -> SigningTester {
|
||||||
EthSigningTester::default()
|
SigningTester::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -101,7 +104,7 @@ fn should_post_sign_to_queue() {
|
|||||||
// when
|
// when
|
||||||
let request = r#"{
|
let request = r#"{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"method": "eth_postSign",
|
"method": "parity_postSign",
|
||||||
"params": [
|
"params": [
|
||||||
""#.to_owned() + format!("0x{:?}", address).as_ref() + r#"",
|
""#.to_owned() + format!("0x{:?}", address).as_ref() + r#"",
|
||||||
"0x0000000000000000000000000000000000000000000000000000000000000005"
|
"0x0000000000000000000000000000000000000000000000000000000000000005"
|
||||||
@ -122,7 +125,7 @@ fn should_check_status_of_request() {
|
|||||||
let address = Address::random();
|
let address = Address::random();
|
||||||
let request = r#"{
|
let request = r#"{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"method": "eth_postSign",
|
"method": "parity_postSign",
|
||||||
"params": [
|
"params": [
|
||||||
""#.to_owned() + format!("0x{:?}", address).as_ref() + r#"",
|
""#.to_owned() + format!("0x{:?}", address).as_ref() + r#"",
|
||||||
"0x0000000000000000000000000000000000000000000000000000000000000005"
|
"0x0000000000000000000000000000000000000000000000000000000000000005"
|
||||||
@ -134,7 +137,7 @@ fn should_check_status_of_request() {
|
|||||||
// when
|
// when
|
||||||
let request = r#"{
|
let request = r#"{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"method": "eth_checkRequest",
|
"method": "parity_checkRequest",
|
||||||
"params": ["0x1"],
|
"params": ["0x1"],
|
||||||
"id": 1
|
"id": 1
|
||||||
}"#;
|
}"#;
|
||||||
@ -151,7 +154,7 @@ fn should_check_status_of_request_when_its_resolved() {
|
|||||||
let address = Address::random();
|
let address = Address::random();
|
||||||
let request = r#"{
|
let request = r#"{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"method": "eth_postSign",
|
"method": "parity_postSign",
|
||||||
"params": [
|
"params": [
|
||||||
""#.to_owned() + format!("0x{:?}", address).as_ref() + r#"",
|
""#.to_owned() + format!("0x{:?}", address).as_ref() + r#"",
|
||||||
"0x0000000000000000000000000000000000000000000000000000000000000005"
|
"0x0000000000000000000000000000000000000000000000000000000000000005"
|
||||||
@ -164,7 +167,7 @@ fn should_check_status_of_request_when_its_resolved() {
|
|||||||
// when
|
// when
|
||||||
let request = r#"{
|
let request = r#"{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"method": "eth_checkRequest",
|
"method": "parity_checkRequest",
|
||||||
"params": ["0x1"],
|
"params": ["0x1"],
|
||||||
"id": 1
|
"id": 1
|
||||||
}"#;
|
}"#;
|
||||||
@ -272,15 +275,15 @@ fn should_dispatch_transaction_if_account_is_unlock() {
|
|||||||
fn should_decrypt_message_if_account_is_unlocked() {
|
fn should_decrypt_message_if_account_is_unlocked() {
|
||||||
// given
|
// given
|
||||||
let tester = eth_signing();
|
let tester = eth_signing();
|
||||||
let ethcore = ethcore::Dependencies::new();
|
let parity = parity::Dependencies::new();
|
||||||
tester.io.add_delegate(ethcore.client(None).to_delegate());
|
tester.io.add_delegate(parity.client(None).to_delegate());
|
||||||
let (address, public) = tester.accounts.new_account_and_public("test").unwrap();
|
let (address, public) = tester.accounts.new_account_and_public("test").unwrap();
|
||||||
tester.accounts.unlock_account_permanently(address, "test".into()).unwrap();
|
tester.accounts.unlock_account_permanently(address, "test".into()).unwrap();
|
||||||
|
|
||||||
|
|
||||||
// First encrypt message
|
// First encrypt message
|
||||||
let request = format!("{}0x{:?}{}",
|
let request = format!("{}0x{:?}{}",
|
||||||
r#"{"jsonrpc": "2.0", "method": "ethcore_encryptMessage", "params":[""#,
|
r#"{"jsonrpc": "2.0", "method": "parity_encryptMessage", "params":[""#,
|
||||||
public,
|
public,
|
||||||
r#"", "0x01020304"], "id": 1}"#
|
r#"", "0x01020304"], "id": 1}"#
|
||||||
);
|
);
|
||||||
@ -288,7 +291,7 @@ fn should_decrypt_message_if_account_is_unlocked() {
|
|||||||
|
|
||||||
// then call decrypt
|
// then call decrypt
|
||||||
let request = format!("{}{:?}{}{:?}{}",
|
let request = format!("{}{:?}{}{:?}{}",
|
||||||
r#"{"jsonrpc": "2.0", "method": "ethcore_decryptMessage", "params":["0x"#,
|
r#"{"jsonrpc": "2.0", "method": "parity_decryptMessage", "params":["0x"#,
|
||||||
address,
|
address,
|
||||||
r#"","#,
|
r#"","#,
|
||||||
encrypted.result,
|
encrypted.result,
|
||||||
@ -311,7 +314,7 @@ fn should_add_decryption_to_the_queue() {
|
|||||||
// when
|
// when
|
||||||
let request = r#"{
|
let request = r#"{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"method": "ethcore_decryptMessage",
|
"method": "parity_decryptMessage",
|
||||||
"params": ["0x"#.to_owned() + &format!("{:?}", acc.address()) + r#"",
|
"params": ["0x"#.to_owned() + &format!("{:?}", acc.address()) + r#"",
|
||||||
"0x012345"],
|
"0x012345"],
|
||||||
"id": 1
|
"id": 1
|
@ -23,41 +23,18 @@ pub trait EthSigning: Sized + Send + Sync + 'static {
|
|||||||
/// Signs the data with given address signature.
|
/// Signs the data with given address signature.
|
||||||
fn sign(&self, _: Params, _: Ready);
|
fn sign(&self, _: Params, _: Ready);
|
||||||
|
|
||||||
/// Posts sign request asynchronously.
|
|
||||||
/// Will return a confirmation ID for later use with check_transaction.
|
|
||||||
fn post_sign(&self, _: Params) -> Result<Value, Error>;
|
|
||||||
|
|
||||||
/// Sends transaction; will block for 20s to try to return the
|
/// Sends transaction; will block for 20s to try to return the
|
||||||
/// transaction hash.
|
/// transaction hash.
|
||||||
/// If it cannot yet be signed, it will return a transaction ID for
|
/// If it cannot yet be signed, it will return a transaction ID for
|
||||||
/// later use with check_transaction.
|
/// later use with check_transaction.
|
||||||
fn send_transaction(&self, _: Params, _: Ready);
|
fn send_transaction(&self, _: Params, _: Ready);
|
||||||
|
|
||||||
/// Posts transaction asynchronously.
|
|
||||||
/// Will return a transaction ID for later use with check_transaction.
|
|
||||||
fn post_transaction(&self, _: Params) -> Result<Value, Error>;
|
|
||||||
|
|
||||||
/// Checks the progress of a previously posted request (transaction/sign).
|
|
||||||
/// Should be given a valid send_transaction ID.
|
|
||||||
/// Returns the transaction hash, the zero hash (not yet available),
|
|
||||||
/// or the signature,
|
|
||||||
/// or an error.
|
|
||||||
fn check_request(&self, _: Params) -> Result<Value, Error>;
|
|
||||||
|
|
||||||
/// Decrypt some ECIES-encrypted message.
|
|
||||||
/// First parameter is the address with which it is encrypted, second is the ciphertext.
|
|
||||||
fn decrypt_message(&self, _: Params, _: Ready);
|
|
||||||
|
|
||||||
/// Should be used to convert object to io delegate.
|
/// Should be used to convert object to io delegate.
|
||||||
fn to_delegate(self) -> IoDelegate<Self> {
|
fn to_delegate(self) -> IoDelegate<Self> {
|
||||||
let mut delegate = IoDelegate::new(Arc::new(self));
|
let mut delegate = IoDelegate::new(Arc::new(self));
|
||||||
delegate.add_async_method("eth_sign", EthSigning::sign);
|
delegate.add_async_method("eth_sign", EthSigning::sign);
|
||||||
delegate.add_async_method("eth_sendTransaction", EthSigning::send_transaction);
|
delegate.add_async_method("eth_sendTransaction", EthSigning::send_transaction);
|
||||||
delegate.add_async_method("ethcore_decryptMessage", EthSigning::decrypt_message);
|
|
||||||
|
|
||||||
delegate.add_method("eth_postSign", EthSigning::post_sign);
|
|
||||||
delegate.add_method("eth_postTransaction", EthSigning::post_transaction);
|
|
||||||
delegate.add_method("eth_checkRequest", EthSigning::check_request);
|
|
||||||
delegate
|
delegate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,12 @@ pub mod web3;
|
|||||||
pub mod eth;
|
pub mod eth;
|
||||||
pub mod eth_signing;
|
pub mod eth_signing;
|
||||||
pub mod net;
|
pub mod net;
|
||||||
|
pub mod parity;
|
||||||
|
pub mod parity_accounts;
|
||||||
|
pub mod parity_set;
|
||||||
|
pub mod parity_signing;
|
||||||
pub mod personal;
|
pub mod personal;
|
||||||
pub mod ethcore;
|
pub mod signer;
|
||||||
pub mod ethcore_set;
|
|
||||||
pub mod traces;
|
pub mod traces;
|
||||||
pub mod rpc;
|
pub mod rpc;
|
||||||
|
|
||||||
@ -30,9 +33,12 @@ pub use self::web3::Web3;
|
|||||||
pub use self::eth::{Eth, EthFilter};
|
pub use self::eth::{Eth, EthFilter};
|
||||||
pub use self::eth_signing::EthSigning;
|
pub use self::eth_signing::EthSigning;
|
||||||
pub use self::net::Net;
|
pub use self::net::Net;
|
||||||
pub use self::personal::{Personal, PersonalAccounts, PersonalSigner};
|
pub use self::parity::Parity;
|
||||||
pub use self::ethcore::Ethcore;
|
pub use self::parity_accounts::ParityAccounts;
|
||||||
pub use self::ethcore_set::EthcoreSet;
|
pub use self::parity_set::ParitySet;
|
||||||
|
pub use self::parity_signing::ParitySigning;
|
||||||
|
pub use self::personal::Personal;
|
||||||
|
pub use self::signer::Signer;
|
||||||
pub use self::traces::Traces;
|
pub use self::traces::Traces;
|
||||||
pub use self::rpc::Rpc;
|
pub use self::rpc::Rpc;
|
||||||
|
|
||||||
|
@ -14,128 +14,129 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//! Ethcore-specific rpc interface.
|
//! Parity-specific rpc interface.
|
||||||
use jsonrpc_core::Error;
|
use jsonrpc_core::Error;
|
||||||
|
|
||||||
use v1::helpers::auto_args::{Wrap, WrapAsync, Ready};
|
use std::collections::BTreeMap;
|
||||||
|
use v1::helpers::auto_args::Wrap;
|
||||||
use v1::types::{H160, H256, H512, U256, Bytes, Peers, Transaction, RpcSettings, Histogram};
|
use v1::types::{H160, H256, H512, U256, Bytes, Peers, Transaction, RpcSettings, Histogram};
|
||||||
|
|
||||||
build_rpc_trait! {
|
build_rpc_trait! {
|
||||||
/// Ethcore-specific rpc interface.
|
/// Parity-specific rpc interface.
|
||||||
pub trait Ethcore {
|
pub trait Parity {
|
||||||
/// Returns current transactions limit.
|
/// Returns current transactions limit.
|
||||||
#[rpc(name = "ethcore_transactionsLimit")]
|
#[rpc(name = "parity_transactionsLimit")]
|
||||||
fn transactions_limit(&self) -> Result<usize, Error>;
|
fn transactions_limit(&self) -> Result<usize, Error>;
|
||||||
|
|
||||||
/// Returns mining extra data.
|
/// Returns mining extra data.
|
||||||
#[rpc(name = "ethcore_extraData")]
|
#[rpc(name = "parity_extraData")]
|
||||||
fn extra_data(&self) -> Result<Bytes, Error>;
|
fn extra_data(&self) -> Result<Bytes, Error>;
|
||||||
|
|
||||||
/// Returns mining gas floor target.
|
/// Returns mining gas floor target.
|
||||||
#[rpc(name = "ethcore_gasFloorTarget")]
|
#[rpc(name = "parity_gasFloorTarget")]
|
||||||
fn gas_floor_target(&self) -> Result<U256, Error>;
|
fn gas_floor_target(&self) -> Result<U256, Error>;
|
||||||
|
|
||||||
/// Returns mining gas floor cap.
|
/// Returns mining gas floor cap.
|
||||||
#[rpc(name = "ethcore_gasCeilTarget")]
|
#[rpc(name = "parity_gasCeilTarget")]
|
||||||
fn gas_ceil_target(&self) -> Result<U256, Error>;
|
fn gas_ceil_target(&self) -> Result<U256, Error>;
|
||||||
|
|
||||||
/// Returns minimal gas price for transaction to be included in queue.
|
/// Returns minimal gas price for transaction to be included in queue.
|
||||||
#[rpc(name = "ethcore_minGasPrice")]
|
#[rpc(name = "parity_minGasPrice")]
|
||||||
fn min_gas_price(&self) -> Result<U256, Error>;
|
fn min_gas_price(&self) -> Result<U256, Error>;
|
||||||
|
|
||||||
/// Returns latest logs
|
/// Returns latest logs
|
||||||
#[rpc(name = "ethcore_devLogs")]
|
#[rpc(name = "parity_devLogs")]
|
||||||
fn dev_logs(&self) -> Result<Vec<String>, Error>;
|
fn dev_logs(&self) -> Result<Vec<String>, Error>;
|
||||||
|
|
||||||
/// Returns logs levels
|
/// Returns logs levels
|
||||||
#[rpc(name = "ethcore_devLogsLevels")]
|
#[rpc(name = "parity_devLogsLevels")]
|
||||||
fn dev_logs_levels(&self) -> Result<String, Error>;
|
fn dev_logs_levels(&self) -> Result<String, Error>;
|
||||||
|
|
||||||
/// Returns chain name
|
/// Returns chain name
|
||||||
#[rpc(name = "ethcore_netChain")]
|
#[rpc(name = "parity_netChain")]
|
||||||
fn net_chain(&self) -> Result<String, Error>;
|
fn net_chain(&self) -> Result<String, Error>;
|
||||||
|
|
||||||
/// Returns peers details
|
/// Returns peers details
|
||||||
#[rpc(name = "ethcore_netPeers")]
|
#[rpc(name = "parity_netPeers")]
|
||||||
fn net_peers(&self) -> Result<Peers, Error>;
|
fn net_peers(&self) -> Result<Peers, Error>;
|
||||||
|
|
||||||
/// Returns network port
|
/// Returns network port
|
||||||
#[rpc(name = "ethcore_netPort")]
|
#[rpc(name = "parity_netPort")]
|
||||||
fn net_port(&self) -> Result<u16, Error>;
|
fn net_port(&self) -> Result<u16, Error>;
|
||||||
|
|
||||||
/// Returns rpc settings
|
/// Returns rpc settings
|
||||||
#[rpc(name = "ethcore_rpcSettings")]
|
#[rpc(name = "parity_rpcSettings")]
|
||||||
fn rpc_settings(&self) -> Result<RpcSettings, Error>;
|
fn rpc_settings(&self) -> Result<RpcSettings, Error>;
|
||||||
|
|
||||||
/// Returns node name
|
/// Returns node name
|
||||||
#[rpc(name = "ethcore_nodeName")]
|
#[rpc(name = "parity_nodeName")]
|
||||||
fn node_name(&self) -> Result<String, Error>;
|
fn node_name(&self) -> Result<String, Error>;
|
||||||
|
|
||||||
/// Returns default extra data
|
/// Returns default extra data
|
||||||
#[rpc(name = "ethcore_defaultExtraData")]
|
#[rpc(name = "parity_defaultExtraData")]
|
||||||
fn default_extra_data(&self) -> Result<Bytes, Error>;
|
fn default_extra_data(&self) -> Result<Bytes, Error>;
|
||||||
|
|
||||||
/// Returns distribution of gas price in latest blocks.
|
/// Returns distribution of gas price in latest blocks.
|
||||||
#[rpc(name = "ethcore_gasPriceHistogram")]
|
#[rpc(name = "parity_gasPriceHistogram")]
|
||||||
fn gas_price_histogram(&self) -> Result<Histogram, Error>;
|
fn gas_price_histogram(&self) -> Result<Histogram, Error>;
|
||||||
|
|
||||||
/// Returns number of unsigned transactions waiting in the signer queue (if signer enabled)
|
/// Returns number of unsigned transactions waiting in the signer queue (if signer enabled)
|
||||||
/// Returns error when signer is disabled
|
/// Returns error when signer is disabled
|
||||||
#[rpc(name = "ethcore_unsignedTransactionsCount")]
|
#[rpc(name = "parity_unsignedTransactionsCount")]
|
||||||
fn unsigned_transactions_count(&self) -> Result<usize, Error>;
|
fn unsigned_transactions_count(&self) -> Result<usize, Error>;
|
||||||
|
|
||||||
/// Returns a cryptographically random phrase sufficient for securely seeding a secret key.
|
/// Returns a cryptographically random phrase sufficient for securely seeding a secret key.
|
||||||
#[rpc(name = "ethcore_generateSecretPhrase")]
|
#[rpc(name = "parity_generateSecretPhrase")]
|
||||||
fn generate_secret_phrase(&self) -> Result<String, Error>;
|
fn generate_secret_phrase(&self) -> Result<String, Error>;
|
||||||
|
|
||||||
/// Returns whatever address would be derived from the given phrase if it were to seed a brainwallet.
|
/// Returns whatever address would be derived from the given phrase if it were to seed a brainwallet.
|
||||||
#[rpc(name = "ethcore_phraseToAddress")]
|
#[rpc(name = "parity_phraseToAddress")]
|
||||||
fn phrase_to_address(&self, String) -> Result<H160, Error>;
|
fn phrase_to_address(&self, String) -> Result<H160, Error>;
|
||||||
|
|
||||||
/// Returns the value of the registrar for this network.
|
/// Returns the value of the registrar for this network.
|
||||||
#[rpc(name = "ethcore_registryAddress")]
|
#[rpc(name = "parity_registryAddress")]
|
||||||
fn registry_address(&self) -> Result<Option<H160>, Error>;
|
fn registry_address(&self) -> Result<Option<H160>, Error>;
|
||||||
|
|
||||||
/// Returns all addresses if Fat DB is enabled (`--fat-db`), or null if not.
|
/// Returns all addresses if Fat DB is enabled (`--fat-db`), or null if not.
|
||||||
#[rpc(name = "ethcore_listAccounts")]
|
#[rpc(name = "parity_listAccounts")]
|
||||||
fn list_accounts(&self) -> Result<Option<Vec<H160>>, Error>;
|
fn list_accounts(&self) -> Result<Option<Vec<H160>>, Error>;
|
||||||
|
|
||||||
/// Returns all storage keys of the given address (first parameter) if Fat DB is enabled (`--fat-db`),
|
/// Returns all storage keys of the given address (first parameter) if Fat DB is enabled (`--fat-db`),
|
||||||
/// or null if not.
|
/// or null if not.
|
||||||
#[rpc(name = "ethcore_listStorageKeys")]
|
#[rpc(name = "parity_listStorageKeys")]
|
||||||
fn list_storage_keys(&self, H160) -> Result<Option<Vec<H256>>, Error>;
|
fn list_storage_keys(&self, H160) -> Result<Option<Vec<H256>>, Error>;
|
||||||
|
|
||||||
/// Encrypt some data with a public key under ECIES.
|
/// Encrypt some data with a public key under ECIES.
|
||||||
/// First parameter is the 512-byte destination public key, second is the message.
|
/// First parameter is the 512-byte destination public key, second is the message.
|
||||||
#[rpc(name = "ethcore_encryptMessage")]
|
#[rpc(name = "parity_encryptMessage")]
|
||||||
fn encrypt_message(&self, H512, Bytes) -> Result<Bytes, Error>;
|
fn encrypt_message(&self, H512, Bytes) -> Result<Bytes, Error>;
|
||||||
|
|
||||||
/// Returns all pending transactions from transaction queue.
|
/// Returns all pending transactions from transaction queue.
|
||||||
#[rpc(name = "ethcore_pendingTransactions")]
|
#[rpc(name = "parity_pendingTransactions")]
|
||||||
fn pending_transactions(&self) -> Result<Vec<Transaction>, Error>;
|
fn pending_transactions(&self) -> Result<Vec<Transaction>, Error>;
|
||||||
|
|
||||||
/// Hash a file content under given URL.
|
|
||||||
#[rpc(async, name = "ethcore_hashContent")]
|
|
||||||
fn hash_content(&self, Ready<H256>, String);
|
|
||||||
|
|
||||||
/// Returns current Trusted Signer port or an error if signer is disabled.
|
/// Returns current Trusted Signer port or an error if signer is disabled.
|
||||||
#[rpc(name = "ethcore_signerPort")]
|
#[rpc(name = "parity_signerPort")]
|
||||||
fn signer_port(&self) -> Result<u16, Error>;
|
fn signer_port(&self) -> Result<u16, Error>;
|
||||||
|
|
||||||
/// Returns current Dapps Server port or an error if dapps server is disabled.
|
/// Returns current Dapps Server port or an error if dapps server is disabled.
|
||||||
#[rpc(name = "ethcore_dappsPort")]
|
#[rpc(name = "parity_dappsPort")]
|
||||||
fn dapps_port(&self) -> Result<u16, Error>;
|
fn dapps_port(&self) -> Result<u16, Error>;
|
||||||
|
|
||||||
/// Returns next nonce for particular sender. Should include all transactions in the queue.
|
/// Returns next nonce for particular sender. Should include all transactions in the queue.
|
||||||
#[rpc(name = "ethcore_nextNonce")]
|
#[rpc(name = "parity_nextNonce")]
|
||||||
fn next_nonce(&self, H160) -> Result<U256, Error>;
|
fn next_nonce(&self, H160) -> Result<U256, Error>;
|
||||||
|
|
||||||
/// Get the mode. Results one of: "active", "passive", "dark", "offline".
|
/// Get the mode. Results one of: "active", "passive", "dark", "offline".
|
||||||
#[rpc(name = "ethcore_mode")]
|
#[rpc(name = "parity_mode")]
|
||||||
fn mode(&self) -> Result<String, Error>;
|
fn mode(&self) -> Result<String, Error>;
|
||||||
|
|
||||||
/// Get the enode of this node.
|
/// Get the enode of this node.
|
||||||
#[rpc(name = "ethcore_enode")]
|
#[rpc(name = "parity_enode")]
|
||||||
fn enode(&self) -> Result<String, Error>;
|
fn enode(&self) -> Result<String, Error>;
|
||||||
|
|
||||||
|
/// Returns accounts information.
|
||||||
|
#[rpc(name = "parity_accounts")]
|
||||||
|
fn accounts(&self) -> Result<BTreeMap<String, BTreeMap<String, String>>, Error>;
|
||||||
}
|
}
|
||||||
}
|
}
|
77
rpc/src/v1/traits/parity_accounts.rs
Normal file
77
rpc/src/v1/traits/parity_accounts.rs
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
// 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/>.
|
||||||
|
|
||||||
|
//! Parity Accounts-related rpc interface.
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
use jsonrpc_core::{Value, Error};
|
||||||
|
|
||||||
|
use v1::helpers::auto_args::Wrap;
|
||||||
|
use v1::types::{H160, H256};
|
||||||
|
|
||||||
|
build_rpc_trait! {
|
||||||
|
/// Personal Parity rpc interface.
|
||||||
|
pub trait ParityAccounts {
|
||||||
|
/// Returns accounts information.
|
||||||
|
#[rpc(name = "parity_accountsInfo")]
|
||||||
|
fn accounts_info(&self) -> Result<BTreeMap<String, Value>, Error>;
|
||||||
|
|
||||||
|
/// Creates new account from the given phrase using standard brainwallet mechanism.
|
||||||
|
/// Second parameter is password for the new account.
|
||||||
|
#[rpc(name = "parity_newAccountFromPhrase")]
|
||||||
|
fn new_account_from_phrase(&self, String, String) -> Result<H160, Error>;
|
||||||
|
|
||||||
|
/// Creates new account from the given JSON wallet.
|
||||||
|
/// Second parameter is password for the wallet and the new account.
|
||||||
|
#[rpc(name = "parity_newAccountFromWallet")]
|
||||||
|
fn new_account_from_wallet(&self, String, String) -> Result<H160, Error>;
|
||||||
|
|
||||||
|
/// Creates new account from the given raw secret.
|
||||||
|
/// Second parameter is password for the new account.
|
||||||
|
#[rpc(name = "parity_newAccountFromSecret")]
|
||||||
|
fn new_account_from_secret(&self, H256, String) -> Result<H160, Error>;
|
||||||
|
|
||||||
|
/// Returns true if given `password` would unlock given `account`.
|
||||||
|
/// Arguments: `account`, `password`.
|
||||||
|
#[rpc(name = "parity_testPassword")]
|
||||||
|
fn test_password(&self, H160, String) -> Result<bool, Error>;
|
||||||
|
|
||||||
|
/// Changes an account's password.
|
||||||
|
/// Arguments: `account`, `password`, `new_password`.
|
||||||
|
#[rpc(name = "parity_changePassword")]
|
||||||
|
fn change_password(&self, H160, String, String) -> Result<bool, Error>;
|
||||||
|
|
||||||
|
/// Set an account's name.
|
||||||
|
#[rpc(name = "parity_setAccountName")]
|
||||||
|
fn set_account_name(&self, H160, String) -> Result<bool, Error>;
|
||||||
|
|
||||||
|
/// Set an account's metadata string.
|
||||||
|
#[rpc(name = "parity_setAccountMeta")]
|
||||||
|
fn set_account_meta(&self, H160, String) -> Result<bool, Error>;
|
||||||
|
|
||||||
|
/// Returns accounts information.
|
||||||
|
#[rpc(name = "parity_setAccountVisiblity")]
|
||||||
|
fn set_account_visibility(&self, H160, H256, bool) -> Result<bool, Error>;
|
||||||
|
|
||||||
|
/// Imports a number of Geth accounts, with the list provided as the argument.
|
||||||
|
#[rpc(name = "parity_importGethAccounts")]
|
||||||
|
fn import_geth_accounts(&self, Vec<H160>) -> Result<Vec<H160>, Error>;
|
||||||
|
|
||||||
|
/// Returns the accounts available for importing from Geth.
|
||||||
|
#[rpc(name = "parity_listGethAccounts")]
|
||||||
|
fn geth_accounts(&self) -> Result<Vec<H160>, Error>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -14,74 +14,78 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//! Ethcore-specific rpc interface for operations altering the settings.
|
//! Parity-specific rpc interface for operations altering the settings.
|
||||||
|
|
||||||
use jsonrpc_core::Error;
|
use jsonrpc_core::Error;
|
||||||
|
|
||||||
use v1::helpers::auto_args::Wrap;
|
use v1::helpers::auto_args::{Wrap, WrapAsync, Ready};
|
||||||
use v1::types::{Bytes, H160, U256};
|
use v1::types::{Bytes, H160, H256, U256};
|
||||||
|
|
||||||
build_rpc_trait! {
|
build_rpc_trait! {
|
||||||
/// Ethcore-specific rpc interface for operations altering the settings.
|
/// Parity-specific rpc interface for operations altering the settings.
|
||||||
pub trait EthcoreSet {
|
pub trait ParitySet {
|
||||||
/// Sets new minimal gas price for mined blocks.
|
/// Sets new minimal gas price for mined blocks.
|
||||||
#[rpc(name = "ethcore_setMinGasPrice")]
|
#[rpc(name = "parity_setMinGasPrice")]
|
||||||
fn set_min_gas_price(&self, U256) -> Result<bool, Error>;
|
fn set_min_gas_price(&self, U256) -> Result<bool, Error>;
|
||||||
|
|
||||||
/// Sets new gas floor target for mined blocks.
|
/// Sets new gas floor target for mined blocks.
|
||||||
#[rpc(name = "ethcore_setGasFloorTarget")]
|
#[rpc(name = "parity_setGasFloorTarget")]
|
||||||
fn set_gas_floor_target(&self, U256) -> Result<bool, Error>;
|
fn set_gas_floor_target(&self, U256) -> Result<bool, Error>;
|
||||||
|
|
||||||
/// Sets new gas ceiling target for mined blocks.
|
/// Sets new gas ceiling target for mined blocks.
|
||||||
#[rpc(name = "ethcore_setGasCeilTarget")]
|
#[rpc(name = "parity_setGasCeilTarget")]
|
||||||
fn set_gas_ceil_target(&self, U256) -> Result<bool, Error>;
|
fn set_gas_ceil_target(&self, U256) -> Result<bool, Error>;
|
||||||
|
|
||||||
/// Sets new extra data for mined blocks.
|
/// Sets new extra data for mined blocks.
|
||||||
#[rpc(name = "ethcore_setExtraData")]
|
#[rpc(name = "parity_setExtraData")]
|
||||||
fn set_extra_data(&self, Bytes) -> Result<bool, Error>;
|
fn set_extra_data(&self, Bytes) -> Result<bool, Error>;
|
||||||
|
|
||||||
/// Sets new author for mined block.
|
/// Sets new author for mined block.
|
||||||
#[rpc(name = "ethcore_setAuthor")]
|
#[rpc(name = "parity_setAuthor")]
|
||||||
fn set_author(&self, H160) -> Result<bool, Error>;
|
fn set_author(&self, H160) -> Result<bool, Error>;
|
||||||
|
|
||||||
/// Sets the limits for transaction queue.
|
/// Sets the limits for transaction queue.
|
||||||
#[rpc(name = "ethcore_setTransactionsLimit")]
|
#[rpc(name = "parity_setTransactionsLimit")]
|
||||||
fn set_transactions_limit(&self, usize) -> Result<bool, Error>;
|
fn set_transactions_limit(&self, usize) -> Result<bool, Error>;
|
||||||
|
|
||||||
/// Sets the maximum amount of gas a single transaction may consume.
|
/// Sets the maximum amount of gas a single transaction may consume.
|
||||||
#[rpc(name = "ethcore_setMaxTransactionGas")]
|
#[rpc(name = "parity_setMaxTransactionGas")]
|
||||||
fn set_tx_gas_limit(&self, U256) -> Result<bool, Error>;
|
fn set_tx_gas_limit(&self, U256) -> Result<bool, Error>;
|
||||||
|
|
||||||
/// Add a reserved peer.
|
/// Add a reserved peer.
|
||||||
#[rpc(name = "ethcore_addReservedPeer")]
|
#[rpc(name = "parity_addReservedPeer")]
|
||||||
fn add_reserved_peer(&self, String) -> Result<bool, Error>;
|
fn add_reserved_peer(&self, String) -> Result<bool, Error>;
|
||||||
|
|
||||||
/// Remove a reserved peer.
|
/// Remove a reserved peer.
|
||||||
#[rpc(name = "ethcore_removeReservedPeer")]
|
#[rpc(name = "parity_removeReservedPeer")]
|
||||||
fn remove_reserved_peer(&self, String) -> Result<bool, Error>;
|
fn remove_reserved_peer(&self, String) -> Result<bool, Error>;
|
||||||
|
|
||||||
/// Drop all non-reserved peers.
|
/// Drop all non-reserved peers.
|
||||||
#[rpc(name = "ethcore_dropNonReservedPeers")]
|
#[rpc(name = "parity_dropNonReservedPeers")]
|
||||||
fn drop_non_reserved_peers(&self) -> Result<bool, Error>;
|
fn drop_non_reserved_peers(&self) -> Result<bool, Error>;
|
||||||
|
|
||||||
/// Accept non-reserved peers (default behavior)
|
/// Accept non-reserved peers (default behavior)
|
||||||
#[rpc(name = "ethcore_acceptNonReservedPeers")]
|
#[rpc(name = "parity_acceptNonReservedPeers")]
|
||||||
fn accept_non_reserved_peers(&self) -> Result<bool, Error>;
|
fn accept_non_reserved_peers(&self) -> Result<bool, Error>;
|
||||||
|
|
||||||
/// Start the network.
|
/// Start the network.
|
||||||
///
|
///
|
||||||
/// Deprecated. Use `set_mode("active")` instead.
|
/// Deprecated. Use `set_mode("active")` instead.
|
||||||
#[rpc(name = "ethcore_startNetwork")]
|
#[rpc(name = "parity_startNetwork")]
|
||||||
fn start_network(&self) -> Result<bool, Error>;
|
fn start_network(&self) -> Result<bool, Error>;
|
||||||
|
|
||||||
/// Stop the network.
|
/// Stop the network.
|
||||||
///
|
///
|
||||||
/// Deprecated. Use `set_mode("offline")` instead.
|
/// Deprecated. Use `set_mode("offline")` instead.
|
||||||
#[rpc(name = "ethcore_stopNetwork")]
|
#[rpc(name = "parity_stopNetwork")]
|
||||||
fn stop_network(&self) -> Result<bool, Error>;
|
fn stop_network(&self) -> Result<bool, Error>;
|
||||||
|
|
||||||
/// Set the mode. Argument must be one of: "active", "passive", "dark", "offline".
|
/// Set the mode. Argument must be one of: "active", "passive", "dark", "offline".
|
||||||
#[rpc(name = "ethcore_setMode")]
|
#[rpc(name = "parity_setMode")]
|
||||||
fn set_mode(&self, String) -> Result<bool, Error>;
|
fn set_mode(&self, String) -> Result<bool, Error>;
|
||||||
|
|
||||||
|
/// Hash a file content under given URL.
|
||||||
|
#[rpc(async, name = "parity_hashContent")]
|
||||||
|
fn hash_content(&self, Ready<H256>, String);
|
||||||
}
|
}
|
||||||
}
|
}
|
52
rpc/src/v1/traits/parity_signing.rs
Normal file
52
rpc/src/v1/traits/parity_signing.rs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// 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/>.
|
||||||
|
|
||||||
|
//! ParitySigning rpc interface.
|
||||||
|
use std::sync::Arc;
|
||||||
|
use jsonrpc_core::*;
|
||||||
|
|
||||||
|
/// Signing methods implementation relying on unlocked accounts.
|
||||||
|
pub trait ParitySigning: Sized + Send + Sync + 'static {
|
||||||
|
/// Posts sign request asynchronously.
|
||||||
|
/// Will return a confirmation ID for later use with check_transaction.
|
||||||
|
fn post_sign(&self, _: Params) -> Result<Value, Error>;
|
||||||
|
|
||||||
|
/// Posts transaction asynchronously.
|
||||||
|
/// Will return a transaction ID for later use with check_transaction.
|
||||||
|
fn post_transaction(&self, _: Params) -> Result<Value, Error>;
|
||||||
|
|
||||||
|
/// Checks the progress of a previously posted request (transaction/sign).
|
||||||
|
/// Should be given a valid send_transaction ID.
|
||||||
|
/// Returns the transaction hash, the zero hash (not yet available),
|
||||||
|
/// or the signature,
|
||||||
|
/// or an error.
|
||||||
|
fn check_request(&self, _: Params) -> Result<Value, Error>;
|
||||||
|
|
||||||
|
/// Decrypt some ECIES-encrypted message.
|
||||||
|
/// First parameter is the address with which it is encrypted, second is the ciphertext.
|
||||||
|
fn decrypt_message(&self, _: Params, _: Ready);
|
||||||
|
|
||||||
|
/// Should be used to convert object to io delegate.
|
||||||
|
fn to_delegate(self) -> IoDelegate<Self> {
|
||||||
|
let mut delegate = IoDelegate::new(Arc::new(self));
|
||||||
|
delegate.add_method("parity_postSign", ParitySigning::post_sign);
|
||||||
|
delegate.add_method("parity_postTransaction", ParitySigning::post_transaction);
|
||||||
|
delegate.add_method("parity_checkRequest", ParitySigning::check_request);
|
||||||
|
delegate.add_async_method("parity_decryptMessage", ParitySigning::decrypt_message);
|
||||||
|
|
||||||
|
delegate
|
||||||
|
}
|
||||||
|
}
|
@ -15,11 +15,10 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//! Personal rpc interface.
|
//! Personal rpc interface.
|
||||||
use std::collections::BTreeMap;
|
use jsonrpc_core::Error;
|
||||||
use jsonrpc_core::{Value, Error};
|
|
||||||
|
|
||||||
use v1::helpers::auto_args::Wrap;
|
use v1::helpers::auto_args::Wrap;
|
||||||
use v1::types::{H160, H256, U256, TransactionRequest, TransactionModification, ConfirmationRequest};
|
use v1::types::{H160, H256, TransactionRequest};
|
||||||
|
|
||||||
build_rpc_trait! {
|
build_rpc_trait! {
|
||||||
/// Personal rpc interface. Safe (read-only) functions.
|
/// Personal rpc interface. Safe (read-only) functions.
|
||||||
@ -28,91 +27,17 @@ build_rpc_trait! {
|
|||||||
#[rpc(name = "personal_listAccounts")]
|
#[rpc(name = "personal_listAccounts")]
|
||||||
fn accounts(&self) -> Result<Vec<H160>, Error>;
|
fn accounts(&self) -> Result<Vec<H160>, Error>;
|
||||||
|
|
||||||
/// Returns accounts information.
|
|
||||||
#[rpc(name = "personal_accountsInfo")]
|
|
||||||
fn accounts_info(&self) -> Result<BTreeMap<String, Value>, Error>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
build_rpc_trait! {
|
|
||||||
/// Personal rpc methods altering stored accounts or their settings.
|
|
||||||
pub trait PersonalAccounts {
|
|
||||||
|
|
||||||
/// Creates new account (it becomes new current unlocked account)
|
/// Creates new account (it becomes new current unlocked account)
|
||||||
/// Param is the password for the account.
|
/// Param is the password for the account.
|
||||||
#[rpc(name = "personal_newAccount")]
|
#[rpc(name = "personal_newAccount")]
|
||||||
fn new_account(&self, String) -> Result<H160, Error>;
|
fn new_account(&self, String) -> Result<H160, Error>;
|
||||||
|
|
||||||
/// Creates new account from the given phrase using standard brainwallet mechanism.
|
|
||||||
/// Second parameter is password for the new account.
|
|
||||||
#[rpc(name = "personal_newAccountFromPhrase")]
|
|
||||||
fn new_account_from_phrase(&self, String, String) -> Result<H160, Error>;
|
|
||||||
|
|
||||||
/// Creates new account from the given JSON wallet.
|
|
||||||
/// Second parameter is password for the wallet and the new account.
|
|
||||||
#[rpc(name = "personal_newAccountFromWallet")]
|
|
||||||
fn new_account_from_wallet(&self, String, String) -> Result<H160, Error>;
|
|
||||||
|
|
||||||
/// Creates new account from the given raw secret.
|
|
||||||
/// Second parameter is password for the new account.
|
|
||||||
#[rpc(name = "personal_newAccountFromSecret")]
|
|
||||||
fn new_account_from_secret(&self, H256, String) -> Result<H160, Error>;
|
|
||||||
|
|
||||||
/// Unlocks specified account for use (can only be one unlocked account at one moment)
|
/// Unlocks specified account for use (can only be one unlocked account at one moment)
|
||||||
#[rpc(name = "personal_unlockAccount")]
|
#[rpc(name = "personal_unlockAccount")]
|
||||||
fn unlock_account(&self, H160, String, Option<u64>) -> Result<bool, Error>;
|
fn unlock_account(&self, H160, String, Option<u64>) -> Result<bool, Error>;
|
||||||
|
|
||||||
/// Returns true if given `password` would unlock given `account`.
|
|
||||||
/// Arguments: `account`, `password`.
|
|
||||||
#[rpc(name = "personal_testPassword")]
|
|
||||||
fn test_password(&self, H160, String) -> Result<bool, Error>;
|
|
||||||
|
|
||||||
/// Changes an account's password.
|
|
||||||
/// Arguments: `account`, `password`, `new_password`.
|
|
||||||
#[rpc(name = "personal_changePassword")]
|
|
||||||
fn change_password(&self, H160, String, String) -> Result<bool, Error>;
|
|
||||||
|
|
||||||
/// Sends transaction and signs it in single call. The account is not unlocked in such case.
|
/// Sends transaction and signs it in single call. The account is not unlocked in such case.
|
||||||
#[rpc(name = "personal_signAndSendTransaction")]
|
#[rpc(name = "personal_signAndSendTransaction")]
|
||||||
fn sign_and_send_transaction(&self, TransactionRequest, String) -> Result<H256, Error>;
|
fn sign_and_send_transaction(&self, TransactionRequest, String) -> Result<H256, Error>;
|
||||||
|
|
||||||
/// Set an account's name.
|
|
||||||
#[rpc(name = "personal_setAccountName")]
|
|
||||||
fn set_account_name(&self, H160, String) -> Result<bool, Error>;
|
|
||||||
|
|
||||||
/// Set an account's metadata string.
|
|
||||||
#[rpc(name = "personal_setAccountMeta")]
|
|
||||||
fn set_account_meta(&self, H160, String) -> Result<bool, Error>;
|
|
||||||
|
|
||||||
/// Imports a number of Geth accounts, with the list provided as the argument.
|
|
||||||
#[rpc(name = "personal_importGethAccounts")]
|
|
||||||
fn import_geth_accounts(&self, Vec<H160>) -> Result<Vec<H160>, Error>;
|
|
||||||
|
|
||||||
/// Returns the accounts available for importing from Geth.
|
|
||||||
#[rpc(name = "personal_listGethAccounts")]
|
|
||||||
fn geth_accounts(&self) -> Result<Vec<H160>, Error>;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
build_rpc_trait! {
|
|
||||||
/// Personal extension for confirmations rpc interface.
|
|
||||||
pub trait PersonalSigner {
|
|
||||||
|
|
||||||
/// Returns a list of items to confirm.
|
|
||||||
#[rpc(name = "personal_requestsToConfirm")]
|
|
||||||
fn requests_to_confirm(&self) -> Result<Vec<ConfirmationRequest>, Error>;
|
|
||||||
|
|
||||||
/// Confirm specific request.
|
|
||||||
#[rpc(name = "personal_confirmRequest")]
|
|
||||||
fn confirm_request(&self, U256, TransactionModification, String) -> Result<Value, Error>;
|
|
||||||
|
|
||||||
/// Reject the confirmation request.
|
|
||||||
#[rpc(name = "personal_rejectRequest")]
|
|
||||||
fn reject_request(&self, U256) -> Result<bool, Error>;
|
|
||||||
|
|
||||||
/// Generates new authorization token.
|
|
||||||
#[rpc(name = "personal_generateAuthorizationToken")]
|
|
||||||
fn generate_token(&self) -> Result<String, Error>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user