Skip to main content

breez_sdk_spark/models/
token_allowance.rs

1use std::str::FromStr;
2
3use serde::{Deserialize, Serialize};
4
5use crate::{Payment, PaymentStatus, SignedTransferPackage};
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
8#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
9pub enum TokenAllowanceLimit {
10    Unlimited,
11    Amount { amount: u128 },
12}
13
14#[derive(Debug, Clone)]
15#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
16pub struct CreateTokenAllowanceRequest {
17    /// The spender's Spark address.
18    pub spender_address: String,
19    pub token_identifier: String,
20    /// The most a single pull may move.
21    pub max_per_payment: TokenAllowanceLimit,
22    /// The most all pulls together may move.
23    pub max_total: TokenAllowanceLimit,
24    /// When the allowance expires, in Unix seconds.
25    pub expiry_time: u64,
26    /// Spark addresses the spender may pay, or empty to allow any recipient.
27    pub allowed_recipients: Vec<String>,
28}
29
30#[derive(Debug, Clone, Serialize)]
31#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
32pub struct CreateTokenAllowanceResponse {
33    pub allowance: TokenAllowance,
34}
35
36#[derive(Debug, Clone)]
37#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
38pub struct RevokeTokenAllowanceRequest {
39    pub allowance_id: String,
40}
41
42#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
43#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
44pub enum TokenAllowanceRole {
45    Owner,
46    Spender,
47}
48
49impl FromStr for TokenAllowanceRole {
50    type Err = String;
51
52    fn from_str(s: &str) -> Result<Self, Self::Err> {
53        match s.to_lowercase().as_str() {
54            "owner" => Ok(Self::Owner),
55            "spender" => Ok(Self::Spender),
56            _ => Err(format!("Invalid token allowance role '{s}'")),
57        }
58    }
59}
60
61#[derive(Debug, Clone)]
62#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
63pub struct ListTokenAllowancesRequest {
64    pub role: TokenAllowanceRole,
65    #[cfg_attr(feature = "uniffi", uniffi(default = None))]
66    pub counterparty_address: Option<String>,
67    #[cfg_attr(feature = "uniffi", uniffi(default = None))]
68    pub token_identifier: Option<String>,
69    #[cfg_attr(feature = "uniffi", uniffi(default = None))]
70    pub include_inactive: Option<bool>,
71    #[cfg_attr(feature = "uniffi", uniffi(default = None))]
72    pub offset: Option<u32>,
73    #[cfg_attr(feature = "uniffi", uniffi(default = None))]
74    pub limit: Option<u32>,
75}
76
77#[derive(Debug, Clone, Serialize)]
78#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
79pub struct ListTokenAllowancesResponse {
80    pub allowances: Vec<TokenAllowance>,
81}
82
83#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
84#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
85pub enum TokenAllowanceStatus {
86    Active,
87    Exhausted,
88    Expired,
89    Revoked,
90}
91
92#[derive(Debug, Clone, Serialize)]
93#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
94pub struct TokenAllowance {
95    pub id: String,
96    pub owner_address: String,
97    pub spender_address: String,
98    pub token_identifier: String,
99    /// The most a single pull may move.
100    pub max_per_payment: TokenAllowanceLimit,
101    /// The most all pulls together may move.
102    pub max_total: TokenAllowanceLimit,
103    /// The amount of every pull sent so far, including pulls that later failed, so it can be
104    /// higher than what was actually pulled.
105    pub spent_amount: u128,
106    /// Spark addresses the spender may pay, or empty to allow any recipient.
107    pub allowed_recipients: Vec<String>,
108    /// When the allowance expires, in Unix seconds.
109    pub expiry_time: u64,
110    pub created_at: u64,
111    pub revoked_at: Option<u64>,
112    pub status: TokenAllowanceStatus,
113}
114
115#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
116#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
117pub struct PullReceiver {
118    pub amount: u128,
119    /// The receiver's Spark address, or unset to pay this wallet. Responses always set it.
120    #[cfg_attr(feature = "uniffi", uniffi(default = None))]
121    pub receiver_address: Option<String>,
122}
123
124#[derive(Debug, Clone)]
125#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
126pub struct PreparePullPaymentRequest {
127    /// The payer's Spark address.
128    pub payer_address: String,
129    pub token_identifier: String,
130    pub receivers: Vec<PullReceiver>,
131}
132
133#[derive(Debug, Clone, Serialize)]
134#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
135pub struct PreparePullPaymentResponse {
136    pub payer_address: String,
137    pub token_identifier: String,
138    pub receivers: Vec<PullReceiver>,
139    pub amount: u128,
140    pub allowance_id: String,
141    /// When the prepared pull stops being sendable, in Unix seconds.
142    pub expiry_time: u64,
143    /// Opaque data describing the prepared pull, to pass back unchanged.
144    pub pull_context: Vec<u8>,
145}
146
147#[derive(Debug, Clone)]
148#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
149pub struct PullPaymentRequest {
150    pub prepare_response: PreparePullPaymentResponse,
151}
152
153#[derive(Debug, Clone, Serialize)]
154#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
155pub struct PullPaymentResponse {
156    pub tx_hash: String,
157    /// Pending while the pull is accepted but not final yet (repeat the same call to refresh
158    /// it), otherwise completed.
159    pub status: PaymentStatus,
160    /// This wallet's payment from the pull, unset while the pull is pending or when this wallet
161    /// isn't one of its receivers.
162    pub payment: Option<Payment>,
163}
164
165#[derive(Debug, Clone)]
166#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
167pub struct BuildUnsignedPullPackageRequest {
168    pub prepare_response: PreparePullPaymentResponse,
169}
170
171#[derive(Debug, Clone)]
172#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
173pub struct PublishSignedPullPackageRequest {
174    pub signed_package: SignedTransferPackage,
175}
176
177impl From<TokenAllowanceLimit> for Option<u128> {
178    fn from(limit: TokenAllowanceLimit) -> Self {
179        match limit {
180            TokenAllowanceLimit::Unlimited => None,
181            TokenAllowanceLimit::Amount { amount } => Some(amount),
182        }
183    }
184}
185
186impl From<Option<u128>> for TokenAllowanceLimit {
187    fn from(limit: Option<u128>) -> Self {
188        match limit {
189            Some(amount) => Self::Amount { amount },
190            None => Self::Unlimited,
191        }
192    }
193}
194
195impl From<TokenAllowanceRole> for spark_wallet::TokenAllowanceRole {
196    fn from(role: TokenAllowanceRole) -> Self {
197        match role {
198            TokenAllowanceRole::Owner => Self::Owner,
199            TokenAllowanceRole::Spender => Self::Spender,
200        }
201    }
202}
203
204impl From<spark_wallet::TokenAllowanceStatus> for TokenAllowanceStatus {
205    fn from(status: spark_wallet::TokenAllowanceStatus) -> Self {
206        match status {
207            spark_wallet::TokenAllowanceStatus::Active => Self::Active,
208            spark_wallet::TokenAllowanceStatus::Exhausted => Self::Exhausted,
209            spark_wallet::TokenAllowanceStatus::Expired => Self::Expired,
210            spark_wallet::TokenAllowanceStatus::Revoked => Self::Revoked,
211        }
212    }
213}