diff --git a/js/src/api/format/output.js b/js/src/api/format/output.js index dd61c82b1..dc8421516 100644 --- a/js/src/api/format/output.js +++ b/js/src/api/format/output.js @@ -17,6 +17,7 @@ import BigNumber from 'bignumber.js'; import { toChecksumAddress } from '../../abi/util/address'; +import { isString } from '../util/types'; export function outAccountInfo (infos) { return Object @@ -344,3 +345,17 @@ export function outTraceReplay (trace) { return trace; } + +export function outVaultMeta (meta) { + if (isString(meta)) { + try { + const obj = JSON.parse(meta); + + return obj; + } catch (error) { + return {}; + } + } + + return meta || {}; +} diff --git a/js/src/api/format/output.spec.js b/js/src/api/format/output.spec.js index d744a642c..504cc0687 100644 --- a/js/src/api/format/output.spec.js +++ b/js/src/api/format/output.spec.js @@ -16,7 +16,7 @@ import BigNumber from 'bignumber.js'; -import { outBlock, outAccountInfo, outAddress, outChainStatus, outDate, outHistogram, outNumber, outPeer, outPeers, outReceipt, outSyncing, outTransaction, outTrace } from './output'; +import { outBlock, outAccountInfo, outAddress, outChainStatus, outDate, outHistogram, outNumber, outPeer, outPeers, outReceipt, outSyncing, outTransaction, outTrace, outVaultMeta } from './output'; import { isAddress, isBigNumber, isInstanceOf } from '../../../test/types'; describe('api/format/output', () => { @@ -455,4 +455,22 @@ describe('api/format/output', () => { expect(formatted.transactionPosition.toNumber()).to.equal(11); }); }); + + describe('outVaultMeta', () => { + it('returns an exmpt object on null', () => { + expect(outVaultMeta(null)).to.deep.equal({}); + }); + + it('returns the original value if not string', () => { + expect(outVaultMeta({ test: 123 })).to.deep.equal({ test: 123 }); + }); + + it('returns an object from JSON string', () => { + expect(outVaultMeta('{"test":123}')).to.deep.equal({ test: 123 }); + }); + + it('returns an empty object on invalid JSON', () => { + expect(outVaultMeta('{"test"}')).to.deep.equal({}); + }); + }); }); diff --git a/js/src/api/rpc/parity/parity.js b/js/src/api/rpc/parity/parity.js index 160e7513a..7001a9c49 100644 --- a/js/src/api/rpc/parity/parity.js +++ b/js/src/api/rpc/parity/parity.js @@ -15,7 +15,7 @@ // along with Parity. If not, see . import { inAddress, inAddresses, inData, inHex, inNumber16, inOptions, inBlockNumber } from '../../format/input'; -import { outAccountInfo, outAddress, outAddresses, outChainStatus, outHistogram, outNumber, outPeers, outTransaction } from '../../format/output'; +import { outAccountInfo, outAddress, outAddresses, outChainStatus, outHistogram, outNumber, outPeers, outTransaction, outVaultMeta } from '../../format/output'; export default class Parity { constructor (transport) { @@ -55,11 +55,26 @@ export default class Parity { .execute('parity_changePassword', inAddress(account), password, newPassword); } + changeVault (account, vaultName) { + return this._transport + .execute('parity_changeVault', inAddress(account), vaultName); + } + + changeVaultPassword (vaultName, password) { + return this._transport + .execute('parity_changeVaultPassword', vaultName, password); + } + checkRequest (requestId) { return this._transport .execute('parity_checkRequest', inNumber16(requestId)); } + closeVault (vaultName) { + return this._transport + .execute('parity_closeVault', vaultName); + } + consensusCapability () { return this._transport .execute('parity_consensusCapability'); @@ -167,6 +182,12 @@ export default class Parity { .then((addresses) => addresses ? addresses.map(outAddress) : null); } + getVaultMeta (vaultName) { + return this._transport + .execute('parity_getVaultMeta', vaultName) + .then(outVaultMeta); + } + hashContent (url) { return this._transport .execute('parity_hashContent', url); @@ -189,6 +210,16 @@ export default class Parity { .then((accounts) => (accounts || []).map(outAddress)); } + listOpenedVaults () { + return this._transport + .execute('parity_listOpenedVaults'); + } + + listVaults () { + return this._transport + .execute('parity_listVaults'); + } + listRecentDapps () { return this._transport .execute('parity_listRecentDapps'); @@ -275,6 +306,11 @@ export default class Parity { .then(outAddress); } + newVault (vaultName, password) { + return this._transport + .execute('parity_newVault', vaultName, password); + } + nextNonce (account) { return this._transport .execute('parity_nextNonce', inAddress(account)) @@ -286,6 +322,11 @@ export default class Parity { .execute('parity_nodeName'); } + openVault (vaultName, password) { + return this._transport + .execute('parity_openVault', vaultName, password); + } + pendingTransactions () { return this._transport .execute('parity_pendingTransactions') @@ -399,6 +440,11 @@ export default class Parity { .execute('parity_setTransactionsLimit', inNumber16(quantity)); } + setVaultMeta (vaultName, meta) { + return this._transport + .execute('parity_setVaultMeta', vaultName, JSON.stringify(meta)); + } + signerPort () { return this._transport .execute('parity_signerPort') diff --git a/js/src/api/subscriptions/personal.js b/js/src/api/subscriptions/personal.js index 1574dcacc..4f386b7c8 100644 --- a/js/src/api/subscriptions/personal.js +++ b/js/src/api/subscriptions/personal.js @@ -104,11 +104,14 @@ export default class Personal { } switch (data.method) { + case 'parity_closeVault': + case 'parity_openVault': case 'parity_killAccount': case 'parity_importGethAccounts': - case 'personal_newAccount': case 'parity_newAccountFromPhrase': case 'parity_newAccountFromWallet': + case 'personal_newAccount': + this._defaultAccount(true); this._listAccounts(); this._accountsInfo(); return; @@ -116,6 +119,7 @@ export default class Personal { case 'parity_removeAddress': case 'parity_setAccountName': case 'parity_setAccountMeta': + case 'parity_changeVault': this._accountsInfo(); return; diff --git a/js/src/jsonrpc/interfaces/parity.js b/js/src/jsonrpc/interfaces/parity.js index 97e52fe73..978c77f88 100644 --- a/js/src/jsonrpc/interfaces/parity.js +++ b/js/src/jsonrpc/interfaces/parity.js @@ -17,11 +17,12 @@ import { Address, Data, Hash, Quantity, BlockNumber, TransactionRequest } from '../types'; import { fromDecimal, withComment, Dummy } from '../helpers'; -const SECTION_MINING = 'Block Authoring (aka "mining")'; -const SECTION_DEV = 'Development'; -const SECTION_NODE = 'Node Settings'; -const SECTION_NET = 'Network Information'; const SECTION_ACCOUNTS = 'Accounts (read-only) and Signatures'; +const SECTION_DEV = 'Development'; +const SECTION_MINING = 'Block Authoring (aka "mining")'; +const SECTION_NET = 'Network Information'; +const SECTION_NODE = 'Node Settings'; +const SECTION_VAULT = 'Account Vaults'; const SUBDOC_SET = 'set'; const SUBDOC_ACCOUNTS = 'accounts'; @@ -151,6 +152,67 @@ export default { } }, + changeVault: { + section: SECTION_VAULT, + desc: 'Changes the current valut for the account', + params: [ + { + type: Address, + desc: 'Account address', + example: '0x63Cf90D3f0410092FC0fca41846f596223979195' + }, + { + type: String, + desc: 'Vault name', + example: 'StrongVault' + } + ], + returns: { + type: Boolean, + desc: 'True on success', + example: true + } + }, + + changeVaultPassword: { + section: SECTION_VAULT, + desc: 'Changes the password for any given vault', + params: [ + { + type: String, + desc: 'Vault name', + example: 'StrongVault' + }, + { + type: String, + desc: 'New Password', + example: 'p@55w0rd' + } + ], + returns: { + type: Boolean, + desc: 'True on success', + example: true + } + }, + + closeVault: { + section: SECTION_VAULT, + desc: 'Closes a vault with the given name', + params: [ + { + type: String, + desc: 'Vault name', + example: 'StrongVault' + } + ], + returns: { + type: Boolean, + desc: 'True on success', + example: true + } + }, + consensusCapability: { desc: 'Returns information on current consensus capability.', params: [], @@ -314,6 +376,43 @@ export default { } }, + getVaultMeta: { + section: SECTION_VAULT, + desc: 'Returns the metadata for a specific vault', + params: [ + { + type: String, + desc: 'Vault name', + example: 'StrongVault' + } + ], + returns: { + type: String, + desc: 'The associated JSON metadata for this vault', + example: '{"passwordHint":"something"}' + } + }, + + listOpenedVaults: { + desc: 'Returns a list of all opened vaults', + params: [], + returns: { + type: Array, + desc: 'Names of all opened vaults', + example: "['Personal']" + } + }, + + listVaults: { + desc: 'Returns a list of all available vaults', + params: [], + returns: { + type: Array, + desc: 'Names of all available vaults', + example: "['Personal','Work']" + } + }, + localTransactions: { desc: 'Returns an object of current and past local transactions.', params: [], @@ -430,6 +529,28 @@ export default { } }, + newVault: { + section: SECTION_VAULT, + desc: 'Creates a new vault with the given name & password', + params: [ + { + type: String, + desc: 'Vault name', + example: 'StrongVault' + }, + { + type: String, + desc: 'Password', + example: 'p@55w0rd' + } + ], + returns: { + type: Boolean, + desc: 'True on success', + example: true + } + }, + nextNonce: { section: SECTION_NET, desc: 'Returns next available nonce for transaction from given account. Includes pending block and transaction queue.', @@ -458,6 +579,28 @@ export default { } }, + openVault: { + section: SECTION_VAULT, + desc: 'Opens a vault with the given name & password', + params: [ + { + type: String, + desc: 'Vault name', + example: 'StrongVault' + }, + { + type: String, + desc: 'Password', + example: 'p@55w0rd' + } + ], + returns: { + type: Boolean, + desc: 'True on success', + example: true + } + }, + pendingTransactions: { section: SECTION_NET, desc: 'Returns a list of transactions currently in the queue.', @@ -594,6 +737,28 @@ export default { } }, + setVaultMeta: { + section: SECTION_VAULT, + desc: 'Sets the metadata for a specific vault', + params: [ + { + type: String, + desc: 'Vault name', + example: 'StrongVault' + }, + { + type: String, + desc: 'The metadata as a JSON string', + example: '{"passwordHint":"something"}' + } + ], + returns: { + type: Boolean, + desc: 'The boolean call result, true on success', + example: true + } + }, + signerPort: { section: SECTION_NODE, desc: 'Returns the port the signer is running on, error if not enabled',