Append wallet settings to file during creation
This commit is contained in:
parent
e85f89dc7f
commit
58bccef4cd
@ -148,11 +148,6 @@ impl Backup {
|
||||
};
|
||||
|
||||
let name = if let Some(settings) = settings {
|
||||
assert_eq!(settings.wallets.len(), 1);
|
||||
if settings.wallets.len() != 1 {
|
||||
return Err(Error::NotSingleWallet);
|
||||
}
|
||||
let settings = settings.wallets.first().expect("only one wallet");
|
||||
let name = settings.name.clone();
|
||||
if let Ok(settings) = serde_json::to_value(settings) {
|
||||
proprietary.insert(SETTINGS_KEY.to_string(), settings);
|
||||
|
||||
@ -2,7 +2,7 @@ use liana::miniscript::{
|
||||
bitcoin::{bip32::Fingerprint, Network},
|
||||
DescriptorPublicKey,
|
||||
};
|
||||
use std::{collections::HashMap, path::PathBuf};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use super::{context, Error};
|
||||
use crate::{
|
||||
@ -28,7 +28,11 @@ use crate::{
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Message {
|
||||
UserActionDone(bool),
|
||||
Exit(PathBuf, Option<Bitcoind>, /* remove log */ bool),
|
||||
Exit(
|
||||
Box<settings::WalletSettings>,
|
||||
Option<Bitcoind>,
|
||||
/* remove log */ bool,
|
||||
),
|
||||
Clibpboard(String),
|
||||
Next,
|
||||
Skip,
|
||||
@ -39,7 +43,7 @@ pub enum Message {
|
||||
Reload,
|
||||
Select(usize),
|
||||
UseHotSigner,
|
||||
Installed(Result<PathBuf, Error>),
|
||||
Installed(Result<settings::WalletSettings, Error>),
|
||||
CreateTaprootDescriptor(bool),
|
||||
SelectDescriptorTemplate(context::DescriptorTemplate),
|
||||
SelectBackend(SelectBackend),
|
||||
|
||||
@ -23,7 +23,7 @@ use std::sync::{Arc, Mutex};
|
||||
use crate::{
|
||||
app::{
|
||||
config as gui_config,
|
||||
settings::{self as gui_settings, AuthConfig, Settings, SettingsError, WalletSettings},
|
||||
settings::{update_settings_file, AuthConfig, SettingsError, WalletSettings},
|
||||
wallet::wallet_name,
|
||||
},
|
||||
backup,
|
||||
@ -362,7 +362,7 @@ pub fn daemon_check(cfg: lianad::config::Config) -> Result<(), Error> {
|
||||
pub async fn install_local_wallet(
|
||||
ctx: Context,
|
||||
signer: Arc<Mutex<Signer>>,
|
||||
) -> Result<PathBuf, Error> {
|
||||
) -> Result<WalletSettings, Error> {
|
||||
let network_datadir = ctx
|
||||
.liana_directory
|
||||
.network_directory(ctx.bitcoin_config.network);
|
||||
@ -412,7 +412,7 @@ pub async fn install_local_wallet(
|
||||
}
|
||||
|
||||
// create liana GUI configuration file
|
||||
let gui_config_path = create_and_write_file(
|
||||
let _gui_config_path = create_and_write_file(
|
||||
&network_datadir,
|
||||
gui_config::DEFAULT_FILE_NAME,
|
||||
toml::to_string(&gui_config::Config::new(
|
||||
@ -426,25 +426,24 @@ pub async fn install_local_wallet(
|
||||
info!("Gui configuration file created");
|
||||
|
||||
// create liana GUI settings file
|
||||
let settings: gui_settings::Settings = extract_local_gui_settings(&ctx);
|
||||
create_and_write_file(
|
||||
&network_datadir,
|
||||
gui_settings::DEFAULT_FILE_NAME,
|
||||
serde_json::to_string_pretty(&settings)
|
||||
.map_err(|e| Error::Unexpected(format!("Failed to serialize settings: {}", e)))?
|
||||
.as_bytes(),
|
||||
)?;
|
||||
let wallet_settings = extract_local_gui_settings(&ctx);
|
||||
update_settings_file(&network_datadir, |mut settings| {
|
||||
settings.wallets.push(wallet_settings.clone());
|
||||
settings
|
||||
})
|
||||
.await
|
||||
.map_err(|e| Error::Unexpected(e.to_string()))?;
|
||||
|
||||
info!("Settings file created");
|
||||
|
||||
Ok(gui_config_path)
|
||||
Ok(wallet_settings)
|
||||
}
|
||||
|
||||
pub async fn create_remote_wallet(
|
||||
ctx: Context,
|
||||
signer: Arc<Mutex<Signer>>,
|
||||
remote_backend: BackendClient,
|
||||
) -> Result<PathBuf, Error> {
|
||||
) -> Result<WalletSettings, Error> {
|
||||
let network_datadir = ctx.liana_directory.network_directory(ctx.network);
|
||||
network_datadir
|
||||
.init()
|
||||
@ -477,7 +476,7 @@ pub async fn create_remote_wallet(
|
||||
}
|
||||
|
||||
// create liana GUI configuration file
|
||||
let gui_config_path = create_and_write_file(
|
||||
let _gui_config_path = create_and_write_file(
|
||||
&network_datadir,
|
||||
gui_config::DEFAULT_FILE_NAME,
|
||||
toml::to_string(&gui_config::Config {
|
||||
@ -540,14 +539,13 @@ pub async fn create_remote_wallet(
|
||||
let remote_backend = remote_backend.connect_wallet(wallet).0;
|
||||
|
||||
// create liana GUI settings file
|
||||
let settings: gui_settings::Settings = extract_remote_gui_settings(&ctx, &remote_backend).await;
|
||||
create_and_write_file(
|
||||
&network_datadir,
|
||||
gui_settings::DEFAULT_FILE_NAME,
|
||||
serde_json::to_string_pretty(&settings)
|
||||
.map_err(|e| Error::Unexpected(format!("Failed to serialize settings: {}", e)))?
|
||||
.as_bytes(),
|
||||
)?;
|
||||
let wallet_settings = extract_remote_gui_settings(&ctx, &remote_backend).await;
|
||||
update_settings_file(&network_datadir, |mut settings| {
|
||||
settings.wallets.push(wallet_settings.clone());
|
||||
settings
|
||||
})
|
||||
.await
|
||||
.map_err(|e| Error::Unexpected(e.to_string()))?;
|
||||
|
||||
info!("Settings file created");
|
||||
|
||||
@ -567,13 +565,13 @@ pub async fn create_remote_wallet(
|
||||
info!("Liana-Connect cache updated");
|
||||
};
|
||||
|
||||
Ok(gui_config_path)
|
||||
Ok(wallet_settings)
|
||||
}
|
||||
|
||||
pub async fn import_remote_wallet(
|
||||
ctx: Context,
|
||||
backend: BackendWalletClient,
|
||||
) -> Result<PathBuf, Error> {
|
||||
) -> Result<WalletSettings, Error> {
|
||||
tracing::info!("Importing wallet from remote backend");
|
||||
|
||||
if let Some(signer) = &ctx.recovered_signer {
|
||||
@ -590,19 +588,18 @@ pub async fn import_remote_wallet(
|
||||
.map_err(|e| Error::Unexpected(format!("Failed to create datadir path: {}", e)))?;
|
||||
|
||||
// create liana GUI settings file
|
||||
let settings: gui_settings::Settings = extract_remote_gui_settings(&ctx, &backend).await;
|
||||
create_and_write_file(
|
||||
&network_datadir,
|
||||
gui_settings::DEFAULT_FILE_NAME,
|
||||
serde_json::to_string_pretty(&settings)
|
||||
.map_err(|e| Error::Unexpected(format!("Failed to serialize settings: {}", e)))?
|
||||
.as_bytes(),
|
||||
)?;
|
||||
let wallet_settings = extract_remote_gui_settings(&ctx, &backend).await;
|
||||
update_settings_file(&network_datadir, |mut settings| {
|
||||
settings.wallets.push(wallet_settings.clone());
|
||||
settings
|
||||
})
|
||||
.await
|
||||
.map_err(|e| Error::Unexpected(e.to_string()))?;
|
||||
|
||||
info!("Settings file created");
|
||||
|
||||
// create liana GUI configuration file
|
||||
let gui_config_path = create_and_write_file(
|
||||
let _gui_config_path = create_and_write_file(
|
||||
&network_datadir,
|
||||
gui_config::DEFAULT_FILE_NAME,
|
||||
toml::to_string(&gui_config::Config {
|
||||
@ -632,7 +629,7 @@ pub async fn import_remote_wallet(
|
||||
info!("Liana-Connect cache updated");
|
||||
};
|
||||
|
||||
Ok(gui_config_path)
|
||||
Ok(wallet_settings)
|
||||
}
|
||||
|
||||
pub fn create_and_write_file(
|
||||
@ -651,7 +648,10 @@ pub fn create_and_write_file(
|
||||
|
||||
// if the wallet is using the remote backend, then the hardware wallet settings and
|
||||
// keys will be store on the remote backend side and not in the settings file.
|
||||
pub async fn extract_remote_gui_settings(ctx: &Context, backend: &BackendWalletClient) -> Settings {
|
||||
pub async fn extract_remote_gui_settings(
|
||||
ctx: &Context,
|
||||
backend: &BackendWalletClient,
|
||||
) -> WalletSettings {
|
||||
let descriptor = ctx
|
||||
.descriptor
|
||||
.as_ref()
|
||||
@ -664,23 +664,21 @@ pub async fn extract_remote_gui_settings(ctx: &Context, backend: &BackendWalletC
|
||||
.expect("LianaDescriptor.to_string() always include the checksum")
|
||||
.to_string();
|
||||
|
||||
Settings {
|
||||
wallets: vec![WalletSettings {
|
||||
name: wallet_name(descriptor),
|
||||
descriptor_checksum,
|
||||
pinned_at: Some(chrono::Utc::now().timestamp()),
|
||||
keys: Vec::new(),
|
||||
hardware_wallets: Vec::new(),
|
||||
remote_backend_auth: Some(AuthConfig::new(
|
||||
backend.user_email().to_string(),
|
||||
backend.wallet_id(),
|
||||
)),
|
||||
start_internal_bitcoind: None,
|
||||
}],
|
||||
WalletSettings {
|
||||
name: wallet_name(descriptor),
|
||||
descriptor_checksum,
|
||||
pinned_at: Some(chrono::Utc::now().timestamp()),
|
||||
keys: Vec::new(),
|
||||
hardware_wallets: Vec::new(),
|
||||
remote_backend_auth: Some(AuthConfig::new(
|
||||
backend.user_email().to_string(),
|
||||
backend.wallet_id(),
|
||||
)),
|
||||
start_internal_bitcoind: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extract_local_gui_settings(ctx: &Context) -> Settings {
|
||||
pub fn extract_local_gui_settings(ctx: &Context) -> WalletSettings {
|
||||
let descriptor = ctx
|
||||
.descriptor
|
||||
.as_ref()
|
||||
@ -702,16 +700,14 @@ pub fn extract_local_gui_settings(ctx: &Context) -> Settings {
|
||||
.map(|token| HardwareWalletConfig::new(kind, *fingerprint, token))
|
||||
})
|
||||
.collect();
|
||||
Settings {
|
||||
wallets: vec![WalletSettings {
|
||||
name: wallet_name(descriptor),
|
||||
pinned_at: Some(chrono::Utc::now().timestamp()),
|
||||
descriptor_checksum,
|
||||
keys: ctx.keys.values().cloned().collect(),
|
||||
hardware_wallets,
|
||||
remote_backend_auth: None,
|
||||
start_internal_bitcoind: Some(ctx.internal_bitcoind.is_some()),
|
||||
}],
|
||||
WalletSettings {
|
||||
name: wallet_name(descriptor),
|
||||
pinned_at: Some(chrono::Utc::now().timestamp()),
|
||||
descriptor_checksum,
|
||||
keys: ctx.keys.values().cloned().collect(),
|
||||
hardware_wallets,
|
||||
remote_backend_auth: None,
|
||||
start_internal_bitcoind: Some(ctx.internal_bitcoind.is_some()),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -21,14 +21,14 @@ pub use mnemonic::{BackupMnemonic, RecoverMnemonic};
|
||||
pub use share_xpubs::ShareXpubs;
|
||||
use tracing::warn;
|
||||
|
||||
use std::{collections::HashMap, path::PathBuf};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use iced::{Subscription, Task};
|
||||
|
||||
use liana_ui::widget::*;
|
||||
|
||||
use crate::{
|
||||
app::settings::ProviderKey,
|
||||
app::settings::{ProviderKey, WalletSettings},
|
||||
hw::HardwareWallets,
|
||||
installer::{context::Context, message::Message, view},
|
||||
node::bitcoind::Bitcoind,
|
||||
@ -67,7 +67,7 @@ pub struct Final {
|
||||
generating: bool,
|
||||
internal_bitcoind: Option<Bitcoind>,
|
||||
warning: Option<String>,
|
||||
config_path: Option<PathBuf>,
|
||||
wallet_settings: Option<WalletSettings>,
|
||||
key_redemptions: HashMap<ProviderKey, Option<Result<(), services::keys::Error>>>,
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ impl Final {
|
||||
internal_bitcoind: None,
|
||||
generating: false,
|
||||
warning: None,
|
||||
config_path: None,
|
||||
wallet_settings: None,
|
||||
key_redemptions: HashMap::new(),
|
||||
}
|
||||
}
|
||||
@ -99,7 +99,7 @@ impl Step for Final {
|
||||
.collect();
|
||||
}
|
||||
fn load(&self) -> Task<Message> {
|
||||
if !self.generating && self.config_path.is_none() {
|
||||
if !self.generating && self.wallet_settings.is_none() {
|
||||
Task::perform(async {}, |_| Message::Install)
|
||||
} else {
|
||||
Task::none()
|
||||
@ -142,30 +142,30 @@ impl Step for Final {
|
||||
}
|
||||
// Now exit the installer whether or not any redemption errors occurred.
|
||||
let internal_bitcoind = self.internal_bitcoind.clone();
|
||||
let path = self.config_path.clone().expect("config path already set");
|
||||
let settings = self.wallet_settings.clone().expect("Install is done");
|
||||
// If there were any errors, don't remove the installer log.
|
||||
return Task::perform(
|
||||
async move { (path, internal_bitcoind, has_error) },
|
||||
|(path, internal_bitcoind, has_error)| {
|
||||
Message::Exit(path, internal_bitcoind, !has_error)
|
||||
async move { (settings, internal_bitcoind, has_error) },
|
||||
|(settings, internal_bitcoind, has_error)| {
|
||||
Message::Exit(Box::new(settings), internal_bitcoind, !has_error)
|
||||
},
|
||||
);
|
||||
}
|
||||
Message::Installed(res) => match res {
|
||||
Err(e) => {
|
||||
self.generating = false;
|
||||
self.config_path = None;
|
||||
self.wallet_settings = None;
|
||||
self.warning = Some(e.to_string());
|
||||
}
|
||||
Ok(path) => {
|
||||
self.config_path = Some(path.clone());
|
||||
Ok(wallet_settings) => {
|
||||
self.wallet_settings = Some(wallet_settings);
|
||||
// Now redeem any provider keys.
|
||||
return Task::perform(async move {}, |_| Message::RedeemNextKey);
|
||||
}
|
||||
},
|
||||
Message::Install => {
|
||||
self.generating = true;
|
||||
self.config_path = None;
|
||||
self.wallet_settings = None;
|
||||
self.warning = None;
|
||||
}
|
||||
_ => {}
|
||||
@ -183,7 +183,7 @@ impl Step for Final {
|
||||
progress,
|
||||
email,
|
||||
self.generating,
|
||||
self.config_path.as_ref(),
|
||||
self.wallet_settings.is_some(),
|
||||
self.warning.as_ref(),
|
||||
)
|
||||
}
|
||||
|
||||
@ -1485,7 +1485,7 @@ pub fn install<'a>(
|
||||
progress: (usize, usize),
|
||||
email: Option<&'a str>,
|
||||
generating: bool,
|
||||
config_path: Option<&std::path::PathBuf>,
|
||||
installed: bool,
|
||||
warning: Option<&'a String>,
|
||||
) -> Element<'a, Message> {
|
||||
let prev_msg = if !generating && warning.is_some() {
|
||||
@ -1501,7 +1501,7 @@ pub fn install<'a>(
|
||||
.push_maybe(warning.map(|e| card::invalid(text(e))))
|
||||
.push(if generating {
|
||||
Container::new(text("Installing..."))
|
||||
} else if config_path.is_some() {
|
||||
} else if installed {
|
||||
Container::new(
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
|
||||
@ -266,19 +266,20 @@ impl GUI {
|
||||
_ => l.update(*msg).map(|msg| Message::Login(Box::new(msg))),
|
||||
},
|
||||
(State::Installer(i), Message::Install(msg)) => {
|
||||
if let installer::Message::Exit(path, internal_bitcoind, remove_log) = *msg {
|
||||
let network_dir = i.datadir.network_directory(i.network);
|
||||
// We get the first one created.
|
||||
let settings = app::settings::WalletSettings::from_file(&network_dir, |_| true)
|
||||
.expect("A settings file was created")
|
||||
.expect("A wallet was created");
|
||||
if let Some(setting) = settings.remote_backend_auth {
|
||||
if let installer::Message::Exit(settings, internal_bitcoind, remove_log) = *msg {
|
||||
if let Some(auth) = settings.remote_backend_auth {
|
||||
let (login, command) =
|
||||
login::LianaLiteLogin::new(i.datadir.clone(), i.network, setting);
|
||||
login::LianaLiteLogin::new(i.datadir.clone(), i.network, auth);
|
||||
self.state = State::Login(Box::new(login));
|
||||
command.map(|msg| Message::Login(Box::new(msg)))
|
||||
} else {
|
||||
let cfg = app::Config::from_file(&path).expect("A config file was created");
|
||||
let cfg = app::Config::from_file(
|
||||
&i.datadir
|
||||
.network_directory(i.network)
|
||||
.path()
|
||||
.join(app::config::DEFAULT_FILE_NAME),
|
||||
)
|
||||
.expect("A gui configuration file must be present");
|
||||
|
||||
self.logger.set_running_mode(
|
||||
i.datadir.clone(),
|
||||
@ -296,7 +297,7 @@ impl GUI {
|
||||
i.network,
|
||||
internal_bitcoind,
|
||||
i.context.backup.take(),
|
||||
settings,
|
||||
*settings,
|
||||
);
|
||||
self.state = State::Loader(Box::new(loader));
|
||||
command.map(|msg| Message::Load(Box::new(msg)))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user