fedimint_wallet_client/
api.rs

1use bitcoin::{Address, Amount};
2use fedimint_api_client::api::{FederationApiExt, FederationResult, IModuleFederationApi};
3use fedimint_core::envs::BitcoinRpcConfig;
4use fedimint_core::module::{ApiAuth, ApiRequestErased, ModuleConsensusVersion};
5use fedimint_core::task::{MaybeSend, MaybeSync};
6use fedimint_core::{PeerId, apply, async_trait_maybe_send};
7use fedimint_wallet_common::endpoint_constants::{
8    ACTIVATE_CONSENSUS_VERSION_VOTING_ENDPOINT, BITCOIN_KIND_ENDPOINT, BITCOIN_RPC_CONFIG_ENDPOINT,
9    BLOCK_COUNT_ENDPOINT, MODULE_CONSENSUS_VERSION_ENDPOINT, PEG_OUT_FEES_ENDPOINT,
10    UTXO_CONFIRMED_ENDPOINT, WALLET_SUMMARY_ENDPOINT,
11};
12use fedimint_wallet_common::{PegOutFees, WalletSummary};
13
14#[apply(async_trait_maybe_send!)]
15pub trait WalletFederationApi {
16    async fn module_consensus_version(&self) -> FederationResult<ModuleConsensusVersion>;
17
18    async fn fetch_consensus_block_count(&self) -> FederationResult<u64>;
19
20    async fn fetch_peg_out_fees(
21        &self,
22        address: &Address,
23        amount: Amount,
24    ) -> FederationResult<Option<PegOutFees>>;
25
26    async fn fetch_bitcoin_rpc_kind(&self, peer_id: PeerId) -> FederationResult<String>;
27
28    async fn fetch_bitcoin_rpc_config(&self, auth: ApiAuth) -> FederationResult<BitcoinRpcConfig>;
29
30    async fn fetch_wallet_summary(&self) -> FederationResult<WalletSummary>;
31
32    async fn is_utxo_confirmed(&self, outpoint: bitcoin::OutPoint) -> FederationResult<bool>;
33
34    async fn activate_consensus_version_voting(&self, auth: ApiAuth) -> FederationResult<()>;
35}
36
37#[apply(async_trait_maybe_send!)]
38impl<T: ?Sized> WalletFederationApi for T
39where
40    T: IModuleFederationApi + MaybeSend + MaybeSync + 'static,
41{
42    async fn module_consensus_version(&self) -> FederationResult<ModuleConsensusVersion> {
43        let response = self
44            .request_current_consensus(
45                MODULE_CONSENSUS_VERSION_ENDPOINT.to_string(),
46                ApiRequestErased::default(),
47            )
48            .await;
49
50        if let Err(e) = &response {
51            if e.any_peer_error_method_not_found() {
52                return Ok(ModuleConsensusVersion::new(2, 0));
53            }
54        }
55
56        response
57    }
58
59    async fn is_utxo_confirmed(&self, outpoint: bitcoin::OutPoint) -> FederationResult<bool> {
60        let res = self
61            .request_current_consensus(
62                UTXO_CONFIRMED_ENDPOINT.to_string(),
63                ApiRequestErased::new(outpoint),
64            )
65            .await;
66
67        if let Err(e) = &res {
68            if e.any_peer_error_method_not_found() {
69                return Ok(false);
70            }
71        }
72
73        res
74    }
75
76    async fn fetch_consensus_block_count(&self) -> FederationResult<u64> {
77        self.request_current_consensus(
78            BLOCK_COUNT_ENDPOINT.to_string(),
79            ApiRequestErased::default(),
80        )
81        .await
82    }
83
84    async fn fetch_peg_out_fees(
85        &self,
86        address: &Address,
87        amount: Amount,
88    ) -> FederationResult<Option<PegOutFees>> {
89        self.request_current_consensus(
90            PEG_OUT_FEES_ENDPOINT.to_string(),
91            ApiRequestErased::new((address, amount.to_sat())),
92        )
93        .await
94    }
95
96    async fn fetch_bitcoin_rpc_kind(&self, peer_id: PeerId) -> FederationResult<String> {
97        self.request_single_peer_federation(
98            BITCOIN_KIND_ENDPOINT.to_string(),
99            ApiRequestErased::default(),
100            peer_id,
101        )
102        .await
103    }
104
105    async fn fetch_bitcoin_rpc_config(&self, auth: ApiAuth) -> FederationResult<BitcoinRpcConfig> {
106        self.request_admin(
107            BITCOIN_RPC_CONFIG_ENDPOINT,
108            ApiRequestErased::default(),
109            auth,
110        )
111        .await
112    }
113
114    async fn fetch_wallet_summary(&self) -> FederationResult<WalletSummary> {
115        self.request_current_consensus(
116            WALLET_SUMMARY_ENDPOINT.to_string(),
117            ApiRequestErased::default(),
118        )
119        .await
120    }
121
122    async fn activate_consensus_version_voting(&self, auth: ApiAuth) -> FederationResult<()> {
123        self.request_admin(
124            ACTIVATE_CONSENSUS_VERSION_VOTING_ENDPOINT,
125            ApiRequestErased::default(),
126            auth,
127        )
128        .await
129    }
130}