Skip to content

Conversation

@benalleng
Copy link

This adds the scaffolding for the receiver to display bip21 QR codes when a payjoin or other bip21 receive format is required.

This is the first commit to begin support for #1806 by splitting it up into many smaller commits. This particular commit does not require any payjoin support.

@benalleng benalleng force-pushed the bip21-support branch 2 times, most recently from a062d7b to 1e90273 Compare November 7, 2025 22:02
#[derive(Debug, Default)]
pub struct Addresses {
list: Vec<Address>,
bip21s: HashMap<Address, String>,
Copy link
Collaborator

Choose a reason for hiding this comment

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

I dont think we should store uri strings, they can be generated in the view, it's not ressources intensive

Copy link
Author

@benalleng benalleng Nov 25, 2025

Choose a reason for hiding this comment

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

If we don't store the uri string how do you think we should flag that the address being displayed should have some extra bip21 information, just a simple bool flag to indicate some additional method should be called?

Copy link
Collaborator

Choose a reason for hiding this comment

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

If we don't store the uri string how do you think we should flag that the address being displayed should have some extra, just a simple bool flag to indicate some additional method should be called?

I think so, but I'm not sure to have the whole context in mind, what additional infos can the uri potentially contains in our usage? I imagine:

  • the amount user expect to receive (we do not yet support this feature, do we want it in the future @nondiremanuel?)
  • information for receive payjoin (Directory url + auth metadata?), iiuc this is per-session based, do we store it in the DB? can several addresses share sames set of metadata? Can we have to deal with different set of metadata while the receive screen is still open? can an address have to been appended with different set of metatdat in some edge cases?

Copy link
Author

Choose a reason for hiding this comment

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

You're right for all that. I was mostly asking in reference to just the physical display to keep the Qr code methods simple to just add some is_bip21 flag that just appends the relevant data on at the end since Message::ShowQrCode would need to either be passed or generate the bip21 data as it is built for a simple address index right now

Copy link
Collaborator

Choose a reason for hiding this comment

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

what about this:

do we store it in the DB? can several addresses share sames set of metadata? Can we have to deal with different set of metadata while the receive screen is still open? can an address have to been appended with different set of metatdat in some edge cases?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Bullbitcoin wallet allow user to add amount & note for a PJ (receive), but I mean it can be another feature (not related to PJ) also

Copy link
Author

@benalleng benalleng Dec 2, 2025

Choose a reason for hiding this comment

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

do we store it in the DB? can several addresses share sames set of metadata? Can we have to deal with different set of metadata while the receive screen is still open? can an address have to been appended with different set of metatdat in some edge cases?

So no, each address should have a new pj session, reused addresses will cause problems as far as I know. There aren't really any practical edge cases where I could think of wanting to do that practically

Can we have to deal with different set of metadata while the receive screen is still open?

As for this I think the only 3 things that are really notable to happen during this stage

  1. the directory rejects / never receives our payjoin initialization
  2. the sender responds before we even exit this screen so we jump to the second signing stage immediately
  3. All other states are simply waiting for the sender

Copy link
Author

@benalleng benalleng Dec 2, 2025

Choose a reason for hiding this comment

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

The amount is not explicitly required in a pj, so for now I don't think we need to add it unless we think that an amount would dramatically change or improve the UX, especially with looking at the receive screen as it stands now it would likely require some design work to think about how to add a fixed amount seamlessly when it is not necessary for payjoins

Copy link
Collaborator

Choose a reason for hiding this comment

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

each address should have a new pj session,

where we store metadata about the PJ session? in RAM? in DB?
just to get back to the topic of this thread, I dont think it makes sense to store it here, as ReceivePanel is reset on reload:

*self = Self::new(data_dir, wallet);

Copy link
Author

Choose a reason for hiding this comment

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

A payjoin session data would ideally be stored in the DB but the bip21 associated with it would ideally not be recalled as a user really shouldn't be reusing it outside of the initial receive screen as it would be essentially restarting a sessions and could encourage some bad user patterns like giving a bip21 to 2 separate senders.

I think it might be helpful to perhaps open a more complete receiver PR to give some more context on some design decisions.

.map(|qr_code| Self {
pub fn new(address: &str, index: ChildNumber) -> Option<Self> {
if Address::from_str(address).is_ok() {
qr_code::Data::new(format!("bitcoin:{}?index={}", address, index))
Copy link
Collaborator

Choose a reason for hiding this comment

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

when an address is displayed as QR, its expected to be passed to a peer for payment, I dont see a good reason to let him know our derivation index.

The index can be usefull only for a signing device to verify the address, like #1040 or with Coldcard-Q/Krux devices, but in this case we should also pass the descriptor name. (Not related to this PR, but maybe we should open an issue more generic tan #1040 since we support more QR devices @nondiremanuel)

@benalleng benalleng force-pushed the bip21-support branch 3 times, most recently from 68a1dc7 to c9e81ef Compare December 2, 2025 19:42
This adds the scaffolding for the receiver to display bip21 QR codes
when a payjoin or other bip21 receive format is required.
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.

3 participants