1#[cfg(feature = "fs")]
23use std::path::PathBuf;
24
25#[cfg(all(feature = "fs", feature = "bp"))]
26use bpwallet::fs::FsTextStore;
27#[cfg(all(feature = "fs", feature = "bp"))]
28use bpwallet::Wallet;
29#[cfg(all(not(target_arch = "wasm32"), feature = "fs"))]
30use nonasync::persistence::PersistenceProvider;
31use psrgbt::{RgbOutExt, RgbPropKeyExt};
32use rgbstd::containers::Transfer;
33use rgbstd::contract::ContractOp;
34#[cfg(feature = "fs")]
35use rgbstd::persistence::fs::FsBinStore;
36use rgbstd::persistence::{
37 IndexProvider, MemIndex, MemStash, MemState, StashProvider, StateProvider, Stock, StockError,
38};
39
40use super::{
41 CompletionError, CompositionError, ContractId, PayError, TransferParams, WalletProvider,
42};
43#[cfg(all(feature = "fs", feature = "bp"))]
44use super::{DescriptorRgb, WalletError};
45use crate::invoice::RgbInvoice;
46use crate::pay::PsbtMeta;
47
48#[derive(Getters)]
49pub struct RgbWallet<
50 W: WalletProvider,
51 S: StashProvider = MemStash,
52 H: StateProvider = MemState,
53 I: IndexProvider = MemIndex,
54> {
55 stock: Stock<S, H, I>,
56 wallet: W,
57}
58
59#[cfg(all(feature = "fs", feature = "bp"))]
60impl<
61 K,
62 D: DescriptorRgb + bpwallet::Descriptor<K>,
63 S: StashProvider,
64 H: StateProvider,
65 I: IndexProvider,
66 > RgbWallet<Wallet<K, D>, S, H, I>
67{
68 #[allow(clippy::result_large_err)]
69 pub fn load(
70 stock_path: PathBuf,
71 wallet_path: PathBuf,
72 autosave: bool,
73 ) -> Result<Self, WalletError>
74 where
75 D: serde::Serialize + for<'de> serde::Deserialize<'de>,
76 FsBinStore: PersistenceProvider<S>,
77 FsBinStore: PersistenceProvider<H>,
78 FsBinStore: PersistenceProvider<I>,
79 {
80 use nonasync::persistence::PersistenceError;
81 let provider = FsBinStore::new(stock_path)
82 .map_err(|e| WalletError::StockPersist(PersistenceError::with(e)))?;
83 let stock = Stock::load(provider, autosave).map_err(WalletError::StockPersist)?;
84 let provider = FsTextStore::new(wallet_path)
85 .map_err(|e| WalletError::WalletPersist(PersistenceError::with(e)))?;
86 let wallet = Wallet::load(provider, autosave).map_err(WalletError::WalletPersist)?;
87 Ok(Self { wallet, stock })
88 }
89}
90
91impl<W: WalletProvider, S: StashProvider, H: StateProvider, I: IndexProvider>
92 RgbWallet<W, S, H, I>
93{
94 pub fn new(stock: Stock<S, H, I>, wallet: W) -> Self { Self { stock, wallet } }
95
96 pub fn stock_mut(&mut self) -> &mut Stock<S, H, I> { &mut self.stock }
97
98 pub fn wallet_mut(&mut self) -> &mut W { &mut self.wallet }
99
100 pub fn history(&self, contract_id: ContractId) -> Result<Vec<ContractOp>, StockError<S, H, I>> {
101 let contract = self.stock.contract_data(contract_id)?;
102 let wallet = &self.wallet;
103 Ok(contract.history(wallet.filter_outpoints(), wallet.filter_witnesses()))
104 }
105
106 #[allow(clippy::result_large_err)]
107 pub fn pay<P: RgbPropKeyExt, O: RgbOutExt<P>>(
108 &mut self,
109 invoice: &RgbInvoice,
110 params: TransferParams,
111 ) -> Result<(W::Psbt, PsbtMeta, Transfer), PayError> {
112 self.wallet
113 .pay::<S, H, I, P, O>(&mut self.stock, invoice, params)
114 }
115
116 #[allow(clippy::result_large_err)]
117 pub fn construct_psbt<P: RgbPropKeyExt, O: RgbOutExt<P>>(
118 &mut self,
119 invoice: &RgbInvoice,
120 params: TransferParams,
121 ) -> Result<(W::Psbt, PsbtMeta), CompositionError> {
122 self.wallet
123 .construct_psbt_rgb::<S, H, I, P, O>(&self.stock, invoice, params)
124 }
125
126 #[allow(clippy::result_large_err)]
127 pub fn transfer(
128 &mut self,
129 invoice: &RgbInvoice,
130 psbt: &mut W::Psbt,
131 beneficiary_vout: Option<u32>,
132 ) -> Result<Transfer, CompletionError> {
133 self.wallet
134 .transfer(&mut self.stock, invoice, psbt, beneficiary_vout)
135 }
136}