refactor: Remove nostr last checked methods from database trait and implementations

This commit is contained in:
thesimplekid (aider)
2025-03-09 22:53:19 +00:00
committed by thesimplekid
parent 214b75ac31
commit cb87fefacd
6 changed files with 66 additions and 121 deletions

View File

@@ -17,6 +17,7 @@ use tracing::Level;
use tracing_subscriber::EnvFilter; use tracing_subscriber::EnvFilter;
use url::Url; use url::Url;
mod nostr_storage;
mod sub_commands; mod sub_commands;
const DEFAULT_WORK_DIR: &str = ".cdk-cli"; const DEFAULT_WORK_DIR: &str = ".cdk-cli";
@@ -188,6 +189,7 @@ async fn main() -> Result<()> {
localstore, localstore,
&mnemonic.to_seed_normalized(""), &mnemonic.to_seed_normalized(""),
sub_command_args, sub_command_args,
&work_dir,
) )
.await .await
} }

View File

@@ -0,0 +1,37 @@
use std::fs;
use std::path::Path;
use anyhow::Result;
use cdk::nuts::PublicKey;
use cdk::util::hex;
/// Stores the last checked time for a nostr key in a file
pub async fn store_nostr_last_checked(
work_dir: &Path,
verifying_key: &PublicKey,
last_checked: u32,
) -> Result<()> {
let key_hex = hex::encode(verifying_key.to_bytes());
let file_path = work_dir.join(format!("nostr_last_checked_{}", key_hex));
fs::write(file_path, last_checked.to_string())?;
Ok(())
}
/// Gets the last checked time for a nostr key from a file
pub async fn get_nostr_last_checked(
work_dir: &Path,
verifying_key: &PublicKey,
) -> Result<Option<u32>> {
let key_hex = hex::encode(verifying_key.to_bytes());
let file_path = work_dir.join(format!("nostr_last_checked_{}", key_hex));
match fs::read_to_string(file_path) {
Ok(content) => {
let timestamp = content.trim().parse::<u32>()?;
Ok(Some(timestamp))
}
Err(_) => Ok(None),
}
}

View File

@@ -1,4 +1,5 @@
use std::collections::HashSet; use std::collections::HashSet;
use std::path::Path;
use std::str::FromStr; use std::str::FromStr;
use std::sync::Arc; use std::sync::Arc;
@@ -14,6 +15,8 @@ use clap::Args;
use nostr_sdk::nips::nip04; use nostr_sdk::nips::nip04;
use nostr_sdk::{Filter, Keys, Kind, Timestamp}; use nostr_sdk::{Filter, Keys, Kind, Timestamp};
use crate::nostr_storage;
#[derive(Args)] #[derive(Args)]
pub struct ReceiveSubCommand { pub struct ReceiveSubCommand {
/// Cashu Token /// Cashu Token
@@ -40,6 +43,7 @@ pub async fn receive(
localstore: Arc<dyn WalletDatabase<Err = cdk_database::Error> + Send + Sync>, localstore: Arc<dyn WalletDatabase<Err = cdk_database::Error> + Send + Sync>,
seed: &[u8], seed: &[u8],
sub_command_args: &ReceiveSubCommand, sub_command_args: &ReceiveSubCommand,
work_dir: &Path,
) -> Result<()> { ) -> Result<()> {
let mut signing_keys = Vec::new(); let mut signing_keys = Vec::new();
@@ -89,12 +93,19 @@ pub async fn receive(
signing_keys.push(nostr_key.clone()); signing_keys.push(nostr_key.clone());
let relays = sub_command_args.relay.clone(); let relays = sub_command_args.relay.clone();
let since = localstore let since =
.get_nostr_last_checked(&nostr_key.public_key()) nostr_storage::get_nostr_last_checked(work_dir, &nostr_key.public_key()).await?;
.await?;
let tokens = nostr_receive(relays, nostr_key.clone(), since).await?; let tokens = nostr_receive(relays, nostr_key.clone(), since).await?;
// Store the current time as last checked
nostr_storage::store_nostr_last_checked(
work_dir,
&nostr_key.public_key(),
unix_time() as u32,
)
.await?;
let mut total_amount = Amount::ZERO; let mut total_amount = Amount::ZERO;
for token_str in &tokens { for token_str in &tokens {
match receive_token( match receive_token(
@@ -116,9 +127,6 @@ pub async fn receive(
} }
} }
localstore
.add_nostr_last_checked(nostr_key.public_key(), unix_time() as u32)
.await?;
total_amount total_amount
} }
}; };

View File

@@ -105,16 +105,4 @@ pub trait Database: Debug {
async fn increment_keyset_counter(&self, keyset_id: &Id, count: u32) -> Result<(), Self::Err>; async fn increment_keyset_counter(&self, keyset_id: &Id, count: u32) -> Result<(), Self::Err>;
/// Get current Keyset counter /// Get current Keyset counter
async fn get_keyset_counter(&self, keyset_id: &Id) -> Result<Option<u32>, Self::Err>; async fn get_keyset_counter(&self, keyset_id: &Id) -> Result<Option<u32>, Self::Err>;
/// Get when nostr key was last checked
async fn get_nostr_last_checked(
&self,
verifying_key: &PublicKey,
) -> Result<Option<u32>, Self::Err>;
/// Update last checked time
async fn add_nostr_last_checked(
&self,
verifying_key: PublicKey,
last_checked: u32,
) -> Result<(), Self::Err>;
} }

View File

@@ -702,42 +702,4 @@ impl WalletDatabase for WalletRedbDatabase {
Ok(counter.map(|c| c.value())) Ok(counter.map(|c| c.value()))
} }
#[instrument(skip_all)]
async fn get_nostr_last_checked(
&self,
verifying_key: &PublicKey,
) -> Result<Option<u32>, Self::Err> {
let read_txn = self.db.begin_read().map_err(Error::from)?;
let table = read_txn
.open_table(NOSTR_LAST_CHECKED)
.map_err(Error::from)?;
let last_checked = table
.get(verifying_key.to_string().as_str())
.map_err(Error::from)?;
Ok(last_checked.map(|c| c.value()))
}
#[instrument(skip(self, verifying_key))]
async fn add_nostr_last_checked(
&self,
verifying_key: PublicKey,
last_checked: u32,
) -> Result<(), Self::Err> {
let write_txn = self.db.begin_write().map_err(Error::from)?;
{
let mut table = write_txn
.open_table(NOSTR_LAST_CHECKED)
.map_err(Error::from)?;
table
.insert(verifying_key.to_string().as_str(), last_checked)
.map_err(Error::from)?;
}
write_txn.commit().map_err(Error::from)?;
Ok(())
}
} }

View File

@@ -782,61 +782,6 @@ WHERE id=?;
Ok(count) Ok(count)
} }
#[instrument(skip_all)]
async fn get_nostr_last_checked(
&self,
verifying_key: &PublicKey,
) -> Result<Option<u32>, Self::Err> {
let rec = sqlx::query(
r#"
SELECT last_check
FROM nostr_last_checked
WHERE key=?;
"#,
)
.bind(verifying_key.to_bytes().to_vec())
.fetch_one(&self.pool)
.await;
let count = match rec {
Ok(rec) => {
let count: Option<u32> = rec.try_get("last_check").map_err(Error::from)?;
count
}
Err(err) => match err {
sqlx::Error::RowNotFound => return Ok(None),
_ => return Err(Error::SQLX(err).into()),
},
};
Ok(count)
}
#[instrument(skip_all)]
async fn add_nostr_last_checked(
&self,
verifying_key: PublicKey,
last_checked: u32,
) -> Result<(), Self::Err> {
sqlx::query(
r#"
INSERT INTO nostr_last_checked
(key, last_check)
VALUES (?, ?)
ON CONFLICT(key) DO UPDATE SET
last_check = excluded.last_check
;
"#,
)
.bind(verifying_key.to_bytes().to_vec())
.bind(last_checked)
.execute(&self.pool)
.await
.map_err(Error::from)?;
Ok(())
}
} }
fn sqlite_row_to_mint_info(row: &SqliteRow) -> Result<MintInfo, Error> { fn sqlite_row_to_mint_info(row: &SqliteRow) -> Result<MintInfo, Error> {
@@ -970,11 +915,13 @@ fn sqlite_row_to_proof_info(row: &SqliteRow) -> Result<ProofInfo, Error> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::env::temp_dir;
#[tokio::test] #[tokio::test]
#[cfg(feature = "sqlcipher")] #[cfg(feature = "sqlcipher")]
async fn test_sqlcipher() { async fn test_sqlcipher() {
use cdk_common::mint_url::MintUrl;
use cdk_common::MintInfo;
use super::*; use super::*;
let path = std::env::temp_dir() let path = std::env::temp_dir()
.to_path_buf() .to_path_buf()
@@ -985,14 +932,15 @@ mod tests {
db.migrate().await; db.migrate().await;
// do something simple to test the database let mint_info = MintInfo::new().description("test");
let pk = PublicKey::from_hex( let mint_url = MintUrl::from_str("https://mint.xyz").unwrap();
"02194603ffa36356f4a56b7df9371fc3192472351453ec7398b8da8117e7c3e104",
) db.add_mint(mint_url.clone(), Some(mint_info.clone()))
.unwrap(); .await
let last_checked = 6969; .unwrap();
db.add_nostr_last_checked(pk, last_checked).await.unwrap();
let res = db.get_nostr_last_checked(&pk).await.unwrap(); let res = db.get_mint(mint_url).await.unwrap();
assert_eq!(res, Some(last_checked)); assert_eq!(mint_info, res.clone().unwrap());
assert_eq!("test", &res.unwrap().description.unwrap());
} }
} }