|
| 1 | +# Return user-facing events when applying updates after syncing |
| 2 | + |
| 3 | +* Status: accepted |
| 4 | +* Authors: @notmandatory |
| 5 | +* Date: 2025-09-21 |
| 6 | +* Targeted modules: wallet |
| 7 | +* Associated tickets/PRs: #6, #310 |
| 8 | + |
| 9 | +## Context and Problem Statement |
| 10 | + |
| 11 | +When syncing a `Wallet` with new blockchain data using `Wallet::apply_update` it does not return any value on success, |
| 12 | +only a `CannotConnectError` if it fails. |
| 13 | + |
| 14 | +Users have asked for a concise list of events that reflect if or how new blockchain data has changed the |
| 15 | +blockchain tip and the status of transactions relevant to the wallet's bitcoin balance. This information should also |
| 16 | +be useful for on-chain apps who want to notify users of wallet changes after syncing. |
| 17 | + |
| 18 | +If the end user app ends for some reason before handling the wallet events, the same wallet events should be |
| 19 | +regenerated when the same blockchain sync data is re-downloaded and reapplied to the wallet. |
| 20 | + |
| 21 | +## Decision Drivers |
| 22 | + |
| 23 | +* Currently `Wallet::apply_update` does not return any value except a `CannotConnectError` if it fails. |
| 24 | +* Downstream users need updates on chain tip, new transactions and transaction status changes. |
| 25 | +* If the app doesn't process all the events before it ends the same events should be returned on a subsequent sync. |
| 26 | +* Current downstream users requesting this feature are: LDK node (@tnull) and Bitkit (@ovitrif). |
| 27 | +* This feature was requested in May 2024, over a year and a half ago. |
| 28 | + |
| 29 | +## Considered Options |
| 30 | + |
| 31 | +#### Option 1: Do nothing |
| 32 | + |
| 33 | +Do not change anything since all the data the users require is available with the current API by comparing the |
| 34 | +wallet's canonical transaction list before and after applying a sync update. |
| 35 | + |
| 36 | +**Pros:** |
| 37 | + |
| 38 | +* No API changes are needed and user can customize the events to exactly what they need. |
| 39 | + |
| 40 | +**Cons:** |
| 41 | + |
| 42 | +* Users will need to duplicate the work to add this feature on every project. |
| 43 | +* It's easier for the core BDK team to add this feature once in a way that meets most users needs. |
| 44 | + |
| 45 | +#### Option 2: Modify the `Wallet::apply_update` to return a list of `WalletEvent` |
| 46 | + |
| 47 | +Adds `WalletEvent` enum of user facing events that are generated when a sync update is applied to a wallet using the |
| 48 | +existing `Wallet::apply_update` function. The `WalletEvent` enum includes an event for changes in blockchain tip and |
| 49 | +events for changes to the status of transactions that are relevant to the wallet, including: |
| 50 | + |
| 51 | +1. newly seen in the mempool |
| 52 | +2. replaced in the mempool |
| 53 | +3. dropped from the mempool |
| 54 | +4. confirmed in a block |
| 55 | +5. confirmed in a new block due to a reorg |
| 56 | +6. unconfirmed due to a reorg |
| 57 | + |
| 58 | +Chain tip change events are generated by comparing the wallet's chain tip before and after applying an update. Wallet |
| 59 | +transaction events are generated by comparing a snapshot of canonical transactions. |
| 60 | + |
| 61 | +As long as updates to the wallet are not persisted until after all events are processed by the caller then if the app |
| 62 | +crashes for some reason and the wallet is re-sync'd a new update will re-return the same events. |
| 63 | + |
| 64 | +The `WalletEvent` enum is non-exhaustive. |
| 65 | + |
| 66 | +**Pros:** |
| 67 | + |
| 68 | +* Events are always generated when a wallet update is applied. |
| 69 | +* The user doesn't need to add this functionality themselves. |
| 70 | +* New events can be added without a breaking change. |
| 71 | + |
| 72 | +**Cons:** |
| 73 | + |
| 74 | +* This can not be rolled out except as a breaking release since it changes the `Wallet::apply_update` function signature. |
| 75 | +* If an app doesn't care about these events they must still generate them. |
| 76 | + |
| 77 | +#### Option 3: Same as option 2 but add a new function |
| 78 | + |
| 79 | +This option is the same as option 2 but adds a new `Wallet::apply_update_events` function to update the wallet and |
| 80 | +return the list of `WalletEvent` enums. |
| 81 | + |
| 82 | +**Pros:** |
| 83 | + |
| 84 | +* Same reasons as above and does not require an API breaking release. |
| 85 | +* Keeps option for users to update the wallet with original `Wallet::apply_update` and not get events. |
| 86 | + |
| 87 | +**Cons:** |
| 88 | + |
| 89 | +* Could be confusing to users which function to use, the original or new one. |
| 90 | +* If in a future breaking release we decide to always return events we'll need to deprecate `Wallet::apply_update_events`. |
| 91 | + |
| 92 | +## Decision Outcome |
| 93 | + |
| 94 | +Chosen option: "Option 3", because it can be delivered to users in the next minor release. This option also lets us |
| 95 | +get user feedback and see how the events are used before forcing all users to generate them during an update. |
| 96 | + |
| 97 | +### Positive Consequences |
| 98 | + |
| 99 | +* The new wallet events can be used for more responsive on chain wallet UIs. |
| 100 | + |
| 101 | +### Negative Consequences |
| 102 | + |
| 103 | +* The down stream `bdk-ffi` and book of bdk projects will need to be updated for this new feature. |
| 104 | + |
0 commit comments