Proper default accounts RPCs (#4580)
* Default accounts setting - account provider * RPC support for default accounts * Updating JS code * Rename whitelist to addresses
This commit is contained in:
parent
1949d44d0c
commit
72998d3ce3
@ -23,7 +23,7 @@ use self::stores::{AddressBook, DappsSettingsStore, NewDappsPolicy};
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::time::{Instant, Duration};
|
use std::time::{Instant, Duration};
|
||||||
use util::RwLock;
|
use util::{FixedHash, RwLock};
|
||||||
use ethstore::{SimpleSecretStore, SecretStore, Error as SSError, EthStore, EthMultiStore,
|
use ethstore::{SimpleSecretStore, SecretStore, Error as SSError, EthStore, EthMultiStore,
|
||||||
random_string, SecretVaultRef, StoreAccountRef};
|
random_string, SecretVaultRef, StoreAccountRef};
|
||||||
use ethstore::dir::MemoryDirectory;
|
use ethstore::dir::MemoryDirectory;
|
||||||
@ -241,25 +241,88 @@ impl AccountProvider {
|
|||||||
Ok(accounts.into_iter().map(|a| a.address).collect())
|
Ok(accounts.into_iter().map(|a| a.address).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets a whitelist of accounts exposed for unknown dapps.
|
/// Sets addresses of accounts exposed for unknown dapps.
|
||||||
/// `None` means that all accounts will be visible.
|
/// `None` means that all accounts will be visible.
|
||||||
pub fn set_new_dapps_whitelist(&self, accounts: Option<Vec<Address>>) -> Result<(), Error> {
|
/// If not `None` or empty it will also override default account.
|
||||||
|
pub fn set_new_dapps_addresses(&self, accounts: Option<Vec<Address>>) -> Result<(), Error> {
|
||||||
|
let current_default = self.new_dapps_default_address()?;
|
||||||
|
|
||||||
self.dapps_settings.write().set_policy(match accounts {
|
self.dapps_settings.write().set_policy(match accounts {
|
||||||
None => NewDappsPolicy::AllAccounts,
|
None => NewDappsPolicy::AllAccounts {
|
||||||
|
default: current_default,
|
||||||
|
},
|
||||||
Some(accounts) => NewDappsPolicy::Whitelist(accounts),
|
Some(accounts) => NewDappsPolicy::Whitelist(accounts),
|
||||||
});
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a whitelist of accounts exposed for unknown dapps.
|
/// Gets addresses of accounts exposed for unknown dapps.
|
||||||
/// `None` means that all accounts will be visible.
|
/// `None` means that all accounts will be visible.
|
||||||
pub fn new_dapps_whitelist(&self) -> Result<Option<Vec<Address>>, Error> {
|
pub fn new_dapps_addresses(&self) -> Result<Option<Vec<Address>>, Error> {
|
||||||
Ok(match self.dapps_settings.read().policy() {
|
Ok(match self.dapps_settings.read().policy() {
|
||||||
NewDappsPolicy::AllAccounts => None,
|
NewDappsPolicy::AllAccounts { .. } => None,
|
||||||
NewDappsPolicy::Whitelist(accounts) => Some(accounts),
|
NewDappsPolicy::Whitelist(accounts) => Some(accounts),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets a default account for unknown dapps.
|
||||||
|
/// This account will always be returned as the first one.
|
||||||
|
pub fn set_new_dapps_default_address(&self, address: Address) -> Result<(), Error> {
|
||||||
|
if !self.valid_addresses()?.contains(&address) {
|
||||||
|
return Err(SSError::InvalidAccount.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut settings = self.dapps_settings.write();
|
||||||
|
let new_policy = match settings.policy() {
|
||||||
|
NewDappsPolicy::AllAccounts { .. } => NewDappsPolicy::AllAccounts { default: address },
|
||||||
|
NewDappsPolicy::Whitelist(list) => NewDappsPolicy::Whitelist(Self::insert_default(list, address)),
|
||||||
|
};
|
||||||
|
settings.set_policy(new_policy);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Inserts given address as first in the vector, preventing duplicates.
|
||||||
|
fn insert_default(mut addresses: Vec<Address>, default: Address) -> Vec<Address> {
|
||||||
|
if let Some(position) = addresses.iter().position(|address| address == &default) {
|
||||||
|
addresses.swap(0, position);
|
||||||
|
} else {
|
||||||
|
addresses.insert(0, default);
|
||||||
|
}
|
||||||
|
|
||||||
|
addresses
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a list of accounts that new dapp should see.
|
||||||
|
/// First account is always the default account.
|
||||||
|
fn new_dapps_addresses_list(&self) -> Result<Vec<Address>, Error> {
|
||||||
|
match self.dapps_settings.read().policy() {
|
||||||
|
NewDappsPolicy::AllAccounts { default } => if default.is_zero() {
|
||||||
|
self.accounts()
|
||||||
|
} else {
|
||||||
|
Ok(Self::insert_default(self.accounts()?, default))
|
||||||
|
},
|
||||||
|
NewDappsPolicy::Whitelist(accounts) => {
|
||||||
|
let addresses = self.filter_addresses(accounts)?;
|
||||||
|
if addresses.is_empty() {
|
||||||
|
Ok(vec![self.accounts()?.get(0).cloned().unwrap_or(0.into())])
|
||||||
|
} else {
|
||||||
|
Ok(addresses)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets a default account for new dapps
|
||||||
|
/// Will return zero address in case the default is not set and there are no accounts configured.
|
||||||
|
pub fn new_dapps_default_address(&self) -> Result<Address, Error> {
|
||||||
|
Ok(self.new_dapps_addresses_list()?
|
||||||
|
.get(0)
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or(0.into())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// Gets a list of dapps recently requesting accounts.
|
/// Gets a list of dapps recently requesting accounts.
|
||||||
pub fn recent_dapps(&self) -> Result<HashMap<DappId, u64>, Error> {
|
pub fn recent_dapps(&self) -> Result<HashMap<DappId, u64>, Error> {
|
||||||
Ok(self.dapps_settings.read().recent_dapps())
|
Ok(self.dapps_settings.read().recent_dapps())
|
||||||
@ -272,41 +335,74 @@ impl AccountProvider {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets addresses visile for dapp.
|
/// Gets addresses visible for given dapp.
|
||||||
pub fn dapps_addresses(&self, dapp: DappId) -> Result<Vec<Address>, Error> {
|
pub fn dapp_addresses(&self, dapp: DappId) -> Result<Vec<Address>, Error> {
|
||||||
let dapps = self.dapps_settings.read();
|
let accounts = self.dapps_settings.read().settings().get(&dapp).map(|settings| {
|
||||||
|
(settings.accounts.clone(), settings.default.clone())
|
||||||
|
});
|
||||||
|
|
||||||
let accounts = dapps.settings().get(&dapp).map(|settings| settings.accounts.clone());
|
|
||||||
match accounts {
|
match accounts {
|
||||||
Some(accounts) => Ok(accounts),
|
Some((Some(accounts), Some(default))) => self.filter_addresses(Self::insert_default(accounts, default)),
|
||||||
None => match dapps.policy() {
|
Some((Some(accounts), None)) => self.filter_addresses(accounts),
|
||||||
NewDappsPolicy::AllAccounts => self.accounts(),
|
Some((None, Some(default))) => self.filter_addresses(Self::insert_default(self.new_dapps_addresses_list()?, default)),
|
||||||
NewDappsPolicy::Whitelist(accounts) => self.filter_addresses(accounts),
|
_ => self.new_dapps_addresses_list(),
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns default account for particular dapp falling back to other allowed accounts if necessary.
|
/// Returns default account for particular dapp falling back to other allowed accounts if necessary.
|
||||||
pub fn default_address(&self, dapp: DappId) -> Result<Address, Error> {
|
pub fn dapp_default_address(&self, dapp: DappId) -> Result<Address, Error> {
|
||||||
self.dapps_addresses(dapp)?
|
let dapp_default = self.dapp_addresses(dapp)?
|
||||||
.get(0)
|
.get(0)
|
||||||
.cloned()
|
.cloned();
|
||||||
.ok_or(SSError::InvalidAccount)
|
|
||||||
|
match dapp_default {
|
||||||
|
Some(default) => Ok(default),
|
||||||
|
None => self.new_dapps_default_address(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets addresses visile for dapp.
|
/// Sets default address for given dapp.
|
||||||
pub fn set_dapps_addresses(&self, dapp: DappId, addresses: Vec<Address>) -> Result<(), Error> {
|
/// Does not alter dapp addresses, but this account will always be returned as the first one.
|
||||||
let addresses = self.filter_addresses(addresses)?;
|
pub fn set_dapp_default_address(&self, dapp: DappId, address: Address) -> Result<(), Error> {
|
||||||
self.dapps_settings.write().set_accounts(dapp, addresses);
|
if !self.valid_addresses()?.contains(&address) {
|
||||||
|
return Err(SSError::InvalidAccount.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
self.dapps_settings.write().set_default(dapp, address);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets addresses visible for given dapp.
|
||||||
|
/// If `None` - falls back to dapps addresses
|
||||||
|
/// If not `None` and not empty it will also override default account.
|
||||||
|
pub fn set_dapp_addresses(&self, dapp: DappId, addresses: Option<Vec<Address>>) -> Result<(), Error> {
|
||||||
|
let (addresses, default) = match addresses {
|
||||||
|
Some(addresses) => {
|
||||||
|
let addresses = self.filter_addresses(addresses)?;
|
||||||
|
let default = addresses.get(0).cloned();
|
||||||
|
(Some(addresses), default)
|
||||||
|
},
|
||||||
|
None => (None, None),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut settings = self.dapps_settings.write();
|
||||||
|
if let Some(default) = default {
|
||||||
|
settings.set_default(dapp.clone(), default);
|
||||||
|
}
|
||||||
|
settings.set_accounts(dapp, addresses);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn valid_addresses(&self) -> Result<HashSet<Address>, Error> {
|
||||||
|
Ok(self.addresses_info().into_iter()
|
||||||
|
.map(|(address, _)| address)
|
||||||
|
.chain(self.accounts()?)
|
||||||
|
.collect())
|
||||||
|
}
|
||||||
|
|
||||||
/// Removes addresses that are neither accounts nor in address book.
|
/// Removes addresses that are neither accounts nor in address book.
|
||||||
fn filter_addresses(&self, addresses: Vec<Address>) -> Result<Vec<Address>, Error> {
|
fn filter_addresses(&self, addresses: Vec<Address>) -> Result<Vec<Address>, Error> {
|
||||||
let valid = self.addresses_info().into_iter()
|
let valid = self.valid_addresses()?;
|
||||||
.map(|(address, _)| address)
|
|
||||||
.chain(self.accounts()?)
|
|
||||||
.collect::<HashSet<_>>();
|
|
||||||
|
|
||||||
Ok(addresses.into_iter()
|
Ok(addresses.into_iter()
|
||||||
.filter(|a| valid.contains(&a))
|
.filter(|a| valid.contains(&a))
|
||||||
@ -743,44 +839,92 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_set_dapps_addresses() {
|
fn should_reset_dapp_addresses_to_default() {
|
||||||
|
// given
|
||||||
|
let ap = AccountProvider::transient_provider();
|
||||||
|
let app = DappId("app1".into());
|
||||||
|
// add accounts to address book
|
||||||
|
ap.set_address_name(1.into(), "1".into());
|
||||||
|
ap.set_address_name(2.into(), "2".into());
|
||||||
|
// set `AllAccounts` policy
|
||||||
|
ap.set_new_dapps_addresses(Some(vec![1.into(), 2.into()])).unwrap();
|
||||||
|
assert_eq!(ap.dapp_addresses(app.clone()).unwrap(), vec![1.into(), 2.into()]);
|
||||||
|
|
||||||
|
// Alter and check
|
||||||
|
ap.set_dapp_addresses(app.clone(), Some(vec![1.into(), 3.into()])).unwrap();
|
||||||
|
assert_eq!(ap.dapp_addresses(app.clone()).unwrap(), vec![1.into()]);
|
||||||
|
|
||||||
|
// Reset back to default
|
||||||
|
ap.set_dapp_addresses(app.clone(), None).unwrap();
|
||||||
|
assert_eq!(ap.dapp_addresses(app.clone()).unwrap(), vec![1.into(), 2.into()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_set_dapps_default_address() {
|
||||||
// given
|
// given
|
||||||
let ap = AccountProvider::transient_provider();
|
let ap = AccountProvider::transient_provider();
|
||||||
let app = DappId("app1".into());
|
let app = DappId("app1".into());
|
||||||
// set `AllAccounts` policy
|
// set `AllAccounts` policy
|
||||||
ap.set_new_dapps_whitelist(None).unwrap();
|
ap.set_new_dapps_addresses(None).unwrap();
|
||||||
// add accounts to address book
|
// add accounts to address book
|
||||||
ap.set_address_name(1.into(), "1".into());
|
ap.set_address_name(1.into(), "1".into());
|
||||||
ap.set_address_name(2.into(), "2".into());
|
ap.set_address_name(2.into(), "2".into());
|
||||||
|
|
||||||
// when
|
ap.set_dapp_addresses(app.clone(), Some(vec![1.into(), 2.into(), 3.into()])).unwrap();
|
||||||
ap.set_dapps_addresses(app.clone(), vec![1.into(), 2.into(), 3.into()]).unwrap();
|
assert_eq!(ap.dapp_addresses(app.clone()).unwrap(), vec![1.into(), 2.into()]);
|
||||||
|
assert_eq!(ap.dapp_default_address("app1".into()).unwrap(), 1.into());
|
||||||
|
|
||||||
// then
|
// when setting empty list
|
||||||
assert_eq!(ap.dapps_addresses(app.clone()).unwrap(), vec![1.into(), 2.into()]);
|
ap.set_dapp_addresses(app.clone(), Some(vec![])).unwrap();
|
||||||
|
|
||||||
|
// then default account is intact
|
||||||
|
assert_eq!(ap.dapp_addresses(app.clone()).unwrap(), vec![1.into()]);
|
||||||
|
assert_eq!(ap.dapp_default_address("app1".into()).unwrap(), 1.into());
|
||||||
|
|
||||||
|
// alter default account
|
||||||
|
ap.set_dapp_default_address("app1".into(), 2.into()).unwrap();
|
||||||
|
assert_eq!(ap.dapp_addresses(app.clone()).unwrap(), vec![2.into()]);
|
||||||
|
assert_eq!(ap.dapp_default_address("app1".into()).unwrap(), 2.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_set_dapps_policy() {
|
fn should_set_dapps_policy_and_default_account() {
|
||||||
// given
|
// given
|
||||||
let ap = AccountProvider::transient_provider();
|
let ap = AccountProvider::transient_provider();
|
||||||
|
|
||||||
|
// default_account should be always available
|
||||||
|
assert_eq!(ap.new_dapps_default_address().unwrap(), 0.into());
|
||||||
|
|
||||||
let address = ap.new_account("test").unwrap();
|
let address = ap.new_account("test").unwrap();
|
||||||
ap.set_address_name(1.into(), "1".into());
|
ap.set_address_name(1.into(), "1".into());
|
||||||
|
|
||||||
// When returning nothing
|
// Default account set to first account by default
|
||||||
ap.set_new_dapps_whitelist(Some(vec![])).unwrap();
|
assert_eq!(ap.new_dapps_default_address().unwrap(), address);
|
||||||
assert_eq!(ap.dapps_addresses("app1".into()).unwrap(), vec![]);
|
assert_eq!(ap.dapp_default_address("app1".into()).unwrap(), address);
|
||||||
|
|
||||||
|
// Even when returning nothing
|
||||||
|
ap.set_new_dapps_addresses(Some(vec![])).unwrap();
|
||||||
|
// Default account is still returned
|
||||||
|
assert_eq!(ap.dapp_addresses("app1".into()).unwrap(), vec![address]);
|
||||||
|
|
||||||
// change to all
|
// change to all
|
||||||
ap.set_new_dapps_whitelist(None).unwrap();
|
ap.set_new_dapps_addresses(None).unwrap();
|
||||||
assert_eq!(ap.dapps_addresses("app1".into()).unwrap(), vec![address]);
|
assert_eq!(ap.dapp_addresses("app1".into()).unwrap(), vec![address]);
|
||||||
|
|
||||||
// change to non-existent account
|
// change to non-existent account
|
||||||
ap.set_new_dapps_whitelist(Some(vec![2.into()])).unwrap();
|
ap.set_new_dapps_addresses(Some(vec![2.into()])).unwrap();
|
||||||
assert_eq!(ap.dapps_addresses("app1".into()).unwrap(), vec![]);
|
assert_eq!(ap.dapp_addresses("app1".into()).unwrap(), vec![address]);
|
||||||
|
|
||||||
// change to a whitelist
|
// change to a addresses
|
||||||
ap.set_new_dapps_whitelist(Some(vec![1.into()])).unwrap();
|
ap.set_new_dapps_addresses(Some(vec![1.into()])).unwrap();
|
||||||
assert_eq!(ap.dapps_addresses("app1".into()).unwrap(), vec![1.into()]);
|
assert_eq!(ap.dapp_addresses("app1".into()).unwrap(), vec![1.into()]);
|
||||||
|
|
||||||
|
// it overrides default account
|
||||||
|
assert_eq!(ap.new_dapps_default_address().unwrap(), 1.into());
|
||||||
|
assert_eq!(ap.dapp_default_address("app1".into()).unwrap(), 1.into());
|
||||||
|
|
||||||
|
ap.set_new_dapps_default_address(address).unwrap();
|
||||||
|
assert_eq!(ap.new_dapps_default_address().unwrap(), address);
|
||||||
|
assert_eq!(ap.dapp_default_address("app1".into()).unwrap(), address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,13 +92,16 @@ impl AddressBook {
|
|||||||
#[derive(Debug, Default, Clone, Eq, PartialEq)]
|
#[derive(Debug, Default, Clone, Eq, PartialEq)]
|
||||||
pub struct DappsSettings {
|
pub struct DappsSettings {
|
||||||
/// A list of visible accounts
|
/// A list of visible accounts
|
||||||
pub accounts: Vec<Address>,
|
pub accounts: Option<Vec<Address>>,
|
||||||
|
/// Default account
|
||||||
|
pub default: Option<Address>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<JsonSettings> for DappsSettings {
|
impl From<JsonSettings> for DappsSettings {
|
||||||
fn from(s: JsonSettings) -> Self {
|
fn from(s: JsonSettings) -> Self {
|
||||||
DappsSettings {
|
DappsSettings {
|
||||||
accounts: s.accounts.into_iter().map(Into::into).collect(),
|
accounts: s.accounts.map(|accounts| accounts.into_iter().map(Into::into).collect()),
|
||||||
|
default: s.default.map(Into::into),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -106,7 +109,8 @@ impl From<JsonSettings> for DappsSettings {
|
|||||||
impl From<DappsSettings> for JsonSettings {
|
impl From<DappsSettings> for JsonSettings {
|
||||||
fn from(s: DappsSettings) -> Self {
|
fn from(s: DappsSettings) -> Self {
|
||||||
JsonSettings {
|
JsonSettings {
|
||||||
accounts: s.accounts.into_iter().map(Into::into).collect(),
|
accounts: s.accounts.map(|accounts| accounts.into_iter().map(Into::into).collect()),
|
||||||
|
default: s.default.map(Into::into),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -114,14 +118,18 @@ impl From<DappsSettings> for JsonSettings {
|
|||||||
/// Dapps user settings
|
/// Dapps user settings
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
pub enum NewDappsPolicy {
|
pub enum NewDappsPolicy {
|
||||||
AllAccounts,
|
AllAccounts {
|
||||||
|
default: Address,
|
||||||
|
},
|
||||||
Whitelist(Vec<Address>),
|
Whitelist(Vec<Address>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<JsonNewDappsPolicy> for NewDappsPolicy {
|
impl From<JsonNewDappsPolicy> for NewDappsPolicy {
|
||||||
fn from(s: JsonNewDappsPolicy) -> Self {
|
fn from(s: JsonNewDappsPolicy) -> Self {
|
||||||
match s {
|
match s {
|
||||||
JsonNewDappsPolicy::AllAccounts => NewDappsPolicy::AllAccounts,
|
JsonNewDappsPolicy::AllAccounts { default } => NewDappsPolicy::AllAccounts {
|
||||||
|
default: default.into(),
|
||||||
|
},
|
||||||
JsonNewDappsPolicy::Whitelist(accounts) => NewDappsPolicy::Whitelist(
|
JsonNewDappsPolicy::Whitelist(accounts) => NewDappsPolicy::Whitelist(
|
||||||
accounts.into_iter().map(Into::into).collect()
|
accounts.into_iter().map(Into::into).collect()
|
||||||
),
|
),
|
||||||
@ -132,7 +140,9 @@ impl From<JsonNewDappsPolicy> for NewDappsPolicy {
|
|||||||
impl From<NewDappsPolicy> for JsonNewDappsPolicy {
|
impl From<NewDappsPolicy> for JsonNewDappsPolicy {
|
||||||
fn from(s: NewDappsPolicy) -> Self {
|
fn from(s: NewDappsPolicy) -> Self {
|
||||||
match s {
|
match s {
|
||||||
NewDappsPolicy::AllAccounts => JsonNewDappsPolicy::AllAccounts,
|
NewDappsPolicy::AllAccounts { default } => JsonNewDappsPolicy::AllAccounts {
|
||||||
|
default: default.into(),
|
||||||
|
},
|
||||||
NewDappsPolicy::Whitelist(accounts) => JsonNewDappsPolicy::Whitelist(
|
NewDappsPolicy::Whitelist(accounts) => JsonNewDappsPolicy::Whitelist(
|
||||||
accounts.into_iter().map(Into::into).collect()
|
accounts.into_iter().map(Into::into).collect()
|
||||||
),
|
),
|
||||||
@ -230,7 +240,9 @@ impl DappsSettingsStore {
|
|||||||
|
|
||||||
/// Returns current new dapps policy
|
/// Returns current new dapps policy
|
||||||
pub fn policy(&self) -> NewDappsPolicy {
|
pub fn policy(&self) -> NewDappsPolicy {
|
||||||
self.policy.get("default").cloned().unwrap_or(NewDappsPolicy::AllAccounts)
|
self.policy.get("default").cloned().unwrap_or(NewDappsPolicy::AllAccounts {
|
||||||
|
default: 0.into(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns recent dapps with last accessed timestamp
|
/// Returns recent dapps with last accessed timestamp
|
||||||
@ -266,13 +278,22 @@ impl DappsSettingsStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sets accounts for specific dapp.
|
/// Sets accounts for specific dapp.
|
||||||
pub fn set_accounts(&mut self, id: DappId, accounts: Vec<Address>) {
|
pub fn set_accounts(&mut self, id: DappId, accounts: Option<Vec<Address>>) {
|
||||||
{
|
{
|
||||||
let mut settings = self.settings.entry(id).or_insert_with(DappsSettings::default);
|
let mut settings = self.settings.entry(id).or_insert_with(DappsSettings::default);
|
||||||
settings.accounts = accounts;
|
settings.accounts = accounts;
|
||||||
}
|
}
|
||||||
self.settings.save(JsonSettings::write);
|
self.settings.save(JsonSettings::write);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets a default account for specific dapp.
|
||||||
|
pub fn set_default(&mut self, id: DappId, default: Address) {
|
||||||
|
{
|
||||||
|
let mut settings = self.settings.entry(id).or_insert_with(DappsSettings::default);
|
||||||
|
settings.default = Some(default);
|
||||||
|
}
|
||||||
|
self.settings.save(JsonSettings::write);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Disk-serializable HashMap
|
/// Disk-serializable HashMap
|
||||||
@ -385,13 +406,14 @@ mod tests {
|
|||||||
let mut b = DappsSettingsStore::new(&path);
|
let mut b = DappsSettingsStore::new(&path);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
b.set_accounts("dappOne".into(), vec![1.into(), 2.into()]);
|
b.set_accounts("dappOne".into(), Some(vec![1.into(), 2.into()]));
|
||||||
|
|
||||||
// then
|
// then
|
||||||
let b = DappsSettingsStore::new(&path);
|
let b = DappsSettingsStore::new(&path);
|
||||||
assert_eq!(b.settings(), hash_map![
|
assert_eq!(b.settings(), hash_map![
|
||||||
"dappOne".into() => DappsSettings {
|
"dappOne".into() => DappsSettings {
|
||||||
accounts: vec![1.into(), 2.into()],
|
accounts: Some(vec![1.into(), 2.into()]),
|
||||||
|
default: None,
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -422,7 +444,9 @@ mod tests {
|
|||||||
let mut store = DappsSettingsStore::new(&path);
|
let mut store = DappsSettingsStore::new(&path);
|
||||||
|
|
||||||
// Test default policy
|
// Test default policy
|
||||||
assert_eq!(store.policy(), NewDappsPolicy::AllAccounts);
|
assert_eq!(store.policy(), NewDappsPolicy::AllAccounts {
|
||||||
|
default: 0.into(),
|
||||||
|
});
|
||||||
|
|
||||||
// when
|
// when
|
||||||
store.set_policy(NewDappsPolicy::Whitelist(vec![1.into(), 2.into()]));
|
store.set_policy(NewDappsPolicy::Whitelist(vec![1.into(), 2.into()]));
|
||||||
|
@ -170,18 +170,30 @@ export default class Parity {
|
|||||||
.execute('parity_generateSecretPhrase');
|
.execute('parity_generateSecretPhrase');
|
||||||
}
|
}
|
||||||
|
|
||||||
getDappsAddresses (dappId) {
|
getDappAddresses (dappId) {
|
||||||
return this._transport
|
return this._transport
|
||||||
.execute('parity_getDappsAddresses', dappId)
|
.execute('parity_getDappAddresses', dappId)
|
||||||
.then(outAddresses);
|
.then(outAddresses);
|
||||||
}
|
}
|
||||||
|
|
||||||
getNewDappsWhitelist () {
|
getDappDefaultAddress (dappId) {
|
||||||
return this._transport
|
return this._transport
|
||||||
.execute('parity_getNewDappsWhitelist')
|
.execute('parity_getDappDefaultAddress', dappId)
|
||||||
|
.then(outAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
getNewDappsAddresses () {
|
||||||
|
return this._transport
|
||||||
|
.execute('parity_getNewDappsAddresses')
|
||||||
.then((addresses) => addresses ? addresses.map(outAddress) : null);
|
.then((addresses) => addresses ? addresses.map(outAddress) : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getNewDappsDefaultAddress () {
|
||||||
|
return this._transport
|
||||||
|
.execute('parity_getNewDappsDefaultAddress')
|
||||||
|
.then(outAddress);
|
||||||
|
}
|
||||||
|
|
||||||
getVaultMeta (vaultName) {
|
getVaultMeta (vaultName) {
|
||||||
return this._transport
|
return this._transport
|
||||||
.execute('parity_getVaultMeta', vaultName)
|
.execute('parity_getVaultMeta', vaultName)
|
||||||
@ -391,9 +403,14 @@ export default class Parity {
|
|||||||
.execute('parity_setAuthor', inAddress(address));
|
.execute('parity_setAuthor', inAddress(address));
|
||||||
}
|
}
|
||||||
|
|
||||||
setDappsAddresses (dappId, addresses) {
|
setDappAddresses (dappId, addresses) {
|
||||||
return this._transport
|
return this._transport
|
||||||
.execute('parity_setDappsAddresses', dappId, inAddresses(addresses));
|
.execute('parity_setDappAddresses', dappId, inAddresses(addresses));
|
||||||
|
}
|
||||||
|
|
||||||
|
setDappDefaultAddress (dappId, address) {
|
||||||
|
return this._transport
|
||||||
|
.execute('parity_setDappDefaultAddress', dappId, address ? inAddress(address) : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
setEngineSigner (address, password) {
|
setEngineSigner (address, password) {
|
||||||
@ -431,9 +448,14 @@ export default class Parity {
|
|||||||
.execute('parity_setMode', mode);
|
.execute('parity_setMode', mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
setNewDappsWhitelist (addresses) {
|
setNewDappsAddresses (addresses) {
|
||||||
return this._transport
|
return this._transport
|
||||||
.execute('parity_setNewDappsWhitelist', addresses ? inAddresses(addresses) : null);
|
.execute('parity_setNewDappsAddresses', addresses ? inAddresses(addresses) : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
setNewDappsDefaultAddress (address) {
|
||||||
|
return this._transport
|
||||||
|
.execute('parity_setNewDappsDefaultAddress', inAddress(address));
|
||||||
}
|
}
|
||||||
|
|
||||||
setTransactionsLimit (quantity) {
|
setTransactionsLimit (quantity) {
|
||||||
|
@ -123,8 +123,10 @@ export default class Personal {
|
|||||||
this._accountsInfo();
|
this._accountsInfo();
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 'parity_setDappsAddresses':
|
case 'parity_setDappAddresses':
|
||||||
case 'parity_setNewDappsWhitelist':
|
case 'parity_setDappDefaultAddress':
|
||||||
|
case 'parity_setNewDappsAddresses':
|
||||||
|
case 'parity_setNewDappsDefaultAddress':
|
||||||
this._defaultAccount(true);
|
this._defaultAccount(true);
|
||||||
this._listAccounts();
|
this._listAccounts();
|
||||||
return;
|
return;
|
||||||
|
@ -1186,9 +1186,9 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setDappsAddresses: {
|
setDappAddresses: {
|
||||||
subdoc: SUBDOC_ACCOUNTS,
|
subdoc: SUBDOC_ACCOUNTS,
|
||||||
desc: 'Sets the available addresses for a dapp.',
|
desc: 'Sets the available addresses for a dapp. When provided with non-empty list changes the default account as well.',
|
||||||
params: [
|
params: [
|
||||||
{
|
{
|
||||||
type: String,
|
type: String,
|
||||||
@ -1197,7 +1197,7 @@ export default {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: Array,
|
type: Array,
|
||||||
desc: 'Array of available accounts available to the dapp.',
|
desc: 'Array of available accounts available to the dapp or `null` for default list.',
|
||||||
example: ['0x407d73d8a49eeb85d32cf465507dd71d507100c1']
|
example: ['0x407d73d8a49eeb85d32cf465507dd71d507100c1']
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -1208,7 +1208,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getDappsAddresses: {
|
getDappAddresses: {
|
||||||
subdoc: SUBDOC_ACCOUNTS,
|
subdoc: SUBDOC_ACCOUNTS,
|
||||||
desc: 'Returns the list of accounts available to a specific dapp.',
|
desc: 'Returns the list of accounts available to a specific dapp.',
|
||||||
params: [
|
params: [
|
||||||
@ -1225,13 +1225,52 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setNewDappsWhitelist: {
|
setDappDefaultAddress: {
|
||||||
|
subdoc: SUBDOC_ACCOUNTS,
|
||||||
|
desc: 'Changes dapp default address. Does not affect other accounts exposed for this dapp, but default account will always be retured as the first one.',
|
||||||
|
params: [
|
||||||
|
{
|
||||||
|
type: String,
|
||||||
|
desc: 'Dapp Id.',
|
||||||
|
example: 'web'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: Address,
|
||||||
|
desc: 'Default Address.',
|
||||||
|
example: '0x407d73d8a49eeb85d32cf465507dd71d507100c1'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
returns: {
|
||||||
|
type: Boolean,
|
||||||
|
desc: '`true` if the call was successful',
|
||||||
|
example: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getDappDefaultAddress: {
|
||||||
|
subdoc: SUBDOC_ACCOUNTS,
|
||||||
|
desc: 'Returns a default account available to a specific dapp.',
|
||||||
|
params: [
|
||||||
|
{
|
||||||
|
type: String,
|
||||||
|
desc: 'Dapp Id.',
|
||||||
|
example: 'web'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
returns: {
|
||||||
|
type: Address,
|
||||||
|
desc: 'Default Address',
|
||||||
|
example: '0x407d73d8a49eeb85d32cf465507dd71d507100c1'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setNewDappsAddresses: {
|
||||||
subdoc: SUBDOC_ACCOUNTS,
|
subdoc: SUBDOC_ACCOUNTS,
|
||||||
desc: 'Sets the list of accounts available to new dapps.',
|
desc: 'Sets the list of accounts available to new dapps.',
|
||||||
params: [
|
params: [
|
||||||
{
|
{
|
||||||
type: Array,
|
type: Array,
|
||||||
desc: 'List of accounts available by default.',
|
desc: 'List of accounts available by default or `null` for all accounts.',
|
||||||
example: ['0x407d73d8a49eeb85d32cf465507dd71d507100c1']
|
example: ['0x407d73d8a49eeb85d32cf465507dd71d507100c1']
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -1242,7 +1281,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getNewDappsWhitelist: {
|
getNewDappsAddresses: {
|
||||||
subdoc: SUBDOC_ACCOUNTS,
|
subdoc: SUBDOC_ACCOUNTS,
|
||||||
desc: 'Returns the list of accounts available to a new dapps.',
|
desc: 'Returns the list of accounts available to a new dapps.',
|
||||||
params: [],
|
params: [],
|
||||||
@ -1253,6 +1292,34 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setNewDappsDefaultAddress: {
|
||||||
|
subdoc: SUBDOC_ACCOUNTS,
|
||||||
|
desc: 'Changes global default address. This setting may be overriden for a specific dapp.',
|
||||||
|
params: [
|
||||||
|
{
|
||||||
|
type: Address,
|
||||||
|
desc: 'Default Address.',
|
||||||
|
example: '0x407d73d8a49eeb85d32cf465507dd71d507100c1'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
returns: {
|
||||||
|
type: Boolean,
|
||||||
|
desc: '`true` if the call was successful',
|
||||||
|
example: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getNewDappsDefaultAddress: {
|
||||||
|
subdoc: SUBDOC_ACCOUNTS,
|
||||||
|
desc: 'Returns a default account available to dapps.',
|
||||||
|
params: [],
|
||||||
|
returns: {
|
||||||
|
type: Address,
|
||||||
|
desc: 'Default Address',
|
||||||
|
example: '0x407d73d8a49eeb85d32cf465507dd71d507100c1'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
listRecentDapps: {
|
listRecentDapps: {
|
||||||
subdoc: SUBDOC_ACCOUNTS,
|
subdoc: SUBDOC_ACCOUNTS,
|
||||||
desc: 'Returns a list of the most recent active dapps.',
|
desc: 'Returns a list of the most recent active dapps.',
|
||||||
|
@ -102,7 +102,7 @@ export default class Store {
|
|||||||
|
|
||||||
loadWhitelist () {
|
loadWhitelist () {
|
||||||
return this._api.parity
|
return this._api.parity
|
||||||
.getNewDappsWhitelist()
|
.getNewDappsAddresses()
|
||||||
.then((whitelist) => {
|
.then((whitelist) => {
|
||||||
this.setWhitelist(whitelist);
|
this.setWhitelist(whitelist);
|
||||||
})
|
})
|
||||||
@ -113,7 +113,7 @@ export default class Store {
|
|||||||
|
|
||||||
updateWhitelist (whitelist) {
|
updateWhitelist (whitelist) {
|
||||||
return this._api.parity
|
return this._api.parity
|
||||||
.setNewDappsWhitelist(whitelist)
|
.setNewDappsAddresses(whitelist)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.setWhitelist(whitelist);
|
this.setWhitelist(whitelist);
|
||||||
})
|
})
|
||||||
|
@ -31,8 +31,8 @@ let store;
|
|||||||
function create () {
|
function create () {
|
||||||
api = {
|
api = {
|
||||||
parity: {
|
parity: {
|
||||||
getNewDappsWhitelist: sinon.stub().resolves(WHITELIST),
|
getNewDappsAddresses: sinon.stub().resolves(WHITELIST),
|
||||||
setNewDappsWhitelist: sinon.stub().resolves(true)
|
setNewDappsAddresses: sinon.stub().resolves(true)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ describe('modals/DappPermissions/store', () => {
|
|||||||
|
|
||||||
describe('constructor', () => {
|
describe('constructor', () => {
|
||||||
it('retrieves the whitelist via api', () => {
|
it('retrieves the whitelist via api', () => {
|
||||||
expect(api.parity.getNewDappsWhitelist).to.be.calledOnce;
|
expect(api.parity.getNewDappsAddresses).to.be.calledOnce;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sets the retrieved whitelist', () => {
|
it('sets the retrieved whitelist', () => {
|
||||||
@ -79,12 +79,12 @@ describe('modals/DappPermissions/store', () => {
|
|||||||
store.closeModal();
|
store.closeModal();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('calls setNewDappsWhitelist', () => {
|
it('calls setNewDappsAddresses', () => {
|
||||||
expect(api.parity.setNewDappsWhitelist).to.have.been.calledOnce;
|
expect(api.parity.setNewDappsAddresses).to.have.been.calledOnce;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('has the default account in first position', () => {
|
it('has the default account in first position', () => {
|
||||||
expect(api.parity.setNewDappsWhitelist).to.have.been.calledWith(['789', '456']);
|
expect(api.parity.setNewDappsAddresses).to.have.been.calledWith(['789', '456']);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ export default class AccountStore {
|
|||||||
this.setDefaultAccount(address);
|
this.setDefaultAccount(address);
|
||||||
|
|
||||||
return this._api.parity
|
return this._api.parity
|
||||||
.setNewDappsWhitelist(accounts)
|
.setNewDappsAddresses(accounts)
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.warn('makeDefaultAccount', error);
|
console.warn('makeDefaultAccount', error);
|
||||||
});
|
});
|
||||||
@ -78,7 +78,7 @@ export default class AccountStore {
|
|||||||
|
|
||||||
return Promise
|
return Promise
|
||||||
.all([
|
.all([
|
||||||
this._api.parity.getNewDappsWhitelist(),
|
this._api.parity.getNewDappsAddresses(),
|
||||||
this._api.parity.allAccountsInfo()
|
this._api.parity.allAccountsInfo()
|
||||||
])
|
])
|
||||||
.then(([whitelist, accounts]) => {
|
.then(([whitelist, accounts]) => {
|
||||||
|
@ -76,8 +76,8 @@ describe('views/ParityBar/AccountStore', () => {
|
|||||||
store.setAccounts.restore();
|
store.setAccounts.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('calls into parity_getNewDappsWhitelist', () => {
|
it('calls into parity_getNewDappsAddresses', () => {
|
||||||
expect(api.parity.getNewDappsWhitelist).to.have.been.called;
|
expect(api.parity.getNewDappsAddresses).to.have.been.called;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('calls into parity_allAccountsInfo', () => {
|
it('calls into parity_allAccountsInfo', () => {
|
||||||
@ -104,8 +104,8 @@ describe('views/ParityBar/AccountStore', () => {
|
|||||||
return store.makeDefaultAccount(ACCOUNT_NEW);
|
return store.makeDefaultAccount(ACCOUNT_NEW);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('calls into parity_setNewDappsWhitelist (with ordering)', () => {
|
it('calls into parity_setNewDappsAddresses (with ordering)', () => {
|
||||||
expect(api.parity.setNewDappsWhitelist).to.have.been.calledWith([
|
expect(api.parity.setNewDappsAddresses).to.have.been.calledWith([
|
||||||
ACCOUNT_NEW, ACCOUNT_FIRST, ACCOUNT_DEFAULT
|
ACCOUNT_NEW, ACCOUNT_FIRST, ACCOUNT_DEFAULT
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
@ -36,8 +36,8 @@ function createApi () {
|
|||||||
parity: {
|
parity: {
|
||||||
defaultAccount: sinon.stub().resolves(ACCOUNT_DEFAULT),
|
defaultAccount: sinon.stub().resolves(ACCOUNT_DEFAULT),
|
||||||
allAccountsInfo: sinon.stub().resolves(ACCOUNTS),
|
allAccountsInfo: sinon.stub().resolves(ACCOUNTS),
|
||||||
getNewDappsWhitelist: sinon.stub().resolves(null),
|
getNewDappsAddresses: sinon.stub().resolves(null),
|
||||||
setNewDappsWhitelist: sinon.stub().resolves(true)
|
setNewDappsAddresses: sinon.stub().resolves(true)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -22,7 +22,9 @@ use hash;
|
|||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct DappsSettings {
|
pub struct DappsSettings {
|
||||||
/// A list of accounts this Dapp can see.
|
/// A list of accounts this Dapp can see.
|
||||||
pub accounts: Vec<hash::Address>,
|
pub accounts: Option<Vec<hash::Address>>,
|
||||||
|
/// Default account
|
||||||
|
pub default: Option<hash::Address>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_serialization!(String => DappsSettings);
|
impl_serialization!(String => DappsSettings);
|
||||||
@ -40,7 +42,10 @@ impl_serialization!(String => DappsHistory);
|
|||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
pub enum NewDappsPolicy {
|
pub enum NewDappsPolicy {
|
||||||
/// All accounts are exposed by default.
|
/// All accounts are exposed by default.
|
||||||
AllAccounts,
|
AllAccounts {
|
||||||
|
/// Default account, which should be returned as the first one.
|
||||||
|
default: hash::Address,
|
||||||
|
},
|
||||||
/// Only accounts listed here are exposed by default for new dapps.
|
/// Only accounts listed here are exposed by default for new dapps.
|
||||||
Whitelist(Vec<hash::Address>),
|
Whitelist(Vec<hash::Address>),
|
||||||
}
|
}
|
||||||
|
@ -221,7 +221,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> EthClient<C, SN, S, M, EM> where
|
|||||||
let store = take_weak!(self.accounts);
|
let store = take_weak!(self.accounts);
|
||||||
store
|
store
|
||||||
.note_dapp_used(dapp.clone())
|
.note_dapp_used(dapp.clone())
|
||||||
.and_then(|_| store.dapps_addresses(dapp))
|
.and_then(|_| store.dapp_addresses(dapp))
|
||||||
.map_err(|e| errors::internal("Could not fetch accounts.", e))
|
.map_err(|e| errors::internal("Could not fetch accounts.", e))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -308,10 +308,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
let author = move || {
|
let author = move || {
|
||||||
let mut miner = take_weak!(self.miner).author();
|
let mut miner = take_weak!(self.miner).author();
|
||||||
if miner == 0.into() {
|
if miner == 0.into() {
|
||||||
let accounts = self.dapp_accounts(dapp.into())?;
|
miner = self.dapp_accounts(dapp.into())?.get(0).cloned().unwrap_or_default();
|
||||||
if let Some(address) = accounts.get(0) {
|
|
||||||
miner = *address;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(RpcH160::from(miner))
|
Ok(RpcH160::from(miner))
|
||||||
|
@ -187,7 +187,7 @@ impl Eth for EthClient {
|
|||||||
|
|
||||||
let accounts = self.accounts
|
let accounts = self.accounts
|
||||||
.note_dapp_used(dapp.clone())
|
.note_dapp_used(dapp.clone())
|
||||||
.and_then(|_| self.accounts.dapps_addresses(dapp))
|
.and_then(|_| self.accounts.dapp_addresses(dapp))
|
||||||
.map_err(|e| errors::internal("Could not fetch accounts.", e))
|
.map_err(|e| errors::internal("Could not fetch accounts.", e))
|
||||||
.map(|accs| accs.into_iter().map(Into::<RpcH160>::into).collect());
|
.map(|accs| accs.into_iter().map(Into::<RpcH160>::into).collect());
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::collections::{BTreeMap, HashSet};
|
use std::collections::{BTreeMap, HashSet};
|
||||||
use futures::{self, Future, BoxFuture};
|
use futures::{future, Future, BoxFuture};
|
||||||
|
|
||||||
use util::{RotatingLogger, Address};
|
use util::{RotatingLogger, Address};
|
||||||
use util::misc::version_data;
|
use util::misc::version_data;
|
||||||
@ -118,7 +118,7 @@ impl<C, M, S: ?Sized, U> Parity for ParityClient<C, M, S, U> where
|
|||||||
let store = take_weak!(self.accounts);
|
let store = take_weak!(self.accounts);
|
||||||
let dapp_accounts = store
|
let dapp_accounts = store
|
||||||
.note_dapp_used(dapp.clone().into())
|
.note_dapp_used(dapp.clone().into())
|
||||||
.and_then(|_| store.dapps_addresses(dapp.into()))
|
.and_then(|_| store.dapp_addresses(dapp.into()))
|
||||||
.map_err(|e| errors::internal("Could not fetch accounts.", e))?
|
.map_err(|e| errors::internal("Could not fetch accounts.", e))?
|
||||||
.into_iter().collect::<HashSet<_>>();
|
.into_iter().collect::<HashSet<_>>();
|
||||||
|
|
||||||
@ -146,16 +146,13 @@ impl<C, M, S: ?Sized, U> Parity for ParityClient<C, M, S, U> where
|
|||||||
|
|
||||||
fn default_account(&self, meta: Self::Metadata) -> BoxFuture<H160, Error> {
|
fn default_account(&self, meta: Self::Metadata) -> BoxFuture<H160, Error> {
|
||||||
let dapp_id = meta.dapp_id();
|
let dapp_id = meta.dapp_id();
|
||||||
let default_account = move || {
|
future::ok(
|
||||||
Ok(take_weak!(self.accounts)
|
take_weakf!(self.accounts)
|
||||||
.dapps_addresses(dapp_id.into())
|
.dapp_default_address(dapp_id.into())
|
||||||
|
.map(Into::into)
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|accounts| accounts.get(0).cloned())
|
.unwrap_or_default()
|
||||||
.map(|acc| acc.into())
|
).boxed()
|
||||||
.unwrap_or_default())
|
|
||||||
};
|
|
||||||
|
|
||||||
futures::done(default_account()).boxed()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transactions_limit(&self) -> Result<usize, Error> {
|
fn transactions_limit(&self) -> Result<usize, Error> {
|
||||||
|
@ -142,41 +142,69 @@ impl ParityAccounts for ParityAccountsClient {
|
|||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_account_visibility(&self, _address: RpcH160, _dapp: RpcH256, _visible: bool) -> Result<bool, Error> {
|
fn set_dapp_addresses(&self, dapp: DappId, addresses: Option<Vec<RpcH160>>) -> Result<bool, Error> {
|
||||||
Ok(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_dapps_addresses(&self, dapp: DappId, addresses: Vec<RpcH160>) -> Result<bool, Error> {
|
|
||||||
let store = take_weak!(self.accounts);
|
let store = take_weak!(self.accounts);
|
||||||
|
|
||||||
store.set_dapps_addresses(dapp.into(), into_vec(addresses))
|
store.set_dapp_addresses(dapp.into(), addresses.map(into_vec))
|
||||||
|
.map_err(|e| errors::account("Couldn't set dapp addresses.", e))
|
||||||
|
.map(|_| true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dapp_addresses(&self, dapp: DappId) -> Result<Vec<RpcH160>, Error> {
|
||||||
|
let store = take_weak!(self.accounts);
|
||||||
|
|
||||||
|
store.dapp_addresses(dapp.into())
|
||||||
|
.map_err(|e| errors::account("Couldn't get dapp addresses.", e))
|
||||||
|
.map(into_vec)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_dapp_default_address(&self, dapp: DappId, address: RpcH160) -> Result<bool, Error> {
|
||||||
|
let store = take_weak!(self.accounts);
|
||||||
|
|
||||||
|
store.set_dapp_default_address(dapp.into(), address.into())
|
||||||
|
.map_err(|e| errors::account("Couldn't set dapp default address.", e))
|
||||||
|
.map(|_| true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dapp_default_address(&self, dapp: DappId) -> Result<RpcH160, Error> {
|
||||||
|
let store = take_weak!(self.accounts);
|
||||||
|
|
||||||
|
store.dapp_default_address(dapp.into())
|
||||||
|
.map_err(|e| errors::account("Couldn't get dapp default address.", e))
|
||||||
|
.map(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_new_dapps_addresses(&self, addresses: Option<Vec<RpcH160>>) -> Result<bool, Error> {
|
||||||
|
let store = take_weak!(self.accounts);
|
||||||
|
|
||||||
|
store
|
||||||
|
.set_new_dapps_addresses(addresses.map(into_vec))
|
||||||
.map_err(|e| errors::account("Couldn't set dapps addresses.", e))
|
.map_err(|e| errors::account("Couldn't set dapps addresses.", e))
|
||||||
.map(|_| true)
|
.map(|_| true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dapps_addresses(&self, dapp: DappId) -> Result<Vec<RpcH160>, Error> {
|
fn new_dapps_addresses(&self) -> Result<Option<Vec<RpcH160>>, Error> {
|
||||||
let store = take_weak!(self.accounts);
|
let store = take_weak!(self.accounts);
|
||||||
|
|
||||||
store.dapps_addresses(dapp.into())
|
store.new_dapps_addresses()
|
||||||
.map_err(|e| errors::account("Couldn't get dapps addresses.", e))
|
.map_err(|e| errors::account("Couldn't get dapps addresses.", e))
|
||||||
.map(into_vec)
|
.map(|accounts| accounts.map(into_vec))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_new_dapps_whitelist(&self, whitelist: Option<Vec<RpcH160>>) -> Result<bool, Error> {
|
fn set_new_dapps_default_address(&self, address: RpcH160) -> Result<bool, Error> {
|
||||||
let store = take_weak!(self.accounts);
|
let store = take_weak!(self.accounts);
|
||||||
|
|
||||||
store
|
store.set_new_dapps_default_address(address.into())
|
||||||
.set_new_dapps_whitelist(whitelist.map(into_vec))
|
.map_err(|e| errors::account("Couldn't set new dapps default address.", e))
|
||||||
.map_err(|e| errors::account("Couldn't set dapps whitelist.", e))
|
|
||||||
.map(|_| true)
|
.map(|_| true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_dapps_whitelist(&self) -> Result<Option<Vec<RpcH160>>, Error> {
|
fn new_dapps_default_address(&self) -> Result<RpcH160, Error> {
|
||||||
let store = take_weak!(self.accounts);
|
let store = take_weak!(self.accounts);
|
||||||
|
|
||||||
store.new_dapps_whitelist()
|
store.new_dapps_default_address()
|
||||||
.map_err(|e| errors::account("Couldn't get dapps whitelist.", e))
|
.map_err(|e| errors::account("Couldn't get new dapps default address.", e))
|
||||||
.map(|accounts| accounts.map(into_vec))
|
.map(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recent_dapps(&self) -> Result<BTreeMap<DappId, u64>, Error> {
|
fn recent_dapps(&self) -> Result<BTreeMap<DappId, u64>, Error> {
|
||||||
|
@ -101,7 +101,7 @@ impl<D: Dispatcher + 'static> Personal for PersonalClient<D> {
|
|||||||
let default = match request.from.as_ref() {
|
let default = match request.from.as_ref() {
|
||||||
Some(account) => Ok(account.clone().into()),
|
Some(account) => Ok(account.clone().into()),
|
||||||
None => accounts
|
None => accounts
|
||||||
.default_address(meta.dapp_id().into())
|
.dapp_default_address(meta.dapp_id().into())
|
||||||
.map_err(|e| errors::account("Cannot find default account.", e)),
|
.map_err(|e| errors::account("Cannot find default account.", e)),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ impl<D: Dispatcher + 'static> SigningQueueClient<D> {
|
|||||||
let accounts = take_weakf!(self.accounts);
|
let accounts = take_weakf!(self.accounts);
|
||||||
let default_account = match default_account {
|
let default_account = match default_account {
|
||||||
DefaultAccount::Provided(acc) => acc,
|
DefaultAccount::Provided(acc) => acc,
|
||||||
DefaultAccount::ForDapp(dapp) => accounts.default_address(dapp).ok().unwrap_or_default(),
|
DefaultAccount::ForDapp(dapp) => accounts.dapp_default_address(dapp).ok().unwrap_or_default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let dispatcher = self.dispatcher.clone();
|
let dispatcher = self.dispatcher.clone();
|
||||||
|
@ -55,7 +55,7 @@ impl<D: Dispatcher + 'static> SigningUnsafeClient<D> {
|
|||||||
let accounts = take_weakf!(self.accounts);
|
let accounts = take_weakf!(self.accounts);
|
||||||
let default = match account {
|
let default = match account {
|
||||||
DefaultAccount::Provided(acc) => acc,
|
DefaultAccount::Provided(acc) => acc,
|
||||||
DefaultAccount::ForDapp(dapp) => accounts.default_address(dapp).ok().unwrap_or_default(),
|
DefaultAccount::ForDapp(dapp) => accounts.dapp_default_address(dapp).ok().unwrap_or_default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let dis = self.dispatcher.clone();
|
let dis = self.dispatcher.clone();
|
||||||
|
@ -368,7 +368,7 @@ fn rpc_eth_gas_price() {
|
|||||||
fn rpc_eth_accounts() {
|
fn rpc_eth_accounts() {
|
||||||
let tester = EthTester::default();
|
let tester = EthTester::default();
|
||||||
let address = tester.accounts_provider.new_account("").unwrap();
|
let address = tester.accounts_provider.new_account("").unwrap();
|
||||||
tester.accounts_provider.set_new_dapps_whitelist(None).unwrap();
|
tester.accounts_provider.set_new_dapps_addresses(None).unwrap();
|
||||||
tester.accounts_provider.set_address_name(1.into(), "1".into());
|
tester.accounts_provider.set_address_name(1.into(), "1".into());
|
||||||
tester.accounts_provider.set_address_name(10.into(), "10".into());
|
tester.accounts_provider.set_address_name(10.into(), "10".into());
|
||||||
|
|
||||||
@ -377,14 +377,14 @@ fn rpc_eth_accounts() {
|
|||||||
let response = r#"{"jsonrpc":"2.0","result":[""#.to_owned() + &format!("0x{:?}", address) + r#""],"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":[""#.to_owned() + &format!("0x{:?}", address) + r#""],"id":1}"#;
|
||||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
|
||||||
tester.accounts_provider.set_new_dapps_whitelist(Some(vec![1.into()])).unwrap();
|
tester.accounts_provider.set_new_dapps_addresses(Some(vec![1.into()])).unwrap();
|
||||||
// even with some account it should return empty list (no dapp detected)
|
// even with some account it should return empty list (no dapp detected)
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "eth_accounts", "params": [], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "eth_accounts", "params": [], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":["0x0000000000000000000000000000000000000001"],"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":["0x0000000000000000000000000000000000000001"],"id":1}"#;
|
||||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
|
||||||
// when we add visible address it should return that.
|
// when we add visible address it should return that.
|
||||||
tester.accounts_provider.set_dapps_addresses("app1".into(), vec![10.into()]).unwrap();
|
tester.accounts_provider.set_dapp_addresses("app1".into(), Some(vec![10.into()])).unwrap();
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "eth_accounts", "params": [], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "eth_accounts", "params": [], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":["0x000000000000000000000000000000000000000a"],"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":["0x000000000000000000000000000000000000000a"],"id":1}"#;
|
||||||
let mut meta = Metadata::default();
|
let mut meta = Metadata::default();
|
||||||
|
@ -110,17 +110,19 @@ fn rpc_parity_accounts_info() {
|
|||||||
assert_eq!(accounts.len(), 1);
|
assert_eq!(accounts.len(), 1);
|
||||||
let address = accounts[0];
|
let address = accounts[0];
|
||||||
|
|
||||||
deps.accounts.set_account_name(address.clone(), "Test".to_owned()).unwrap();
|
deps.accounts.set_address_name(1.into(), "XX".into());
|
||||||
deps.accounts.set_account_meta(address.clone(), "{foo: 69}".to_owned()).unwrap();
|
deps.accounts.set_account_name(address.clone(), "Test".into()).unwrap();
|
||||||
|
deps.accounts.set_account_meta(address.clone(), "{foo: 69}".into()).unwrap();
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_accountsInfo", "params": [], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_accountsInfo", "params": [], "id": 1}"#;
|
||||||
let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":{{\"0x{}\":{{\"name\":\"Test\"}}}},\"id\":1}}", address.hex());
|
let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":{{\"0x{}\":{{\"name\":\"Test\"}}}},\"id\":1}}", address.hex());
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response));
|
assert_eq!(io.handle_request_sync(request), Some(response));
|
||||||
|
|
||||||
// Change the whitelist
|
// Change the whitelist
|
||||||
deps.accounts.set_new_dapps_whitelist(Some(vec![1.into()])).unwrap();
|
let address = Address::from(1);
|
||||||
|
deps.accounts.set_new_dapps_addresses(Some(vec![address.clone()])).unwrap();
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_accountsInfo", "params": [], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_accountsInfo", "params": [], "id": 1}"#;
|
||||||
let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":{{}},\"id\":1}}");
|
let response = format!("{{\"jsonrpc\":\"2.0\",\"result\":{{\"0x{}\":{{\"name\":\"XX\"}}}},\"id\":1}}", address.hex());
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response));
|
assert_eq!(io.handle_request_sync(request), Some(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,48 +125,87 @@ fn rpc_parity_set_and_get_dapps_accounts() {
|
|||||||
// given
|
// given
|
||||||
let tester = setup();
|
let tester = setup();
|
||||||
tester.accounts.set_address_name(10.into(), "10".into());
|
tester.accounts.set_address_name(10.into(), "10".into());
|
||||||
assert_eq!(tester.accounts.dapps_addresses("app1".into()).unwrap(), vec![]);
|
assert_eq!(tester.accounts.dapp_addresses("app1".into()).unwrap(), vec![]);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_setDappsAddresses","params":["app1",["0x000000000000000000000000000000000000000a","0x0000000000000000000000000000000000000001"]], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_setDappAddresses","params":["app1",["0x000000000000000000000000000000000000000a","0x0000000000000000000000000000000000000001"]], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(tester.accounts.dapps_addresses("app1".into()).unwrap(), vec![10.into()]);
|
assert_eq!(tester.accounts.dapp_addresses("app1".into()).unwrap(), vec![10.into()]);
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_getDappsAddresses","params":["app1"], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_getDappAddresses","params":["app1"], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":["0x000000000000000000000000000000000000000a"],"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":["0x000000000000000000000000000000000000000a"],"id":1}"#;
|
||||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_parity_set_and_get_dapp_default_address() {
|
||||||
|
// given
|
||||||
|
let tester = setup();
|
||||||
|
tester.accounts.set_address_name(10.into(), "10".into());
|
||||||
|
assert_eq!(tester.accounts.dapp_addresses("app1".into()).unwrap(), vec![]);
|
||||||
|
|
||||||
|
// when
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_setDappDefaultAddress","params":["app1", "0x000000000000000000000000000000000000000a"], "id": 1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
|
||||||
|
// then
|
||||||
|
assert_eq!(tester.accounts.dapp_addresses("app1".into()).unwrap(), vec![10.into()]);
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_getDappDefaultAddress","params":["app1"], "id": 1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":"0x000000000000000000000000000000000000000a","id":1}"#;
|
||||||
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_parity_set_and_get_new_dapps_whitelist() {
|
fn rpc_parity_set_and_get_new_dapps_whitelist() {
|
||||||
// given
|
// given
|
||||||
let tester = setup();
|
let tester = setup();
|
||||||
|
|
||||||
// when set to whitelist
|
// when set to whitelist
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_setNewDappsWhitelist","params":[["0x000000000000000000000000000000000000000a"]], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_setNewDappsAddresses","params":[["0x000000000000000000000000000000000000000a"]], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(tester.accounts.new_dapps_whitelist().unwrap(), Some(vec![10.into()]));
|
assert_eq!(tester.accounts.new_dapps_addresses().unwrap(), Some(vec![10.into()]));
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_getNewDappsWhitelist","params":[], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_getNewDappsAddresses","params":[], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":["0x000000000000000000000000000000000000000a"],"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":["0x000000000000000000000000000000000000000a"],"id":1}"#;
|
||||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
|
||||||
// when set to empty
|
// when set to empty
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_setNewDappsWhitelist","params":[null], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_setNewDappsAddresses","params":[null], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(tester.accounts.new_dapps_whitelist().unwrap(), None);
|
assert_eq!(tester.accounts.new_dapps_addresses().unwrap(), None);
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_getNewDappsWhitelist","params":[], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_getNewDappsAddresses","params":[], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#;
|
||||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_parity_set_and_get_new_dapps_default_address() {
|
||||||
|
// given
|
||||||
|
let tester = setup();
|
||||||
|
tester.accounts.set_address_name(10.into(), "10".into());
|
||||||
|
assert_eq!(tester.accounts.new_dapps_default_address().unwrap(), 0.into());
|
||||||
|
|
||||||
|
// when
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_setNewDappsDefaultAddress","params":["0x000000000000000000000000000000000000000a"], "id": 1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
|
||||||
|
// then
|
||||||
|
assert_eq!(tester.accounts.new_dapps_default_address().unwrap(), 10.into());
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_getNewDappsDefaultAddress","params":[], "id": 1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":"0x000000000000000000000000000000000000000a","id":1}"#;
|
||||||
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_parity_recent_dapps() {
|
fn rpc_parity_recent_dapps() {
|
||||||
// given
|
// given
|
||||||
|
@ -70,28 +70,51 @@ build_rpc_trait! {
|
|||||||
#[rpc(name = "parity_setAccountMeta")]
|
#[rpc(name = "parity_setAccountMeta")]
|
||||||
fn set_account_meta(&self, H160, String) -> Result<bool, Error>;
|
fn set_account_meta(&self, H160, String) -> Result<bool, Error>;
|
||||||
|
|
||||||
/// Sets account visibility.
|
/// Sets addresses exposed for particular dapp.
|
||||||
/// @unimplemented
|
/// Setting a non-empty list will also override default account.
|
||||||
#[rpc(name = "parity_setAccountVisiblity")]
|
/// Setting `None` will resets visible account to what's visible for new dapps
|
||||||
fn set_account_visibility(&self, H160, H256, bool) -> Result<bool, Error>;
|
/// (does not affect default account though)
|
||||||
|
#[rpc(name = "parity_setDappAddresses")]
|
||||||
/// Sets accounts exposed for particular dapp.
|
fn set_dapp_addresses(&self, DappId, Option<Vec<H160>>) -> Result<bool, Error>;
|
||||||
#[rpc(name = "parity_setDappsAddresses")]
|
|
||||||
fn set_dapps_addresses(&self, DappId, Vec<H160>) -> Result<bool, Error>;
|
|
||||||
|
|
||||||
/// Gets accounts exposed for particular dapp.
|
/// Gets accounts exposed for particular dapp.
|
||||||
#[rpc(name = "parity_getDappsAddresses")]
|
#[rpc(name = "parity_getDappAddresses")]
|
||||||
fn dapps_addresses(&self, DappId) -> Result<Vec<H160>, Error>;
|
fn dapp_addresses(&self, DappId) -> Result<Vec<H160>, Error>;
|
||||||
|
|
||||||
|
/// Changes dapp default address.
|
||||||
|
/// Does not affect other accounts exposed for this dapp, but
|
||||||
|
/// default account will always be retured as the first one.
|
||||||
|
#[rpc(name = "parity_setDappDefaultAddress")]
|
||||||
|
fn set_dapp_default_address(&self, DappId, H160) -> Result<bool, Error>;
|
||||||
|
|
||||||
|
/// Returns current dapp default address.
|
||||||
|
/// If not set explicite for the dapp will return global default.
|
||||||
|
#[rpc(name = "parity_getDappDefaultAddress")]
|
||||||
|
fn dapp_default_address(&self, DappId) -> Result<H160, Error>;
|
||||||
|
|
||||||
/// Sets accounts exposed for new dapps.
|
/// Sets accounts exposed for new dapps.
|
||||||
/// `None` means that all accounts will be exposed.
|
/// Setting a non-empty list will also override default account.
|
||||||
#[rpc(name = "parity_setNewDappsWhitelist")]
|
/// Setting `None` exposes all internal-managed accounts.
|
||||||
fn set_new_dapps_whitelist(&self, Option<Vec<H160>>) -> Result<bool, Error>;
|
/// (does not affect default account though)
|
||||||
|
#[rpc(name = "parity_setNewDappsAddresses")]
|
||||||
|
fn set_new_dapps_addresses(&self, Option<Vec<H160>>) -> Result<bool, Error>;
|
||||||
|
|
||||||
/// Gets accounts exposed for new dapps.
|
/// Gets accounts exposed for new dapps.
|
||||||
/// `None` means that all accounts will be exposed.
|
/// `None` means that all accounts are exposes.
|
||||||
#[rpc(name = "parity_getNewDappsWhitelist")]
|
#[rpc(name = "parity_getNewDappsAddresses")]
|
||||||
fn new_dapps_whitelist(&self) -> Result<Option<Vec<H160>>, Error>;
|
fn new_dapps_addresses(&self) -> Result<Option<Vec<H160>>, Error>;
|
||||||
|
|
||||||
|
/// Changes default address for new dapps (global default address)
|
||||||
|
/// Does not affect other accounts exposed for new dapps, but
|
||||||
|
/// default account will always be retured as the first one.
|
||||||
|
#[rpc(name = "parity_setNewDappsDefaultAddress")]
|
||||||
|
fn set_new_dapps_default_address(&self, H160) -> Result<bool, Error>;
|
||||||
|
|
||||||
|
/// Returns current default address for new dapps (global default address)
|
||||||
|
/// In case it's not set explicite will return first available account.
|
||||||
|
/// If no accounts are available will return `0x0`
|
||||||
|
#[rpc(name = "parity_getNewDappsDefaultAddress")]
|
||||||
|
fn new_dapps_default_address(&self) -> Result<H160, Error>;
|
||||||
|
|
||||||
/// Returns identified dapps that recently used RPC
|
/// Returns identified dapps that recently used RPC
|
||||||
/// Includes last usage timestamp.
|
/// Includes last usage timestamp.
|
||||||
|
Loading…
Reference in New Issue
Block a user