ui + config: wallet connections setup, initial wallet config, wallet list state, update translations

This commit is contained in:
ardocrat
2023-07-25 03:42:52 +03:00
parent 5cefb61bb3
commit f461f27e4c
23 changed files with 564 additions and 127 deletions
+95
View File
@@ -0,0 +1,95 @@
// Copyright 2023 The Grim Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::ffi::OsString;
use std::path::PathBuf;
use serde_derive::{Deserialize, Serialize};
use crate::{AppConfig, Settings};
use crate::wallet::WalletList;
/// Wallet configuration.
#[derive(Serialize, Deserialize, Clone)]
pub struct WalletConfig {
/// Identifier for a wallet.
id: OsString,
/// Readable wallet name.
name: String,
/// External node connection URL.
external_node_url: Option<String>,
}
/// Wallet configuration file name.
const CONFIG_FILE_NAME: &'static str = "grim-wallet.toml";
impl WalletConfig {
/// Create wallet config.
pub fn create(id: OsString, name: String) -> WalletConfig {
let config_path = Self::get_config_path(&id);
let config = WalletConfig {
id,
name,
external_node_url: None,
};
Settings::write_to_file(&config, config_path);
config
}
/// Load config from provided wallet dir.
pub fn load(wallet_dir: PathBuf) -> Option<WalletConfig> {
let mut config_path: PathBuf = wallet_dir.clone();
config_path.push(CONFIG_FILE_NAME);
if let Ok(config) = Settings::read_from_file::<WalletConfig>(config_path) {
return Some(config)
}
None
}
/// Get config file path for provided wallet identifier.
fn get_config_path(id: &OsString) -> PathBuf {
let chain_type = AppConfig::chain_type();
let mut config_path = WalletList::get_wallets_base_dir(&chain_type);
config_path.push(id);
config_path.push(CONFIG_FILE_NAME);
config_path
}
/// Save wallet config.
fn save(&self) {
let config_path = Self::get_config_path(&self.id);
Settings::write_to_file(self, config_path);
}
/// Get readable wallet name.
pub fn get_name(&self) -> &String {
&self.name
}
/// Set readable wallet name.
pub fn set_name(&mut self, name: String) {
self.name = name;
self.save();
}
/// Get external node connection URL.
pub fn get_external_node_url(&self) -> &Option<String> {
&self.external_node_url
}
/// Set external node connection URL.
pub fn set_external_node_url(&mut self, url: Option<String>) {
self.external_node_url = url;
self.save();
}
}
+81
View File
@@ -0,0 +1,81 @@
// Copyright 2023 The Grim Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::fs;
use std::path::PathBuf;
use std::sync::{Arc, RwLock};
use grin_core::global::ChainTypes;
use lazy_static::lazy_static;
use crate::{AppConfig, Settings};
use crate::wallet::Wallet;
lazy_static! {
/// Global wallets state.
static ref WALLETS_STATE: Arc<RwLock<WalletList >> = Arc::new(RwLock::new(WalletList::load()));
}
/// List of created wallets.
pub struct WalletList {
list: Vec<Wallet>
}
/// Base wallets directory name.
pub const BASE_DIR_NAME: &'static str = "wallets";
impl WalletList {
/// Load list of wallets.
fn load() -> Self {
Self { list: Self::load_wallets(&AppConfig::chain_type()) }
}
/// Load wallets for provided [`ChainType`].
fn load_wallets(chain_type: &ChainTypes) -> Vec<Wallet> {
let mut wallets = Vec::new();
let wallets_dir = Self::get_wallets_base_dir(chain_type);
// Load wallets from directory.
for dir in wallets_dir.read_dir().unwrap() {
let wallet = Wallet::load(dir.unwrap().path());
if let Some(w) = wallet {
wallets.push(w);
}
continue;
}
wallets
}
/// Get wallets base directory for provided [`ChainTypes`].
pub fn get_wallets_base_dir(chain_type: &ChainTypes) -> PathBuf {
let mut wallets_path = Settings::get_base_path(Some(chain_type.shortname()));
wallets_path.push(BASE_DIR_NAME);
// Create wallets directory if it doesn't exist.
if !wallets_path.exists() {
let _ = fs::create_dir_all(wallets_path.clone());
}
wallets_path
}
/// Get list of wallets.
pub fn list() -> Vec<Wallet> {
let r_state = WALLETS_STATE.read().unwrap();
r_state.list.clone()
}
/// Reload list of wallets for provided [`ChainTypes`].
pub fn reload(chain_type: &ChainTypes) {
let mut w_state = WALLETS_STATE.write().unwrap();
w_state.list = Self::load_wallets(chain_type);
}
}
+6 -1
View File
@@ -13,5 +13,10 @@
// limitations under the License.
mod wallet;
pub use wallet::Wallet;
// pub use self::wallet::{init, init_from_seed};
mod config;
pub use config::*;
mod list;
pub use list::WalletList;
+48
View File
@@ -12,3 +12,51 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use std::ffi::OsString;
use std::path::PathBuf;
use crate::node::NodeConfig;
use crate::wallet::WalletConfig;
/// Wallet loaded from config.
#[derive(Clone)]
pub struct Wallet {
/// Identifier for a wallet, name of wallet directory.
id: OsString,
/// Base path for wallet data.
pub(crate) path: String,
/// Loaded file config.
pub(crate) config: WalletConfig,
}
impl Wallet {
/// Create new wallet from provided name.
pub fn create(name: String ) {
}
/// Load wallet from provided data path.
pub fn load(data_path: PathBuf) -> Option<Wallet> {
if !data_path.is_dir() {
return None;
}
let wallet_config = WalletConfig::load(data_path.clone());
if let Some(config) = wallet_config {
// Set id as wallet directory name.
let id = data_path.file_name().unwrap().to_os_string();
let path = data_path.to_str().unwrap().to_string();
return Some(Self { id, path, config });
}
None
}
/// Get wallet node connection URL.
pub fn get_connection_url(&self) -> String {
match self.config.get_external_node_url() {
None => {
format!("http://{}", NodeConfig::get_api_address())
}
Some(url) => url.to_string()
}
}
}