Browse Source

Wallet: add generate & list

pull/18/head
Sun 5 years ago
parent
commit
570b20efb5
  1. 70
      src/apps/wallet/models.rs
  2. 49
      src/apps/wallet/rpc.rs
  3. 20
      src/migrate.rs
  4. 4
      src/migrate/account.rs
  5. 9
      src/migrate/wallet.rs
  6. 10
      src/storage.rs

70
src/apps/wallet/models.rs

@ -35,35 +35,73 @@ impl ChainToken { @@ -35,35 +35,73 @@ impl ChainToken {
}
}
pub(crate) struct Address {
pub(crate) struct Token {
pub id: i64,
pub index: i64,
pub chain: ChainToken,
pub address: String,
pub public_key: String,
pub secret_key: String,
pub contract: String,
pub decimal: i64,
}
pub(crate) struct Token {
pub(crate) struct Address {
pub id: i64,
pub chain: ChainToken,
pub contract: String,
pub decimal: i64,
pub index: i64,
pub name: String,
pub address: String,
}
impl Address {
pub fn generate(index: i64, chain: ChainToken) -> Self {
let address = String::new();
let public_key = String::new();
let secret_key = String::new();
pub fn new(chain: ChainToken, index: i64, address: String) -> Self {
Self {
index,
chain,
index,
address,
public_key,
secret_key,
name: format!("Account {}", index),
id: 0,
}
}
pub fn to_rpc(&self) -> RpcParam {
json!([self.id, self.chain.to_i64(), self.index, self.address])
}
fn from_values(mut v: Vec<DsValue>) -> Self {
Self {
address: v.pop().unwrap().as_string(),
name: v.pop().unwrap().as_string(),
index: v.pop().unwrap().as_i64(),
chain: ChainToken::from_i64(v.pop().unwrap().as_i64()),
id: v.pop().unwrap().as_i64(),
}
}
pub fn insert(&mut self, db: &DStorage) -> Result<()> {
let sql = format!(
"INSERT INTO addresses (chain, indx, name, address) VALUES ({}, {}, '{}', '{}')",
self.chain.to_i64(),
self.index,
self.name,
self.address,
);
let id = db.insert(&sql)?;
self.id = id;
Ok(())
}
pub fn list(db: &DStorage) -> Result<Vec<Self>> {
let matrix = db.query(&format!(
"SELECT id, chain, indx, name, address FROM addresses"
))?;
let mut addresses = vec![];
for values in matrix {
addresses.push(Self::from_values(values));
}
Ok(addresses)
}
pub fn delete(db: &DStorage, id: &i64) -> Result<()> {
let sql = format!("DELETE FROM addresses WHERE id = {}", id);
db.delete(&sql)?;
Ok(())
}
}

49
src/apps/wallet/rpc.rs

@ -4,22 +4,44 @@ use tdn::types::{ @@ -4,22 +4,44 @@ use tdn::types::{
primitive::HandleResult,
rpc::{json, RpcError, RpcHandler, RpcParam},
};
use tdn_did::generate_eth_account;
use tdn_did::{generate_btc_account, generate_eth_account};
use web3::signing::Key;
use crate::rpc::RpcState;
use crate::{rpc::RpcState, storage::wallet_db};
use super::{models::ChainToken, ETH_NODE};
use super::{
models::{Address, ChainToken},
ETH_NODE,
};
#[inline]
fn wallet_list(devices: Vec<Address>) -> RpcParam {
let mut results = vec![];
for wallet in devices {
results.push(wallet.to_rpc());
}
json!(results)
}
pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
handler.add_method("wallet-echo", |_, params, _| async move {
Ok(HandleResult::rpc(json!(params)))
});
handler.add_method(
"wallet-list",
|gid: GroupId, _params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let db = wallet_db(state.layer.read().await.base(), &gid)?;
let addresses = Address::list(&db)?;
Ok(HandleResult::rpc(wallet_list(addresses)))
},
);
handler.add_method(
"wallet-generate",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let lock = params[0].as_str().ok_or(RpcError::ParseError)?;
let chain = ChainToken::from_i64(params[0].as_i64().ok_or(RpcError::ParseError)?);
let lock = params[1].as_str().ok_or(RpcError::ParseError)?;
let group_lock = state.group.read().await;
let mnemonic = group_lock.mnemonic(&gid, lock)?;
@ -35,11 +57,22 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -35,11 +57,22 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
None
};
let index = 0; // TOOD
let sk = generate_eth_account(lang, &mnemonic, account_index, index, pass)?;
let address = (&sk).address();
println!("{:?}", address);
let mut address = match chain {
ChainToken::ETH | ChainToken::ERC20 | ChainToken::ERC721 => {
let sk = generate_eth_account(lang, &mnemonic, account_index, index, pass)?;
let address = (&sk).address().to_string();
Address::new(chain, index as i64, address)
}
ChainToken::BTC => {
let _sk = generate_btc_account(lang, &mnemonic, account_index, index, pass)?;
todo!();
}
};
let db = wallet_db(state.layer.read().await.base(), &gid)?;
address.insert(&db)?;
Ok(HandleResult::rpc(json!([mnemonic])))
Ok(HandleResult::rpc(address.to_rpc()))
},
);

20
src/migrate.rs

@ -11,6 +11,7 @@ mod file; @@ -11,6 +11,7 @@ mod file;
mod group_chat;
mod service;
mod session;
mod wallet;
use account::ACCOUNT_VERSIONS;
use chat::CHAT_VERSIONS;
@ -20,6 +21,7 @@ use file::FILE_VERSIONS; @@ -20,6 +21,7 @@ use file::FILE_VERSIONS;
use group_chat::GROUP_CHAT_VERSIONS;
use service::SERVICE_VERSIONS;
use session::SESSION_VERSIONS;
use wallet::WALLET_VERSIONS;
use crate::apps::assistant::ASSISTANT_VERSIONS;
@ -50,6 +52,9 @@ pub(crate) const GROUP_CHAT_DB: &'static str = "group_chat.db"; @@ -50,6 +52,9 @@ pub(crate) const GROUP_CHAT_DB: &'static str = "group_chat.db";
/// Account's domain database name
pub(crate) const DOMAIN_DB: &'static str = "domain.db";
/// Account's domain database name
pub(crate) const WALLET_DB: &'static str = "wallet.db";
pub(crate) fn main_migrate(path: &PathBuf) -> Result<()> {
let mut db_path = path.clone();
db_path.push(ACCOUNT_DB);
@ -118,6 +123,7 @@ pub(crate) fn main_migrate(path: &PathBuf) -> Result<()> { @@ -118,6 +123,7 @@ pub(crate) fn main_migrate(path: &PathBuf) -> Result<()> {
GROUP_CHAT_DB => GROUP_CHAT_VERSIONS.as_ref(),
CHAT_DB => CHAT_VERSIONS.as_ref(),
DOMAIN_DB => DOMAIN_VERSIONS.as_ref(),
WALLET_DB => WALLET_VERSIONS.as_ref(),
_ => {
continue;
}
@ -207,6 +213,12 @@ pub(crate) fn main_migrate(path: &PathBuf) -> Result<()> { @@ -207,6 +213,12 @@ pub(crate) fn main_migrate(path: &PathBuf) -> Result<()> {
DOMAIN_DB,
))?;
db.update(&format!(
"UPDATE migrates SET version = {} where db_name = '{}'",
WALLET_VERSIONS.len(),
WALLET_DB,
))?;
db.close()?;
}
@ -276,5 +288,13 @@ pub(crate) fn account_init_migrate(path: &PathBuf) -> Result<()> { @@ -276,5 +288,13 @@ pub(crate) fn account_init_migrate(path: &PathBuf) -> Result<()> {
for i in &DOMAIN_VERSIONS {
db.execute(i)?;
}
db.close()?;
let mut db_path = path.clone();
db_path.push(WALLET_DB);
let db = DStorage::open(db_path)?;
for i in &WALLET_VERSIONS {
db.execute(i)?;
}
db.close()
}

4
src/migrate/account.rs

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
#[rustfmt::skip]
pub(super) const ACCOUNT_VERSIONS: [&str; 9] = [
pub(super) const ACCOUNT_VERSIONS: [&str; 11] = [
"CREATE TABLE IF NOT EXISTS accounts(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
gid TEXT NOT NULL,
@ -24,4 +24,6 @@ pub(super) const ACCOUNT_VERSIONS: [&str; 9] = [ @@ -24,4 +24,6 @@ pub(super) const ACCOUNT_VERSIONS: [&str; 9] = [
"INSERT INTO migrates (db_name, version) values ('assistant.db', 0)",
"INSERT INTO migrates (db_name, version) values ('group_chat.db', 0)",
"INSERT INTO migrates (db_name, version) values ('chat.db', 0)",
"INSERT INTO migrates (db_name, version) values ('domain.db', 0)",
"INSERT INTO migrates (db_name, version) values ('wallet.db', 0)",
];

9
src/migrate/wallet.rs

@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
#[rustfmt::skip]
pub(super) const WALLET_VERSIONS: [&str; 1] = [
"CREATE TABLE IF NOT EXISTS addresses(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
chain INTEGER NOT NULL,
indx INTEGER NOT NULL,
name TEXT NOT NULL,
address TEXT NOT NULL);",
];

10
src/storage.rs

@ -9,7 +9,7 @@ use tdn_storage::local::DStorage; @@ -9,7 +9,7 @@ use tdn_storage::local::DStorage;
use crate::migrate::{
account_init_migrate, ACCOUNT_DB, ASSISTANT_DB, CHAT_DB, CONSENSUS_DB, DOMAIN_DB, FILE_DB,
GROUP_CHAT_DB, SERVICE_DB, SESSION_DB,
GROUP_CHAT_DB, SERVICE_DB, SESSION_DB, WALLET_DB,
};
const FILES_DIR: &'static str = "files";
@ -400,6 +400,14 @@ pub(crate) fn domain_db(base: &PathBuf, gid: &GroupId) -> Result<DStorage> { @@ -400,6 +400,14 @@ pub(crate) fn domain_db(base: &PathBuf, gid: &GroupId) -> Result<DStorage> {
DStorage::open(db_path)
}
#[inline]
pub(crate) fn wallet_db(base: &PathBuf, gid: &GroupId) -> Result<DStorage> {
let mut db_path = base.clone();
db_path.push(gid.to_hex());
db_path.push(WALLET_DB);
DStorage::open(db_path)
}
/// account independent db and storage directory.
pub(crate) async fn account_init(base: &PathBuf, gid: &GroupId) -> Result<()> {
let mut db_path = base.clone();

Loading…
Cancel
Save