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::lightning::PaymentHash;
9use ark::offboard::OffboardRequest;
10use ark::tree::signed::UnlockHash;
11use ark::vtxo::VtxoPolicyKind;
12
13#[cfg(feature = "utoipa")]
14use utoipa::ToSchema;
15
16use crate::cli::RoundStatus;
17
18
19/// Query parameters for filtering wallet history by payment method.
20///
21/// Both fields are optional but must be supplied together: omit both to get the
22/// full history, or provide both to filter by a single payment method. The pair
23/// mirrors the serialized form of a payment method (its `type` tag and `value`).
24#[derive(Default, Serialize, Deserialize)]
25#[cfg_attr(feature = "utoipa", derive(ToSchema))]
26pub struct HistoryQuery {
27	/// The payment method type tag to filter by, e.g. `ark`, `bitcoin`,
28	/// `output-script`, `invoice`, `offer`, `lightning-address`, `lnurl` or
29	/// `custom`. Must be provided together with `value`.
30	#[serde(rename = "type")]
31	pub method_type: Option<String>,
32	/// The payment method value to filter by, e.g. the destination address or
33	/// invoice. Must be provided together with `type`.
34	pub value: Option<String>,
35}
36
37/// Query parameters for fee estimates that only require an amount.
38#[derive(Serialize, Deserialize)]
39#[cfg_attr(feature = "utoipa", derive(ToSchema))]
40pub struct FeeEstimateQuery {
41	/// The amount in satoshis to estimate fees for
42	pub amount_sat: u64,
43}
44
45/// Query parameters for send-onchain fee estimates.
46#[derive(Serialize, Deserialize)]
47#[cfg_attr(feature = "utoipa", derive(ToSchema))]
48pub struct SendOnchainFeeEstimateQuery {
49	/// The amount in satoshis to send
50	pub amount_sat: u64,
51	/// The destination Bitcoin address
52	pub address: String,
53}
54
55/// Query parameters for offboard-all fee estimates.
56#[derive(Serialize, Deserialize)]
57#[cfg_attr(feature = "utoipa", derive(ToSchema))]
58pub struct OffboardAllFeeEstimateQuery {
59	/// The destination Bitcoin address
60	pub address: String,
61}
62
63/// Request body for estimating the fee of offboarding a specific set of VTXOs.
64#[derive(Serialize, Deserialize)]
65#[cfg_attr(feature = "utoipa", derive(ToSchema))]
66pub struct OffboardFeeEstimateRequest {
67	/// The destination Bitcoin address. The fee depends on its script type.
68	pub address: String,
69	/// The IDs of the VTXOs to offboard. Each is offboarded in full.
70	pub vtxos: Vec<String>,
71}
72
73/// A fee estimate for an Ark wallet operation.
74#[derive(Serialize, Deserialize)]
75#[cfg_attr(feature = "utoipa", derive(ToSchema))]
76pub struct FeeEstimateResponse {
77	/// The total amount including fees (in satoshis)
78	#[serde(rename = "gross_amount_sat", with = "bitcoin::amount::serde::as_sat")]
79	#[cfg_attr(feature = "utoipa", schema(value_type = u64))]
80	pub gross_amount: Amount,
81	/// The fee portion (in satoshis)
82	#[serde(rename = "fee_sat", with = "bitcoin::amount::serde::as_sat")]
83	#[cfg_attr(feature = "utoipa", schema(value_type = u64))]
84	pub fee: Amount,
85	/// The amount excluding fees (in satoshis). For sends, this is the amount
86	/// the recipient receives. For receives, this is the amount the user gets.
87	#[serde(rename = "net_amount_sat", with = "bitcoin::amount::serde::as_sat")]
88	#[cfg_attr(feature = "utoipa", schema(value_type = u64))]
89	pub net_amount: Amount,
90	/// The VTXOs that would be spent for this operation
91	#[cfg_attr(feature = "utoipa", schema(value_type = Vec<String>))]
92	pub vtxos_spent: Vec<VtxoId>,
93}
94
95impl From<bark::FeeEstimate> for FeeEstimateResponse {
96	fn from(estimate: bark::FeeEstimate) -> Self {
97		FeeEstimateResponse {
98			gross_amount: estimate.gross_amount,
99			fee: estimate.fee,
100			net_amount: estimate.net_amount,
101			vtxos_spent: estimate.vtxos_spent,
102		}
103	}
104}
105
106/// Query parameters for emergency (unilateral) exit fee estimates.
107#[derive(Serialize, Deserialize)]
108#[cfg_attr(feature = "utoipa", derive(ToSchema))]
109pub struct EmergencyExitFeeEstimateQuery {
110	/// Comma-separated VTXO ids to estimate the exit for. When omitted, every spendable VTXO in
111	/// the wallet is used (i.e. exit the entire wallet).
112	pub vtxo_ids: Option<String>,
113	/// The fee rate to price the estimate at, in sat/vB. Applied to both the broadcast and claim
114	/// legs. When omitted, the broadcast leg uses the current `fast` rate and the claim leg the
115	/// `regular` rate.
116	pub fee_rate_sat_per_vb: Option<u64>,
117	/// The destination address for the claim. Only affects the claim-fee weight; when omitted a
118	/// placeholder of the configured network is used.
119	pub destination: Option<String>,
120}
121
122/// A fee breakdown for unilaterally (emergency) exiting a set of VTXOs.
123#[derive(Debug, Clone, Serialize, Deserialize)]
124#[cfg_attr(feature = "utoipa", derive(ToSchema))]
125pub struct EmergencyExitFeeEstimateResponse {
126	/// The CPFP fees to broadcast every not-yet-confirmed exit transaction (in satoshis). Paid now
127	/// from confirmed on-chain funds.
128	#[serde(rename = "exit_broadcast_fee_sat", with = "bitcoin::amount::serde::as_sat")]
129	#[cfg_attr(feature = "utoipa", schema(value_type = u64))]
130	pub exit_broadcast_fee: Amount,
131	/// The fee for the single batched transaction that drains the matured exit outputs (in
132	/// satoshis). Paid later out of the recovered value.
133	#[serde(rename = "claim_fee_sat", with = "bitcoin::amount::serde::as_sat")]
134	#[cfg_attr(feature = "utoipa", schema(value_type = u64))]
135	pub claim_fee: Amount,
136	/// The sum of the broadcast and claim fees (in satoshis).
137	#[serde(rename = "total_fee_sat", with = "bitcoin::amount::serde::as_sat")]
138	#[cfg_attr(feature = "utoipa", schema(value_type = u64))]
139	pub total_fee: Amount,
140	/// The fee rate the exit-broadcast leg was priced at (sat/vB). Unless an explicit fee rate was
141	/// supplied, the claim leg is priced separately at the chain's `regular` rate.
142	pub fee_rate_sat_per_vb: u64,
143	/// The number of exit transactions that still need to be broadcast and CPFP-bumped.
144	pub txs_to_broadcast: usize,
145	/// Whether the wallet's current on-chain balance covers the full serial exit-broadcast walk.
146	pub fundable: bool,
147}
148
149impl From<bark::exit::ExitFeeEstimate> for EmergencyExitFeeEstimateResponse {
150	fn from(e: bark::exit::ExitFeeEstimate) -> Self {
151		EmergencyExitFeeEstimateResponse {
152			total_fee: e.total(),
153			exit_broadcast_fee: e.exit_broadcast_fee,
154			claim_fee: e.claim_fee,
155			fee_rate_sat_per_vb: e.fee_rate.to_sat_per_vb_ceil(),
156			txs_to_broadcast: e.txs_to_broadcast,
157			fundable: e.fundable,
158		}
159	}
160}
161
162/// Mempool fee rates for on-chain transactions.
163#[derive(Serialize, Deserialize)]
164#[cfg_attr(feature = "utoipa", derive(ToSchema))]
165pub struct OnchainFeeRatesResponse {
166	/// Fee rate targeting ~1 block confirmation (sat/vB)
167	pub fast_sat_per_vb: u64,
168	/// Fee rate targeting ~3 block confirmation (sat/vB)
169	pub regular_sat_per_vb: u64,
170	/// Fee rate targeting ~6 block confirmation (sat/vB)
171	pub slow_sat_per_vb: u64,
172}
173
174
175#[derive(Serialize, Deserialize)]
176#[cfg_attr(feature = "utoipa", derive(ToSchema))]
177pub struct TipResponse {
178	pub tip_height: u32,
179}
180
181#[derive(Serialize, Deserialize)]
182#[cfg_attr(feature = "utoipa", derive(ToSchema))]
183pub struct MailboxSyncResponse {
184	/// The mailbox checkpoint (tip) the wallet has consumed up to after
185	/// the sync. Monotonically non-decreasing across successful syncs.
186	pub checkpoint: u64,
187}
188
189#[derive(Serialize, Deserialize)]
190#[cfg_attr(feature = "utoipa", derive(ToSchema))]
191pub struct CreateWalletRequest {
192	/// The Ark server to use for the wallet.
193	/// Optional when a config.toml already exists in the datadir.
194	pub ark_server: Option<String>,
195	/// An access token for a private Ark server.
196	///
197	/// **Deprecated**: access tokens are no longer enforced by the server;
198	/// this field will be removed in a future release.
199	#[deprecated(
200		since = "0.2.4",
201		note = "access tokens are not enforced by the server; this field will be removed",
202	)]
203	pub ark_server_access_token: Option<String>,
204	/// The chain source to use for the wallet.
205	/// Optional when a config.toml already exists in the datadir.
206	pub chain_source: Option<ChainSourceConfig>,
207	/// The optional mnemonic to use for the wallet
208	pub mnemonic: Option<String>,
209	/// The network to use for the wallet
210	pub network: BarkNetwork,
211	/// An optional birthday height to start syncing the wallet from
212	pub birthday_height: Option<u32>,
213	/// Proceed even if the datadir contains unexpected files
214	#[serde(default)]
215	pub force: bool,
216}
217
218/// Networks bark can be used on
219#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
220#[serde(rename_all = "kebab-case")]
221#[cfg_attr(feature = "utoipa", derive(ToSchema))]
222pub enum BarkNetwork {
223	/// Bitcoin's mainnet
224	Mainnet,
225	/// The official Bitcoin Core signet
226	Signet,
227	/// Mutinynet
228	Mutinynet,
229	/// Any regtest network
230	Regtest,
231}
232
233#[derive(Serialize, Deserialize)]
234#[serde(rename_all = "kebab-case")]
235#[cfg_attr(feature = "utoipa", derive(ToSchema))]
236pub enum ChainSourceConfig {
237	/// Use a bitcoind RPC server
238	Bitcoind {
239		bitcoind: String,
240		bitcoind_auth: BitcoindAuth,
241	},
242	/// Use an Esplora HTTP server
243	Esplora {
244		url: String,
245	},
246}
247
248#[derive(Serialize, Deserialize)]
249#[serde(rename_all = "kebab-case")]
250#[cfg_attr(feature = "utoipa", derive(ToSchema))]
251pub enum BitcoindAuth {
252	/// Use a cookie file for authentication
253	Cookie {
254		cookie: String,
255	},
256	/// Use a username and password for authentication
257	UserPass {
258		user: String,
259		pass: String,
260	},
261}
262
263#[derive(Serialize, Deserialize)]
264#[cfg_attr(feature = "utoipa", derive(ToSchema))]
265pub struct CreateWalletResponse {
266	pub fingerprint: String,
267}
268
269#[derive(Serialize, Deserialize)]
270#[cfg_attr(feature = "utoipa", derive(ToSchema))]
271pub struct ConnectedResponse {
272	/// Whether the wallet is currently connected to its Ark server
273	pub connected: bool,
274}
275
276#[derive(Serialize, Deserialize)]
277#[cfg_attr(feature = "utoipa", derive(ToSchema))]
278pub struct MnemonicResponse {
279	/// The BIP-39 mnemonic phrase backing the wallet.
280	pub mnemonic: String,
281}
282
283#[derive(Serialize, Deserialize)]
284#[cfg_attr(feature = "utoipa", derive(ToSchema))]
285pub struct ArkAddressResponse {
286	#[cfg_attr(feature = "utoipa", schema(value_type = String))]
287	pub address: String,
288}
289
290/// Request to build a BIP 321 unified payment URI.
291///
292/// An Ark address is always included. A BOLT11 invoice is only included when
293/// `amount_sat` is given (an amount is required to create one). An on-chain
294/// address is included only when `onchain` is `true`.
295#[derive(Serialize, Deserialize)]
296#[cfg_attr(feature = "utoipa", derive(ToSchema))]
297pub struct Bip321UriRequest {
298	/// Optional amount (in satoshis) to request. When set, it is embedded in
299	/// the URI and used to create the BOLT11 invoice. Any server-configured
300	/// [LightningReceiveFees](crate::cli::fees::LightningReceiveFees) are
301	/// deducted from the amount the client ultimately receives over Lightning.
302	#[serde(default, skip_serializing_if = "Option::is_none")]
303	pub amount_sat: Option<u64>,
304	/// Whether to include a fresh on-chain address as a payment destination.
305	/// Defaults to `false`.
306	#[serde(default, skip_serializing_if = "Option::is_none")]
307	pub onchain: Option<bool>,
308	/// Optional label describing the payment, recorded in the URI's `label`.
309	#[serde(default, skip_serializing_if = "Option::is_none")]
310	pub label: Option<String>,
311	/// Optional message describing the payment, recorded in the URI's `message`.
312	#[serde(default, skip_serializing_if = "Option::is_none")]
313	pub message: Option<String>,
314}
315
316/// Query parameters for building a BIP 321 URI.
317#[derive(Serialize, Deserialize)]
318#[cfg_attr(feature = "utoipa", derive(ToSchema))]
319pub struct Bip321UriQuery {
320	/// Whether to upper-case the returned `bip321` URI so QR encoders can use
321	/// the compact alphanumeric mode. Defaults to `false`.
322	/// Requesting an upper-case URI fails when it carries case-sensitive data
323	/// (a label or message with lowercase characters, or base58 address) that
324	/// cannot be upper-cased.
325	pub uppercase: Option<bool>,
326}
327
328/// A BIP 321 unified payment URI together with its individual destinations.
329///
330/// The `bip321` field is the combined `bitcoin:` URI; the other fields expose
331/// each generated destination separately for convenience. A field is `null`
332/// when that destination was not requested or could not be produced.
333#[derive(Serialize, Deserialize)]
334#[cfg_attr(feature = "utoipa", derive(ToSchema))]
335pub struct Bip321UriResponse {
336	/// The generated Ark address, if any.
337	#[serde(skip_serializing_if = "Option::is_none")]
338	pub ark: Option<String>,
339	/// The generated BOLT11 invoice, included only when an amount was given.
340	#[serde(skip_serializing_if = "Option::is_none")]
341	pub bolt11: Option<String>,
342	/// The generated on-chain address, included only when `onchain` was set.
343	#[serde(skip_serializing_if = "Option::is_none")]
344	pub onchain: Option<String>,
345	/// The combined BIP 321 `bitcoin:` URI.
346	pub bip321: String,
347}
348
349/// Response for the encoded-VTXO endpoint.
350///
351/// Wraps the hex-encoded VTXO in a named field so clients can easily
352/// extract it.
353#[derive(Serialize, Deserialize)]
354#[cfg_attr(feature = "utoipa", derive(ToSchema))]
355pub struct EncodedVtxoResponse {
356	/// Hex-encoded serialized VTXO.
357	pub encoded: crate::primitives::EncodedVtxo,
358}
359
360#[derive(Serialize, Deserialize)]
361#[cfg_attr(feature = "utoipa", derive(ToSchema))]
362pub struct VtxosQuery {
363	/// Return all VTXOs regardless of their state (including spent ones)
364	pub all: Option<bool>,
365}
366
367#[derive(Serialize, Deserialize)]
368#[cfg_attr(feature = "utoipa", derive(ToSchema))]
369pub struct RefreshRequest {
370	/// List of VTXO IDs to refresh. The sum of the VTXOs being refreshed must be
371	/// >= [P2TR_DUST](bitcoin_ext::P2TR_DUST). Keep in mind that fees set out in
372	/// [RefreshFees](crate::cli::fees::RefreshFees) will be deducted from the newly created VTXO, this
373	/// value must also be >= [P2TR_DUST](bitcoin_ext::P2TR_DUST).
374	pub vtxos: Vec<String>,
375}
376
377#[derive(Serialize, Deserialize)]
378#[cfg_attr(feature = "utoipa", derive(ToSchema))]
379pub struct DelegatedRefreshRequest {
380	/// List of VTXO IDs to refresh. The sum of the VTXOs being refreshed must be
381	/// >= [P2TR_DUST](bitcoin_ext::P2TR_DUST). Keep in mind that fees set out in
382	/// [RefreshFees](crate::cli::fees::RefreshFees) will be deducted from the newly created VTXO, this
383	/// value must also be >= [P2TR_DUST](bitcoin_ext::P2TR_DUST).
384	pub vtxos: Vec<String>,
385	/// Optional block height to schedule the refresh at. When set, the refresh fee is priced at
386	/// that height and the server includes the participation in the first round once the chain
387	/// tip reaches it; when omitted, the participation is eligible for the next round.
388	pub height: Option<u32>,
389}
390
391#[derive(Serialize, Deserialize)]
392#[cfg_attr(feature = "utoipa", derive(ToSchema))]
393pub struct BoardRequest {
394	/// An amount of onchain funds to board (in satoshis). For a board operation to be successful,
395	/// this value, with any server-configured [BoardFees](crate::cli::fees::BoardFees) deducted, must be
396	/// >= [P2TR_DUST](bitcoin_ext::P2TR_DUST).
397	pub amount_sat: u64,
398}
399
400#[derive(Serialize, Deserialize)]
401#[cfg_attr(feature = "utoipa", derive(ToSchema))]
402pub struct SendRequest {
403	/// The destination can be an Ark address, a BOLT11-invoice, LNURL or a lightning address
404	pub destination: String,
405	/// The amount to send (in satoshis). Optional for bolt11 invoices. Depending on the
406	/// `destination`, the wallet must contain this amount plus any fees configured by the server in
407	/// [FeeSchedule](crate::cli::fees::FeeSchedule).
408	pub amount_sat: Option<u64>,
409	/// An optional comment, only supported when paying to lightning addresses
410	pub comment: Option<String>,
411}
412
413#[derive(Serialize, Deserialize)]
414#[cfg_attr(feature = "utoipa", derive(ToSchema))]
415pub struct SendResponse {
416	/// Success message
417	pub message: String,
418	/// The payment hash, when the destination resolved to a lightning
419	/// payment. Can be used to poll the payment status.
420	#[serde(default, skip_serializing_if = "Option::is_none")]
421	#[cfg_attr(feature = "utoipa", schema(value_type = Option<String>))]
422	pub payment_hash: Option<PaymentHash>,
423}
424
425/// Request to sign an arbitrary message with one of the wallet's keys
426#[derive(Serialize, Deserialize)]
427#[cfg_attr(feature = "utoipa", derive(ToSchema))]
428pub struct SignMessageRequest {
429	/// The message to sign
430	pub message: String,
431	/// The Ark address to sign the message with
432	pub address: String,
433}
434
435/// Request to verify a signed message
436///
437/// Exactly one of `pubkey` and `address` must be set.
438#[derive(Serialize, Deserialize)]
439#[cfg_attr(feature = "utoipa", derive(ToSchema))]
440pub struct VerifyMessageRequest {
441	/// The message that was signed
442	pub message: String,
443	/// The BIP-340 Schnorr signature over the message digest
444	/// `SHA256("bark/message" || message)`, in hex
445	pub signature: String,
446	/// The public key to verify the signature against
447	pub pubkey: Option<String>,
448	/// The Ark address whose user public key to verify the signature against
449	pub address: Option<String>,
450}
451
452#[derive(Serialize, Deserialize)]
453#[cfg_attr(feature = "utoipa", derive(ToSchema))]
454pub struct SendOnchainRequest {
455	/// The destination Bitcoin address
456	pub destination: String,
457	/// The amount (in satoshis) to be received by `destination` onchain. Must be
458	/// >= [P2TR_DUST](bitcoin_ext::P2TR_DUST). Server-configured fees laid out in
459	/// [OffboardFees](crate::cli::fees::OffboardFees) will be added on top of this amount.
460	pub amount_sat: u64,
461}
462
463#[derive(Serialize, Deserialize)]
464#[cfg_attr(feature = "utoipa", derive(ToSchema))]
465pub struct OffboardVtxosRequest {
466	/// Optional Bitcoin address to send to. If not provided, uses the onchain wallet's address
467	pub address: Option<String>,
468	/// List of VTXO IDs to offboard. The sum of the VTXOs being refreshed must be
469	/// >= [P2TR_DUST](bitcoin_ext::P2TR_DUST) after the server-configured
470	/// [OffboardFees](crate::cli::fees::OffboardFees) are deducted.
471	pub vtxos: Vec<String>,
472}
473
474#[derive(Serialize, Deserialize)]
475#[cfg_attr(feature = "utoipa", derive(ToSchema))]
476pub struct OffboardAllRequest {
477	/// Optional Bitcoin address to send to. If not provided, uses the onchain wallet's address
478	pub address: Option<String>,
479}
480
481#[derive(Serialize, Deserialize)]
482#[cfg_attr(feature = "utoipa", derive(ToSchema))]
483pub struct ImportVtxoRequest {
484	/// Hex-encoded VTXOs to import
485	pub vtxos: Vec<String>,
486}
487
488#[derive(Serialize, Deserialize)]
489#[cfg_attr(feature = "utoipa", derive(ToSchema))]
490pub struct LightningInvoiceRequest {
491	/// The amount to create invoice for (in satoshis). This is the amount the payee will pay but
492	/// the final amount received by the client will have any server-configured
493	/// [LightningReceiveFees](crate::cli::fees::LightningReceiveFees) deducted.
494	pub amount_sat: u64,
495	/// Optional description embedded in the invoice as its memo.
496	#[serde(default, skip_serializing_if = "Option::is_none")]
497	pub description: Option<String>,
498	/// Optional lightning receive token for authentication of the claim, if
499	/// the server requires one and there are no existing spendable VTXOs to
500	/// prove ownership of.
501	#[serde(default, skip_serializing_if = "Option::is_none")]
502	pub token: Option<String>,
503}
504
505#[derive(Serialize, Deserialize)]
506#[cfg_attr(feature = "utoipa", derive(ToSchema))]
507pub struct LightningInvoiceForAddressRequest {
508	/// The amount to create invoice for (in satoshis).
509	pub amount_sat: u64,
510	/// Ark address that will receive the claimed VTXO.
511	pub address: String,
512	/// Optional description embedded in the invoice as its memo.
513	#[serde(default, skip_serializing_if = "Option::is_none")]
514	pub description: Option<String>,
515}
516
517#[derive(Serialize, Deserialize)]
518#[cfg_attr(feature = "utoipa", derive(ToSchema))]
519pub struct LightningPayRequest {
520	/// The invoice, offer, or lightning address to pay
521	pub destination: String,
522	/// The amount to send (in satoshis). Optional for bolt11 invoices with amount. This must be
523	/// higher than the minimum fee laid out in server-configured
524	/// [LightningSendFees](crate::cli::fees::LightningSendFees). The wallet must also contain enough
525	/// funds to cover the amount plus any fees.
526	pub amount_sat: Option<u64>,
527	/// An optional comment, only supported when paying to lightning addresses
528	pub comment: Option<String>,
529}
530
531#[derive(Serialize, Deserialize)]
532#[cfg_attr(feature = "utoipa", derive(ToSchema))]
533pub struct LightningPayResponse {
534	/// Success message
535	pub message: String,
536	/// The payment hash of the lightning payment. Can be used to poll the
537	/// payment status.
538	#[serde(default, skip_serializing_if = "Option::is_none")]
539	#[cfg_attr(feature = "utoipa", schema(value_type = Option<String>))]
540	pub payment_hash: Option<PaymentHash>,
541}
542
543#[derive(Serialize, Deserialize)]
544#[cfg_attr(feature = "utoipa", derive(ToSchema))]
545pub struct OnchainSendRequest {
546	/// The destination Bitcoin address
547	pub destination: String,
548	/// The amount to send (in satoshis)
549	pub amount_sat: u64,
550}
551
552#[derive(Serialize, Deserialize)]
553#[cfg_attr(feature = "utoipa", derive(ToSchema))]
554pub struct OnchainSendManyRequest {
555	/// List of destinations in format "address:amount"
556	pub destinations: Vec<String>,
557	/// Sends the transaction immediately instead of waiting
558	pub immediate: Option<bool>,
559}
560
561#[derive(Serialize, Deserialize)]
562#[cfg_attr(feature = "utoipa", derive(ToSchema))]
563pub struct OnchainDrainRequest {
564	/// The destination Bitcoin address
565	pub destination: String,
566}
567
568#[derive(Serialize, Deserialize)]
569#[cfg_attr(feature = "utoipa", derive(ToSchema))]
570pub struct ExitStatusRequest {
571	/// Whether to include the detailed history of the exit process
572	pub history: Option<bool>,
573	/// Whether to include the exit transactions and their CPFP children
574	pub transactions: Option<bool>,
575}
576
577#[derive(Serialize, Deserialize)]
578#[cfg_attr(feature = "utoipa", derive(ToSchema))]
579pub struct ExitStartRequest {
580	/// The ID of VTXOs to unilaterally exit
581	pub vtxos: Vec<String>,
582}
583
584#[derive(Serialize, Deserialize)]
585#[cfg_attr(feature = "utoipa", derive(ToSchema))]
586pub struct ExitStartResponse {
587	pub message: String,
588}
589
590#[derive(Serialize, Deserialize)]
591#[cfg_attr(feature = "utoipa", derive(ToSchema))]
592pub struct ExitProgressRequest {
593	/// Wait until the exit is completed
594	pub wait: Option<bool>,
595	/// Sets the desired fee-rate in sats/kvB to use broadcasting exit transactions
596	pub fee_rate: Option<u64>,
597}
598
599#[derive(Serialize, Deserialize)]
600#[cfg_attr(feature = "utoipa", derive(ToSchema))]
601pub struct ExitClaimAllRequest {
602	/// The destination Bitcoin address
603	pub destination: String,
604	/// Sets the desired fee-rate in sats/kvB to use broadcasting exit transactions
605	pub fee_rate: Option<u64>,
606}
607
608#[derive(Serialize, Deserialize)]
609#[cfg_attr(feature = "utoipa", derive(ToSchema))]
610pub struct ExitClaimVtxosRequest {
611	/// The destination Bitcoin address
612	pub destination: String,
613	/// The ID of an exited VTXO to be claimed
614	pub vtxos: Vec<String>,
615	/// Sets the desired fee-rate in sats/kvB to use broadcasting exit transactions
616	pub fee_rate: Option<u64>,
617}
618
619#[derive(Serialize, Deserialize)]
620#[cfg_attr(feature = "utoipa", derive(ToSchema))]
621pub struct ExitClaimResponse {
622	pub message: String,
623}
624
625#[derive(Serialize, Deserialize)]
626#[cfg_attr(feature = "utoipa", derive(ToSchema))]
627pub struct ExitCancelResponse {
628	pub message: String,
629}
630
631
632#[derive(Serialize, Deserialize)]
633#[cfg_attr(feature = "utoipa", derive(ToSchema))]
634pub struct VtxoRequestInfo {
635	#[serde(rename = "amount_sat", with = "bitcoin::amount::serde::as_sat")]
636	#[cfg_attr(feature = "utoipa", schema(value_type = u64))]
637	pub amount: Amount,
638	#[cfg_attr(feature = "utoipa", schema(value_type = String))]
639	pub policy_type: VtxoPolicyKind,
640	#[cfg_attr(feature = "utoipa", schema(value_type = String))]
641	pub user_pubkey: PublicKey,
642}
643
644impl<'a> From<&'a ark::VtxoRequest> for VtxoRequestInfo {
645	fn from(v: &'a ark::VtxoRequest) -> Self {
646		Self {
647			amount: v.amount,
648			policy_type: v.policy.policy_type(),
649			user_pubkey: v.policy.user_pubkey(),
650		}
651	}
652}
653
654#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
655#[cfg_attr(feature = "utoipa", derive(ToSchema))]
656pub struct OffboardRequestInfo {
657	/// hexadecimal representation of the output script
658	pub script_pubkey_hex: String,
659	/// opcode representation of the output script
660	pub script_pubkey_asm: String,
661	/// The target amount in sats.
662	#[serde(rename = "net_amount_sat", with = "bitcoin::amount::serde::as_sat")]
663	#[cfg_attr(feature = "utoipa", schema(value_type = u64))]
664	pub net_amount: Amount,
665	/// Determines whether fees should be added onto the given amount or deducted from it.
666	pub deduct_fees_from_gross_amount: bool,
667	/// What fee rate was used when calculating the fee for the offboard.
668	#[serde(rename = "fee_rate_kwu")]
669	#[cfg_attr(feature = "utoipa", schema(value_type = u64))]
670	pub fee_rate: FeeRate,
671}
672
673impl<'a> From<&'a OffboardRequest> for OffboardRequestInfo {
674	fn from(v: &'a OffboardRequest) -> Self {
675		Self {
676			script_pubkey_hex: v.script_pubkey.to_hex_string(),
677			script_pubkey_asm: v.script_pubkey.to_asm_string(),
678			net_amount: v.net_amount,
679			deduct_fees_from_gross_amount: v.deduct_fees_from_gross_amount,
680			fee_rate: v.fee_rate,
681		}
682	}
683}
684
685#[derive(Serialize, Deserialize)]
686#[cfg_attr(feature = "utoipa", derive(ToSchema))]
687pub struct RoundParticipationInfo {
688	#[cfg_attr(feature = "utoipa", schema(value_type = Vec<String>))]
689	pub inputs: Vec<VtxoId>,
690	pub outputs: Vec<VtxoRequestInfo>,
691}
692
693impl<'a> From<&'a bark::round::RoundParticipation> for RoundParticipationInfo {
694	fn from(v: &'a bark::round::RoundParticipation) -> Self {
695		Self {
696			inputs: v.inputs.iter().map(|v| v.id()).collect(),
697			outputs: v.outputs.iter().map(Into::into).collect(),
698		}
699	}
700}
701
702#[derive(Serialize, Deserialize)]
703#[cfg_attr(feature = "utoipa", derive(ToSchema))]
704pub struct PendingRoundInfo {
705	/// Unique identifier for the round
706	pub id: u32,
707	/// the current status of the round
708	pub status: RoundStatus,
709	/// the round participation details
710	pub participation: RoundParticipationInfo,
711	#[cfg_attr(feature = "utoipa", schema(value_type = String, nullable = true))]
712	pub unlock_hash: Option<UnlockHash>,
713	/// The round transaction id, if already assigned
714	#[cfg_attr(feature = "utoipa", schema(value_type = String, nullable = true))]
715	pub funding_txid: Option<Txid>,
716	pub funding_tx_hex: Option<String>,
717}
718
719impl PendingRoundInfo {
720	pub fn new<G>(
721		state: &bark::persist::models::StoredRoundState<G>,
722		sync_result: anyhow::Result<bark::round::RoundStatus>,
723	) -> Self {
724		let funding_tx = state.state().funding_tx();
725		Self {
726			id: state.id().0,
727			status: match sync_result {
728				Ok(status) => status.into(),
729				Err(e) => RoundStatus::SyncError {
730					error: format!("{:#}", e),
731				},
732			},
733			participation: state.state().participation().into(),
734			unlock_hash: state.state().unlock_hash(),
735			funding_txid: funding_tx.map(|t| t.compute_txid()),
736			funding_tx_hex: funding_tx.map(|t| serialize_hex(t)),
737		}
738	}
739}
740
741#[derive(Serialize, Deserialize)]
742#[cfg_attr(feature = "utoipa", derive(ToSchema))]
743pub struct WalletExistsResponse {
744	pub fingerprint: Option<String>,
745}
746
747#[derive(Serialize, Deserialize)]
748#[cfg_attr(feature = "utoipa", derive(ToSchema))]
749pub struct WalletDeleteRequest {
750	pub dangerous: bool,
751	pub fingerprint: String,
752}
753
754#[derive(Serialize, Deserialize)]
755#[cfg_attr(feature = "utoipa", derive(ToSchema))]
756pub struct WalletDeleteResponse {
757	pub deleted: bool,
758	pub message: String,
759}