1use std::collections::HashMap;
4
5use serde::{Deserialize, Serialize};
6
7use super::amount::CurrencyUnit;
8use crate::error::FfiError;
9
10#[derive(Debug, Clone, Serialize, Deserialize, uniffi::Record)]
12pub struct KeySetInfo {
13 pub id: String,
14 pub unit: CurrencyUnit,
15 pub active: bool,
16 pub input_fee_ppk: u64,
18}
19
20impl From<cdk::nuts::KeySetInfo> for KeySetInfo {
21 fn from(keyset: cdk::nuts::KeySetInfo) -> Self {
22 Self {
23 id: keyset.id.to_string(),
24 unit: keyset.unit.into(),
25 active: keyset.active,
26 input_fee_ppk: keyset.input_fee_ppk,
27 }
28 }
29}
30
31impl TryFrom<KeySetInfo> for cdk::nuts::KeySetInfo {
32 type Error = FfiError;
33
34 fn try_from(keyset: KeySetInfo) -> Result<Self, Self::Error> {
35 use std::str::FromStr;
36
37 Ok(Self {
38 id: cdk::nuts::Id::from_str(&keyset.id)
39 .map_err(|e| FfiError::internal(format!("Invalid keyset ID: {}", e)))?,
40 unit: keyset.unit.into(),
41 active: keyset.active,
42 final_expiry: None,
43 input_fee_ppk: keyset.input_fee_ppk,
44 })
45 }
46}
47
48impl KeySetInfo {
49 pub fn to_json(&self) -> Result<String, FfiError> {
51 Ok(serde_json::to_string(self)?)
52 }
53}
54
55#[uniffi::export]
57pub fn decode_key_set_info(json: String) -> Result<KeySetInfo, FfiError> {
58 Ok(serde_json::from_str(&json)?)
59}
60
61#[uniffi::export]
63pub fn encode_key_set_info(info: KeySetInfo) -> Result<String, FfiError> {
64 Ok(serde_json::to_string(&info)?)
65}
66
67#[derive(Debug, Clone, Copy, uniffi::Enum)]
69pub enum KeysetFilter {
70 Active,
72 All,
74}
75
76impl From<KeysetFilter> for cdk_common::wallet::KeysetFilter {
77 fn from(filter: KeysetFilter) -> Self {
78 match filter {
79 KeysetFilter::Active => cdk_common::wallet::KeysetFilter::Active,
80 KeysetFilter::All => cdk_common::wallet::KeysetFilter::All,
81 }
82 }
83}
84
85#[derive(Debug, Clone, Serialize, Deserialize, uniffi::Record)]
87#[serde(transparent)]
88pub struct PublicKey {
89 pub hex: String,
91}
92
93impl From<cdk::nuts::PublicKey> for PublicKey {
94 fn from(key: cdk::nuts::PublicKey) -> Self {
95 Self {
96 hex: key.to_string(),
97 }
98 }
99}
100
101impl TryFrom<PublicKey> for cdk::nuts::PublicKey {
102 type Error = FfiError;
103
104 fn try_from(key: PublicKey) -> Result<Self, Self::Error> {
105 key.hex
106 .parse()
107 .map_err(|e| FfiError::internal(format!("Invalid public key: {}", e)))
108 }
109}
110
111#[derive(Debug, Clone, Serialize, Deserialize, uniffi::Record)]
113pub struct Keys {
114 pub keys: HashMap<u64, String>,
116}
117
118impl From<cdk::nuts::Keys> for Keys {
119 fn from(keys: cdk::nuts::Keys) -> Self {
120 Self {
121 keys: keys
122 .keys()
123 .iter()
124 .map(|(amount, pubkey)| (u64::from(*amount), pubkey.to_string()))
125 .collect(),
126 }
127 }
128}
129
130impl TryFrom<Keys> for cdk::nuts::Keys {
131 type Error = FfiError;
132
133 fn try_from(keys: Keys) -> Result<Self, Self::Error> {
134 use std::collections::BTreeMap;
135 use std::str::FromStr;
136
137 let mut keys_map = BTreeMap::new();
139 for (amount_u64, pubkey_hex) in keys.keys {
140 let amount = cdk::Amount::from(amount_u64);
141 let pubkey = cdk::nuts::PublicKey::from_str(&pubkey_hex)
142 .map_err(|e| FfiError::internal(format!("Invalid public key: {}", e)))?;
143 keys_map.insert(amount, pubkey);
144 }
145
146 Ok(cdk::nuts::Keys::new(keys_map))
147 }
148}
149
150impl Keys {
151 pub fn to_json(&self) -> Result<String, FfiError> {
153 Ok(serde_json::to_string(self)?)
154 }
155}
156
157#[uniffi::export]
159pub fn decode_keys(json: String) -> Result<Keys, FfiError> {
160 Ok(serde_json::from_str(&json)?)
161}
162
163#[uniffi::export]
165pub fn encode_keys(keys: Keys) -> Result<String, FfiError> {
166 Ok(serde_json::to_string(&keys)?)
167}
168
169#[derive(Debug, Clone, Serialize, Deserialize, uniffi::Record)]
171pub struct KeySet {
172 pub id: String,
174 pub unit: CurrencyUnit,
176 pub active: Option<bool>,
178 pub input_fee_ppk: u64,
180 pub keys: HashMap<u64, String>,
182 pub final_expiry: Option<u64>,
184}
185
186impl From<cdk::nuts::KeySet> for KeySet {
187 fn from(keyset: cdk::nuts::KeySet) -> Self {
188 Self {
189 id: keyset.id.to_string(),
190 unit: keyset.unit.into(),
191 active: keyset.active,
192 input_fee_ppk: keyset.input_fee_ppk,
193 keys: keyset
194 .keys
195 .keys()
196 .iter()
197 .map(|(amount, pubkey)| (u64::from(*amount), pubkey.to_string()))
198 .collect(),
199 final_expiry: keyset.final_expiry,
200 }
201 }
202}
203
204impl TryFrom<KeySet> for cdk::nuts::KeySet {
205 type Error = FfiError;
206
207 fn try_from(keyset: KeySet) -> Result<Self, Self::Error> {
208 use std::collections::BTreeMap;
209 use std::str::FromStr;
210
211 let id = cdk::nuts::Id::from_str(&keyset.id)
213 .map_err(|e| FfiError::internal(format!("Invalid keyset ID: {}", e)))?;
214
215 let unit: cdk::nuts::CurrencyUnit = keyset.unit.into();
217
218 let mut keys_map = BTreeMap::new();
220 for (amount_u64, pubkey_hex) in keyset.keys {
221 let amount = cdk::Amount::from(amount_u64);
222 let pubkey = cdk::nuts::PublicKey::from_str(&pubkey_hex)
223 .map_err(|e| FfiError::internal(format!("Invalid public key: {}", e)))?;
224 keys_map.insert(amount, pubkey);
225 }
226 let keys = cdk::nuts::Keys::new(keys_map);
227
228 Ok(cdk::nuts::KeySet {
229 id,
230 unit,
231 active: keyset.active,
232 input_fee_ppk: keyset.input_fee_ppk,
233 keys,
234 final_expiry: keyset.final_expiry,
235 })
236 }
237}
238
239impl KeySet {
240 pub fn to_json(&self) -> Result<String, FfiError> {
242 Ok(serde_json::to_string(self)?)
243 }
244}
245
246#[uniffi::export]
248pub fn decode_key_set(json: String) -> Result<KeySet, FfiError> {
249 Ok(serde_json::from_str(&json)?)
250}
251
252#[uniffi::export]
254pub fn encode_key_set(keyset: KeySet) -> Result<String, FfiError> {
255 Ok(serde_json::to_string(&keyset)?)
256}
257
258#[derive(Debug, Clone, Serialize, Deserialize, uniffi::Record)]
260#[serde(transparent)]
261pub struct Id {
262 pub hex: String,
263}
264
265impl From<cdk::nuts::Id> for Id {
266 fn from(id: cdk::nuts::Id) -> Self {
267 Self {
268 hex: id.to_string(),
269 }
270 }
271}
272
273impl TryFrom<Id> for cdk::nuts::Id {
274 type Error = FfiError;
275
276 fn try_from(id: Id) -> Result<Self, Self::Error> {
277 use std::str::FromStr;
278
279 Self::from_str(&id.hex).map_err(|e| FfiError::internal(format!("Invalid ID hex: {}", e)))
280 }
281}