Skip to content

Commit

Permalink
revert searchAssets condition order and cover all cases for nft filter (
Browse files Browse the repository at this point in the history
metaplex-foundation#236)

* revert searchAssets params order and cover all cases for nft filter

* move newly added api params to end of struct
  • Loading branch information
Nagaprasadvr authored Feb 4, 2025
1 parent 9575f8a commit 4eac91c
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 38 deletions.
4 changes: 2 additions & 2 deletions das_api/src/api/api_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,6 @@ impl ApiContract for DasApi {
negate,
condition_type,
interface,
token_type,
owner_address,
owner_type,
creator_address,
Expand All @@ -404,6 +403,7 @@ impl ApiContract for DasApi {
options,
cursor,
name,
token_type,
} = payload;

// Deserialize search assets query
Expand Down Expand Up @@ -439,7 +439,6 @@ impl ApiContract for DasApi {
interface,
specification_version,
specification_asset_class,
token_type,
owner_address,
owner_type,
creator_address,
Expand All @@ -458,6 +457,7 @@ impl ApiContract for DasApi {
burnt,
json_uri,
name,
token_type,
};
let options = options.unwrap_or_default();
let sort_by = sort_by.unwrap_or_default();
Expand Down
2 changes: 1 addition & 1 deletion das_api/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ pub struct SearchAssets {
pub negate: Option<bool>,
pub condition_type: Option<SearchConditionType>,
pub interface: Option<Interface>,
pub token_type: Option<TokenTypeClass>,
pub owner_address: Option<String>,
pub owner_type: Option<OwnershipModel>,
pub creator_address: Option<String>,
Expand Down Expand Up @@ -126,6 +125,7 @@ pub struct SearchAssets {
pub cursor: Option<String>,
#[serde(default)]
pub name: Option<String>,
pub token_type: Option<TokenTypeClass>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
Expand Down
66 changes: 35 additions & 31 deletions digital_asset_types/src/dao/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ pub struct SearchAssetsQuery {
pub interface: Option<Interface>,
pub specification_version: Option<SpecificationVersions>,
pub specification_asset_class: Option<SpecificationAssetClass>,
pub token_type: Option<TokenTypeClass>,
pub owner_address: Option<Vec<u8>>,
pub owner_type: Option<OwnerType>,
pub creator_address: Option<Vec<u8>>,
Expand All @@ -76,25 +75,25 @@ pub struct SearchAssetsQuery {
pub burnt: Option<bool>,
pub json_uri: Option<String>,
pub name: Option<Vec<u8>>,
pub token_type: Option<TokenTypeClass>,
}

impl SearchAssetsQuery {
fn validate(&self) -> Result<(), DbErr> {
if self.token_type.is_some() {
if self.owner_type.is_some() {
return Err(DbErr::Custom(
"`owner_type` is not supported when using `token_type` field".to_string(),
"`ownerType` is not supported when using `tokenType` field".to_string(),
));
}
if self.owner_address.is_none() {
return Err(DbErr::Custom(
"Must provide `owner_address` when using `token_type` field".to_string(),
"Must provide `ownerAddress` when using `tokenType` field".to_string(),
));
}
if self.interface.is_some() {
return Err(DbErr::Custom(
"`specification_asset_class` is not supported when using `token_type` field"
.to_string(),
"`interface` is not supported when using `tokenType` field".to_string(),
));
}
}
Expand All @@ -110,6 +109,8 @@ impl SearchAssetsQuery {
Some(ConditionType::Any) => Condition::any(),
};

// Joins
let mut joins = Vec::new();
conditions = conditions
.add_option(
self.specification_version
Expand All @@ -128,7 +129,17 @@ impl SearchAssetsQuery {
.or(asset::Column::SpecificationAssetClass
.eq(SpecificationAssetClass::ProgrammableNft))
.or(asset::Column::SpecificationAssetClass
.eq(SpecificationAssetClass::MplCoreCollection)),
.eq(SpecificationAssetClass::MplCoreCollection))
.or(asset::Column::SpecificationAssetClass
.eq(SpecificationAssetClass::NonTransferableNft))
.or(asset::Column::SpecificationAssetClass
.eq(SpecificationAssetClass::IdentityNft))
.or(asset::Column::SpecificationAssetClass
.eq(SpecificationAssetClass::Print))
.or(asset::Column::SpecificationAssetClass
.eq(SpecificationAssetClass::PrintableNft))
.or(asset::Column::SpecificationAssetClass
.eq(SpecificationAssetClass::TransferRestrictedNft)),
)
}
TokenTypeClass::Fungible => asset::Column::SpecificationAssetClass
Expand All @@ -143,6 +154,24 @@ impl SearchAssetsQuery {
.clone()
.map(|x| asset::Column::SpecificationAssetClass.eq(x)),
)
.add_option(self.owner_address.as_ref().map(|o| match self.token_type {
Some(TokenTypeClass::Fungible) | Some(TokenTypeClass::All) => {
let rel = extensions::token_accounts::Relation::Asset
.def()
.rev()
.on_condition(|left, right| {
Expr::tbl(right, token_accounts::Column::Mint)
.eq(Expr::tbl(left, asset::Column::Id))
.into_condition()
});
joins.push(rel);

asset::Column::Owner
.eq(o.clone())
.or(token_accounts::Column::Owner.eq(o.clone()))
}
_ => asset::Column::Owner.eq(o.clone()),
}))
.add_option(
self.delegate
.to_owned()
Expand Down Expand Up @@ -231,7 +260,6 @@ impl SearchAssetsQuery {
}

// If creator_address or creator_verified is set, join with asset_creators
let mut joins = Vec::new();
if self.creator_address.is_some() || self.creator_verified.is_some() {
let rel = extensions::asset_creators::Relation::Asset
.def()
Expand All @@ -257,30 +285,6 @@ impl SearchAssetsQuery {
joins.push(rel);
}

if let Some(o) = self.owner_address.to_owned() {
if self.token_type == Some(TokenTypeClass::Fungible)
|| self.token_type == Some(TokenTypeClass::All)
{
conditions = conditions.add(
asset::Column::Owner
.eq(o.clone())
.or(token_accounts::Column::Owner.eq(o)),
);

let rel = extensions::token_accounts::Relation::Asset
.def()
.rev()
.on_condition(|left, right| {
Expr::tbl(right, token_accounts::Column::Mint)
.eq(Expr::tbl(left, asset::Column::Id))
.into_condition()
});
joins.push(rel);
} else {
conditions = conditions.add(asset::Column::Owner.eq(o));
}
}

if let Some(g) = self.grouping.to_owned() {
let cond = Condition::all()
.add(asset_grouping::Column::GroupKey.eq(g.0))
Expand Down
2 changes: 1 addition & 1 deletion digital_asset_types/src/dao/scopes/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,7 @@ pub async fn get_token_accounts(

if owner_address.is_none() && mint_address.is_none() {
return Err(DbErr::Custom(
"Either 'owner_address' or 'mint_address' must be provided".to_string(),
"Either 'ownerAddress' or 'mintAddress' must be provided".to_string(),
));
}

Expand Down
4 changes: 1 addition & 3 deletions digital_asset_types/src/dapi/common/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,9 +362,7 @@ pub fn get_interface(asset: &asset::Model) -> Result<Interface, DbErr> {
asset
.specification_asset_class
.as_ref()
.ok_or(DbErr::Custom(
"Specification asset class not found".to_string(),
))?,
.ok_or(DbErr::Custom("interface not found".to_string()))?,
)))
}

Expand Down

0 comments on commit 4eac91c

Please sign in to comment.