Skip to content

Commit fbb2610

Browse files
committed
feat: add initializing wallet config
- add config.rs to store and retrieve values - add toml and serde crates for desearilizing and reading values - update utils, commands and handlers files to use values from config.toml -refactor prepare_wallet_db fn - fix clippy issues [Issue: #192]
1 parent f100d65 commit fbb2610

File tree

10 files changed

+679
-31
lines changed

10 files changed

+679
-31
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ Changelog info is also documented on the [GitHub releases](https://github.com/bi
44
page. See [DEVELOPMENT_CYCLE.md](DEVELOPMENT_CYCLE.md) for more details.
55

66
## [Unreleased]
7+
- Add wallet configs initialization for initialiazing and saving wallet configs
8+
- Add wallet subcommand `config` to save wallet configs
79

810
## [2.0.0]
911

Cargo.lock

Lines changed: 87 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ serde_json = "1.0"
2121
thiserror = "2.0.11"
2222
tokio = { version = "1", features = ["full"] }
2323
cli-table = "0.5.0"
24+
toml = "0.8.23"
25+
serde= {version = "1.0", features = ["derive"]}
2426

2527
# Optional dependencies
2628
bdk_bitcoind_rpc = { version = "0.21.0", features = ["std"], optional = true }

Justfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,4 +99,4 @@ descriptors private wallet=default_wallet:
9999
# run any bitcoin-cli rpc command
100100
[group('rpc')]
101101
rpc command wallet=default_wallet:
102-
bitcoin-cli -datadir={{default_datadir}} -regtest -rpcwallet={{wallet}} -rpcuser={{rpc_user}} -rpcpassword={{rpc_password}} {{command}}
102+
bitcoin-cli -datadir={{default_datadir}} -regtest -rpcwallet={{wallet}} -rpcuser={{rpc_user}} -rpcpassword={{rpc_password}} {{command}}

README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,3 +202,42 @@ You can optionally return outputs of commands in human-readable, tabular format
202202
cargo run --pretty -n signet wallet -w {wallet_name} -d sqlite balance
203203
```
204204
This is available for wallet, key, repl and compile features. When ommitted, outputs default to `JSON`.
205+
206+
## Initializing Wallet Configurations with `init` Subcommand
207+
208+
The `wallet init` sub-command simplifies wallet operations by saving configuration parameters to `config.toml` in the data directory (default `~/.bdk-bitcoin/config.toml`). This allows you to run subsequent `bdk-cli wallet` commands without repeatedly specifying configuration details, easing wallet operations.
209+
210+
To initialize a wallet configuration, use the following command structure:
211+
212+
```shell
213+
cargo run --features <list-of-features> -- -n <network> wallet --wallet <wallet_name> --ext-descriptor <ext_descriptor> --int-descriptor <int_descriptor> --client-type <client_type> --url <server_url> [--database-type <database_type>] [--rpc-user <rpc_user>]
214+
[--rpc-password <rpc_password>] init
215+
```
216+
217+
For example, to initialize a wallet named `my_wallet` with `electrum` as the backend on `signet` network:
218+
219+
```shell
220+
cargo run --features electrum -- -n signet wallet -w my_wallet -e "tr(tprv8Z.../0/*)#dtdqk3dx" -i "tr(tprv8Z.../1/*)#ulgptya7" -d sqlite -c electrum -u "ssl://mempool.space:60602" init
221+
```
222+
223+
To overwrite an existing wallet configuration, use the `--force` flag after the `init` sub-command.
224+
225+
You can omit the following arguments to use their default values:
226+
227+
`network`: Defaults to `testnet`
228+
229+
`database_type`: Defaults to `sqlite`
230+
231+
#### Using Saved Configuration
232+
233+
After a wallet is initialized, you can then run `bdk-cli` wallet commands without specifying the parameters, referencing only the wallet subcommand.
234+
235+
For example, with the wallet `my_wallet` initialized, generate a new address and sync the wallet as follow:
236+
237+
```shell
238+
cargo run wallet -w my_wallet --use-config new_address
239+
240+
cargo run --features electrum wallet -w my_wallet --use-config sync
241+
```
242+
243+
Note that each wallet has its own configuration, allowing multiple wallets with different configurations.

src/commands.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,14 @@
1414
1515
#![allow(clippy::large_enum_variant)]
1616

17+
use crate::config::WalletConfig;
18+
use crate::error::BDKCliError as Error;
1719
use bdk_wallet::bitcoin::{
1820
Address, Network, OutPoint, ScriptBuf,
1921
bip32::{DerivationPath, Xpriv},
2022
};
2123
use clap::{Args, Parser, Subcommand, ValueEnum, value_parser};
24+
use std::path::Path;
2225

2326
#[cfg(any(feature = "electrum", feature = "esplora", feature = "rpc"))]
2427
use crate::utils::parse_proxy_auth;
@@ -112,6 +115,12 @@ pub enum CliSubCommand {
112115
/// Wallet operation subcommands.
113116
#[derive(Debug, Subcommand, Clone, PartialEq)]
114117
pub enum WalletSubCommand {
118+
/// Initialize a wallet configuration and save to `config.toml`.
119+
Init {
120+
/// Overwrite existing wallet configuration if it exists.
121+
#[arg(long = "force", default_value_t = false)]
122+
force: bool,
123+
},
115124
#[cfg(any(
116125
feature = "electrum",
117126
feature = "esplora",
@@ -214,6 +223,56 @@ pub struct WalletOpts {
214223
pub compactfilter_opts: CompactFilterOpts,
215224
}
216225

226+
impl WalletOpts {
227+
/// Merges optional configuration values from config.toml into the current WalletOpts.
228+
pub fn load_config(&mut self, wallet_name: &str, datadir: &Path) -> Result<(), Error> {
229+
if let Some(config) = WalletConfig::load(datadir)? {
230+
if let Ok(config_opts) = config.get_wallet_opts(wallet_name) {
231+
self.verbose = self.verbose || config_opts.verbose;
232+
#[cfg(feature = "electrum")]
233+
{
234+
self.batch_size = if self.batch_size != 10 {
235+
self.batch_size
236+
} else {
237+
config_opts.batch_size
238+
};
239+
}
240+
#[cfg(feature = "esplora")]
241+
{
242+
self.parallel_requests = if self.parallel_requests != 5 {
243+
self.parallel_requests
244+
} else {
245+
config_opts.parallel_requests
246+
};
247+
}
248+
#[cfg(feature = "rpc")]
249+
{
250+
self.basic_auth = if self.basic_auth != ("user".into(), "password".into()) {
251+
self.basic_auth.clone()
252+
} else {
253+
config_opts.basic_auth
254+
};
255+
self.cookie = self.cookie.take().or(config_opts.cookie);
256+
}
257+
#[cfg(feature = "cbf")]
258+
{
259+
if self.compactfilter_opts.conn_count == 2
260+
&& config_opts.compactfilter_opts.conn_count != 2
261+
{
262+
self.compactfilter_opts.conn_count =
263+
config_opts.compactfilter_opts.conn_count;
264+
}
265+
if self.compactfilter_opts.skip_blocks.is_none() {
266+
self.compactfilter_opts.skip_blocks =
267+
config_opts.compactfilter_opts.skip_blocks;
268+
}
269+
}
270+
}
271+
}
272+
Ok(())
273+
}
274+
}
275+
217276
/// Options to configure a SOCKS5 proxy for a blockchain client connection.
218277
#[cfg(any(feature = "electrum", feature = "esplora"))]
219278
#[derive(Debug, Args, Clone, PartialEq, Eq)]

0 commit comments

Comments
 (0)