Skip to content

wallet: no payment proof for a tx to a public offline address (#1826) - #2155

Open
profinch wants to merge 1 commit into
BeamMW:masterfrom
profinch:fix/1826-offline-payment-proof
Open

profinch wants to merge 1 commit into
BeamMW:masterfrom
profinch:fix/1826-offline-payment-proof

Conversation

@profinch

@profinch profinch commented Oct 7, 2026

Copy link
Copy Markdown

Fixes #1826 (the guard suggested in the issue; a real proof for these transactions needs a new proof format, #1975).

Problem

The sender of a transaction to a public offline address doesn't know the receiver:

  • Legacy (unsigned) public address: LoadReceiverParams makes up the voucher itself and signs it with a random one-time key that it stores as PeerEndpoint. ExportPaymentProof exported that key as the receiver, and VerifyPaymentProof accepted the proof, because it only checks the voucher against that same key. So the wallet produced a proof that "verifies" but names a receiver that doesn't exist.
  • Signed public address: no voucher is stored, so the export failed with the generic "No payment confirmation" warning, and wallet-api export_payment_proof returned "payment_proof": "" as a success.

Change

  • storage::ExportPaymentProof refuses public offline transactions (TxParameterID::AddressType == PublicOffline) with a clear message. The CLI payment_proof_export shows it.
  • wallet-api export_payment_proof returns PaymentProofExportError with the same message instead of an empty proof.

Tests

lelantus_test / TestPublicAddressTx now also sends through a legacy public address. The parameters go through the real LoadReceiverParams, so the made-up voucher and endpoint are the ones the wallet really uses. The test checks that both transactions complete, that the receiver gets both coins, and that no proof is exported for either.

  • Without the fix the new check fails: the legacy transaction exports a proof with Receiver: 35c541…, a random key.
  • With the fix: lelantus_test, wallet_api_test and wallet_test pass (macOS arm64, Ninja RelWithDebInfo).

…dress

The sender of a public offline tx doesn't know the receiver. For a legacy
(unsigned) public address it makes up the voucher and signs it with a random
one-time key stored as PeerEndpoint, so the exported proof named that key as
the receiver and still verified. For a signed public address no voucher is
stored and the export failed with a generic message, while wallet-api returned
an empty payment_proof as success.

ExportPaymentProof now refuses public offline txs with a clear message, and
wallet-api export_payment_proof returns PaymentProofExportError for them.
A real proof for these txs needs a new proof format (BeamMW#1975).
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.

Payment proof for a public offline transaction (receiver does not converge)

1 participant