Skip to content

fix: keep restored receives silent - #1343

Merged
jvsena42 merged 2 commits into
masterfrom
fix/restore-historical-received-sheet
Sep 25, 2026
Merged

jvsena42 merged 2 commits into
masterfrom
fix/restore-historical-received-sheet

Conversation

@jvsena42

@jvsena42 jvsena42 commented Sep 25, 2026 •

Copy link
Copy Markdown
Member

Fixes #1342
Related: synonymdev/bitkit-ios#588 (same fix on iOS)

This PR keeps a pre-restore on-chain receive confirmed within the last hour from showing a Received sheet after a mnemonic restore.

LDK events are handled in separate coroutines, so a replayed OnchainTransactionConfirmed could pass the restore-hold check after the first on-chain sync had already swept history and lifted the hold. The deposit's block time was inside the one-hour window, so the sheet showed and covered home.

Description

  • Records the chain tip of the first on-chain sync after a restore (SettingsData.restoreSyncedBlockHeight), in the same settings update that lifts the hold, so a historical confirmation stays silent however late its event is handled or a later rescan replays it.
  • Skips confirmed-only receives at or below that tip in NotifyPaymentReceivedHandler, reading the hold and the tip from one settings snapshot so no check can see the hold lifted without the tip.
  • Carries the confirming block height on NotifyPaymentReceived.Command.Onchain.
  • Runs one post-restore sweep at a time, so a later sync finishing while it runs cannot record a higher tip and silence a receive confirmed in between.
  • Keeps the recorded tip when settings are restored from a backup, and resets it when a new restore starts.
  • Releases the restore hold when the wallet restore fails, since no node starts to lift it and it would otherwise silence every later on-chain receive.
  • Adds the restore-recent-receive-stays-silent journey.

Out of Scope

  • NotifyPaymentReceivedHandler: a reorg that replaces a block at or below the restore tip with one paying the wallet a tx it never saw in the mempool shows no sheet; SyncCompleted reports only a height, so the replacement block cannot be told apart. A tx seen in the mempool first still notifies.
  • NotifyPaymentReceivedHandler: a genuinely new deposit that arrives while the first post-restore sync runs is still held; it notifies when it confirms, as long as that is within the hour. The first sync cannot tell it from an unconfirmed pre-restore transaction it replays.
  • SettingsData.restoreSyncedBlockHeight: kept until the next restore. On a regtest chain reset with a persisted dev install, confirmed-only sheets stay silent until the new chain passes the old tip.

Design

N/A — no UI changes.

Preview

N/A

QA Notes

Journeys

  • new restore-recent-receive-stays-silent.xml — a deposit confirmed within the hour stays silent after restoring its seed, and a deposit mined after the restore still shows the sheet

Manual Tests

N/A

Automated Checks

  • added NotifyPaymentReceivedHandlerTest.kt — a confirmed-only receive at or below the restore tip is skipped, and one above it shows the sheet
  • added WalletViewModelTest.kt — a failed restore releases the received-sheet hold
  • added SettingsStoreTest.kt — restoring settings from a backup keeps the restore tip recorded on this device
  • updated AppViewModelSendFlowTest.kt — the first on-chain sync after a restore records its tip, and a failed sweep does not
  • updated LightningNodeServiceTest.kt — confirmed commands carry the block height

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[Medium risk] Adds logic to silence payment notifications after wallet restore.

The PR appears safe to merge based on the reviewed changes.

Summary

The PR records the first successful post-restore on-chain sync height and uses it to keep historical confirmed-only receives silent after the restore hold lifts.

  • Serializes restore sweeps, preserves the recorded tip across backup-settings restoration, and releases the hold when wallet restoration fails.
  • Adds handler and sync tests and a restore-receive journey.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A[Restore starts: hold armed] --> B[First on-chain sync]
  B --> C[Mark historical activities seen]
  C --> D[Atomically save sync tip and lift hold]
  D --> E{Confirmed-only receive}
  E -->|Height at or below tip| F[Skip historical receive]
  E -->|Height above tip| G[Apply remaining notification checks]
Loading

Reviews (2) · Last reviewed commit: "fix: record only the first restore sync ..."

Comment thread app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt Outdated
Comment thread app/src/main/java/to/bitkit/domain/commands/NotifyPaymentReceivedHandler.kt Outdated
Comment thread journeys/onchain-receive/restore-recent-receive-stays-silent.xml Outdated
@github-actions

github-actions Bot commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Regtest APK

Built from 62774c0 (run).

Download bitkit-dev-debug universal APK (expires in 30 days).

@jvsena42 jvsena42 self-assigned this Sep 25, 2026
@jvsena42
jvsena42 marked this pull request as draft September 25, 2026 10:42
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jvsena42
jvsena42 marked this pull request as ready for review September 25, 2026 10:50
@piotr-iohk

Copy link
Copy Markdown
Collaborator

@jvsena42
jvsena42 requested review from a team, piotr-iohk and pwltr and removed request for a team September 25, 2026 12:41

@piotr-iohk piotr-iohk left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QA LGTM on 62774c0d.

No actionable code findings. Restore-tip silence looks correct vs iOS#588; Greptile/CodeQL threads verified at this head.

Migration @migration_1 green for RN v1.1.3 and v1.1.4 (the #1342 nightly failures). v1.1.6 @migration_1 re-run still in flight; prior fail attributed to #1258 (tracked, unrelated to this fix).

@jvsena42
jvsena42 merged commit 7a7b350 into master Sep 25, 2026
72 of 76 checks passed
@jvsena42
jvsena42 deleted the fix/restore-historical-received-sheet branch September 25, 2026 13:38
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]: historical on-chain receive sheet stays up after mnemonic restore

3 participants