From 043ca2186369effb69628bf33e9605725d08dfd1 Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Mon, 7 Nov 2016 14:46:41 +0100 Subject: [PATCH] Backporting to beta (#3229) * Use ethcore_dappsPort when constructing URLs (#3139) * Upon connect, retrieve the available api ports * Update dapps to load from dappsPort * Update dapps summary with dappsPort * Allow proxy to use dappsPort * Replace /api/ping with HEAD / * Dynamic port for available apps * Retrieve content images with dappsPort * Fix / * Transfer token dropdown image fix * IdentityIcon loads images via contentHash * Update apps fetch to cater for dev & prod * DRY up 127.0.0.1:${dappsPort} with ${dappsUrl} * Cleaning up polluted namespaces (#3143) * Renaming ethcore_ to parity_ * Renaming files * Renaming poluted EthSigning * Tidy up the namespaces * Renaming files to match new structure * Splitting EthSigning into separate traits * jsapi move ethcore.* -> parity.* * Move jsonrpc parity definitions * Update UI API calls for parity interfaces * Move jsapi signer interfaces from personal to signer * Update UI to use signer.* where applicable * Updsate jsapi subscriptions for signer * Fix dodgy merge. * Update README. * Fix some tests. * Move parity-only personal.* to parity.* * Update UI for personal -> parity API moves * Update subscription APIs after personal -> parity move * personal. generateAuthorizationToken -> parity. generateAuthorizationToken (UI) * enode, dappsPort & signerPort (UI) * Update subscription tests (accountsInfo) * subscription update * personal -> parity * Additional error logging on method failures * move postTransaction to parity * Additional debug info with method failures * Fix personal tests. * Console wrning shows parameters, error object does not * Include parity_ signing methods. * Console log http transport info * Fix failing tests * Add RPC stubs for parity_accounts. * Allow some secure built-in dapps * Use parity_accounts in place of accountsInfo * Improve error reporting * Cleanup GHH error handling Former-commit-id: 5a094ccb9f0596d0e07abc23504b80dc099ad584 --- README.md | 22 +- js/src/api/README.md | 3 +- js/src/api/api.js | 13 +- js/src/api/contract/contract.js | 6 +- js/src/api/contract/contract.spec.js | 22 +- js/src/api/rpc/eth/eth.js | 10 - js/src/api/rpc/ethcore/ethcore.js | 201 ------------- js/src/api/rpc/index.js | 3 +- js/src/api/rpc/{ethcore => parity}/index.js | 2 +- .../ethcore.e2e.js => parity/parity.e2e.js} | 14 +- js/src/api/rpc/parity/parity.js | 273 ++++++++++++++++++ .../ethcore.spec.js => parity/parity.spec.js} | 40 ++- js/src/api/rpc/personal/personal.js | 86 +----- js/src/api/rpc/personal/personal.spec.js | 22 -- js/src/api/rpc/signer/index.js | 17 ++ js/src/api/rpc/signer/signer.js | 50 ++++ js/src/api/subscriptions/manager.js | 6 +- js/src/api/subscriptions/personal.js | 20 +- js/src/api/subscriptions/personal.spec.js | 17 +- js/src/api/subscriptions/signer.js | 6 +- js/src/api/transport/http/http.js | 6 +- js/src/api/transport/ws/ws.js | 4 +- js/src/contracts/registry.js | 2 +- .../basiccoin/Application/application.js | 2 +- .../basiccoin/Deploy/Deployment/deployment.js | 2 +- js/src/dapps/basiccoin/Transfer/Send/send.js | 2 +- js/src/dapps/basiccoin/services.js | 4 +- js/src/dapps/githubhint.html | 1 - .../githubhint/Application/application.js | 49 +++- js/src/dapps/githubhint/parity.js | 2 +- js/src/dapps/githubhint/services.js | 4 +- js/src/dapps/registry/actions.js | 2 +- js/src/dapps/registry/addresses/actions.js | 2 +- js/src/dapps/signaturereg/services.js | 4 +- js/src/dapps/tokenreg/Accounts/actions.js | 2 +- js/src/dapps/tokenreg/Status/actions.js | 2 +- js/src/index.js | 2 +- js/src/jsonrpc/index.js | 20 +- js/src/jsonrpc/interfaces/eth.js | 30 -- .../interfaces/{ethcore.js => parity.js} | 189 ++++++++++++ js/src/jsonrpc/interfaces/personal.js | 199 ------------- js/src/jsonrpc/interfaces/signer.js | 82 ++++++ js/src/modals/AddAddress/addAddress.js | 4 +- js/src/modals/AddContract/addContract.js | 4 +- .../CreateAccount/NewAccount/newAccount.js | 12 +- .../modals/CreateAccount/NewGeth/newGeth.js | 2 +- js/src/modals/CreateAccount/createAccount.js | 22 +- .../modals/DeployContract/deployContract.js | 4 +- js/src/modals/EditMeta/editMeta.js | 4 +- .../modals/ExecuteContract/executeContract.js | 2 +- js/src/modals/FirstRun/firstRun.js | 4 +- .../modals/PasswordManager/passwordManager.js | 8 +- js/src/modals/Transfer/Details/details.js | 8 +- js/src/modals/Transfer/transfer.js | 6 +- js/src/redux/providers/balances.js | 4 +- js/src/redux/providers/imagesReducer.js | 4 +- js/src/redux/providers/personal.js | 4 +- js/src/redux/providers/signer.js | 18 +- js/src/redux/providers/signerMiddleware.js | 4 +- js/src/redux/providers/status.js | 30 +- js/src/secureApi.js | 34 ++- js/src/ui/Balance/balance.js | 8 +- js/src/ui/IdentityIcon/identityIcon.js | 5 +- js/src/views/Account/Header/header.js | 2 +- js/src/views/Address/Delete/delete.js | 2 +- js/src/views/Application/application.js | 4 +- js/src/views/Dapp/dapp.js | 72 ++++- js/src/views/Dapps/Summary/summary.js | 18 +- js/src/views/Dapps/registry.js | 33 +-- js/src/views/Settings/Parity/parity.js | 4 +- js/src/views/Settings/Proxy/proxy.js | 9 +- .../components/SignRequest/SignRequest.js | 2 +- .../TransactionFinished.js | 2 +- .../TransactionPending/TransactionPending.js | 2 +- .../MiningSettings/MiningSettings.js | 8 +- parity/cli/config.full.toml | 4 +- parity/cli/mod.rs | 8 +- parity/cli/usage.txt | 4 +- parity/configuration.rs | 14 +- parity/rpc_apis.rs | 128 +++++--- rpc/src/v1/impls/mod.rs | 22 +- rpc/src/v1/impls/{ethcore.rs => parity.rs} | 120 +++----- ...ersonal_accounts.rs => parity_accounts.rs} | 81 ++---- .../impls/{ethcore_set.rs => parity_set.rs} | 95 +++++- rpc/src/v1/impls/personal.rs | 76 +++-- .../impls/{personal_signer.rs => signer.rs} | 6 +- .../v1/impls/{eth_signing.rs => signing.rs} | 154 +++------- rpc/src/v1/impls/signing_unsafe.rs | 110 +++++++ rpc/src/v1/mod.rs | 2 +- rpc/src/v1/tests/eth.rs | 4 +- rpc/src/v1/tests/mocked/eth.rs | 4 +- rpc/src/v1/tests/mocked/mod.rs | 9 +- .../v1/tests/mocked/{ethcore.rs => parity.rs} | 104 +++---- rpc/src/v1/tests/mocked/parity_accounts.rs | 118 ++++++++ .../mocked/{ethcore_set.rs => parity_set.rs} | 67 +++-- rpc/src/v1/tests/mocked/personal.rs | 66 +---- .../mocked/{personal_signer.rs => signer.rs} | 20 +- .../mocked/{eth_signing.rs => signing.rs} | 41 +-- rpc/src/v1/traits/eth_signing.rs | 23 -- rpc/src/v1/traits/mod.rs | 16 +- rpc/src/v1/traits/{ethcore.rs => parity.rs} | 71 ++--- rpc/src/v1/traits/parity_accounts.rs | 77 +++++ .../traits/{ethcore_set.rs => parity_set.rs} | 46 +-- rpc/src/v1/traits/parity_signing.rs | 52 ++++ rpc/src/v1/traits/personal.rs | 79 +---- rpc/src/v1/traits/signer.rs | 44 +++ 106 files changed, 1974 insertions(+), 1485 deletions(-) delete mode 100644 js/src/api/rpc/ethcore/ethcore.js rename js/src/api/rpc/{ethcore => parity}/index.js (95%) rename js/src/api/rpc/{ethcore/ethcore.e2e.js => parity/parity.e2e.js} (82%) create mode 100644 js/src/api/rpc/parity/parity.js rename js/src/api/rpc/{ethcore/ethcore.spec.js => parity/parity.spec.js} (66%) create mode 100644 js/src/api/rpc/signer/index.js create mode 100644 js/src/api/rpc/signer/signer.js rename js/src/jsonrpc/interfaces/{ethcore.js => parity.js} (66%) create mode 100644 js/src/jsonrpc/interfaces/signer.js rename rpc/src/v1/impls/{ethcore.rs => parity.rs} (74%) rename rpc/src/v1/impls/{personal_accounts.rs => parity_accounts.rs} (68%) rename rpc/src/v1/impls/{ethcore_set.rs => parity_set.rs} (62%) rename rpc/src/v1/impls/{personal_signer.rs => signer.rs} (94%) rename rpc/src/v1/impls/{eth_signing.rs => signing.rs} (72%) create mode 100644 rpc/src/v1/impls/signing_unsafe.rs rename rpc/src/v1/tests/mocked/{ethcore.rs => parity.rs} (73%) create mode 100644 rpc/src/v1/tests/mocked/parity_accounts.rs rename rpc/src/v1/tests/mocked/{ethcore_set.rs => parity_set.rs} (57%) rename rpc/src/v1/tests/mocked/{personal_signer.rs => signer.rs} (91%) rename rpc/src/v1/tests/mocked/{eth_signing.rs => signing.rs} (90%) rename rpc/src/v1/traits/{ethcore.rs => parity.rs} (74%) create mode 100644 rpc/src/v1/traits/parity_accounts.rs rename rpc/src/v1/traits/{ethcore_set.rs => parity_set.rs} (70%) create mode 100644 rpc/src/v1/traits/parity_signing.rs create mode 100644 rpc/src/v1/traits/signer.rs diff --git a/README.md b/README.md index 08c04c097..6ebf90b6f 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,12 @@ # [Parity](https://ethcore.io/parity.html) ### 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] [![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] @@ -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 [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 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 -of RPC APIs. +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 +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`. -This includes a few useful Dapps, including Ethereum Wallet, Maker OTC, and a node status page. -In a near-future release, it will be easy to install Dapps and use them through this web interface. +By default, Parity will also run a JSONRPC server on `127.0.0.1:8545`. This is fully configurable and supports a number +of RPC APIs. 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! diff --git a/js/src/api/README.md b/js/src/api/README.md index 691a24cca..e28c6c2a1 100644 --- a/js/src/api/README.md +++ b/js/src/api/README.md @@ -135,10 +135,11 @@ APIs implement the calls as exposed in the [Ethcore JSON Ethereum RPC](https://g - [ethapi.db](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#db) - [ethapi.eth](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#eth) -- [ethapi.ethcore](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#ethcore) +- [ethapi.parity](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#parity) - [ethapi.net](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#net) - [ethapi.personal](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#personal) - [ethapi.shh](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#shh) +- [ethapi.signer](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#signer) - [ethapi.trace](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#trace) - [ethapi.web3](https://github.com/ethcore/ethereum-rpc-json/blob/master/interfaces.md#web3) diff --git a/js/src/api/api.js b/js/src/api/api.js index 9768b9acb..75d4392d0 100644 --- a/js/src/api/api.js +++ b/js/src/api/api.js @@ -17,7 +17,7 @@ import { Http, Ws } from './transport'; import Contract from './contract'; -import { Db, Eth, Ethcore, Net, Personal, Shh, Trace, Web3 } from './rpc'; +import { Db, Eth, Parity, Net, Personal, Shh, Signer, Trace, Web3 } from './rpc'; import Subscriptions from './subscriptions'; import util from './util'; import { isFunction } from './util/types'; @@ -32,10 +32,11 @@ export default class Api { this._db = new Db(transport); this._eth = new Eth(transport); - this._ethcore = new Ethcore(transport); this._net = new Net(transport); + this._parity = new Parity(transport); this._personal = new Personal(transport); this._shh = new Shh(transport); + this._signer = new Signer(transport); this._trace = new Trace(transport); this._web3 = new Web3(transport); @@ -50,8 +51,8 @@ export default class Api { return this._eth; } - get ethcore () { - return this._ethcore; + get parity () { + return this._parity; } get net () { @@ -66,6 +67,10 @@ export default class Api { return this._shh; } + get signer () { + return this._signer; + } + get trace () { return this._trace; } diff --git a/js/src/api/contract/contract.js b/js/src/api/contract/contract.js index cef75eda7..bb6c15d8d 100644 --- a/js/src/api/contract/contract.js +++ b/js/src/api/contract/contract.js @@ -102,7 +102,7 @@ export default class Contract { options.gas = gas.toFixed(0); setState({ state: 'postTransaction', gas }); - return this._api.eth.postTransaction(this._encodeOptions(this.constructors[0], options, values)); + return this._api.parity.postTransaction(this._encodeOptions(this.constructors[0], options, values)); }) .then((requestId) => { setState({ state: 'checkRequest', requestId }); @@ -166,7 +166,7 @@ export default class Contract { } _pollCheckRequest = (requestId) => { - return this._api.pollMethod('eth_checkRequest', requestId); + return this._api.pollMethod('parity_checkRequest', requestId); } _pollTransactionReceipt = (txhash, gas) => { @@ -208,7 +208,7 @@ export default class Contract { if (!func.constant) { func.postTransaction = (options, values = []) => { - return this._api.eth + return this._api.parity .postTransaction(this._encodeOptions(func, this._addOptionsTo(options), values)); }; diff --git a/js/src/api/contract/contract.spec.js b/js/src/api/contract/contract.spec.js index 0d6169e26..9065b4fad 100644 --- a/js/src/api/contract/contract.spec.js +++ b/js/src/api/contract/contract.spec.js @@ -249,9 +249,9 @@ describe('api/contract/Contract', () => { before(() => { scope = mockHttp([ { method: 'eth_estimateGas', reply: { result: 1000 } }, - { method: 'eth_postTransaction', reply: { result: '0x678' } }, - { method: 'eth_checkRequest', reply: { result: null } }, - { method: 'eth_checkRequest', reply: { result: '0x890' } }, + { method: 'parity_postTransaction', reply: { result: '0x678' } }, + { method: 'parity_checkRequest', reply: { result: null } }, + { method: 'parity_checkRequest', reply: { result: '0x890' } }, { method: 'eth_getTransactionReceipt', reply: { result: null } }, { method: 'eth_getTransactionReceipt', reply: { result: RECEIPT_PEND } }, { method: 'eth_getTransactionReceipt', reply: { result: RECEIPT_DONE } }, @@ -266,7 +266,7 @@ describe('api/contract/Contract', () => { }); it('passes the options through to postTransaction (incl. gas calculation)', () => { - expect(scope.body.eth_postTransaction.params).to.deep.equal([ + expect(scope.body.parity_postTransaction.params).to.deep.equal([ { data: '0x123', gas: '0x4b0' } ]); }); @@ -280,8 +280,8 @@ describe('api/contract/Contract', () => { it('fails when gasUsed == gas', () => { mockHttp([ { method: 'eth_estimateGas', reply: { result: 1000 } }, - { method: 'eth_postTransaction', reply: { result: '0x678' } }, - { method: 'eth_checkRequest', reply: { result: '0x789' } }, + { method: 'parity_postTransaction', reply: { result: '0x678' } }, + { method: 'parity_checkRequest', reply: { result: '0x789' } }, { method: 'eth_getTransactionReceipt', reply: { result: RECEIPT_EXCP } } ]); @@ -295,8 +295,8 @@ describe('api/contract/Contract', () => { it('fails when no code was deployed', () => { mockHttp([ { method: 'eth_estimateGas', reply: { result: 1000 } }, - { method: 'eth_postTransaction', reply: { result: '0x678' } }, - { method: 'eth_checkRequest', reply: { result: '0x789' } }, + { method: 'parity_postTransaction', reply: { result: '0x678' } }, + { method: 'parity_checkRequest', reply: { result: '0x789' } }, { method: 'eth_getTransactionReceipt', reply: { result: RECEIPT_DONE } }, { method: 'eth_getCode', reply: { result: '0x' } } ]); @@ -360,15 +360,15 @@ describe('api/contract/Contract', () => { describe('postTransaction', () => { beforeEach(() => { - scope = mockHttp([{ method: 'eth_postTransaction', reply: { result: ['hashId'] } }]); + scope = mockHttp([{ method: 'parity_postTransaction', reply: { result: ['hashId'] } }]); }); - it('encodes options and mades an eth_postTransaction call', () => { + it('encodes options and mades an parity_postTransaction call', () => { return func .postTransaction({ someExtras: 'foo' }, VALUES) .then(() => { expect(scope.isDone()).to.be.true; - expect(scope.body.eth_postTransaction.params[0]).to.deep.equal({ + expect(scope.body.parity_postTransaction.params[0]).to.deep.equal({ someExtras: 'foo', to: ADDR, data: ENCODED diff --git a/js/src/api/rpc/eth/eth.js b/js/src/api/rpc/eth/eth.js index 703f3ed11..43f8025e1 100644 --- a/js/src/api/rpc/eth/eth.js +++ b/js/src/api/rpc/eth/eth.js @@ -39,11 +39,6 @@ export default class Eth { .execute('eth_call', inOptions(options), inBlockNumber(blockNumber)); } - checkRequest (requestId) { - return this._transport - .execute('eth_checkRequest', inNumber16(requestId)); - } - coinbase () { return this._transport .execute('eth_coinbase') @@ -267,11 +262,6 @@ export default class Eth { .execute('eth_pendingTransactions'); } - postTransaction (options) { - return this._transport - .execute('eth_postTransaction', inOptions(options)); - } - protocolVersion () { return this._transport .execute('eth_protocolVersion'); diff --git a/js/src/api/rpc/ethcore/ethcore.js b/js/src/api/rpc/ethcore/ethcore.js deleted file mode 100644 index e21c83193..000000000 --- a/js/src/api/rpc/ethcore/ethcore.js +++ /dev/null @@ -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 . - -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); - } -} diff --git a/js/src/api/rpc/index.js b/js/src/api/rpc/index.js index e7e94b9ed..7961da81c 100644 --- a/js/src/api/rpc/index.js +++ b/js/src/api/rpc/index.js @@ -16,9 +16,10 @@ export Db from './db'; export Eth from './eth'; -export Ethcore from './ethcore'; +export Parity from './parity'; export Net from './net'; export Personal from './personal'; export Shh from './shh'; +export Signer from './signer'; export Trace from './trace'; export Web3 from './web3'; diff --git a/js/src/api/rpc/ethcore/index.js b/js/src/api/rpc/parity/index.js similarity index 95% rename from js/src/api/rpc/ethcore/index.js rename to js/src/api/rpc/parity/index.js index 2372a2171..38f08f725 100644 --- a/js/src/api/rpc/ethcore/index.js +++ b/js/src/api/rpc/parity/index.js @@ -14,4 +14,4 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -export default from './ethcore'; +export default from './parity'; diff --git a/js/src/api/rpc/ethcore/ethcore.e2e.js b/js/src/api/rpc/parity/parity.e2e.js similarity index 82% rename from js/src/api/rpc/ethcore/ethcore.e2e.js rename to js/src/api/rpc/parity/parity.e2e.js index aae7108e7..91e01ab6a 100644 --- a/js/src/api/rpc/ethcore/ethcore.e2e.js +++ b/js/src/api/rpc/parity/parity.e2e.js @@ -16,12 +16,12 @@ import { createHttpApi } from '../../../../test/e2e/ethapi'; -describe('ethapi.ethcore', () => { +describe('ethapi.parity', () => { const ethapi = createHttpApi(); describe('gasFloorTarget', () => { it('returns and translates the target', () => { - return ethapi.ethcore.gasFloorTarget().then((value) => { + return ethapi.parity.gasFloorTarget().then((value) => { expect(value.gt(0)).to.be.true; }); }); @@ -29,7 +29,7 @@ describe('ethapi.ethcore', () => { describe('gasPriceHistogram', () => { it('returns and translates the target', () => { - return ethapi.ethcore.gasPriceHistogram().then((result) => { + return ethapi.parity.gasPriceHistogram().then((result) => { expect(Object.keys(result)).to.deep.equal(['bucketBounds', 'counts']); expect(result.bucketBounds.length > 0).to.be.true; expect(result.counts.length > 0).to.be.true; @@ -39,7 +39,7 @@ describe('ethapi.ethcore', () => { describe('netChain', () => { it('returns and the chain', () => { - return ethapi.ethcore.netChain().then((value) => { + return ethapi.parity.netChain().then((value) => { expect(value).to.equal('morden'); }); }); @@ -47,7 +47,7 @@ describe('ethapi.ethcore', () => { describe('netPort', () => { it('returns and translates the port', () => { - return ethapi.ethcore.netPort().then((value) => { + return ethapi.parity.netPort().then((value) => { expect(value.gt(0)).to.be.true; }); }); @@ -55,7 +55,7 @@ describe('ethapi.ethcore', () => { describe('transactionsLimit', () => { it('returns and translates the limit', () => { - return ethapi.ethcore.transactionsLimit().then((value) => { + return ethapi.parity.transactionsLimit().then((value) => { expect(value.gt(0)).to.be.true; }); }); @@ -63,7 +63,7 @@ describe('ethapi.ethcore', () => { describe('rpcSettings', () => { it('returns and translates the settings', () => { - return ethapi.ethcore.rpcSettings().then((value) => { + return ethapi.parity.rpcSettings().then((value) => { expect(value).to.be.ok; }); }); diff --git a/js/src/api/rpc/parity/parity.js b/js/src/api/rpc/parity/parity.js new file mode 100644 index 000000000..f1739f848 --- /dev/null +++ b/js/src/api/rpc/parity/parity.js @@ -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 . + +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); + } +} diff --git a/js/src/api/rpc/ethcore/ethcore.spec.js b/js/src/api/rpc/parity/parity.spec.js similarity index 66% rename from js/src/api/rpc/ethcore/ethcore.spec.js rename to js/src/api/rpc/parity/parity.spec.js index fd34550a7..ea0dd8d8c 100644 --- a/js/src/api/rpc/ethcore/ethcore.spec.js +++ b/js/src/api/rpc/parity/parity.spec.js @@ -18,14 +18,36 @@ import { TEST_HTTP_URL, mockHttp } from '../../../../test/mockRpc'; import { isBigNumber } from '../../../../test/types'; import Http from '../../transport/http'; -import Ethcore from './ethcore'; +import Parity from './parity'; -const instance = new Ethcore(new Http(TEST_HTTP_URL)); +const instance = new Parity(new Http(TEST_HTTP_URL)); + +describe('api/rpc/parity', () => { + describe('accountsInfo', () => { + it('retrieves the available account info', () => { + mockHttp([{ method: 'parity_accountsInfo', reply: { + result: { + '0x63cf90d3f0410092fc0fca41846f596223979195': { + name: 'name', uuid: 'uuid', meta: '{"data":"data"}' + } + } + } }]); + + return instance.accountsInfo().then((result) => { + expect(result).to.deep.equal({ + '0x63Cf90D3f0410092FC0fca41846f596223979195': { + name: 'name', uuid: 'uuid', meta: { + data: 'data' + } + } + }); + }); + }); + }); -describe('api/rpc/Ethcore', () => { describe('gasFloorTarget', () => { it('returns the gasfloor, formatted', () => { - mockHttp([{ method: 'ethcore_gasFloorTarget', reply: { result: '0x123456' } }]); + mockHttp([{ method: 'parity_gasFloorTarget', reply: { result: '0x123456' } }]); return instance.gasFloorTarget().then((count) => { expect(isBigNumber(count)).to.be.true; @@ -36,7 +58,7 @@ describe('api/rpc/Ethcore', () => { describe('minGasPrice', () => { it('returns the min gasprice, formatted', () => { - mockHttp([{ method: 'ethcore_minGasPrice', reply: { result: '0x123456' } }]); + mockHttp([{ method: 'parity_minGasPrice', reply: { result: '0x123456' } }]); return instance.minGasPrice().then((count) => { expect(isBigNumber(count)).to.be.true; @@ -47,7 +69,7 @@ describe('api/rpc/Ethcore', () => { describe('netMaxPeers', () => { it('returns the max peers, formatted', () => { - mockHttp([{ method: 'ethcore_netMaxPeers', reply: { result: 25 } }]); + mockHttp([{ method: 'parity_netMaxPeers', reply: { result: 25 } }]); return instance.netMaxPeers().then((count) => { expect(isBigNumber(count)).to.be.true; @@ -58,7 +80,7 @@ describe('api/rpc/Ethcore', () => { describe('newPeers', () => { it('returns the peer structure, formatted', () => { - mockHttp([{ method: 'ethcore_netPeers', reply: { result: { active: 123, connected: 456, max: 789 } } }]); + mockHttp([{ method: 'parity_netPeers', reply: { result: { active: 123, connected: 456, max: 789 } } }]); return instance.netPeers().then((peers) => { expect(peers.active.eq(123)).to.be.true; @@ -70,7 +92,7 @@ describe('api/rpc/Ethcore', () => { describe('netPort', () => { it('returns the connected port, formatted', () => { - mockHttp([{ method: 'ethcore_netPort', reply: { result: 33030 } }]); + mockHttp([{ method: 'parity_netPort', reply: { result: 33030 } }]); return instance.netPort().then((count) => { expect(isBigNumber(count)).to.be.true; @@ -81,7 +103,7 @@ describe('api/rpc/Ethcore', () => { describe('transactionsLimit', () => { it('returns the tx limit, formatted', () => { - mockHttp([{ method: 'ethcore_transactionsLimit', reply: { result: 1024 } }]); + mockHttp([{ method: 'parity_transactionsLimit', reply: { result: 1024 } }]); return instance.transactionsLimit().then((count) => { expect(isBigNumber(count)).to.be.true; diff --git a/js/src/api/rpc/personal/personal.js b/js/src/api/rpc/personal/personal.js index ca7dbce9b..db9a71d23 100644 --- a/js/src/api/rpc/personal/personal.js +++ b/js/src/api/rpc/personal/personal.js @@ -14,113 +14,31 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -import { inAddress, inHex, inNumber10, inNumber16, inOptions } from '../../format/input'; -import { outAccountInfo, outAddress, outSignerRequest } from '../../format/output'; +import { inAddress, inNumber10, inOptions } from '../../format/input'; +import { outAddress } from '../../format/output'; export default class Personal { constructor (transport) { this._transport = transport; } - accountsInfo () { - return this._transport - .execute('personal_accountsInfo') - .then(outAccountInfo); - } - - confirmRequest (requestId, options, password) { - return this._transport - .execute('personal_confirmRequest', inNumber16(requestId), options, password); - } - - changePassword (account, password, newPassword) { - return this._transport - .execute('personal_changePassword', inAddress(account), password, newPassword); - } - - generateAuthorizationToken () { - return this._transport - .execute('personal_generateAuthorizationToken'); - } - listAccounts () { return this._transport .execute('personal_listAccounts') .then((accounts) => (accounts || []).map(outAddress)); } - listGethAccounts () { - return this._transport - .execute('personal_listGethAccounts') - .then((accounts) => (accounts || []).map(outAddress)); - } - - importGethAccounts (accounts) { - return this._transport - .execute('personal_importGethAccounts', (accounts || []).map(inAddress)) - .then((accounts) => (accounts || []).map(outAddress)); - } - newAccount (password) { return this._transport .execute('personal_newAccount', password) .then(outAddress); } - newAccountFromPhrase (phrase, password) { - return this._transport - .execute('personal_newAccountFromPhrase', phrase, password) - .then(outAddress); - } - - newAccountFromSecret (secret, password) { - return this._transport - .execute('personal_newAccountFromSecret', inHex(secret), password) - .then(outAddress); - } - - newAccountFromWallet (json, password) { - return this._transport - .execute('personal_newAccountFromWallet', json, password) - .then(outAddress); - } - - rejectRequest (requestId) { - return this._transport - .execute('personal_rejectRequest', inNumber16(requestId)); - } - - requestsToConfirm () { - return this._transport - .execute('personal_requestsToConfirm') - .then((requests) => (requests || []).map(outSignerRequest)); - } - - setAccountName (address, name) { - return this._transport - .execute('personal_setAccountName', inAddress(address), name); - } - - setAccountMeta (address, meta) { - return this._transport - .execute('personal_setAccountMeta', inAddress(address), JSON.stringify(meta)); - } - signAndSendTransaction (options, password) { return this._transport .execute('personal_signAndSendTransaction', inOptions(options), password); } - signerEnabled () { - return this._transport - .execute('personal_signerEnabled'); - } - - testPassword (account, password) { - return this._transport - .execute('personal_testPassword', inAddress(account), password); - } - unlockAccount (account, password, duration = 1) { return this._transport .execute('personal_unlockAccount', inAddress(account), password, inNumber10(duration)); diff --git a/js/src/api/rpc/personal/personal.spec.js b/js/src/api/rpc/personal/personal.spec.js index 70734c7ee..a9bf4f644 100644 --- a/js/src/api/rpc/personal/personal.spec.js +++ b/js/src/api/rpc/personal/personal.spec.js @@ -26,28 +26,6 @@ describe('rpc/Personal', () => { const checksum = '0x63Cf90D3f0410092FC0fca41846f596223979195'; let scope; - describe('accountsInfo', () => { - it('retrieves the available account info', () => { - scope = mockHttp([{ method: 'personal_accountsInfo', reply: { - result: { - '0x63cf90d3f0410092fc0fca41846f596223979195': { - name: 'name', uuid: 'uuid', meta: '{"data":"data"}' - } - } - } }]); - - return instance.accountsInfo().then((result) => { - expect(result).to.deep.equal({ - '0x63Cf90D3f0410092FC0fca41846f596223979195': { - name: 'name', uuid: 'uuid', meta: { - data: 'data' - } - } - }); - }); - }); - }); - describe('listAccounts', () => { it('retrieves a list of available accounts', () => { scope = mockHttp([{ method: 'personal_listAccounts', reply: { result: [account] } }]); diff --git a/js/src/api/rpc/signer/index.js b/js/src/api/rpc/signer/index.js new file mode 100644 index 000000000..6426bdc06 --- /dev/null +++ b/js/src/api/rpc/signer/index.js @@ -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 . + +export default from './signer'; diff --git a/js/src/api/rpc/signer/signer.js b/js/src/api/rpc/signer/signer.js new file mode 100644 index 000000000..7f905cf50 --- /dev/null +++ b/js/src/api/rpc/signer/signer.js @@ -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 . + +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'); + } +} diff --git a/js/src/api/subscriptions/manager.js b/js/src/api/subscriptions/manager.js index 61e06499e..08f1a9e53 100644 --- a/js/src/api/subscriptions/manager.js +++ b/js/src/api/subscriptions/manager.js @@ -24,9 +24,9 @@ import Signer from './signer'; const events = { 'logging': { module: 'logging' }, 'eth_blockNumber': { module: 'eth' }, - 'personal_accountsInfo': { module: 'personal' }, - 'personal_listAccounts': { module: 'personal' }, - 'personal_requestsToConfirm': { module: 'signer' } + 'parity_accountsInfo': { module: 'personal' }, + 'eth_accounts': { module: 'personal' }, + 'signer_requestsToConfirm': { module: 'signer' } }; export default class Manager { diff --git a/js/src/api/subscriptions/personal.js b/js/src/api/subscriptions/personal.js index d65419962..58428895b 100644 --- a/js/src/api/subscriptions/personal.js +++ b/js/src/api/subscriptions/personal.js @@ -37,18 +37,18 @@ export default class Personal { } _listAccounts = () => { - return this._api.personal - .listAccounts() + return this._api.eth + .accounts() .then((accounts) => { - this._updateSubscriptions('personal_listAccounts', null, accounts); + this._updateSubscriptions('eth_accounts', null, accounts); }); } _accountsInfo = () => { - return this._api.personal + return this._api.parity .accountsInfo() .then((info) => { - this._updateSubscriptions('personal_accountsInfo', null, info); + this._updateSubscriptions('parity_accountsInfo', null, info); }); } @@ -59,16 +59,16 @@ export default class Personal { } switch (data.method) { - case 'personal_importGethAccounts': + case 'parity_importGethAccounts': case 'personal_newAccount': - case 'personal_newAccountFromPhrase': - case 'personal_newAccountFromWallet': + case 'parity_newAccountFromPhrase': + case 'parity_newAccountFromWallet': this._listAccounts(); this._accountsInfo(); return; - case 'personal_setAccountName': - case 'personal_setAccountMeta': + case 'parity_setAccountName': + case 'parity_setAccountMeta': this._accountsInfo(); return; } diff --git a/js/src/api/subscriptions/personal.spec.js b/js/src/api/subscriptions/personal.spec.js index 1a77b5f61..d6fd2b203 100644 --- a/js/src/api/subscriptions/personal.spec.js +++ b/js/src/api/subscriptions/personal.spec.js @@ -34,14 +34,15 @@ function stubApi (accounts, info) { return { _calls, - personal: { + parity: { accountsInfo: () => { const stub = sinon.stub().resolves(info || TEST_INFO)(); _calls.accountsInfo.push(stub); return stub; - }, - - listAccounts: () => { + } + }, + eth: { + accounts: () => { const stub = sinon.stub().resolves(accounts || TEST_LIST)(); _calls.listAccounts.push(stub); return stub; @@ -85,17 +86,17 @@ describe('api/subscriptions/personal', () => { expect(personal.isStarted).to.be.true; }); - it('calls personal_accountsInfo', () => { + it('calls parity_accountsInfo', () => { expect(api._calls.accountsInfo.length).to.be.ok; }); - it('calls personal_listAccounts', () => { + it('calls eth_accounts', () => { expect(api._calls.listAccounts.length).to.be.ok; }); it('updates subscribers', () => { - expect(cb.firstCall).to.have.been.calledWith('personal_listAccounts', null, TEST_LIST); - expect(cb.secondCall).to.have.been.calledWith('personal_accountsInfo', null, TEST_INFO); + expect(cb.firstCall).to.have.been.calledWith('eth_accounts', null, TEST_LIST); + expect(cb.secondCall).to.have.been.calledWith('parity_accountsInfo', null, TEST_INFO); }); }); diff --git a/js/src/api/subscriptions/signer.js b/js/src/api/subscriptions/signer.js index af745261b..4413fe432 100644 --- a/js/src/api/subscriptions/signer.js +++ b/js/src/api/subscriptions/signer.js @@ -49,10 +49,10 @@ export default class Signer { return; } - return this._api.personal + return this._api.signer .requestsToConfirm() .then((requests) => { - this._updateSubscriptions('personal_requestsToConfirm', null, requests); + this._updateSubscriptions('signer_requestsToConfirm', null, requests); nextTimeout(); }) .catch(nextTimeout); @@ -65,7 +65,7 @@ export default class Signer { } switch (data.method) { - case 'eth_postTransaction': + case 'parity_postTransaction': case 'eth_sendTranasction': case 'eth_sendRawTransaction': this._listRequests(false); diff --git a/js/src/api/transport/http/http.js b/js/src/api/transport/http/http.js index 65ba089cc..08d9422f8 100644 --- a/js/src/api/transport/http/http.js +++ b/js/src/api/transport/http/http.js @@ -56,6 +56,8 @@ export default class Http extends JsonRpcBase { if (response.status !== 200) { this._connected = false; this.error(JSON.stringify({ status: response.status, statusText: response.statusText })); + console.error(`${method}(${JSON.stringify(params)}): ${response.status}: ${response.statusText}`); + throw new Error(`${response.status}: ${response.statusText}`); } @@ -66,7 +68,9 @@ export default class Http extends JsonRpcBase { if (response.error) { this.error(JSON.stringify(response)); - throw new Error(`${response.error.code}: ${response.error.message}`); + console.error(`${method}(${JSON.stringify(params)}): ${response.error.code}: ${response.error.message}`); + + throw new Error(`${method}: ${response.error.code}: ${response.error.message}`); } this.log(JSON.stringify(response)); diff --git a/js/src/api/transport/ws/ws.js b/js/src/api/transport/ws/ws.js index 119f4ba76..d608426b0 100644 --- a/js/src/api/transport/ws/ws.js +++ b/js/src/api/transport/ws/ws.js @@ -107,7 +107,9 @@ export default class Ws extends JsonRpcBase { if (result.error) { this.error(event.data); - reject(new Error(`${result.error.code}: ${result.error.message}`)); + console.error(`${method}(${JSON.stringify(params)}): ${result.error.code}: ${result.error.message}`); + + reject(new Error(`${method}: ${result.error.code}: ${result.error.message}`)); delete this._messages[result.id]; return; } diff --git a/js/src/contracts/registry.js b/js/src/contracts/registry.js index 85b9d6bb5..9853c0df9 100644 --- a/js/src/contracts/registry.js +++ b/js/src/contracts/registry.js @@ -32,7 +32,7 @@ export default class Registry { return; } - this._api.ethcore + this._api.parity .registryAddress() .then((address) => { this._instance = this._api.newContract(abis.registry, address).instance; diff --git a/js/src/dapps/basiccoin/Application/application.js b/js/src/dapps/basiccoin/Application/application.js index 4ab97ab6c..abe0c90c5 100644 --- a/js/src/dapps/basiccoin/Application/application.js +++ b/js/src/dapps/basiccoin/Application/application.js @@ -83,7 +83,7 @@ export default class Application extends Component { Promise .all([ attachInstances(), - api.personal.accountsInfo() + api.parity.accounts() ]) .then(([{ managerInstance, registryInstance, tokenregInstance }, accountsInfo]) => { accountsInfo = accountsInfo || {}; diff --git a/js/src/dapps/basiccoin/Deploy/Deployment/deployment.js b/js/src/dapps/basiccoin/Deploy/Deployment/deployment.js index f9232789b..0fa7dc863 100644 --- a/js/src/dapps/basiccoin/Deploy/Deployment/deployment.js +++ b/js/src/dapps/basiccoin/Deploy/Deployment/deployment.js @@ -296,7 +296,7 @@ export default class Deployment extends Component { .then((signerRequestId) => { this.setState({ signerRequestId, deployState: 'Transaction posted, Waiting for transaction authorization' }); - return api.pollMethod('eth_checkRequest', signerRequestId); + return api.pollMethod('parity_checkRequest', signerRequestId); }) .then((txHash) => { this.setState({ txHash, deployState: 'Transaction authorized, Waiting for network confirmations' }); diff --git a/js/src/dapps/basiccoin/Transfer/Send/send.js b/js/src/dapps/basiccoin/Transfer/Send/send.js index aee860fe2..a9c05a228 100644 --- a/js/src/dapps/basiccoin/Transfer/Send/send.js +++ b/js/src/dapps/basiccoin/Transfer/Send/send.js @@ -279,7 +279,7 @@ export default class Send extends Component { .then((signerRequestId) => { this.setState({ signerRequestId, sendState: 'Transaction posted, Waiting for transaction authorization' }); - return api.pollMethod('eth_checkRequest', signerRequestId); + return api.pollMethod('parity_checkRequest', signerRequestId); }) .then((txHash) => { this.setState({ txHash, sendState: 'Transaction authorized, Waiting for network confirmations' }); diff --git a/js/src/dapps/basiccoin/services.js b/js/src/dapps/basiccoin/services.js index 28cc662a7..4aed4199f 100644 --- a/js/src/dapps/basiccoin/services.js +++ b/js/src/dapps/basiccoin/services.js @@ -100,8 +100,8 @@ export function attachInstances () { return Promise .all([ - api.ethcore.registryAddress(), - api.ethcore.netChain() + api.parity.registryAddress(), + api.parity.netChain() ]) .then(([registryAddress, netChain]) => { const registry = api.newContract(abis.registry, registryAddress).instance; diff --git a/js/src/dapps/githubhint.html b/js/src/dapps/githubhint.html index 631182fcb..746c7f466 100644 --- a/js/src/dapps/githubhint.html +++ b/js/src/dapps/githubhint.html @@ -11,7 +11,6 @@
- diff --git a/js/src/dapps/githubhint/Application/application.js b/js/src/dapps/githubhint/Application/application.js index 4a25d3855..5a7494928 100644 --- a/js/src/dapps/githubhint/Application/application.js +++ b/js/src/dapps/githubhint/Application/application.js @@ -41,7 +41,9 @@ export default class Application extends Component { registerBusy: false, registerError: null, registerState: '', - registerType: 'file' + registerType: 'file', + repo: '', + repoError: null } componentDidMount () { @@ -206,47 +208,64 @@ export default class Application extends Component { } onChangeCommit = (event) => { - const commit = event.target.value; + let commit = event.target.value; const commitError = null; + let hasContent = false; - // TODO: field validation + this.setState({ commit, commitError, contentHashError: null }, () => { + const { repo } = this.state || ''; + const parts = repo.split('/'); - this.setState({ commit, commitError, contentHashError: 'hash lookup in progress' }, () => { - const { repo } = this.state; - this.lookupHash(`https://codeload.github.com/${repo}/zip/${commit}`); + hasContent = commit.length !== 0 && parts.length === 2 && parts[0].length !== 0 && parts[1].length !== 0; + if (!commitError && hasContent) { + this.setState({ contentHashError: 'hash lookup in progress' }); + this.lookupHash(`https://codeload.github.com/${repo}/zip/${commit}`); + } }); } onChangeRepo = (event) => { let repo = event.target.value; const repoError = null; + let hasContent = false; // TODO: field validation if (!repoError) { repo = repo.replace('https://github.com/', ''); } - this.setState({ repo, repoError, contentHashError: 'hash lookup in progress' }, () => { - const { commit } = this.state; - this.lookupHash(`https://codeload.github.com/${repo}/zip/${commit}`); + this.setState({ repo, repoError, contentHashError: null }, () => { + const { commit } = this.state || ''; + const parts = repo.split('/'); + + hasContent = commit.length !== 0 && parts.length === 2 && parts[0].length !== 0 && parts[1].length !== 0; + if (!repoError && hasContent) { + this.setState({ contentHashError: 'hash lookup in progress' }); + this.lookupHash(`https://codeload.github.com/${repo}/zip/${commit}`); + } }); } onChangeUrl = (event) => { let url = event.target.value; const urlError = null; + let hasContent = false; // TODO: field validation if (!urlError) { const parts = url.split('/'); + hasContent = parts.length !== 0; if (parts[2] === 'github.com' || parts[2] === 'raw.githubusercontent.com') { url = `https://raw.githubusercontent.com/${parts.slice(3).join('/')}`.replace('/blob/', '/'); } } - this.setState({ url, urlError, contentHashError: 'hash lookup in progress' }, () => { - this.lookupHash(url); + this.setState({ url, urlError, contentHashError: null }, () => { + if (!urlError && hasContent) { + this.setState({ contentHashError: 'hash lookup in progress' }); + this.lookupHash(url); + } }); } @@ -271,7 +290,7 @@ export default class Application extends Component { .then((signerRequestId) => { this.setState({ signerRequestId, registerState: 'Transaction posted, Waiting for transaction authorization' }); - return api.pollMethod('eth_checkRequest', signerRequestId); + return api.pollMethod('parity_checkRequest', signerRequestId); }) .then((txHash) => { this.setState({ txHash, registerState: 'Transaction authorized, Waiting for network confirmations' }); @@ -285,7 +304,7 @@ export default class Application extends Component { }); }) .then((txReceipt) => { - this.setState({ txReceipt, registerBusy: false, registerState: 'Network confirmed, Received transaction receipt', url: '', commit: '', commitError: null, contentHash: '', contentHashOwner: null, contentHashError: null }); + this.setState({ txReceipt, registerBusy: false, registerState: 'Network confirmed, Received transaction receipt', url: '', commit: '', repo: '', commitError: null, contentHash: '', contentHashOwner: null, contentHashError: null }); }) .catch((error) => { console.error('onSend', error); @@ -298,7 +317,7 @@ export default class Application extends Component { this.setState({ registerBusy: true, registerState: 'Estimating gas for the transaction' }); - const values = [contentHash, repo, commit]; + const values = [contentHash, repo, commit.substr(0, 2) === '0x' ? commit : `0x${commit}`]; const options = { from: fromAddress }; this.trackRequest( @@ -367,7 +386,7 @@ export default class Application extends Component { console.log(`lookupHash ${url}`); - api.ethcore + api.parity .hashContent(url) .then((contentHash) => { console.log('lookupHash', contentHash); diff --git a/js/src/dapps/githubhint/parity.js b/js/src/dapps/githubhint/parity.js index f6d59f44d..acee4dee0 100644 --- a/js/src/dapps/githubhint/parity.js +++ b/js/src/dapps/githubhint/parity.js @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -const { api } = window.parity; +const api = window.parent.secureApi; export { api diff --git a/js/src/dapps/githubhint/services.js b/js/src/dapps/githubhint/services.js index b7676d5f5..c9d260b73 100644 --- a/js/src/dapps/githubhint/services.js +++ b/js/src/dapps/githubhint/services.js @@ -18,7 +18,7 @@ import * as abis from '../../contracts/abi'; import { api } from './parity'; export function attachInterface () { - return api.ethcore + return api.parity .registryAddress() .then((registryAddress) => { console.log(`the registry was found at ${registryAddress}`); @@ -29,7 +29,7 @@ export function attachInterface () { .all([ registry.getAddress.call({}, [api.util.sha3('githubhint'), 'A']), api.eth.accounts(), - api.personal.accountsInfo() + api.parity.accounts() ]); }) .then(([address, addresses, accountsInfo]) => { diff --git a/js/src/dapps/registry/actions.js b/js/src/dapps/registry/actions.js index 882af0360..b1390926b 100644 --- a/js/src/dapps/registry/actions.js +++ b/js/src/dapps/registry/actions.js @@ -29,7 +29,7 @@ export { addresses, accounts, lookup, events, names, records }; export const setContract = (contract) => ({ type: 'set contract', contract }); export const fetchContract = () => (dispatch) => - api.ethcore.registryAddress() + api.parity.registryAddress() .then((address) => { const contract = api.newContract(registryAbi, address); dispatch(setContract(contract)); diff --git a/js/src/dapps/registry/addresses/actions.js b/js/src/dapps/registry/addresses/actions.js index 17975f9e6..2341d716c 100644 --- a/js/src/dapps/registry/addresses/actions.js +++ b/js/src/dapps/registry/addresses/actions.js @@ -22,7 +22,7 @@ export const fetch = () => (dispatch) => { return Promise .all([ api.eth.accounts(), - api.personal.accountsInfo() + api.parity.accounts() ]) .then(([ accounts, data ]) => { data = data || {}; diff --git a/js/src/dapps/signaturereg/services.js b/js/src/dapps/signaturereg/services.js index cab324f7e..54394c4b8 100644 --- a/js/src/dapps/signaturereg/services.js +++ b/js/src/dapps/signaturereg/services.js @@ -39,7 +39,7 @@ const logToEvent = (log) => { }; export function attachInterface (callback) { - return api.ethcore + return api.parity .registryAddress() .then((registryAddress) => { console.log(`the registry was found at ${registryAddress}`); @@ -50,7 +50,7 @@ export function attachInterface (callback) { .all([ registry.getAddress.call({}, [api.util.sha3('signaturereg'), 'A']), api.eth.accounts(), - api.personal.accountsInfo() + api.parity.accounts() ]); }) .then(([address, addresses, accountsInfo]) => { diff --git a/js/src/dapps/tokenreg/Accounts/actions.js b/js/src/dapps/tokenreg/Accounts/actions.js index f501399c2..58a74dfd8 100644 --- a/js/src/dapps/tokenreg/Accounts/actions.js +++ b/js/src/dapps/tokenreg/Accounts/actions.js @@ -38,7 +38,7 @@ export const loadAccounts = () => (dispatch) => { Promise .all([ api.eth.accounts(), - api.personal.accountsInfo() + api.parity.accounts() ]) .then(([ accounts, accountsInfo ]) => { accountsInfo = accountsInfo || {}; diff --git a/js/src/dapps/tokenreg/Status/actions.js b/js/src/dapps/tokenreg/Status/actions.js index b7de9c108..e9e217d6a 100644 --- a/js/src/dapps/tokenreg/Status/actions.js +++ b/js/src/dapps/tokenreg/Status/actions.js @@ -34,7 +34,7 @@ export const FIND_CONTRACT = 'FIND_CONTRACT'; export const loadContract = () => (dispatch) => { dispatch(setLoading(true)); - api.ethcore + api.parity .registryAddress() .then((registryAddress) => { console.log(`registry found at ${registryAddress}`); diff --git a/js/src/index.js b/js/src/index.js index 8782438c9..9a4ad2e1a 100644 --- a/js/src/index.js +++ b/js/src/index.js @@ -72,7 +72,7 @@ ReactDOM.render( - + diff --git a/js/src/jsonrpc/index.js b/js/src/jsonrpc/index.js index 18bd4302d..9e9692279 100644 --- a/js/src/jsonrpc/index.js +++ b/js/src/jsonrpc/index.js @@ -16,20 +16,22 @@ import db from './interfaces/db'; import eth from './interfaces/eth'; -import ethcore from './interfaces/ethcore'; import net from './interfaces/net'; +import parity from './interfaces/parity'; import personal from './interfaces/personal'; import shh from './interfaces/shh'; +import signer from './interfaces/signer'; import trace from './interfaces/trace'; import web3 from './interfaces/web3'; export default { - db: db, - eth: eth, - ethcore: ethcore, - net: net, - personal: personal, - shh: shh, - trace: trace, - web3: web3 + db, + eth, + parity, + net, + personal, + shh, + signer, + trace, + web3 }; diff --git a/js/src/jsonrpc/interfaces/eth.js b/js/src/jsonrpc/interfaces/eth.js index f1c8fb86f..d5ff471fb 100644 --- a/js/src/jsonrpc/interfaces/eth.js +++ b/js/src/jsonrpc/interfaces/eth.js @@ -86,20 +86,6 @@ export default { } }, - checkRequest: { - desc: 'Returns the transactionhash of the requestId (received from eth_postTransaction) if the request was confirmed', - params: [ - { - type: Quantity, - desc: 'The requestId to check for' - } - ], - returns: { - type: Hash, - desc: '32 Bytes - the transaction hash, or the zero hash if the transaction is not yet available' - } - }, - coinbase: { desc: 'Returns the client coinbase address.', params: [], @@ -823,22 +809,6 @@ export default { } }, - postTransaction: { - desc: 'Posts a transaction to the Signer.', - params: [ - { - type: Object, - desc: 'see [eth_sendTransaction](#eth_sendTransaction)', - format: 'inputCallFormatter' - } - ], - returns: { - type: Quantity, - desc: 'The id of the actual transaction', - format: 'utils.toDecimal' - } - }, - protocolVersion: { desc: 'Returns the current ethereum protocol version.', params: [], diff --git a/js/src/jsonrpc/interfaces/ethcore.js b/js/src/jsonrpc/interfaces/parity.js similarity index 66% rename from js/src/jsonrpc/interfaces/ethcore.js rename to js/src/jsonrpc/interfaces/parity.js index 310276cc8..66a8ea962 100644 --- a/js/src/jsonrpc/interfaces/ethcore.js +++ b/js/src/jsonrpc/interfaces/parity.js @@ -26,6 +26,52 @@ export default { } }, + accounts: { + desc: 'returns a map of accounts as an object', + params: [], + returns: { + type: Array, + desc: 'Account metadata', + details: { + name: { + type: String, + desc: 'Account name' + }, + meta: { + type: String, + desc: 'Encoded JSON string the defines additional account metadata' + }, + uuid: { + type: String, + desc: 'The account UUID, or null if not available/unknown/not applicable.' + } + } + } + }, + + accountsInfo: { + desc: 'returns a map of accounts as an object', + params: [], + returns: { + type: Array, + desc: 'Account metadata', + details: { + name: { + type: String, + desc: 'Account name' + }, + meta: { + type: String, + desc: 'Encoded JSON string the defines additional account metadata' + }, + uuid: { + type: String, + desc: 'The account UUID, or null if not available/unknown/not applicable.' + } + } + } + }, + addReservedPeer: { desc: '?', params: [ @@ -40,6 +86,20 @@ export default { } }, + checkRequest: { + desc: 'Returns the transactionhash of the requestId (received from parity_postTransaction) if the request was confirmed', + params: [ + { + type: Quantity, + desc: 'The requestId to check for' + } + ], + returns: { + type: Hash, + desc: '32 Bytes - the transaction hash, or the zero hash if the transaction is not yet available' + } + }, + dappsPort: { desc: 'Returns the port the dapps are running on, error if not enabled', params: [], @@ -155,6 +215,29 @@ export default { } }, + listGethAccounts: { + desc: 'Returns a list of the accounts available from Geth', + params: [], + returns: { + type: Array, + desc: '20 Bytes addresses owned by the client.' + } + }, + + importGethAccounts: { + desc: 'Imports a list of accounts from geth', + params: [ + { + type: Array, + desc: 'List of the geth addresses to import' + } + ], + returns: { + type: Array, + desc: 'Array of the imported addresses' + } + }, + minGasPrice: { desc: 'Returns currently set minimal gas price', params: [], @@ -210,6 +293,60 @@ export default { } }, + newAccountFromPhrase: { + desc: 'Creates a new account from a recovery passphrase', + params: [ + { + type: String, + desc: 'Phrase' + }, + { + type: String, + desc: 'Password' + } + ], + returns: { + type: Address, + desc: 'The created address' + } + }, + + newAccountFromSecret: { + desc: 'Creates a new account from a private ethstore secret key', + params: [ + { + type: Data, + desc: 'Secret, 32-byte hex' + }, + { + type: String, + desc: 'Password' + } + ], + returns: { + type: Address, + desc: 'The created address' + } + }, + + newAccountFromWallet: { + desc: 'Creates a new account from a JSON import', + params: [ + { + type: String, + desc: 'JSON' + }, + { + type: String, + desc: 'Password' + } + ], + returns: { + type: Address, + desc: 'The created address' + } + }, + nodeName: { desc: 'Returns node name (identity)', params: [], @@ -233,6 +370,22 @@ export default { } }, + postTransaction: { + desc: 'Posts a transaction to the Signer.', + params: [ + { + type: Object, + desc: 'see [eth_sendTransaction](#eth_sendTransaction)', + format: 'inputCallFormatter' + } + ], + returns: { + type: Quantity, + desc: 'The id of the actual transaction', + format: 'utils.toDecimal' + } + }, + removeReservedPeer: { desc: '?', params: [ @@ -265,6 +418,42 @@ export default { } }, + setAccountName: { + desc: 'Sets a name for the account', + params: [ + { + type: Address, + desc: 'Address' + }, + { + type: String, + desc: 'Name' + } + ], + returns: { + type: Object, + desc: 'Returns null in all cases' + } + }, + + setAccountMeta: { + desc: 'Sets metadata for the account', + params: [ + { + type: Address, + desc: 'Address' + }, + { + type: String, + desc: 'Metadata (JSON encoded)' + } + ], + returns: { + type: Object, + desc: 'Returns null in all cases' + } + }, + setAuthor: { desc: 'Changes author (coinbase) for mined blocks.', params: [ diff --git a/js/src/jsonrpc/interfaces/personal.js b/js/src/jsonrpc/interfaces/personal.js index 2a9ce7c19..eb7e5fc0f 100644 --- a/js/src/jsonrpc/interfaces/personal.js +++ b/js/src/jsonrpc/interfaces/personal.js @@ -17,83 +17,6 @@ import { Address, Data, Quantity } from '../types'; export default { - accountsInfo: { - desc: 'returns a map of accounts as an object', - params: [], - returns: { - type: Array, - desc: 'Account metadata', - details: { - name: { - type: String, - desc: 'Account name' - }, - meta: { - type: String, - desc: 'Encoded JSON string the defines additional account metadata' - }, - uuid: { - type: String, - desc: 'The account UUID, or null if not available/unknown/not applicable.' - } - } - } - }, - - generateAuthorizationToken: { - desc: 'Generates a new authorization token', - params: [], - returns: { - type: String, - desc: 'The new authorization token' - } - }, - - requestsToConfirm: { - desc: 'Returns a list of the transactions requiring authorization', - params: [], - returns: { - type: Array, - desc: 'A list of the outstanding transactions' - } - }, - - confirmRequest: { - desc: 'Confirm a request in the signer queue', - params: [ - { - type: Quantity, - desc: 'The request id' - }, - { - type: Object, - desc: 'The request options' - }, - { - type: String, - desc: 'The account password' - } - ], - returns: { - type: Boolean, - desc: 'The status of the confirmation' - } - }, - - rejectRequest: { - desc: 'Rejects a request in the signer queue', - params: [ - { - type: Quantity, - desc: 'The request id' - } - ], - returns: { - type: Boolean, - desc: 'The status of the rejection' - } - }, - listAccounts: { desc: 'Returns a list of addresses owned by client.', params: [], @@ -103,29 +26,6 @@ export default { } }, - listGethAccounts: { - desc: 'Returns a list of the accounts available from Geth', - params: [], - returns: { - type: Array, - desc: '20 Bytes addresses owned by the client.' - } - }, - - importGethAccounts: { - desc: 'Imports a list of accounts from geth', - params: [ - { - type: Array, - desc: 'List of the geth addresses to import' - } - ], - returns: { - type: Array, - desc: 'Array of the imported addresses' - } - }, - newAccount: { desc: 'Creates new account', params: [ @@ -140,96 +40,6 @@ export default { } }, - newAccountFromPhrase: { - desc: 'Creates a new account from a recovery passphrase', - params: [ - { - type: String, - desc: 'Phrase' - }, - { - type: String, - desc: 'Password' - } - ], - returns: { - type: Address, - desc: 'The created address' - } - }, - - newAccountFromSecret: { - desc: 'Creates a new account from a private ethstore secret key', - params: [ - { - type: Data, - desc: 'Secret, 32-byte hex' - }, - { - type: String, - desc: 'Password' - } - ], - returns: { - type: Address, - desc: 'The created address' - } - }, - - newAccountFromWallet: { - desc: 'Creates a new account from a JSON import', - params: [ - { - type: String, - desc: 'JSON' - }, - { - type: String, - desc: 'Password' - } - ], - returns: { - type: Address, - desc: 'The created address' - } - }, - - setAccountName: { - desc: 'Sets a name for the account', - params: [ - { - type: Address, - desc: 'Address' - }, - { - type: String, - desc: 'Name' - } - ], - returns: { - type: Object, - desc: 'Returns null in all cases' - } - }, - - setAccountMeta: { - desc: 'Sets metadata for the account', - params: [ - { - type: Address, - desc: 'Address' - }, - { - type: String, - desc: 'Metadata (JSON encoded)' - } - ], - returns: { - type: Object, - desc: 'Returns null in all cases' - } - }, - signAndSendTransaction: { desc: 'Sends and signs a transaction given account passphrase. Does not require the account to be unlocked nor unlocks the account for future transactions. ', params: [ @@ -284,15 +94,6 @@ export default { } }, - signerEnabled: { - desc: 'Returns whether signer is enabled/disabled.', - params: [], - returns: { - type: Boolean, - desc: 'true when enabled, false when disabled' - } - }, - unlockAccount: { desc: '?', params: [ diff --git a/js/src/jsonrpc/interfaces/signer.js b/js/src/jsonrpc/interfaces/signer.js new file mode 100644 index 000000000..f394dbb61 --- /dev/null +++ b/js/src/jsonrpc/interfaces/signer.js @@ -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 . + +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' + } + } +}; diff --git a/js/src/modals/AddAddress/addAddress.js b/js/src/modals/AddAddress/addAddress.js index ebcf78815..c8845aa13 100644 --- a/js/src/modals/AddAddress/addAddress.js +++ b/js/src/modals/AddAddress/addAddress.js @@ -133,8 +133,8 @@ export default class AddAddress extends Component { const { address, name, description } = this.state; Promise.all([ - api.personal.setAccountName(address, name), - api.personal.setAccountMeta(address, { + api.parity.setAccountName(address, name), + api.parity.setAccountMeta(address, { description, timestamp: Date.now(), deleted: false diff --git a/js/src/modals/AddContract/addContract.js b/js/src/modals/AddContract/addContract.js index ad7345430..418378136 100644 --- a/js/src/modals/AddContract/addContract.js +++ b/js/src/modals/AddContract/addContract.js @@ -141,8 +141,8 @@ export default class AddContract extends Component { const { abiParsed, address, name, description } = this.state; Promise.all([ - api.personal.setAccountName(address, name), - api.personal.setAccountMeta(address, { + api.parity.setAccountName(address, name), + api.parity.setAccountMeta(address, { contract: true, deleted: false, timestamp: Date.now(), diff --git a/js/src/modals/CreateAccount/NewAccount/newAccount.js b/js/src/modals/CreateAccount/NewAccount/newAccount.js index b05a6db75..2fde79ca6 100644 --- a/js/src/modals/CreateAccount/NewAccount/newAccount.js +++ b/js/src/modals/CreateAccount/NewAccount/newAccount.js @@ -173,15 +173,15 @@ export default class CreateAccount extends Component { Promise .all([ - api.ethcore.generateSecretPhrase(), - api.ethcore.generateSecretPhrase(), - api.ethcore.generateSecretPhrase(), - api.ethcore.generateSecretPhrase(), - api.ethcore.generateSecretPhrase() + api.parity.generateSecretPhrase(), + api.parity.generateSecretPhrase(), + api.parity.generateSecretPhrase(), + api.parity.generateSecretPhrase(), + api.parity.generateSecretPhrase() ]) .then((phrases) => { return Promise - .all(phrases.map((phrase) => api.ethcore.phraseToAddress(phrase))) + .all(phrases.map((phrase) => api.parity.phraseToAddress(phrase))) .then((addresses) => { const accounts = {}; diff --git a/js/src/modals/CreateAccount/NewGeth/newGeth.js b/js/src/modals/CreateAccount/NewGeth/newGeth.js index 8853a671b..4b6cc2c96 100644 --- a/js/src/modals/CreateAccount/NewGeth/newGeth.js +++ b/js/src/modals/CreateAccount/NewGeth/newGeth.js @@ -102,7 +102,7 @@ export default class NewGeth extends Component { const { api } = this.context; const { accounts } = this.props; - api.personal + api.parity .listGethAccounts() .then((_addresses) => { const addresses = (addresses || []).filter((address) => !accounts[address]); diff --git a/js/src/modals/CreateAccount/createAccount.js b/js/src/modals/CreateAccount/createAccount.js index aacc91d5e..283e91531 100644 --- a/js/src/modals/CreateAccount/createAccount.js +++ b/js/src/modals/CreateAccount/createAccount.js @@ -208,13 +208,13 @@ export default class CreateAccount extends Component { }); if (createType === 'fromNew' || createType === 'fromPhrase') { - return api.personal + return api.parity .newAccountFromPhrase(this.state.phrase, this.state.password) .then((address) => { this.setState({ address }); - return api.personal + return api.parity .setAccountName(address, this.state.name) - .then(() => api.personal.setAccountMeta(address, { + .then(() => api.parity.setAccountMeta(address, { timestamp: Date.now(), passwordHint: this.state.passwordHint })); @@ -233,13 +233,13 @@ export default class CreateAccount extends Component { this.newError(error); }); } else if (createType === 'fromRaw') { - return api.personal + return api.parity .newAccountFromSecret(this.state.rawKey, this.state.password) .then((address) => { this.setState({ address }); - return api.personal + return api.parity .setAccountName(address, this.state.name) - .then(() => api.personal.setAccountMeta(address, { + .then(() => api.parity.setAccountMeta(address, { timestamp: Date.now(), passwordHint: this.state.passwordHint })); @@ -258,13 +258,13 @@ export default class CreateAccount extends Component { this.newError(error); }); } else if (createType === 'fromGeth') { - return api.personal + return api.parity .importGethAccounts(this.state.gethAddresses) .then((result) => { console.log('result', result); return Promise.all(this.state.gethAddresses.map((address) => { - return api.personal.setAccountName(address, 'Geth Import'); + return api.parity.setAccountName(address, 'Geth Import'); })); }) .then(() => { @@ -282,16 +282,16 @@ export default class CreateAccount extends Component { }); } - return api.personal + return api.parity .newAccountFromWallet(this.state.json, this.state.password) .then((address) => { this.setState({ address: address }); - return api.personal + return api.parity .setAccountName(address, this.state.name) - .then(() => api.personal.setAccountMeta(address, { + .then(() => api.parity.setAccountMeta(address, { timestamp: Date.now(), passwordHint: this.state.passwordHint })); diff --git a/js/src/modals/DeployContract/deployContract.js b/js/src/modals/DeployContract/deployContract.js index c62b968b5..cec1b9d90 100644 --- a/js/src/modals/DeployContract/deployContract.js +++ b/js/src/modals/DeployContract/deployContract.js @@ -212,8 +212,8 @@ export default class DeployContract extends Component { .deploy(options, params, this.onDeploymentState) .then((address) => { return Promise.all([ - api.personal.setAccountName(address, name), - api.personal.setAccountMeta(address, { + api.parity.setAccountName(address, name), + api.parity.setAccountMeta(address, { abi: abiParsed, contract: true, timestamp: Date.now(), diff --git a/js/src/modals/EditMeta/editMeta.js b/js/src/modals/EditMeta/editMeta.js index b2ba89d61..ad893aa17 100644 --- a/js/src/modals/EditMeta/editMeta.js +++ b/js/src/modals/EditMeta/editMeta.js @@ -139,8 +139,8 @@ export default class EditMeta extends Component { Promise .all([ - api.personal.setAccountName(account.address, name), - api.personal.setAccountMeta(account.address, Object.assign({}, account.meta, meta)) + api.parity.setAccountName(account.address, name), + api.parity.setAccountMeta(account.address, Object.assign({}, account.meta, meta)) ]) .then(() => this.props.onClose()) .catch((error) => { diff --git a/js/src/modals/ExecuteContract/executeContract.js b/js/src/modals/ExecuteContract/executeContract.js index e0462982d..b45cf6875 100644 --- a/js/src/modals/ExecuteContract/executeContract.js +++ b/js/src/modals/ExecuteContract/executeContract.js @@ -221,7 +221,7 @@ export default class ExecuteContract extends Component { }) .then((requestId) => { this.setState({ busyState: 'Waiting for authorization in the Parity Signer' }); - return api.pollMethod('eth_checkRequest', requestId); + return api.pollMethod('parity_checkRequest', requestId); }) .then((txhash) => { this.setState({ sending: false, step: 2, txhash, busyState: 'Your transaction has been posted to the network' }); diff --git a/js/src/modals/FirstRun/firstRun.js b/js/src/modals/FirstRun/firstRun.js index ea49e852e..3a676fc3b 100644 --- a/js/src/modals/FirstRun/firstRun.js +++ b/js/src/modals/FirstRun/firstRun.js @@ -183,9 +183,9 @@ export default class FirstRun extends Component { canCreate: false }); - return api.personal + return api.parity .newAccountFromPhrase(phrase, password) - .then((address) => api.personal.setAccountName(address, name)) + .then((address) => api.parity.setAccountName(address, name)) .then(() => { this.onNext(); }) diff --git a/js/src/modals/PasswordManager/passwordManager.js b/js/src/modals/PasswordManager/passwordManager.js index 368664a71..aabf691ef 100644 --- a/js/src/modals/PasswordManager/passwordManager.js +++ b/js/src/modals/PasswordManager/passwordManager.js @@ -317,7 +317,7 @@ export default class PasswordManager extends Component { this.setState({ waiting: true, showMessage: false }); this.context - .api.personal + .api.parity .testPassword(account.address, currentPass) .then(correct => { const message = correct @@ -343,7 +343,7 @@ export default class PasswordManager extends Component { this.setState({ waiting: true, showMessage: false }); this.context - .api.personal + .api.parity .testPassword(account.address, currentPass) .then(correct => { if (!correct) { @@ -363,11 +363,11 @@ export default class PasswordManager extends Component { return Promise.all([ this.context - .api.personal + .api.parity .setAccountMeta(account.address, meta), this.context - .api.personal + .api.parity .changePassword(account.address, currentPass, newPass) ]) .then(() => { diff --git a/js/src/modals/Transfer/Details/details.js b/js/src/modals/Transfer/Details/details.js index f7cc70ad4..decd69c3c 100644 --- a/js/src/modals/Transfer/Details/details.js +++ b/js/src/modals/Transfer/Details/details.js @@ -123,7 +123,13 @@ export default class Details extends Component { .map((balance, index) => { const token = balance.token; const isEth = index === 0; - const imagesrc = token.image || images[token.address] || imageUnknown; + let imagesrc = token.image; + if (!imagesrc) { + imagesrc = + images[token.address] + ? `${api.dappsUrl}${images[token.address]}` + : imageUnknown; + } let value = 0; if (isEth) { diff --git a/js/src/modals/Transfer/transfer.js b/js/src/modals/Transfer/transfer.js index b505ad0ae..506e91930 100644 --- a/js/src/modals/Transfer/transfer.js +++ b/js/src/modals/Transfer/transfer.js @@ -424,7 +424,7 @@ export default class Transfer extends Component { options.data = data; } - return api.eth.postTransaction(options); + return api.parity.postTransaction(options); } _sendToken () { @@ -455,7 +455,7 @@ export default class Transfer extends Component { : this._sendToken() ).then((requestId) => { this.setState({ busyState: 'Waiting for authorization in the Parity Signer' }); - return api.pollMethod('eth_checkRequest', requestId); + return api.pollMethod('parity_checkRequest', requestId); }) .then((txhash) => { this.onNext(); @@ -592,7 +592,7 @@ export default class Transfer extends Component { Promise .all([ - api.ethcore.gasPriceHistogram(), + api.parity.gasPriceHistogram(), api.eth.gasPrice() ]) .then(([gasPriceHistogram, gasPrice]) => { diff --git a/js/src/redux/providers/balances.js b/js/src/redux/providers/balances.js index fa60e4310..b80fad28f 100644 --- a/js/src/redux/providers/balances.js +++ b/js/src/redux/providers/balances.js @@ -42,7 +42,7 @@ export default class Balances { _subscribeAccountsInfo () { this._api - .subscribe('personal_accountsInfo', (error, accountsInfo) => { + .subscribe('parity_accountsInfo', (error, accountsInfo) => { if (error) { return; } @@ -76,7 +76,7 @@ export default class Balances { } _retrieveTokens () { - this._api.ethcore + this._api.parity .registryAddress() .then((registryAddress) => { const registry = this._api.newContract(abis.registry, registryAddress); diff --git a/js/src/redux/providers/imagesReducer.js b/js/src/redux/providers/imagesReducer.js index 15745932d..396576cc8 100644 --- a/js/src/redux/providers/imagesReducer.js +++ b/js/src/redux/providers/imagesReducer.js @@ -17,8 +17,6 @@ import { handleActions } from 'redux-actions'; import { bytesToHex } from '../../api/util/format'; -import { parityNode } from '../../environment'; - const ZERO = '0x0000000000000000000000000000000000000000000000000000000000000000'; const initialState = { @@ -28,7 +26,7 @@ const initialState = { export function hashToImageUrl (hashArray) { const hash = hashArray ? bytesToHex(hashArray) : ZERO; - return hash === ZERO ? null : `${parityNode}/api/content/${hash.substr(2)}`; + return hash === ZERO ? null : `/api/content/${hash.substr(2)}`; } export default handleActions({ diff --git a/js/src/redux/providers/personal.js b/js/src/redux/providers/personal.js index e75b4082b..fd67ab5f7 100644 --- a/js/src/redux/providers/personal.js +++ b/js/src/redux/providers/personal.js @@ -28,9 +28,9 @@ export default class Personal { _subscribeAccountsInfo () { this._api - .subscribe('personal_accountsInfo', (error, accountsInfo) => { + .subscribe('parity_accountsInfo', (error, accountsInfo) => { if (error) { - console.error('personal_accountsInfo', error); + console.error('parity_accountsInfo', error); return; } diff --git a/js/src/redux/providers/signer.js b/js/src/redux/providers/signer.js index 92f80d51e..5ece371c2 100644 --- a/js/src/redux/providers/signer.js +++ b/js/src/redux/providers/signer.js @@ -14,22 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -// 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 . - import { signerRequestsToConfirm } from './signerActions'; export default class Signer { @@ -44,7 +28,7 @@ export default class Signer { _subscribeRequestsToConfirm () { this._api - .subscribe('personal_requestsToConfirm', (error, pending) => { + .subscribe('signer_requestsToConfirm', (error, pending) => { if (error) { return; } diff --git a/js/src/redux/providers/signerMiddleware.js b/js/src/redux/providers/signerMiddleware.js index 53144e454..6d09eeb4e 100644 --- a/js/src/redux/providers/signerMiddleware.js +++ b/js/src/redux/providers/signerMiddleware.js @@ -51,7 +51,7 @@ export default class SignerMiddleware { onConfirmStart = (store, action) => { const { id, password } = action.payload; - this._api.personal + this._api.signer .confirmRequest(id, {}, password) .then((txHash) => { console.log('confirmRequest', id, txHash); @@ -71,7 +71,7 @@ export default class SignerMiddleware { onRejectStart = (store, action) => { const id = action.payload; - this._api.personal + this._api.signer .rejectRequest(id) .then(() => { store.dispatch(actions.successRejectRequest({ id })); diff --git a/js/src/redux/providers/status.js b/js/src/redux/providers/status.js index 658f54197..0e2bf6866 100644 --- a/js/src/redux/providers/status.js +++ b/js/src/redux/providers/status.js @@ -16,8 +16,6 @@ import { statusBlockNumber, statusCollection, statusLogs } from './statusActions'; -import { parityNode } from '../../environment'; - export default class Status { constructor (store, api) { this._api = api; @@ -33,8 +31,8 @@ export default class Status { } _fetchEnode () { - this._api - .ethcore.enode() + this._api.parity + .enode() .then((enode) => { this._store.dispatch(statusCollection({ enode })); }) @@ -65,7 +63,7 @@ export default class Status { setTimeout(this._pollPing, timeout); }; - fetch(`${parityNode}/api/ping`, { method: 'GET' }) + fetch('/', { method: 'HEAD' }) .then((response) => dispatch(!!response.ok)) .catch(() => dispatch(false)); } @@ -103,16 +101,16 @@ export default class Status { .all([ this._api.web3.clientVersion(), this._api.eth.coinbase(), - this._api.ethcore.defaultExtraData(), - this._api.ethcore.extraData(), - this._api.ethcore.gasFloorTarget(), + this._api.parity.defaultExtraData(), + this._api.parity.extraData(), + this._api.parity.gasFloorTarget(), this._api.eth.hashrate(), - this._api.ethcore.minGasPrice(), - this._api.ethcore.netChain(), - this._api.ethcore.netPeers(), - this._api.ethcore.netPort(), - this._api.ethcore.nodeName(), - this._api.ethcore.rpcSettings(), + this._api.parity.minGasPrice(), + this._api.parity.netChain(), + this._api.parity.netPeers(), + this._api.parity.netPort(), + this._api.parity.nodeName(), + this._api.parity.rpcSettings(), this._api.eth.syncing(), this._pollTraceMode() ]) @@ -155,8 +153,8 @@ export default class Status { Promise .all([ - this._api.ethcore.devLogs(), - this._api.ethcore.devLogsLevels() + this._api.parity.devLogs(), + this._api.parity.devLogsLevels() ]) .then(([devLogs, devLogsLevels]) => { this._store.dispatch(statusLogs({ diff --git a/js/src/secureApi.js b/js/src/secureApi.js index 545cfd459..2f03d62e9 100644 --- a/js/src/secureApi.js +++ b/js/src/secureApi.js @@ -25,6 +25,8 @@ export default class SecureApi extends Api { this._isConnecting = true; this._connectState = 0; this._needsToken = false; + this._dappsPort = 8080; + this._signerPort = 8180; this._followConnection(); } @@ -50,7 +52,7 @@ export default class SecureApi extends Api { case 0: if (isConnected) { this._isConnecting = false; - return this.setToken(); + return this.connectSuccess(); } else if (lastError) { this.updateToken('initial', 1); } @@ -60,7 +62,7 @@ export default class SecureApi extends Api { case 1: if (isConnected) { this._connectState = 2; - this.personal + this.parity .generateAuthorizationToken() .then((token) => { this.updateToken(token, 2); @@ -79,7 +81,7 @@ export default class SecureApi extends Api { case 2: if (isConnected) { this._isConnecting = false; - return this.setToken(); + return this.connectSuccess(); } else if (lastError) { return setManual(); } @@ -89,12 +91,38 @@ export default class SecureApi extends Api { nextTick(); } + connectSuccess () { + this.setToken(); + + Promise + .all([ + this.parity.dappsPort(), + this.parity.signerPort() + ]) + .then(([dappsPort, signerPort]) => { + this._dappsPort = dappsPort.toNumber(); + this._signerPort = signerPort.toNumber(); + }); + } + updateToken (token, connectedState = 0) { this._connectState = connectedState; this._transport.updateToken(token.replace(/[^a-zA-Z0-9]/g, '')); this._followConnection(); } + get dappsPort () { + return this._dappsPort; + } + + get dappsUrl () { + return `http://127.0.0.1:${this._dappsPort}`; + } + + get signerPort () { + return this._signerPort; + } + get isConnecting () { return this._isConnecting; } diff --git a/js/src/ui/Balance/balance.js b/js/src/ui/Balance/balance.js index b6f786648..22b9fc1ae 100644 --- a/js/src/ui/Balance/balance.js +++ b/js/src/ui/Balance/balance.js @@ -47,7 +47,13 @@ class Balance extends Component { const value = token.format ? new BigNumber(balance.value).div(new BigNumber(token.format)).toFormat(3) : api.util.fromWei(balance.value).toFormat(3); - const imagesrc = token.image || images[token.address] || unknownImage; + let imagesrc = token.image; + if (!imagesrc) { + imagesrc = + images[token.address] + ? `${api.dappsUrl}${images[token.address]}` + : unknownImage; + } return (
{ - api.personal + api.parity .setAccountName(account.address, name) .catch((error) => { console.error(error); diff --git a/js/src/views/Address/Delete/delete.js b/js/src/views/Address/Delete/delete.js index 66e6edb95..8aeaf48e2 100644 --- a/js/src/views/Address/Delete/delete.js +++ b/js/src/views/Address/Delete/delete.js @@ -81,7 +81,7 @@ class Delete extends Component { account.meta.deleted = true; - api.personal + api.parity .setAccountMeta(account.address, account.meta) .then(() => { router.push(route); diff --git a/js/src/views/Application/application.js b/js/src/views/Application/application.js index 6b38f90d8..d49aa5d90 100644 --- a/js/src/views/Application/application.js +++ b/js/src/views/Application/application.js @@ -104,8 +104,8 @@ class Application extends Component { checkAccounts () { const { api } = this.context; - api.personal - .listAccounts() + api.eth + .accounts() .then((accounts) => { this.setState({ showFirstRun: showFirstRun || accounts.length === 0 diff --git a/js/src/views/Dapp/dapp.js b/js/src/views/Dapp/dapp.js index 3cc096f66..7f5f36d1d 100644 --- a/js/src/views/Dapp/dapp.js +++ b/js/src/views/Dapp/dapp.js @@ -16,20 +16,54 @@ import React, { Component, PropTypes } from 'react'; +import Contracts from '../../contracts'; +import { fetchAvailable } from '../Dapps/registry'; + import styles from './dapp.css'; -const dapphost = process.env.NODE_ENV === 'production' ? 'http://127.0.0.1:8080/ui' : ''; - export default class Dapp extends Component { + static contextTypes = { + api: PropTypes.object.isRequired + } + static propTypes = { params: PropTypes.object }; + state = { + app: null + } + + componentWillMount () { + this.lookup(); + } + render () { - const { name, type } = this.props.params; - const src = (type === 'builtin') - ? `${dapphost}/${name}.html` - : `http://127.0.0.1:8080/${name}/`; + const { app } = this.state; + const { dappsUrl } = this.context.api; + + if (!app) { + return null; + } + + let src = null; + switch (app.type) { + case 'builtin': + const dapphost = process.env.NODE_ENV === 'production' && !app.secure + ? `${dappsUrl}/ui` + : ''; + src = `${dapphost}/${app.url}.html`; + break; + case 'local': + src = `${dappsUrl}/${app.id}/`; + break; + case 'network': + src = `${dappsUrl}/${app.contentHash}/`; + break; + default: + console.error('unknown type', app.type); + break; + } return (