mirror of
https://github.com/aljazceru/cdk.git
synced 2025-12-21 22:54:49 +01:00
refactor: Remove nostr last checked methods from database trait and implementations
This commit is contained in:
committed by
thesimplekid
parent
214b75ac31
commit
cb87fefacd
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
37
crates/cdk-cli/src/nostr_storage.rs
Normal file
37
crates/cdk-cli/src/nostr_storage.rs
Normal 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),
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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>;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()))
|
||||||
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let last_checked = 6969;
|
|
||||||
db.add_nostr_last_checked(pk, last_checked).await.unwrap();
|
let res = db.get_mint(mint_url).await.unwrap();
|
||||||
let res = db.get_nostr_last_checked(&pk).await.unwrap();
|
assert_eq!(mint_info, res.clone().unwrap());
|
||||||
assert_eq!(res, Some(last_checked));
|
assert_eq!("test", &res.unwrap().description.unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user