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(Default, Serialize, Deserialize)]
24#[cfg_attr(feature = "utoipa", derive(ToSchema))]
25pub struct HistoryQuery {
26 #[serde(rename = "type")]
30 pub method_type: Option<String>,
31 pub value: Option<String>,
34}
35
36#[derive(Serialize, Deserialize)]
38#[cfg_attr(feature = "utoipa", derive(ToSchema))]
39pub struct FeeEstimateQuery {
40 pub amount_sat: u64,
42}
43
44#[derive(Serialize, Deserialize)]
46#[cfg_attr(feature = "utoipa", derive(ToSchema))]
47pub struct SendOnchainFeeEstimateQuery {
48 pub amount_sat: u64,
50 pub address: String,
52}
53
54#[derive(Serialize, Deserialize)]
56#[cfg_attr(feature = "utoipa", derive(ToSchema))]
57pub struct OffboardAllFeeEstimateQuery {
58 pub address: String,
60}
61
62#[derive(Serialize, Deserialize)]
64#[cfg_attr(feature = "utoipa", derive(ToSchema))]
65pub struct OffboardFeeEstimateRequest {
66 pub address: String,
68 pub vtxos: Vec<String>,
70}
71
72#[derive(Serialize, Deserialize)]
74#[cfg_attr(feature = "utoipa", derive(ToSchema))]
75pub struct FeeEstimateResponse {
76 #[serde(rename = "gross_amount_sat", with = "bitcoin::amount::serde::as_sat")]
78 #[cfg_attr(feature = "utoipa", schema(value_type = u64))]
79 pub gross_amount: Amount,
80 #[serde(rename = "fee_sat", with = "bitcoin::amount::serde::as_sat")]
82 #[cfg_attr(feature = "utoipa", schema(value_type = u64))]
83 pub fee: Amount,
84 #[serde(rename = "net_amount_sat", with = "bitcoin::amount::serde::as_sat")]
87 #[cfg_attr(feature = "utoipa", schema(value_type = u64))]
88 pub net_amount: Amount,
89 #[cfg_attr(feature = "utoipa", schema(value_type = Vec<String>))]
91 pub vtxos_spent: Vec<VtxoId>,
92}
93
94impl From<bark::FeeEstimate> for FeeEstimateResponse {
95 fn from(estimate: bark::FeeEstimate) -> Self {
96 FeeEstimateResponse {
97 gross_amount: estimate.gross_amount,
98 fee: estimate.fee,
99 net_amount: estimate.net_amount,
100 vtxos_spent: estimate.vtxos_spent,
101 }
102 }
103}
104
105#[derive(Serialize, Deserialize)]
107#[cfg_attr(feature = "utoipa", derive(ToSchema))]
108pub struct OnchainFeeRatesResponse {
109 pub fast_sat_per_vb: u64,
111 pub regular_sat_per_vb: u64,
113 pub slow_sat_per_vb: u64,
115}
116
117
118#[derive(Serialize, Deserialize)]
119#[cfg_attr(feature = "utoipa", derive(ToSchema))]
120pub struct TipResponse {
121 pub tip_height: u32,
122}
123
124#[derive(Serialize, Deserialize)]
125#[cfg_attr(feature = "utoipa", derive(ToSchema))]
126pub struct MailboxSyncResponse {
127 pub checkpoint: u64,
130}
131
132#[derive(Serialize, Deserialize)]
133#[cfg_attr(feature = "utoipa", derive(ToSchema))]
134pub struct CreateWalletRequest {
135 pub ark_server: Option<String>,
138 #[deprecated(
143 since = "0.2.4",
144 note = "access tokens are not enforced by the server; this field will be removed",
145 )]
146 pub ark_server_access_token: Option<String>,
147 pub chain_source: Option<ChainSourceConfig>,
150 pub mnemonic: Option<String>,
152 pub network: BarkNetwork,
154 pub birthday_height: Option<u32>,
156}
157
158#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
160#[serde(rename_all = "kebab-case")]
161#[cfg_attr(feature = "utoipa", derive(ToSchema))]
162pub enum BarkNetwork {
163 Mainnet,
165 Signet,
167 Mutinynet,
169 Regtest,
171}
172
173#[derive(Serialize, Deserialize)]
174#[serde(rename_all = "kebab-case")]
175#[cfg_attr(feature = "utoipa", derive(ToSchema))]
176pub enum ChainSourceConfig {
177 Bitcoind {
179 bitcoind: String,
180 bitcoind_auth: BitcoindAuth,
181 },
182 Esplora {
184 url: String,
185 },
186}
187
188#[derive(Serialize, Deserialize)]
189#[serde(rename_all = "kebab-case")]
190#[cfg_attr(feature = "utoipa", derive(ToSchema))]
191pub enum BitcoindAuth {
192 Cookie {
194 cookie: String,
195 },
196 UserPass {
198 user: String,
199 pass: String,
200 },
201}
202
203#[derive(Serialize, Deserialize)]
204#[cfg_attr(feature = "utoipa", derive(ToSchema))]
205pub struct CreateWalletResponse {
206 pub fingerprint: String,
207}
208
209#[derive(Serialize, Deserialize)]
210#[cfg_attr(feature = "utoipa", derive(ToSchema))]
211pub struct ConnectedResponse {
212 pub connected: bool,
214}
215
216#[derive(Serialize, Deserialize)]
217#[cfg_attr(feature = "utoipa", derive(ToSchema))]
218pub struct MnemonicResponse {
219 pub mnemonic: String,
221}
222
223#[derive(Serialize, Deserialize)]
224#[cfg_attr(feature = "utoipa", derive(ToSchema))]
225pub struct ArkAddressResponse {
226 #[cfg_attr(feature = "utoipa", schema(value_type = String))]
227 pub address: String,
228}
229
230#[derive(Serialize, Deserialize)]
236#[cfg_attr(feature = "utoipa", derive(ToSchema))]
237pub struct Bip321UriRequest {
238 #[serde(default, skip_serializing_if = "Option::is_none")]
243 pub amount_sat: Option<u64>,
244 #[serde(default, skip_serializing_if = "Option::is_none")]
247 pub onchain: Option<bool>,
248 #[serde(default, skip_serializing_if = "Option::is_none")]
250 pub label: Option<String>,
251 #[serde(default, skip_serializing_if = "Option::is_none")]
253 pub message: Option<String>,
254}
255
256#[derive(Serialize, Deserialize)]
258#[cfg_attr(feature = "utoipa", derive(ToSchema))]
259pub struct Bip321UriQuery {
260 pub uppercase: Option<bool>,
266}
267
268#[derive(Serialize, Deserialize)]
274#[cfg_attr(feature = "utoipa", derive(ToSchema))]
275pub struct Bip321UriResponse {
276 #[serde(skip_serializing_if = "Option::is_none")]
278 pub ark: Option<String>,
279 #[serde(skip_serializing_if = "Option::is_none")]
281 pub bolt11: Option<String>,
282 #[serde(skip_serializing_if = "Option::is_none")]
284 pub onchain: Option<String>,
285 pub bip321: String,
287}
288
289#[derive(Serialize, Deserialize)]
294#[cfg_attr(feature = "utoipa", derive(ToSchema))]
295pub struct EncodedVtxoResponse {
296 pub encoded: crate::primitives::EncodedVtxo,
298}
299
300#[derive(Serialize, Deserialize)]
301#[cfg_attr(feature = "utoipa", derive(ToSchema))]
302pub struct VtxosQuery {
303 pub all: Option<bool>,
305}
306
307#[derive(Serialize, Deserialize)]
308#[cfg_attr(feature = "utoipa", derive(ToSchema))]
309pub struct RefreshRequest {
310 pub vtxos: Vec<String>,
315}
316
317#[derive(Serialize, Deserialize)]
318#[cfg_attr(feature = "utoipa", derive(ToSchema))]
319pub struct DelegatedRefreshRequest {
320 pub vtxos: Vec<String>,
325 pub height: Option<u32>,
329}
330
331#[derive(Serialize, Deserialize)]
332#[cfg_attr(feature = "utoipa", derive(ToSchema))]
333pub struct BoardRequest {
334 pub amount_sat: u64,
338}
339
340#[derive(Serialize, Deserialize)]
341#[cfg_attr(feature = "utoipa", derive(ToSchema))]
342pub struct SendRequest {
343 pub destination: String,
345 pub amount_sat: Option<u64>,
349 pub comment: Option<String>,
351}
352
353#[derive(Serialize, Deserialize)]
354#[cfg_attr(feature = "utoipa", derive(ToSchema))]
355pub struct SendResponse {
356 pub message: String,
358}
359
360#[derive(Serialize, Deserialize)]
361#[cfg_attr(feature = "utoipa", derive(ToSchema))]
362pub struct SendOnchainRequest {
363 pub destination: String,
365 pub amount_sat: u64,
369}
370
371#[derive(Serialize, Deserialize)]
372#[cfg_attr(feature = "utoipa", derive(ToSchema))]
373pub struct OffboardVtxosRequest {
374 pub address: Option<String>,
376 pub vtxos: Vec<String>,
380}
381
382#[derive(Serialize, Deserialize)]
383#[cfg_attr(feature = "utoipa", derive(ToSchema))]
384pub struct OffboardAllRequest {
385 pub address: Option<String>,
387}
388
389#[derive(Serialize, Deserialize)]
390#[cfg_attr(feature = "utoipa", derive(ToSchema))]
391pub struct ImportVtxoRequest {
392 pub vtxos: Vec<String>,
394}
395
396#[derive(Serialize, Deserialize)]
397#[cfg_attr(feature = "utoipa", derive(ToSchema))]
398pub struct LightningInvoiceRequest {
399 pub amount_sat: u64,
403 #[serde(default, skip_serializing_if = "Option::is_none")]
405 pub description: Option<String>,
406}
407
408#[derive(Serialize, Deserialize)]
409#[cfg_attr(feature = "utoipa", derive(ToSchema))]
410pub struct LightningInvoiceForAddressRequest {
411 pub amount_sat: u64,
413 pub address: String,
415 #[serde(default, skip_serializing_if = "Option::is_none")]
417 pub description: Option<String>,
418}
419
420#[derive(Serialize, Deserialize)]
421#[cfg_attr(feature = "utoipa", derive(ToSchema))]
422pub struct LightningPayRequest {
423 pub destination: String,
425 pub amount_sat: Option<u64>,
430 pub comment: Option<String>,
432}
433
434#[derive(Serialize, Deserialize)]
435#[cfg_attr(feature = "utoipa", derive(ToSchema))]
436pub struct LightningPayResponse {
437 pub message: String,
439}
440
441#[derive(Serialize, Deserialize)]
442#[cfg_attr(feature = "utoipa", derive(ToSchema))]
443pub struct OnchainSendRequest {
444 pub destination: String,
446 pub amount_sat: u64,
448}
449
450#[derive(Serialize, Deserialize)]
451#[cfg_attr(feature = "utoipa", derive(ToSchema))]
452pub struct OnchainSendManyRequest {
453 pub destinations: Vec<String>,
455 pub immediate: Option<bool>,
457}
458
459#[derive(Serialize, Deserialize)]
460#[cfg_attr(feature = "utoipa", derive(ToSchema))]
461pub struct OnchainDrainRequest {
462 pub destination: String,
464}
465
466#[derive(Serialize, Deserialize)]
467#[cfg_attr(feature = "utoipa", derive(ToSchema))]
468pub struct ExitStatusRequest {
469 pub history: Option<bool>,
471 pub transactions: Option<bool>,
473}
474
475#[derive(Serialize, Deserialize)]
476#[cfg_attr(feature = "utoipa", derive(ToSchema))]
477pub struct ExitStartRequest {
478 pub vtxos: Vec<String>,
480}
481
482#[derive(Serialize, Deserialize)]
483#[cfg_attr(feature = "utoipa", derive(ToSchema))]
484pub struct ExitStartResponse {
485 pub message: String,
486}
487
488#[derive(Serialize, Deserialize)]
489#[cfg_attr(feature = "utoipa", derive(ToSchema))]
490pub struct ExitProgressRequest {
491 pub wait: Option<bool>,
493 pub fee_rate: Option<u64>,
495}
496
497#[derive(Serialize, Deserialize)]
498#[cfg_attr(feature = "utoipa", derive(ToSchema))]
499pub struct ExitClaimAllRequest {
500 pub destination: String,
502 pub fee_rate: Option<u64>,
504}
505
506#[derive(Serialize, Deserialize)]
507#[cfg_attr(feature = "utoipa", derive(ToSchema))]
508pub struct ExitClaimVtxosRequest {
509 pub destination: String,
511 pub vtxos: Vec<String>,
513 pub fee_rate: Option<u64>,
515}
516
517#[derive(Serialize, Deserialize)]
518#[cfg_attr(feature = "utoipa", derive(ToSchema))]
519pub struct ExitClaimResponse {
520 pub message: String,
521}
522
523#[derive(Serialize, Deserialize)]
524#[cfg_attr(feature = "utoipa", derive(ToSchema))]
525pub struct ExitCancelResponse {
526 pub message: String,
527}
528
529
530#[derive(Serialize, Deserialize)]
531#[cfg_attr(feature = "utoipa", derive(ToSchema))]
532pub struct VtxoRequestInfo {
533 #[serde(rename = "amount_sat", with = "bitcoin::amount::serde::as_sat")]
534 #[cfg_attr(feature = "utoipa", schema(value_type = u64))]
535 pub amount: Amount,
536 #[cfg_attr(feature = "utoipa", schema(value_type = String))]
537 pub policy_type: VtxoPolicyKind,
538 #[cfg_attr(feature = "utoipa", schema(value_type = String))]
539 pub user_pubkey: PublicKey,
540}
541
542impl<'a> From<&'a ark::VtxoRequest> for VtxoRequestInfo {
543 fn from(v: &'a ark::VtxoRequest) -> Self {
544 Self {
545 amount: v.amount,
546 policy_type: v.policy.policy_type(),
547 user_pubkey: v.policy.user_pubkey(),
548 }
549 }
550}
551
552#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
553#[cfg_attr(feature = "utoipa", derive(ToSchema))]
554pub struct OffboardRequestInfo {
555 pub script_pubkey_hex: String,
557 pub script_pubkey_asm: String,
559 #[serde(rename = "net_amount_sat", with = "bitcoin::amount::serde::as_sat")]
561 #[cfg_attr(feature = "utoipa", schema(value_type = u64))]
562 pub net_amount: Amount,
563 pub deduct_fees_from_gross_amount: bool,
565 #[serde(rename = "fee_rate_kwu")]
567 #[cfg_attr(feature = "utoipa", schema(value_type = u64))]
568 pub fee_rate: FeeRate,
569}
570
571impl<'a> From<&'a OffboardRequest> for OffboardRequestInfo {
572 fn from(v: &'a OffboardRequest) -> Self {
573 Self {
574 script_pubkey_hex: v.script_pubkey.to_hex_string(),
575 script_pubkey_asm: v.script_pubkey.to_asm_string(),
576 net_amount: v.net_amount,
577 deduct_fees_from_gross_amount: v.deduct_fees_from_gross_amount,
578 fee_rate: v.fee_rate,
579 }
580 }
581}
582
583#[derive(Serialize, Deserialize)]
584#[cfg_attr(feature = "utoipa", derive(ToSchema))]
585pub struct RoundParticipationInfo {
586 #[cfg_attr(feature = "utoipa", schema(value_type = Vec<String>))]
587 pub inputs: Vec<VtxoId>,
588 pub outputs: Vec<VtxoRequestInfo>,
589}
590
591impl<'a> From<&'a bark::round::RoundParticipation> for RoundParticipationInfo {
592 fn from(v: &'a bark::round::RoundParticipation) -> Self {
593 Self {
594 inputs: v.inputs.iter().map(|v| v.id()).collect(),
595 outputs: v.outputs.iter().map(Into::into).collect(),
596 }
597 }
598}
599
600#[derive(Serialize, Deserialize)]
601#[cfg_attr(feature = "utoipa", derive(ToSchema))]
602pub struct PendingRoundInfo {
603 pub id: u32,
605 pub status: RoundStatus,
607 pub participation: RoundParticipationInfo,
609 #[cfg_attr(feature = "utoipa", schema(value_type = String, nullable = true))]
610 pub unlock_hash: Option<UnlockHash>,
611 #[cfg_attr(feature = "utoipa", schema(value_type = String, nullable = true))]
613 pub funding_txid: Option<Txid>,
614 pub funding_tx_hex: Option<String>,
615}
616
617impl PendingRoundInfo {
618 pub fn new<G>(
619 state: &bark::persist::models::StoredRoundState<G>,
620 sync_result: anyhow::Result<bark::round::RoundStatus>,
621 ) -> Self {
622 let funding_tx = state.state().funding_tx();
623 Self {
624 id: state.id().0,
625 status: match sync_result {
626 Ok(status) => status.into(),
627 Err(e) => RoundStatus::SyncError {
628 error: format!("{:#}", e),
629 },
630 },
631 participation: state.state().participation().into(),
632 unlock_hash: state.state().unlock_hash(),
633 funding_txid: funding_tx.map(|t| t.compute_txid()),
634 funding_tx_hex: funding_tx.map(|t| serialize_hex(t)),
635 }
636 }
637}
638
639#[derive(Serialize, Deserialize)]
640#[cfg_attr(feature = "utoipa", derive(ToSchema))]
641pub struct WalletExistsResponse {
642 pub fingerprint: Option<String>,
643}
644
645#[derive(Serialize, Deserialize)]
646#[cfg_attr(feature = "utoipa", derive(ToSchema))]
647pub struct WalletDeleteRequest {
648 pub dangerous: bool,
649 pub fingerprint: String,
650}
651
652#[derive(Serialize, Deserialize)]
653#[cfg_attr(feature = "utoipa", derive(ToSchema))]
654pub struct WalletDeleteResponse {
655 pub deleted: bool,
656 pub message: String,
657}