diff --git a/digital_asset_types/src/dao/scopes/asset.rs b/digital_asset_types/src/dao/scopes/asset.rs index 175091830..42c25adcf 100644 --- a/digital_asset_types/src/dao/scopes/asset.rs +++ b/digital_asset_types/src/dao/scopes/asset.rs @@ -6,7 +6,7 @@ use crate::{ sea_orm_active_enums::Instruction, token_accounts, Cursor, FullAsset, GroupingSize, Pagination, }, - rpc::filter::AssetSortDirection, + rpc::{filter::AssetSortDirection, options::Options}, }; use indexmap::IndexMap; use sea_orm::{entity::*, query::*, ConnectionTrait, DbErr, Order}; @@ -560,9 +560,16 @@ pub async fn get_token_accounts( mint_address: Option>, pagination: &Pagination, limit: u64, + options: &Options, ) -> Result, DbErr> { let mut condition = Condition::all(); + if options.show_zero_balance { + condition = condition.add(token_accounts::Column::Amount.gte(0)); + } else { + condition = condition.add(token_accounts::Column::Amount.gt(0)); + } + if owner_address.is_none() && mint_address.is_none() { return Err(DbErr::Custom( "Either 'owner_address' or 'mint_address' must be provided".to_string(), diff --git a/digital_asset_types/src/dapi/get_token_accounts.rs b/digital_asset_types/src/dapi/get_token_accounts.rs index ae5967c34..28dcfc503 100644 --- a/digital_asset_types/src/dapi/get_token_accounts.rs +++ b/digital_asset_types/src/dapi/get_token_accounts.rs @@ -22,6 +22,7 @@ pub async fn get_token_accounts( mint_address, &pagination, page_options.limit, + options, ) .await?; diff --git a/digital_asset_types/src/rpc/options.rs b/digital_asset_types/src/rpc/options.rs index a1fafa2c4..219f27c6e 100644 --- a/digital_asset_types/src/rpc/options.rs +++ b/digital_asset_types/src/rpc/options.rs @@ -6,4 +6,6 @@ use serde::{Deserialize, Serialize}; pub struct Options { #[serde(default)] pub show_unverified_collections: bool, + #[serde(default)] + pub show_zero_balance: bool, } diff --git a/integration_tests/tests/data/accounts/show_zero_balance_filter_being_disabled/BE1CkzRjLTXAWcSVCaqzycwXsZ18Yuk3jMDMnPUoHjjS b/integration_tests/tests/data/accounts/show_zero_balance_filter_being_disabled/BE1CkzRjLTXAWcSVCaqzycwXsZ18Yuk3jMDMnPUoHjjS new file mode 100644 index 000000000..5cf4586cc Binary files /dev/null and b/integration_tests/tests/data/accounts/show_zero_balance_filter_being_disabled/BE1CkzRjLTXAWcSVCaqzycwXsZ18Yuk3jMDMnPUoHjjS differ diff --git a/integration_tests/tests/data/accounts/show_zero_balance_filter_being_disabled/CyqarC6hyNYvb3EDueyeYrnGeAUjCDtMvWrbtdAnA53a b/integration_tests/tests/data/accounts/show_zero_balance_filter_being_disabled/CyqarC6hyNYvb3EDueyeYrnGeAUjCDtMvWrbtdAnA53a new file mode 100644 index 000000000..0f73124a7 Binary files /dev/null and b/integration_tests/tests/data/accounts/show_zero_balance_filter_being_disabled/CyqarC6hyNYvb3EDueyeYrnGeAUjCDtMvWrbtdAnA53a differ diff --git a/integration_tests/tests/data/accounts/show_zero_balance_filter_being_enabled/BE1CkzRjLTXAWcSVCaqzycwXsZ18Yuk3jMDMnPUoHjjS b/integration_tests/tests/data/accounts/show_zero_balance_filter_being_enabled/BE1CkzRjLTXAWcSVCaqzycwXsZ18Yuk3jMDMnPUoHjjS new file mode 100644 index 000000000..a25676b25 Binary files /dev/null and b/integration_tests/tests/data/accounts/show_zero_balance_filter_being_enabled/BE1CkzRjLTXAWcSVCaqzycwXsZ18Yuk3jMDMnPUoHjjS differ diff --git a/integration_tests/tests/data/accounts/show_zero_balance_filter_being_enabled/CyqarC6hyNYvb3EDueyeYrnGeAUjCDtMvWrbtdAnA53a b/integration_tests/tests/data/accounts/show_zero_balance_filter_being_enabled/CyqarC6hyNYvb3EDueyeYrnGeAUjCDtMvWrbtdAnA53a new file mode 100644 index 000000000..6f5616699 Binary files /dev/null and b/integration_tests/tests/data/accounts/show_zero_balance_filter_being_enabled/CyqarC6hyNYvb3EDueyeYrnGeAUjCDtMvWrbtdAnA53a differ diff --git a/integration_tests/tests/integration_tests/main.rs b/integration_tests/tests/integration_tests/main.rs index 695836168..7f88a27a8 100644 --- a/integration_tests/tests/integration_tests/main.rs +++ b/integration_tests/tests/integration_tests/main.rs @@ -4,4 +4,5 @@ mod common; mod general_scenario_tests; mod mpl_core_tests; mod regular_nft_tests; +mod test_show_zero_balance_filter; mod token_accounts_tests; diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__test_show_zero_balance_filter__show_zero_balance_filter_being_disabled.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__test_show_zero_balance_filter__show_zero_balance_filter_being_disabled.snap new file mode 100644 index 000000000..f2a5d1a10 --- /dev/null +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__test_show_zero_balance_filter__show_zero_balance_filter_being_disabled.snap @@ -0,0 +1,24 @@ +--- +source: integration_tests/tests/integration_tests/test_show_zero_balance_filter.rs +expression: response +snapshot_kind: text +--- +{ + "total": 1, + "limit": 1000, + "token_accounts": [ + { + "address": "CyqarC6hyNYvb3EDueyeYrnGeAUjCDtMvWrbtdAnA53a", + "mint": "7Y5WQ2e3FummR2DebrqP8caC64QvXzpnhSTNWjNabxWn", + "amount": 1, + "owner": "2oerfxddTpK5hWAmCMYB6fr9WvNrjEH54CHCWK8sAq7g", + "frozen": true, + "delegate": "D98f1ebFe6kfZTcztLo1iPeKAwogbWHAgXzgSpdRDiu7", + "delegated_amount": 1, + "close_authority": null, + "extensions": null + } + ], + "cursor": null, + "errors": [] +} diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__test_show_zero_balance_filter__show_zero_balance_filter_being_enabled.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__test_show_zero_balance_filter__show_zero_balance_filter_being_enabled.snap new file mode 100644 index 000000000..c628cdebb --- /dev/null +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__test_show_zero_balance_filter__show_zero_balance_filter_being_enabled.snap @@ -0,0 +1,35 @@ +--- +source: integration_tests/tests/integration_tests/test_show_zero_balance_filter.rs +expression: response +snapshot_kind: text +--- +{ + "total": 2, + "limit": 1000, + "token_accounts": [ + { + "address": "BE1CkzRjLTXAWcSVCaqzycwXsZ18Yuk3jMDMnPUoHjjS", + "mint": "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN", + "amount": 0, + "owner": "2oerfxddTpK5hWAmCMYB6fr9WvNrjEH54CHCWK8sAq7g", + "frozen": false, + "delegate": null, + "delegated_amount": 0, + "close_authority": null, + "extensions": null + }, + { + "address": "CyqarC6hyNYvb3EDueyeYrnGeAUjCDtMvWrbtdAnA53a", + "mint": "7Y5WQ2e3FummR2DebrqP8caC64QvXzpnhSTNWjNabxWn", + "amount": 1, + "owner": "2oerfxddTpK5hWAmCMYB6fr9WvNrjEH54CHCWK8sAq7g", + "frozen": true, + "delegate": "D98f1ebFe6kfZTcztLo1iPeKAwogbWHAgXzgSpdRDiu7", + "delegated_amount": 1, + "close_authority": null, + "extensions": null + } + ], + "cursor": null, + "errors": [] +} diff --git a/integration_tests/tests/integration_tests/test_show_zero_balance_filter.rs b/integration_tests/tests/integration_tests/test_show_zero_balance_filter.rs new file mode 100644 index 000000000..e19f18d71 --- /dev/null +++ b/integration_tests/tests/integration_tests/test_show_zero_balance_filter.rs @@ -0,0 +1,83 @@ +use function_name::named; + +use das_api::api::{self, ApiContract}; + +use itertools::Itertools; + +use serial_test::serial; + +use super::common::*; + +#[tokio::test] +#[serial] +#[named] +async fn test_show_zero_balance_filter_being_enabled() { + 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([ + "BE1CkzRjLTXAWcSVCaqzycwXsZ18Yuk3jMDMnPUoHjjS", + "CyqarC6hyNYvb3EDueyeYrnGeAUjCDtMvWrbtdAnA53a", + ]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "ownerAddress":"2oerfxddTpK5hWAmCMYB6fr9WvNrjEH54CHCWK8sAq7g", + "displayOptions": { + "showZeroBalance": true + } + } + "#; + + let request: api::GetTokenAccounts = serde_json::from_str(request).unwrap(); + let response = setup.das_api.get_token_accounts(request).await.unwrap(); + + insta::assert_json_snapshot!(name, response); +} + +#[tokio::test] +#[serial] +#[named] +async fn test_show_zero_balance_filter_being_disabled() { + 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([ + "BE1CkzRjLTXAWcSVCaqzycwXsZ18Yuk3jMDMnPUoHjjS", + "CyqarC6hyNYvb3EDueyeYrnGeAUjCDtMvWrbtdAnA53a", + ]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "ownerAddress":"2oerfxddTpK5hWAmCMYB6fr9WvNrjEH54CHCWK8sAq7g", + "displayOptions": { + "showZeroBalance": false + } + } + "#; + + let request: api::GetTokenAccounts = serde_json::from_str(request).unwrap(); + let response = setup.das_api.get_token_accounts(request).await.unwrap(); + + insta::assert_json_snapshot!(name, response); +}