diff --git a/digital_asset_types/src/dao/scopes/asset.rs b/digital_asset_types/src/dao/scopes/asset.rs index cb7bf032..1ec170b9 100644 --- a/digital_asset_types/src/dao/scopes/asset.rs +++ b/digital_asset_types/src/dao/scopes/asset.rs @@ -3,7 +3,7 @@ use crate::{ asset::{self}, asset_authority, asset_creators, asset_data, asset_grouping, cl_audits_v2, extensions::{self, instruction::PascalCase}, - sea_orm_active_enums::Instruction, + sea_orm_active_enums::{Instruction, OwnerType}, token_accounts, tokens, Cursor, FullAsset, GroupingSize, Pagination, }, rpc::{filter::AssetSortDirection, options::Options}, @@ -79,6 +79,7 @@ pub async fn get_by_creator( limit, show_unverified_collections, Some(creator), + false, ) .await } @@ -139,6 +140,7 @@ pub async fn get_by_grouping( limit, show_unverified_collections, None, + false, ) .await } @@ -181,6 +183,7 @@ pub async fn get_assets_by_owner( pagination, limit, options.show_unverified_collections, + true, ) .await } @@ -205,6 +208,7 @@ pub async fn get_assets( pagination, limit, false, + false, ) .await } @@ -231,6 +235,7 @@ pub async fn get_by_authority( limit, show_unverified_collections, None, + false, ) .await } @@ -246,6 +251,7 @@ async fn get_by_related_condition( limit: u64, show_unverified_collections: bool, required_creator: Option>, + show_owner_for_fungible: bool, ) -> Result, DbErr> where E: RelationTrait, @@ -263,7 +269,14 @@ where let assets = paginate(pagination, limit, stmt, sort_direction, asset::Column::Id) .all(conn) .await?; - get_related_for_assets(conn, assets, show_unverified_collections, required_creator).await + get_related_for_assets( + conn, + assets, + show_unverified_collections, + required_creator, + show_owner_for_fungible, + ) + .await } pub async fn get_related_for_assets( @@ -271,11 +284,12 @@ pub async fn get_related_for_assets( assets: Vec, show_unverified_collections: bool, required_creator: Option>, + show_owner_for_fungible: bool, ) -> Result, DbErr> { let asset_ids = assets.iter().map(|a| a.id.clone()).collect::>(); let asset_data: Vec = asset_data::Entity::find() - .filter(asset_data::Column::Id.is_in(asset_ids)) + .filter(asset_data::Column::Id.is_in(asset_ids.clone())) .all(conn) .await?; let asset_data_map = asset_data.into_iter().fold(HashMap::new(), |mut acc, ad| { @@ -320,6 +334,25 @@ pub async fn get_related_for_assets( } } + // When using getAssetByOwner or searchAssets with an owner_address to retrieve fungible assets, the 'owner' field was previously returned as empty. + // Instead of an empty value, we should now display the actual owner of the token account associated with the asset. + + if show_owner_for_fungible { + let token_account_data: Vec = token_accounts::Entity::find() + .filter(token_accounts::Column::Mint.is_in(asset_ids)) + .all(conn) + .await?; + + for t in token_account_data.into_iter() { + if let Some(asset) = assets_map.get_mut(&t.mint) { + if asset.asset.owner.clone().is_none() && asset.asset.owner_type == OwnerType::Token + { + asset.asset.owner = Some(t.owner); + } + } + } + } + // Filter out stale creators from each asset. for (_id, asset) in assets_map.iter_mut() { filter_out_stale_creators(&mut asset.creators); @@ -389,6 +422,7 @@ pub async fn get_assets_by_condition( pagination: &Pagination, limit: u64, show_unverified_collections: bool, + show_owner_for_fungible: bool, ) -> Result, DbErr> { let mut stmt = asset::Entity::find(); for def in joins { @@ -404,8 +438,14 @@ pub async fn get_assets_by_condition( let assets = paginate(pagination, limit, stmt, sort_direction, asset::Column::Id) .all(conn) .await?; - let full_assets = - get_related_for_assets(conn, assets, show_unverified_collections, None).await?; + let full_assets = get_related_for_assets( + conn, + assets, + show_unverified_collections, + None, + show_owner_for_fungible, + ) + .await?; Ok(full_assets) } diff --git a/digital_asset_types/src/dapi/search_assets.rs b/digital_asset_types/src/dapi/search_assets.rs index a7ee6550..5b8aeacc 100644 --- a/digital_asset_types/src/dapi/search_assets.rs +++ b/digital_asset_types/src/dapi/search_assets.rs @@ -24,6 +24,7 @@ pub async fn search_assets( &pagination, page_options.limit, options.show_unverified_collections, + true, ) .await?; Ok(build_asset_response( diff --git a/integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible_for_fungible_asset/6BRNfDfdq1nKyU1TQiCEQLWyPtD8EwUH9Kt2ahsbidUx b/integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible_for_fungible_asset/6BRNfDfdq1nKyU1TQiCEQLWyPtD8EwUH9Kt2ahsbidUx new file mode 100644 index 00000000..22011a98 Binary files /dev/null and b/integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible_for_fungible_asset/6BRNfDfdq1nKyU1TQiCEQLWyPtD8EwUH9Kt2ahsbidUx differ diff --git a/integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible_for_fungible_asset/7BajpcYgnxmWK91RhrfsdB3Tm83PcDwPvMC8ZinvtTY6 b/integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible_for_fungible_asset/7BajpcYgnxmWK91RhrfsdB3Tm83PcDwPvMC8ZinvtTY6 new file mode 100644 index 00000000..fb1372e3 Binary files /dev/null and b/integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible_for_fungible_asset/7BajpcYgnxmWK91RhrfsdB3Tm83PcDwPvMC8ZinvtTY6 differ diff --git a/integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible_for_fungible_asset/7EYnhQoR9YM3N7UoaKRoA44Uy8JeaZV3qyouov87awMs b/integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible_for_fungible_asset/7EYnhQoR9YM3N7UoaKRoA44Uy8JeaZV3qyouov87awMs new file mode 100644 index 00000000..bcedc7a6 Binary files /dev/null and b/integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible_for_fungible_asset/7EYnhQoR9YM3N7UoaKRoA44Uy8JeaZV3qyouov87awMs differ diff --git a/integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible_scenario_2/6BRNfDfdq1nKyU1TQiCEQLWyPtD8EwUH9Kt2ahsbidUx b/integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible_scenario_2/6BRNfDfdq1nKyU1TQiCEQLWyPtD8EwUH9Kt2ahsbidUx new file mode 100644 index 00000000..c1ed0573 Binary files /dev/null and b/integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible_scenario_2/6BRNfDfdq1nKyU1TQiCEQLWyPtD8EwUH9Kt2ahsbidUx differ diff --git a/integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible_scenario_2/7BajpcYgnxmWK91RhrfsdB3Tm83PcDwPvMC8ZinvtTY6 b/integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible_scenario_2/7BajpcYgnxmWK91RhrfsdB3Tm83PcDwPvMC8ZinvtTY6 new file mode 100644 index 00000000..5affc4cc Binary files /dev/null and b/integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible_scenario_2/7BajpcYgnxmWK91RhrfsdB3Tm83PcDwPvMC8ZinvtTY6 differ diff --git a/integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible_scenario_2/7EYnhQoR9YM3N7UoaKRoA44Uy8JeaZV3qyouov87awMs b/integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible_scenario_2/7EYnhQoR9YM3N7UoaKRoA44Uy8JeaZV3qyouov87awMs new file mode 100644 index 00000000..4288c7fe Binary files /dev/null and b/integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible_scenario_2/7EYnhQoR9YM3N7UoaKRoA44Uy8JeaZV3qyouov87awMs differ diff --git a/integration_tests/tests/integration_tests/show_fungible_flag_tests.rs b/integration_tests/tests/integration_tests/show_fungible_flag_tests.rs index 3a762610..defacc3c 100644 --- a/integration_tests/tests/integration_tests/show_fungible_flag_tests.rs +++ b/integration_tests/tests/integration_tests/show_fungible_flag_tests.rs @@ -190,6 +190,43 @@ async fn test_get_asset_by_owner_with_show_fungible() { insta::assert_json_snapshot!(name, response); } +#[tokio::test] +#[serial] +#[named] +async fn test_get_asset_by_owner_with_show_fungible_for_fungible_asset() { + let name = trim_test_name(function_name!()); + let setup = TestSetup::new_with_options( + name.clone(), + TestSetupOptions { + network: Some(Network::Mainnet), + }, + ) + .await; + + let seeds: Vec = seed_accounts([ + "7EYnhQoR9YM3N7UoaKRoA44Uy8JeaZV3qyouov87awMs", + "7BajpcYgnxmWK91RhrfsdB3Tm83PcDwPvMC8ZinvtTY6", + "6BRNfDfdq1nKyU1TQiCEQLWyPtD8EwUH9Kt2ahsbidUx", + ]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "ownerAddress": "2oerfxddTpK5hWAmCMYB6fr9WvNrjEH54CHCWK8sAq7g", + "displayOptions": { + "showFungible": true + } + } + "#; + + let request: api::GetAssetsByOwner = serde_json::from_str(request).unwrap(); + let response = setup.das_api.get_assets_by_owner(request).await.unwrap(); + + insta::assert_json_snapshot!(name, response); +} + #[tokio::test] #[serial] #[named] diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_by_owner_with_show_fungible_for_fungible_asset.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_by_owner_with_show_fungible_for_fungible_asset.snap new file mode 100644 index 00000000..e982981d --- /dev/null +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_by_owner_with_show_fungible_for_fungible_asset.snap @@ -0,0 +1,69 @@ +--- +source: integration_tests/tests/integration_tests/show_fungible_flag_tests.rs +expression: response +snapshot_kind: text +--- +{ + "total": 1, + "limit": 1000, + "cursor": "7EYnhQoR9YM3N7UoaKRoA44Uy8JeaZV3qyouov87awMs", + "items": [ + { + "interface": "FungibleToken", + "id": "7EYnhQoR9YM3N7UoaKRoA44Uy8JeaZV3qyouov87awMs", + "content": { + "$schema": "https://schema.metaplex.com/nft1.0.json", + "json_uri": "https://gateway.irys.xyz/P8X64pGutyX5eyTpQmqZr3H4_Lqhm0IYxr5SyzFFNek", + "files": [], + "metadata": { + "name": "Silly Dragon", + "symbol": "SILLY", + "token_standard": "Fungible" + }, + "links": {} + }, + "authorities": [ + { + "address": "38qZKCqcphT5wDrVNJGHYcuenjEtEFPitvrqvMFQkPu7", + "scopes": [ + "full" + ] + } + ], + "compression": { + "eligible": false, + "compressed": false, + "data_hash": "", + "creator_hash": "", + "asset_hash": "", + "tree": "", + "seq": 0, + "leaf_id": 0 + }, + "grouping": [], + "royalty": { + "royalty_model": "creators", + "target": null, + "percent": 0.0, + "basis_points": 0, + "primary_sale_happened": true, + "locked": false + }, + "creators": [], + "ownership": { + "frozen": false, + "delegated": false, + "delegate": null, + "ownership_model": "token", + "owner": "2oerfxddTpK5hWAmCMYB6fr9WvNrjEH54CHCWK8sAq7g" + }, + "mutable": true, + "burnt": false, + "token_info": { + "supply": 999913799054684527, + "decimals": 9, + "token_program": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + } + } + ] +}