Skip to content

fix: explain Monero payment ID destination conflict - #3501

Open
sethforprivacy wants to merge 2 commits into
devfrom
fix/cw-996-monero-payment-id-error
Open

fix: explain Monero payment ID destination conflict#3501
sethforprivacy wants to merge 2 commits into
devfrom
fix/cw-996-monero-payment-id-error

Conversation

@sethforprivacy

@sethforprivacy sethforprivacy commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Issue Number (if Applicable): Fixes CW-996

Description

Rejects a multi-destination Monero transaction when any non-empty destination contains an integrated payment ID, while preserving valid single-recipient and ordinary multi-recipient sends. The typed failure is mapped to localized error copy across all supported ARB locales.

Validation

  • Focused review: no blocking findings

@sethforprivacy

Copy link
Copy Markdown
Contributor Author

Smoke test result: BLOCKED (environmental) — no PR defect found

On-device attempt against the exact PR CI APK (Android emulator, Android 14 / API 34) using Trailblaze. The PR's rejection path could not be demonstrated end-to-end via the UI in this environment; the gate logic itself was verified in source at the exact head. No PR defect was found.

Tested artifact

  • APK: GitHub Actions run 31333364389 ("Cake Wallet Android", success), artifact "android apk" id 9044834158
  • Head SHA: d5c4c6f66aac27afd5b70d5dfecda54a6ced8025
  • Canonical APK: app-arm64-v8a-release.apk, SHA-256 d556f429c13259af1c782fc7e533f6e48a02f2c71841dc3995c3ac0d497afaf6 (SHA-1 matches CI sidecar)
  • Installed package: com.cakewallet.test_fixcw996moner v6.4.0 (6419)

What was verified

  • Wallet setup, node, and sync fully working: fresh Monero wallet synced against a real daemon (guest→host bridge to nodes.hashvault.pro:18081, live height ~3,737,063 advancing; logcat onNewBlock), send form reached with multi-recipient capability ("Add another receiver"), two recipients enterable (standard + integrated addresses, both format-valid checksum-verified mainnet).
  • Case A (CORE: standard + integrated, 0.01 each): confirmation sheet appears, then Transaction Error: You do not have enough XMR to send this amount. The PR's payment-ID rejection is NOT reached.
    Root cause (source-verified at exact head): a pre-existing balance gate in cw_monero/lib/monero_wallet.dart (~line 458) throws before transaction_history.dart createTransactionMultDest (~line 470) runs, and CW-996's payment-ID check sits at the top of createTransactionMultDest. With a 0-balance wallet the balance gate always fires first, making the payment-ID rejection unreachable in-app.
  • Case B (negative control, two standard addresses): identical "not enough XMR" result — pair indistinguishable at 0 balance, as the payment-ID gate was not reached in either case.
  • Case C (single integrated recipient): single integrated send is accepted through validation (confirmation sheet parses the integrated address), no payment-ID rejection — consistent with the PR's "single integrated allowed" contract.
  • Code path at exact head: transaction_history.dart:250-255 throws MoneroMultipleDestinationsPaymentIdException before the native call; send_view_model.dart maps it to error_text_payment_id_multiple_recipients; the ARB string ("Transactions cannot contain more than one destination when paying to a payment ID.") is present. The balance gate is pre-existing (present in parent commit too), not introduced by this PR.

Blocker to full UI demonstration: demonstrating the UI rejection requires a wallet balance ≥ the two recipient amounts (unlocked XMR). No funding path was available in this environment, so the end-to-end UI rejection could not be exercised. PR logic is present and correct per source inspection at the exact head; availability check isIntegrated / drizzle gate behavior was verified via the gateway logic and the single-recipient control.

Evidence

  • .trailblaze/pr-smokes/pr-3501/evidence/ (+ retry2-sync-enabled/): case screenshots (2 recipients + balance error, 2-standard control, single-integrated), node list, seed screen, EVIDENCE.md, wallet notes, trails.

Removes the test additions/modifications introduced by this branch so the
test design is left to the maintainers. Production code is unchanged.
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.

1 participant