use std::collections::BTreeSet;
use std::str::FromStr;
use crate::error::FfiError;
use crate::{Amount, CurrencyUnit, KeySetInfo, MintUrl, Proofs};
#[derive(Debug, uniffi::Object)]
pub struct Token {
pub(crate) inner: cdk::nuts::Token,
}
impl std::fmt::Display for Token {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.inner)
}
}
impl FromStr for Token {
type Err = FfiError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let token = cdk::nuts::Token::from_str(s)
.map_err(|e| FfiError::internal(format!("Invalid token: {}", e)))?;
Ok(Token { inner: token })
}
}
impl From<cdk::nuts::Token> for Token {
fn from(token: cdk::nuts::Token) -> Self {
Self { inner: token }
}
}
impl From<Token> for cdk::nuts::Token {
fn from(token: Token) -> Self {
token.inner
}
}
#[uniffi::export]
impl Token {
#[uniffi::constructor]
pub fn from_string(encoded_token: String) -> Result<Token, FfiError> {
let token = cdk::nuts::Token::from_str(&encoded_token)
.map_err(|e| FfiError::internal(format!("Invalid token: {}", e)))?;
Ok(Token { inner: token })
}
pub fn value(&self) -> Result<Amount, FfiError> {
Ok(self.inner.value()?.into())
}
pub fn memo(&self) -> Option<String> {
self.inner.memo().clone()
}
pub fn unit(&self) -> Option<CurrencyUnit> {
self.inner.unit().map(Into::into)
}
pub fn mint_url(&self) -> Result<MintUrl, FfiError> {
Ok(self.inner.mint_url()?.into())
}
pub fn proofs_simple(&self) -> Result<Proofs, FfiError> {
let empty_keysets = vec![];
let proofs = self.inner.proofs(&empty_keysets)?;
Ok(proofs.into_iter().map(|p| p.into()).collect())
}
pub fn proofs(&self, mint_keysets: Vec<KeySetInfo>) -> Result<Proofs, FfiError> {
let mint_keysets: Vec<_> = mint_keysets
.into_iter()
.map(TryInto::try_into)
.collect::<Result<_, _>>()?;
let proofs = self.inner.proofs(&mint_keysets)?;
Ok(proofs.into_iter().map(|p| p.into()).collect())
}
pub fn to_raw_bytes(&self) -> Result<Vec<u8>, FfiError> {
Ok(self.inner.to_raw_bytes()?)
}
pub fn encode(&self) -> String {
self.to_string()
}
#[uniffi::constructor]
pub fn from_raw_bytes(bytes: Vec<u8>) -> Result<Token, FfiError> {
let token = cdk::nuts::Token::try_from(&bytes)?;
Ok(Token { inner: token })
}
#[uniffi::constructor]
pub fn decode(encoded_token: String) -> Result<Token, FfiError> {
encoded_token.parse()
}
pub fn spending_conditions(&self) -> Vec<crate::types::SpendingConditions> {
self.inner
.spending_conditions()
.map(|set| set.into_iter().map(Into::into).collect())
.unwrap_or_default()
}
pub fn p2pk_pubkeys(&self) -> Vec<String> {
let set = self
.inner
.p2pk_pubkeys()
.map(|keys| {
keys.into_iter()
.map(|k| k.to_string())
.collect::<BTreeSet<_>>()
})
.unwrap_or_default();
set.into_iter().collect()
}
pub fn p2pk_refund_pubkeys(&self) -> Vec<String> {
let set = self
.inner
.p2pk_refund_pubkeys()
.map(|keys| {
keys.into_iter()
.map(|k| k.to_string())
.collect::<BTreeSet<_>>()
})
.unwrap_or_default();
set.into_iter().collect()
}
pub fn htlc_hashes(&self) -> Vec<String> {
let set = self
.inner
.htlc_hashes()
.map(|hashes| {
hashes
.into_iter()
.map(|h| h.to_string())
.collect::<BTreeSet<_>>()
})
.unwrap_or_default();
set.into_iter().collect()
}
pub fn locktimes(&self) -> Vec<u64> {
self.inner
.locktimes()
.map(|s| s.into_iter().collect())
.unwrap_or_default()
}
}