1use alloy_primitives::U256;
2use serde::{Deserialize, Serialize};
3
4pub mod codec;
5
6const DEFAULT_ASSET_ADDRESS: &str = "0x0000000000000000000000000000000000000000";
7
8pub const GUARANTEE_CLAIMS_VERSION: u64 = 1;
9
10#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
11pub struct PaymentGuaranteeClaims {
12 pub domain: [u8; 32],
13 pub user_address: String,
14 pub recipient_address: String,
15 pub tab_id: U256,
16 pub req_id: U256,
17 pub amount: U256,
18 pub total_amount: U256,
19 pub asset_address: String,
20 pub timestamp: u64,
21 pub version: u64,
22}
23
24impl PaymentGuaranteeClaims {
25 pub fn from_request(
26 request: &PaymentGuaranteeRequestClaims,
27 domain: [u8; 32],
28 total_amount: U256,
29 ) -> Self {
30 match request {
31 PaymentGuaranteeRequestClaims::V1(claims) => Self {
32 domain,
33 user_address: claims.user_address.clone(),
34 recipient_address: claims.recipient_address.clone(),
35 tab_id: claims.tab_id,
36 req_id: claims.req_id,
37 amount: claims.amount,
38 total_amount,
39 asset_address: claims.asset_address.clone(),
40 timestamp: claims.timestamp,
41 version: GUARANTEE_CLAIMS_VERSION,
42 },
43 }
44 }
45}
46
47impl TryInto<Vec<u8>> for PaymentGuaranteeClaims {
48 type Error = anyhow::Error;
49
50 fn try_into(self) -> Result<Vec<u8>, Self::Error> {
51 codec::encode_guarantee_claims(self)
52 .map_err(|e| anyhow::anyhow!("Failed to encode guarantee bytes: {}", e))
53 }
54}
55
56impl TryFrom<&[u8]> for PaymentGuaranteeClaims {
57 type Error = anyhow::Error;
58
59 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
60 let claims = codec::decode_guarantee_claims(value)?;
61 Ok(claims)
62 }
63}
64
65#[derive(Debug, Clone, Serialize, Deserialize)]
66pub struct PaymentGuaranteeRequestClaimsV1 {
67 pub user_address: String,
68 pub recipient_address: String,
69 pub tab_id: U256,
70 pub req_id: U256,
71 pub amount: U256,
72 pub asset_address: String,
73 pub timestamp: u64,
74}
75
76impl PaymentGuaranteeRequestClaimsV1 {
77 pub fn new(
78 user_address: String,
79 recipient_address: String,
80 tab_id: U256,
81 req_id: U256,
82 amount: U256,
83 timestamp: u64,
84 erc20_token: Option<String>,
85 ) -> Self {
86 let asset_address = erc20_token.unwrap_or(DEFAULT_ASSET_ADDRESS.to_string());
87 Self {
88 user_address,
89 recipient_address,
90 tab_id,
91 req_id,
92 amount,
93 asset_address,
94 timestamp,
95 }
96 }
97}
98
99pub trait PaymentGuaranteeRequestEssentials {
100 fn user_address(&self) -> &str;
101
102 fn recipient_address(&self) -> &str;
103
104 fn tab_id(&self) -> U256;
105
106 fn amount(&self) -> U256;
107}
108
109impl PaymentGuaranteeRequestEssentials for PaymentGuaranteeRequestClaims {
110 fn user_address(&self) -> &str {
111 match self {
112 PaymentGuaranteeRequestClaims::V1(claims) => &claims.user_address,
113 }
114 }
115
116 fn recipient_address(&self) -> &str {
117 match self {
118 PaymentGuaranteeRequestClaims::V1(claims) => &claims.recipient_address,
119 }
120 }
121
122 fn tab_id(&self) -> U256 {
123 match self {
124 PaymentGuaranteeRequestClaims::V1(claims) => claims.tab_id,
125 }
126 }
127
128 fn amount(&self) -> U256 {
129 match self {
130 PaymentGuaranteeRequestClaims::V1(claims) => claims.amount,
131 }
132 }
133}
134
135#[derive(Debug, Clone, Serialize, Deserialize)]
136#[serde(rename_all = "snake_case", tag = "version")]
137pub enum PaymentGuaranteeRequestClaims {
138 V1(PaymentGuaranteeRequestClaimsV1),
139}
140
141#[derive(Debug, Clone, Serialize, Deserialize)]
142#[serde(rename_all = "snake_case")]
143pub enum SigningScheme {
144 Eip712,
145 Eip191, }
147
148#[derive(Debug, Clone, Serialize, Deserialize)]
149pub struct PaymentGuaranteeRequest {
150 pub claims: PaymentGuaranteeRequestClaims,
151 pub signature: String,
153 pub scheme: SigningScheme,
154}
155
156impl PaymentGuaranteeRequest {
157 pub fn new(
158 claims: PaymentGuaranteeRequestClaims,
159 signature: String,
160 scheme: SigningScheme,
161 ) -> Self {
162 Self {
163 claims,
164 signature,
165 scheme,
166 }
167 }
168}