]> Untitled Git - bdk/commitdiff
feat(wallet): make wallet compatible with sync/full-scan structures
author志宇 <hello@evanlinjin.me>
Wed, 24 Apr 2024 08:54:03 +0000 (16:54 +0800)
committer志宇 <hello@evanlinjin.me>
Fri, 26 Apr 2024 04:55:48 +0000 (12:55 +0800)
* Changed `Wallet::apply_update` to also take in anything that
  implements `Into<Update>`. This allows us to directly apply a
  `FullScanResult` or `SyncResult`.
* Added `start_full_scan` and `start_sync_with_revealed_spks` methods to
  `Wallet`.

Co-authored-by: Steve Myers <steve@notmandatory.org>
crates/bdk/src/wallet/mod.rs

index 1e24dd50e4436f54cb2156ca6aab125838aaddc1..b959a3adac5ff8a494c4cbdd96ea59dae71e70bd 100644 (file)
@@ -26,6 +26,7 @@ use bdk_chain::{
     local_chain::{
         self, ApplyHeaderError, CannotConnectError, CheckPoint, CheckPointIter, LocalChain,
     },
+    spk_client::{FullScanRequest, FullScanResult, SyncRequest, SyncResult},
     tx_graph::{CanonicalTx, TxGraph},
     Append, BlockId, ChainPosition, ConfirmationTime, ConfirmationTimeHeightAnchor, FullTxOut,
     IndexedTxGraph, Persist, PersistBackend,
@@ -110,6 +111,26 @@ pub struct Update {
     pub chain: Option<CheckPoint>,
 }
 
+impl From<FullScanResult<KeychainKind>> for Update {
+    fn from(value: FullScanResult<KeychainKind>) -> Self {
+        Self {
+            last_active_indices: value.last_active_indices,
+            graph: value.graph_update,
+            chain: Some(value.chain_update),
+        }
+    }
+}
+
+impl From<SyncResult> for Update {
+    fn from(value: SyncResult) -> Self {
+        Self {
+            last_active_indices: BTreeMap::new(),
+            graph: value.graph_update,
+            chain: Some(value.chain_update),
+        }
+    }
+}
+
 /// The changes made to a wallet by applying an [`Update`].
 #[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, Default)]
 pub struct ChangeSet {
@@ -2262,7 +2283,8 @@ impl Wallet {
     /// transactions related to your wallet into it.
     ///
     /// [`commit`]: Self::commit
-    pub fn apply_update(&mut self, update: Update) -> Result<(), CannotConnectError> {
+    pub fn apply_update(&mut self, update: impl Into<Update>) -> Result<(), CannotConnectError> {
+        let update = update.into();
         let mut changeset = match update.chain {
             Some(chain_update) => ChangeSet::from(self.chain.apply_update(chain_update)?),
             None => ChangeSet::default(),
@@ -2387,6 +2409,31 @@ impl Wallet {
     }
 }
 
+/// Methods to construct sync/full-scan requests for spk-based chain sources.
+impl Wallet {
+    /// Create a partial [`SyncRequest`] for this wallet for all revealed spks.
+    ///
+    /// This is the first step when performing a spk-based wallet partial sync, the returned
+    /// [`SyncRequest`] collects all revealed script pubkeys from the wallet keychain needed to
+    /// start a blockchain sync with a spk based blockchain client.
+    pub fn start_sync_with_revealed_spks(&self) -> SyncRequest {
+        SyncRequest::from_chain_tip(self.chain.tip())
+            .populate_with_revealed_spks(&self.indexed_graph.index, ..)
+    }
+
+    /// Create a [`FullScanRequest] for this wallet.
+    ///
+    /// This is the first step when performing a spk-based wallet full scan, the returned
+    /// [`FullScanRequest] collects iterators for the wallet's keychain script pub keys needed to
+    /// start a blockchain full scan with a spk based blockchain client.
+    ///
+    /// This operation is generally only used when importing or restoring a previously used wallet
+    /// in which the list of used scripts is not known.
+    pub fn start_full_scan(&self) -> FullScanRequest<KeychainKind> {
+        FullScanRequest::from_keychain_txout_index(self.chain.tip(), &self.indexed_graph.index)
+    }
+}
+
 impl AsRef<bdk_chain::tx_graph::TxGraph<ConfirmationTimeHeightAnchor>> for Wallet {
     fn as_ref(&self) -> &bdk_chain::tx_graph::TxGraph<ConfirmationTimeHeightAnchor> {
         self.indexed_graph.graph()