Skip to content

fix: default to a subaddress on Monero/Wownero receive - #3508

Open
thomasbuilds wants to merge 1 commit into
cake-tech:devfrom
thomasbuilds:fix/monero-default-receive-subaddress
Open

fix: default to a subaddress on Monero/Wownero receive#3508
thomasbuilds wants to merge 1 commit into
cake-tech:devfrom
thomasbuilds:fix/monero-default-receive-subaddress

Conversation

@thomasbuilds

Copy link
Copy Markdown

Issue Number (if Applicable): Fixes #1645

Description

With "auto generate subaddresses" enabled (the default), a fresh Monero/Wownero wallet offered the account's primary address (index 0) on the receive screen; a subaddress was only minted after the primary had been used. Rotating manually did work, but the next save() — autosave runs every 30s — reassigned the receive address back to index 0.

  • _getAllUnusedAddresses(): generate a subaddress when index 0 is all the account has, and re-read the list afterwards — the old code mapped the pre-generation snapshot and so never returned the address it had just created. Monero additionally keyed the used-check on index 0 rather than on the newest subaddress. Wownero: the length check now precedes .last, which previously threw on an empty list.
  • updateUnusedSubaddress(): take the highest non-zero index explicitly rather than relying on list position. Three different orderings reach this list depending on which method last populated it, and subaddresses.last is index 0 on the reversed one.
  • latestAddress, addressForExchange: floored at index 1. latestAddress matters because the receive view model assigns it to walletAddresses.address directly, racing the reaction that drives updateUnusedSubaddress, so both writers have to agree. addressForExchange is the deposit address handed to swap providers.
  • isPrimary (Monero): derived positionally from subaddresses.first, which on the reversed list is the newest address, so the badge landed on the wrong entry. Now compares the index, matching the Bitcoin branches further down the same function. Also drops a .first that threw on an empty list (Wownero).

The primary stays in the address list and remains reachable, as integrated addresses require. Only the default changes.

Two notes for reviewers:

The Monero .first.last change is load-bearing, not cosmetic. The old condition asked "is the primary used?", which is permanently false once we stop handing out the primary — rotation would never fire again.

This does not reopen CW-705. usedAddresses is still not exhaustive; nothing here depends on it being complete, since index 0 is excluded unconditionally rather than tested for use. Relevant because #1620 was reverted in #1656 over a large-wallet perf regression, and its successor #1657 needed a new monero_c API and was never merged.

Out of scope: createNewAddress() in wallet_address_util.dart has the same stale list-ordering assumption, causing the rotate button to add the primary to manualAddresses. Happy to file separately.

Pull Request - Checklist

  • Initial Manual Tests Passed
  • Double check modified code and verify it with the feature/task requirements
  • Format code
  • Look for code duplication
  • Clear naming for variables and methods
  • Manual tests in accessibility mode (TalkBack on Android) passed

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@thomasbuilds

Copy link
Copy Markdown
Author

Note: I've never used Dart/Flutter so far, this was made entirely by AI. I'm asking reviewers to verify it works as intended, it has never been built or run on my side.

I did my best though to verify everything is correct.

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.

bug: xmr/wow autorotate subaddr requires use of primary

1 participant