Skip to content

feat: show how much each module recovered in the transaction history - #587

Closed
FrankChinedu wants to merge 1 commit into
fedimint:masterfrom
FrankChinedu:feat/recovery-history
Closed

FrankChinedu wants to merge 1 commit into
fedimint:masterfrom
FrankChinedu:feat/recovery-history

Conversation

@FrankChinedu

Copy link
Copy Markdown
Contributor

A wallet restored from a seed phrase comes back with its balance but an empty transaction history: the operation log is local state no seed can reconstruct, so the recovered funds appear with nothing to account for them.

Fedimint already logs a ModuleRecoveryCompleted event per module, with the recovered amount for modules that track one. This indexes those events into our own database and renders each as a history row.

Rust:

  • ModuleRecoveryKey/ModuleRecovery persist one row per module, keyed by module instance so re-indexing is idempotent.
  • spawn_recovery_event_indexer scans the client event log from the start on every client open. Starting at zero rather than at the tip is what reads events written by the recovery client — which wait_for_recovery retires and replaces — and what backfills wallets that recovered before this existed. The event is Persistent, so it is never trimmed away. It is filtered on entry.kind because ModuleRecoveryCompleted::MODULE is None, leaving the module kind in the payload rather than on the entry.
  • MultimintEvent::ModuleRecoveryComplete is published only when the stored row changes, so the rescan on each open cannot re-announce a recovery that finished months ago.
  • merge_recovery_rows folds the rows into a page of the operation log. It sorts rather than appends, because mintv2 recovers in RecoveryMode::Usable and ecash spent during a recovery predates the completion event; and it applies the operation log's own strict cursor bound, so a row the UI paged past is not handed back.

Only the mint modules report an amount. The wallet module recovers but cannot price the outputs it finds, and ln/lnv2 declare RecoveryMode::None and never recover, so the amount is optional throughout and an amount-less row renders as "—" rather than as zero.

A wallet restored from a seed phrase comes back with its balance but an
empty transaction history: the operation log is local state no seed can
reconstruct, so the recovered funds appear with nothing to account for
them.

Fedimint already logs a `ModuleRecoveryCompleted` event per module, with
the recovered amount for modules that track one. This indexes those
events into our own database and renders each as a history row.

Rust:

- `ModuleRecoveryKey`/`ModuleRecovery` persist one row per module,
  keyed by module instance so re-indexing is idempotent.
- `spawn_recovery_event_indexer` scans the client event log from the
  start on every client open. Starting at zero rather than at the tip
  is what reads events written by the recovery client — which
  `wait_for_recovery` retires and replaces — and what backfills wallets
  that recovered before this existed. The event is `Persistent`, so it
  is never trimmed away. It is filtered on `entry.kind` because
  `ModuleRecoveryCompleted::MODULE` is `None`, leaving the module kind
  in the payload rather than on the entry.
- `MultimintEvent::ModuleRecoveryComplete` is published only when the
  stored row changes, so the rescan on each open cannot re-announce a
  recovery that finished months ago.
- `merge_recovery_rows` folds the rows into a page of the operation
  log. It sorts rather than appends, because `mintv2` recovers in
  `RecoveryMode::Usable` and ecash spent during a recovery predates the
  completion event; and it applies the operation log's own strict
  cursor bound, so a row the UI paged past is not handed back.

Only the mint modules report an amount. The wallet module recovers but
cannot price the outputs it finds, and `ln`/`lnv2` declare
`RecoveryMode::None` and never recover, so the amount is optional
throughout and an amount-less row renders as "—" rather than as zero.

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

Copy link
Copy Markdown
Collaborator

Closing in favor of #591

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.

2 participants