2025-12-31 04:02:25 +03:00
|
|
|
use std::{
|
2026-01-07 13:13:14 +11:00
|
|
|
collections::HashMap,
|
2025-12-31 04:02:25 +03:00
|
|
|
io::{BufReader, Write as _},
|
|
|
|
|
path::Path,
|
2026-03-14 03:20:37 +03:00
|
|
|
str::FromStr as _,
|
2026-02-24 20:52:14 +03:00
|
|
|
time::Duration,
|
2025-12-31 04:02:25 +03:00
|
|
|
};
|
2025-12-08 18:26:35 +03:00
|
|
|
|
2025-12-31 04:02:25 +03:00
|
|
|
use anyhow::{Context as _, Result};
|
2026-01-29 22:20:42 +03:00
|
|
|
use common::config::BasicAuth;
|
2026-02-24 20:52:14 +03:00
|
|
|
use humantime_serde;
|
2025-11-10 16:29:33 +02:00
|
|
|
use key_protocol::key_management::{
|
|
|
|
|
KeyChain,
|
|
|
|
|
key_tree::{
|
|
|
|
|
chain_index::ChainIndex, keys_private::ChildKeysPrivate, keys_public::ChildKeysPublic,
|
|
|
|
|
},
|
|
|
|
|
};
|
2025-12-31 04:02:25 +03:00
|
|
|
use log::warn;
|
2025-08-19 14:14:09 +03:00
|
|
|
use serde::{Deserialize, Serialize};
|
2026-01-29 22:20:42 +03:00
|
|
|
use url::Url;
|
2024-12-03 09:32:35 +02:00
|
|
|
|
2025-08-19 14:14:09 +03:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
2025-09-11 18:32:46 +03:00
|
|
|
pub struct InitialAccountDataPublic {
|
2026-01-29 22:20:42 +03:00
|
|
|
pub account_id: nssa::AccountId,
|
2025-08-19 14:14:09 +03:00
|
|
|
pub pub_sign_key: nssa::PrivateKey,
|
|
|
|
|
}
|
2025-02-28 12:32:54 +02:00
|
|
|
|
2025-09-02 09:01:33 +03:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
2025-09-11 18:32:46 +03:00
|
|
|
pub struct PersistentAccountDataPublic {
|
2025-11-24 17:09:30 +03:00
|
|
|
pub account_id: nssa::AccountId,
|
2025-11-10 16:29:33 +02:00
|
|
|
pub chain_index: ChainIndex,
|
|
|
|
|
pub data: ChildKeysPublic,
|
2025-09-02 09:01:33 +03:00
|
|
|
}
|
|
|
|
|
|
2025-09-11 18:32:46 +03:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
|
|
|
pub struct InitialAccountDataPrivate {
|
2026-01-29 22:20:42 +03:00
|
|
|
pub account_id: nssa::AccountId,
|
2025-09-11 18:32:46 +03:00
|
|
|
pub account: nssa_core::account::Account,
|
|
|
|
|
pub key_chain: KeyChain,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
|
|
|
pub struct PersistentAccountDataPrivate {
|
2025-11-24 17:09:30 +03:00
|
|
|
pub account_id: nssa::AccountId,
|
2025-11-10 16:29:33 +02:00
|
|
|
pub chain_index: ChainIndex,
|
|
|
|
|
pub data: ChildKeysPrivate,
|
2025-09-11 18:32:46 +03:00
|
|
|
}
|
|
|
|
|
|
2025-11-26 00:27:20 +03:00
|
|
|
// Big difference in enum variants sizes
|
|
|
|
|
// however it is improbable, that we will have that much accounts, that it will substantialy affect
|
|
|
|
|
// memory
|
2025-09-11 18:32:46 +03:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
|
|
|
pub enum InitialAccountData {
|
|
|
|
|
Public(InitialAccountDataPublic),
|
2026-03-04 18:42:33 +03:00
|
|
|
Private(Box<InitialAccountDataPrivate>),
|
2025-09-11 18:32:46 +03:00
|
|
|
}
|
|
|
|
|
|
2025-11-26 00:27:20 +03:00
|
|
|
// Big difference in enum variants sizes
|
|
|
|
|
// however it is improbable, that we will have that much accounts, that it will substantialy affect
|
|
|
|
|
// memory
|
2025-09-11 18:32:46 +03:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
|
|
|
pub enum PersistentAccountData {
|
|
|
|
|
Public(PersistentAccountDataPublic),
|
2026-03-04 18:42:33 +03:00
|
|
|
Private(Box<PersistentAccountDataPrivate>),
|
2025-11-11 12:15:20 +02:00
|
|
|
Preconfigured(InitialAccountData),
|
2025-09-11 18:32:46 +03:00
|
|
|
}
|
|
|
|
|
|
2026-01-07 13:13:14 +11:00
|
|
|
/// A human-readable label for an account.
|
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
|
|
|
|
pub struct Label(String);
|
|
|
|
|
|
|
|
|
|
impl Label {
|
2026-03-03 23:21:08 +03:00
|
|
|
#[must_use]
|
2026-03-09 18:27:56 +03:00
|
|
|
pub const fn new(label: String) -> Self {
|
2026-01-07 13:13:14 +11:00
|
|
|
Self(label)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl std::fmt::Display for Label {
|
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
|
write!(f, "{}", self.0)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-28 16:02:30 +02:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
|
|
|
pub struct PersistentStorage {
|
|
|
|
|
pub accounts: Vec<PersistentAccountData>,
|
|
|
|
|
pub last_synced_block: u64,
|
2026-01-07 13:13:14 +11:00
|
|
|
/// Account labels keyed by account ID string (e.g.,
|
2026-03-10 00:17:43 +03:00
|
|
|
/// "2rnKprXqWGWJTkDZKsQbFXa4ctKRbapsdoTKQFnaVGG8").
|
2026-01-07 13:13:14 +11:00
|
|
|
#[serde(default)]
|
|
|
|
|
pub labels: HashMap<String, Label>,
|
2025-10-28 16:02:30 +02:00
|
|
|
}
|
|
|
|
|
|
2025-12-31 04:02:25 +03:00
|
|
|
impl PersistentStorage {
|
|
|
|
|
pub fn from_path(path: &Path) -> Result<Self> {
|
2026-03-04 18:42:33 +03:00
|
|
|
#[expect(
|
|
|
|
|
clippy::wildcard_enum_match_arm,
|
|
|
|
|
reason = "We want to provide a specific error message for not found case"
|
|
|
|
|
)]
|
2025-12-31 04:02:25 +03:00
|
|
|
match std::fs::File::open(path) {
|
|
|
|
|
Ok(file) => {
|
|
|
|
|
let storage_content = BufReader::new(file);
|
|
|
|
|
Ok(serde_json::from_reader(storage_content)?)
|
|
|
|
|
}
|
|
|
|
|
Err(err) => match err.kind() {
|
|
|
|
|
std::io::ErrorKind::NotFound => {
|
|
|
|
|
anyhow::bail!("Not found, please setup roots from config command beforehand");
|
|
|
|
|
}
|
|
|
|
|
_ => {
|
|
|
|
|
anyhow::bail!("IO error {err:#?}");
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-11 18:32:46 +03:00
|
|
|
impl InitialAccountData {
|
2026-03-03 23:21:08 +03:00
|
|
|
#[must_use]
|
2025-11-24 17:09:30 +03:00
|
|
|
pub fn account_id(&self) -> nssa::AccountId {
|
2025-09-11 18:32:46 +03:00
|
|
|
match &self {
|
2026-01-29 22:20:42 +03:00
|
|
|
Self::Public(acc) => acc.account_id,
|
|
|
|
|
Self::Private(acc) => acc.account_id,
|
2025-09-11 18:32:46 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl PersistentAccountData {
|
2026-03-03 23:21:08 +03:00
|
|
|
#[must_use]
|
2025-11-24 17:09:30 +03:00
|
|
|
pub fn account_id(&self) -> nssa::AccountId {
|
2025-09-11 18:32:46 +03:00
|
|
|
match &self {
|
2025-11-24 17:09:30 +03:00
|
|
|
Self::Public(acc) => acc.account_id,
|
|
|
|
|
Self::Private(acc) => acc.account_id,
|
2025-11-27 13:46:35 +02:00
|
|
|
Self::Preconfigured(acc) => acc.account_id(),
|
2025-09-11 18:32:46 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<InitialAccountDataPublic> for InitialAccountData {
|
|
|
|
|
fn from(value: InitialAccountDataPublic) -> Self {
|
|
|
|
|
Self::Public(value)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<InitialAccountDataPrivate> for InitialAccountData {
|
|
|
|
|
fn from(value: InitialAccountDataPrivate) -> Self {
|
2026-03-04 18:42:33 +03:00
|
|
|
Self::Private(Box::new(value))
|
2025-09-11 18:32:46 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<PersistentAccountDataPublic> for PersistentAccountData {
|
|
|
|
|
fn from(value: PersistentAccountDataPublic) -> Self {
|
|
|
|
|
Self::Public(value)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<PersistentAccountDataPrivate> for PersistentAccountData {
|
|
|
|
|
fn from(value: PersistentAccountDataPrivate) -> Self {
|
2026-03-04 18:42:33 +03:00
|
|
|
Self::Private(Box::new(value))
|
2025-09-11 18:32:46 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-11 12:15:20 +02:00
|
|
|
impl From<InitialAccountData> for PersistentAccountData {
|
|
|
|
|
fn from(value: InitialAccountData) -> Self {
|
|
|
|
|
Self::Preconfigured(value)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-28 12:32:54 +02:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
|
|
|
pub struct GasConfig {
|
2026-03-10 00:17:43 +03:00
|
|
|
/// Gas spent per deploying one byte of data.
|
2025-02-28 12:32:54 +02:00
|
|
|
pub gas_fee_per_byte_deploy: u64,
|
2026-03-10 00:17:43 +03:00
|
|
|
/// Gas spent per reading one byte of data in VM.
|
2025-02-28 12:32:54 +02:00
|
|
|
pub gas_fee_per_input_buffer_runtime: u64,
|
2026-03-10 00:17:43 +03:00
|
|
|
/// Gas spent per one byte of contract data in runtime.
|
2025-02-28 12:32:54 +02:00
|
|
|
pub gas_fee_per_byte_runtime: u64,
|
2026-03-10 00:17:43 +03:00
|
|
|
/// Cost of one gas of runtime in public balance.
|
2025-02-28 12:32:54 +02:00
|
|
|
pub gas_cost_runtime: u64,
|
2026-03-10 00:17:43 +03:00
|
|
|
/// Cost of one gas of deployment in public balance.
|
2025-02-28 12:32:54 +02:00
|
|
|
pub gas_cost_deploy: u64,
|
2026-03-10 00:17:43 +03:00
|
|
|
/// Gas limit for deployment.
|
2025-02-28 12:32:54 +02:00
|
|
|
pub gas_limit_deploy: u64,
|
2026-03-10 00:17:43 +03:00
|
|
|
/// Gas limit for runtime.
|
2025-02-28 12:32:54 +02:00
|
|
|
pub gas_limit_runtime: u64,
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-03 19:04:41 -03:00
|
|
|
#[optfield::optfield(pub WalletConfigOverrides, rewrap, attrs = (derive(Debug, Default, Clone)))]
|
2024-12-03 09:32:35 +02:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
2025-08-11 08:55:08 +03:00
|
|
|
pub struct WalletConfig {
|
2026-03-10 00:17:43 +03:00
|
|
|
/// Sequencer URL.
|
2026-01-29 22:20:42 +03:00
|
|
|
pub sequencer_addr: Url,
|
2026-03-10 00:17:43 +03:00
|
|
|
/// Sequencer polling duration for new blocks.
|
2026-02-24 20:52:14 +03:00
|
|
|
#[serde(with = "humantime_serde")]
|
|
|
|
|
pub seq_poll_timeout: Duration,
|
2026-03-10 00:17:43 +03:00
|
|
|
/// Sequencer polling max number of blocks to find transaction.
|
2025-12-04 14:55:45 +03:00
|
|
|
pub seq_tx_poll_max_blocks: usize,
|
2026-03-10 00:17:43 +03:00
|
|
|
/// Sequencer polling max number error retries.
|
2025-08-21 15:58:31 +03:00
|
|
|
pub seq_poll_max_retries: u64,
|
2026-03-10 00:17:43 +03:00
|
|
|
/// Max amount of blocks to poll in one request.
|
2025-12-04 14:55:45 +03:00
|
|
|
pub seq_block_poll_max_amount: u64,
|
2026-03-10 00:17:43 +03:00
|
|
|
/// Initial accounts for wallet.
|
2025-08-19 14:14:09 +03:00
|
|
|
pub initial_accounts: Vec<InitialAccountData>,
|
2026-03-10 00:17:43 +03:00
|
|
|
/// Basic authentication credentials.
|
2025-12-31 04:02:25 +03:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
2025-12-08 18:26:35 +03:00
|
|
|
pub basic_auth: Option<BasicAuth>,
|
2024-12-03 09:32:35 +02:00
|
|
|
}
|
2025-10-29 13:23:07 +02:00
|
|
|
|
|
|
|
|
impl Default for WalletConfig {
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
Self {
|
2026-01-29 22:20:42 +03:00
|
|
|
sequencer_addr: "http://127.0.0.1:3040".parse().unwrap(),
|
2026-02-24 20:52:14 +03:00
|
|
|
seq_poll_timeout: Duration::from_secs(12),
|
2025-12-04 14:55:45 +03:00
|
|
|
seq_tx_poll_max_blocks: 5,
|
2025-10-29 13:23:07 +02:00
|
|
|
seq_poll_max_retries: 5,
|
2025-12-04 14:55:45 +03:00
|
|
|
seq_block_poll_max_amount: 100,
|
2025-12-08 18:26:35 +03:00
|
|
|
basic_auth: None,
|
2026-03-14 03:20:37 +03:00
|
|
|
initial_accounts: vec![
|
|
|
|
|
InitialAccountData::Public(InitialAccountDataPublic {
|
|
|
|
|
account_id: nssa::AccountId::from_str(
|
|
|
|
|
"CbgR6tj5kWx5oziiFptM7jMvrQeYY3Mzaao6ciuhSr2r",
|
|
|
|
|
)
|
|
|
|
|
.unwrap(),
|
|
|
|
|
pub_sign_key: nssa::PrivateKey::try_new([
|
|
|
|
|
127, 39, 48, 152, 242, 91, 113, 230, 192, 5, 169, 81, 159, 38, 120, 218,
|
|
|
|
|
141, 28, 127, 1, 246, 162, 119, 120, 226, 217, 148, 138, 189, 249, 1, 251,
|
|
|
|
|
])
|
|
|
|
|
.unwrap(),
|
|
|
|
|
}),
|
|
|
|
|
InitialAccountData::Public(InitialAccountDataPublic {
|
|
|
|
|
account_id: nssa::AccountId::from_str(
|
|
|
|
|
"7wHg9sbJwc6h3NP1S9bekfAzB8CHifEcxKswCKUt3YQo",
|
|
|
|
|
)
|
|
|
|
|
.unwrap(),
|
|
|
|
|
pub_sign_key: nssa::PrivateKey::try_new([
|
|
|
|
|
244, 52, 248, 116, 23, 32, 1, 69, 134, 174, 67, 53, 109, 42, 236, 98, 87,
|
|
|
|
|
218, 8, 98, 34, 246, 4, 221, 183, 93, 105, 115, 59, 134, 252, 76,
|
|
|
|
|
])
|
|
|
|
|
.unwrap(),
|
|
|
|
|
}),
|
|
|
|
|
InitialAccountData::Private(Box::new(InitialAccountDataPrivate {
|
|
|
|
|
account_id: nssa::AccountId::from_str(
|
|
|
|
|
"HWkW5qd4XK3me6sCAb4bfPj462k33DjtKtEcYpuzNwB",
|
|
|
|
|
)
|
|
|
|
|
.unwrap(),
|
|
|
|
|
account: nssa::Account {
|
|
|
|
|
balance: 10_000,
|
|
|
|
|
..Default::default()
|
2025-10-29 13:23:07 +02:00
|
|
|
},
|
2026-03-14 03:20:37 +03:00
|
|
|
key_chain: KeyChain::new_mnemonic("default_private_account_1".to_owned()),
|
|
|
|
|
})),
|
|
|
|
|
InitialAccountData::Private(Box::new(InitialAccountDataPrivate {
|
|
|
|
|
account_id: nssa::AccountId::from_str(
|
|
|
|
|
"HUpbRQ1vEcZv5y6TDYv9tpt1VA64ji2v4RDLJfK2rpZn",
|
|
|
|
|
)
|
|
|
|
|
.unwrap(),
|
|
|
|
|
account: nssa::Account {
|
|
|
|
|
balance: 20_000,
|
|
|
|
|
..Default::default()
|
2025-10-29 13:23:07 +02:00
|
|
|
},
|
2026-03-14 03:20:37 +03:00
|
|
|
key_chain: KeyChain::new_mnemonic("default_private_account_2".to_owned()),
|
|
|
|
|
})),
|
|
|
|
|
],
|
2025-10-29 13:23:07 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-12-31 04:02:25 +03:00
|
|
|
|
|
|
|
|
impl WalletConfig {
|
2026-03-09 18:27:56 +03:00
|
|
|
pub fn from_path_or_initialize_default(config_path: &Path) -> Result<Self> {
|
2025-12-31 04:02:25 +03:00
|
|
|
match std::fs::File::open(config_path) {
|
|
|
|
|
Ok(file) => {
|
|
|
|
|
let reader = std::io::BufReader::new(file);
|
|
|
|
|
Ok(serde_json::from_reader(reader)?)
|
|
|
|
|
}
|
|
|
|
|
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
|
|
|
|
|
println!("Config not found, setting up default config");
|
|
|
|
|
|
|
|
|
|
let config_home = config_path.parent().ok_or_else(|| {
|
|
|
|
|
anyhow::anyhow!(
|
2026-03-03 23:21:08 +03:00
|
|
|
"Could not get parent directory of config file at {}",
|
|
|
|
|
config_path.display()
|
2025-12-31 04:02:25 +03:00
|
|
|
)
|
|
|
|
|
})?;
|
|
|
|
|
std::fs::create_dir_all(config_home)?;
|
|
|
|
|
|
2026-03-03 23:21:08 +03:00
|
|
|
println!("Created configs dir at path {}", config_home.display());
|
2025-12-31 04:02:25 +03:00
|
|
|
|
|
|
|
|
let mut file = std::fs::OpenOptions::new()
|
|
|
|
|
.write(true)
|
|
|
|
|
.create(true)
|
|
|
|
|
.truncate(true)
|
|
|
|
|
.open(config_path)?;
|
|
|
|
|
|
2026-03-09 18:27:56 +03:00
|
|
|
let config = Self::default();
|
2025-12-31 04:02:25 +03:00
|
|
|
let default_config_serialized = serde_json::to_vec_pretty(&config).unwrap();
|
|
|
|
|
|
|
|
|
|
file.write_all(&default_config_serialized)?;
|
|
|
|
|
|
|
|
|
|
println!("Configs set up");
|
|
|
|
|
Ok(config)
|
|
|
|
|
}
|
|
|
|
|
Err(err) => Err(err).context("IO error"),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn apply_overrides(&mut self, overrides: WalletConfigOverrides) {
|
2026-03-09 18:27:56 +03:00
|
|
|
let Self {
|
2025-12-31 04:02:25 +03:00
|
|
|
sequencer_addr,
|
2026-02-24 20:52:14 +03:00
|
|
|
seq_poll_timeout,
|
2025-12-31 04:02:25 +03:00
|
|
|
seq_tx_poll_max_blocks,
|
|
|
|
|
seq_poll_max_retries,
|
|
|
|
|
seq_block_poll_max_amount,
|
|
|
|
|
initial_accounts,
|
|
|
|
|
basic_auth,
|
|
|
|
|
} = self;
|
|
|
|
|
|
|
|
|
|
let WalletConfigOverrides {
|
|
|
|
|
sequencer_addr: o_sequencer_addr,
|
2026-02-24 20:52:14 +03:00
|
|
|
seq_poll_timeout: o_seq_poll_timeout,
|
2025-12-31 04:02:25 +03:00
|
|
|
seq_tx_poll_max_blocks: o_seq_tx_poll_max_blocks,
|
|
|
|
|
seq_poll_max_retries: o_seq_poll_max_retries,
|
|
|
|
|
seq_block_poll_max_amount: o_seq_block_poll_max_amount,
|
|
|
|
|
initial_accounts: o_initial_accounts,
|
|
|
|
|
basic_auth: o_basic_auth,
|
|
|
|
|
} = overrides;
|
|
|
|
|
|
|
|
|
|
if let Some(v) = o_sequencer_addr {
|
|
|
|
|
warn!("Overriding wallet config 'sequencer_addr' to {v}");
|
|
|
|
|
*sequencer_addr = v;
|
|
|
|
|
}
|
2026-02-24 20:52:14 +03:00
|
|
|
if let Some(v) = o_seq_poll_timeout {
|
|
|
|
|
warn!("Overriding wallet config 'seq_poll_timeout' to {v:?}");
|
|
|
|
|
*seq_poll_timeout = v;
|
2025-12-31 04:02:25 +03:00
|
|
|
}
|
|
|
|
|
if let Some(v) = o_seq_tx_poll_max_blocks {
|
|
|
|
|
warn!("Overriding wallet config 'seq_tx_poll_max_blocks' to {v}");
|
|
|
|
|
*seq_tx_poll_max_blocks = v;
|
|
|
|
|
}
|
|
|
|
|
if let Some(v) = o_seq_poll_max_retries {
|
|
|
|
|
warn!("Overriding wallet config 'seq_poll_max_retries' to {v}");
|
|
|
|
|
*seq_poll_max_retries = v;
|
|
|
|
|
}
|
|
|
|
|
if let Some(v) = o_seq_block_poll_max_amount {
|
|
|
|
|
warn!("Overriding wallet config 'seq_block_poll_max_amount' to {v}");
|
|
|
|
|
*seq_block_poll_max_amount = v;
|
|
|
|
|
}
|
|
|
|
|
if let Some(v) = o_initial_accounts {
|
|
|
|
|
warn!("Overriding wallet config 'initial_accounts' to {v:#?}");
|
|
|
|
|
*initial_accounts = v;
|
|
|
|
|
}
|
|
|
|
|
if let Some(v) = o_basic_auth {
|
|
|
|
|
warn!("Overriding wallet config 'basic_auth' to {v:#?}");
|
|
|
|
|
*basic_auth = v;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|