strike_rs/
invoice.rs

1//! Handle invoice creation
2
3use anyhow::{bail, Result};
4use serde::{Deserialize, Serialize};
5
6use crate::{Amount, ConversionRate, InvoiceState, Strike};
7
8/// Invoice Request
9#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
10#[serde(rename_all = "camelCase")]
11pub struct InvoiceRequest {
12    /// Correlation ID
13    pub correlation_id: Option<String>,
14    /// Invoice description
15    pub description: Option<String>,
16    /// Invoice [`Amount`]
17    pub amount: Amount,
18}
19
20/// Invoice Response
21#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
22#[serde(rename_all = "camelCase")]
23pub struct InvoiceResponse {
24    /// Invoice ID
25    pub invoice_id: String,
26    /// Invoice [`Amount`]
27    pub amount: Amount,
28    /// Invoice State
29    pub state: InvoiceState,
30    /// Created timestamp
31    pub created: String,
32    /// Invoice Description
33    pub description: Option<String>,
34    /// Isser ID
35    pub issuer_id: String,
36    /// Receiver ID
37    pub receiver_id: String,
38}
39
40/// Invoice Response
41#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
42#[serde(rename_all = "camelCase")]
43pub struct InvoiceQuoteResponse {
44    /// Invoice Quote ID
45    pub quote_id: String,
46    /// Invoice description
47    pub description: Option<String>,
48    /// Bolt11 invoice
49    pub ln_invoice: String,
50    /// Onchain Address
51    pub onchain_address: Option<String>,
52    /// Expiration of quote
53    pub expiration: String,
54    /// Experition in secs
55    pub expiration_in_sec: u64,
56    /// Source Amount
57    pub source_amount: Amount,
58    /// Target Amount
59    pub target_amount: Amount,
60    /// Conversion Rate
61    pub conversion_rate: ConversionRate,
62}
63
64impl Strike {
65    /// Create Invoice
66    pub async fn create_invoice(&self, invoice_request: InvoiceRequest) -> Result<InvoiceResponse> {
67        let url = self.base_url.join("/v1/invoices")?;
68
69        let res = self
70            .make_post(url, Some(serde_json::to_value(invoice_request)?))
71            .await?;
72
73        match serde_json::from_value(res.clone()) {
74            Ok(res) => Ok(res),
75            Err(_) => {
76                log::error!("Api error response on invoice creation");
77                log::error!("{}", res);
78                bail!("Could not create invoice")
79            }
80        }
81    }
82
83    /// Find incoming invoice
84    pub async fn get_incoming_invoice(&self, invoice_id: &str) -> Result<InvoiceResponse> {
85        let url = self.base_url.join("/v1/invoices/")?.join(invoice_id)?;
86
87        let res = self.make_get(url).await?;
88
89        match serde_json::from_value(res.clone()) {
90            Ok(res) => Ok(res),
91            Err(_) => {
92                log::error!("Api error response on find invoice");
93                log::error!("{}", res);
94                bail!("Could not find invoice")
95            }
96        }
97    }
98
99    /// Invoice quote
100    pub async fn invoice_quote(&self, invoice_id: &str) -> Result<InvoiceQuoteResponse> {
101        let url = self
102            .base_url
103            .join(&format!("/v1/invoices/{invoice_id}/quote"))?;
104
105        let res = self.make_post(url, None::<String>).await?;
106
107        match serde_json::from_value(res.clone()) {
108            Ok(res) => Ok(res),
109            Err(_) => {
110                log::error!("Api error response on invoice quote");
111                log::error!("{}", res);
112                bail!("Could get invoice quote")
113            }
114        }
115    }
116}