Skip to content

Commit

Permalink
feat: add wallet stub to collectibles app (#3589)
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron Hambly committed Nov 18, 2021
1 parent 0c47bc8 commit dfc3b92
Show file tree
Hide file tree
Showing 26 changed files with 856 additions and 145 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Expand Up @@ -521,7 +521,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer {
}));
},
};
Err(Status::unknown("Could not find a matching arm"))
// Err(Status::unknown("Could not find a matching arm"))
} else {
Err(Status::not_found("Could not find any utxo"))
}
Expand Down
1 change: 1 addition & 0 deletions applications/tari_collectibles/src-tauri/Cargo.toml
Expand Up @@ -18,6 +18,7 @@ tauri-build = { version = "1.0.0-beta.4" }
tari_app_grpc = { path = "../../tari_app_grpc" }
tari_common_types = { path = "../../../base_layer/common_types" }
tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", branch = "main" }
tari_key_manager = { path = "../../../base_layer/key_manager" }
tari_mmr = { path = "../../../base_layer/mmr"}
tari_utilities = "*"

Expand Down
@@ -0,0 +1 @@
-- This file should undo anything in `up.sql`
@@ -0,0 +1,6 @@
-- Your SQL goes here
create table wallets (
id blob not null primary key,
name text,
cipher_seed blob not null unique
);
11 changes: 10 additions & 1 deletion applications/tari_collectibles/src-tauri/src/app_state.rs
Expand Up @@ -28,14 +28,14 @@ use crate::{
StorageError,
},
};
use diesel::SqliteConnection;
use std::sync::Arc;
use tari_common_types::types::PublicKey;
use tauri::async_runtime::RwLock;

pub struct AppState {
config: Settings,
db_factory: SqliteDbFactory,
passphrase: Option<String>,
}

#[derive(Clone)]
Expand All @@ -50,10 +50,19 @@ impl ConcurrentAppState {
inner: Arc::new(RwLock::new(AppState {
db_factory: SqliteDbFactory::new(settings.data_dir.as_path()),
config: settings,
passphrase: None,
})),
}
}

pub async fn passphrase(&self) -> Option<String> {
self.inner.read().await.passphrase.clone()
}

pub async fn set_passphrase(&mut self, pass: Option<String>) {
self.inner.write().await.passphrase = pass;
}

pub async fn create_wallet_client(&self) -> WalletClient {
WalletClient::new(self.inner.read().await.config.wallet_grpc_address.clone())
}
Expand Down
Expand Up @@ -21,8 +21,8 @@
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
use crate::{
app_state::ConcurrentAppState,
models::{Account, NewAccount},
storage::{AccountsTableGateway, CollectiblesStorage},
models::{Account, NewAccount, NewWallet, Wallet},
storage::{AccountsTableGateway, CollectiblesStorage, WalletsTableGateway},
};
use tari_common_types::types::PublicKey;
use tari_utilities::hex::Hex;
Expand Down
13 changes: 13 additions & 0 deletions applications/tari_collectibles/src-tauri/src/commands/mod.rs
Expand Up @@ -20,6 +20,19 @@
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use crate::app_state::ConcurrentAppState;

pub mod accounts;
pub mod assets;
pub mod tips;
pub mod wallets;

#[tauri::command]
pub async fn create_db(state: tauri::State<'_, ConcurrentAppState>) -> Result<(), String> {
let _db = state
.create_db()
.await
.map_err(|e| format!("Could not connect to DB: {}", e))?;

Ok(())
}
116 changes: 116 additions & 0 deletions applications/tari_collectibles/src-tauri/src/commands/wallets/mod.rs
@@ -0,0 +1,116 @@
// Copyright 2021. The Tari Project
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
// following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
// disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
// products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use crate::{
app_state::ConcurrentAppState,
models::{NewWallet, Wallet, WalletInfo},
storage::{CollectiblesStorage, WalletsTableGateway},
};
use tari_key_manager::{
cipher_seed::CipherSeed,
mnemonic::{Mnemonic, MnemonicLanguage},
};
use uuid::Uuid;

#[tauri::command]
pub(crate) async fn wallets_create(
name: Option<String>,
passphrase: Option<String>,
state: tauri::State<'_, ConcurrentAppState>,
) -> Result<Wallet, String> {
let new_wallet = NewWallet {
name,
cipher_seed: CipherSeed::new(),
};

let result = state
.create_db()
.await
.map_err(|e| format!("Could not connect to DB: {}", e))?
.wallets()
.insert(new_wallet, passphrase)
.map_err(|e| format!("Could not save wallet: {}", e))?;
Ok(result)
}

#[tauri::command]
pub(crate) async fn wallets_list(
state: tauri::State<'_, ConcurrentAppState>,
) -> Result<Vec<WalletInfo>, String> {
let db = state
.create_db()
.await
.map_err(|e| format!("Could not connect to DB: {}", e))?;

let result = db
.wallets()
.list()
.map_err(|e| format!("Could list wallets from DB: {}", e))?;
Ok(result)
}

#[tauri::command]
pub(crate) async fn wallets_find(
id: String,
passphrase: Option<String>,
state: tauri::State<'_, ConcurrentAppState>,
) -> Result<Wallet, String> {
let db = state
.create_db()
.await
.map_err(|e| format!("Could not connect to DB: {}", e))?;

let uuid = Uuid::parse_str(&id).map_err(|e| format!("Failed to parse UUID: {}", e))?;

let result = db
.wallets()
.find(uuid, passphrase)
.map_err(|e| e.to_string())?;

Ok(result)
}

#[tauri::command]
pub(crate) async fn wallets_seed_words(
id: String,
passphrase: Option<String>,
state: tauri::State<'_, ConcurrentAppState>,
) -> Result<Vec<String>, String> {
let db = state
.create_db()
.await
.map_err(|e| format!("Could not connect to DB: {}", e))?;

let uuid = Uuid::parse_str(&id).map_err(|e| format!("Failed to parse UUID: {}", e))?;

let wallet = db
.wallets()
.find(uuid, passphrase.clone())
.map_err(|e| e.to_string())?;

let seed_words = wallet
.cipher_seed
.to_mnemonic(&MnemonicLanguage::English, passphrase)
.map_err(|e| format!("Failed to convert cipher seed to seed words: {}", e))?;

Ok(seed_words)
}
7 changes: 6 additions & 1 deletion applications/tari_collectibles/src-tauri/src/main.rs
Expand Up @@ -26,12 +26,17 @@ fn main() {
tauri::Builder::default()
.manage(state)
.invoke_handler(tauri::generate_handler![
commands::create_db,
commands::assets::assets_create,
commands::assets::assets_list_owned,
commands::assets::assets_list_registered_assets,
commands::assets::assets_issue_simple_tokens,
commands::accounts::accounts_create,
commands::accounts::accounts_list
commands::accounts::accounts_list,
commands::wallets::wallets_create,
commands::wallets::wallets_list,
commands::wallets::wallets_find,
commands::wallets::wallets_seed_words,
])
.run(tauri::generate_context!())
.expect("error while running tauri application");
Expand Down
2 changes: 2 additions & 0 deletions applications/tari_collectibles/src-tauri/src/models/mod.rs
Expand Up @@ -26,5 +26,7 @@ mod registered_asset_info;
pub use registered_asset_info::RegisteredAssetInfo;
mod account;
pub use account::{Account, NewAccount};
mod wallet;
pub use wallet::{NewWallet, Wallet, WalletInfo};
mod tip002_info;
pub use tip002_info::Tip002Info;
52 changes: 52 additions & 0 deletions applications/tari_collectibles/src-tauri/src/models/wallet.rs
@@ -0,0 +1,52 @@
// Copyright 2021. The Tari Project
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
// following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
// disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
// products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use serde::{Deserialize, Serialize};
use tari_key_manager::cipher_seed::CipherSeed;
use uuid::Uuid;

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Wallet {
pub id: Uuid,
pub name: Option<String>,
pub cipher_seed: CipherSeed,
}

pub struct NewWallet {
pub name: Option<String>,
pub cipher_seed: CipherSeed,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct WalletInfo {
pub id: Uuid,
pub name: Option<String>,
}

impl From<Wallet> for WalletInfo {
fn from(wallet: Wallet) -> Self {
WalletInfo {
id: wallet.id,
name: wallet.name,
}
}
}
8 changes: 8 additions & 0 deletions applications/tari_collectibles/src-tauri/src/schema.rs
Expand Up @@ -9,3 +9,11 @@ table! {
committee_pub_keys -> Binary,
}
}

table! {
wallets (id) {
id -> Binary,
name -> Nullable<Text>,
cipher_seed -> Binary,
}
}
13 changes: 12 additions & 1 deletion applications/tari_collectibles/src-tauri/src/storage/mod.rs
Expand Up @@ -20,19 +20,30 @@
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use crate::models::{Account, NewAccount};
use crate::models::{Account, NewAccount, NewWallet, Wallet, WalletInfo};
pub mod sqlite;
mod storage_error;
pub use storage_error::StorageError;
use uuid::Uuid;

pub trait CollectiblesStorage {
type Accounts: AccountsTableGateway;
type Wallets: WalletsTableGateway;

fn accounts(&self) -> Self::Accounts;
fn wallets(&self) -> Self::Wallets;
}

pub trait AccountsTableGateway {
fn list(&self) -> Result<Vec<Account>, StorageError>;
fn insert(&self, account: NewAccount) -> Result<Account, StorageError>;
fn find(&self, account_id: Uuid) -> Result<Account, StorageError>;
}

pub trait WalletsTableGateway {
type Passphrase;

fn list(&self) -> Result<Vec<WalletInfo>, StorageError>;
fn insert(&self, wallet: NewWallet, pass: Self::Passphrase) -> Result<Wallet, StorageError>;
fn find(&self, id: Uuid, pass: Self::Passphrase) -> Result<Wallet, StorageError>;
}

0 comments on commit dfc3b92

Please sign in to comment.