bdk icon indicating copy to clipboard operation
bdk copied to clipboard

Feature Request: BIP47 payment codes for private donations (PayNym)

Open satrinity402 opened this issue 3 years ago • 33 comments

In the current environment, it would be extremely beneficial if bitcoin wallet developers using BDK could have an easy way to integrate BIP47 payment codes into their wallets for receiving payments privately (especially donations) without needing to setup a server to generate fresh addresses for each payment. Would need functionality for sending to other BIP47 payment codes as well.

Both Samourai Wallet and Sparrow Wallet are FOSS, and have integrated this functionality into their wallets.

satrinity402 avatar Feb 17 '22 18:02 satrinity402

I am for this enhancement and would love to see it adopted by all major wallets.

artdesignbySF avatar Feb 18 '22 08:02 artdesignbySF

Another +1 here

BitcoinQnA avatar Feb 18 '22 15:02 BitcoinQnA

Looks like there is already a BIP47 implementation for Rust: https://github.com/rust-bitcoin/rust-bip47

satrinity402 avatar Feb 18 '22 18:02 satrinity402

I am for this enhancement and would love to see it adopted by all major wallets.

I echo this sentiment.

modl21 avatar Feb 18 '22 19:02 modl21

The goal of a reusable donation address is great, but BIP47 is a bad way to do it. Recommend against implementing.

luke-jr avatar Feb 19 '22 01:02 luke-jr

@luke-jr Yeah, that's why we should always post our legacy BTC addresses to receive donations; everyone can snoop in for eternity, right? No SegWit, that must be a bad way to do it too. We need to advise against BIP47 and SegWit, all the way.

  • https://oxt.me/address/1A6eLsi6cmm2xKDSGThd8C2kfzDBXD8YTw
  • https://twitter.com/LukeDashjr/status/1468009813913309193

A toast for Bitcoin's efficiency and privacy!

rottenwheel avatar Feb 19 '22 02:02 rottenwheel

Let's not get ahead of ourselves here! We have spent years trying to ignore BIP47 and have spent a huge deal of energy and time trying to push the narrative against the Red Wall that we just can't possibly start to implement it into our wallets. Don't get me wrong it's nothing to do with privacy, it's more of a save face kinda thang.

Just HODL thru it y'all.

ElmoOutlaw avatar Feb 19 '22 08:02 ElmoOutlaw

The goal of a reusable donation address is great, but BIP47 is a bad way to do it. Recommend against implementing.

@luke-jr It would be useful if you could explain the technicals behind why you think this. Saying 'it's bad' doesn't help.

BitcoinQnA avatar Feb 19 '22 11:02 BitcoinQnA

Are we doing a bounty for this one? Some of the peeps were sceptical of a pr merge into Bluewallet (https://github.com/BlueWallet/BlueWallet/issues/2883). I could offer a first to implement bounty on my 500k sats from Bluewallet. Not sure if that is acceptable within the gentleman's agreements.

apemithrandir avatar Feb 19 '22 12:02 apemithrandir

I'm gonna try to work on this myself since there's so much demand for it, I might have to fix a few things along the way but it shouldn't take too long

The goal of a reusable donation address is great, but BIP47 is a bad way to do it. Recommend against implementing.

@luke-jr with BDK we are trying to support as much as we can in terms of existing standards, so I think it makes sense to implement it even if it might not be the best option for everyone. We had a similar discussion in #534 about BIP69, and in the end we decided to just add a warning and avoid removing the implementation entirely, in case somebody needs it for compatibility with older protocols.

If you can provide a technical explanation we could consider doing the same for BIP47 and provide a link to this discussion in the warning message.

afilini avatar Feb 21 '22 14:02 afilini

The goal of a reusable donation address is great, but BIP47 is a bad way to do it. Recommend against implementing.

@luke-jr It would be useful if you could explain the technicals behind why you think this. Saying 'it's bad' doesn't help.

I am always interested to learn why things are bad for bitcoin. Please explain.

artdesignbySF avatar Feb 22 '22 11:02 artdesignbySF

@luke-jr Yeah, that's why we should always post our legacy BTC addresses to receive donations; everyone can snoop in for eternity, right? No SegWit, that must be a bad way to do it too. We need to advise against BIP47 and SegWit, all the way.

@rottenstonks there is no need to get snarky or ad hominem in this discussion.

notmandatory avatar Mar 02 '22 18:03 notmandatory

I've done a little googling and not found any good analysis about BIP47. There may be other issues but I suspect one of the concerns is with the on-chain "Notification Transactions", in particular:

  1. on-chain transactions are used for messaging (to communicate payment codes) and data storage (to recover payment codes from an HD seed);
  2. they must be created for every pair of senders/receivers so N^2 transactions for N users, which isn't great scaling.

An interesting, related proposal for "Reusable Taproot Addresses" looks to reduce the "Notification Transaction" overhead of BIP47.

EDIT: BIP47v3 appears to use a similar approach as "Reusable Taproot Addresses" of using TX outputs to reduce on-chain footprint of transmitting payment codes.

notmandatory avatar Mar 03 '22 01:03 notmandatory

While BIP47 isn’t perfect, it’s currently the only way to receive bitcoin funds privately on chain from a static text string/QR code. Adding it to BDK will at least give wallet devs the option of integrating it into their wallets.

Sparrow Wallet just implemented BIP47 today: https://github.com/sparrowwallet/sparrow/releases/tag/1.6.0

satrinity402 avatar Mar 03 '22 14:03 satrinity402

I'm having some issues with BIP47, it doesn't really integrate well with our descriptors-everywhere model.

Since I see a few Sparrow/Samourai people in here, do you think there's any room for changes to the BIP, since it's still in draft? I would still implement the current thing, but I'd like to see it disappear going forward...

Mainly I would change the way the shared secret is applied to a payment code: rather than deriving the nth key first and then applying some tweaking, I would tweak the xpub directly and then derive children on that, which would make it possible to express the entire alice-bob wallet in a single descriptor as pkh(<tweaked_xpub>/*)

afilini avatar Mar 04 '22 15:03 afilini

I'm having some issues with BIP47, it doesn't really integrate well with our descriptors-everywhere model.

Since I see a few Sparrow/Samourai people in here, do you think there's any room for changes to the BIP, since it's still in draft? I would still implement the current thing, but I'd like to see it disappear going forward...

Mainly I would change the way the shared secret is applied to a payment code: rather than deriving the nth key first and then applying some tweaking, I would tweak the xpub directly and then derive children on that, which would make it possible to express the entire alice-bob wallet in a single descriptor as pkh(<tweaked_xpub>/*)

I posed the question to a few guys on twitter that have implemented v1 BIP47. TDev responded with a tweet thread that may provide some useful info:

https://twitter.com/samouraidev/status/1499796801733419009?s=21

satrinity402 avatar Mar 04 '22 17:03 satrinity402

I am for this enhancement and would love to see it adopted by all major wallets.

+1 I would love to see this implementation adopted by more wallets.

decentralizedb avatar Mar 04 '22 18:03 decentralizedb

Just want to post a clarification because "PayNym" is mentioned in the title, and I think some people think it's the same as BIP 47. "PayNym" is a custom implementation by Samourai which adds user-friendly handles ("+christoph") via a centralized directory. BIP 47 by itself does not give you nice handles, if that's what anyone is expecting.

GBKS avatar Mar 16 '22 07:03 GBKS

I'm having some issues with BIP47, it doesn't really integrate well with our descriptors-everywhere model.

Since I see a few Sparrow/Samourai people in here, do you think there's any room for changes to the BIP, since it's still in draft? I would still implement the current thing, but I'd like to see it disappear going forward...

Mainly I would change the way the shared secret is applied to a payment code: rather than deriving the nth key first and then applying some tweaking, I would tweak the xpub directly and then derive children on that, which would make it possible to express the entire alice-bob wallet in a single descriptor as pkh(<tweaked_xpub>/*)

I don't understand much of this.. but I am interested to lean if descriptors and bip47 can work without hitch together.

artdesignbySF avatar Mar 16 '22 08:03 artdesignbySF

Yeah I guess I should clarify this: I'm not working on an integration with "paynyms", because that's essentially a centralized directory maintained by Samourai (and I assume it's fairly trivial to connect and upload/download payment codes anyway if you anybody wants that).

What I'm working on is a way to send a payment from a BDK wallet to a BIP47 payment code.

but I am interested to lean if descriptors and bip47 can work without hitch together.

The answer is: kinda. There are a few things that are not very descriptor-friendly, or "light-wallet" friendly in general. But it can work, I'm almost done with the implementation and I'm working on upstreaming patches progressively.

afilini avatar Mar 16 '22 14:03 afilini

Yeah I guess I should clarify this: I'm not working on an integration with "paynyms", because that's essentially a centralized directory maintained by Samourai (and I assume it's fairly trivial to connect and upload/download payment codes anyway if you anybody wants that).

What I'm working on is a way to send a payment from a BDK wallet to a BIP47 payment code.

but I am interested to lean if descriptors and bip47 can work without hitch together.

The answer is: kinda. There are a few things that are not very descriptor-friendly, or "light-wallet" friendly in general. But it can work, I'm almost done with the implementation and I'm working on upstreaming patches progressively.

Will people also be able to receive bitcoin via their own generated BIP47 payment code? Or will only sends work in this first iteration?

satrinity402 avatar Mar 16 '22 16:03 satrinity402

Yes sorry, I meant that I'm not working on sending to paynym but only sending to payment code.

But receiving also works, and if you want to be integrated with the directory you could generate your own payment code (which would be handled by BDK) and upload it to the paynym directory (which would have to be implemented externally)

afilini avatar Mar 17 '22 08:03 afilini

Ok, interesting stuff! Thank you for explaining a bit more :)

artdesignbySF avatar Mar 18 '22 17:03 artdesignbySF

I'm reluctantly giving a soft (and probably too late to be useful) NACK on this. The main reason is that a much better scheme is possible with schnorr/taproot which requires no interaction and whose payments are indistinguishable from other payments. See @RubenSomsen 's posts in https://gist.github.com/Kixunil/0ddb3a9cdec33342b97431e438252c0a?permalink_comment_id=4013189#gistcomment-4013189

BIP47 is outdated tech and it is rightly marked as discouraged. I think @afilini's time is worth more than a BIP47 implementation and a experimental Schnorr/TR version that could be turned into a BIP would be far more valuable IMO.

LLFourn avatar Mar 20 '22 23:03 LLFourn

Seems reasonable if indeed the Reusable taproot addresses are picked up broadly.

artdesignbySF avatar Mar 21 '22 14:03 artdesignbySF

I think it still makes sense to have this, just because it's relatively widely used, I agree that maybe I shouldn't spend too much time on it and focus and better and newer things.

I wanted to try implementing @Kixunil's proposal but I think I'm gonna wait for taproot support first because I don't want to grow that branch too much.

afilini avatar Mar 21 '22 15:03 afilini

Is there any reason to implement this in-house as opposed to using https://github.com/rust-bitcoin/rust-bip47?

ghost avatar Mar 23 '22 23:03 ghost

See my answer here.

In short, this does a lot more compared to rust-bip47, which can mainly be used to generate addresses. Addresses are not useful to us, we need descriptors, so it seemed wasteful to add that extra dependency just to use a couple of structs.

afilini avatar Mar 24 '22 10:03 afilini

Attempting to keep discussion of merits of BIP47 away from the PR #574. In there @afilini mentioned:

Also, my personal opinion is that BIP47 is pretty cool: it works with zero interaction between sender and receiver, it's relatively easy to get it working on light clients, while some of the other protocols that try to achieve the same goal are totally impossible to implement.

Why is this impossible to implement? There are several reasons I can see why it might be tricky atm like it's a WIP and needs TR support in BDK but is there something else?

LLFourn avatar Mar 30 '22 23:03 LLFourn

I think I meant to say that it's impossible to implement on light-clients, but since BDK is mainly designed for clients that are not constantly online it also applies here: basically you need to scan every tx, from every block (plus mempool if you wanna see unconfirmed txs) to look for transactions paying to you.

It's heavy in terms of bandwidth and computation, which are both very scarce resources in light clients.

afilini avatar Apr 02 '22 22:04 afilini