1use std::collections::HashMap;
3
4use serde::{Deserialize, Serialize};
5
6use crate::error::NodelessError;
7use crate::serde_utils::{opt_serde_timestamp, serde_timestamp};
8use crate::Nodeless;
9
10#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
12pub enum PaywallType {
13 #[serde(rename = "content")]
14 Content,
15 #[serde(rename = "download")]
16 Download,
17 #[serde(rename = "redirect")]
18 Redirect,
19 #[serde(rename = "wp_article")]
20 WPArticle,
21}
22
23#[derive(Clone, Debug, Deserialize, Serialize)]
25pub struct Paywall {
26 #[serde(skip_serializing_if = "Option::is_none")]
27 pub id: Option<String>,
28 pub name: Option<String>,
29 #[serde(rename = "type")]
30 pub type_: PaywallType,
31 pub price: u64,
32 pub settings: Option<HashMap<String, String>>,
33 #[serde(with = "opt_serde_timestamp")]
34 pub created_at: Option<i64>,
35 #[serde(with = "opt_serde_timestamp")]
36 pub updated_at: Option<i64>,
37}
38
39#[derive(Clone, Debug, Deserialize, Serialize)]
41#[serde(rename_all = "camelCase")]
42pub struct PaywallRequest {
43 pub id: String,
44 pub sats_amount: u64,
45 pub status: String,
46 pub metadata: Option<Vec<String>>,
47 #[serde(with = "serde_timestamp")]
48 pub created_at: i64,
49 #[serde(with = "opt_serde_timestamp")]
50 pub paid_at: Option<i64>,
51 pub onchain_address: String,
52 pub lightning_invoice: String,
53 pub paywall: Option<Paywall>,
54}
55
56impl Nodeless {
57 pub async fn create_paywall(&self, paywall: Paywall) -> Result<Paywall, NodelessError> {
59 let url = self.base_url.join("api/v1/paywall")?;
60
61 let res = self
62 .make_post(url, Some(serde_json::to_value(paywall)?))
63 .await?;
64 Ok(serde_json::from_value(res["data"].to_owned())?)
65 }
66
67 pub async fn get_paywalls(&self) -> Result<Vec<Paywall>, NodelessError> {
69 let url = self.base_url.join("api/v1/paywall")?;
70
71 let res = self.make_get(url).await?;
72 Ok(serde_json::from_value(res["data"].clone())?)
73 }
74
75 pub async fn get_paywall(&self, paywall_id: &str) -> Result<Option<Paywall>, NodelessError> {
77 let url = self
78 .base_url
79 .join(&format!("api/v1/paywall/{}", paywall_id))?;
80
81 let res = self.make_get(url).await?;
82 Ok(serde_json::from_value(res["data"].clone())?)
83 }
84
85 pub async fn update_paywall(&self, id: &str, paywall: Paywall) -> Result<(), NodelessError> {
87 let url = self.base_url.join(&format!("api/v1/paywall/{}", id))?;
88 let _res = self
89 .make_put(url, Some(serde_json::to_value(paywall)?))
90 .await?;
91 Ok(())
92 }
93
94 pub async fn delete_paywall(&self, paywall_id: &str) -> Result<(), NodelessError> {
96 let url = self
97 .base_url
98 .join(&format!("api/v1/paywall/{}", paywall_id))?;
99 let _res = self.make_delete(url).await?;
100 Ok(())
101 }
102
103 pub async fn create_paywall_request(
105 &self,
106 paywall_id: &str,
107 ) -> Result<PaywallRequest, NodelessError> {
108 let url = self
109 .base_url
110 .join(&format!("api/v1/paywall/{}/request", paywall_id))?;
111
112 let res = self.make_post(url, None).await?;
113 Ok(serde_json::from_value(res["data"].to_owned())?)
114 }
115
116 pub async fn get_paywall_request(
118 &self,
119 paywall_id: &str,
120 request_id: &str,
121 ) -> Result<PaywallRequest, NodelessError> {
122 let url = self
123 .base_url
124 .join(&format!("api/v1/paywall/{paywall_id}/request/{request_id}"))?;
125
126 let res = &self.make_get(url).await?["data"];
127
128 Ok(serde_json::from_value(res.to_owned())?)
129 }
130
131 pub async fn get_paywall_request_status(
133 &self,
134 paywall_id: &str,
135 request_id: &str,
136 ) -> Result<String, NodelessError> {
137 let url = self.base_url.join(&format!(
138 "api/v1/paywall/{paywall_id}/request/{request_id}/status"
139 ))?;
140
141 let res = self.make_get(url).await?;
142 Ok(serde_json::from_value(res["status"].to_owned())?)
143 }
144}