Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Payments to BIP47 payment codes go "missing" (to address not in recipient's wallet) #1642

Open
SpottyMatt opened this issue Feb 19, 2025 · 4 comments

Comments

@SpottyMatt
Copy link

SpottyMatt commented Feb 19, 2025

I have observed the following, and I am not sure if it is a bug or user error. I was directed to submit an issue from the Telegram channel.

When paying to a Payment Code (not a PayNym), Sparrow seems to send funds to an address that is NOT in the destination wallet.

Steps

Here are three different attempts to use Sparrow to pay to a Payment Code, with steps, pictures, and results.

✅ Sparrow ➡️ Sparrow by PayNym

1. Setup Recipient

  1. SparrowWallet 2.1.2 on Windows 11
  2. import a hot wallet into Sparrow via mnemonic seed, no passPHRASE
    • I used 12 words for this example
    • derivation: m/84'/0'/0' for this example
    • script: wpkh(BIP39)
    • I did set a passWORD on the wallet

2. Get Address(es)

  1. Menu tools -> show paynym
    • Payment Code: PM8TJRQaXFKLoqUV3JdYJvqMTDDP6r1h9UARPUFwBCVnvXbTvpo3uFNGeBnFLpN4b6TGTRQdP29aMrpXmYyeWuzACLqngMSppiNGPqewrgku1z3EArka
    • PayNym: +charmingstation96
    • Image
  2. Go to "Addresses" tab; note there are no PayNym addresses shown:
    Image
  3. Assumption: I can now close the hot wallet in Sparrow & the rest of the world can use the above Payment Code to send payments to unique addresses in the wallet.
  4. Close the wallet in Sparrow.

3. Pay

  1. Open a different wallet in Sparrow. In my case, this is another local hot wallet.
    • In this case it is a script: wpkh(BIP39), derivation: m/84'/0'/0', with passPHRASE, using Account 3 - m/84'/0'/3'
  2. "Send" tab, paste the recipient's Payment Code into the "Pay to" field
  3. Receive prompt to send notification txn
    Image
  4. "Yes" - Notification txn is created:
    Image
  5. The "Pay To" field is now pre-filled with the target wallet's PayNym:
    Image
  6. Pay 1000 sats to+charmingstation96
    Image
  7. Close the sending wallet in Sparrow.

4. Receive

  1. Re-open the original wallet in Sparrow
  2. ✅ See incoming txn to 1Q6vvnGguiTnrqmRFRHAUUuR2er7fCh7ev
  3. Close recipient wallet

5. Pay Again

  1. Open the sending wallet in Sparrow
  2. Wallet prompts for refresh, "history has changed":
    Image
  3. Refresh - nothing obvious changes; history is still there.
  4. "Send" tab, paste the recipient's payment code into the "pay to" field again
  5. ⚠ Prompted to send a notification txn again
    • I would not expect this to prompt again.
  6. Cancel; do not send a notification txn
  7. Select "PayNym or Payment code" from the "Pay to" dropdown
  8. +charmingstation96 is shown as a linked contact, select it
  9. Everything seems to work as before.
❌ Sparrow ➡️ Sparrow by Raw Payment Code

1. Setup Recipient

  1. SparrowWallet 2.1.2 on Windows 11
  2. import a hot wallet into Sparrow via mnemonic seed, no passPHRASE
    • I used 24 words for this example
    • derivation: m/84'/0'/0' for this example
    • script: wpkh(BIP39)
    • I did set a passWORD on the wallet

2. Get Address(es)

  1. Menu tools -> show paynym
    • Payment Code: PM8TJRHzcJ1xS76sK4pjT7jENsuiSa1HMBbBgn249dVd79NDkbWGTmG7ovtekeJK8hyoVDy1NhDWid9vrZroxivyaeJeYvBsukDZpomhrhjnspEBTG58
    • Did NOT retrieve PayNym
      • Assumption: It is not necessary to retrieve a PayNym to use BIP47 payment codes.
    • Image
  2. Go to "Addresses" tab; note there are no PayNym addresses shown:
    Image
  3. Assumption: I can now close the hot wallet in Sparrow & the rest of the world can use the above Payment Code to send payments to unique addresses in the wallet.
  4. Close the wallet in Sparrow.

3. Pay

  1. Open a different wallet in Sparrow. In my case, this is another local hot wallet.
    • In this case it is a script: wpkh(BIP39), derivation: m/84'/0'/0', with passPHRASE, using Account 3 - m/84'/0'/3'
    • same wallet as what "worked" above
  2. "Send" tab, paste the recipient's Payment Code into the "Pay to" field
  3. Receive prompt to send notification txn
    Image
  4. "Yes" - Notification txn is created:
    Image
  5. The "Pay To" field is now pre-filled with the target wallet's Payment Code:
  6. Pay 1000 sats to PM8TJRHzcJ1xS76sK4pjT7jENsuiSa1HMBbBgn249dVd79NDkbWGTmG7ovtekeJK8hyoVDy1NhDWid9vrZroxivyaeJeYvBsukDZpomhrhjnspEBTG58
    Image
  7. Close the sending wallet in Sparrow.

4. Receive

  1. Re-open the original wallet in Sparrow
  2. ❌ No incoming txns
  3. First "normal" receive address is bc1qgwvcsqs3qu3nt2szzzwp5xrdq699ua6rpdk7ry - not the one that was sent to, but that's expected. It should be sent to a PayNym address... let's look at those.
  4. "Addresses" tab -> "PayNyms" button
    There are 3 options:
    Image
    • P2PKH
      Image
    • P2SH-P2WPKH
      Image
    • P2WPKH
      Image
  5. None of the PayNym address sets have the actual address that was sent to - bc1qqgg5wd80a00zcf8at47cspjjtv6h50kt9d8jvx - in it.

5. Where Money? 💸

Various maybe useful info?

"From ..."

The "From" payment code above - PM8TJMRj...kT6 - isn't one I recognize. It is NOT the Payment code shown by the Sending wallet when I retrieve that wallet's PayNym.

Unlinked Contacts

The receiving wallet now shows the unrecognized PM8TJMRj...kT6 as an unlinked contact:

Image

❌ Sparrow ➡️ BlueWallet by Raw Payment Code

1. Setup Recipient

  1. I created a hot wallet in the iOS BlueWallet app
    • Type: HD SegWit (BIP84 Bech32 Native)
    • Derivation: M/84'/0'/0'

2. Get Address(es)

  1. I clicked "receive" in the app
  2. App offered payment code PM8TJN6HE49BcEyF6u84R6S2WyiZPVC43jjFmEixkqAh5MEVcmCJJss4t2ecTFRY7CW7BYNeY2K8wnpN7K7AR29dM8CrH38GDuLm7mbihvrsdqMZueyR

3. Pay

  1. Open a different wallet in Sparrow. In my case, this is another local hot wallet.
    • In this case it is a script: wpkh(BIP39), derivation: m/84'/0'/0', with passPHRASE, using Account 3 - m/84'/0'/3'
    • same wallet as what "worked" above
  2. "Send" tab, paste the recipient's Payment Code into the "Pay to" field
  3. Receive prompt to send notification txn
  4. "Yes" - Notification txn is created:
    Image
  5. The "Pay To" field is now pre-filled with the target wallet's Payment Code:
  6. Pay 1000 sats to PM8TJN6HE49BcEyF6u84R6S2WyiZPVC43jjFmEixkqAh5MEVcmCJJss4t2ecTFRY7CW7BYNeY2K8wnpN7K7AR29dM8CrH38GDuLm7mbihvrsdqMZueyR
    Image
  7. Close the sending wallet in Sparrow.

4. Receive

  1. Open BlueWallet app
  2. ❌ No incoming txns

5. Where Money 💸

As far as I can tell, BlueWallet doesn't provide a utility for claiming a PayNym from a payment code, which is what I naturally wanted to test next.

BlueWallet also doesn't provide a list of the BIP47 receive addresses, so I cannot confirm whether bc1q37r7zzn0s23nxqfhk763ts0gsxf4kdtv687m9y is actually in there somewhere.

Please let me know if I've done something wrong, or if there is any additional information I could provide that would be helpful!

@craigraw
Copy link
Collaborator

I've been unable to reproduce this, even after creating a unit test in sparrowwallet/drongo@4296802 which creates different random wallets and uses the BIP47 protocol to exchange payment information.

The "history has changed" message is a bit suspicious here - be aware that any changes to the passphrase will change the seed, and thus the payment code, and thus any previous notification transactions will not apply to the "new wallet". Is there anything unusual about the passphrase?

@SpottyMatt
Copy link
Author

I definitely got the passphrase correct each time. Master fingerprint matches, and all txn history remains present after the refresh. The passphrase is an English sentence, with the only punctuation marks being period(s) ..

✅ NEW Sparrow (2a), No Passphrase ➡️ Sparrow by Raw Payment Code

1. Create Sender

  1. I created a new Sparrow hot wallet
    • 24 words
    • no passPHRASE
    • derivation m/84'/0'/0'
  2. Sent some sats to its first normal receive address.

2. Pay

  1. Using the Payment Code from the BlueWallet test above (PM8TJN6HE49BcEyF6u84R6S2WyiZPVC43jjFmEixkqAh5MEVcmCJJss4t2ecTFRY7CW7BYNeY2K8wnpN7K7AR29dM8CrH38GDuLm7mbihvrsdqMZueyR)
  2. Send a payment
  3. Prompted to create notification txn:
    Image
  4. Send linking txn:
    Image
  5. Pay 1000 sats:
    Image
  6. 1000 sats sent to bc1qtg32v029gtjppsmh3ct75xgd692ds5tyakgawx in target BlueWallet.
    Image

3. Receive ✅

Funds do show up in target bluewallet!

✅ NEW Sparrow (2b), With Passphrase ➡️ Sparrow by Raw Payment Code

1. Create Sender

  1. I created a new Sparrow hot wallet
    • 24 words
    • with a passPHRASE that is representative of the passphrase used by the original Sparrow wallet that failed to send.
    • derivation m/84'/0'/0'
  2. Sent some sats to its first normal receive address.

2. Pay

  1. Using the Payment Code from the BlueWallet test above (PM8TJN6HE49BcEyF6u84R6S2WyiZPVC43jjFmEixkqAh5MEVcmCJJss4t2ecTFRY7CW7BYNeY2K8wnpN7K7AR29dM8CrH38GDuLm7mbihvrsdqMZueyR)
  2. Send a payment
  3. Prompted to create notification txn:
    Image
  4. Send linking txn:
    Image
  5. Pay 1000 sats:
    Image
  6. 1000 sats sent to bc1q3t2wvfupan8qqjgldzxyq0eydch7xuj7xjamen in target BlueWallet.
    Image

3. Receive ✅

Funds do show up in target bluewallet!

The issue really does seem to be confined to my original Sparrow hot wallet.

For future wallets, if I can succeed at any raw payment code send from a Sparrow hot wallet, would that suggest that all Payment code sends should work, and the wallet is safe to use?

@SpottyMatt
Copy link
Author

SpottyMatt commented Feb 24, 2025

I will update the original report to be more clear. The behavior was observed originally in the third account - m/84'/0'/2' - of the original wallet, and later reproduced from the fourth account - m/84'/0'/3 - on the affected wallet. This fourth account is the account used in the documented failures in the original report of this issue.

The later two successes with new wallets both used the first/primary account.

Here is an attempt with the original affected wallet's first, primary account.

✅ Sparrow (affected) acct 0 ➡️ NEW Sparrow (2b) With Passphrase by Raw Payment Code

1. Get Address

  1. Open New Sparrow (2b) wallet in Sparrow Wallet
  2. Tools -> Show PayNym (I have not retrieved a paynym); payment code reported as PM8TJdvMHmE9J5ZS8RM4sTSGURjeeM3JUpMhL4qQenHAa4aUzRKUrjDhraZdvf7uTHkScovNhve8J7MSuGLGSrFF5ZPw4LMrio9CL832CHb4igxuzaYE
  3. Close wallet.

2. Pay

  1. Open original, affected wallet.
  2. Select the first account ("Deposit")
  3. Enter payment code
    Prompted to create linking txn:
    Image
  4. Send linking txn:
  5. Sparrow reports success:
    Image
  6. Send 1000 sats to PM8TJdvMHmE9J5ZS8RM4sTSGURjeeM3JUpMhL4qQenHAa4aUzRKUrjDhraZdvf7uTHkScovNhve8J7MSuGLGSrFF5ZPw4LMrio9CL832CHb4igxuzaYE
    Image
  7. 1000 sats sent to bc1qxscm7kc3xjezsu5qnznwn0psddp7vn6k8x2a94

3. Receive

  1. Open New Sparrow (2b) wallet in Sparrow Wallet
  2. I see the transaction listed!

I also see that this wallet in Sparrow knows the actual PayNym of the sending wallet, and refers to the wallet in the "PayNym Addresses" window by its PayNym, and not by raw payment code. Even though I paid from the sending wallet to the Payment Code (not PayNym) of the recipient, I guess something out there (Local Sparrow data? The PayNym service?) knows, and the UI in the recipient wallet is looking up the sending Payment Code and resolving it to a PayNym.

I also see that the sending wallet's PayNym shows up in the "Contacts" box of the "Tools > Show PayNyM" window, as not linked - the "link contact" button is clickable.

@craigraw
Copy link
Collaborator

Thanks again for the test. It's starting to look like this was a temporary issue related to the state of the wallet at that time, rather than something recorded in the wallet file. But a repeat test sending from the third or fourth account where the issue occurred would confirm that either way.

Even though I paid from the sending wallet to the Payment Code (not PayNym) of the recipient, I guess something out there (Local Sparrow data? The PayNym service?) knows, and the UI in the recipient wallet is looking up the sending Payment Code and resolving it to a PayNym.

Yes, that's correct - Sparrow is contacting paynym.rs for this data. This behaviour is controlled by the usePayNym field in the Sparrow config file.

I also see that the sending wallet's PayNym shows up in the "Contacts" box of the "Tools > Show PayNyM" window, as not linked - the "link contact" button is clickable.

Yes, as per BIP47: Bob MUST send a notification transaction to Alice prior to the first time he sends funds to Alice, even if he has received transactions from her in the past.

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

No branches or pull requests

2 participants