1use async_trait::async_trait;
2
3use moksha_core::{
4 blind::BlindedMessage,
5 keyset::V1Keysets,
6 primitives::{
7 CurrencyUnit, GetMeltOnchainResponse, KeysResponse, MintInfoResponse,
8 PostMeltBolt11Request, PostMeltBolt11Response, PostMeltOnchainRequest,
9 PostMeltOnchainResponse, PostMeltQuoteBolt11Request, PostMeltQuoteBolt11Response,
10 PostMeltQuoteOnchainRequest, PostMeltQuoteOnchainResponse, PostMintBolt11Request,
11 PostMintBolt11Response, PostMintOnchainRequest, PostMintOnchainResponse,
12 PostMintQuoteBolt11Request, PostMintQuoteBolt11Response, PostMintQuoteOnchainRequest,
13 PostMintQuoteOnchainResponse, PostSwapRequest, PostSwapResponse,
14 },
15 proof::Proofs,
16};
17
18use url::Url;
19
20use crate::{error::MokshaWalletError, http::CrossPlatformHttpClient};
21
22use super::CashuClient;
23
24#[async_trait(?Send)]
25impl CashuClient for CrossPlatformHttpClient {
26 async fn get_keys(&self, mint_url: &Url) -> Result<KeysResponse, MokshaWalletError> {
27 self.do_get(&mint_url.join("v1/keys")?).await
28 }
29
30 async fn get_keys_by_id(
31 &self,
32 mint_url: &Url,
33 keyset_id: String,
34 ) -> Result<KeysResponse, MokshaWalletError> {
35 self.do_get(&mint_url.join(&format!("v1/keys/{}", keyset_id))?)
36 .await
37 }
38
39 async fn get_keysets(&self, mint_url: &Url) -> Result<V1Keysets, MokshaWalletError> {
40 self.do_get(&mint_url.join("v1/keysets")?).await
41 }
42
43 async fn post_swap(
44 &self,
45 mint_url: &Url,
46 inputs: Proofs,
47 outputs: Vec<BlindedMessage>,
48 ) -> Result<PostSwapResponse, MokshaWalletError> {
49 let body = PostSwapRequest { inputs, outputs };
50
51 self.do_post(&mint_url.join("v1/swap")?, &body).await
52 }
53
54 async fn post_melt_bolt11(
55 &self,
56 mint_url: &Url,
57 inputs: Proofs,
58 quote: String,
59 outputs: Vec<BlindedMessage>,
60 ) -> Result<PostMeltBolt11Response, MokshaWalletError> {
61 let body = PostMeltBolt11Request {
62 quote,
63 inputs,
64 outputs,
65 };
66
67 self.do_post(&mint_url.join("v1/melt/bolt11")?, &body).await
68 }
69
70 async fn post_melt_quote_bolt11(
71 &self,
72 mint_url: &Url,
73 payment_request: String,
74 unit: CurrencyUnit,
75 ) -> Result<PostMeltQuoteBolt11Response, MokshaWalletError> {
76 let body = PostMeltQuoteBolt11Request {
77 request: payment_request,
78 unit,
79 };
80
81 self.do_post(&mint_url.join("v1/melt/quote/bolt11")?, &body)
82 .await
83 }
84
85 async fn get_melt_quote_bolt11(
86 &self,
87 mint_url: &Url,
88 quote: String,
89 ) -> Result<PostMeltQuoteBolt11Response, MokshaWalletError> {
90 let url = mint_url.join(&format!("v1/melt/quote/bolt11/{}", quote))?;
91 self.do_get(&url).await
92 }
93
94 async fn post_mint_bolt11(
95 &self,
96 mint_url: &Url,
97 quote: String,
98 blinded_messages: Vec<BlindedMessage>,
99 ) -> Result<PostMintBolt11Response, MokshaWalletError> {
100 let body = PostMintBolt11Request {
101 quote,
102 outputs: blinded_messages,
103 };
104 self.do_post(&mint_url.join("v1/mint/bolt11")?, &body).await
105 }
106
107 async fn post_mint_quote_bolt11(
108 &self,
109 mint_url: &Url,
110 amount: u64,
111 unit: CurrencyUnit,
112 ) -> Result<PostMintQuoteBolt11Response, MokshaWalletError> {
113 let body = PostMintQuoteBolt11Request { amount, unit };
114 self.do_post(&mint_url.join("v1/mint/quote/bolt11")?, &body)
115 .await
116 }
117
118 async fn get_mint_quote_bolt11(
119 &self,
120 mint_url: &Url,
121 quote: String,
122 ) -> Result<PostMintQuoteBolt11Response, MokshaWalletError> {
123 self.do_get(&mint_url.join(&format!("v1/mint/quote/bolt11/{}", quote))?)
124 .await
125 }
126
127 async fn post_mint_onchain(
128 &self,
129 mint_url: &Url,
130 quote: String,
131 blinded_messages: Vec<BlindedMessage>,
132 ) -> Result<PostMintOnchainResponse, MokshaWalletError> {
133 let body = PostMintOnchainRequest {
134 quote,
135 outputs: blinded_messages,
136 };
137 self.do_post(&mint_url.join("v1/mint/btconchain")?, &body)
138 .await
139 }
140
141 async fn post_mint_quote_onchain(
142 &self,
143 mint_url: &Url,
144 amount: u64,
145 unit: CurrencyUnit,
146 ) -> Result<PostMintQuoteOnchainResponse, MokshaWalletError> {
147 let body = PostMintQuoteOnchainRequest { amount, unit };
148 self.do_post(&mint_url.join("v1/mint/quote/btconchain")?, &body)
149 .await
150 }
151
152 async fn get_mint_quote_onchain(
153 &self,
154 mint_url: &Url,
155 quote: String,
156 ) -> Result<PostMintQuoteOnchainResponse, MokshaWalletError> {
157 self.do_get(&mint_url.join(&format!("v1/mint/quote/btconchain/{}", quote))?)
158 .await
159 }
160
161 async fn get_info(&self, mint_url: &Url) -> Result<MintInfoResponse, MokshaWalletError> {
162 self.do_get(&mint_url.join("v1/info")?).await
163 }
164
165 async fn is_v1_supported(&self, mint_url: &Url) -> Result<bool, MokshaWalletError> {
166 self.get_status(&mint_url.join("v1/info")?)
167 .await
168 .map(|s| s == 200)
169 }
170
171 async fn post_melt_onchain(
172 &self,
173 mint_url: &Url,
174 inputs: Proofs,
175 quote: String,
176 ) -> Result<PostMeltOnchainResponse, MokshaWalletError> {
177 let body = PostMeltOnchainRequest { quote, inputs };
178 self.do_post(&mint_url.join("v1/melt/btconchain")?, &body)
179 .await
180 }
181
182 async fn post_melt_quote_onchain(
183 &self,
184 mint_url: &Url,
185 address: String,
186 amount: u64,
187 unit: CurrencyUnit,
188 ) -> Result<Vec<PostMeltQuoteOnchainResponse>, MokshaWalletError> {
189 let body = PostMeltQuoteOnchainRequest {
190 address,
191 amount,
192 unit,
193 };
194 self.do_post(&mint_url.join("v1/melt/quote/btconchain")?, &body)
195 .await
196 }
197
198 async fn get_melt_quote_onchain(
199 &self,
200 mint_url: &Url,
201 quote: String,
202 ) -> Result<PostMeltQuoteOnchainResponse, MokshaWalletError> {
203 self.do_get(&mint_url.join(&format!("/v1/melt/quote/btconchain/{quote}"))?)
204 .await
205 }
206
207 async fn get_melt_onchain(
208 &self,
209 mint_url: &Url,
210 txid: String,
211 ) -> Result<GetMeltOnchainResponse, MokshaWalletError> {
212 self.do_get(&mint_url.join(&format!("/v1/melt/btconchain/{txid}"))?)
213 .await
214 }
215}