fedimint_wallet_client/
api.rs1use 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}