Skip to main content

bark_json/
web.rs

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/// Query parameters for filtering wallet history by payment method.
19///
20/// Both fields are optional but must be supplied together: omit both to get the
21/// full history, or provide both to filter by a single payment method. The pair
22/// mirrors the serialized form of a payment method (its `type` tag and `value`).
23#[derive(Default, Serialize, Deserialize)]
24#[cfg_attr(feature = "utoipa", derive(ToSchema))]
25pub struct HistoryQuery {
26	/// The payment method type tag to filter by, e.g. `ark`, `bitcoin`,
27	/// `output-script`, `invoice`, `offer`, `lightning-address`, `lnurl` or
28	/// `custom`. Must be provided together with `value`.
29	#[serde(rename = "type")]
30	pub method_type: Option<String>,
31	/// The payment method value to filter by, e.g. the destination address or
32	/// invoice. Must be provided together with `type`.
33	pub value: Option<String>,
34}
35
36/// Query parameters for fee estimates that only require an amount.
37#[derive(Serialize, Deserialize)]
38#[cfg_attr(feature = "utoipa", derive(ToSchema))]
39pub struct FeeEstimateQuery {
40	/// The amount in satoshis to estimate fees for
41	pub amount_sat: u64,
42}
43
44/// Query parameters for send-onchain fee estimates.
45#[derive(Serialize, Deserialize)]
46#[cfg_attr(feature = "utoipa", derive(ToSchema))]
47pub struct SendOnchainFeeEstimateQuery {
48	/// The amount in satoshis to send
49	pub amount_sat: u64,
50	/// The destination Bitcoin address
51	pub address: String,
52}
53
54/// Query parameters for offboard-all fee estimates.
55#[derive(Serialize, Deserialize)]
56#[cfg_attr(feature = "utoipa", derive(ToSchema))]
57pub struct OffboardAllFeeEstimateQuery {
58	/// The destination Bitcoin address
59	pub address: String,
60}
61
62/// Request body for estimating the fee of offboarding a specific set of VTXOs.
63#[derive(Serialize, Deserialize)]
64#[cfg_attr(feature = "utoipa", derive(ToSchema))]
65pub struct OffboardFeeEstimateRequest {
66	/// The destination Bitcoin address. The fee depends on its script type.
67	pub address: String,
68	/// The IDs of the VTXOs to offboard. Each is offboarded in full.
69	pub vtxos: Vec<String>,
70}
71
72/// A fee estimate for an Ark wallet operation.
73#[derive(Serialize, Deserialize)]
74#[cfg_attr(feature = "utoipa", derive(ToSchema))]
75pub struct FeeEstimateResponse {
76	/// The total amount including fees (in satoshis)
77	#[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	/// The fee portion (in satoshis)
81	#[serde(rename = "fee_sat", with = "bitcoin::amount::serde::as_sat")]
82	#[cfg_attr(feature = "utoipa", schema(value_type = u64))]
83	pub fee: Amount,
84	/// The amount excluding fees (in satoshis). For sends, this is the amount
85	/// the recipient receives. For receives, this is the amount the user gets.
86	#[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	/// The VTXOs that would be spent for this operation
90	#[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/// Mempool fee rates for on-chain transactions.
106#[derive(Serialize, Deserialize)]
107#[cfg_attr(feature = "utoipa", derive(ToSchema))]
108pub struct OnchainFeeRatesResponse {
109	/// Fee rate targeting ~1 block confirmation (sat/vB)
110	pub fast_sat_per_vb: u64,
111	/// Fee rate targeting ~3 block confirmation (sat/vB)
112	pub regular_sat_per_vb: u64,
113	/// Fee rate targeting ~6 block confirmation (sat/vB)
114	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	/// The mailbox checkpoint (tip) the wallet has consumed up to after
128	/// the sync. Monotonically non-decreasing across successful syncs.
129	pub checkpoint: u64,
130}
131
132#[derive(Serialize, Deserialize)]
133#[cfg_attr(feature = "utoipa", derive(ToSchema))]
134pub struct CreateWalletRequest {
135	/// The Ark server to use for the wallet.
136	/// Optional when a config.toml already exists in the datadir.
137	pub ark_server: Option<String>,
138	/// An access token for a private Ark server.
139	///
140	/// **Deprecated**: access tokens are no longer enforced by the server;
141	/// this field will be removed in a future release.
142	#[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	/// The chain source to use for the wallet.
148	/// Optional when a config.toml already exists in the datadir.
149	pub chain_source: Option<ChainSourceConfig>,
150	/// The optional mnemonic to use for the wallet
151	pub mnemonic: Option<String>,
152	/// The network to use for the wallet
153	pub network: BarkNetwork,
154	/// An optional birthday height to start syncing the wallet from
155	pub birthday_height: Option<u32>,
156	/// Proceed even if the datadir contains unexpected files
157	#[serde(default)]
158	pub force: bool,
159}
160
161/// Networks bark can be used on
162#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
163#[serde(rename_all = "kebab-case")]
164#[cfg_attr(feature = "utoipa", derive(ToSchema))]
165pub enum BarkNetwork {
166	/// Bitcoin's mainnet
167	Mainnet,
168	/// The official Bitcoin Core signet
169	Signet,
170	/// Mutinynet
171	Mutinynet,
172	/// Any regtest network
173	Regtest,
174}
175
176#[derive(Serialize, Deserialize)]
177#[serde(rename_all = "kebab-case")]
178#[cfg_attr(feature = "utoipa", derive(ToSchema))]
179pub enum ChainSourceConfig {
180	/// Use a bitcoind RPC server
181	Bitcoind {
182		bitcoind: String,
183		bitcoind_auth: BitcoindAuth,
184	},
185	/// Use an Esplora HTTP server
186	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	/// Use a cookie file for authentication
196	Cookie {
197		cookie: String,
198	},
199	/// Use a username and password for authentication
200	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	/// Whether the wallet is currently connected to its Ark server
216	pub connected: bool,
217}
218
219#[derive(Serialize, Deserialize)]
220#[cfg_attr(feature = "utoipa", derive(ToSchema))]
221pub struct MnemonicResponse {
222	/// The BIP-39 mnemonic phrase backing the wallet.
223	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/// Request to build a BIP 321 unified payment URI.
234///
235/// An Ark address is always included. A BOLT11 invoice is only included when
236/// `amount_sat` is given (an amount is required to create one). An on-chain
237/// address is included only when `onchain` is `true`.
238#[derive(Serialize, Deserialize)]
239#[cfg_attr(feature = "utoipa", derive(ToSchema))]
240pub struct Bip321UriRequest {
241	/// Optional amount (in satoshis) to request. When set, it is embedded in
242	/// the URI and used to create the BOLT11 invoice. Any server-configured
243	/// [LightningReceiveFees](crate::cli::fees::LightningReceiveFees) are
244	/// deducted from the amount the client ultimately receives over Lightning.
245	#[serde(default, skip_serializing_if = "Option::is_none")]
246	pub amount_sat: Option<u64>,
247	/// Whether to include a fresh on-chain address as a payment destination.
248	/// Defaults to `false`.
249	#[serde(default, skip_serializing_if = "Option::is_none")]
250	pub onchain: Option<bool>,
251	/// Optional label describing the payment, recorded in the URI's `label`.
252	#[serde(default, skip_serializing_if = "Option::is_none")]
253	pub label: Option<String>,
254	/// Optional message describing the payment, recorded in the URI's `message`.
255	#[serde(default, skip_serializing_if = "Option::is_none")]
256	pub message: Option<String>,
257}
258
259/// Query parameters for building a BIP 321 URI.
260#[derive(Serialize, Deserialize)]
261#[cfg_attr(feature = "utoipa", derive(ToSchema))]
262pub struct Bip321UriQuery {
263	/// Whether to upper-case the returned `bip321` URI so QR encoders can use
264	/// the compact alphanumeric mode. Defaults to `false`.
265	/// Requesting an upper-case URI fails when it carries case-sensitive data
266	/// (a label or message with lowercase characters, or base58 address) that
267	/// cannot be upper-cased.
268	pub uppercase: Option<bool>,
269}
270
271/// A BIP 321 unified payment URI together with its individual destinations.
272///
273/// The `bip321` field is the combined `bitcoin:` URI; the other fields expose
274/// each generated destination separately for convenience. A field is `null`
275/// when that destination was not requested or could not be produced.
276#[derive(Serialize, Deserialize)]
277#[cfg_attr(feature = "utoipa", derive(ToSchema))]
278pub struct Bip321UriResponse {
279	/// The generated Ark address, if any.
280	#[serde(skip_serializing_if = "Option::is_none")]
281	pub ark: Option<String>,
282	/// The generated BOLT11 invoice, included only when an amount was given.
283	#[serde(skip_serializing_if = "Option::is_none")]
284	pub bolt11: Option<String>,
285	/// The generated on-chain address, included only when `onchain` was set.
286	#[serde(skip_serializing_if = "Option::is_none")]
287	pub onchain: Option<String>,
288	/// The combined BIP 321 `bitcoin:` URI.
289	pub bip321: String,
290}
291
292/// Response for the encoded-VTXO endpoint.
293///
294/// Wraps the hex-encoded VTXO in a named field so clients can easily
295/// extract it.
296#[derive(Serialize, Deserialize)]
297#[cfg_attr(feature = "utoipa", derive(ToSchema))]
298pub struct EncodedVtxoResponse {
299	/// Hex-encoded serialized VTXO.
300	pub encoded: crate::primitives::EncodedVtxo,
301}
302
303#[derive(Serialize, Deserialize)]
304#[cfg_attr(feature = "utoipa", derive(ToSchema))]
305pub struct VtxosQuery {
306	/// Return all VTXOs regardless of their state (including spent ones)
307	pub all: Option<bool>,
308}
309
310#[derive(Serialize, Deserialize)]
311#[cfg_attr(feature = "utoipa", derive(ToSchema))]
312pub struct RefreshRequest {
313	/// List of VTXO IDs to refresh. The sum of the VTXOs being refreshed must be
314	/// >= [P2TR_DUST](bitcoin_ext::P2TR_DUST). Keep in mind that fees set out in
315	/// [RefreshFees](crate::cli::fees::RefreshFees) will be deducted from the newly created VTXO, this
316	/// value must also be >= [P2TR_DUST](bitcoin_ext::P2TR_DUST).
317	pub vtxos: Vec<String>,
318}
319
320#[derive(Serialize, Deserialize)]
321#[cfg_attr(feature = "utoipa", derive(ToSchema))]
322pub struct DelegatedRefreshRequest {
323	/// List of VTXO IDs to refresh. The sum of the VTXOs being refreshed must be
324	/// >= [P2TR_DUST](bitcoin_ext::P2TR_DUST). Keep in mind that fees set out in
325	/// [RefreshFees](crate::cli::fees::RefreshFees) will be deducted from the newly created VTXO, this
326	/// value must also be >= [P2TR_DUST](bitcoin_ext::P2TR_DUST).
327	pub vtxos: Vec<String>,
328	/// Optional block height to schedule the refresh at. When set, the refresh fee is priced at
329	/// that height and the server includes the participation in the first round once the chain
330	/// tip reaches it; when omitted, the participation is eligible for the next round.
331	pub height: Option<u32>,
332}
333
334#[derive(Serialize, Deserialize)]
335#[cfg_attr(feature = "utoipa", derive(ToSchema))]
336pub struct BoardRequest {
337	/// An amount of onchain funds to board (in satoshis). For a board operation to be successful,
338	/// this value, with any server-configured [BoardFees](crate::cli::fees::BoardFees) deducted, must be
339	/// >= [P2TR_DUST](bitcoin_ext::P2TR_DUST).
340	pub amount_sat: u64,
341}
342
343#[derive(Serialize, Deserialize)]
344#[cfg_attr(feature = "utoipa", derive(ToSchema))]
345pub struct SendRequest {
346	/// The destination can be an Ark address, a BOLT11-invoice, LNURL or a lightning address
347	pub destination: String,
348	/// The amount to send (in satoshis). Optional for bolt11 invoices. Depending on the
349	/// `destination`, the wallet must contain this amount plus any fees configured by the server in
350	/// [FeeSchedule](crate::cli::fees::FeeSchedule).
351	pub amount_sat: Option<u64>,
352	/// An optional comment, only supported when paying to lightning addresses
353	pub comment: Option<String>,
354}
355
356#[derive(Serialize, Deserialize)]
357#[cfg_attr(feature = "utoipa", derive(ToSchema))]
358pub struct SendResponse {
359	/// Success message
360	pub message: String,
361}
362
363#[derive(Serialize, Deserialize)]
364#[cfg_attr(feature = "utoipa", derive(ToSchema))]
365pub struct SendOnchainRequest {
366	/// The destination Bitcoin address
367	pub destination: String,
368	/// The amount (in satoshis) to be received by `destination` onchain. Must be
369	/// >= [P2TR_DUST](bitcoin_ext::P2TR_DUST). Server-configured fees laid out in
370	/// [OffboardFees](crate::cli::fees::OffboardFees) will be added on top of this amount.
371	pub amount_sat: u64,
372}
373
374#[derive(Serialize, Deserialize)]
375#[cfg_attr(feature = "utoipa", derive(ToSchema))]
376pub struct OffboardVtxosRequest {
377	/// Optional Bitcoin address to send to. If not provided, uses the onchain wallet's address
378	pub address: Option<String>,
379	/// List of VTXO IDs to offboard. The sum of the VTXOs being refreshed must be
380	/// >= [P2TR_DUST](bitcoin_ext::P2TR_DUST) after the server-configured
381	/// [OffboardFees](crate::cli::fees::OffboardFees) are deducted.
382	pub vtxos: Vec<String>,
383}
384
385#[derive(Serialize, Deserialize)]
386#[cfg_attr(feature = "utoipa", derive(ToSchema))]
387pub struct OffboardAllRequest {
388	/// Optional Bitcoin address to send to. If not provided, uses the onchain wallet's address
389	pub address: Option<String>,
390}
391
392#[derive(Serialize, Deserialize)]
393#[cfg_attr(feature = "utoipa", derive(ToSchema))]
394pub struct ImportVtxoRequest {
395	/// Hex-encoded VTXOs to import
396	pub vtxos: Vec<String>,
397}
398
399#[derive(Serialize, Deserialize)]
400#[cfg_attr(feature = "utoipa", derive(ToSchema))]
401pub struct LightningInvoiceRequest {
402	/// The amount to create invoice for (in satoshis). This is the amount the payee will pay but
403	/// the final amount received by the client will have any server-configured
404	/// [LightningReceiveFees](crate::cli::fees::LightningReceiveFees) deducted.
405	pub amount_sat: u64,
406	/// Optional description embedded in the invoice as its memo.
407	#[serde(default, skip_serializing_if = "Option::is_none")]
408	pub description: Option<String>,
409	/// Optional lightning receive token for authentication of the claim, if
410	/// the server requires one and there are no existing spendable VTXOs to
411	/// prove ownership of.
412	#[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	/// The amount to create invoice for (in satoshis).
420	pub amount_sat: u64,
421	/// Ark address that will receive the claimed VTXO.
422	pub address: String,
423	/// Optional description embedded in the invoice as its memo.
424	#[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	/// The invoice, offer, or lightning address to pay
432	pub destination: String,
433	/// The amount to send (in satoshis). Optional for bolt11 invoices with amount. This must be
434	/// higher than the minimum fee laid out in server-configured
435	/// [LightningSendFees](crate::cli::fees::LightningSendFees). The wallet must also contain enough
436	/// funds to cover the amount plus any fees.
437	pub amount_sat: Option<u64>,
438	/// An optional comment, only supported when paying to lightning addresses
439	pub comment: Option<String>,
440}
441
442#[derive(Serialize, Deserialize)]
443#[cfg_attr(feature = "utoipa", derive(ToSchema))]
444pub struct LightningPayResponse {
445	/// Success message
446	pub message: String,
447}
448
449#[derive(Serialize, Deserialize)]
450#[cfg_attr(feature = "utoipa", derive(ToSchema))]
451pub struct OnchainSendRequest {
452	/// The destination Bitcoin address
453	pub destination: String,
454	/// The amount to send (in satoshis)
455	pub amount_sat: u64,
456}
457
458#[derive(Serialize, Deserialize)]
459#[cfg_attr(feature = "utoipa", derive(ToSchema))]
460pub struct OnchainSendManyRequest {
461	/// List of destinations in format "address:amount"
462	pub destinations: Vec<String>,
463	/// Sends the transaction immediately instead of waiting
464	pub immediate: Option<bool>,
465}
466
467#[derive(Serialize, Deserialize)]
468#[cfg_attr(feature = "utoipa", derive(ToSchema))]
469pub struct OnchainDrainRequest {
470	/// The destination Bitcoin address
471	pub destination: String,
472}
473
474#[derive(Serialize, Deserialize)]
475#[cfg_attr(feature = "utoipa", derive(ToSchema))]
476pub struct ExitStatusRequest {
477	/// Whether to include the detailed history of the exit process
478	pub history: Option<bool>,
479	/// Whether to include the exit transactions and their CPFP children
480	pub transactions: Option<bool>,
481}
482
483#[derive(Serialize, Deserialize)]
484#[cfg_attr(feature = "utoipa", derive(ToSchema))]
485pub struct ExitStartRequest {
486	/// The ID of VTXOs to unilaterally exit
487	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	/// Wait until the exit is completed
500	pub wait: Option<bool>,
501	/// Sets the desired fee-rate in sats/kvB to use broadcasting exit transactions
502	pub fee_rate: Option<u64>,
503}
504
505#[derive(Serialize, Deserialize)]
506#[cfg_attr(feature = "utoipa", derive(ToSchema))]
507pub struct ExitClaimAllRequest {
508	/// The destination Bitcoin address
509	pub destination: String,
510	/// Sets the desired fee-rate in sats/kvB to use broadcasting exit transactions
511	pub fee_rate: Option<u64>,
512}
513
514#[derive(Serialize, Deserialize)]
515#[cfg_attr(feature = "utoipa", derive(ToSchema))]
516pub struct ExitClaimVtxosRequest {
517	/// The destination Bitcoin address
518	pub destination: String,
519	/// The ID of an exited VTXO to be claimed
520	pub vtxos: Vec<String>,
521	/// Sets the desired fee-rate in sats/kvB to use broadcasting exit transactions
522	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	/// hexadecimal representation of the output script
564	pub script_pubkey_hex: String,
565	/// opcode representation of the output script
566	pub script_pubkey_asm: String,
567	/// The target amount in sats.
568	#[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	/// Determines whether fees should be added onto the given amount or deducted from it.
572	pub deduct_fees_from_gross_amount: bool,
573	/// What fee rate was used when calculating the fee for the offboard.
574	#[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	/// Unique identifier for the round
612	pub id: u32,
613	/// the current status of the round
614	pub status: RoundStatus,
615	/// the round participation details
616	pub participation: RoundParticipationInfo,
617	#[cfg_attr(feature = "utoipa", schema(value_type = String, nullable = true))]
618	pub unlock_hash: Option<UnlockHash>,
619	/// The round transaction id, if already assigned
620	#[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}