bark/onchain/
mod.rs

1
2//! Onchain wallet integration interfaces.
3//!
4//! This module defines the traits and types that an external onchain wallet must
5//! implement to be used by the library. The goal is to let integrators plug in
6//! their own wallet implementation, so features like boarding (moving onchain funds
7//! into Ark) and unilateral exit (claiming VTXOs onchain without server cooperation)
8//! are supported.
9//!
10//! Key concepts exposed here:
11//! - [Utxo], [LocalUtxo] & [SpendableExit]: lightweight types representing wallet UTXOs and
12//!   spendable exit outputs.
13//! - [PreparePsbt] & [SignPsbt]: funding and signing interfaces for building transactions.
14//! - [GetBalance], [GetWalletTx], [GetSpendingTx]: read-access to wallet state for balance
15//!   and [Transaction] lookups required by various parts of the library.
16//! - [MakeCpfp]: CPFP construction interfaces used for create child transactions.
17//! - [ExitUnilaterally]: a convenience trait that aggregates the required capabilities a
18//!   wallet must provide to support unilateral exits.
19//!
20//! A reference implementation based on BDK is available behind the `onchain_bdk`
21//! cargo feature. Enable it to use the provided [OnchainWallet] implementation.
22//! You can use all features from BDK because [bdk_wallet] is re-exported.
23
24mod chain;
25#[cfg(feature = "onchain_bdk")]
26mod bdk;
27
28#[cfg(feature = "onchain_bdk")]
29pub use bdk_wallet;
30
31pub use bitcoin_ext::cpfp::{CpfpError, MakeCpfpFees};
32pub use crate::onchain::chain::{ChainSourceSpec, ChainSource, ChainSourceClient, FeeRates};
33
34/// BDK-backed onchain wallet implementation.
35///
36/// Available only when the `onchain_bdk` feature is enabled.
37#[cfg(feature = "onchain_bdk")]
38pub use crate::onchain::bdk::{OnchainWallet, TxBuilderExt};
39
40use std::sync::Arc;
41
42use bitcoin::{
43	Address, Amount, FeeRate, OutPoint, Psbt, Transaction, Txid
44};
45
46use ark::Vtxo;
47use bitcoin_ext::{BlockHeight, BlockRef};
48
49/// Represents an onchain UTXO known to the wallet.
50///
51/// This can be either:
52/// - `Local`: a standard wallet UTXO
53/// - `Exit`: a spendable exit output produced by the Ark exit mechanism
54#[derive(Debug, Clone)]
55pub enum Utxo {
56	Local(LocalUtxo),
57	Exit(SpendableExit),
58}
59
60/// A standard wallet [Utxo] owned by the local wallet implementation.
61#[derive(Debug, Clone)]
62pub struct LocalUtxo {
63	/// The outpoint referencing the UTXO.
64	pub outpoint: OutPoint,
65	/// The amount contained in the UTXO.
66	pub amount: Amount,
67	/// Optional confirmation height; `None` if unconfirmed.
68	pub confirmation_height: Option<BlockHeight>,
69}
70
71/// A spendable unilateral exit of a [Vtxo] which can be claimed onchain.
72///
73/// When exiting unilaterally, the wallet will end up with onchain outputs that correspond to
74/// previously-held VTXOs. These can be claimed and used for further spending.
75#[derive(Debug, Clone)]
76pub struct SpendableExit {
77	/// The VTXO being exited.
78	pub vtxo: Vtxo,
79	/// The block height associated with the exits' validity window.
80	pub height: BlockHeight,
81}
82
83/// Ability to finalize a [Psbt] into a fully signed [Transaction].
84///
85/// Wallets should apply all necessary signatures and finalize inputs according
86/// to their internal key management and policies.
87pub trait SignPsbt {
88	/// Consume a [Psbt] and return a fully signed and finalized [Transaction].
89	fn finish_tx(&mut self, psbt: Psbt) -> anyhow::Result<Transaction>;
90}
91
92/// Ability to query the wallets' total balance.
93///
94/// This is used by higher-level flows to decide when onchain funds are available for boarding or
95/// fee bumping, and to present balance information to users.
96pub trait GetBalance {
97	/// Get the total balance of the wallet.
98	fn get_balance(&self) -> Amount;
99}
100
101/// Ability to look up transactions known to the wallet.
102///
103/// Implementations should return wallet-related transactions and, when possible,
104/// the block information those transactions confirmed in.
105pub trait GetWalletTx {
106	/// Retrieve the wallet [Transaction] for the given [Txid] if any.
107	fn get_wallet_tx(&self, txid: Txid) -> Option<Arc<Transaction>>;
108
109	/// Retrieve information about the block, if any, a given wallet transaction was confirmed in.
110	fn get_wallet_tx_confirmed_block(&self, txid: Txid) -> anyhow::Result<Option<BlockRef>>;
111}
112
113/// Ability to construct funded PSBTs for specific destinations or to drain the wallet.
114///
115/// These methods are used to build transactions for boarding, exits, and fee bumping.
116pub trait PreparePsbt {
117	/// Prepare a [Transaction] which will send to the given destinations.
118	fn prepare_tx(
119		&mut self,
120		destinations: &[(Address, Amount)],
121		fee_rate: FeeRate,
122	) -> anyhow::Result<Psbt>;
123
124	/// Prepare a [Transaction] for sending all wallet funds to the given destination.
125	fn prepare_drain_tx(
126		&mut self,
127		destination: Address,
128		fee_rate: FeeRate,
129	) -> anyhow::Result<Psbt>;
130}
131
132/// Ability to find wallet-local spends of a specific [OutPoint].
133///
134/// This helps identify if the wallet has already spent an exit or parent [Transaction].
135pub trait GetSpendingTx {
136	/// This should search the wallet and look for any [Transaction] that spends the given
137	/// [OutPoint]. The intent of the function is to only look at spends which happen in the wallet
138	/// itself.
139	fn get_spending_tx(&self, outpoint: OutPoint) -> Option<Arc<Transaction>>;
140}
141
142/// Ability to create and persist CPFP transactions for spending P2A outputs.
143pub trait MakeCpfp {
144	/// Creates a signed Child Pays for Parent (CPFP) transaction using a Pay-to-Anchor (P2A) output
145	/// to broadcast unilateral exits and other TRUC transactions.
146	///
147	/// For more information please see [BIP431](https://github.com/bitcoin/bips/blob/master/bip-0431.mediawiki#topologically-restricted-until-confirmation).
148	///
149	/// # Arguments
150	///
151	/// * `tx` - A parent `Transaction` that is guaranteed to have one P2A output which
152	///          implementations must spend so that both the parent and child transactions can be
153	///          broadcast to the network as a v3 transaction package.
154	/// * `fees` - Informs the implementation how fees should be paid by the child transaction. Note
155	///            that an effective fee rate should be calculated using the weight of both the
156	///            parent and child transactions.
157	///
158	/// # Returns
159	///
160	/// Returns a `Result` containing:
161	/// * `Transaction` - The signed CPFP transaction ready to be broadcasted to the network with
162	///                   the given parent transaction if construction and signing were successful.
163	/// * `CpfpError` - An error indicating the reason for failure in constructing the CPFP
164	///                 transaction (e.g., insufficient funds, invalid parent transaction, or
165	///                 signing failure).
166	fn make_signed_p2a_cpfp(
167		&mut self,
168		tx: &Transaction,
169		fees: MakeCpfpFees,
170	) -> Result<Transaction, CpfpError>;
171
172	/// Persist the signed CPFP transaction so it can be rebroadcast or retrieved as needed.
173	fn store_signed_p2a_cpfp(&mut self, tx: &Transaction) -> anyhow::Result<(), CpfpError>;
174}
175
176/// Trait alias for wallets that support boarding.
177///
178/// Any wallet type implementing these component traits automatically implements
179/// `Board`. The trait requires Send + Sync because boarding flows may be
180/// executed from async tasks and across threads.
181///
182/// Required capabilities:
183/// - [SignPsbt]: to finalize transactions
184/// - [GetWalletTx]: to query related transactions and their confirmations
185/// - [PreparePsbt]: to prepare transactions for boarding
186pub trait Board: PreparePsbt + SignPsbt + GetWalletTx + Send + Sync {}
187
188impl <W: PreparePsbt + SignPsbt + GetWalletTx + Send + Sync> Board for W {}
189
190/// Trait alias for wallets that support unilateral exit end-to-end.
191///
192/// Any wallet type implementing these component traits automatically implements
193/// `ExitUnilaterally`. The trait requires Send + Sync because exit flows may be
194/// executed from async tasks and across threads.
195///
196/// Required capabilities:
197/// - [GetBalance]: to evaluate available funds
198/// - [GetWalletTx]: to query related transactions and their confirmations
199/// - [MakeCpfp]: to accelerate slow/pinned exits
200/// - [SignPsbt]: to finalize transactions
201/// - [GetSpendingTx]: to detect local spends relevant to exit coordination
202pub trait ExitUnilaterally:
203	GetBalance +
204	GetWalletTx +
205	MakeCpfp +
206	SignPsbt +
207	GetSpendingTx +
208	Send + Sync + {}
209
210impl <W: GetBalance +
211	GetWalletTx +
212	MakeCpfp +
213	SignPsbt +
214	GetSpendingTx +
215	Send + Sync> ExitUnilaterally for W {}