diff --git a/src/database/transaction.rs b/src/database/transaction.rs index 8544779..867f4f1 100644 --- a/src/database/transaction.rs +++ b/src/database/transaction.rs @@ -139,7 +139,12 @@ impl<'q> Model { let offset = pagination.offset.unwrap_or(0); let limit = limit.clamp(1, 1000); - let q = r#"SELECT * FROM transactions ORDER BY date DESC LIMIT $1 OFFSET $2;"#; + let q = match pagination.exclude_mined { + Some(true) => { + r#"SELECT * FROM transactions WHERE transaction_type != 'mined' ORDER BY date DESC LIMIT $1 OFFSET $2;"# + } + _ => r#"SELECT * FROM transactions ORDER BY date DESC LIMIT $1 OFFSET $2;"#, + }; sqlx::query_as(q) .bind(limit) diff --git a/src/database/wallet.rs b/src/database/wallet.rs index 0e21742..fe6b519 100644 --- a/src/database/wallet.rs +++ b/src/database/wallet.rs @@ -296,4 +296,24 @@ impl<'q> Model { Ok(models) } + + pub async fn fetch_by_address_names(pool: E, address: S) -> Result> + where + S: AsRef, + E: 'q + Executor<'q, Database = Postgres>, + { + let address = address.as_ref(); + + let q = r#"SELECT wallets.*, + COUNT(names.id) AS NAMES + FROM wallets + LEFT JOIN NAMES ON wallets.address = names.owner + WHERE wallets.address = $1 GROUP BY wallets.id + ORDER BY NAMES DESC"#; + sqlx::query_as(q) + .bind(address) + .fetch_optional(pool) + .await + .map_err(DatabaseError::Sqlx) + } } diff --git a/src/models/krist/addresses.rs b/src/models/krist/addresses.rs index f7a6b95..f3c5899 100644 --- a/src/models/krist/addresses.rs +++ b/src/models/krist/addresses.rs @@ -58,6 +58,12 @@ impl From for AddressJson { } } +#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize, Default)] +pub struct AddressGetQuery { + #[serde(alias = "fetchNames")] + pub fetch_names: Option, +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/routes/krist/wallet.rs b/src/routes/krist/wallet.rs index ab27594..3d68c93 100644 --- a/src/routes/krist/wallet.rs +++ b/src/routes/krist/wallet.rs @@ -5,7 +5,9 @@ use crate::AppState; use crate::database::{ModelExt, name::Model as Name, wallet::Model as Wallet}; use crate::errors::krist::KristError; use crate::errors::krist::address::AddressError; -use crate::models::krist::addresses::{AddressJson, AddressListResponse, AddressResponse}; +use crate::models::krist::addresses::{ + AddressGetQuery, AddressJson, AddressListResponse, AddressResponse, +}; use crate::models::krist::names::{NameJson, NameListResponse}; use crate::models::krist::transactions::{ AddressTransactionQuery, TransactionJson, TransactionListResponse, @@ -46,10 +48,14 @@ async fn wallet_list( async fn wallet_get( state: web::Data, address: web::Path, + query: web::Query, ) -> Result { let address = address.into_inner(); - let wallet = Wallet::fetch_by_address(&state.pool, &address).await?; + let wallet = match query.0.fetch_names { + Some(true) => Wallet::fetch_by_address_names(&state.pool, &address).await?, + _ => Wallet::fetch_by_address(&state.pool, &address).await?, + }; wallet .map(|addr| AddressResponse { diff --git a/src/routes/mod.rs b/src/routes/mod.rs index 509a5f9..8ec3507 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs @@ -41,6 +41,9 @@ pub fn config(cfg: &mut web::ServiceConfig) { #[derive(Debug, serde::Deserialize, serde::Serialize)] pub struct PaginationParams { + #[serde(alias = "excludeMined")] + // Only used on /transactions routes + pub exclude_mined: Option, pub limit: Option, pub offset: Option, } @@ -48,6 +51,7 @@ pub struct PaginationParams { impl Default for PaginationParams { fn default() -> Self { Self { + exclude_mined: None, limit: Some(50), offset: Some(0), }