Skip to content

Add optional esplora wallet setup for payjoin-cli backend#1469

Closed
benalleng wants to merge 3 commits intopayjoin:masterfrom
benalleng:payjoin-cli-bdk
Closed

Add optional esplora wallet setup for payjoin-cli backend#1469
benalleng wants to merge 3 commits intopayjoin:masterfrom
benalleng:payjoin-cli-bdk

Conversation

@benalleng
Copy link
Copy Markdown
Collaborator

This adds a new esplora feature to use a bdk wallet as the supporting backend for payjoin-cli to reduce the need for a bitcoind rpc connection when testing against integrations. This does retain the bitcoind functionality so we can continue to run local e2e tests during the payjoin-cli CI tests.

proof that it works https://mempool.space/testnet4/tx/a964e01d71d9dd6349a5e3ec4411e3d45f2769197f507100c692ea0f96dd4292

Claude wrote most of this code.

For review the greatest change is in wallet.rs as much of the other changes are feature gates and naming imports differrently

Pull Request Checklist

Please confirm the following before requesting review:

@benalleng benalleng force-pushed the payjoin-cli-bdk branch 3 times, most recently from eaadeb3 to ad2171a Compare April 7, 2026 20:33
@benalleng
Copy link
Copy Markdown
Collaborator Author

benalleng commented Apr 7, 2026

The payjoin-cli help with esplora

Payjoin - bitcoin scaling, savings, and privacy by default

Usage: payjoin-cli [OPTIONS] <COMMAND>

Commands:
  send     Send a payjoin payment
  receive  Receive a payjoin payment
  resume   Resume pending payjoins (BIP77/v2 only)
  history  Show payjoin session history
  help     Print this message or the help of the given subcommand(s)

Options:
      --bip77                                  Use BIP77 (v2) protocol (default)
      --bip78                                  Use BIP78 (v1) protocol
  -d, --db-path <DB_PATH>                      Sets a custom database path
  -f, --max-fee-rate <MAX_FEE_RATE>            The maximum fee rate to accept in sat/vB
      --descriptor <DESCRIPTOR>                The wallet descriptor
      --change-descriptor <CHANGE_DESCRIPTOR>  The change descriptor
      --esplora-url <ESPLORA_URL>              The esplora API URL
      --network <NETWORK>                      The Bitcoin network to connect to
      --ohttp-relays <OHTTP_RELAYS>            One or more ohttp relay URLs, comma-separated
      --ohttp-keys <OHTTP_KEYS>                The ohttp key config file path
      --pj-directory <PJ_DIRECTORY>            The directory to store payjoin requests
  -h, --help                                   Print help
  -V, --version                                Print version

and bitcoind

Payjoin - bitcoin scaling, savings, and privacy by default

Usage: payjoin-cli [OPTIONS] <COMMAND>

Commands:
  send     Send a payjoin payment
  receive  Receive a payjoin payment
  resume   Resume pending payjoins (BIP77/v2 only)
  history  Show payjoin session history
  help     Print this message or the help of the given subcommand(s)

Options:
      --bip77                        Use BIP77 (v2) protocol (default)
      --bip78                        Use BIP78 (v1) protocol
  -d, --db-path <DB_PATH>            Sets a custom database path
  -f, --max-fee-rate <MAX_FEE_RATE>  The maximum fee rate to accept in sat/vB
  -r, --rpchost <RPCHOST>            The URL of the Bitcoin RPC host, e.g. regtest default is http:/
/localhost:18443
  -c, --cookie-file <COOKIE_FILE>    Path to the cookie file of the bitcoin node
      --rpcuser <RPCUSER>            The username for the bitcoin node
      --rpcpassword <RPCPASSWORD>    The password for the bitcoin node
      --ohttp-relays <OHTTP_RELAYS>  One or more ohttp relay URLs, comma-separated
      --ohttp-keys <OHTTP_KEYS>      The ohttp key config file path
      --pj-directory <PJ_DIRECTORY>  The directory to store payjoin requests
  -h, --help                         Print help
  -V, --version                      Print version

@coveralls
Copy link
Copy Markdown
Collaborator

coveralls commented Apr 7, 2026

Coverage Report for CI Build 24149462551

Coverage increased (+0.2%) to 84.533%

Details

  • Coverage increased (+0.2%) from the base build.
  • Patch coverage: 17 uncovered changes across 1 file (361 of 378 lines covered, 95.5%).
  • 4 coverage regressions across 1 file.

Uncovered Changes

File Changed Covered %
payjoin-cli/src/app/wallet.rs 355 338 95.21%

Coverage Regressions

4 previously-covered lines in 1 file lost coverage.

File Lines Losing Coverage Coverage
payjoin-cli/src/app/v2/mod.rs 4 53.14%

Coverage Stats

Coverage Status
Relevant Lines: 13034
Covered Lines: 11018
Line Coverage: 84.53%
Coverage Strength: 414.32 hits per line

💛 - Coveralls

@benalleng benalleng force-pushed the payjoin-cli-bdk branch 2 times, most recently from ca9bb4b to 50b8c94 Compare April 8, 2026 12:05
@arminsabouri
Copy link
Copy Markdown
Collaborator

@benalleng should we only use the public esplora backend during testing? i.e error out of network == mainnet? Until ohttp wrapper is available bitcoindevkit/rust-esplora-client#145 .

@benalleng benalleng force-pushed the payjoin-cli-bdk branch 4 times, most recently from a3a1c2d to 11f18d8 Compare April 8, 2026 15:03
This adds a new esplora feature to use a bdk wallet as the supporting
backend for payjoin-cli to reduce the need for a bitcoind rpc
connection when testing against integrations.  This does retain the
bitcoind functionality so we can continue to run local e2e tests during
the payjoin-cli CI tests.
@nothingmuch
Copy link
Copy Markdown
Contributor

what is the motivation for this?

this is a bit of a privacy footgun, such servers learn a lot of clustering related information (esplora esp. over http2 or with http1.1 pipelining is equivalent to electrum's leaks in this regard, but even with separate connections per request due to transport layer metadata) that would make breaking payjoin privacy basically trivial by an adversarial server if one of the parties to the payjoin transaction queries their addresses with that server

esplora over ohttp would improve matters but the temporal leak is still enough to be a concern allowing queries for different addresses over different OHTTP requests to still be linked temporally and used as the basis for clustering

this seems like more code that then needs caveats and qualifications to be understood in a constructive way, and because the main purpose of a reference client is to demonstrate that seems counterproductive (especially since bdk-cli integration would kinda make this obsolete?)

@benalleng
Copy link
Copy Markdown
Collaborator Author

benalleng commented Apr 8, 2026

what is the motivation for this?

The motivation is mostly testing infrastructure. This is not intended to be anymore than a dev feature for internal use really. Bull bitcoin only has a way to use testnet3 and to then create a regular way to test against it and payjoin-cli as in SatoshiPortal/bullbitcoin-mobile#1978 we would need to spin up at least a pruned tesnet3 node which is not insignificant given its age.

In yesterday's call we discussed looking into ways to find faster ways to spin up this node setup as there are plenty of wallets that do not support regtest so we don't always have an easy way to quickly do regression tests on them. One of the ways brought up was by simply removing the need for a node altogether.

An alternative approach to solving this was finding or hosting ourselves a mirror of the chainstate for testnet3 and 4 so that we can quickly download and start a rpc node without having to do validation

(especially since bdk-cli integration would kinda make this obsolete?)

While true I think if we want to have bdk-cli be a reliable benchmark to test against for other upstream wallets we need to really take ownership of the payjoin integration there long term if we want to trust bdk-cli <> upstream wallet as a valid test. (Not a totally unreasonable thing to do as we stabilize around 1.0 but we would need to keep a close eye on it)

Copy link
Copy Markdown
Collaborator

@arminsabouri arminsabouri left a comment

Choose a reason for hiding this comment

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

This seems like potential techdebt. From what I understand the problem is BB mobile doesnt support regtest (only testnet3). How much harder is to setup a testnet3 node and run integration tests on that box? Perhaps this can be part of CI somehow

Ok(signed_psbt)
}

fn can_broadcast(&self, _tx: &Transaction) -> Result<bool> { Ok(true) }
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Does esplora support mempoolaccept ? I know blockstream versions does.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

no the bdk esplora doesn't, or at least not that I could find

@benalleng
Copy link
Copy Markdown
Collaborator Author

How much harder is to setup a testnet3 node and run integration tests on that box? Perhaps this can be part of CI somehow

spinning up an rpc node with testnet3 took me about 8 hours on my local machine

@DanGould
Copy link
Copy Markdown
Contributor

DanGould commented Apr 8, 2026

i'm glad we did this experiment to see how much effort it is but it's definitely simpler to just run RPC and a pruned snapshot should do the job. the config ergonomics just add a ton we would need to maintain.

https://bitcoin-snapshots.jaonoctus.dev/ ?

@benalleng benalleng closed this Apr 8, 2026
@nothingmuch
Copy link
Copy Markdown
Contributor

why doesn't bb mobile support regtest? if it already supports testnet3 that implies it's not mainnet only so probably not a major change to add regtest and/or signet support?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants