diff --git a/das_api/src/api/api_impl.rs b/das_api/src/api/api_impl.rs index 55a69d3b6..a533617c1 100644 --- a/das_api/src/api/api_impl.rs +++ b/das_api/src/api/api_impl.rs @@ -22,7 +22,7 @@ use sea_orm::{sea_query::ConditionType, ConnectionTrait, DbBackend, Statement}; use crate::{ feature_flag::{get_feature_flags, FeatureFlags}, - validation::validate_opt_pubkey, + validation::{validate_opt_pubkey, validate_search_with_name}, }; use open_rpc_schema::document::OpenrpcDocument; use { @@ -358,6 +358,7 @@ impl ApiContract for DasApi { after, json_uri, show_collection_metadata, + name, } = payload; // Deserialize search assets query self.validate_pagination(&limit, &page, &before, &after)?; @@ -370,6 +371,7 @@ impl ApiContract for DasApi { SearchConditionType::All => ConditionType::All, }); let owner_address = validate_opt_pubkey(&owner_address)?; + let name = validate_search_with_name(&name, &owner_address)?; let creator_address = validate_opt_pubkey(&creator_address)?; let delegate = validate_opt_pubkey(&delegate)?; @@ -408,6 +410,7 @@ impl ApiContract for DasApi { royalty_amount, burnt, json_uri, + name, }; let sort_by = sort_by.unwrap_or_default(); let transform = AssetTransform { diff --git a/das_api/src/api/mod.rs b/das_api/src/api/mod.rs index 122306c31..31372d601 100644 --- a/das_api/src/api/mod.rs +++ b/das_api/src/api/mod.rs @@ -91,6 +91,7 @@ pub struct SearchAssets { pub json_uri: Option, #[serde(default)] pub show_collection_metadata: Option, + pub name: Option, } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] diff --git a/das_api/src/validation.rs b/das_api/src/validation.rs index b3377a7b4..394463208 100644 --- a/das_api/src/validation.rs +++ b/das_api/src/validation.rs @@ -6,6 +6,23 @@ pub fn validate_pubkey(str_pubkey: String) -> Result { Pubkey::from_str(&str_pubkey).map_err(|_| DasApiError::PubkeyValidationError(str_pubkey)) } +pub fn validate_search_with_name( + name: &Option, + owner: &Option>, +) -> Result>, DasApiError> { + let opt_name = if let Some(n) = name { + if owner.is_none() { + return Err(DasApiError::ValidationError( + "Owner address must be provided in order to search assets by name".to_owned(), + )); + } + Some(n.clone().into_bytes()) + } else { + None + }; + Ok(opt_name) +} + pub fn validate_opt_pubkey(pubkey: &Option) -> Result>, DasApiError> { let opt_bytes = if let Some(pubkey) = pubkey { let pubkey = Pubkey::from_str(pubkey) diff --git a/digital_asset_types/src/dao/mod.rs b/digital_asset_types/src/dao/mod.rs index 677a71185..2d36217eb 100644 --- a/digital_asset_types/src/dao/mod.rs +++ b/digital_asset_types/src/dao/mod.rs @@ -11,7 +11,7 @@ use self::sea_orm_active_enums::{ use sea_orm::{ entity::*, sea_query::Expr, - sea_query::{ConditionType, IntoCondition}, + sea_query::{ConditionType, IntoCondition, SimpleExpr}, Condition, DbErr, RelationDef, }; @@ -54,6 +54,7 @@ pub struct SearchAssetsQuery { pub royalty_amount: Option, pub burnt: Option, pub json_uri: Option, + pub name: Option>, } impl SearchAssetsQuery { @@ -115,6 +116,9 @@ impl SearchAssetsQuery { if self.json_uri.is_some() { num_conditions += 1; } + if self.name.is_some() { + num_conditions += 1; + } num_conditions } @@ -245,6 +249,27 @@ impl SearchAssetsQuery { joins.push(rel); } + if let Some(n) = self.name.to_owned() { + let name_as_str = std::str::from_utf8(&n).map_err(|_| { + DbErr::Custom( + "Could not convert raw name bytes into string for comparison".to_owned(), + ) + })?; + + let name_expr = + SimpleExpr::Custom(format!("chain_data->>'name' LIKE '%{}%'", name_as_str).into()); + conditions = conditions.add(name_expr); + let rel = asset_data::Relation::Asset + .def() + .rev() + .on_condition(|left, right| { + Expr::tbl(right, asset_data::Column::Id) + .eq(Expr::tbl(left, asset::Column::AssetData)) + .into_condition() + }); + joins.push(rel); + } + Ok(( match self.negate { None | Some(false) => conditions, diff --git a/digital_asset_types/tests/common.rs b/digital_asset_types/tests/common.rs index d4df10742..93ff878d2 100644 --- a/digital_asset_types/tests/common.rs +++ b/digital_asset_types/tests/common.rs @@ -231,7 +231,7 @@ pub fn create_asset_grouping( id: row_num, group_key: "collection".to_string(), slot_updated: Some(0), - verified: false, + verified: Some(false), group_info_seq: Some(0), }, )