diff --git a/rpc/src/v1/impls/mod.rs b/rpc/src/v1/impls/mod.rs
index d9102b1db..10d451e9f 100644
--- a/rpc/src/v1/impls/mod.rs
+++ b/rpc/src/v1/impls/mod.rs
@@ -28,7 +28,9 @@ macro_rules! take_weak {
mod web3;
mod eth;
mod net;
+mod personal;
pub use self::web3::Web3Client;
pub use self::eth::{EthClient, EthFilterClient};
pub use self::net::NetClient;
+pub use self::personal::PersonalClient;
diff --git a/rpc/src/v1/impls/personal.rs b/rpc/src/v1/impls/personal.rs
new file mode 100644
index 000000000..b97449541
--- /dev/null
+++ b/rpc/src/v1/impls/personal.rs
@@ -0,0 +1,81 @@
+// 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 .
+
+//! Net rpc implementation.
+use std::sync::{Arc, Weak};
+use jsonrpc_core::*;
+use v1::traits::Personal;
+use util::keys::store::*;
+use util::{Bytes, Address};
+use std::sync::RwLock;
+
+/// Net rpc implementation.
+pub struct PersonalClient {
+ secret_store: Weak,
+ unlocked_account: Arc>>,
+ unlocked_secret: Arc>>,
+}
+
+impl PersonalClient {
+ /// Creates new PersonalClient
+ pub fn new(store: &Arc) -> Self {
+ PersonalClient {
+ secret_store: Arc::downgrade(store),
+ unlocked_account: Arc::new(RwLock::new(None)),
+ unlocked_secret: Arc::new(RwLock::new(None)),
+ }
+ }
+}
+
+impl Personal for PersonalClient {
+ fn accounts(&self, _: Params) -> Result {
+ let store = take_weak!(self.secret_store);
+ match store.accounts() {
+ Ok(account_list) => {
+ Ok(Value::Array(account_list.iter()
+ .map(|&(account, _)| Value::String(format!("{:?}", account)))
+ .collect::>())
+ )
+ }
+ Err(_) => Err(Error::internal_error())
+ }
+ }
+
+ fn new_account(&self, _: Params) -> Result {
+ Err(Error::internal_error())
+ }
+
+ fn unlock_account(&self, params: Params) -> Result {
+ from_params::<(Address, String, u64)>(params).and_then(
+ |(account, account_pass, _)|{
+ let store = take_weak!(self.secret_store);
+ let secret_id = match store.account(&account) {
+ None => { return Ok(Value::Bool(false)); }
+ Some(id) => id
+ };
+ match store.get(&secret_id, &account_pass) {
+ Ok(secret) => {
+ *self.unlocked_account.write().unwrap() = Some(account);
+ *self.unlocked_secret.write().unwrap() = Some(secret);
+ Ok(Value::Bool(true))
+ },
+ Err(_) => {
+ Ok(Value::Bool(false))
+ }
+ }
+ })
+ }
+}
diff --git a/rpc/src/v1/mod.rs b/rpc/src/v1/mod.rs
index 57f7a944a..104a8b3f0 100644
--- a/rpc/src/v1/mod.rs
+++ b/rpc/src/v1/mod.rs
@@ -15,7 +15,7 @@
// along with Parity. If not, see .
//! Ethcore rpc v1.
-//!
+//!
//! Compliant with ethereum rpc.
pub mod traits;
@@ -25,5 +25,5 @@ mod types;
mod tests;
mod helpers;
-pub use self::traits::{Web3, Eth, EthFilter, Net};
+pub use self::traits::{Web3, Eth, EthFilter, Personal, Net};
pub use self::impls::*;
diff --git a/rpc/src/v1/traits/mod.rs b/rpc/src/v1/traits/mod.rs
index c9af6dac3..0a95cb050 100644
--- a/rpc/src/v1/traits/mod.rs
+++ b/rpc/src/v1/traits/mod.rs
@@ -23,7 +23,9 @@ macro_rules! rpc_unimplemented {
pub mod web3;
pub mod eth;
pub mod net;
+pub mod personal;
pub use self::web3::Web3;
pub use self::eth::{Eth, EthFilter};
pub use self::net::Net;
+pub use self::personal::Personal;
diff --git a/rpc/src/v1/traits/personal.rs b/rpc/src/v1/traits/personal.rs
new file mode 100644
index 000000000..0cf72951c
--- /dev/null
+++ b/rpc/src/v1/traits/personal.rs
@@ -0,0 +1,41 @@
+// 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 .
+
+//! Personal rpc interface.
+use std::sync::Arc;
+use jsonrpc_core::*;
+
+/// Personal rpc interface.
+pub trait Personal: Sized + Send + Sync + 'static {
+
+ /// Lists all stored accounts
+ fn accounts(&self, _: Params) -> Result { rpc_unimplemented!() }
+
+ /// Creates new account (it becomes new current unlocked account)
+ fn new_account(&self, _: Params) -> Result { rpc_unimplemented!() }
+
+ /// Unlocks specified account for use (can only be one unlocked account at one moment)
+ fn unlock_account(&self, _: Params) -> Result { rpc_unimplemented!() }
+
+ /// Should be used to convert object to io delegate.
+ fn to_delegate(self) -> IoDelegate {
+ let mut delegate = IoDelegate::new(Arc::new(self));
+ delegate.add_method("personal_listAccounts", Personal::accounts);
+ delegate.add_method("personal_newAccount", Personal::new_account);
+ delegate.add_method("personal_unlockAccount", Personal::unlock_account);
+ delegate
+ }
+}