Skip to content

Conversation

@nymius
Copy link
Collaborator

@nymius nymius commented Aug 25, 2025

Description

Fixes #29 , by moving the computation of the transaction shared secret outside of the indexer, and also including methods to generate script pubkeys just with the knowledge of the scan secret key, the spend public key and the shared secret, without knowing the full transaction.

Fixes #28, by replacing bdk example-crates by bdk-cli in the regtest environment.

This PR introduces significant restructuring and upgrades to the Silent Payments examples and related tooling. Key changes include:

  • Restructuring and renaming of example crates:

    • Moved example-crates/example_silentpayments into a new CLI workspace structure under cli/v1 and cli/v2.
    • Added dedicated binaries (sp-cli1, sp-cli2) for better separation of legacy and new CLI workflows.
    • Updated scripts, casts, and flows from example-crates to cli for more logical organization.
  • New CLI v2 (cli/v2) supporting:

    • Extended commands for creating wallets, deriving silent payment addresses, scanning the blockchain using bitcoind RPC or Kyoto filters, and constructing/spending PSBTs.
    • Integration with Blindbit tweak oracles and Kyoto filter subscribers.
    • Improved error handling and JSON output for easier scripting.
  • Dependency upgrades:

    • Updated bdk_chain, bdk_file_store, bdk_bitcoind_rpc, and bitcoin crate versions across crates (indexer, silentpayments, cli/v1).
    • Introduced optional serde feature flags to certain crates for lightweight builds.
    • Added support for new Bitcoin PSBT silent payment signing (psbt_sp_spend feature in silentpayments).
  • New workspace members:

    • wallet: Implements SpWallet, handling indexing, chain state, balance tracking, labelled addresses, and PSBT candidate selection.
    • oracles: Provides Kyoto-based block filter and Blindbit-based tweak oracle integration.
  • SilentPayments library improvements:

    • Refactored hash utilities into dedicated helper functions (get_label_tweak, get_input_hash, get_shared_secret).
    • Refined SpOut to store full script_pubkey instead of just x-only keys.
    • Cleaner scanning algorithm (scan_txouts) with separation of finding spouts from tweaks.
    • Added PSBT signing helpers (add_sp_data_to_input, sign_sp).
  • CI / Justfile updates:

    • Excluded new CLI crates (bdk_sp_cli_v1, bdk_sp_cli_v2) from default cargo check and cargo test runs.
    • Simplified Docker justfile to use bdk-cli instead of legacy BDK example crates.

Example usage (CLI v2)

Here are example snippets using the new v2 CLI (sp-cli2):

# 1. Create a new silent payment wallet
sp-cli2 create --network signet --birthday 500000
# outputs a tr(...) xprv string and stores local wallet DB

# 2. Get your silent payment code (default)
sp-cli2 code
# { "silent_payment_code": "tsp1q..." }

# 3. Generate a labelled address (recipient-specific label)
sp-cli2 code --label 42
# { "silent_payment_code": "tsp1q...label..." }

# 4. Check balance
sp-cli2 balance
# JSON object with confirmed / unconfirmed / spendable balances

# 5. Construct a transaction to a normal Bitcoin address
sp-cli2 new-tx --to tb1qaddress:10000 "tr([fingerprint]xprv...)" --fee-rate 5

# 6. Construct a transaction to a silent payment address
sp-cli2 new-tx --to-sp tsp1q...:25000 "tr([fingerprint]xprv...)" --fee-rate 5

# 7. Scan blockchain using Kyoto+Blindbit
sp-cli2 scan-cbf https://tweak.server/

Notes to the reviewers

  • The migration to cli/v1 and cli/v2 was done to separate stable, legacy CLI features from new experimental functionality (wallet, oracles, tweak scanning).
  • The addition of oracles and Wallet integration introduces new abstractions; reviewing the module boundaries (wallet, oracles, cli/v2) will help check design consistency.
  • Some areas (especially PSBT signing with --feature psbt_sp_spend) are behind feature flags to avoid coupling core library users with experimental signing functionality.
  • Certain features (like Blindbit integration) are async-heavy and may require further testing in real network conditions.

Changelog notice

  • Added: PSBT signing support for Silent Payments (psbt_sp_spend feature).
  • Added: new bdk_sp_cli_v2 with wallet management, silent payment aware transaction construction, and multiple scanning backends (RPC and Kyoto+Blindbit).
  • Added: new bdk_sp_wallet crate for managing wallet state and persistence.
  • Added: new bdk_sp_oracles crate with filter/oracle subscription integrations.
  • Changed: migrate example_silentpayments into bdk_sp_cli_v1; update dependencies to latest bdk, bdk-chain, and bitcoin.
  • Changed: Refactor internal silent payment receive/send flows and add PSBT signing support via feature flag.
  • Changed: indexer upgraded to v2 model with label + shared secret indexing.
  • Removed: old BDK example crate binaries (example_electrum, example_esplora, etc.) from Docker builds.

Checklists

All Submissions:

New Features:

  • I've added tests for the new feature
  • I've added docs for the new feature

nymius added 12 commits August 22, 2025 13:08
…t_pubkey

Replaces the `xonly_pubkey` field in the `SpOut` struct with
`script_pubkey` to directly store the complete script rather than just
the public key.

This eliminates redundant script generation in multiple places, as the
script was being recalculated from the public key whenever needed.

The change simplifies the code flow and reduces unnecessary conversions
between public key formats and script generation.
…d_spout_for_tweak

Extract the logic for finding silent payment outputs with a given tweak
into a separate function `find_spout_for_tweak`.

This improves code organization by separating the loop iterating through
tweaks from the logic that processes each tweak.

The new function takes the necessary context and returns a single
matched output if found, allowing the main function to focus on
collecting results.
Adds two functions for silent payment PSBT handling:

1. `add_sp_data_to_input` - Adds silent payment data (spend public key
   and tweak) to a PSBT input as proprietary fields
2. `sign_sp` - Signs silent payment inputs in a PSBT by finding inputs
   with silent payment data, deriving the appropriate tweaked keys, and
   adding taproot key signatures

These functions enable proper signing of PSBTs spending silent payment
outputs.
…eys for PSBT outputs

Adds functionality to derive silent payment outputs in PSBTs using
silent payment private keys.

Introduces a new feature flag `psbt_sp_spend` that enables retrieval of
silent payment secrets from PSBT inputs.

The implementation checks for proprietary BIP352 fields in PSBT inputs
before falling back to existing key derivation methods.
…om TxOut

Adds a new SpMeta struct to store just the tweak and label information
from Silent Payments outputs, with a conversion implementation from
SpOut to SpMeta.

This allows separating the transaction output data from its metadata,
improving code organization and making it easier to handle Silent
Payment metadata independently.
Reorders enumeration and filtering operations when collecting outputs to
check in silent payments scanning.

The previous code filtered before enumerating, causing incorrect
outpoint indices.

Now it enumerates first to preserve the original transaction output
indices, then filters for P2TR outputs, ensuring correct outpoint
construction.
…label_tweak}

Add three helper functions to encapsulate hash computation logic used
throughout the codebase:

- `get_input_hash`: Computes a scalar from smallest outpoint and public
  key sum

- `get_shared_secret`: Derives a secret key from a shared secret and
  derivation index

- `get_label_tweak`: Generates a deterministic scalar from a scan key
  and numeric label

This change removes duplicated hash computation code and centralizes
these operations in the hashes module for better code organization and
reuse.
Remove outdated comment about OutPoint redundancy in SpIndexer struct
that explained implementation details no longer relevant to the current
codebase.
…outs

Pass a reference to the BTreeMap instead of cloning it in scan_txouts
function to avoid unnecessary memory allocation.

This improves efficiency by preventing duplication of the label_lookup
table during transaction scanning.
Updates `cargo run` commands in the justfile to explicitly specify the
example_silentpayments package with the -p flag when running the
example_silentpayments binary, ensuring the correct package is targeted
during execution.
@nymius nymius self-assigned this Aug 25, 2025
@nymius nymius added the enhancement New feature or request label Aug 25, 2025
@nymius nymius added this to the bdk-sp 0.1.0 milestone Aug 25, 2025
@nymius nymius force-pushed the refactor/indexer branch 3 times, most recently from 62c4d88 to dbf9584 Compare August 25, 2025 16:00
nymius added 12 commits August 25, 2025 20:58
… struct

Create a Label struct to encapsulate the data previously stored in
BTreeMap<PublicKey, (Scalar, u32)>.

This implementation includes serialization/deserialization support and
conversion methods.

Additionally, add helper serialization functions for Scalar types and
label maps to support persistent storage.
Implements a new `SpIndex` struct that provides functionalities for
indexing and accessing silent payment related data.

The struct includes methods for indexing labels, partial secrets, and
outputs, along with querying capabilities by script, label, transaction,
and other parameters.

This implementation will serve as a replacement for the existing
SpIndexes functionality.
Move the SpIndex struct and related data structures to a new
`indexes.rs` module.

This reorganization improves code structure by separating index-related
functionality from the main library file.

No functional changes were made.
Introduce SpPub struct to encapsulate the minimal data needed to scan
for silent payments onchain.

The struct stores the spend public key and scan secret key, and
provides a method to create labels using these keys.

This refactoring centralizes the silent payment scanning capabilities
by adding a create_label method that generates the necessary
cryptographic components for scanning.
Make serde serialization optional via a new "serde" feature flag.

This allow smaller builds for code that doesn't use
serialization/deserialization.
Introduces a new implementation of the Silent Payments indexer
(SpIndexerV2) that replaces the existing SpIndexer.

The new implementation refactors and increases the functionality for
scanning, indexing, and tracking silent payment transactions, including
methods for block processing, transaction relevance determination, and
label management.

Updates bdk_chain dependency to version 0.23.0 to support the new
implementation.
Adds a new wallet crate for managing silent payments with these capabilities:

- Wallet creation from descriptor keys
- Balance calculation
- Transaction management
- Address derivation for spending and change
- Chain state tracking
- Block processing for relevant transactions
- Integration with bdk_tx for transaction handling

The wallet implementation provides a core structure for handling silent
payment transactions with appropriate security measures and Bitcoin
protocol compatibility.
Add a new example crate `example_silentpayments_v2` that implements a
command-line interface for Silent Payments wallet functionality. This
example demonstrates:

- Creating and managing Silent Payment wallets
- Deriving Silent Payment scripts for transactions
- Displaying Silent Payment codes
- Scanning the blockchain for Silent Payment outputs via RPC
- Creating transactions with both regular and Silent Payment outputs
- Checking wallet balances

The example serves as a practical reference implementation for
integrating the SpWallet library into applications.
Update example_silentpayments dependencies to their latest versions and
adjust code to accommodate API changes. This includes:

- Upgrading bdk_file_store from 0.19.0 to 0.21.0
- Upgrading bdk_chain from 0.21.1 to 0.23.0
- Upgrading bdk_bitcoind_rpc from 0.18.0 to 0.20.0
- Adding required CanonicalizationParams parameter to balance and filter methods
- Updating Emitter constructor with NO_EXPECTED_MEMPOOL_TXIDS parameter
- Moving bdk_bitcoind_rpc imports outside the indexer module
Replace custom BDK example binaries with bdk-cli in the justfile
scripts. This change:

- Switches from the forked BDK repo to official bdk-cli repository
- Uses bdk-cli's standardized wallet commands instead of custom example
  binaries
- Simplifies the silent payment flow implementation to use standard tools
- Updates the Docker build to include only the bdk-cli binary instead of
  multiple example binaries
- Adds libssl3 dependency required by bdk-cli

This change improves maintainability by using official tooling rather
than custom examples.
Add a new `oracles` crate that provides:

1. Kyoto-based filter infrastructure for storing, managing, and
   subscribing to compact block filters
2. BlindBit client implementation that connects to tweak server
   endpoints
3. Mechanisms to match tweaks against filters to identify transactions
   of interest

This enables wallet implementations to efficiently retrieve and process
filter/tweak data from external sources instead of computing them
locally, improving performance for silent payment scanning.
nymius added 4 commits August 25, 2025 21:01
This commit adds a new command `ScanCbf` to the example Silent Payments
application that allows users to scan for payments using kyoto-cbf and
blindbit. The feature:

1. Integrates the `bdk_sp_oracles` dependency to enable communication
   with kyoto compact block filter nodes
2. Implements a tokio-based asynchronous scanning mechanism to detect
   Silent Payments via compact block filters
3. Sets up connections to trusted peers and subscribes to filter events
4. Processes matched transactions by verifying them against blindbit
   tweak server
5. Updates the wallet when relevant payments are found

This enhances the example by demonstrating a more efficient way to scan
for Silent Payments without requiring a full node RPC connection.
Restructured the example code into a proper CLI component by:
- Renaming directory from `example-crates` to `cli`
- Reorganizing examples into `cli/v1` and `cli/v2` subdirectories
- Renaming packages from `example_silentpayments*` to `bdk_sp_cli_v*`
- Adding binary definitions with proper executable names
- Updating workspace members in Cargo.toml
- Adjusting exclude patterns in justfile

This change improves project organization by treating CLI tools as
first-class components rather than examples, making the project
structure more intuitive and providing clearer naming conventions for
both directory structure and package names.
Move the SpIndexerV2 implementation from lib.rs into a dedicated v2
module to improve code organization and maintainability. All existing
functionality is preserved while reducing the size of lib.rs.

This commit restructures the codebase by moving the SpIndexerV2
implementation and its related code (including indexes.rs) into a
dedicated v2 module. The code remains functionally identical, but is now
better organized with clearer module boundaries. All import paths in
dependent files (oracles/tweaks/blindbit.rs, wallet/lib.rs,
wallet/signers.rs) have been updated to reference the new module
location.
@nymius nymius merged commit 96d4f3d into bitcoindevkit:master Aug 26, 2025
3 of 5 checks passed
@nymius nymius deleted the refactor/indexer branch August 26, 2025 00:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

1 participant