Skip to content

docs: fix the stale silent payment example in the README - #76

Merged
nymius merged 2 commits into
bitcoindevkit:masterfrom
kkdao:docs/readme-stale-api
Sep 4, 2026
Merged

docs: fix the stale silent payment example in the README#76
nymius merged 2 commits into
bitcoindevkit:masterfrom
kkdao:docs/readme-stale-api

Conversation

@kkdao

@kkdao kkdao commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Description

Every API reference in the README example is out of date, and nothing compiles it, so nothing caught the drift:

  • receive::Scanner and send::XprivSilentPaymentSender are not re-exported. They live at receive::scan::Scanner and send::bip32::XprivSilentPaymentSender.
  • The SilentPaymentCode struct literal cannot be written outside the crate because version is private, so it needs new_v0.
  • label_to_tweak was never declared mutable, and was a HashMap where Scanner::new takes a BTreeMap.
  • SilentPaymentCode has no as_str.
  • send_to takes inputs carrying a script pubkey alongside the derivation path, and returns the derived x-only keys grouped by recipient, not a flat list of script pubkeys.
  • TxOut::value is an Amount.

The second commit adds silentpayments/tests/integration_tests/readme.rs, which runs the same flow end to end: derive a labelled code, hand it to the sender, derive the output, scan the resulting transaction, and confirm the payment is found, attributed to the label, and spendable.

Notes to the reviewers

The example stays an outline rather than becoming a compiling program. Spelling out the wallet's keys, transaction and inputs would bury the part worth reading, so it says so and links the test that does compile and run the same flow.

Fixed by using the existing nested paths rather than adding re-exports, so the shorter paths do not become public API by accident.

The new test is deterministic and needs no node. The scanner reads an input's public key from the prevout script pubkey rather than the witness, so a placeholder witness is enough for the input to be recognised as taproot.

Changelog notice

Nothing user facing. Documentation and tests only.

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the conventional commit guidelines
  • I ran just p (fmt, clippy and test) before committing

@nymius nymius left a comment

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.

The commit messages have all the info but is enumerating many things that are hard to read, use bullet points please.

Comment thread README.md Outdated
Comment thread README.md Outdated
use std::collections::BTreeMap;

mod psbt;
mod readme;

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.

This is not attached to the readme anymore, I would create an example rather than a test for the complete flow. Also, I like the Entity based test from rust-psbt. If you want to do this, I would replicate it by creating Sender and Receiver types (not necessarily repeating rust-psbt structs).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done - silentpayments/examples/send_and_scan.rs, with Sender and Receiver types, and the test is gone. One note: CI compiles examples but never runs them, so those assertions no longer execute. Happy to add a step that runs it.

Add `send_and_scan`, a runnable program covering both sides of a silent
payment:

- a `Receiver` publishes a labelled code, scans a transaction, finds the
  payment, and reproduces the key that spends it
- a `Sender` derives the output from the private keys of the inputs it is
  spending, then builds the paying transaction

Each step is a method on the party that performs it, following the party
structs in the rust-psbt examples, so the flow reads as the protocol rather
than as a sequence of calls.

The example is deterministic and needs no node. The scanner reads an input's
public key from the prevout script pubkey rather than from the witness, so a
placeholder witness is enough for the input to be recognised as taproot.

Printing is denied workspace wide, which is right for the library and wrong
for a program whose purpose is to be run and watched, so the example allows
it on itself.
Every API reference in the snippet was out of date:

- `receive::Scanner` and `send::XprivSilentPaymentSender` are not
  re-exported, and live at `receive::scan::Scanner` and
  `send::bip32::XprivSilentPaymentSender`
- `SilentPaymentCode` cannot be built from a struct literal outside the
  crate, because `version` is private, so it needs `new_v0`
- `label_to_tweak` was never declared mutable, and was a `HashMap` where
  `Scanner::new` takes a `BTreeMap`
- `SilentPaymentCode` has no `as_str`
- `send_to` takes inputs carrying a script pubkey alongside the derivation
  path, and returns the derived x-only keys grouped by recipient rather than
  a flat list of script pubkeys
- `TxOut::value` is an `Amount`

None of it compiled, because nothing compiled it. Point at the example
instead of repeating it here, so the documented flow is built by CI and
cannot drift from the crate again.
@kkdao
kkdao force-pushed the docs/readme-stale-api branch from 88ae808 to 5554f42 Compare September 3, 2026 10:34
@kkdao

kkdao commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

Commit messages rebuilt with bullets. The branch is two commits now: one adds the example, one replaces the README snippet with a link to it.

@nymius nymius left a comment

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.

ACK 5554f42

@nymius
nymius merged commit 8f88bd8 into bitcoindevkit:master Sep 4, 2026
5 checks passed
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.

2 participants