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 #[serde(default)]
158 pub force: bool,
159}
160
161#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
163#[serde(rename_all = "kebab-case")]
164#[cfg_attr(feature = "utoipa", derive(ToSchema))]
165pub enum BarkNetwork {
166 Mainnet,
168 Signet,
170 Mutinynet,
172 Regtest,
174}
175
176#[derive(Serialize, Deserialize)]
177#[serde(rename_all = "kebab-case")]
178#[cfg_attr(feature = "utoipa", derive(ToSchema))]
179pub enum ChainSourceConfig {
180 Bitcoind {
182 bitcoind: String,
183 bitcoind_auth: BitcoindAuth,
184 },
185 Esplora {
187 url: String,
188 },
189}
190
191#[derive(Serialize, Deserialize)]
192#[serde(rename_all = "kebab-case")]
193#[cfg_attr(feature = "utoipa", derive(ToSchema))]
194pub enum BitcoindAuth {
195 Cookie {
197 cookie: String,
198 },
199 UserPass {
201 user: String,
202 pass: String,
203 },
204}
205
206#[derive(Serialize, Deserialize)]
207#[cfg_attr(feature = "utoipa", derive(ToSchema))]
208pub struct CreateWalletResponse {
209 pub fingerprint: String,
210}
211
212#[derive(Serialize, Deserialize)]
213#[cfg_attr(feature = "utoipa", derive(ToSchema))]
214pub struct ConnectedResponse {
215 pub connected: bool,
217}
218
219#[derive(Serialize, Deserialize)]
220#[cfg_attr(feature = "utoipa", derive(ToSchema))]
221pub struct MnemonicResponse {
222 pub mnemonic: String,
224}
225
226#[derive(Serialize, Deserialize)]
227#[cfg_attr(feature = "utoipa", derive(ToSchema))]
228pub struct ArkAddressResponse {
229 #[cfg_attr(feature = "utoipa", schema(value_type = String))]
230 pub address: String,
231}
232
233#[derive(Serialize, Deserialize)]
239#[cfg_attr(feature = "utoipa", derive(ToSchema))]
240pub struct Bip321UriRequest {
241 #[serde(default, skip_serializing_if = "Option::is_none")]
246 pub amount_sat: Option<u64>,
247 #[serde(default, skip_serializing_if = "Option::is_none")]
250 pub onchain: Option<bool>,
251 #[serde(default, skip_serializing_if = "Option::is_none")]
253 pub label: Option<String>,
254 #[serde(default, skip_serializing_if = "Option::is_none")]
256 pub message: Option<String>,
257}
258
259#[derive(Serialize, Deserialize)]
261#[cfg_attr(feature = "utoipa", derive(ToSchema))]
262pub struct Bip321UriQuery {
263 pub uppercase: Option<bool>,
269}
270
271#[derive(Serialize, Deserialize)]
277#[cfg_attr(feature = "utoipa", derive(ToSchema))]
278pub struct Bip321UriResponse {
279 #[serde(skip_serializing_if = "Option::is_none")]
281 pub ark: Option<String>,
282 #[serde(skip_serializing_if = "Option::is_none")]
284 pub bolt11: Option<String>,
285 #[serde(skip_serializing_if = "Option::is_none")]
287 pub onchain: Option<String>,
288 pub bip321: String,
290}
291
292#[derive(Serialize, Deserialize)]
297#[cfg_attr(feature = "utoipa", derive(ToSchema))]
298pub struct EncodedVtxoResponse {
299 pub encoded: crate::primitives::EncodedVtxo,
301}
302
303#[derive(Serialize, Deserialize)]
304#[cfg_attr(feature = "utoipa", derive(ToSchema))]
305pub struct VtxosQuery {
306 pub all: Option<bool>,
308}
309
310#[derive(Serialize, Deserialize)]
311#[cfg_attr(feature = "utoipa", derive(ToSchema))]
312pub struct RefreshRequest {
313 pub vtxos: Vec<String>,
318}
319
320#[derive(Serialize, Deserialize)]
321#[cfg_attr(feature = "utoipa", derive(ToSchema))]
322pub struct DelegatedRefreshRequest {
323 pub vtxos: Vec<String>,
328 pub height: Option<u32>,
332}
333
334#[derive(Serialize, Deserialize)]
335#[cfg_attr(feature = "utoipa", derive(ToSchema))]
336pub struct BoardRequest {
337 pub amount_sat: u64,
341}
342
343#[derive(Serialize, Deserialize)]
344#[cfg_attr(feature = "utoipa", derive(ToSchema))]
345pub struct SendRequest {
346 pub destination: String,
348 pub amount_sat: Option<u64>,
352 pub comment: Option<String>,
354}
355
356#[derive(Serialize, Deserialize)]
357#[cfg_attr(feature = "utoipa", derive(ToSchema))]
358pub struct SendResponse {
359 pub message: String,
361}
362
363#[derive(Serialize, Deserialize)]
364#[cfg_attr(feature = "utoipa", derive(ToSchema))]
365pub struct SendOnchainRequest {
366 pub destination: String,
368 pub amount_sat: u64,
372}
373
374#[derive(Serialize, Deserialize)]
375#[cfg_attr(feature = "utoipa", derive(ToSchema))]
376pub struct OffboardVtxosRequest {
377 pub address: Option<String>,
379 pub vtxos: Vec<String>,
383}
384
385#[derive(Serialize, Deserialize)]
386#[cfg_attr(feature = "utoipa", derive(ToSchema))]
387pub struct OffboardAllRequest {
388 pub address: Option<String>,
390}
391
392#[derive(Serialize, Deserialize)]
393#[cfg_attr(feature = "utoipa", derive(ToSchema))]
394pub struct ImportVtxoRequest {
395 pub vtxos: Vec<String>,
397}
398
399#[derive(Serialize, Deserialize)]
400#[cfg_attr(feature = "utoipa", derive(ToSchema))]
401pub struct LightningInvoiceRequest {
402 pub amount_sat: u64,
406 #[serde(default, skip_serializing_if = "Option::is_none")]
408 pub description: Option<String>,
409 #[serde(default, skip_serializing_if = "Option::is_none")]
413 pub token: Option<String>,
414}
415
416#[derive(Serialize, Deserialize)]
417#[cfg_attr(feature = "utoipa", derive(ToSchema))]
418pub struct LightningInvoiceForAddressRequest {
419 pub amount_sat: u64,
421 pub address: String,
423 #[serde(default, skip_serializing_if = "Option::is_none")]
425 pub description: Option<String>,
426}
427
428#[derive(Serialize, Deserialize)]
429#[cfg_attr(feature = "utoipa", derive(ToSchema))]
430pub struct LightningPayRequest {
431 pub destination: String,
433 pub amount_sat: Option<u64>,
438 pub comment: Option<String>,
440}
441
442#[derive(Serialize, Deserialize)]
443#[cfg_attr(feature = "utoipa", derive(ToSchema))]
444pub struct LightningPayResponse {
445 pub message: String,
447}
448
449#[derive(Serialize, Deserialize)]
450#[cfg_attr(feature = "utoipa", derive(ToSchema))]
451pub struct OnchainSendRequest {
452 pub destination: String,
454 pub amount_sat: u64,
456}
457
458#[derive(Serialize, Deserialize)]
459#[cfg_attr(feature = "utoipa", derive(ToSchema))]
460pub struct OnchainSendManyRequest {
461 pub destinations: Vec<String>,
463 pub immediate: Option<bool>,
465}
466
467#[derive(Serialize, Deserialize)]
468#[cfg_attr(feature = "utoipa", derive(ToSchema))]
469pub struct OnchainDrainRequest {
470 pub destination: String,
472}
473
474#[derive(Serialize, Deserialize)]
475#[cfg_attr(feature = "utoipa", derive(ToSchema))]
476pub struct ExitStatusRequest {
477 pub history: Option<bool>,
479 pub transactions: Option<bool>,
481}
482
483#[derive(Serialize, Deserialize)]
484#[cfg_attr(feature = "utoipa", derive(ToSchema))]
485pub struct ExitStartRequest {
486 pub vtxos: Vec<String>,
488}
489
490#[derive(Serialize, Deserialize)]
491#[cfg_attr(feature = "utoipa", derive(ToSchema))]
492pub struct ExitStartResponse {
493 pub message: String,
494}
495
496#[derive(Serialize, Deserialize)]
497#[cfg_attr(feature = "utoipa", derive(ToSchema))]
498pub struct ExitProgressRequest {
499 pub wait: Option<bool>,
501 pub fee_rate: Option<u64>,
503}
504
505#[derive(Serialize, Deserialize)]
506#[cfg_attr(feature = "utoipa", derive(ToSchema))]
507pub struct ExitClaimAllRequest {
508 pub destination: String,
510 pub fee_rate: Option<u64>,
512}
513
514#[derive(Serialize, Deserialize)]
515#[cfg_attr(feature = "utoipa", derive(ToSchema))]
516pub struct ExitClaimVtxosRequest {
517 pub destination: String,
519 pub vtxos: Vec<String>,
521 pub fee_rate: Option<u64>,
523}
524
525#[derive(Serialize, Deserialize)]
526#[cfg_attr(feature = "utoipa", derive(ToSchema))]
527pub struct ExitClaimResponse {
528 pub message: String,
529}
530
531#[derive(Serialize, Deserialize)]
532#[cfg_attr(feature = "utoipa", derive(ToSchema))]
533pub struct ExitCancelResponse {
534 pub message: String,
535}
536
537
538#[derive(Serialize, Deserialize)]
539#[cfg_attr(feature = "utoipa", derive(ToSchema))]
540pub struct VtxoRequestInfo {
541 #[serde(rename = "amount_sat", with = "bitcoin::amount::serde::as_sat")]
542 #[cfg_attr(feature = "utoipa", schema(value_type = u64))]
543 pub amount: Amount,
544 #[cfg_attr(feature = "utoipa", schema(value_type = String))]
545 pub policy_type: VtxoPolicyKind,
546 #[cfg_attr(feature = "utoipa", schema(value_type = String))]
547 pub user_pubkey: PublicKey,
548}
549
550impl<'a> From<&'a ark::VtxoRequest> for VtxoRequestInfo {
551 fn from(v: &'a ark::VtxoRequest) -> Self {
552 Self {
553 amount: v.amount,
554 policy_type: v.policy.policy_type(),
555 user_pubkey: v.policy.user_pubkey(),
556 }
557 }
558}
559
560#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
561#[cfg_attr(feature = "utoipa", derive(ToSchema))]
562pub struct OffboardRequestInfo {
563 pub script_pubkey_hex: String,
565 pub script_pubkey_asm: String,
567 #[serde(rename = "net_amount_sat", with = "bitcoin::amount::serde::as_sat")]
569 #[cfg_attr(feature = "utoipa", schema(value_type = u64))]
570 pub net_amount: Amount,
571 pub deduct_fees_from_gross_amount: bool,
573 #[serde(rename = "fee_rate_kwu")]
575 #[cfg_attr(feature = "utoipa", schema(value_type = u64))]
576 pub fee_rate: FeeRate,
577}
578
579impl<'a> From<&'a OffboardRequest> for OffboardRequestInfo {
580 fn from(v: &'a OffboardRequest) -> Self {
581 Self {
582 script_pubkey_hex: v.script_pubkey.to_hex_string(),
583 script_pubkey_asm: v.script_pubkey.to_asm_string(),
584 net_amount: v.net_amount,
585 deduct_fees_from_gross_amount: v.deduct_fees_from_gross_amount,
586 fee_rate: v.fee_rate,
587 }
588 }
589}
590
591#[derive(Serialize, Deserialize)]
592#[cfg_attr(feature = "utoipa", derive(ToSchema))]
593pub struct RoundParticipationInfo {
594 #[cfg_attr(feature = "utoipa", schema(value_type = Vec<String>))]
595 pub inputs: Vec<VtxoId>,
596 pub outputs: Vec<VtxoRequestInfo>,
597}
598
599impl<'a> From<&'a bark::round::RoundParticipation> for RoundParticipationInfo {
600 fn from(v: &'a bark::round::RoundParticipation) -> Self {
601 Self {
602 inputs: v.inputs.iter().map(|v| v.id()).collect(),
603 outputs: v.outputs.iter().map(Into::into).collect(),
604 }
605 }
606}
607
608#[derive(Serialize, Deserialize)]
609#[cfg_attr(feature = "utoipa", derive(ToSchema))]
610pub struct PendingRoundInfo {
611 pub id: u32,
613 pub status: RoundStatus,
615 pub participation: RoundParticipationInfo,
617 #[cfg_attr(feature = "utoipa", schema(value_type = String, nullable = true))]
618 pub unlock_hash: Option<UnlockHash>,
619 #[cfg_attr(feature = "utoipa", schema(value_type = String, nullable = true))]
621 pub funding_txid: Option<Txid>,
622 pub funding_tx_hex: Option<String>,
623}
624
625impl PendingRoundInfo {
626 pub fn new<G>(
627 state: &bark::persist::models::StoredRoundState<G>,
628 sync_result: anyhow::Result<bark::round::RoundStatus>,
629 ) -> Self {
630 let funding_tx = state.state().funding_tx();
631 Self {
632 id: state.id().0,
633 status: match sync_result {
634 Ok(status) => status.into(),
635 Err(e) => RoundStatus::SyncError {
636 error: format!("{:#}", e),
637 },
638 },
639 participation: state.state().participation().into(),
640 unlock_hash: state.state().unlock_hash(),
641 funding_txid: funding_tx.map(|t| t.compute_txid()),
642 funding_tx_hex: funding_tx.map(|t| serialize_hex(t)),
643 }
644 }
645}
646
647#[derive(Serialize, Deserialize)]
648#[cfg_attr(feature = "utoipa", derive(ToSchema))]
649pub struct WalletExistsResponse {
650 pub fingerprint: Option<String>,
651}
652
653#[derive(Serialize, Deserialize)]
654#[cfg_attr(feature = "utoipa", derive(ToSchema))]
655pub struct WalletDeleteRequest {
656 pub dangerous: bool,
657 pub fingerprint: String,
658}
659
660#[derive(Serialize, Deserialize)]
661#[cfg_attr(feature = "utoipa", derive(ToSchema))]
662pub struct WalletDeleteResponse {
663 pub deleted: bool,
664 pub message: String,
665}