1
2use bitcoin::{Amount, FeeRate, Txid};
3use bitcoin::consensus::encode::serialize_hex;
4use bitcoin::secp256k1::PublicKey;
5use serde::{Deserialize, Serialize};
6
7use ark::VtxoId;
8use ark::offboard::OffboardRequest;
9use ark::tree::signed::UnlockHash;
10use ark::vtxo::VtxoPolicyKind;
11
12#[cfg(feature = "utoipa")]
13use utoipa::ToSchema;
14
15use crate::cli::RoundStatus;
16
17
18#[derive(Serialize, Deserialize)]
20#[cfg_attr(feature = "utoipa", derive(ToSchema))]
21pub struct FeeEstimateQuery {
22 pub amount_sat: u64,
24}
25
26#[derive(Serialize, Deserialize)]
28#[cfg_attr(feature = "utoipa", derive(ToSchema))]
29pub struct SendOnchainFeeEstimateQuery {
30 pub amount_sat: u64,
32 pub address: String,
34}
35
36#[derive(Serialize, Deserialize)]
38#[cfg_attr(feature = "utoipa", derive(ToSchema))]
39pub struct OffboardAllFeeEstimateQuery {
40 pub address: String,
42}
43
44#[derive(Serialize, Deserialize)]
46#[cfg_attr(feature = "utoipa", derive(ToSchema))]
47pub struct FeeEstimateResponse {
48 #[serde(rename = "gross_amount_sat", with = "bitcoin::amount::serde::as_sat")]
50 #[cfg_attr(feature = "utoipa", schema(value_type = u64))]
51 pub gross_amount: Amount,
52 #[serde(rename = "fee_sat", with = "bitcoin::amount::serde::as_sat")]
54 #[cfg_attr(feature = "utoipa", schema(value_type = u64))]
55 pub fee: Amount,
56 #[serde(rename = "net_amount_sat", with = "bitcoin::amount::serde::as_sat")]
59 #[cfg_attr(feature = "utoipa", schema(value_type = u64))]
60 pub net_amount: Amount,
61 #[cfg_attr(feature = "utoipa", schema(value_type = Vec<String>))]
63 pub vtxos_spent: Vec<VtxoId>,
64}
65
66impl From<bark::FeeEstimate> for FeeEstimateResponse {
67 fn from(estimate: bark::FeeEstimate) -> Self {
68 FeeEstimateResponse {
69 gross_amount: estimate.gross_amount,
70 fee: estimate.fee,
71 net_amount: estimate.net_amount,
72 vtxos_spent: estimate.vtxos_spent,
73 }
74 }
75}
76
77#[derive(Serialize, Deserialize)]
79#[cfg_attr(feature = "utoipa", derive(ToSchema))]
80pub struct OnchainFeeRatesResponse {
81 pub fast_sat_per_vb: u64,
83 pub regular_sat_per_vb: u64,
85 pub slow_sat_per_vb: u64,
87}
88
89
90#[derive(Serialize, Deserialize)]
91#[cfg_attr(feature = "utoipa", derive(ToSchema))]
92pub struct TipResponse {
93 pub tip_height: u32,
94}
95
96#[derive(Serialize, Deserialize)]
97#[cfg_attr(feature = "utoipa", derive(ToSchema))]
98pub struct MailboxSyncResponse {
99 pub checkpoint: u64,
102}
103
104#[derive(Serialize, Deserialize)]
105#[cfg_attr(feature = "utoipa", derive(ToSchema))]
106pub struct CreateWalletRequest {
107 pub ark_server: Option<String>,
110 pub ark_server_access_token: Option<String>,
112 pub chain_source: Option<ChainSourceConfig>,
115 pub mnemonic: Option<String>,
117 pub network: BarkNetwork,
119 pub birthday_height: Option<u32>,
121}
122
123#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
125#[serde(rename_all = "kebab-case")]
126#[cfg_attr(feature = "utoipa", derive(ToSchema))]
127pub enum BarkNetwork {
128 Mainnet,
130 Signet,
132 Mutinynet,
134 Regtest,
136}
137
138#[derive(Serialize, Deserialize)]
139#[serde(rename_all = "kebab-case")]
140#[cfg_attr(feature = "utoipa", derive(ToSchema))]
141pub enum ChainSourceConfig {
142 Bitcoind {
144 bitcoind: String,
145 bitcoind_auth: BitcoindAuth,
146 },
147 Esplora {
149 url: String,
150 },
151}
152
153#[derive(Serialize, Deserialize)]
154#[serde(rename_all = "kebab-case")]
155#[cfg_attr(feature = "utoipa", derive(ToSchema))]
156pub enum BitcoindAuth {
157 Cookie {
159 cookie: String,
160 },
161 UserPass {
163 user: String,
164 pass: String,
165 },
166}
167
168#[derive(Serialize, Deserialize)]
169#[cfg_attr(feature = "utoipa", derive(ToSchema))]
170pub struct CreateWalletResponse {
171 pub fingerprint: String,
172}
173
174#[derive(Serialize, Deserialize)]
175#[cfg_attr(feature = "utoipa", derive(ToSchema))]
176pub struct ConnectedResponse {
177 pub connected: bool,
179}
180
181#[derive(Serialize, Deserialize)]
182#[cfg_attr(feature = "utoipa", derive(ToSchema))]
183pub struct MnemonicResponse {
184 pub mnemonic: String,
186}
187
188#[derive(Serialize, Deserialize)]
189#[cfg_attr(feature = "utoipa", derive(ToSchema))]
190pub struct ArkAddressResponse {
191 #[cfg_attr(feature = "utoipa", schema(value_type = String))]
192 pub address: String,
193}
194
195#[derive(Serialize, Deserialize)]
200#[cfg_attr(feature = "utoipa", derive(ToSchema))]
201pub struct EncodedVtxoResponse {
202 pub encoded: crate::primitives::EncodedVtxo,
204}
205
206#[derive(Serialize, Deserialize)]
207#[cfg_attr(feature = "utoipa", derive(ToSchema))]
208pub struct VtxosQuery {
209 pub all: Option<bool>,
211}
212
213#[derive(Serialize, Deserialize)]
214#[cfg_attr(feature = "utoipa", derive(ToSchema))]
215pub struct RefreshRequest {
216 pub vtxos: Vec<String>,
221}
222
223#[derive(Serialize, Deserialize)]
224#[cfg_attr(feature = "utoipa", derive(ToSchema))]
225pub struct BoardRequest {
226 pub amount_sat: u64,
230}
231
232#[derive(Serialize, Deserialize)]
233#[cfg_attr(feature = "utoipa", derive(ToSchema))]
234pub struct SendRequest {
235 pub destination: String,
237 pub amount_sat: Option<u64>,
241 pub comment: Option<String>,
243}
244
245#[derive(Serialize, Deserialize)]
246#[cfg_attr(feature = "utoipa", derive(ToSchema))]
247pub struct SendResponse {
248 pub message: String,
250}
251
252#[derive(Serialize, Deserialize)]
253#[cfg_attr(feature = "utoipa", derive(ToSchema))]
254pub struct SendOnchainRequest {
255 pub destination: String,
257 pub amount_sat: u64,
261}
262
263#[derive(Serialize, Deserialize)]
264#[cfg_attr(feature = "utoipa", derive(ToSchema))]
265pub struct OffboardVtxosRequest {
266 pub address: Option<String>,
268 pub vtxos: Vec<String>,
272}
273
274#[derive(Serialize, Deserialize)]
275#[cfg_attr(feature = "utoipa", derive(ToSchema))]
276pub struct OffboardAllRequest {
277 pub address: Option<String>,
279}
280
281#[derive(Serialize, Deserialize)]
282#[cfg_attr(feature = "utoipa", derive(ToSchema))]
283pub struct ImportVtxoRequest {
284 pub vtxos: Vec<String>,
286}
287
288#[derive(Serialize, Deserialize)]
289#[cfg_attr(feature = "utoipa", derive(ToSchema))]
290pub struct LightningInvoiceRequest {
291 pub amount_sat: u64,
295 #[serde(default, skip_serializing_if = "Option::is_none")]
297 pub description: Option<String>,
298}
299
300#[derive(Serialize, Deserialize)]
301#[cfg_attr(feature = "utoipa", derive(ToSchema))]
302pub struct LightningPayRequest {
303 pub destination: String,
305 pub amount_sat: Option<u64>,
310 pub comment: Option<String>,
312}
313
314#[derive(Serialize, Deserialize)]
315#[cfg_attr(feature = "utoipa", derive(ToSchema))]
316pub struct LightningPayResponse {
317 pub message: String,
319}
320
321#[derive(Serialize, Deserialize)]
322#[cfg_attr(feature = "utoipa", derive(ToSchema))]
323pub struct OnchainSendRequest {
324 pub destination: String,
326 pub amount_sat: u64,
328}
329
330#[derive(Serialize, Deserialize)]
331#[cfg_attr(feature = "utoipa", derive(ToSchema))]
332pub struct OnchainSendManyRequest {
333 pub destinations: Vec<String>,
335 pub immediate: Option<bool>,
337}
338
339#[derive(Serialize, Deserialize)]
340#[cfg_attr(feature = "utoipa", derive(ToSchema))]
341pub struct OnchainDrainRequest {
342 pub destination: String,
344}
345
346#[derive(Serialize, Deserialize)]
347#[cfg_attr(feature = "utoipa", derive(ToSchema))]
348pub struct ExitStatusRequest {
349 pub history: Option<bool>,
351 pub transactions: Option<bool>,
353}
354
355#[derive(Serialize, Deserialize)]
356#[cfg_attr(feature = "utoipa", derive(ToSchema))]
357pub struct ExitStartRequest {
358 pub vtxos: Vec<String>,
360}
361
362#[derive(Serialize, Deserialize)]
363#[cfg_attr(feature = "utoipa", derive(ToSchema))]
364pub struct ExitStartResponse {
365 pub message: String,
366}
367
368#[derive(Serialize, Deserialize)]
369#[cfg_attr(feature = "utoipa", derive(ToSchema))]
370pub struct ExitProgressRequest {
371 pub wait: Option<bool>,
373 pub fee_rate: Option<u64>,
375}
376
377#[derive(Serialize, Deserialize)]
378#[cfg_attr(feature = "utoipa", derive(ToSchema))]
379pub struct ExitClaimAllRequest {
380 pub destination: String,
382 pub fee_rate: Option<u64>,
384}
385
386#[derive(Serialize, Deserialize)]
387#[cfg_attr(feature = "utoipa", derive(ToSchema))]
388pub struct ExitClaimVtxosRequest {
389 pub destination: String,
391 pub vtxos: Vec<String>,
393 pub fee_rate: Option<u64>,
395}
396
397#[derive(Serialize, Deserialize)]
398#[cfg_attr(feature = "utoipa", derive(ToSchema))]
399pub struct ExitClaimResponse {
400 pub message: String,
401}
402
403
404#[derive(Serialize, Deserialize)]
405#[cfg_attr(feature = "utoipa", derive(ToSchema))]
406pub struct VtxoRequestInfo {
407 #[serde(rename = "amount_sat", with = "bitcoin::amount::serde::as_sat")]
408 #[cfg_attr(feature = "utoipa", schema(value_type = u64))]
409 pub amount: Amount,
410 #[cfg_attr(feature = "utoipa", schema(value_type = String))]
411 pub policy_type: VtxoPolicyKind,
412 #[cfg_attr(feature = "utoipa", schema(value_type = String))]
413 pub user_pubkey: PublicKey,
414}
415
416impl<'a> From<&'a ark::VtxoRequest> for VtxoRequestInfo {
417 fn from(v: &'a ark::VtxoRequest) -> Self {
418 Self {
419 amount: v.amount,
420 policy_type: v.policy.policy_type(),
421 user_pubkey: v.policy.user_pubkey(),
422 }
423 }
424}
425
426#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
427#[cfg_attr(feature = "utoipa", derive(ToSchema))]
428pub struct OffboardRequestInfo {
429 pub script_pubkey_hex: String,
431 pub script_pubkey_asm: String,
433 #[serde(rename = "net_amount_sat", with = "bitcoin::amount::serde::as_sat")]
435 #[cfg_attr(feature = "utoipa", schema(value_type = u64))]
436 pub net_amount: Amount,
437 pub deduct_fees_from_gross_amount: bool,
439 #[serde(rename = "fee_rate_kwu")]
441 #[cfg_attr(feature = "utoipa", schema(value_type = u64))]
442 pub fee_rate: FeeRate,
443}
444
445impl<'a> From<&'a OffboardRequest> for OffboardRequestInfo {
446 fn from(v: &'a OffboardRequest) -> Self {
447 Self {
448 script_pubkey_hex: v.script_pubkey.to_hex_string(),
449 script_pubkey_asm: v.script_pubkey.to_asm_string(),
450 net_amount: v.net_amount,
451 deduct_fees_from_gross_amount: v.deduct_fees_from_gross_amount,
452 fee_rate: v.fee_rate,
453 }
454 }
455}
456
457#[derive(Serialize, Deserialize)]
458#[cfg_attr(feature = "utoipa", derive(ToSchema))]
459pub struct RoundParticipationInfo {
460 #[cfg_attr(feature = "utoipa", schema(value_type = Vec<String>))]
461 pub inputs: Vec<VtxoId>,
462 pub outputs: Vec<VtxoRequestInfo>,
463}
464
465impl<'a> From<&'a bark::round::RoundParticipation> for RoundParticipationInfo {
466 fn from(v: &'a bark::round::RoundParticipation) -> Self {
467 Self {
468 inputs: v.inputs.iter().map(|v| v.id()).collect(),
469 outputs: v.outputs.iter().map(Into::into).collect(),
470 }
471 }
472}
473
474#[derive(Serialize, Deserialize)]
475#[cfg_attr(feature = "utoipa", derive(ToSchema))]
476pub struct PendingRoundInfo {
477 pub id: u32,
479 pub status: RoundStatus,
481 pub participation: RoundParticipationInfo,
483 #[cfg_attr(feature = "utoipa", schema(value_type = String, nullable = true))]
484 pub unlock_hash: Option<UnlockHash>,
485 #[cfg_attr(feature = "utoipa", schema(value_type = String, nullable = true))]
487 pub funding_txid: Option<Txid>,
488 pub funding_tx_hex: Option<String>,
489}
490
491impl PendingRoundInfo {
492 pub fn new<'a>(
493 state: &'a bark::persist::models::StoredRoundState,
494 sync_result: anyhow::Result<bark::round::RoundStatus>,
495 ) -> Self {
496 let funding_tx = state.state().funding_tx();
497 Self {
498 id: state.id().0,
499 status: match sync_result {
500 Ok(status) => status.into(),
501 Err(e) => RoundStatus::SyncError {
502 error: format!("{:#}", e),
503 },
504 },
505 participation: state.state().participation().into(),
506 unlock_hash: state.state().unlock_hash(),
507 funding_txid: funding_tx.map(|t| t.compute_txid()),
508 funding_tx_hex: funding_tx.map(|t| serialize_hex(t)),
509 }
510 }
511}
512
513#[derive(Serialize, Deserialize)]
514#[cfg_attr(feature = "utoipa", derive(ToSchema))]
515pub struct WalletExistsResponse {
516 pub fingerprint: Option<String>,
517}
518
519#[derive(Serialize, Deserialize)]
520#[cfg_attr(feature = "utoipa", derive(ToSchema))]
521pub struct WalletDeleteRequest {
522 pub dangerous: bool,
523 pub fingerprint: String,
524}
525
526#[derive(Serialize, Deserialize)]
527#[cfg_attr(feature = "utoipa", derive(ToSchema))]
528pub struct WalletDeleteResponse {
529 pub deleted: bool,
530 pub message: String,
531}
532