Add saving wallet config with bdk-cli wallet config - #203

Merged
tvpeter merged 5 commits into
bitcoindevkit:masterfrom
tvpeter:feat/init-wallet-support
Jan 19, 2026
Merged

Add saving wallet config with bdk-cli wallet config#203
tvpeter merged 5 commits into
bitcoindevkit:masterfrom
tvpeter:feat/init-wallet-support

Conversation

@tvpeter

@tvpetertvpeter commented Jun 18, 2025

Copy link
Copy Markdown
Collaborator

Description

This PR adds bdk-cli wallet config command to save wallet configuration information to config.toml file in the data directory.

Fixes#192

Notes to the reviewers

  • Reusing the exported serde crate from bdk_wallet did not offer the derive feature
  • Fix out-of-bound error for shorten fn

Changelog notice

  • Add wallet subcommand config to save wallet configs
  • Add top-level wallets command to show all saved wallet configs

Checklists

Features

  • command to save a wallet config, give wallet name or a default name is used, clap enforces required options; optional -f to override existing config: wallet [-f] [-w <name>] config <wallet opts>
  • All other wallet commands require that a config exists, use wallet name or the default is used. Give error if config is missing: wallet [-w <name>] sync | balance | new_address | etc...
  • Repl uses the same wallet configs: repl [-w <name>]
  • command to list all saved wallet configs: wallets
  • throw warnings if using mainnet and saving a private descriptor in a config.

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

New Features:

  • I've added tests for the new feature
  • I've added docs for the new feature
  • I've updated CHANGELOG.md

@coveralls

coveralls commented Jun 18, 2025

Copy link
Copy Markdown

Pull Request Test Coverage Report for Build 21153320925

Details

  • 99 of 395(25.06%) changed or added relevant lines in 3 files are covered.
  • 1 unchanged line in 1 file lost coverage.
  • Overall coverage increased (+2.8%) to 10.717%

Changes Missing CoverageCovered LinesChanged/Added Lines%
src/utils.rs0430.0%
src/config.rs9615163.58%
src/handlers.rs32011.49%
Files with Coverage ReductionNew Missed Lines%
src/handlers.rs113.0%
TotalsCoverage Status
Change from base Build 20714655583:2.8%
Covered Lines:269
Relevant Lines:2510

💛 - Coveralls

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from b3966e3 to bf14df8CompareJune 19, 2025 04:32
@notmandatorynotmandatory moved this to Ready to Review in BDK-CLIJun 24, 2025
@notmandatorynotmandatory added this to the CLI 1.1.0 milestone Jun 24, 2025
@notmandatory

notmandatory commented Jun 24, 2025

Copy link
Copy Markdown
Member

I like the approach for loading the config file parameters if the file exists, but is there a reason you didn't add a CLI bdk-cli wallet init ... command in rust to create the config file rather than using just ?

Creating the config file in rust should be easier to maintain/keep in sync than your just approach and shouldn't take too much more than adding the Serialize trait to WalletConfigInner. You should be able to reuse the WalletOpts to capture the values with clap that you need to put in the config file too.

@notmandatorynotmandatory added the enhancement New feature or request label Jun 24, 2025
@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I like the approach for loading the config file parameters if the file exists, but is there a reason you didn't add a CLI bdk-cli wallet init ... command in rust to create the config file rather than using just ?

Creating the config file in rust should be easier to maintain/keep in sync than your just approach and shouldn't take too much more than adding the Serialize trait to WalletConfigInner. You should be able to reuse the WalletOpts to capture the values with clap that you need to put in the config file too.

Alright, I will update.

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from bf14df8 to 36ee973CompareJune 27, 2025 04:04
@tvpetertvpeter changed the title Add initializing wallet configuration with JustfileAdd initializing wallet configuration with bdk-cli wallet initJun 27, 2025
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 4 times, most recently from 5125cf8 to fcf7ce8CompareJune 27, 2025 10:03
@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

Alright, I will update.

@notmandatory I have updated the PR

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from f77b1da to 70a5390CompareAugust 25, 2025 19:26
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from 9461e85 to 5d9feb0CompareSeptember 1, 2025 04:20
@thunderbiscuit

Copy link
Copy Markdown
Member

I need to start keeping track of all these awesome new features I honestly see the PRs come in and can't keep up. This is super cool.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I need to start keeping track of all these awesome new features I honestly see the PRs come in and can't keep up. This is super cool.

Thank you @thunderbiscuit

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from 9549e09 to 0f6b320CompareSeptember 3, 2025 15:45
@notmandatory

Copy link
Copy Markdown
Member

I spent some time today reviewing and even though this looks like a workable way to do it and is based on my suggestion I'm afraid it's going to be a hassle to maintain. I've been experimenting with somehow using the different clap parsing functions (https://docs.rs/clap/latest/clap/trait.Parser.html) but so far haven't figured out a better way. I'd like to keep thinking about it. We might have to simplify the problem somehow such as by not trying to merge loaded and CLI args.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I'm afraid it's going to be a hassle to maintain. I've been experimenting with somehow using the different clap parsing functions (https://docs.rs/clap/latest/clap/trait.Parser.html) but so far haven't figured out a better way. I'd like to keep thinking about it. We might have to simplify the problem somehow such as by not trying to merge loaded and CLI args.

Thank you @notmandatory.
Yes, I agree that it will be challenging to maintain, as it involves two steps (pre clap parsing and after parsing) and even more difficult as they are in different locations in the codebase. I thought about moving everything to pre clap parsing based on the wallet sub-command the user has entered but that will clog the entry point as there will be lots of if...else checks.

Also, for the Parser trait, I read that it does not allow interacting with an external resource such as reading a file as I would want it.

I will also be trying out other approaches in case there is a cleaner way to handle it.

@notmandatory

notmandatory commented Sep 6, 2025

Copy link
Copy Markdown
Member

How about something like:

  1. One command to save a wallet config, give wallet name or a default name is used, clap enforces required options; optional -f to override existing config:
    wallet [-f] [-w <name>] config <wallet opts>
  2. All other wallet commands require that a config exists, use wallet name or the default is used. Give error if config is missing:
    wallet [-w <name>] sync | balance | new_address | etc...
  3. Repl uses the same wallet configs:
    repl [-w <name>]
  4. Add a command to list all available config names with summary of configured options:
    wallet list
  5. Should throw warnings if using mainnet and saving a private descriptor in a config.

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from 7cd062b to 28796caCompareOctober 5, 2025 03:50
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from 77864b4 to c5c4fdbCompareOctober 15, 2025 13:17

@notmandatorynotmandatory left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found an error when testing with testnet4, and a couple small nits should be fixed too. Otherwise this looks good.

In the future if everyone prefers the config approach it should probably become the only way to use the wallet features.

Comment threadREADME.md Outdated
Comment threadsrc/commands.rs Outdated
Comment threadsrc/utils.rs
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from c5c4fdb to 7be9a30CompareOctober 27, 2025 19:41
@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I found an error when testing with testnet4, and a couple small nits should be fixed too. Otherwise this looks good.

Thank you for catching all these.
I have updated.

In the future if everyone prefers the config approach it should probably become the only way to use the wallet features.

Yes, I agree.

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from 7be9a30 to 805d075CompareNovember 11, 2025 11:36
- 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: bitcoindevkit#192]
- rename init to config and move walletopts as
config options
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from a95a621 to 4f58575CompareJanuary 16, 2026 12:16

@thunderbiscuitthunderbiscuit left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this! I'll use it for sure once it gets in. I have two little things I want to ask, take them or leave them they're not blockers at all.

Question

When I run the example in the readme, I get the following config file:

network = "signet"
[wallets.my_wallet]
wallet = "my_wallet"network = "signet"ext_descriptor = "tr(tprv8Z.../0/*)#dtdqk3dx"int_descriptor = "tr(tprv8Z.../1/*)#ulgptya7"database_type = "sqlite"client_type = "electrum"server_url = "ssl://mempool.space:60602"batch_size = 10

The network is somehow added as a top-level key, but I suspect it's meant to only be added under the specific wallet config maybe? It doesn't prevent the cli from working as expected however so all is good there.

Comment

I always find it hard when applications require a config file but it's empty by default. I have to search in their docs to find what's available, and even then it's hard to know if you miss anything. A nicer approach is when the config file comes pre-populated, with all keys commented out to start with but they're at least all there so I can use the config file to sort of "discover" what's available in the wallet. This is not always possible for all keys, but could be cool here. When doing this you could do it 2 ways:

  1. Your config file could just come pre-made with a top-level commented section that has all keys available and the rest works as it currently does (easiest to implement). Note that you could also just add this as a codeblock in the readme (a complete list of available config options).
  2. Each newly created wallet comes with its own section of complete config keys, some active and the rest commented out.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

Thanks for this! I'll use it for sure once it gets in. I have two little things I want to ask, take them or leave them they're not blockers at all.

Question

When I run the example in the readme, I get the following config file:

network = "signet"
[wallets.my_wallet]
wallet = "my_wallet"network = "signet"ext_descriptor = "tr(tprv8Z.../0/*)#dtdqk3dx"int_descriptor = "tr(tprv8Z.../1/*)#ulgptya7"database_type = "sqlite"client_type = "electrum"server_url = "ssl://mempool.space:60602"batch_size = 10

The network is somehow added as a top-level key, but I suspect it's meant to only be added under the specific wallet config maybe? It doesn't prevent the cli from working as expected however so all is good there.

Comment

I always find it hard when applications require a config file but it's empty by default. I have to search in their docs to find what's available, and even then it's hard to know if you miss anything. A nicer approach is when the config file comes pre-populated, with all keys commented out to start with but they're at least all there so I can use the config file to sort of "discover" what's available in the wallet. This is not always possible for all keys, but could be cool here. When doing this you could do it 2 ways:

  1. Your config file could just come pre-made with a top-level commented section that has all keys available and the rest works as it currently does (easiest to implement). Note that you could also just add this as a codeblock in the readme (a complete list of available config options).
  2. Each newly created wallet comes with its own section of complete config keys, some active and the rest commented out.

Thank you for the review @thunderbiscuit
I will include this feedback in the next update as I also look at the configure_me lib to pick improvements.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

as I also look at the configure_me lib to pick improvements

I have done a quick review of configure_me, and from my perspective, it may not be suitable for the CLI's use case. It uses a declarative approach to define the config file and generates a static file that updating it requires manually editing and recompiling. It is more suitable for an application-wide configuration and will be challenging to use for a per-wallet configuration. Also, I have not seen how it can handle conditional features. Lastly, I am not sure it can integrate with clap as they seemed to serve the same purpose (might be wrong). But there are improvements that we can pick from the library, things like validation and maybe how we merge fetched values into the CLI values.

@notmandatory

Copy link
Copy Markdown
Member

thanks for looking into it, I agree we should stick with our simpler toml file approach.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

The network is somehow added as a top-level key, but I suspect it's meant to only be added under the specific wallet config maybe? It doesn't prevent the cli from working as expected however so all is good there.

Thank you for noting this. It has been fixed now

Comment

I always find it hard when applications require a config file but it's empty by default. I have to search in their docs to find what's available, and even then it's hard to know if you miss anything. A nicer approach is when the config file comes pre-populated, with all keys commented out to start with but they're at least all there so I can use the config file to sort of "discover" what's available in the wallet. This is not always possible for all keys, but could be cool here. When doing this you could do it 2 ways:

  1. Your config file could just come pre-made with a top-level commented section that has all keys available and the rest works as it currently does (easiest to implement). Note that you could also just add this as a codeblock in the readme (a complete list of available config options).
  2. Each newly created wallet comes with its own section of complete config keys, some active and the rest commented out.

I have considered this approach and agree that having a configuration file for an app is beneficial. However, I’m not sure it applies to this tool for two reasons. Firstly, we do not expect users to manually edit the config file because we want clap to validate the passed values based on the features enabled by the user. Allowing users to modify this file could lead to errors when they run wallet commands.

Secondly, this configuration is intended specifically for the wallet and does not pertain to broader application settings. Users who are not testing their wallet flows may find the config file entirely irrelevant.

- add wallets command
- add warning for using priv descriptors
- update readme
- add loading network from config
- fix review comments
- refactor config by impl TryFrom trait for
WalletOpts
- fix top-level network duplicate in config file
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from ac61b94 to be31c14CompareJanuary 19, 2026 15:18
@notmandatory
notmandatoryforce-pushed the feat/init-wallet-support branch from 87472e3 to ceb9332CompareJanuary 19, 2026 22:39
@notmandatory

Copy link
Copy Markdown
Member

I pushed ceb9332 to update README examples to use new wallet config feature.

@notmandatorynotmandatory left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK ceb9332

Looks good! much easier to use.

@tvpeter
tvpeter merged commit b9cf2ac into bitcoindevkit:masterJan 19, 2026
5 checks passed
@github-project-automationgithub-project-automationBot moved this from Ready to Review to Done in BDK-CLIJan 19, 2026
Comment threadsrc/config.rs
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

Add "init" wallet support

5 participants

@tvpeter@coveralls@notmandatory@thunderbiscuit@nymius
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Add saving wallet config with bdk-cli wallet config - #203

Merged
tvpeter merged 5 commits into
bitcoindevkit:masterfrom
tvpeter:feat/init-wallet-support
Jan 19, 2026
Merged

Add saving wallet config with bdk-cli wallet config#203
tvpeter merged 5 commits into
bitcoindevkit:masterfrom
tvpeter:feat/init-wallet-support

Conversation

@tvpeter

@tvpetertvpeter commented Jun 18, 2025

Copy link
Copy Markdown
Collaborator

Description

This PR adds bdk-cli wallet config command to save wallet configuration information to config.toml file in the data directory.

Fixes#192

Notes to the reviewers

  • Reusing the exported serde crate from bdk_wallet did not offer the derive feature
  • Fix out-of-bound error for shorten fn

Changelog notice

  • Add wallet subcommand config to save wallet configs
  • Add top-level wallets command to show all saved wallet configs

Checklists

Features

  • command to save a wallet config, give wallet name or a default name is used, clap enforces required options; optional -f to override existing config: wallet [-f] [-w <name>] config <wallet opts>
  • All other wallet commands require that a config exists, use wallet name or the default is used. Give error if config is missing: wallet [-w <name>] sync | balance | new_address | etc...
  • Repl uses the same wallet configs: repl [-w <name>]
  • command to list all saved wallet configs: wallets
  • throw warnings if using mainnet and saving a private descriptor in a config.

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

New Features:

  • I've added tests for the new feature
  • I've added docs for the new feature
  • I've updated CHANGELOG.md

@coveralls

coveralls commented Jun 18, 2025

Copy link
Copy Markdown

Pull Request Test Coverage Report for Build 21153320925

Details

  • 99 of 395(25.06%) changed or added relevant lines in 3 files are covered.
  • 1 unchanged line in 1 file lost coverage.
  • Overall coverage increased (+2.8%) to 10.717%

Changes Missing CoverageCovered LinesChanged/Added Lines%
src/utils.rs0430.0%
src/config.rs9615163.58%
src/handlers.rs32011.49%
Files with Coverage ReductionNew Missed Lines%
src/handlers.rs113.0%
TotalsCoverage Status
Change from base Build 20714655583:2.8%
Covered Lines:269
Relevant Lines:2510

💛 - Coveralls

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from b3966e3 to bf14df8CompareJune 19, 2025 04:32
@notmandatorynotmandatory moved this to Ready to Review in BDK-CLIJun 24, 2025
@notmandatorynotmandatory added this to the CLI 1.1.0 milestone Jun 24, 2025
@notmandatory

notmandatory commented Jun 24, 2025

Copy link
Copy Markdown
Member

I like the approach for loading the config file parameters if the file exists, but is there a reason you didn't add a CLI bdk-cli wallet init ... command in rust to create the config file rather than using just ?

Creating the config file in rust should be easier to maintain/keep in sync than your just approach and shouldn't take too much more than adding the Serialize trait to WalletConfigInner. You should be able to reuse the WalletOpts to capture the values with clap that you need to put in the config file too.

@notmandatorynotmandatory added the enhancement New feature or request label Jun 24, 2025
@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I like the approach for loading the config file parameters if the file exists, but is there a reason you didn't add a CLI bdk-cli wallet init ... command in rust to create the config file rather than using just ?

Creating the config file in rust should be easier to maintain/keep in sync than your just approach and shouldn't take too much more than adding the Serialize trait to WalletConfigInner. You should be able to reuse the WalletOpts to capture the values with clap that you need to put in the config file too.

Alright, I will update.

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from bf14df8 to 36ee973CompareJune 27, 2025 04:04
@tvpetertvpeter changed the title Add initializing wallet configuration with JustfileAdd initializing wallet configuration with bdk-cli wallet initJun 27, 2025
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 4 times, most recently from 5125cf8 to fcf7ce8CompareJune 27, 2025 10:03
@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

Alright, I will update.

@notmandatory I have updated the PR

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from f77b1da to 70a5390CompareAugust 25, 2025 19:26
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from 9461e85 to 5d9feb0CompareSeptember 1, 2025 04:20
@thunderbiscuit

Copy link
Copy Markdown
Member

I need to start keeping track of all these awesome new features I honestly see the PRs come in and can't keep up. This is super cool.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I need to start keeping track of all these awesome new features I honestly see the PRs come in and can't keep up. This is super cool.

Thank you @thunderbiscuit

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from 9549e09 to 0f6b320CompareSeptember 3, 2025 15:45
@notmandatory

Copy link
Copy Markdown
Member

I spent some time today reviewing and even though this looks like a workable way to do it and is based on my suggestion I'm afraid it's going to be a hassle to maintain. I've been experimenting with somehow using the different clap parsing functions (https://docs.rs/clap/latest/clap/trait.Parser.html) but so far haven't figured out a better way. I'd like to keep thinking about it. We might have to simplify the problem somehow such as by not trying to merge loaded and CLI args.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I'm afraid it's going to be a hassle to maintain. I've been experimenting with somehow using the different clap parsing functions (https://docs.rs/clap/latest/clap/trait.Parser.html) but so far haven't figured out a better way. I'd like to keep thinking about it. We might have to simplify the problem somehow such as by not trying to merge loaded and CLI args.

Thank you @notmandatory.
Yes, I agree that it will be challenging to maintain, as it involves two steps (pre clap parsing and after parsing) and even more difficult as they are in different locations in the codebase. I thought about moving everything to pre clap parsing based on the wallet sub-command the user has entered but that will clog the entry point as there will be lots of if...else checks.

Also, for the Parser trait, I read that it does not allow interacting with an external resource such as reading a file as I would want it.

I will also be trying out other approaches in case there is a cleaner way to handle it.

@notmandatory

notmandatory commented Sep 6, 2025

Copy link
Copy Markdown
Member

How about something like:

  1. One command to save a wallet config, give wallet name or a default name is used, clap enforces required options; optional -f to override existing config:
    wallet [-f] [-w <name>] config <wallet opts>
  2. All other wallet commands require that a config exists, use wallet name or the default is used. Give error if config is missing:
    wallet [-w <name>] sync | balance | new_address | etc...
  3. Repl uses the same wallet configs:
    repl [-w <name>]
  4. Add a command to list all available config names with summary of configured options:
    wallet list
  5. Should throw warnings if using mainnet and saving a private descriptor in a config.

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from 7cd062b to 28796caCompareOctober 5, 2025 03:50
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from 77864b4 to c5c4fdbCompareOctober 15, 2025 13:17

@notmandatorynotmandatory left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found an error when testing with testnet4, and a couple small nits should be fixed too. Otherwise this looks good.

In the future if everyone prefers the config approach it should probably become the only way to use the wallet features.

Comment threadREADME.md Outdated
Comment threadsrc/commands.rs Outdated
Comment threadsrc/utils.rs
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from c5c4fdb to 7be9a30CompareOctober 27, 2025 19:41
@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I found an error when testing with testnet4, and a couple small nits should be fixed too. Otherwise this looks good.

Thank you for catching all these.
I have updated.

In the future if everyone prefers the config approach it should probably become the only way to use the wallet features.

Yes, I agree.

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from 7be9a30 to 805d075CompareNovember 11, 2025 11:36
- 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: bitcoindevkit#192]
- rename init to config and move walletopts as
config options
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from a95a621 to 4f58575CompareJanuary 16, 2026 12:16

@thunderbiscuitthunderbiscuit left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this! I'll use it for sure once it gets in. I have two little things I want to ask, take them or leave them they're not blockers at all.

Question

When I run the example in the readme, I get the following config file:

network = "signet"
[wallets.my_wallet]
wallet = "my_wallet"network = "signet"ext_descriptor = "tr(tprv8Z.../0/*)#dtdqk3dx"int_descriptor = "tr(tprv8Z.../1/*)#ulgptya7"database_type = "sqlite"client_type = "electrum"server_url = "ssl://mempool.space:60602"batch_size = 10

The network is somehow added as a top-level key, but I suspect it's meant to only be added under the specific wallet config maybe? It doesn't prevent the cli from working as expected however so all is good there.

Comment

I always find it hard when applications require a config file but it's empty by default. I have to search in their docs to find what's available, and even then it's hard to know if you miss anything. A nicer approach is when the config file comes pre-populated, with all keys commented out to start with but they're at least all there so I can use the config file to sort of "discover" what's available in the wallet. This is not always possible for all keys, but could be cool here. When doing this you could do it 2 ways:

  1. Your config file could just come pre-made with a top-level commented section that has all keys available and the rest works as it currently does (easiest to implement). Note that you could also just add this as a codeblock in the readme (a complete list of available config options).
  2. Each newly created wallet comes with its own section of complete config keys, some active and the rest commented out.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

Thanks for this! I'll use it for sure once it gets in. I have two little things I want to ask, take them or leave them they're not blockers at all.

Question

When I run the example in the readme, I get the following config file:

network = "signet"
[wallets.my_wallet]
wallet = "my_wallet"network = "signet"ext_descriptor = "tr(tprv8Z.../0/*)#dtdqk3dx"int_descriptor = "tr(tprv8Z.../1/*)#ulgptya7"database_type = "sqlite"client_type = "electrum"server_url = "ssl://mempool.space:60602"batch_size = 10

The network is somehow added as a top-level key, but I suspect it's meant to only be added under the specific wallet config maybe? It doesn't prevent the cli from working as expected however so all is good there.

Comment

I always find it hard when applications require a config file but it's empty by default. I have to search in their docs to find what's available, and even then it's hard to know if you miss anything. A nicer approach is when the config file comes pre-populated, with all keys commented out to start with but they're at least all there so I can use the config file to sort of "discover" what's available in the wallet. This is not always possible for all keys, but could be cool here. When doing this you could do it 2 ways:

  1. Your config file could just come pre-made with a top-level commented section that has all keys available and the rest works as it currently does (easiest to implement). Note that you could also just add this as a codeblock in the readme (a complete list of available config options).
  2. Each newly created wallet comes with its own section of complete config keys, some active and the rest commented out.

Thank you for the review @thunderbiscuit
I will include this feedback in the next update as I also look at the configure_me lib to pick improvements.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

as I also look at the configure_me lib to pick improvements

I have done a quick review of configure_me, and from my perspective, it may not be suitable for the CLI's use case. It uses a declarative approach to define the config file and generates a static file that updating it requires manually editing and recompiling. It is more suitable for an application-wide configuration and will be challenging to use for a per-wallet configuration. Also, I have not seen how it can handle conditional features. Lastly, I am not sure it can integrate with clap as they seemed to serve the same purpose (might be wrong). But there are improvements that we can pick from the library, things like validation and maybe how we merge fetched values into the CLI values.

@notmandatory

Copy link
Copy Markdown
Member

thanks for looking into it, I agree we should stick with our simpler toml file approach.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

The network is somehow added as a top-level key, but I suspect it's meant to only be added under the specific wallet config maybe? It doesn't prevent the cli from working as expected however so all is good there.

Thank you for noting this. It has been fixed now

Comment

I always find it hard when applications require a config file but it's empty by default. I have to search in their docs to find what's available, and even then it's hard to know if you miss anything. A nicer approach is when the config file comes pre-populated, with all keys commented out to start with but they're at least all there so I can use the config file to sort of "discover" what's available in the wallet. This is not always possible for all keys, but could be cool here. When doing this you could do it 2 ways:

  1. Your config file could just come pre-made with a top-level commented section that has all keys available and the rest works as it currently does (easiest to implement). Note that you could also just add this as a codeblock in the readme (a complete list of available config options).
  2. Each newly created wallet comes with its own section of complete config keys, some active and the rest commented out.

I have considered this approach and agree that having a configuration file for an app is beneficial. However, I’m not sure it applies to this tool for two reasons. Firstly, we do not expect users to manually edit the config file because we want clap to validate the passed values based on the features enabled by the user. Allowing users to modify this file could lead to errors when they run wallet commands.

Secondly, this configuration is intended specifically for the wallet and does not pertain to broader application settings. Users who are not testing their wallet flows may find the config file entirely irrelevant.

- add wallets command
- add warning for using priv descriptors
- update readme
- add loading network from config
- fix review comments
- refactor config by impl TryFrom trait for
WalletOpts
- fix top-level network duplicate in config file
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from ac61b94 to be31c14CompareJanuary 19, 2026 15:18
@notmandatory
notmandatoryforce-pushed the feat/init-wallet-support branch from 87472e3 to ceb9332CompareJanuary 19, 2026 22:39
@notmandatory

Copy link
Copy Markdown
Member

I pushed ceb9332 to update README examples to use new wallet config feature.

@notmandatorynotmandatory left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK ceb9332

Looks good! much easier to use.

@tvpeter
tvpeter merged commit b9cf2ac into bitcoindevkit:masterJan 19, 2026
5 checks passed
@github-project-automationgithub-project-automationBot moved this from Ready to Review to Done in BDK-CLIJan 19, 2026
Comment threadsrc/config.rs
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

Add "init" wallet support

5 participants

@tvpeter@coveralls@notmandatory@thunderbiscuit@nymius
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add saving wallet config with bdk-cli wallet config - #203

Merged
tvpeter merged 5 commits into
bitcoindevkit:masterfrom
tvpeter:feat/init-wallet-support
Jan 19, 2026
Merged

Add saving wallet config with bdk-cli wallet config#203
tvpeter merged 5 commits into
bitcoindevkit:masterfrom
tvpeter:feat/init-wallet-support

Conversation

@tvpeter

@tvpetertvpeter commented Jun 18, 2025

Copy link
Copy Markdown
Collaborator

Description

This PR adds bdk-cli wallet config command to save wallet configuration information to config.toml file in the data directory.

Fixes#192

Notes to the reviewers

  • Reusing the exported serde crate from bdk_wallet did not offer the derive feature
  • Fix out-of-bound error for shorten fn

Changelog notice

  • Add wallet subcommand config to save wallet configs
  • Add top-level wallets command to show all saved wallet configs

Checklists

Features

  • command to save a wallet config, give wallet name or a default name is used, clap enforces required options; optional -f to override existing config: wallet [-f] [-w <name>] config <wallet opts>
  • All other wallet commands require that a config exists, use wallet name or the default is used. Give error if config is missing: wallet [-w <name>] sync | balance | new_address | etc...
  • Repl uses the same wallet configs: repl [-w <name>]
  • command to list all saved wallet configs: wallets
  • throw warnings if using mainnet and saving a private descriptor in a config.

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

New Features:

  • I've added tests for the new feature
  • I've added docs for the new feature
  • I've updated CHANGELOG.md

@coveralls

coveralls commented Jun 18, 2025

Copy link
Copy Markdown

Pull Request Test Coverage Report for Build 21153320925

Details

  • 99 of 395(25.06%) changed or added relevant lines in 3 files are covered.
  • 1 unchanged line in 1 file lost coverage.
  • Overall coverage increased (+2.8%) to 10.717%

Changes Missing CoverageCovered LinesChanged/Added Lines%
src/utils.rs0430.0%
src/config.rs9615163.58%
src/handlers.rs32011.49%
Files with Coverage ReductionNew Missed Lines%
src/handlers.rs113.0%
TotalsCoverage Status
Change from base Build 20714655583:2.8%
Covered Lines:269
Relevant Lines:2510

💛 - Coveralls

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from b3966e3 to bf14df8CompareJune 19, 2025 04:32
@notmandatorynotmandatory moved this to Ready to Review in BDK-CLIJun 24, 2025
@notmandatorynotmandatory added this to the CLI 1.1.0 milestone Jun 24, 2025
@notmandatory

notmandatory commented Jun 24, 2025

Copy link
Copy Markdown
Member

I like the approach for loading the config file parameters if the file exists, but is there a reason you didn't add a CLI bdk-cli wallet init ... command in rust to create the config file rather than using just ?

Creating the config file in rust should be easier to maintain/keep in sync than your just approach and shouldn't take too much more than adding the Serialize trait to WalletConfigInner. You should be able to reuse the WalletOpts to capture the values with clap that you need to put in the config file too.

@notmandatorynotmandatory added the enhancement New feature or request label Jun 24, 2025
@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I like the approach for loading the config file parameters if the file exists, but is there a reason you didn't add a CLI bdk-cli wallet init ... command in rust to create the config file rather than using just ?

Creating the config file in rust should be easier to maintain/keep in sync than your just approach and shouldn't take too much more than adding the Serialize trait to WalletConfigInner. You should be able to reuse the WalletOpts to capture the values with clap that you need to put in the config file too.

Alright, I will update.

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from bf14df8 to 36ee973CompareJune 27, 2025 04:04
@tvpetertvpeter changed the title Add initializing wallet configuration with JustfileAdd initializing wallet configuration with bdk-cli wallet initJun 27, 2025
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 4 times, most recently from 5125cf8 to fcf7ce8CompareJune 27, 2025 10:03
@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

Alright, I will update.

@notmandatory I have updated the PR

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from f77b1da to 70a5390CompareAugust 25, 2025 19:26
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from 9461e85 to 5d9feb0CompareSeptember 1, 2025 04:20
@thunderbiscuit

Copy link
Copy Markdown
Member

I need to start keeping track of all these awesome new features I honestly see the PRs come in and can't keep up. This is super cool.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I need to start keeping track of all these awesome new features I honestly see the PRs come in and can't keep up. This is super cool.

Thank you @thunderbiscuit

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from 9549e09 to 0f6b320CompareSeptember 3, 2025 15:45
@notmandatory

Copy link
Copy Markdown
Member

I spent some time today reviewing and even though this looks like a workable way to do it and is based on my suggestion I'm afraid it's going to be a hassle to maintain. I've been experimenting with somehow using the different clap parsing functions (https://docs.rs/clap/latest/clap/trait.Parser.html) but so far haven't figured out a better way. I'd like to keep thinking about it. We might have to simplify the problem somehow such as by not trying to merge loaded and CLI args.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I'm afraid it's going to be a hassle to maintain. I've been experimenting with somehow using the different clap parsing functions (https://docs.rs/clap/latest/clap/trait.Parser.html) but so far haven't figured out a better way. I'd like to keep thinking about it. We might have to simplify the problem somehow such as by not trying to merge loaded and CLI args.

Thank you @notmandatory.
Yes, I agree that it will be challenging to maintain, as it involves two steps (pre clap parsing and after parsing) and even more difficult as they are in different locations in the codebase. I thought about moving everything to pre clap parsing based on the wallet sub-command the user has entered but that will clog the entry point as there will be lots of if...else checks.

Also, for the Parser trait, I read that it does not allow interacting with an external resource such as reading a file as I would want it.

I will also be trying out other approaches in case there is a cleaner way to handle it.

@notmandatory

notmandatory commented Sep 6, 2025

Copy link
Copy Markdown
Member

How about something like:

  1. One command to save a wallet config, give wallet name or a default name is used, clap enforces required options; optional -f to override existing config:
    wallet [-f] [-w <name>] config <wallet opts>
  2. All other wallet commands require that a config exists, use wallet name or the default is used. Give error if config is missing:
    wallet [-w <name>] sync | balance | new_address | etc...
  3. Repl uses the same wallet configs:
    repl [-w <name>]
  4. Add a command to list all available config names with summary of configured options:
    wallet list
  5. Should throw warnings if using mainnet and saving a private descriptor in a config.

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from 7cd062b to 28796caCompareOctober 5, 2025 03:50
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from 77864b4 to c5c4fdbCompareOctober 15, 2025 13:17

@notmandatorynotmandatory left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found an error when testing with testnet4, and a couple small nits should be fixed too. Otherwise this looks good.

In the future if everyone prefers the config approach it should probably become the only way to use the wallet features.

Comment threadREADME.md Outdated
Comment threadsrc/commands.rs Outdated
Comment threadsrc/utils.rs
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from c5c4fdb to 7be9a30CompareOctober 27, 2025 19:41
@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I found an error when testing with testnet4, and a couple small nits should be fixed too. Otherwise this looks good.

Thank you for catching all these.
I have updated.

In the future if everyone prefers the config approach it should probably become the only way to use the wallet features.

Yes, I agree.

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from 7be9a30 to 805d075CompareNovember 11, 2025 11:36
- 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: bitcoindevkit#192]
- rename init to config and move walletopts as
config options
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from a95a621 to 4f58575CompareJanuary 16, 2026 12:16

@thunderbiscuitthunderbiscuit left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this! I'll use it for sure once it gets in. I have two little things I want to ask, take them or leave them they're not blockers at all.

Question

When I run the example in the readme, I get the following config file:

network = "signet"
[wallets.my_wallet]
wallet = "my_wallet"network = "signet"ext_descriptor = "tr(tprv8Z.../0/*)#dtdqk3dx"int_descriptor = "tr(tprv8Z.../1/*)#ulgptya7"database_type = "sqlite"client_type = "electrum"server_url = "ssl://mempool.space:60602"batch_size = 10

The network is somehow added as a top-level key, but I suspect it's meant to only be added under the specific wallet config maybe? It doesn't prevent the cli from working as expected however so all is good there.

Comment

I always find it hard when applications require a config file but it's empty by default. I have to search in their docs to find what's available, and even then it's hard to know if you miss anything. A nicer approach is when the config file comes pre-populated, with all keys commented out to start with but they're at least all there so I can use the config file to sort of "discover" what's available in the wallet. This is not always possible for all keys, but could be cool here. When doing this you could do it 2 ways:

  1. Your config file could just come pre-made with a top-level commented section that has all keys available and the rest works as it currently does (easiest to implement). Note that you could also just add this as a codeblock in the readme (a complete list of available config options).
  2. Each newly created wallet comes with its own section of complete config keys, some active and the rest commented out.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

Thanks for this! I'll use it for sure once it gets in. I have two little things I want to ask, take them or leave them they're not blockers at all.

Question

When I run the example in the readme, I get the following config file:

network = "signet"
[wallets.my_wallet]
wallet = "my_wallet"network = "signet"ext_descriptor = "tr(tprv8Z.../0/*)#dtdqk3dx"int_descriptor = "tr(tprv8Z.../1/*)#ulgptya7"database_type = "sqlite"client_type = "electrum"server_url = "ssl://mempool.space:60602"batch_size = 10

The network is somehow added as a top-level key, but I suspect it's meant to only be added under the specific wallet config maybe? It doesn't prevent the cli from working as expected however so all is good there.

Comment

I always find it hard when applications require a config file but it's empty by default. I have to search in their docs to find what's available, and even then it's hard to know if you miss anything. A nicer approach is when the config file comes pre-populated, with all keys commented out to start with but they're at least all there so I can use the config file to sort of "discover" what's available in the wallet. This is not always possible for all keys, but could be cool here. When doing this you could do it 2 ways:

  1. Your config file could just come pre-made with a top-level commented section that has all keys available and the rest works as it currently does (easiest to implement). Note that you could also just add this as a codeblock in the readme (a complete list of available config options).
  2. Each newly created wallet comes with its own section of complete config keys, some active and the rest commented out.

Thank you for the review @thunderbiscuit
I will include this feedback in the next update as I also look at the configure_me lib to pick improvements.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

as I also look at the configure_me lib to pick improvements

I have done a quick review of configure_me, and from my perspective, it may not be suitable for the CLI's use case. It uses a declarative approach to define the config file and generates a static file that updating it requires manually editing and recompiling. It is more suitable for an application-wide configuration and will be challenging to use for a per-wallet configuration. Also, I have not seen how it can handle conditional features. Lastly, I am not sure it can integrate with clap as they seemed to serve the same purpose (might be wrong). But there are improvements that we can pick from the library, things like validation and maybe how we merge fetched values into the CLI values.

@notmandatory

Copy link
Copy Markdown
Member

thanks for looking into it, I agree we should stick with our simpler toml file approach.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

The network is somehow added as a top-level key, but I suspect it's meant to only be added under the specific wallet config maybe? It doesn't prevent the cli from working as expected however so all is good there.

Thank you for noting this. It has been fixed now

Comment

I always find it hard when applications require a config file but it's empty by default. I have to search in their docs to find what's available, and even then it's hard to know if you miss anything. A nicer approach is when the config file comes pre-populated, with all keys commented out to start with but they're at least all there so I can use the config file to sort of "discover" what's available in the wallet. This is not always possible for all keys, but could be cool here. When doing this you could do it 2 ways:

  1. Your config file could just come pre-made with a top-level commented section that has all keys available and the rest works as it currently does (easiest to implement). Note that you could also just add this as a codeblock in the readme (a complete list of available config options).
  2. Each newly created wallet comes with its own section of complete config keys, some active and the rest commented out.

I have considered this approach and agree that having a configuration file for an app is beneficial. However, I’m not sure it applies to this tool for two reasons. Firstly, we do not expect users to manually edit the config file because we want clap to validate the passed values based on the features enabled by the user. Allowing users to modify this file could lead to errors when they run wallet commands.

Secondly, this configuration is intended specifically for the wallet and does not pertain to broader application settings. Users who are not testing their wallet flows may find the config file entirely irrelevant.

- add wallets command
- add warning for using priv descriptors
- update readme
- add loading network from config
- fix review comments
- refactor config by impl TryFrom trait for
WalletOpts
- fix top-level network duplicate in config file
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from ac61b94 to be31c14CompareJanuary 19, 2026 15:18
@notmandatory
notmandatoryforce-pushed the feat/init-wallet-support branch from 87472e3 to ceb9332CompareJanuary 19, 2026 22:39
@notmandatory

Copy link
Copy Markdown
Member

I pushed ceb9332 to update README examples to use new wallet config feature.

@notmandatorynotmandatory left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK ceb9332

Looks good! much easier to use.

@tvpeter
tvpeter merged commit b9cf2ac into bitcoindevkit:masterJan 19, 2026
5 checks passed
@github-project-automationgithub-project-automationBot moved this from Ready to Review to Done in BDK-CLIJan 19, 2026
Comment threadsrc/config.rs
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

Add "init" wallet support

5 participants

@tvpeter@coveralls@notmandatory@thunderbiscuit@nymius
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add saving wallet config with bdk-cli wallet config - #203

Merged
tvpeter merged 5 commits into
bitcoindevkit:masterfrom
tvpeter:feat/init-wallet-support
Jan 19, 2026
Merged

Add saving wallet config with bdk-cli wallet config#203
tvpeter merged 5 commits into
bitcoindevkit:masterfrom
tvpeter:feat/init-wallet-support

Conversation

@tvpeter

@tvpetertvpeter commented Jun 18, 2025

Copy link
Copy Markdown
Collaborator

Description

This PR adds bdk-cli wallet config command to save wallet configuration information to config.toml file in the data directory.

Fixes#192

Notes to the reviewers

  • Reusing the exported serde crate from bdk_wallet did not offer the derive feature
  • Fix out-of-bound error for shorten fn

Changelog notice

  • Add wallet subcommand config to save wallet configs
  • Add top-level wallets command to show all saved wallet configs

Checklists

Features

  • command to save a wallet config, give wallet name or a default name is used, clap enforces required options; optional -f to override existing config: wallet [-f] [-w <name>] config <wallet opts>
  • All other wallet commands require that a config exists, use wallet name or the default is used. Give error if config is missing: wallet [-w <name>] sync | balance | new_address | etc...
  • Repl uses the same wallet configs: repl [-w <name>]
  • command to list all saved wallet configs: wallets
  • throw warnings if using mainnet and saving a private descriptor in a config.

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

New Features:

  • I've added tests for the new feature
  • I've added docs for the new feature
  • I've updated CHANGELOG.md

@coveralls

coveralls commented Jun 18, 2025

Copy link
Copy Markdown

Pull Request Test Coverage Report for Build 21153320925

Details

  • 99 of 395(25.06%) changed or added relevant lines in 3 files are covered.
  • 1 unchanged line in 1 file lost coverage.
  • Overall coverage increased (+2.8%) to 10.717%

Changes Missing CoverageCovered LinesChanged/Added Lines%
src/utils.rs0430.0%
src/config.rs9615163.58%
src/handlers.rs32011.49%
Files with Coverage ReductionNew Missed Lines%
src/handlers.rs113.0%
TotalsCoverage Status
Change from base Build 20714655583:2.8%
Covered Lines:269
Relevant Lines:2510

💛 - Coveralls

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from b3966e3 to bf14df8CompareJune 19, 2025 04:32
@notmandatorynotmandatory moved this to Ready to Review in BDK-CLIJun 24, 2025
@notmandatorynotmandatory added this to the CLI 1.1.0 milestone Jun 24, 2025
@notmandatory

notmandatory commented Jun 24, 2025

Copy link
Copy Markdown
Member

I like the approach for loading the config file parameters if the file exists, but is there a reason you didn't add a CLI bdk-cli wallet init ... command in rust to create the config file rather than using just ?

Creating the config file in rust should be easier to maintain/keep in sync than your just approach and shouldn't take too much more than adding the Serialize trait to WalletConfigInner. You should be able to reuse the WalletOpts to capture the values with clap that you need to put in the config file too.

@notmandatorynotmandatory added the enhancement New feature or request label Jun 24, 2025
@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I like the approach for loading the config file parameters if the file exists, but is there a reason you didn't add a CLI bdk-cli wallet init ... command in rust to create the config file rather than using just ?

Creating the config file in rust should be easier to maintain/keep in sync than your just approach and shouldn't take too much more than adding the Serialize trait to WalletConfigInner. You should be able to reuse the WalletOpts to capture the values with clap that you need to put in the config file too.

Alright, I will update.

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from bf14df8 to 36ee973CompareJune 27, 2025 04:04
@tvpetertvpeter changed the title Add initializing wallet configuration with JustfileAdd initializing wallet configuration with bdk-cli wallet initJun 27, 2025
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 4 times, most recently from 5125cf8 to fcf7ce8CompareJune 27, 2025 10:03
@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

Alright, I will update.

@notmandatory I have updated the PR

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from f77b1da to 70a5390CompareAugust 25, 2025 19:26
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from 9461e85 to 5d9feb0CompareSeptember 1, 2025 04:20
@thunderbiscuit

Copy link
Copy Markdown
Member

I need to start keeping track of all these awesome new features I honestly see the PRs come in and can't keep up. This is super cool.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I need to start keeping track of all these awesome new features I honestly see the PRs come in and can't keep up. This is super cool.

Thank you @thunderbiscuit

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from 9549e09 to 0f6b320CompareSeptember 3, 2025 15:45
@notmandatory

Copy link
Copy Markdown
Member

I spent some time today reviewing and even though this looks like a workable way to do it and is based on my suggestion I'm afraid it's going to be a hassle to maintain. I've been experimenting with somehow using the different clap parsing functions (https://docs.rs/clap/latest/clap/trait.Parser.html) but so far haven't figured out a better way. I'd like to keep thinking about it. We might have to simplify the problem somehow such as by not trying to merge loaded and CLI args.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I'm afraid it's going to be a hassle to maintain. I've been experimenting with somehow using the different clap parsing functions (https://docs.rs/clap/latest/clap/trait.Parser.html) but so far haven't figured out a better way. I'd like to keep thinking about it. We might have to simplify the problem somehow such as by not trying to merge loaded and CLI args.

Thank you @notmandatory.
Yes, I agree that it will be challenging to maintain, as it involves two steps (pre clap parsing and after parsing) and even more difficult as they are in different locations in the codebase. I thought about moving everything to pre clap parsing based on the wallet sub-command the user has entered but that will clog the entry point as there will be lots of if...else checks.

Also, for the Parser trait, I read that it does not allow interacting with an external resource such as reading a file as I would want it.

I will also be trying out other approaches in case there is a cleaner way to handle it.

@notmandatory

notmandatory commented Sep 6, 2025

Copy link
Copy Markdown
Member

How about something like:

  1. One command to save a wallet config, give wallet name or a default name is used, clap enforces required options; optional -f to override existing config:
    wallet [-f] [-w <name>] config <wallet opts>
  2. All other wallet commands require that a config exists, use wallet name or the default is used. Give error if config is missing:
    wallet [-w <name>] sync | balance | new_address | etc...
  3. Repl uses the same wallet configs:
    repl [-w <name>]
  4. Add a command to list all available config names with summary of configured options:
    wallet list
  5. Should throw warnings if using mainnet and saving a private descriptor in a config.

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from 7cd062b to 28796caCompareOctober 5, 2025 03:50
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from 77864b4 to c5c4fdbCompareOctober 15, 2025 13:17

@notmandatorynotmandatory left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found an error when testing with testnet4, and a couple small nits should be fixed too. Otherwise this looks good.

In the future if everyone prefers the config approach it should probably become the only way to use the wallet features.

Comment threadREADME.md Outdated
Comment threadsrc/commands.rs Outdated
Comment threadsrc/utils.rs
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from c5c4fdb to 7be9a30CompareOctober 27, 2025 19:41
@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I found an error when testing with testnet4, and a couple small nits should be fixed too. Otherwise this looks good.

Thank you for catching all these.
I have updated.

In the future if everyone prefers the config approach it should probably become the only way to use the wallet features.

Yes, I agree.

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from 7be9a30 to 805d075CompareNovember 11, 2025 11:36
- 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: bitcoindevkit#192]
- rename init to config and move walletopts as
config options
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from a95a621 to 4f58575CompareJanuary 16, 2026 12:16

@thunderbiscuitthunderbiscuit left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this! I'll use it for sure once it gets in. I have two little things I want to ask, take them or leave them they're not blockers at all.

Question

When I run the example in the readme, I get the following config file:

network = "signet"
[wallets.my_wallet]
wallet = "my_wallet"network = "signet"ext_descriptor = "tr(tprv8Z.../0/*)#dtdqk3dx"int_descriptor = "tr(tprv8Z.../1/*)#ulgptya7"database_type = "sqlite"client_type = "electrum"server_url = "ssl://mempool.space:60602"batch_size = 10

The network is somehow added as a top-level key, but I suspect it's meant to only be added under the specific wallet config maybe? It doesn't prevent the cli from working as expected however so all is good there.

Comment

I always find it hard when applications require a config file but it's empty by default. I have to search in their docs to find what's available, and even then it's hard to know if you miss anything. A nicer approach is when the config file comes pre-populated, with all keys commented out to start with but they're at least all there so I can use the config file to sort of "discover" what's available in the wallet. This is not always possible for all keys, but could be cool here. When doing this you could do it 2 ways:

  1. Your config file could just come pre-made with a top-level commented section that has all keys available and the rest works as it currently does (easiest to implement). Note that you could also just add this as a codeblock in the readme (a complete list of available config options).
  2. Each newly created wallet comes with its own section of complete config keys, some active and the rest commented out.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

Thanks for this! I'll use it for sure once it gets in. I have two little things I want to ask, take them or leave them they're not blockers at all.

Question

When I run the example in the readme, I get the following config file:

network = "signet"
[wallets.my_wallet]
wallet = "my_wallet"network = "signet"ext_descriptor = "tr(tprv8Z.../0/*)#dtdqk3dx"int_descriptor = "tr(tprv8Z.../1/*)#ulgptya7"database_type = "sqlite"client_type = "electrum"server_url = "ssl://mempool.space:60602"batch_size = 10

The network is somehow added as a top-level key, but I suspect it's meant to only be added under the specific wallet config maybe? It doesn't prevent the cli from working as expected however so all is good there.

Comment

I always find it hard when applications require a config file but it's empty by default. I have to search in their docs to find what's available, and even then it's hard to know if you miss anything. A nicer approach is when the config file comes pre-populated, with all keys commented out to start with but they're at least all there so I can use the config file to sort of "discover" what's available in the wallet. This is not always possible for all keys, but could be cool here. When doing this you could do it 2 ways:

  1. Your config file could just come pre-made with a top-level commented section that has all keys available and the rest works as it currently does (easiest to implement). Note that you could also just add this as a codeblock in the readme (a complete list of available config options).
  2. Each newly created wallet comes with its own section of complete config keys, some active and the rest commented out.

Thank you for the review @thunderbiscuit
I will include this feedback in the next update as I also look at the configure_me lib to pick improvements.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

as I also look at the configure_me lib to pick improvements

I have done a quick review of configure_me, and from my perspective, it may not be suitable for the CLI's use case. It uses a declarative approach to define the config file and generates a static file that updating it requires manually editing and recompiling. It is more suitable for an application-wide configuration and will be challenging to use for a per-wallet configuration. Also, I have not seen how it can handle conditional features. Lastly, I am not sure it can integrate with clap as they seemed to serve the same purpose (might be wrong). But there are improvements that we can pick from the library, things like validation and maybe how we merge fetched values into the CLI values.

@notmandatory

Copy link
Copy Markdown
Member

thanks for looking into it, I agree we should stick with our simpler toml file approach.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

The network is somehow added as a top-level key, but I suspect it's meant to only be added under the specific wallet config maybe? It doesn't prevent the cli from working as expected however so all is good there.

Thank you for noting this. It has been fixed now

Comment

I always find it hard when applications require a config file but it's empty by default. I have to search in their docs to find what's available, and even then it's hard to know if you miss anything. A nicer approach is when the config file comes pre-populated, with all keys commented out to start with but they're at least all there so I can use the config file to sort of "discover" what's available in the wallet. This is not always possible for all keys, but could be cool here. When doing this you could do it 2 ways:

  1. Your config file could just come pre-made with a top-level commented section that has all keys available and the rest works as it currently does (easiest to implement). Note that you could also just add this as a codeblock in the readme (a complete list of available config options).
  2. Each newly created wallet comes with its own section of complete config keys, some active and the rest commented out.

I have considered this approach and agree that having a configuration file for an app is beneficial. However, I’m not sure it applies to this tool for two reasons. Firstly, we do not expect users to manually edit the config file because we want clap to validate the passed values based on the features enabled by the user. Allowing users to modify this file could lead to errors when they run wallet commands.

Secondly, this configuration is intended specifically for the wallet and does not pertain to broader application settings. Users who are not testing their wallet flows may find the config file entirely irrelevant.

- add wallets command
- add warning for using priv descriptors
- update readme
- add loading network from config
- fix review comments
- refactor config by impl TryFrom trait for
WalletOpts
- fix top-level network duplicate in config file
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from ac61b94 to be31c14CompareJanuary 19, 2026 15:18
@notmandatory
notmandatoryforce-pushed the feat/init-wallet-support branch from 87472e3 to ceb9332CompareJanuary 19, 2026 22:39
@notmandatory

Copy link
Copy Markdown
Member

I pushed ceb9332 to update README examples to use new wallet config feature.

@notmandatorynotmandatory left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK ceb9332

Looks good! much easier to use.

@tvpeter
tvpeter merged commit b9cf2ac into bitcoindevkit:masterJan 19, 2026
5 checks passed
@github-project-automationgithub-project-automationBot moved this from Ready to Review to Done in BDK-CLIJan 19, 2026
Comment threadsrc/config.rs
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

Add "init" wallet support

5 participants

@tvpeter@coveralls@notmandatory@thunderbiscuit@nymius
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Add saving wallet config with bdk-cli wallet config - #203

Merged
tvpeter merged 5 commits into
bitcoindevkit:masterfrom
tvpeter:feat/init-wallet-support
Jan 19, 2026
Merged

Add saving wallet config with bdk-cli wallet config#203
tvpeter merged 5 commits into
bitcoindevkit:masterfrom
tvpeter:feat/init-wallet-support

Conversation

@tvpeter

@tvpetertvpeter commented Jun 18, 2025

Copy link
Copy Markdown
Collaborator

Description

This PR adds bdk-cli wallet config command to save wallet configuration information to config.toml file in the data directory.

Fixes#192

Notes to the reviewers

  • Reusing the exported serde crate from bdk_wallet did not offer the derive feature
  • Fix out-of-bound error for shorten fn

Changelog notice

  • Add wallet subcommand config to save wallet configs
  • Add top-level wallets command to show all saved wallet configs

Checklists

Features

  • command to save a wallet config, give wallet name or a default name is used, clap enforces required options; optional -f to override existing config: wallet [-f] [-w <name>] config <wallet opts>
  • All other wallet commands require that a config exists, use wallet name or the default is used. Give error if config is missing: wallet [-w <name>] sync | balance | new_address | etc...
  • Repl uses the same wallet configs: repl [-w <name>]
  • command to list all saved wallet configs: wallets
  • throw warnings if using mainnet and saving a private descriptor in a config.

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

New Features:

  • I've added tests for the new feature
  • I've added docs for the new feature
  • I've updated CHANGELOG.md

@coveralls

coveralls commented Jun 18, 2025

Copy link
Copy Markdown

Pull Request Test Coverage Report for Build 21153320925

Details

  • 99 of 395(25.06%) changed or added relevant lines in 3 files are covered.
  • 1 unchanged line in 1 file lost coverage.
  • Overall coverage increased (+2.8%) to 10.717%

Changes Missing CoverageCovered LinesChanged/Added Lines%
src/utils.rs0430.0%
src/config.rs9615163.58%
src/handlers.rs32011.49%
Files with Coverage ReductionNew Missed Lines%
src/handlers.rs113.0%
TotalsCoverage Status
Change from base Build 20714655583:2.8%
Covered Lines:269
Relevant Lines:2510

💛 - Coveralls

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from b3966e3 to bf14df8CompareJune 19, 2025 04:32
@notmandatorynotmandatory moved this to Ready to Review in BDK-CLIJun 24, 2025
@notmandatorynotmandatory added this to the CLI 1.1.0 milestone Jun 24, 2025
@notmandatory

notmandatory commented Jun 24, 2025

Copy link
Copy Markdown
Member

I like the approach for loading the config file parameters if the file exists, but is there a reason you didn't add a CLI bdk-cli wallet init ... command in rust to create the config file rather than using just ?

Creating the config file in rust should be easier to maintain/keep in sync than your just approach and shouldn't take too much more than adding the Serialize trait to WalletConfigInner. You should be able to reuse the WalletOpts to capture the values with clap that you need to put in the config file too.

@notmandatorynotmandatory added the enhancement New feature or request label Jun 24, 2025
@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I like the approach for loading the config file parameters if the file exists, but is there a reason you didn't add a CLI bdk-cli wallet init ... command in rust to create the config file rather than using just ?

Creating the config file in rust should be easier to maintain/keep in sync than your just approach and shouldn't take too much more than adding the Serialize trait to WalletConfigInner. You should be able to reuse the WalletOpts to capture the values with clap that you need to put in the config file too.

Alright, I will update.

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from bf14df8 to 36ee973CompareJune 27, 2025 04:04
@tvpetertvpeter changed the title Add initializing wallet configuration with JustfileAdd initializing wallet configuration with bdk-cli wallet initJun 27, 2025
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 4 times, most recently from 5125cf8 to fcf7ce8CompareJune 27, 2025 10:03
@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

Alright, I will update.

@notmandatory I have updated the PR

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from f77b1da to 70a5390CompareAugust 25, 2025 19:26
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from 9461e85 to 5d9feb0CompareSeptember 1, 2025 04:20
@thunderbiscuit

Copy link
Copy Markdown
Member

I need to start keeping track of all these awesome new features I honestly see the PRs come in and can't keep up. This is super cool.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I need to start keeping track of all these awesome new features I honestly see the PRs come in and can't keep up. This is super cool.

Thank you @thunderbiscuit

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from 9549e09 to 0f6b320CompareSeptember 3, 2025 15:45
@notmandatory

Copy link
Copy Markdown
Member

I spent some time today reviewing and even though this looks like a workable way to do it and is based on my suggestion I'm afraid it's going to be a hassle to maintain. I've been experimenting with somehow using the different clap parsing functions (https://docs.rs/clap/latest/clap/trait.Parser.html) but so far haven't figured out a better way. I'd like to keep thinking about it. We might have to simplify the problem somehow such as by not trying to merge loaded and CLI args.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I'm afraid it's going to be a hassle to maintain. I've been experimenting with somehow using the different clap parsing functions (https://docs.rs/clap/latest/clap/trait.Parser.html) but so far haven't figured out a better way. I'd like to keep thinking about it. We might have to simplify the problem somehow such as by not trying to merge loaded and CLI args.

Thank you @notmandatory.
Yes, I agree that it will be challenging to maintain, as it involves two steps (pre clap parsing and after parsing) and even more difficult as they are in different locations in the codebase. I thought about moving everything to pre clap parsing based on the wallet sub-command the user has entered but that will clog the entry point as there will be lots of if...else checks.

Also, for the Parser trait, I read that it does not allow interacting with an external resource such as reading a file as I would want it.

I will also be trying out other approaches in case there is a cleaner way to handle it.

@notmandatory

notmandatory commented Sep 6, 2025

Copy link
Copy Markdown
Member

How about something like:

  1. One command to save a wallet config, give wallet name or a default name is used, clap enforces required options; optional -f to override existing config:
    wallet [-f] [-w <name>] config <wallet opts>
  2. All other wallet commands require that a config exists, use wallet name or the default is used. Give error if config is missing:
    wallet [-w <name>] sync | balance | new_address | etc...
  3. Repl uses the same wallet configs:
    repl [-w <name>]
  4. Add a command to list all available config names with summary of configured options:
    wallet list
  5. Should throw warnings if using mainnet and saving a private descriptor in a config.

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from 7cd062b to 28796caCompareOctober 5, 2025 03:50
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from 77864b4 to c5c4fdbCompareOctober 15, 2025 13:17

@notmandatorynotmandatory left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found an error when testing with testnet4, and a couple small nits should be fixed too. Otherwise this looks good.

In the future if everyone prefers the config approach it should probably become the only way to use the wallet features.

Comment threadREADME.md Outdated
Comment threadsrc/commands.rs Outdated
Comment threadsrc/utils.rs
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from c5c4fdb to 7be9a30CompareOctober 27, 2025 19:41
@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I found an error when testing with testnet4, and a couple small nits should be fixed too. Otherwise this looks good.

Thank you for catching all these.
I have updated.

In the future if everyone prefers the config approach it should probably become the only way to use the wallet features.

Yes, I agree.

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from 7be9a30 to 805d075CompareNovember 11, 2025 11:36
- 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: bitcoindevkit#192]
- rename init to config and move walletopts as
config options
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from a95a621 to 4f58575CompareJanuary 16, 2026 12:16

@thunderbiscuitthunderbiscuit left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this! I'll use it for sure once it gets in. I have two little things I want to ask, take them or leave them they're not blockers at all.

Question

When I run the example in the readme, I get the following config file:

network = "signet"
[wallets.my_wallet]
wallet = "my_wallet"network = "signet"ext_descriptor = "tr(tprv8Z.../0/*)#dtdqk3dx"int_descriptor = "tr(tprv8Z.../1/*)#ulgptya7"database_type = "sqlite"client_type = "electrum"server_url = "ssl://mempool.space:60602"batch_size = 10

The network is somehow added as a top-level key, but I suspect it's meant to only be added under the specific wallet config maybe? It doesn't prevent the cli from working as expected however so all is good there.

Comment

I always find it hard when applications require a config file but it's empty by default. I have to search in their docs to find what's available, and even then it's hard to know if you miss anything. A nicer approach is when the config file comes pre-populated, with all keys commented out to start with but they're at least all there so I can use the config file to sort of "discover" what's available in the wallet. This is not always possible for all keys, but could be cool here. When doing this you could do it 2 ways:

  1. Your config file could just come pre-made with a top-level commented section that has all keys available and the rest works as it currently does (easiest to implement). Note that you could also just add this as a codeblock in the readme (a complete list of available config options).
  2. Each newly created wallet comes with its own section of complete config keys, some active and the rest commented out.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

Thanks for this! I'll use it for sure once it gets in. I have two little things I want to ask, take them or leave them they're not blockers at all.

Question

When I run the example in the readme, I get the following config file:

network = "signet"
[wallets.my_wallet]
wallet = "my_wallet"network = "signet"ext_descriptor = "tr(tprv8Z.../0/*)#dtdqk3dx"int_descriptor = "tr(tprv8Z.../1/*)#ulgptya7"database_type = "sqlite"client_type = "electrum"server_url = "ssl://mempool.space:60602"batch_size = 10

The network is somehow added as a top-level key, but I suspect it's meant to only be added under the specific wallet config maybe? It doesn't prevent the cli from working as expected however so all is good there.

Comment

I always find it hard when applications require a config file but it's empty by default. I have to search in their docs to find what's available, and even then it's hard to know if you miss anything. A nicer approach is when the config file comes pre-populated, with all keys commented out to start with but they're at least all there so I can use the config file to sort of "discover" what's available in the wallet. This is not always possible for all keys, but could be cool here. When doing this you could do it 2 ways:

  1. Your config file could just come pre-made with a top-level commented section that has all keys available and the rest works as it currently does (easiest to implement). Note that you could also just add this as a codeblock in the readme (a complete list of available config options).
  2. Each newly created wallet comes with its own section of complete config keys, some active and the rest commented out.

Thank you for the review @thunderbiscuit
I will include this feedback in the next update as I also look at the configure_me lib to pick improvements.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

as I also look at the configure_me lib to pick improvements

I have done a quick review of configure_me, and from my perspective, it may not be suitable for the CLI's use case. It uses a declarative approach to define the config file and generates a static file that updating it requires manually editing and recompiling. It is more suitable for an application-wide configuration and will be challenging to use for a per-wallet configuration. Also, I have not seen how it can handle conditional features. Lastly, I am not sure it can integrate with clap as they seemed to serve the same purpose (might be wrong). But there are improvements that we can pick from the library, things like validation and maybe how we merge fetched values into the CLI values.

@notmandatory

Copy link
Copy Markdown
Member

thanks for looking into it, I agree we should stick with our simpler toml file approach.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

The network is somehow added as a top-level key, but I suspect it's meant to only be added under the specific wallet config maybe? It doesn't prevent the cli from working as expected however so all is good there.

Thank you for noting this. It has been fixed now

Comment

I always find it hard when applications require a config file but it's empty by default. I have to search in their docs to find what's available, and even then it's hard to know if you miss anything. A nicer approach is when the config file comes pre-populated, with all keys commented out to start with but they're at least all there so I can use the config file to sort of "discover" what's available in the wallet. This is not always possible for all keys, but could be cool here. When doing this you could do it 2 ways:

  1. Your config file could just come pre-made with a top-level commented section that has all keys available and the rest works as it currently does (easiest to implement). Note that you could also just add this as a codeblock in the readme (a complete list of available config options).
  2. Each newly created wallet comes with its own section of complete config keys, some active and the rest commented out.

I have considered this approach and agree that having a configuration file for an app is beneficial. However, I’m not sure it applies to this tool for two reasons. Firstly, we do not expect users to manually edit the config file because we want clap to validate the passed values based on the features enabled by the user. Allowing users to modify this file could lead to errors when they run wallet commands.

Secondly, this configuration is intended specifically for the wallet and does not pertain to broader application settings. Users who are not testing their wallet flows may find the config file entirely irrelevant.

- add wallets command
- add warning for using priv descriptors
- update readme
- add loading network from config
- fix review comments
- refactor config by impl TryFrom trait for
WalletOpts
- fix top-level network duplicate in config file
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from ac61b94 to be31c14CompareJanuary 19, 2026 15:18
@notmandatory
notmandatoryforce-pushed the feat/init-wallet-support branch from 87472e3 to ceb9332CompareJanuary 19, 2026 22:39
@notmandatory

Copy link
Copy Markdown
Member

I pushed ceb9332 to update README examples to use new wallet config feature.

@notmandatorynotmandatory left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK ceb9332

Looks good! much easier to use.

@tvpeter
tvpeter merged commit b9cf2ac into bitcoindevkit:masterJan 19, 2026
5 checks passed
@github-project-automationgithub-project-automationBot moved this from Ready to Review to Done in BDK-CLIJan 19, 2026
Comment threadsrc/config.rs
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

Add "init" wallet support

5 participants

@tvpeter@coveralls@notmandatory@thunderbiscuit@nymius
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add saving wallet config with bdk-cli wallet config - #203

Merged
tvpeter merged 5 commits into
bitcoindevkit:masterfrom
tvpeter:feat/init-wallet-support
Jan 19, 2026
Merged

Add saving wallet config with bdk-cli wallet config#203
tvpeter merged 5 commits into
bitcoindevkit:masterfrom
tvpeter:feat/init-wallet-support

Conversation

@tvpeter

@tvpetertvpeter commented Jun 18, 2025

Copy link
Copy Markdown
Collaborator

Description

This PR adds bdk-cli wallet config command to save wallet configuration information to config.toml file in the data directory.

Fixes#192

Notes to the reviewers

  • Reusing the exported serde crate from bdk_wallet did not offer the derive feature
  • Fix out-of-bound error for shorten fn

Changelog notice

  • Add wallet subcommand config to save wallet configs
  • Add top-level wallets command to show all saved wallet configs

Checklists

Features

  • command to save a wallet config, give wallet name or a default name is used, clap enforces required options; optional -f to override existing config: wallet [-f] [-w <name>] config <wallet opts>
  • All other wallet commands require that a config exists, use wallet name or the default is used. Give error if config is missing: wallet [-w <name>] sync | balance | new_address | etc...
  • Repl uses the same wallet configs: repl [-w <name>]
  • command to list all saved wallet configs: wallets
  • throw warnings if using mainnet and saving a private descriptor in a config.

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

New Features:

  • I've added tests for the new feature
  • I've added docs for the new feature
  • I've updated CHANGELOG.md

@coveralls

coveralls commented Jun 18, 2025

Copy link
Copy Markdown

Pull Request Test Coverage Report for Build 21153320925

Details

  • 99 of 395(25.06%) changed or added relevant lines in 3 files are covered.
  • 1 unchanged line in 1 file lost coverage.
  • Overall coverage increased (+2.8%) to 10.717%

Changes Missing CoverageCovered LinesChanged/Added Lines%
src/utils.rs0430.0%
src/config.rs9615163.58%
src/handlers.rs32011.49%
Files with Coverage ReductionNew Missed Lines%
src/handlers.rs113.0%
TotalsCoverage Status
Change from base Build 20714655583:2.8%
Covered Lines:269
Relevant Lines:2510

💛 - Coveralls

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from b3966e3 to bf14df8CompareJune 19, 2025 04:32
@notmandatorynotmandatory moved this to Ready to Review in BDK-CLIJun 24, 2025
@notmandatorynotmandatory added this to the CLI 1.1.0 milestone Jun 24, 2025
@notmandatory

notmandatory commented Jun 24, 2025

Copy link
Copy Markdown
Member

I like the approach for loading the config file parameters if the file exists, but is there a reason you didn't add a CLI bdk-cli wallet init ... command in rust to create the config file rather than using just ?

Creating the config file in rust should be easier to maintain/keep in sync than your just approach and shouldn't take too much more than adding the Serialize trait to WalletConfigInner. You should be able to reuse the WalletOpts to capture the values with clap that you need to put in the config file too.

@notmandatorynotmandatory added the enhancement New feature or request label Jun 24, 2025
@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I like the approach for loading the config file parameters if the file exists, but is there a reason you didn't add a CLI bdk-cli wallet init ... command in rust to create the config file rather than using just ?

Creating the config file in rust should be easier to maintain/keep in sync than your just approach and shouldn't take too much more than adding the Serialize trait to WalletConfigInner. You should be able to reuse the WalletOpts to capture the values with clap that you need to put in the config file too.

Alright, I will update.

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from bf14df8 to 36ee973CompareJune 27, 2025 04:04
@tvpetertvpeter changed the title Add initializing wallet configuration with JustfileAdd initializing wallet configuration with bdk-cli wallet initJun 27, 2025
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 4 times, most recently from 5125cf8 to fcf7ce8CompareJune 27, 2025 10:03
@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

Alright, I will update.

@notmandatory I have updated the PR

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from f77b1da to 70a5390CompareAugust 25, 2025 19:26
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from 9461e85 to 5d9feb0CompareSeptember 1, 2025 04:20
@thunderbiscuit

Copy link
Copy Markdown
Member

I need to start keeping track of all these awesome new features I honestly see the PRs come in and can't keep up. This is super cool.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I need to start keeping track of all these awesome new features I honestly see the PRs come in and can't keep up. This is super cool.

Thank you @thunderbiscuit

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from 9549e09 to 0f6b320CompareSeptember 3, 2025 15:45
@notmandatory

Copy link
Copy Markdown
Member

I spent some time today reviewing and even though this looks like a workable way to do it and is based on my suggestion I'm afraid it's going to be a hassle to maintain. I've been experimenting with somehow using the different clap parsing functions (https://docs.rs/clap/latest/clap/trait.Parser.html) but so far haven't figured out a better way. I'd like to keep thinking about it. We might have to simplify the problem somehow such as by not trying to merge loaded and CLI args.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I'm afraid it's going to be a hassle to maintain. I've been experimenting with somehow using the different clap parsing functions (https://docs.rs/clap/latest/clap/trait.Parser.html) but so far haven't figured out a better way. I'd like to keep thinking about it. We might have to simplify the problem somehow such as by not trying to merge loaded and CLI args.

Thank you @notmandatory.
Yes, I agree that it will be challenging to maintain, as it involves two steps (pre clap parsing and after parsing) and even more difficult as they are in different locations in the codebase. I thought about moving everything to pre clap parsing based on the wallet sub-command the user has entered but that will clog the entry point as there will be lots of if...else checks.

Also, for the Parser trait, I read that it does not allow interacting with an external resource such as reading a file as I would want it.

I will also be trying out other approaches in case there is a cleaner way to handle it.

@notmandatory

notmandatory commented Sep 6, 2025

Copy link
Copy Markdown
Member

How about something like:

  1. One command to save a wallet config, give wallet name or a default name is used, clap enforces required options; optional -f to override existing config:
    wallet [-f] [-w <name>] config <wallet opts>
  2. All other wallet commands require that a config exists, use wallet name or the default is used. Give error if config is missing:
    wallet [-w <name>] sync | balance | new_address | etc...
  3. Repl uses the same wallet configs:
    repl [-w <name>]
  4. Add a command to list all available config names with summary of configured options:
    wallet list
  5. Should throw warnings if using mainnet and saving a private descriptor in a config.

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from 7cd062b to 28796caCompareOctober 5, 2025 03:50
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from 77864b4 to c5c4fdbCompareOctober 15, 2025 13:17

@notmandatorynotmandatory left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found an error when testing with testnet4, and a couple small nits should be fixed too. Otherwise this looks good.

In the future if everyone prefers the config approach it should probably become the only way to use the wallet features.

Comment threadREADME.md Outdated
Comment threadsrc/commands.rs Outdated
Comment threadsrc/utils.rs
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from c5c4fdb to 7be9a30CompareOctober 27, 2025 19:41
@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I found an error when testing with testnet4, and a couple small nits should be fixed too. Otherwise this looks good.

Thank you for catching all these.
I have updated.

In the future if everyone prefers the config approach it should probably become the only way to use the wallet features.

Yes, I agree.

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from 7be9a30 to 805d075CompareNovember 11, 2025 11:36
- 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: bitcoindevkit#192]
- rename init to config and move walletopts as
config options
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from a95a621 to 4f58575CompareJanuary 16, 2026 12:16

@thunderbiscuitthunderbiscuit left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this! I'll use it for sure once it gets in. I have two little things I want to ask, take them or leave them they're not blockers at all.

Question

When I run the example in the readme, I get the following config file:

network = "signet"
[wallets.my_wallet]
wallet = "my_wallet"network = "signet"ext_descriptor = "tr(tprv8Z.../0/*)#dtdqk3dx"int_descriptor = "tr(tprv8Z.../1/*)#ulgptya7"database_type = "sqlite"client_type = "electrum"server_url = "ssl://mempool.space:60602"batch_size = 10

The network is somehow added as a top-level key, but I suspect it's meant to only be added under the specific wallet config maybe? It doesn't prevent the cli from working as expected however so all is good there.

Comment

I always find it hard when applications require a config file but it's empty by default. I have to search in their docs to find what's available, and even then it's hard to know if you miss anything. A nicer approach is when the config file comes pre-populated, with all keys commented out to start with but they're at least all there so I can use the config file to sort of "discover" what's available in the wallet. This is not always possible for all keys, but could be cool here. When doing this you could do it 2 ways:

  1. Your config file could just come pre-made with a top-level commented section that has all keys available and the rest works as it currently does (easiest to implement). Note that you could also just add this as a codeblock in the readme (a complete list of available config options).
  2. Each newly created wallet comes with its own section of complete config keys, some active and the rest commented out.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

Thanks for this! I'll use it for sure once it gets in. I have two little things I want to ask, take them or leave them they're not blockers at all.

Question

When I run the example in the readme, I get the following config file:

network = "signet"
[wallets.my_wallet]
wallet = "my_wallet"network = "signet"ext_descriptor = "tr(tprv8Z.../0/*)#dtdqk3dx"int_descriptor = "tr(tprv8Z.../1/*)#ulgptya7"database_type = "sqlite"client_type = "electrum"server_url = "ssl://mempool.space:60602"batch_size = 10

The network is somehow added as a top-level key, but I suspect it's meant to only be added under the specific wallet config maybe? It doesn't prevent the cli from working as expected however so all is good there.

Comment

I always find it hard when applications require a config file but it's empty by default. I have to search in their docs to find what's available, and even then it's hard to know if you miss anything. A nicer approach is when the config file comes pre-populated, with all keys commented out to start with but they're at least all there so I can use the config file to sort of "discover" what's available in the wallet. This is not always possible for all keys, but could be cool here. When doing this you could do it 2 ways:

  1. Your config file could just come pre-made with a top-level commented section that has all keys available and the rest works as it currently does (easiest to implement). Note that you could also just add this as a codeblock in the readme (a complete list of available config options).
  2. Each newly created wallet comes with its own section of complete config keys, some active and the rest commented out.

Thank you for the review @thunderbiscuit
I will include this feedback in the next update as I also look at the configure_me lib to pick improvements.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

as I also look at the configure_me lib to pick improvements

I have done a quick review of configure_me, and from my perspective, it may not be suitable for the CLI's use case. It uses a declarative approach to define the config file and generates a static file that updating it requires manually editing and recompiling. It is more suitable for an application-wide configuration and will be challenging to use for a per-wallet configuration. Also, I have not seen how it can handle conditional features. Lastly, I am not sure it can integrate with clap as they seemed to serve the same purpose (might be wrong). But there are improvements that we can pick from the library, things like validation and maybe how we merge fetched values into the CLI values.

@notmandatory

Copy link
Copy Markdown
Member

thanks for looking into it, I agree we should stick with our simpler toml file approach.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

The network is somehow added as a top-level key, but I suspect it's meant to only be added under the specific wallet config maybe? It doesn't prevent the cli from working as expected however so all is good there.

Thank you for noting this. It has been fixed now

Comment

I always find it hard when applications require a config file but it's empty by default. I have to search in their docs to find what's available, and even then it's hard to know if you miss anything. A nicer approach is when the config file comes pre-populated, with all keys commented out to start with but they're at least all there so I can use the config file to sort of "discover" what's available in the wallet. This is not always possible for all keys, but could be cool here. When doing this you could do it 2 ways:

  1. Your config file could just come pre-made with a top-level commented section that has all keys available and the rest works as it currently does (easiest to implement). Note that you could also just add this as a codeblock in the readme (a complete list of available config options).
  2. Each newly created wallet comes with its own section of complete config keys, some active and the rest commented out.

I have considered this approach and agree that having a configuration file for an app is beneficial. However, I’m not sure it applies to this tool for two reasons. Firstly, we do not expect users to manually edit the config file because we want clap to validate the passed values based on the features enabled by the user. Allowing users to modify this file could lead to errors when they run wallet commands.

Secondly, this configuration is intended specifically for the wallet and does not pertain to broader application settings. Users who are not testing their wallet flows may find the config file entirely irrelevant.

- add wallets command
- add warning for using priv descriptors
- update readme
- add loading network from config
- fix review comments
- refactor config by impl TryFrom trait for
WalletOpts
- fix top-level network duplicate in config file
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from ac61b94 to be31c14CompareJanuary 19, 2026 15:18
@notmandatory
notmandatoryforce-pushed the feat/init-wallet-support branch from 87472e3 to ceb9332CompareJanuary 19, 2026 22:39
@notmandatory

Copy link
Copy Markdown
Member

I pushed ceb9332 to update README examples to use new wallet config feature.

@notmandatorynotmandatory left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK ceb9332

Looks good! much easier to use.

@tvpeter
tvpeter merged commit b9cf2ac into bitcoindevkit:masterJan 19, 2026
5 checks passed
@github-project-automationgithub-project-automationBot moved this from Ready to Review to Done in BDK-CLIJan 19, 2026
Comment threadsrc/config.rs
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

Add "init" wallet support

5 participants

@tvpeter@coveralls@notmandatory@thunderbiscuit@nymius
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add saving wallet config with bdk-cli wallet config - #203

Merged
tvpeter merged 5 commits into
bitcoindevkit:masterfrom
tvpeter:feat/init-wallet-support
Jan 19, 2026
Merged

Add saving wallet config with bdk-cli wallet config#203
tvpeter merged 5 commits into
bitcoindevkit:masterfrom
tvpeter:feat/init-wallet-support

Conversation

@tvpeter

@tvpetertvpeter commented Jun 18, 2025

Copy link
Copy Markdown
Collaborator

Description

This PR adds bdk-cli wallet config command to save wallet configuration information to config.toml file in the data directory.

Fixes#192

Notes to the reviewers

  • Reusing the exported serde crate from bdk_wallet did not offer the derive feature
  • Fix out-of-bound error for shorten fn

Changelog notice

  • Add wallet subcommand config to save wallet configs
  • Add top-level wallets command to show all saved wallet configs

Checklists

Features

  • command to save a wallet config, give wallet name or a default name is used, clap enforces required options; optional -f to override existing config: wallet [-f] [-w <name>] config <wallet opts>
  • All other wallet commands require that a config exists, use wallet name or the default is used. Give error if config is missing: wallet [-w <name>] sync | balance | new_address | etc...
  • Repl uses the same wallet configs: repl [-w <name>]
  • command to list all saved wallet configs: wallets
  • throw warnings if using mainnet and saving a private descriptor in a config.

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

New Features:

  • I've added tests for the new feature
  • I've added docs for the new feature
  • I've updated CHANGELOG.md

@coveralls

coveralls commented Jun 18, 2025

Copy link
Copy Markdown

Pull Request Test Coverage Report for Build 21153320925

Details

  • 99 of 395(25.06%) changed or added relevant lines in 3 files are covered.
  • 1 unchanged line in 1 file lost coverage.
  • Overall coverage increased (+2.8%) to 10.717%

Changes Missing CoverageCovered LinesChanged/Added Lines%
src/utils.rs0430.0%
src/config.rs9615163.58%
src/handlers.rs32011.49%
Files with Coverage ReductionNew Missed Lines%
src/handlers.rs113.0%
TotalsCoverage Status
Change from base Build 20714655583:2.8%
Covered Lines:269
Relevant Lines:2510

💛 - Coveralls

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from b3966e3 to bf14df8CompareJune 19, 2025 04:32
@notmandatorynotmandatory moved this to Ready to Review in BDK-CLIJun 24, 2025
@notmandatorynotmandatory added this to the CLI 1.1.0 milestone Jun 24, 2025
@notmandatory

notmandatory commented Jun 24, 2025

Copy link
Copy Markdown
Member

I like the approach for loading the config file parameters if the file exists, but is there a reason you didn't add a CLI bdk-cli wallet init ... command in rust to create the config file rather than using just ?

Creating the config file in rust should be easier to maintain/keep in sync than your just approach and shouldn't take too much more than adding the Serialize trait to WalletConfigInner. You should be able to reuse the WalletOpts to capture the values with clap that you need to put in the config file too.

@notmandatorynotmandatory added the enhancement New feature or request label Jun 24, 2025
@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I like the approach for loading the config file parameters if the file exists, but is there a reason you didn't add a CLI bdk-cli wallet init ... command in rust to create the config file rather than using just ?

Creating the config file in rust should be easier to maintain/keep in sync than your just approach and shouldn't take too much more than adding the Serialize trait to WalletConfigInner. You should be able to reuse the WalletOpts to capture the values with clap that you need to put in the config file too.

Alright, I will update.

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from bf14df8 to 36ee973CompareJune 27, 2025 04:04
@tvpetertvpeter changed the title Add initializing wallet configuration with JustfileAdd initializing wallet configuration with bdk-cli wallet initJun 27, 2025
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 4 times, most recently from 5125cf8 to fcf7ce8CompareJune 27, 2025 10:03
@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

Alright, I will update.

@notmandatory I have updated the PR

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from f77b1da to 70a5390CompareAugust 25, 2025 19:26
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from 9461e85 to 5d9feb0CompareSeptember 1, 2025 04:20
@thunderbiscuit

Copy link
Copy Markdown
Member

I need to start keeping track of all these awesome new features I honestly see the PRs come in and can't keep up. This is super cool.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I need to start keeping track of all these awesome new features I honestly see the PRs come in and can't keep up. This is super cool.

Thank you @thunderbiscuit

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from 9549e09 to 0f6b320CompareSeptember 3, 2025 15:45
@notmandatory

Copy link
Copy Markdown
Member

I spent some time today reviewing and even though this looks like a workable way to do it and is based on my suggestion I'm afraid it's going to be a hassle to maintain. I've been experimenting with somehow using the different clap parsing functions (https://docs.rs/clap/latest/clap/trait.Parser.html) but so far haven't figured out a better way. I'd like to keep thinking about it. We might have to simplify the problem somehow such as by not trying to merge loaded and CLI args.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I'm afraid it's going to be a hassle to maintain. I've been experimenting with somehow using the different clap parsing functions (https://docs.rs/clap/latest/clap/trait.Parser.html) but so far haven't figured out a better way. I'd like to keep thinking about it. We might have to simplify the problem somehow such as by not trying to merge loaded and CLI args.

Thank you @notmandatory.
Yes, I agree that it will be challenging to maintain, as it involves two steps (pre clap parsing and after parsing) and even more difficult as they are in different locations in the codebase. I thought about moving everything to pre clap parsing based on the wallet sub-command the user has entered but that will clog the entry point as there will be lots of if...else checks.

Also, for the Parser trait, I read that it does not allow interacting with an external resource such as reading a file as I would want it.

I will also be trying out other approaches in case there is a cleaner way to handle it.

@notmandatory

notmandatory commented Sep 6, 2025

Copy link
Copy Markdown
Member

How about something like:

  1. One command to save a wallet config, give wallet name or a default name is used, clap enforces required options; optional -f to override existing config:
    wallet [-f] [-w <name>] config <wallet opts>
  2. All other wallet commands require that a config exists, use wallet name or the default is used. Give error if config is missing:
    wallet [-w <name>] sync | balance | new_address | etc...
  3. Repl uses the same wallet configs:
    repl [-w <name>]
  4. Add a command to list all available config names with summary of configured options:
    wallet list
  5. Should throw warnings if using mainnet and saving a private descriptor in a config.

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from 7cd062b to 28796caCompareOctober 5, 2025 03:50
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from 77864b4 to c5c4fdbCompareOctober 15, 2025 13:17

@notmandatorynotmandatory left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found an error when testing with testnet4, and a couple small nits should be fixed too. Otherwise this looks good.

In the future if everyone prefers the config approach it should probably become the only way to use the wallet features.

Comment threadREADME.md Outdated
Comment threadsrc/commands.rs Outdated
Comment threadsrc/utils.rs
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from c5c4fdb to 7be9a30CompareOctober 27, 2025 19:41
@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I found an error when testing with testnet4, and a couple small nits should be fixed too. Otherwise this looks good.

Thank you for catching all these.
I have updated.

In the future if everyone prefers the config approach it should probably become the only way to use the wallet features.

Yes, I agree.

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from 7be9a30 to 805d075CompareNovember 11, 2025 11:36
- 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: bitcoindevkit#192]
- rename init to config and move walletopts as
config options
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from a95a621 to 4f58575CompareJanuary 16, 2026 12:16

@thunderbiscuitthunderbiscuit left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this! I'll use it for sure once it gets in. I have two little things I want to ask, take them or leave them they're not blockers at all.

Question

When I run the example in the readme, I get the following config file:

network = "signet"
[wallets.my_wallet]
wallet = "my_wallet"network = "signet"ext_descriptor = "tr(tprv8Z.../0/*)#dtdqk3dx"int_descriptor = "tr(tprv8Z.../1/*)#ulgptya7"database_type = "sqlite"client_type = "electrum"server_url = "ssl://mempool.space:60602"batch_size = 10

The network is somehow added as a top-level key, but I suspect it's meant to only be added under the specific wallet config maybe? It doesn't prevent the cli from working as expected however so all is good there.

Comment

I always find it hard when applications require a config file but it's empty by default. I have to search in their docs to find what's available, and even then it's hard to know if you miss anything. A nicer approach is when the config file comes pre-populated, with all keys commented out to start with but they're at least all there so I can use the config file to sort of "discover" what's available in the wallet. This is not always possible for all keys, but could be cool here. When doing this you could do it 2 ways:

  1. Your config file could just come pre-made with a top-level commented section that has all keys available and the rest works as it currently does (easiest to implement). Note that you could also just add this as a codeblock in the readme (a complete list of available config options).
  2. Each newly created wallet comes with its own section of complete config keys, some active and the rest commented out.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

Thanks for this! I'll use it for sure once it gets in. I have two little things I want to ask, take them or leave them they're not blockers at all.

Question

When I run the example in the readme, I get the following config file:

network = "signet"
[wallets.my_wallet]
wallet = "my_wallet"network = "signet"ext_descriptor = "tr(tprv8Z.../0/*)#dtdqk3dx"int_descriptor = "tr(tprv8Z.../1/*)#ulgptya7"database_type = "sqlite"client_type = "electrum"server_url = "ssl://mempool.space:60602"batch_size = 10

The network is somehow added as a top-level key, but I suspect it's meant to only be added under the specific wallet config maybe? It doesn't prevent the cli from working as expected however so all is good there.

Comment

I always find it hard when applications require a config file but it's empty by default. I have to search in their docs to find what's available, and even then it's hard to know if you miss anything. A nicer approach is when the config file comes pre-populated, with all keys commented out to start with but they're at least all there so I can use the config file to sort of "discover" what's available in the wallet. This is not always possible for all keys, but could be cool here. When doing this you could do it 2 ways:

  1. Your config file could just come pre-made with a top-level commented section that has all keys available and the rest works as it currently does (easiest to implement). Note that you could also just add this as a codeblock in the readme (a complete list of available config options).
  2. Each newly created wallet comes with its own section of complete config keys, some active and the rest commented out.

Thank you for the review @thunderbiscuit
I will include this feedback in the next update as I also look at the configure_me lib to pick improvements.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

as I also look at the configure_me lib to pick improvements

I have done a quick review of configure_me, and from my perspective, it may not be suitable for the CLI's use case. It uses a declarative approach to define the config file and generates a static file that updating it requires manually editing and recompiling. It is more suitable for an application-wide configuration and will be challenging to use for a per-wallet configuration. Also, I have not seen how it can handle conditional features. Lastly, I am not sure it can integrate with clap as they seemed to serve the same purpose (might be wrong). But there are improvements that we can pick from the library, things like validation and maybe how we merge fetched values into the CLI values.

@notmandatory

Copy link
Copy Markdown
Member

thanks for looking into it, I agree we should stick with our simpler toml file approach.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

The network is somehow added as a top-level key, but I suspect it's meant to only be added under the specific wallet config maybe? It doesn't prevent the cli from working as expected however so all is good there.

Thank you for noting this. It has been fixed now

Comment

I always find it hard when applications require a config file but it's empty by default. I have to search in their docs to find what's available, and even then it's hard to know if you miss anything. A nicer approach is when the config file comes pre-populated, with all keys commented out to start with but they're at least all there so I can use the config file to sort of "discover" what's available in the wallet. This is not always possible for all keys, but could be cool here. When doing this you could do it 2 ways:

  1. Your config file could just come pre-made with a top-level commented section that has all keys available and the rest works as it currently does (easiest to implement). Note that you could also just add this as a codeblock in the readme (a complete list of available config options).
  2. Each newly created wallet comes with its own section of complete config keys, some active and the rest commented out.

I have considered this approach and agree that having a configuration file for an app is beneficial. However, I’m not sure it applies to this tool for two reasons. Firstly, we do not expect users to manually edit the config file because we want clap to validate the passed values based on the features enabled by the user. Allowing users to modify this file could lead to errors when they run wallet commands.

Secondly, this configuration is intended specifically for the wallet and does not pertain to broader application settings. Users who are not testing their wallet flows may find the config file entirely irrelevant.

- add wallets command
- add warning for using priv descriptors
- update readme
- add loading network from config
- fix review comments
- refactor config by impl TryFrom trait for
WalletOpts
- fix top-level network duplicate in config file
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from ac61b94 to be31c14CompareJanuary 19, 2026 15:18
@notmandatory
notmandatoryforce-pushed the feat/init-wallet-support branch from 87472e3 to ceb9332CompareJanuary 19, 2026 22:39
@notmandatory

Copy link
Copy Markdown
Member

I pushed ceb9332 to update README examples to use new wallet config feature.

@notmandatorynotmandatory left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK ceb9332

Looks good! much easier to use.

@tvpeter
tvpeter merged commit b9cf2ac into bitcoindevkit:masterJan 19, 2026
5 checks passed
@github-project-automationgithub-project-automationBot moved this from Ready to Review to Done in BDK-CLIJan 19, 2026
Comment threadsrc/config.rs
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

Add "init" wallet support

5 participants

@tvpeter@coveralls@notmandatory@thunderbiscuit@nymius
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Add saving wallet config with bdk-cli wallet config - #203

Merged
tvpeter merged 5 commits into
bitcoindevkit:masterfrom
tvpeter:feat/init-wallet-support
Jan 19, 2026
Merged

Add saving wallet config with bdk-cli wallet config#203
tvpeter merged 5 commits into
bitcoindevkit:masterfrom
tvpeter:feat/init-wallet-support

Conversation

@tvpeter

@tvpetertvpeter commented Jun 18, 2025

Copy link
Copy Markdown
Collaborator

Description

This PR adds bdk-cli wallet config command to save wallet configuration information to config.toml file in the data directory.

Fixes#192

Notes to the reviewers

  • Reusing the exported serde crate from bdk_wallet did not offer the derive feature
  • Fix out-of-bound error for shorten fn

Changelog notice

  • Add wallet subcommand config to save wallet configs
  • Add top-level wallets command to show all saved wallet configs

Checklists

Features

  • command to save a wallet config, give wallet name or a default name is used, clap enforces required options; optional -f to override existing config: wallet [-f] [-w <name>] config <wallet opts>
  • All other wallet commands require that a config exists, use wallet name or the default is used. Give error if config is missing: wallet [-w <name>] sync | balance | new_address | etc...
  • Repl uses the same wallet configs: repl [-w <name>]
  • command to list all saved wallet configs: wallets
  • throw warnings if using mainnet and saving a private descriptor in a config.

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

New Features:

  • I've added tests for the new feature
  • I've added docs for the new feature
  • I've updated CHANGELOG.md

@coveralls

coveralls commented Jun 18, 2025

Copy link
Copy Markdown

Pull Request Test Coverage Report for Build 21153320925

Details

  • 99 of 395(25.06%) changed or added relevant lines in 3 files are covered.
  • 1 unchanged line in 1 file lost coverage.
  • Overall coverage increased (+2.8%) to 10.717%

Changes Missing CoverageCovered LinesChanged/Added Lines%
src/utils.rs0430.0%
src/config.rs9615163.58%
src/handlers.rs32011.49%
Files with Coverage ReductionNew Missed Lines%
src/handlers.rs113.0%
TotalsCoverage Status
Change from base Build 20714655583:2.8%
Covered Lines:269
Relevant Lines:2510

💛 - Coveralls

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from b3966e3 to bf14df8CompareJune 19, 2025 04:32
@notmandatorynotmandatory moved this to Ready to Review in BDK-CLIJun 24, 2025
@notmandatorynotmandatory added this to the CLI 1.1.0 milestone Jun 24, 2025
@notmandatory

notmandatory commented Jun 24, 2025

Copy link
Copy Markdown
Member

I like the approach for loading the config file parameters if the file exists, but is there a reason you didn't add a CLI bdk-cli wallet init ... command in rust to create the config file rather than using just ?

Creating the config file in rust should be easier to maintain/keep in sync than your just approach and shouldn't take too much more than adding the Serialize trait to WalletConfigInner. You should be able to reuse the WalletOpts to capture the values with clap that you need to put in the config file too.

@notmandatorynotmandatory added the enhancement New feature or request label Jun 24, 2025
@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I like the approach for loading the config file parameters if the file exists, but is there a reason you didn't add a CLI bdk-cli wallet init ... command in rust to create the config file rather than using just ?

Creating the config file in rust should be easier to maintain/keep in sync than your just approach and shouldn't take too much more than adding the Serialize trait to WalletConfigInner. You should be able to reuse the WalletOpts to capture the values with clap that you need to put in the config file too.

Alright, I will update.

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from bf14df8 to 36ee973CompareJune 27, 2025 04:04
@tvpetertvpeter changed the title Add initializing wallet configuration with JustfileAdd initializing wallet configuration with bdk-cli wallet initJun 27, 2025
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 4 times, most recently from 5125cf8 to fcf7ce8CompareJune 27, 2025 10:03
@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

Alright, I will update.

@notmandatory I have updated the PR

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from f77b1da to 70a5390CompareAugust 25, 2025 19:26
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from 9461e85 to 5d9feb0CompareSeptember 1, 2025 04:20
@thunderbiscuit

Copy link
Copy Markdown
Member

I need to start keeping track of all these awesome new features I honestly see the PRs come in and can't keep up. This is super cool.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I need to start keeping track of all these awesome new features I honestly see the PRs come in and can't keep up. This is super cool.

Thank you @thunderbiscuit

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from 9549e09 to 0f6b320CompareSeptember 3, 2025 15:45
@notmandatory

Copy link
Copy Markdown
Member

I spent some time today reviewing and even though this looks like a workable way to do it and is based on my suggestion I'm afraid it's going to be a hassle to maintain. I've been experimenting with somehow using the different clap parsing functions (https://docs.rs/clap/latest/clap/trait.Parser.html) but so far haven't figured out a better way. I'd like to keep thinking about it. We might have to simplify the problem somehow such as by not trying to merge loaded and CLI args.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I'm afraid it's going to be a hassle to maintain. I've been experimenting with somehow using the different clap parsing functions (https://docs.rs/clap/latest/clap/trait.Parser.html) but so far haven't figured out a better way. I'd like to keep thinking about it. We might have to simplify the problem somehow such as by not trying to merge loaded and CLI args.

Thank you @notmandatory.
Yes, I agree that it will be challenging to maintain, as it involves two steps (pre clap parsing and after parsing) and even more difficult as they are in different locations in the codebase. I thought about moving everything to pre clap parsing based on the wallet sub-command the user has entered but that will clog the entry point as there will be lots of if...else checks.

Also, for the Parser trait, I read that it does not allow interacting with an external resource such as reading a file as I would want it.

I will also be trying out other approaches in case there is a cleaner way to handle it.

@notmandatory

notmandatory commented Sep 6, 2025

Copy link
Copy Markdown
Member

How about something like:

  1. One command to save a wallet config, give wallet name or a default name is used, clap enforces required options; optional -f to override existing config:
    wallet [-f] [-w <name>] config <wallet opts>
  2. All other wallet commands require that a config exists, use wallet name or the default is used. Give error if config is missing:
    wallet [-w <name>] sync | balance | new_address | etc...
  3. Repl uses the same wallet configs:
    repl [-w <name>]
  4. Add a command to list all available config names with summary of configured options:
    wallet list
  5. Should throw warnings if using mainnet and saving a private descriptor in a config.

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from 7cd062b to 28796caCompareOctober 5, 2025 03:50
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from 77864b4 to c5c4fdbCompareOctober 15, 2025 13:17

@notmandatorynotmandatory left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found an error when testing with testnet4, and a couple small nits should be fixed too. Otherwise this looks good.

In the future if everyone prefers the config approach it should probably become the only way to use the wallet features.

Comment threadREADME.md Outdated
Comment threadsrc/commands.rs Outdated
Comment threadsrc/utils.rs
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from c5c4fdb to 7be9a30CompareOctober 27, 2025 19:41
@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

I found an error when testing with testnet4, and a couple small nits should be fixed too. Otherwise this looks good.

Thank you for catching all these.
I have updated.

In the future if everyone prefers the config approach it should probably become the only way to use the wallet features.

Yes, I agree.

@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from 7be9a30 to 805d075CompareNovember 11, 2025 11:36
- 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: bitcoindevkit#192]
- rename init to config and move walletopts as
config options
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch 2 times, most recently from a95a621 to 4f58575CompareJanuary 16, 2026 12:16

@thunderbiscuitthunderbiscuit left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this! I'll use it for sure once it gets in. I have two little things I want to ask, take them or leave them they're not blockers at all.

Question

When I run the example in the readme, I get the following config file:

network = "signet"
[wallets.my_wallet]
wallet = "my_wallet"network = "signet"ext_descriptor = "tr(tprv8Z.../0/*)#dtdqk3dx"int_descriptor = "tr(tprv8Z.../1/*)#ulgptya7"database_type = "sqlite"client_type = "electrum"server_url = "ssl://mempool.space:60602"batch_size = 10

The network is somehow added as a top-level key, but I suspect it's meant to only be added under the specific wallet config maybe? It doesn't prevent the cli from working as expected however so all is good there.

Comment

I always find it hard when applications require a config file but it's empty by default. I have to search in their docs to find what's available, and even then it's hard to know if you miss anything. A nicer approach is when the config file comes pre-populated, with all keys commented out to start with but they're at least all there so I can use the config file to sort of "discover" what's available in the wallet. This is not always possible for all keys, but could be cool here. When doing this you could do it 2 ways:

  1. Your config file could just come pre-made with a top-level commented section that has all keys available and the rest works as it currently does (easiest to implement). Note that you could also just add this as a codeblock in the readme (a complete list of available config options).
  2. Each newly created wallet comes with its own section of complete config keys, some active and the rest commented out.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

Thanks for this! I'll use it for sure once it gets in. I have two little things I want to ask, take them or leave them they're not blockers at all.

Question

When I run the example in the readme, I get the following config file:

network = "signet"
[wallets.my_wallet]
wallet = "my_wallet"network = "signet"ext_descriptor = "tr(tprv8Z.../0/*)#dtdqk3dx"int_descriptor = "tr(tprv8Z.../1/*)#ulgptya7"database_type = "sqlite"client_type = "electrum"server_url = "ssl://mempool.space:60602"batch_size = 10

The network is somehow added as a top-level key, but I suspect it's meant to only be added under the specific wallet config maybe? It doesn't prevent the cli from working as expected however so all is good there.

Comment

I always find it hard when applications require a config file but it's empty by default. I have to search in their docs to find what's available, and even then it's hard to know if you miss anything. A nicer approach is when the config file comes pre-populated, with all keys commented out to start with but they're at least all there so I can use the config file to sort of "discover" what's available in the wallet. This is not always possible for all keys, but could be cool here. When doing this you could do it 2 ways:

  1. Your config file could just come pre-made with a top-level commented section that has all keys available and the rest works as it currently does (easiest to implement). Note that you could also just add this as a codeblock in the readme (a complete list of available config options).
  2. Each newly created wallet comes with its own section of complete config keys, some active and the rest commented out.

Thank you for the review @thunderbiscuit
I will include this feedback in the next update as I also look at the configure_me lib to pick improvements.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

as I also look at the configure_me lib to pick improvements

I have done a quick review of configure_me, and from my perspective, it may not be suitable for the CLI's use case. It uses a declarative approach to define the config file and generates a static file that updating it requires manually editing and recompiling. It is more suitable for an application-wide configuration and will be challenging to use for a per-wallet configuration. Also, I have not seen how it can handle conditional features. Lastly, I am not sure it can integrate with clap as they seemed to serve the same purpose (might be wrong). But there are improvements that we can pick from the library, things like validation and maybe how we merge fetched values into the CLI values.

@notmandatory

Copy link
Copy Markdown
Member

thanks for looking into it, I agree we should stick with our simpler toml file approach.

@tvpeter

Copy link
Copy Markdown
CollaboratorAuthor

The network is somehow added as a top-level key, but I suspect it's meant to only be added under the specific wallet config maybe? It doesn't prevent the cli from working as expected however so all is good there.

Thank you for noting this. It has been fixed now

Comment

I always find it hard when applications require a config file but it's empty by default. I have to search in their docs to find what's available, and even then it's hard to know if you miss anything. A nicer approach is when the config file comes pre-populated, with all keys commented out to start with but they're at least all there so I can use the config file to sort of "discover" what's available in the wallet. This is not always possible for all keys, but could be cool here. When doing this you could do it 2 ways:

  1. Your config file could just come pre-made with a top-level commented section that has all keys available and the rest works as it currently does (easiest to implement). Note that you could also just add this as a codeblock in the readme (a complete list of available config options).
  2. Each newly created wallet comes with its own section of complete config keys, some active and the rest commented out.

I have considered this approach and agree that having a configuration file for an app is beneficial. However, I’m not sure it applies to this tool for two reasons. Firstly, we do not expect users to manually edit the config file because we want clap to validate the passed values based on the features enabled by the user. Allowing users to modify this file could lead to errors when they run wallet commands.

Secondly, this configuration is intended specifically for the wallet and does not pertain to broader application settings. Users who are not testing their wallet flows may find the config file entirely irrelevant.

- add wallets command
- add warning for using priv descriptors
- update readme
- add loading network from config
- fix review comments
- refactor config by impl TryFrom trait for
WalletOpts
- fix top-level network duplicate in config file
@tvpeter
tvpeterforce-pushed the feat/init-wallet-support branch from ac61b94 to be31c14CompareJanuary 19, 2026 15:18
@notmandatory
notmandatoryforce-pushed the feat/init-wallet-support branch from 87472e3 to ceb9332CompareJanuary 19, 2026 22:39
@notmandatory

Copy link
Copy Markdown
Member

I pushed ceb9332 to update README examples to use new wallet config feature.

@notmandatorynotmandatory left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK ceb9332

Looks good! much easier to use.

@tvpeter
tvpeter merged commit b9cf2ac into bitcoindevkit:masterJan 19, 2026
5 checks passed
@github-project-automationgithub-project-automationBot moved this from Ready to Review to Done in BDK-CLIJan 19, 2026
Comment threadsrc/config.rs
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

Add "init" wallet support

5 participants

@tvpeter@coveralls@notmandatory@thunderbiscuit@nymius