mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-06 03:38:23 +00:00
The kind:7375 fix made the balance whole; the transaction list was still whatever one uncapped REQ returned. CashuWalletEoseManager asks six kinds of one relay in a single REQ with no limit, and kind:7376 history is the most numerous of them, so the list every device shows is a recent-N suffix chosen by that relay's cap — and no later REQ asks for the rest, because the EOSE moves `since` forward. Proofs and history want opposite fixes. A balance summed over a partial proof set is wrong rather than incomplete, so those are walked to exhaustion in one shot. History is display-only and unbounded, and the user reads it newest-first, so pulling all of it at launch would be a large download for something they may never scroll. That is exactly the shape until+limit paging is for. Built on the existing machinery rather than a new one: BackwardRelayPager with cursors on the Account (Account.cashuHistory, beside notificationHistory), modelled on AccountNotificationsHistoryEoseManager for the loader and on the NIP-29 thread list for the two UI drivers — a bootstrap that fills the first screen and a look-ahead that pulls another page only while the user is scrolling toward the bottom. Nothing is fetched while the wallet is off screen, and a relay that finished a page parks at its cursor so another relay advancing doesn't re-REQ it. One deliberate divergence from the DM and notification pagers: they floor at `now - liveTail` because a separate live loader provably covers everything newer. The wallet has no such guarantee — its live REQ carries neither `since` nor `limit`, so how far back it reaches is whatever the relay decided, which is the bug being fixed. Flooring at a fixed tail would leave a band between the relay's cap and the tail boundary that neither loader ever asks for. This pager floors at `now` and overlaps the live subscription completely; duplicates are free (both LocalCache and CashuWalletState.historyEvents are keyed by event id) and gaplessness is worth more than the overlap. The footer splits on stalledCount rather than reporting `exhausted` as "all loaded": exhausted means nothing more is reachable right now, and a relay that answered an auth CLOSE or went silent is stalled, not done. Telling someone their transaction history is complete when part of it was never served is a lie about their own money. Page limit is 100, not the notification pager's 500 — every kind:7376 row costs a NIP-44 decrypt to render, which on an external signer is an out-of-process round-trip. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HaZ8RprmKC3sidsq6W8dKY