notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

commit 61943aa6c781474874445fd22dac6accf0cdd581
parent 4b608cef5f6877225af2bc65a341a60bc741d8a1
Author: kernelkind <kernelkind@gmail.com>
Date:   Thu, 17 Apr 2025 19:27:39 -0400

introduce `ZapWallet`

Signed-off-by: kernelkind <kernelkind@gmail.com>

Diffstat:
Mcrates/notedeck/src/wallet.rs | 113+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Mcrates/notedeck/src/zaps/mod.rs | 2+-
2 files changed, 112 insertions(+), 3 deletions(-)

diff --git a/crates/notedeck/src/wallet.rs b/crates/notedeck/src/wallet.rs @@ -5,10 +5,10 @@ use nwc::{ NWC, }; use poll_promise::Promise; -use tokenator::TokenSerializable; +use tokenator::{ParseError, TokenParser, TokenSerializable}; use tokio::sync::RwLock; -use crate::{Accounts, DataPath, TokenHandler}; +use crate::{zaps::UserZapMsats, Accounts, DataPath, DefaultZapMsats, TokenHandler}; pub fn get_wallet_for_mut<'a>( accounts: &'a mut Accounts, @@ -188,12 +188,98 @@ fn construct_global_wallet(wallet_handler: &TokenHandler) -> Option<Wallet> { Some(wallet) } +#[derive(Debug)] +pub struct ZapWallet { + pub wallet: Wallet, + pub default_zap: DefaultZapMsats, +} + +enum ZapWalletRoute { + Wallet(Wallet), + DefaultZapMsats(UserZapMsats), +} + +impl TokenSerializable for ZapWallet { + fn parse_from_tokens<'a>( + parser: &mut tokenator::TokenParser<'a>, + ) -> Result<Self, tokenator::ParseError<'a>> { + let mut m_wallet = None; + let mut m_default_zap = None; + loop { + let res = TokenParser::alt( + parser, + &[ + |p| Ok(ZapWalletRoute::Wallet(Wallet::parse_from_tokens(p)?)), + |p| { + Ok(ZapWalletRoute::DefaultZapMsats( + UserZapMsats::parse_from_tokens(p)?, + )) + }, + ], + ); + + match res { + Ok(ZapWalletRoute::Wallet(wallet)) => m_wallet = Some(wallet), + Ok(ZapWalletRoute::DefaultZapMsats(msats)) => m_default_zap = Some(msats), + Err(ParseError::AltAllFailed) => break, + Err(_) => {} + } + + if m_wallet.is_some() && m_default_zap.is_some() { + break; + } + } + + let Some(wallet) = m_wallet else { + return Err(ParseError::DecodeFailed); + }; + + let mut zap_wallet = ZapWallet::new(wallet); + + let default_zap = DefaultZapMsats::from_user(m_default_zap); + + zap_wallet.default_zap = default_zap; + + Ok(zap_wallet) + } + + fn serialize_tokens(&self, writer: &mut tokenator::TokenWriter) { + self.wallet.serialize_tokens(writer); + + if let Some(user_zap_msats) = self.default_zap.try_into_user() { + user_zap_msats.serialize_tokens(writer); + } + } +} + +impl ZapWallet { + pub fn new(wallet: Wallet) -> Self { + Self { + wallet, + default_zap: DefaultZapMsats::default(), + } + } + + pub fn with_default_zap_msats(mut self, msats: u64) -> Self { + self.default_zap.set_user_selection(msats); + self + } +} + +impl From<Wallet> for ZapWallet { + fn from(value: Wallet) -> Self { + ZapWallet::new(value) + } +} + #[cfg(test)] mod tests { use tokenator::{TokenParser, TokenSerializable, TokenWriter}; use crate::Wallet; + use super::ZapWallet; + const URI: &str = "nostr+walletconnect://b889ff5b1513b641e2a139f661a661364979c5beee91842f8f0ef42ab558e9d4?relay=wss%3A%2F%2Frelay.damus.io&secret=71a8c14c1407c113601079c4302dab36460f0ccd0ad506f1f2dc73b5100e4f3c&lud16=nostr%40nostr.com"; #[test] @@ -220,4 +306,27 @@ mod tests { assert_eq!(wallet.uri, new_wallet.uri); } + + #[test] + fn test_zap_wallet_serialize_deserialize() { + const MSATS: u64 = 64_000; + let zap_wallet = + ZapWallet::new(Wallet::new(URI.to_owned()).unwrap()).with_default_zap_msats(MSATS); + + let mut writer = TokenWriter::new("\t"); + zap_wallet.serialize_tokens(&mut writer); + let serialized = writer.str(); + + let data = &serialized.split("\t").collect::<Vec<&str>>(); + let mut parser = TokenParser::new(data); + + let m_new_zap_wallet = ZapWallet::parse_from_tokens(&mut parser); + + assert!(m_new_zap_wallet.is_ok()); + + let new_zap_wallet = m_new_zap_wallet.unwrap(); + + assert_eq!(zap_wallet.wallet.uri, new_zap_wallet.wallet.uri); + assert_eq!(new_zap_wallet.default_zap.get_default_zap_msats(), MSATS); + } } diff --git a/crates/notedeck/src/zaps/mod.rs b/crates/notedeck/src/zaps/mod.rs @@ -7,4 +7,4 @@ pub use cache::{ AnyZapState, NoteZapTarget, NoteZapTargetOwned, ZapTarget, ZapTargetOwned, ZappingError, Zaps, }; -pub use default_zap::{DefaultZapError, DefaultZapMsats, PendingDefaultZapState}; +pub use default_zap::{DefaultZapError, DefaultZapMsats, PendingDefaultZapState, UserZapMsats};