Skip to content

Feat: Add bip329 wallet labels#266

Open
Musab1258 wants to merge 5 commits intobitcoindevkit:masterfrom
Musab1258:feat/add-bip329-wallet-labels
Open

Feat: Add bip329 wallet labels#266
Musab1258 wants to merge 5 commits intobitcoindevkit:masterfrom
Musab1258:feat/add-bip329-wallet-labels

Conversation

@Musab1258
Copy link
Copy Markdown

@Musab1258 Musab1258 commented Mar 31, 2026

Description

This PR adds BIP-329 wallet label support to bdk-cli, to fix #184. It uses the [bip329] crate to manage label data, persists it in a separate labels.jsonl file within the wallet's data directory (e.g. ~/.bdk-bitcoin/<wallet_name>/labels.jsonl), and keeps it decoupled from the wallet's SQLite/redb database. It also exports and imports label files.

This PR includes the following functionality:

  • Set labels: It uses a new label offline subcommand to attach a human-readable label to either a transaction ID, address, or UTXO (outpoint).
  • Persist labels: It ensures that Labels are loaded from disk at the start of every offline wallet command and saved back after the command completes, so they survive across sessions.
  • Display labels: The unspent and transactions commands now include a Label column in both --pretty table output and standard JSON output, showing the stored label or an em dash if none exists.
  • Import labels: The import_labels subcommand merges labels from an external BIP-329 JSONL file into the wallet's current label state. If a label for the same item already exists, it is overwritten by the imported one.
  • Export labels: The export_labels subcommand writes the wallet's current label state to a user-specified BIP-329 JSONL file, suitable for backup or use in other BIP-329 compliant wallets.

Notes to the reviewers

  • Labels are stored in a separate labels.jsonl file rather than inside the wallet database. This keeps the label format portable and interoperable with other BIP-329 compliant wallets.
  • The Label import from bip329 is aliased as BipLabel in handlers.rs to avoid a name clash with the OfflineWalletSubCommand::Label variant brought into scope via use crate::commands::OfflineWalletSubCommand::*.
  • The import_labels command uses the existing add_or_update_label helper to merge incoming labels one at a time, new label references are inserted, and existing label references are overwritten by the imported value.
  • The export_labels command writes to a user-specified path, which is independent of the wallet's internal labels.jsonl file. The internal file is always managed automatically by the save-on-exit mechanism, so the two files remain separate.

Changelog notice

Added

  • New label subcommand to OfflineWalletSubCommand for tagging transactions, addresses, and UTXOs with human-readable labels.
  • New import_labels subcommand to merge labels from an external BIP-329 JSONL file into the wallet's current label state.
  • New export_labels subcommand to back up the wallet's current label state to a user-specified BIP-329 JSONL file.
  • BIP-329 compliant label persistence via a labels.jsonl file in the wallet data directory.
  • Label column in unspent and transactions output (both --pretty and JSON).
  • parse_txid helper in utils.rs.
  • bip329 = "0.4.0" dependency in Cargo.toml.

Checklists

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

Bugfixes:

  • This pull request breaks the existing API
  • I've added tests to reproduce the issue which are now passing
  • I'm linking the issue being fixed by this PR

- Loads the \'Labels\' state from \'<wallet>.labels.jsonl\' after \'load_wallet_config\'.

- Updates \'handle_offline_wallet_subcommand\' to accept mutable label state.

- Exports and saves the in-memory labels to disk before the command return.
- Injects label lookups into the `unspent` and `transactions` match arms.

- Updates the `--pretty` table formatting to include a new 'Label' column (using an em dash for missing labels).

- Appends the label string to the standard JSON output
- Introduces the `Label` variant to `OfflineWalletSubCommand` with strict `clap` conflict rules.

- Adds a `parse_txid` helper to utils.rs.

- Implements an `add_or_add_update_label` helper in `handlers.rs` to mutate the in-memory label state in place.
@Musab1258
Copy link
Copy Markdown
Author

Hi @tvpeter, I am done with this. You can check it out when you are free.

I will start working on the follow-up PR to add import and export of label files.

- Introduces `ImportLabels` and `ExportLabels` variants to `OfflineWalletSubCommand` for CLI parsing.

- Implements label merging from external JSONL files using `try_from_file` and `add_or_update_label`.

- Enables backing up the current label state to a user-specified path using `export_to_file`.
@Musab1258
Copy link
Copy Markdown
Author

Hi @tvpeter, I eventually decided to add the import and export of BIP-329 JSONL files' implementation here when, after I was done with the implementation, I saw that it was something that could fit into this PR without bloating it.

So, instead of creating a second PR and having reviewers go through the stress of reviewing two PRs that can probably fit into one, I decided to make it one PR.

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 4, 2026

Codecov Report

❌ Patch coverage is 0% with 132 lines in your changes missing coverage. Please review.
✅ Project coverage is 10.59%. Comparing base (07fd32f) to head (8422d82).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
src/handlers.rs 0.00% 129 Missing ⚠️
src/utils.rs 0.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #266      +/-   ##
==========================================
- Coverage   11.13%   10.59%   -0.55%     
==========================================
  Files           8        8              
  Lines        2488     2615     +127     
==========================================
  Hits          277      277              
- Misses       2211     2338     +127     
Flag Coverage Δ
rust 10.59% <0.00%> (-0.55%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

Add BIP-329 wallet label support

1 participant