-
Notifications
You must be signed in to change notification settings - Fork 1
feat: add multi-address type support for on-chain wallet #45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
acked the concept & description discussed with Spiral and with Ben in private next step: Ben is exploring a more "fork-friendly" alternative |
|
Caution Sharing here some interesting concepts that I didn't double-check but if they're not slop we might have to address this in the new implementation. Review SummaryPR adds multi-address type support (Legacy/NestedSegwit/NativeSegwit/Taproot) via multiple BDK wallet instances per node. +6296/-975 lines across 32 files. The architecture is fundamentally sound but has several critical issues that must be addressed before merge. CRITICAL ISSUES (Must Fix)1. Backwards-Incompatible Persistence Namespace Change (Data Loss Risk)Files: The persistence macro now appends address type suffixes to secondary namespaces:
Impact: Existing users upgrading to this version will have their wallet data stored under the OLD namespace (without suffix). The new code looks in the NEW namespace (with Required fix: Add migration logic that:
2. Incorrect UTXO Weight Calculation in Coin SelectionFile:
let descriptor = primary_wallet.public_descriptor(utxo.keychain);
let satisfaction_weight = descriptor.max_weight_to_satisfy()...For non-primary UTXOs (e.g., Legacy UTXOs when primary is NativeSegwit), Required fix: Look up the correct wallet for each UTXO (by finding which wallet owns the outpoint) and use that wallet's descriptor for weight calculation. 3. Fee Calculation Bug for Cross-Wallet Transactions in Payment StoreFile: let total_fee = primary_wallet.calculate_fee(&tx).unwrap_or(Amount::ZERO).to_sat();BDK's Required fix: Calculate fees by iterating all wallets and summing input values, similar to how 4.
|
|
@ben-kaufman I drafted the PR until the next iteration. |
Multi-Address Type Support for On-Chain Wallet
Summary
Adds comprehensive multi-address type support, allowing a single LDK Node to manage multiple Bitcoin address types (Legacy, NestedSegwit, NativeSegwit, Taproot) simultaneously:
AddressTypeenum with Legacy, NestedSegwit, NativeSegwit, and Taproot variantsConfig.address_typefor new addresses and change outputsConfig.address_types_to_monitorfor migration scenariosNode::get_balance_for_address_type()OnchainPayment::new_address_for_type()Motivation
Many Bitcoin wallets need to support multiple address types simultaneously:
API Changes
Configuration
New configuration options in
Config:address_type: AddressType- Primary address type for new addresses and change outputs (default: NativeSegwit)address_types_to_monitor: Vec<AddressType>- Additional address types to monitor (default: empty)Builder Methods
Builder::set_address_type(AddressType)- Set the primary address typeBuilder::set_address_types_to_monitor(Vec<AddressType>)- Set additional types to monitorNode Methods
Node::get_balance_for_address_type(AddressType)- Get balance for a specific address typeNode::list_monitored_address_types()- List all monitored address types (primary + monitored)OnchainPayment Methods
OnchainPayment::new_address_for_type(AddressType)- Get address for specific typeNew Types
AddressTypeenum:Legacy,NestedSegwit,NativeSegwit,TaprootAddressTypeBalance/OnchainBalanceForType- Balance info for a specific address typeImplementation Details
Multi-Wallet Architecture
Internally manages multiple BDK wallet instances (one per address type) with unified coordination:
Chain Source Updates
All chain backends (Esplora, Electrum, Bitcoind) updated to:
Wallet Persistence
Test Plan
test_multi_wallet_setup- Basic multi-wallet configurationtest_multi_wallet_balance_aggregation- Balance aggregation across typestest_multi_wallet_get_address_balance- Per-type balance queriestest_cross_wallet_spending- Spending from multiple wallet typestest_cross_wallet_spending_three_types- Three wallet types in one txtest_multi_wallet_send_operation- Send with multi-wallet configtest_multi_wallet_send_all- Send all with aggregated UTXOstest_send_all_drains_all_wallets- Verify all wallets are drainedtest_multi_wallet_utxo_selection- UTXO selection across typestest_rbf_single_wallet_input_with_multi_wallet_config- Single-wallet RBFtest_rbf_cross_wallet_transaction- Cross-wallet RBFtest_rbf_additional_inputs_fee_rate_correctness- Fee rate with added inputstest_cpfp_for_cross_wallet_transaction- Cross-wallet CPFPtest_multi_wallet_persistence_across_restart- Persistence verificationtest_new_address_for_type- Address generation per typetest_new_address_for_unmonitored_type- Error for unmonitored typestest_all_address_types_as_primary- Each type as primarytest_sync_updates_all_wallet_balances- Sync updates all typesBreaking Changes
None. The default configuration (
address_types_to_monitor = []) maintains existing single-wallet behavior.Files Changed
src/config.rsAddressTypeenum and config optionssrc/builder.rssrc/wallet/mod.rssrc/wallet/persist.rssrc/chain/mod.rssrc/chain/esplora.rssrc/chain/electrum.rssrc/chain/bitcoind.rssrc/payment/onchain.rsnew_address_for_type()src/lib.rssrc/balance.rsAddressTypeBalancestructsrc/io/utils.rsbindings/ldk_node.udltests/multi_wallet_tests.rs