From 2524c1bc68b73285a099c615c48fe63d8db7b6f4 Mon Sep 17 00:00:00 2001 From: niks3089 Date: Tue, 20 Feb 2024 22:19:41 +0530 Subject: [PATCH 01/20] Token extensions Indexing support --- Cargo.lock | 24 +- .../src/dao/extensions/asset.rs | 1 + .../src/dao/generated/asset.rs | 3 + .../src/dao/generated/tokens.rs | 3 + digital_asset_types/src/dapi/common/asset.rs | 28 ++ digital_asset_types/src/rpc/asset.rs | 2 + migration/src/lib.rs | 2 + .../m20240219_115532_add_extensions_column.rs | 59 ++++ program_transformers/src/lib.rs | 2 + program_transformers/src/token/mod.rs | 3 +- .../src/token_extensions/mint.rs | 329 ++++++++++++++++++ .../src/token_extensions/mod.rs | 36 ++ .../src/token_extensions/token_account.rs | 136 ++++++++ .../src/token_metadata/v1_asset.rs | 4 +- program_transformers/src/utils.rs | 37 ++ 15 files changed, 654 insertions(+), 15 deletions(-) create mode 100644 migration/src/m20240219_115532_add_extensions_column.rs create mode 100644 program_transformers/src/token_extensions/mint.rs create mode 100644 program_transformers/src/token_extensions/mod.rs create mode 100644 program_transformers/src/token_extensions/token_account.rs create mode 100644 program_transformers/src/utils.rs diff --git a/Cargo.lock b/Cargo.lock index f2a48155b..7833978c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1207,9 +1207,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "d32a994c2b3ca201d9b263612a374263f05e7adde37c4707f693dcd375076d1f" [[package]] name = "bv" @@ -1566,9 +1566,9 @@ checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" dependencies = [ "cfg-if", ] @@ -2052,9 +2052,9 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" dependencies = [ "serde", ] @@ -2885,9 +2885,9 @@ dependencies = [ [[package]] name = "indicatif" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" +checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" dependencies = [ "console", "instant", @@ -3707,9 +3707,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", ] @@ -7419,9 +7419,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" diff --git a/digital_asset_types/src/dao/extensions/asset.rs b/digital_asset_types/src/dao/extensions/asset.rs index 18525e39e..6628b234b 100644 --- a/digital_asset_types/src/dao/extensions/asset.rs +++ b/digital_asset_types/src/dao/extensions/asset.rs @@ -103,6 +103,7 @@ impl Default for asset::Model { owner_delegate_seq: None, leaf_seq: None, base_info_seq: None, + mint_extensions: None, mpl_core_plugins: None, mpl_core_unknown_plugins: None, mpl_core_collection_current_size: None, diff --git a/digital_asset_types/src/dao/generated/asset.rs b/digital_asset_types/src/dao/generated/asset.rs index f70e0b383..f2f74d6a9 100644 --- a/digital_asset_types/src/dao/generated/asset.rs +++ b/digital_asset_types/src/dao/generated/asset.rs @@ -50,6 +50,7 @@ pub struct Model { pub owner_delegate_seq: Option, pub leaf_seq: Option, pub base_info_seq: Option, + pub mint_extensions: Option, pub mpl_core_plugins: Option, pub mpl_core_unknown_plugins: Option, pub mpl_core_collection_num_minted: Option, @@ -93,6 +94,7 @@ pub enum Column { OwnerDelegateSeq, LeafSeq, BaseInfoSeq, + MintExtensions, MplCorePlugins, MplCoreUnknownPlugins, MplCoreCollectionNumMinted, @@ -153,6 +155,7 @@ impl ColumnTrait for Column { Self::OwnerDelegateSeq => ColumnType::BigInteger.def().null(), Self::LeafSeq => ColumnType::BigInteger.def().null(), Self::BaseInfoSeq => ColumnType::BigInteger.def().null(), + Self::MintExtensions => ColumnType::JsonBinary.def().null(), Self::MplCorePlugins => ColumnType::JsonBinary.def().null(), Self::MplCoreUnknownPlugins => ColumnType::JsonBinary.def().null(), Self::MplCoreCollectionNumMinted => ColumnType::Integer.def().null(), diff --git a/digital_asset_types/src/dao/generated/tokens.rs b/digital_asset_types/src/dao/generated/tokens.rs index 326b8d968..3f6442fa9 100644 --- a/digital_asset_types/src/dao/generated/tokens.rs +++ b/digital_asset_types/src/dao/generated/tokens.rs @@ -23,6 +23,7 @@ pub struct Model { pub close_authority: Option>, pub extension_data: Option>, pub slot_updated: i64, + pub extensions: Option, } #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] @@ -36,6 +37,7 @@ pub enum Column { CloseAuthority, ExtensionData, SlotUpdated, + Extensions, } #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] @@ -66,6 +68,7 @@ impl ColumnTrait for Column { Self::CloseAuthority => ColumnType::Binary.def().null(), Self::ExtensionData => ColumnType::Binary.def().null(), Self::SlotUpdated => ColumnType::BigInteger.def(), + Self::Extensions => ColumnType::JsonBinary.def().null(), } } } diff --git a/digital_asset_types/src/dapi/common/asset.rs b/digital_asset_types/src/dapi/common/asset.rs index c9a9dd486..854fe7e5d 100644 --- a/digital_asset_types/src/dapi/common/asset.rs +++ b/digital_asset_types/src/dapi/common/asset.rs @@ -16,6 +16,7 @@ use log::warn; use mime_guess::Mime; use sea_orm::DbErr; +use serde_json::Map; use serde_json::Value; use std::cmp::Ordering; use std::collections::HashMap; @@ -47,6 +48,30 @@ pub fn file_from_str(str: String) -> File { } } +fn filter_non_null_fields(value: Option<&Value>) -> Option { + match value { + Some(Value::Null) => None, + Some(Value::Object(map)) => { + if map.values().all(|v| matches!(v, Value::Null)) { + None + } else { + let filtered_map: Map = map + .into_iter() + .filter(|(_k, v)| !matches!(v, Value::Null)) + .map(|(k, v)| (k.clone(), v.clone())) + .collect(); + + if filtered_map.is_empty() { + None + } else { + Some(Value::Object(filtered_map)) + } + } + } + _ => value.cloned(), + } +} + pub fn build_asset_response( assets: Vec, limit: u64, @@ -368,6 +393,8 @@ pub fn asset_to_rpc(asset: FullAsset, options: &Options) -> Result Some(MplCoreInfo { num_minted: asset.mpl_core_collection_num_minted, @@ -444,6 +471,7 @@ pub fn asset_to_rpc(asset: FullAsset, options: &Options) -> Result, + #[serde(skip_serializing_if = "Option::is_none")] pub plugins: Option, #[serde(skip_serializing_if = "Option::is_none")] pub unknown_plugins: Option, diff --git a/migration/src/lib.rs b/migration/src/lib.rs index 7cee77f5e..d2d5c9051 100644 --- a/migration/src/lib.rs +++ b/migration/src/lib.rs @@ -38,6 +38,7 @@ mod m20240116_130744_add_update_metadata_ix; mod m20240117_120101_alter_creator_indices; mod m20240124_173104_add_tree_seq_index_to_cl_audits_v2; mod m20240124_181900_add_slot_updated_column_per_update_type; +mod m20240219_115532_add_extensions_column; mod m20240313_120101_add_mpl_core_plugins_columns; mod m20240319_120101_add_mpl_core_enum_vals; mod m20240320_120101_add_mpl_core_info_items; @@ -90,6 +91,7 @@ impl MigratorTrait for Migrator { Box::new(m20240117_120101_alter_creator_indices::Migration), Box::new(m20240124_173104_add_tree_seq_index_to_cl_audits_v2::Migration), Box::new(m20240124_181900_add_slot_updated_column_per_update_type::Migration), + Box::new(m20240219_115532_add_extensions_column::Migration), Box::new(m20240313_120101_add_mpl_core_plugins_columns::Migration), Box::new(m20240319_120101_add_mpl_core_enum_vals::Migration), Box::new(m20240320_120101_add_mpl_core_info_items::Migration), diff --git a/migration/src/m20240219_115532_add_extensions_column.rs b/migration/src/m20240219_115532_add_extensions_column.rs new file mode 100644 index 000000000..dc3f3eada --- /dev/null +++ b/migration/src/m20240219_115532_add_extensions_column.rs @@ -0,0 +1,59 @@ +use sea_orm_migration::{ + prelude::*, + sea_orm::{ConnectionTrait, DatabaseBackend, Statement}, +}; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + let connection = manager.get_connection(); + + connection + .execute(Statement::from_string( + DatabaseBackend::Postgres, + "ALTER TABLE asset ADD COLUMN mint_extensions jsonb;".to_string(), + )) + .await?; + connection + .execute(Statement::from_string( + DatabaseBackend::Postgres, + "ALTER TABLE tokens ADD COLUMN extensions jsonb;".to_string(), + )) + .await?; + connection + .execute(Statement::from_string( + DatabaseBackend::Postgres, + "ALTER TABLE token_accounts ADD COLUMN extensions jsonb;".to_string(), + )) + .await?; + Ok(()) + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + let connection = manager.get_connection(); + + connection + .execute(Statement::from_string( + DatabaseBackend::Postgres, + "ALTER TABLE asset DROP COLUMN mint_extensions;".to_string(), + )) + .await?; + connection + .execute(Statement::from_string( + DatabaseBackend::Postgres, + "ALTER TABLE tokens DROP COLUMN extensions;".to_string(), + )) + .await?; + connection + .execute(Statement::from_string( + DatabaseBackend::Postgres, + "ALTER TABLE token_accounts DROP COLUMN extensions;".to_string(), + )) + .await?; + + Ok(()) + } +} diff --git a/program_transformers/src/lib.rs b/program_transformers/src/lib.rs index b317c47f6..9b7dae22a 100644 --- a/program_transformers/src/lib.rs +++ b/program_transformers/src/lib.rs @@ -33,7 +33,9 @@ mod bubblegum; pub mod error; mod mpl_core_program; mod token; +mod token_extensions; mod token_metadata; +mod utils; #[derive(Debug, Clone, PartialEq, Eq)] pub struct AccountInfo { diff --git a/program_transformers/src/token/mod.rs b/program_transformers/src/token/mod.rs index d46360317..c9dd8dfb0 100644 --- a/program_transformers/src/token/mod.rs +++ b/program_transformers/src/token/mod.rs @@ -13,7 +13,7 @@ use { entity::{ActiveValue, ColumnTrait}, query::{QueryFilter, QueryTrait}, sea_query::query::OnConflict, - ConnectionTrait, DatabaseConnection, DbBackend, EntityTrait, TransactionTrait, + ConnectionTrait, DatabaseConnection, DbBackend, EntityTrait, Set, TransactionTrait, }, solana_sdk::program_option::COption, spl_token::state::AccountState, @@ -116,6 +116,7 @@ pub async fn handle_token_program_account<'a, 'b>( extension_data: ActiveValue::Set(None), mint_authority: ActiveValue::Set(mint_auth), freeze_authority: ActiveValue::Set(freeze_auth), + extensions: ActiveValue::Set(None), }; let mut query = tokens::Entity::insert(model) diff --git a/program_transformers/src/token_extensions/mint.rs b/program_transformers/src/token_extensions/mint.rs new file mode 100644 index 000000000..b1bec2d96 --- /dev/null +++ b/program_transformers/src/token_extensions/mint.rs @@ -0,0 +1,329 @@ +use crate::{ + error::IngesterError, + program_transformers::{ + asset_upserts::{upsert_assets_token_account_columns, AssetTokenAccountColumns}, + utils::find_model_with_retry, + }, + tasks::{DownloadMetadata, IntoTaskData, TaskData}, +}; +use blockbuster::programs::token_extensions::{extension::ShadowMetadata, MintAccount}; +use chrono::Utc; +use digital_asset_types::dao::{ + asset, asset_authority, asset_data, + sea_orm_active_enums::{ + ChainMutability, OwnerType, SpecificationAssetClass, SpecificationVersions, + }, + token_accounts, tokens, +}; +use log::warn; +use plerkle_serialization::AccountInfo; +use sea_orm::{ + entity::*, query::*, sea_query::OnConflict, ActiveValue::Set, ConnectionTrait, + DatabaseConnection, DatabaseTransaction, DbBackend, DbErr, EntityTrait, +}; +use solana_sdk::{program_option::COption, pubkey::Pubkey}; + +const RETRY_INTERVALS: &[u64] = &[0, 5, 10]; + +pub async fn handle_token2022_mint_account<'a, 'b, 'c>( + m: &MintAccount, + account_update: &'a AccountInfo<'a>, + db: &'c DatabaseConnection, +) -> Result, IngesterError> { + let key = *account_update.pubkey().unwrap(); + let key_bytes = key.0.to_vec(); + let spl_token_program = account_update.owner().unwrap().0.to_vec(); + + let mut task: Option = None; + + let txn = db.begin().await?; + + insert_into_tokens_table( + m, + key_bytes.clone(), + spl_token_program, + account_update.slot() as i64, + &txn, + ) + .await?; + + if let Some(metadata) = &m.extensions.metadata { + upsert_asset_data( + metadata, + key_bytes.clone(), + account_update.slot() as i64, + &txn, + ) + .await?; + + task = Some(create_task(metadata, key_bytes.clone())?); + } + + if should_upsert_asset(m) { + upsert_asset(m, key_bytes.clone(), account_update.slot() as i64, db, &txn).await?; + } + + txn.commit().await?; + + Ok(task) +} + +fn should_upsert_asset(m: &MintAccount) -> bool { + is_token_nft(m) || m.extensions.metadata.is_some() +} + +fn is_token_nft(m: &MintAccount) -> bool { + m.account.supply == 1 && m.account.decimals == 0 +} + +async fn insert_into_tokens_table( + m: &MintAccount, + key_bytes: Vec, + spl_token_program: Vec, + slot: i64, + txn: &DatabaseTransaction, +) -> Result<(), IngesterError> { + let extensions = serde_json::to_value(m.extensions.clone()) + .map_err(|e| IngesterError::SerializatonError(e.to_string()))?; + let freeze_auth: Option> = match m.account.freeze_authority { + COption::Some(d) => Some(d.to_bytes().to_vec()), + COption::None => None, + }; + let mint_auth: Option> = match m.account.mint_authority { + COption::Some(d) => Some(d.to_bytes().to_vec()), + COption::None => None, + }; + let tokens_model = tokens::ActiveModel { + mint: Set(key_bytes.clone()), + token_program: Set(spl_token_program), + slot_updated: Set(slot), + supply: Set(m.account.supply as i64), + decimals: Set(m.account.decimals as i32), + close_authority: Set(None), + extension_data: Set(None), + mint_authority: Set(mint_auth), + freeze_authority: Set(freeze_auth), + extensions: Set(Some(extensions.clone())), + }; + + let mut tokens_query = tokens::Entity::insert(tokens_model) + .on_conflict( + OnConflict::columns([tokens::Column::Mint]) + .update_columns([ + tokens::Column::Supply, + tokens::Column::TokenProgram, + tokens::Column::MintAuthority, + tokens::Column::CloseAuthority, + tokens::Column::Extensions, + tokens::Column::SlotUpdated, + tokens::Column::Decimals, + tokens::Column::FreezeAuthority, + ]) + .to_owned(), + ) + .build(DbBackend::Postgres); + tokens_query.sql = format!( + "{} WHERE excluded.slot_updated >= tokens.slot_updated", + tokens_query.sql + ); + + txn.execute(tokens_query) + .await + .map_err(|db_err| IngesterError::AssetIndexError(db_err.to_string()))?; + + Ok(()) +} + +async fn upsert_asset_data( + metadata: &ShadowMetadata, + key_bytes: Vec, + slot: i64, + txn: &DatabaseTransaction, +) -> Result<(), IngesterError> { + let metadata_json = serde_json::to_value(metadata.clone()) + .map_err(|e| IngesterError::SerializatonError(e.to_string()))?; + let asset_data_model = asset_data::ActiveModel { + metadata_url: Set(metadata.uri.clone()), + id: Set(key_bytes.clone()), + chain_data_mutability: Set(ChainMutability::Mutable), + chain_data: Set(metadata_json), + slot_updated: Set(slot), + base_info_seq: Set(Some(0)), + raw_name: Set(Some(metadata.name.clone().into_bytes().to_vec())), + raw_symbol: Set(Some(metadata.symbol.clone().into_bytes().to_vec())), + ..Default::default() + }; + let mut asset_data_query = asset_data::Entity::insert(asset_data_model) + .on_conflict( + OnConflict::columns([asset_data::Column::Id]) + .update_columns([ + asset_data::Column::ChainDataMutability, + asset_data::Column::ChainData, + asset_data::Column::MetadataUrl, + asset_data::Column::SlotUpdated, + asset_data::Column::BaseInfoSeq, + ]) + .to_owned(), + ) + .build(DbBackend::Postgres); + asset_data_query.sql = format!( + "{} WHERE excluded.slot_updated >= asset_data.slot_updated", + asset_data_query.sql + ); + txn.execute(asset_data_query) + .await + .map_err(|db_err| IngesterError::AssetIndexError(db_err.to_string()))?; + Ok(()) +} + +async fn upsert_asset( + m: &MintAccount, + key_bytes: Vec, + slot: i64, + db: &DatabaseConnection, + txn: &DatabaseTransaction, +) -> Result<(), IngesterError> { + let is_nft = is_token_nft(m); + let owner_type = match is_nft { + true => OwnerType::Single, + false => OwnerType::Token, + }; + if is_nft { + let token_account: Option = find_model_with_retry( + db, + "token_accounts", + &token_accounts::Entity::find() + .filter(token_accounts::Column::Mint.eq(key_bytes.clone())) + .filter(token_accounts::Column::Amount.gt(0)) + .order_by(token_accounts::Column::SlotUpdated, Order::Desc), + RETRY_INTERVALS, + ) + .await + .map_err(|e: DbErr| IngesterError::DatabaseError(e.to_string()))?; + + match token_account { + Some(ta) => { + upsert_assets_token_account_columns( + AssetTokenAccountColumns { + mint: key_bytes.clone(), + owner: ta.owner, + frozen: ta.frozen, + delegate: ta.delegate, + slot_updated_token_account: Some(ta.slot_updated), + }, + txn, + ) + .await? + } + None => { + if m.account.supply == 1 { + warn!( + target: "Account not found", + "Token acc not found in 'token_accounts' table for mint {}", + bs58::encode(&key_bytes).into_string() + ); + } + } + } + + let extensions = serde_json::to_value(m.extensions.clone()) + .map_err(|e| IngesterError::SerializatonError(e.to_string()))?; + + let class = match is_nft { + true => SpecificationAssetClass::Nft, + false => SpecificationAssetClass::FungibleToken, + }; + + let mut asset_model = asset::ActiveModel { + id: Set(key_bytes.clone()), + owner_type: Set(owner_type), + supply: Set(m.account.supply as i64), + supply_mint: Set(Some(key_bytes.clone())), + specification_version: Set(Some(SpecificationVersions::V1)), + specification_asset_class: Set(Some(class)), + nonce: Set(Some(0)), + seq: Set(Some(0)), + compressed: Set(false), + compressible: Set(false), + asset_data: Set(Some(key_bytes.clone())), + slot_updated: Set(Some(slot)), + burnt: Set(false), + mint_extensions: Set(Some(extensions)), + ..Default::default() + }; + + let auth_address: Option> = m.extensions.metadata.clone().and_then(|m| { + let auth_pubkey: Option = m.update_authority.into(); + auth_pubkey.map(|value| value.to_bytes().to_vec()) + }); + + if let Some(authority) = auth_address { + let model = asset_authority::ActiveModel { + asset_id: Set(key_bytes.clone()), + authority: Set(authority), + seq: Set(0), + slot_updated: Set(slot), + ..Default::default() + }; + + let mut query = asset_authority::Entity::insert(model) + .on_conflict( + OnConflict::columns([asset_authority::Column::AssetId]) + .update_columns([ + asset_authority::Column::Authority, + asset_authority::Column::Seq, + asset_authority::Column::SlotUpdated, + ]) + .to_owned(), + ) + .build(DbBackend::Postgres); + query.sql = format!( + "{} WHERE excluded.slot_updated > asset_authority.slot_updated", + query.sql + ); + txn.execute(query) + .await + .map_err(|db_err| IngesterError::AssetIndexError(db_err.to_string()))?; + } + + let mut asset_query = asset::Entity::insert(asset_model) + .on_conflict( + OnConflict::columns([asset::Column::Id]) + .update_columns(vec![ + asset::Column::OwnerType, + asset::Column::Supply, + asset::Column::SupplyMint, + asset::Column::SpecificationVersion, + asset::Column::SpecificationAssetClass, + asset::Column::Nonce, + asset::Column::Seq, + asset::Column::Compressed, + asset::Column::Compressible, + asset::Column::AssetData, + asset::Column::SlotUpdated, + asset::Column::Burnt, + ]) + .to_owned(), + ) + .build(DbBackend::Postgres); + asset_query.sql = format!( + "{} WHERE excluded.slot_updated_mint_account >= asset.slot_updated_mint_account OR asset.slot_updated_mint_account IS NULL", + asset_query.sql + ); + txn.execute(asset_query) + .await + .map_err(|db_err| IngesterError::AssetIndexError(db_err.to_string()))?; + } + Ok(()) +} + +fn create_task(metadata: &ShadowMetadata, key_bytes: Vec) -> Result { + let mut dm = DownloadMetadata { + asset_data_id: key_bytes.clone(), + uri: metadata.uri.clone(), + created_at: Some(Utc::now().naive_utc()), + }; + dm.sanitize(); + let td = dm.into_task_data()?; + Ok(td) +} diff --git a/program_transformers/src/token_extensions/mod.rs b/program_transformers/src/token_extensions/mod.rs new file mode 100644 index 000000000..219fe5425 --- /dev/null +++ b/program_transformers/src/token_extensions/mod.rs @@ -0,0 +1,36 @@ +mod mint; +mod token_account; + +use crate::{ + error::{ProgramTransformerError, ProgramTransformerResult}, + tasks::TaskData, +}; +use blockbuster::programs::token_extensions::TokenExtensionsProgramAccount; +use plerkle_serialization::AccountInfo; +use sea_orm::DatabaseConnection; +use tokio::sync::mpsc::UnboundedSender; + +use self::{mint::handle_token2022_mint_account, token_account::handle_token2022_token_account}; + +pub async fn handle_token_extensions_program_account<'a, 'b, 'c>( + account_update: &'a AccountInfo<'a>, + parsing_result: &'b TokenExtensionsProgramAccount, + db: &'c DatabaseConnection, + task_manager: &UnboundedSender, +) -> ProgramTransformerResult<()> { + match &parsing_result { + TokenExtensionsProgramAccount::TokenAccount(ta) => { + handle_token2022_token_account(ta, account_update, db).await?; + Ok(()) + } + TokenExtensionsProgramAccount::MintAccount(m) => { + let task = handle_token2022_mint_account(m, account_update, db).await?; + if let Some(t) = task { + task_manager.send(t)?; + } + Ok(()) + } + _ => Err(ProgramTransformerError::NotImplemented), + }?; + Ok(()) +} diff --git a/program_transformers/src/token_extensions/token_account.rs b/program_transformers/src/token_extensions/token_account.rs new file mode 100644 index 000000000..7f5df68fa --- /dev/null +++ b/program_transformers/src/token_extensions/token_account.rs @@ -0,0 +1,136 @@ +use crate::{ + error::IngesterError, + metric, + program_transformers::{ + asset_upserts::{upsert_assets_token_account_columns, AssetTokenAccountColumns}, + token::upsert_owner_for_token_account, + }, +}; +use blockbuster::programs::token_extensions::TokenAccount; +use cadence_macros::{is_global_default_set, statsd_count}; +use digital_asset_types::dao::asset; +use plerkle_serialization::AccountInfo; +use sea_orm::{entity::*, query::*, ActiveValue::Set, DatabaseConnection, EntityTrait}; +use solana_sdk::program_option::COption; +use spl_token_2022::state::AccountState; + +pub async fn handle_token2022_token_account<'a, 'b, 'c>( + ta: &TokenAccount, + account_update: &'a AccountInfo<'a>, + db: &'c DatabaseConnection, +) -> Result<(), IngesterError> { + let key = *account_update.pubkey().unwrap(); + let key_bytes = key.0.to_vec(); + let spl_token_program = account_update.owner().unwrap().0.to_vec(); + + let mint = ta.account.mint.to_bytes().to_vec(); + let delegate: Option> = match ta.account.delegate { + COption::Some(d) => Some(d.to_bytes().to_vec()), + COption::None => None, + }; + let frozen = match ta.account.state { + AccountState::Frozen => true, + _ => false, + }; + let owner = ta.account.owner.to_bytes().to_vec(); + + upsert_owner_for_token_account( + db, + mint.clone(), + key_bytes, + owner.clone(), + delegate.clone(), + account_update.slot() as i64, + frozen, + ta.account.amount, + ta.account.delegated_amount as i64, + spl_token_program, + ) + .await?; + + // Metrics + let mut token_owner_update = false; + let mut token_delegate_update = false; + let mut token_freeze_update = false; + + let txn = db.begin().await?; + let asset_update = asset::Entity::find_by_id(mint.clone()) + .filter( + asset::Column::OwnerType.eq("single").and( + asset::Column::SlotUpdated + .is_null() + .or(asset::Column::SlotUpdated.lte(account_update.slot() as i64)), + ), + ) + .one(&txn) + .await?; + + if let Some(asset) = asset_update { + // Only handle token account updates for NFTs (supply=1) + let asset_clone = asset.clone(); + if asset_clone.supply == 1 { + let mut save_required = false; + let mut active: asset::ActiveModel = asset.into(); + + // Handle ownership updates + let old_owner = asset_clone.owner.clone(); + let new_owner = owner.clone(); + if ta.account.amount > 0 && Some(new_owner) != old_owner { + active.owner = Set(Some(owner.clone())); + token_owner_update = true; + save_required = true; + } + + // Handle delegate updates + if ta.account.amount > 0 && delegate.clone() != asset_clone.delegate { + active.delegate = Set(delegate.clone()); + token_delegate_update = true; + save_required = true; + } + + // Handle freeze updates + if ta.account.amount > 0 && frozen != asset_clone.frozen { + active.frozen = Set(frozen); + token_freeze_update = true; + save_required = true; + } + + let token_extensions = serde_json::to_value(ta.extensions.clone()) + .map_err(|e| IngesterError::SerializatonError(e.to_string()))?; + + if save_required { + upsert_assets_token_account_columns( + AssetTokenAccountColumns { + mint, + owner: Some(owner), + frozen, + delegate, + slot_updated_token_account: Some(account_update.slot() as i64), + }, + &txn, + ) + .await?; + } + } + } + txn.commit().await?; + + // Publish metrics outside of the txn to reduce txn latency. + if token_owner_update { + metric! { + statsd_count!("token_account.owner_update", 1); + } + } + if token_delegate_update { + metric! { + statsd_count!("token_account.delegate_update", 1); + } + } + if token_freeze_update { + metric! { + statsd_count!("token_account.freeze_update", 1); + } + } + + Ok(()) +} diff --git a/program_transformers/src/token_metadata/v1_asset.rs b/program_transformers/src/token_metadata/v1_asset.rs index 7c45b68b7..f303d3e4a 100644 --- a/program_transformers/src/token_metadata/v1_asset.rs +++ b/program_transformers/src/token_metadata/v1_asset.rs @@ -109,7 +109,7 @@ async fn index_token_account_data( ) -> ProgramTransformerResult<()> { let token_account: Option = find_model_with_retry( conn, - "owners", + "token_accounts", &token_accounts::Entity::find() .filter(token_accounts::Column::Mint.eq(mint_pubkey_vec.clone())) .filter(token_accounts::Column::Amount.gt(0)) @@ -135,7 +135,7 @@ async fn index_token_account_data( } else { warn!( target: "Account not found", - "Token acc not found in 'owners' table for mint {}", + "Token acc not found in 'token-accounts' table for mint {}", bs58::encode(&mint_pubkey_vec).into_string() ); } diff --git a/program_transformers/src/utils.rs b/program_transformers/src/utils.rs new file mode 100644 index 000000000..ca549a707 --- /dev/null +++ b/program_transformers/src/utils.rs @@ -0,0 +1,37 @@ +use cadence_macros::{is_global_default_set, statsd_count}; +use sea_orm::{query::*, ConnectionTrait, DbErr, EntityTrait}; +use std::time::Duration; +use tokio::time::sleep; + +pub async fn find_model_with_retry( + conn: &T, + model_name: &str, + select: &Select, + retry_intervals: &[u64], +) -> Result, DbErr> { + let mut retries = 0; + let metric_name = format!("{}_found", model_name); + + for interval in retry_intervals { + let interval_duration = Duration::from_millis(interval.to_owned()); + sleep(interval_duration).await; + + let model = select.clone().one(conn).await?; + if let Some(m) = model { + record_metric(&metric_name, true, retries); + return Ok(Some(m)); + } + retries += 1; + } + + record_metric(&metric_name, false, retries - 1); + Ok(None) +} + +fn record_metric(metric_name: &str, success: bool, retries: u32) { + let retry_count = &retries.to_string(); + let success = if success { "true" } else { "false" }; + metric! { + statsd_count!(metric_name, 1, "success" => success, "retry_count" => retry_count); + } +} From 0b5a5451bb8089640678fa154bc20484d43d10fa Mon Sep 17 00:00:00 2001 From: Kyle Espinola Date: Fri, 29 Mar 2024 07:17:43 +0100 Subject: [PATCH 02/20] fix: register token extensions parser with program transform. add integration test for the token extensions. --- ...Kwjfsx6qpiw3RkwUbQZgjm9t6cpf6gnvGmNJPunerx | Bin 0 -> 312 bytes ...U5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y | Bin 0 -> 496 bytes .../tests/integration_tests/main.rs | 1 + ...ons_tests__token_extensions_get_asset.snap | 74 ++++++++++++++++++ .../token_extensions_tests.rs | 42 ++++++++++ program_transformers/src/lib.rs | 26 +++++- .../src/token_extensions/mint.rs | 1 + .../src/token_extensions/mod.rs | 1 - 8 files changed, 140 insertions(+), 5 deletions(-) create mode 100644 integration_tests/tests/data/accounts/token_extensions_get_asset/AXKwjfsx6qpiw3RkwUbQZgjm9t6cpf6gnvGmNJPunerx create mode 100644 integration_tests/tests/data/accounts/token_extensions_get_asset/BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y create mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__token_extensions_tests__token_extensions_get_asset.snap create mode 100644 integration_tests/tests/integration_tests/token_extensions_tests.rs diff --git a/integration_tests/tests/data/accounts/token_extensions_get_asset/AXKwjfsx6qpiw3RkwUbQZgjm9t6cpf6gnvGmNJPunerx b/integration_tests/tests/data/accounts/token_extensions_get_asset/AXKwjfsx6qpiw3RkwUbQZgjm9t6cpf6gnvGmNJPunerx new file mode 100644 index 0000000000000000000000000000000000000000..4134dad7e63f443d165ab067e2367317593db757 GIT binary patch literal 312 zcmY#jfB*@G3p*mPvm7 zv-jKKU(-HiPV!~D`|aVo(*AoAPO*EQ@AF=dhi4)_{gn4#WYB-_+%C;;rsV|(_HB87Di~-C(SQ`SD26hzgSh~z C6I=lR literal 0 HcmV?d00001 diff --git a/integration_tests/tests/data/accounts/token_extensions_get_asset/BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y b/integration_tests/tests/data/accounts/token_extensions_get_asset/BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y new file mode 100644 index 0000000000000000000000000000000000000000..357411c17a7feac2d92f747959c0bddb86837e2b GIT binary patch literal 496 zcmY#jfB*@G3eYws-;VJdtF72Lx%-&gT7jO& z(Os`MziO5JSbLf6?ze~UO8f6gIK}RHl5_UfHmN_p%{zJ3|Ly&$absckACQ>|2F5^= zf#E+Ctk*XZ1o597Jm1#G$iR>U#6ZMwCjXK>@AF=dhi4)_{gn4#WYB-_+%C;;rsV|( z_HB87Dj1{&4B!ly0G((?AqEG6t|Sy = seed_accounts([ + "BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y", + "AXKwjfsx6qpiw3RkwUbQZgjm9t6cpf6gnvGmNJPunerx", + ]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "id": "BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y" + } + "#; + + let request: api::GetAsset = serde_json::from_str(request).unwrap(); + let response = setup.das_api.get_asset(request).await.unwrap(); + + insta::assert_json_snapshot!(name, response); +} diff --git a/program_transformers/src/lib.rs b/program_transformers/src/lib.rs index 9b7dae22a..3a95ac66e 100644 --- a/program_transformers/src/lib.rs +++ b/program_transformers/src/lib.rs @@ -11,8 +11,8 @@ use { program_handler::ProgramParser, programs::{ bubblegum::BubblegumParser, mpl_core_program::MplCoreParser, - token_account::TokenAccountParser, token_metadata::TokenMetadataParser, - ProgramParseResult, + token_account::TokenAccountParser, token_extensions::Token2022AccountParser, + token_metadata::TokenMetadataParser, ProgramParseResult, }, }, futures::future::BoxFuture, @@ -89,16 +89,23 @@ pub struct ProgramTransformer { } impl ProgramTransformer { - pub fn new(pool: PgPool, download_metadata_notifier: DownloadMetadataNotifier) -> Self { - let mut parsers: HashMap> = HashMap::with_capacity(3); + pub fn new( + pool: PgPool, + download_metadata_notifier: DownloadMetadataNotifier, + cl_audits: bool, + ) -> Self { + info!("Initializing Program Transformer"); + let mut parsers: HashMap> = HashMap::with_capacity(5); let bgum = BubblegumParser {}; let token_metadata = TokenMetadataParser {}; let token = TokenAccountParser {}; let mpl_core = MplCoreParser {}; + let token_extensions = Token2022AccountParser {}; parsers.insert(bgum.key(), Box::new(bgum)); parsers.insert(token_metadata.key(), Box::new(token_metadata)); parsers.insert(token.key(), Box::new(token)); parsers.insert(mpl_core.key(), Box::new(mpl_core)); + parsers.insert(token_extensions.key(), Box::new(token_extensions)); let hs = parsers.iter().fold(HashSet::new(), |mut acc, (k, _)| { acc.insert(*k); acc @@ -213,6 +220,7 @@ impl ProgramTransformer { &self, account_info: &AccountInfo, ) -> ProgramTransformerResult<()> { + info!("Handling Account Update: {:?}", account_info.pubkey); if let Some(program) = self.match_program(&account_info.owner) { let result = program.handle_account(&account_info.data)?; match result.result_type() { @@ -234,6 +242,16 @@ impl ProgramTransformer { ) .await } + ProgramParseResult::TokenExtensionsProgramAccount(parsing_result) => { + info!("Handling Token Extensions Program Account"); + handle_token_extensions_program_account( + account_info, + parsing_result, + &self.storage, + &self.download_metadata_notifier, + ) + .await + } ProgramParseResult::MplCore(parsing_result) => { handle_mpl_core_account( account_info, diff --git a/program_transformers/src/token_extensions/mint.rs b/program_transformers/src/token_extensions/mint.rs index b1bec2d96..a0343fd55 100644 --- a/program_transformers/src/token_extensions/mint.rs +++ b/program_transformers/src/token_extensions/mint.rs @@ -144,6 +144,7 @@ async fn upsert_asset_data( .map_err(|e| IngesterError::SerializatonError(e.to_string()))?; let asset_data_model = asset_data::ActiveModel { metadata_url: Set(metadata.uri.clone()), + metadata: Set(JsonValue::String("processing".to_string())), id: Set(key_bytes.clone()), chain_data_mutability: Set(ChainMutability::Mutable), chain_data: Set(metadata_json), diff --git a/program_transformers/src/token_extensions/mod.rs b/program_transformers/src/token_extensions/mod.rs index 219fe5425..599bc47b0 100644 --- a/program_transformers/src/token_extensions/mod.rs +++ b/program_transformers/src/token_extensions/mod.rs @@ -1,6 +1,5 @@ mod mint; mod token_account; - use crate::{ error::{ProgramTransformerError, ProgramTransformerResult}, tasks::TaskData, From d1855e0ba6d5e9d1ddf269dec8251126f68933ed Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Thu, 7 Nov 2024 17:36:38 +0530 Subject: [PATCH 03/20] WIP : token extensions --- Cargo.lock | 1 + blockbuster/src/programs/token_account/mod.rs | 10 + .../src/programs/token_extensions/mod.rs | 39 +++ .../src/dao/generated/token_accounts.rs | 3 + .../src/dao/generated/tokens.rs | 10 + digital_asset_types/src/dapi/common/asset.rs | 42 +-- digital_asset_types/src/rpc/asset.rs | 27 +- digital_asset_types/tests/common.rs | 1 + .../m20240219_115532_add_extensions_column.rs | 1 + program_transformers/Cargo.toml | 1 + program_transformers/src/asset_upserts.rs | 25 +- program_transformers/src/lib.rs | 34 +- .../src/mpl_core_program/v1_asset.rs | 5 +- program_transformers/src/token/mod.rs | 96 +++-- .../src/token_extensions/mint.rs | 330 ------------------ .../src/token_extensions/mod.rs | 253 ++++++++++++-- .../src/token_extensions/token_account.rs | 136 -------- .../src/token_metadata/v1_asset.rs | 10 +- program_transformers/src/utils.rs | 37 -- 19 files changed, 432 insertions(+), 629 deletions(-) delete mode 100644 program_transformers/src/token_extensions/mint.rs delete mode 100644 program_transformers/src/token_extensions/token_account.rs delete mode 100644 program_transformers/src/utils.rs diff --git a/Cargo.lock b/Cargo.lock index 7833978c8..672bb3651 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4286,6 +4286,7 @@ dependencies = [ "solana-transaction-status", "spl-account-compression", "spl-token", + "spl-token-2022", "sqlx", "thiserror", "tokio", diff --git a/blockbuster/src/programs/token_account/mod.rs b/blockbuster/src/programs/token_account/mod.rs index 298fa3336..455552935 100644 --- a/blockbuster/src/programs/token_account/mod.rs +++ b/blockbuster/src/programs/token_account/mod.rs @@ -75,3 +75,13 @@ impl ProgramParser for TokenAccountParser { Ok(Box::new(account_type)) } } + +pub trait IsNonFungible { + fn is_non_fungible(&self) -> bool; +} + +impl IsNonFungible for Mint { + fn is_non_fungible(&self) -> bool { + self.decimals == 0 && self.mint_authority.is_none() + } +} diff --git a/blockbuster/src/programs/token_extensions/mod.rs b/blockbuster/src/programs/token_extensions/mod.rs index ec1633c9c..b8c5afe08 100644 --- a/blockbuster/src/programs/token_extensions/mod.rs +++ b/blockbuster/src/programs/token_extensions/mod.rs @@ -56,6 +56,26 @@ pub struct MintAccountExtensions { pub token_group_member: Option, } +impl MintAccountExtensions { + pub fn is_some(&self) -> bool { + self.default_account_state.is_some() + || self.confidential_transfer_mint.is_some() + || self.confidential_transfer_account.is_some() + || self.confidential_transfer_fee_config.is_some() + || self.interest_bearing_config.is_some() + || self.transfer_fee_config.is_some() + || self.mint_close_authority.is_some() + || self.permanent_delegate.is_some() + || self.metadata_pointer.is_some() + || self.metadata.is_some() + || self.transfer_hook.is_some() + || self.group_pointer.is_some() + || self.token_group.is_some() + || self.group_member_pointer.is_some() + || self.token_group_member.is_some() + } +} + #[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] pub struct TokenAccountExtensions { pub confidential_transfer: Option, @@ -63,6 +83,15 @@ pub struct TokenAccountExtensions { pub memo_transfer: Option, pub transfer_fee_amount: Option, } + +impl TokenAccountExtensions { + pub fn is_some(&self) -> bool { + self.confidential_transfer.is_some() + || self.cpi_guard.is_some() + || self.memo_transfer.is_some() + || self.transfer_fee_amount.is_some() + } +} #[derive(Debug, PartialEq)] pub struct TokenAccount { pub account: Account, @@ -208,3 +237,13 @@ impl ProgramParser for Token2022AccountParser { Ok(Box::new(result)) } } + +pub trait IsNonFungible { + fn is_non_fungible(&self) -> bool; +} + +impl IsNonFungible for Mint { + fn is_non_fungible(&self) -> bool { + self.decimals == 0 && self.mint_authority.is_none() + } +} diff --git a/digital_asset_types/src/dao/generated/token_accounts.rs b/digital_asset_types/src/dao/generated/token_accounts.rs index 380e29b42..d758403b8 100644 --- a/digital_asset_types/src/dao/generated/token_accounts.rs +++ b/digital_asset_types/src/dao/generated/token_accounts.rs @@ -24,6 +24,7 @@ pub struct Model { pub delegated_amount: i64, pub slot_updated: i64, pub token_program: Vec, + pub extensions: Option, } #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] @@ -38,6 +39,7 @@ pub enum Column { DelegatedAmount, SlotUpdated, TokenProgram, + Extensions, } #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] @@ -69,6 +71,7 @@ impl ColumnTrait for Column { Self::DelegatedAmount => ColumnType::BigInteger.def(), Self::SlotUpdated => ColumnType::BigInteger.def(), Self::TokenProgram => ColumnType::Binary.def(), + Self::Extensions => ColumnType::Json.def().null(), } } } diff --git a/digital_asset_types/src/dao/generated/tokens.rs b/digital_asset_types/src/dao/generated/tokens.rs index 3f6442fa9..de8a0e352 100644 --- a/digital_asset_types/src/dao/generated/tokens.rs +++ b/digital_asset_types/src/dao/generated/tokens.rs @@ -80,3 +80,13 @@ impl RelationTrait for Relation { } impl ActiveModelBehavior for ActiveModel {} + +pub trait IsNonFungible { + fn is_non_fungible(&self) -> bool; +} + +impl IsNonFungible for Model { + fn is_non_fungible(&self) -> bool { + self.decimals == 0 && self.mint_authority.is_none() + } +} diff --git a/digital_asset_types/src/dapi/common/asset.rs b/digital_asset_types/src/dapi/common/asset.rs index 854fe7e5d..e7d331956 100644 --- a/digital_asset_types/src/dapi/common/asset.rs +++ b/digital_asset_types/src/dapi/common/asset.rs @@ -16,7 +16,6 @@ use log::warn; use mime_guess::Mime; use sea_orm::DbErr; -use serde_json::Map; use serde_json::Value; use std::cmp::Ordering; use std::collections::HashMap; @@ -48,30 +47,6 @@ pub fn file_from_str(str: String) -> File { } } -fn filter_non_null_fields(value: Option<&Value>) -> Option { - match value { - Some(Value::Null) => None, - Some(Value::Object(map)) => { - if map.values().all(|v| matches!(v, Value::Null)) { - None - } else { - let filtered_map: Map = map - .into_iter() - .filter(|(_k, v)| !matches!(v, Value::Null)) - .map(|(k, v)| (k.clone(), v.clone())) - .collect(); - - if filtered_map.is_empty() { - None - } else { - Some(Value::Object(filtered_map)) - } - } - } - _ => value.cloned(), - } -} - pub fn build_asset_response( assets: Vec, limit: u64, @@ -394,7 +369,6 @@ pub fn asset_to_rpc(asset: FullAsset, options: &Options) -> Result Some(MplCoreInfo { num_minted: asset.mpl_core_collection_num_minted, @@ -404,6 +378,16 @@ pub fn asset_to_rpc(asset: FullAsset, options: &Options) -> Result None, }; + if interface == Interface::FungibleToken { + return Ok(RpcAsset { + interface: interface.clone(), + id: bs58::encode(asset.id).into_string(), + content: Some(content), + mint_extensions: asset.mint_extensions, + ..Default::default() + }); + } + Ok(RpcAsset { interface: interface.clone(), id: bs58::encode(asset.id).into_string(), @@ -442,7 +426,7 @@ pub fn asset_to_rpc(asset: FullAsset, options: &Options) -> Result Result Some(Supply { edition_nonce, @@ -471,7 +455,7 @@ pub fn asset_to_rpc(asset: FullAsset, options: &Options) -> Result for Interface { @@ -60,6 +63,8 @@ impl From<(&SpecificationVersions, &SpecificationAssetClass)> for Interface { } (_, SpecificationAssetClass::MplCoreAsset) => Interface::MplCoreAsset, (_, SpecificationAssetClass::MplCoreCollection) => Interface::MplCoreCollection, + (_, SpecificationAssetClass::FungibleAsset) => Interface::FungibleAsset, + (_, SpecificationAssetClass::FungibleToken) => Interface::FungibleToken, _ => Interface::Custom, } } @@ -87,6 +92,10 @@ impl From for (SpecificationVersions, SpecificationAssetClass) { SpecificationVersions::V1, SpecificationAssetClass::MplCoreCollection, ), + Interface::FungibleToken => ( + SpecificationVersions::V0, + SpecificationAssetClass::FungibleToken, + ), _ => (SpecificationVersions::V1, SpecificationAssetClass::Unknown), } } @@ -366,7 +375,7 @@ pub struct MplCoreInfo { pub plugins_json_version: Option, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema, Default)] pub struct Asset { pub interface: Interface, pub id: String, @@ -382,9 +391,11 @@ pub struct Asset { pub royalty: Option, #[serde(skip_serializing_if = "Option::is_none")] pub creators: Option>, - pub ownership: Ownership, + #[serde(skip_serializing_if = "Option::is_none")] + pub ownership: Option, #[serde(skip_serializing_if = "Option::is_none")] pub uses: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub supply: Option, pub mutable: bool, pub burnt: bool, diff --git a/digital_asset_types/tests/common.rs b/digital_asset_types/tests/common.rs index 0dcad71ef..6f40f610e 100644 --- a/digital_asset_types/tests/common.rs +++ b/digital_asset_types/tests/common.rs @@ -169,6 +169,7 @@ pub fn create_asset( mpl_core_plugins_json_version: None, mpl_core_external_plugins: None, mpl_core_unknown_external_plugins: None, + mint_extensions: None, }, ) } diff --git a/migration/src/m20240219_115532_add_extensions_column.rs b/migration/src/m20240219_115532_add_extensions_column.rs index dc3f3eada..d0414ea18 100644 --- a/migration/src/m20240219_115532_add_extensions_column.rs +++ b/migration/src/m20240219_115532_add_extensions_column.rs @@ -29,6 +29,7 @@ impl MigrationTrait for Migration { "ALTER TABLE token_accounts ADD COLUMN extensions jsonb;".to_string(), )) .await?; + Ok(()) } diff --git a/program_transformers/Cargo.toml b/program_transformers/Cargo.toml index 35bab7a19..de6eb6cc3 100644 --- a/program_transformers/Cargo.toml +++ b/program_transformers/Cargo.toml @@ -25,6 +25,7 @@ sqlx = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true, features = ["time"] } tracing = { workspace = true } +spl-token-2022 = {workspace = true, features = ["no-entrypoint"]} [lints] workspace = true diff --git a/program_transformers/src/asset_upserts.rs b/program_transformers/src/asset_upserts.rs index 5561ff5fd..e9dcea0b9 100644 --- a/program_transformers/src/asset_upserts.rs +++ b/program_transformers/src/asset_upserts.rs @@ -56,19 +56,31 @@ pub async fn upsert_assets_token_account_columns, pub supply: Decimal, - pub supply_mint: Option>, - pub slot_updated_mint_account: u64, + pub slot_updated_mint_account: i64, + pub extensions: Option, } pub async fn upsert_assets_mint_account_columns( columns: AssetMintAccountColumns, + is_non_fungible: bool, txn_or_conn: &T, ) -> Result<(), DbErr> { + let specification_asset_class = if is_non_fungible { + None + } else { + // If its not non-fungible then + // by default, we assume that the asset is fungibleToken and later update based on token metadata + Some(SpecificationAssetClass::FungibleToken) + }; + let active_model = asset::ActiveModel { - id: Set(columns.mint), + id: Set(columns.mint.clone()), supply: Set(columns.supply), - supply_mint: Set(columns.supply_mint), - slot_updated_mint_account: Set(Some(columns.slot_updated_mint_account as i64)), + supply_mint: Set(Some(columns.mint.clone())), + slot_updated_mint_account: Set(Some(columns.slot_updated_mint_account)), + mint_extensions: Set(columns.extensions), + asset_data: Set(Some(columns.mint)), + specification_asset_class: Set(specification_asset_class), ..Default::default() }; let mut query = asset::Entity::insert(active_model) @@ -76,8 +88,9 @@ pub async fn upsert_assets_mint_account_columns Self { + pub fn new(pool: PgPool, download_metadata_notifier: DownloadMetadataNotifier) -> Self { info!("Initializing Program Transformer"); let mut parsers: HashMap> = HashMap::with_capacity(5); let bgum = BubblegumParser {}; @@ -248,7 +245,6 @@ impl ProgramTransformer { account_info, parsing_result, &self.storage, - &self.download_metadata_notifier, ) .await } @@ -300,3 +296,27 @@ fn record_metric(metric_name: &str, success: bool, retries: u32) { cadence_macros::statsd_count!(metric_name, 1, "success" => success, "retry_count" => retry_count); } } + +pub fn filter_non_null_fields(value: Value) -> Option { + match value { + Value::Null => None, + Value::Object(map) => { + if map.values().all(|v| matches!(v, Value::Null)) { + None + } else { + let filtered_map: Map = map + .into_iter() + .filter(|(_k, v)| !matches!(v, Value::Null)) + .map(|(k, v)| (k.clone(), v.clone())) + .collect(); + + if filtered_map.is_empty() { + None + } else { + Some(Value::Object(filtered_map)) + } + } + } + _ => Some(value), + } +} diff --git a/program_transformers/src/mpl_core_program/v1_asset.rs b/program_transformers/src/mpl_core_program/v1_asset.rs index 42e449286..fb3929915 100644 --- a/program_transformers/src/mpl_core_program/v1_asset.rs +++ b/program_transformers/src/mpl_core_program/v1_asset.rs @@ -316,10 +316,11 @@ pub async fn save_v1_asset( upsert_assets_mint_account_columns( AssetMintAccountColumns { mint: id_vec.clone(), - supply_mint: None, supply, - slot_updated_mint_account: slot, + slot_updated_mint_account: slot as i64, + extensions: None, }, + true, &txn, ) .await?; diff --git a/program_transformers/src/token/mod.rs b/program_transformers/src/token/mod.rs index c9dd8dfb0..2969b7bae 100644 --- a/program_transformers/src/token/mod.rs +++ b/program_transformers/src/token/mod.rs @@ -7,13 +7,14 @@ use { error::ProgramTransformerResult, AccountInfo, DownloadMetadataNotifier, }, - blockbuster::programs::token_account::TokenProgramAccount, - digital_asset_types::dao::{asset, sea_orm_active_enums::OwnerType, token_accounts, tokens}, + blockbuster::programs::token_account::{IsNonFungible, TokenProgramAccount}, + digital_asset_types::dao::{ + token_accounts, + tokens::{self, IsNonFungible as IsNonFungibleModel}, + }, sea_orm::{ - entity::{ActiveValue, ColumnTrait}, - query::{QueryFilter, QueryTrait}, - sea_query::query::OnConflict, - ConnectionTrait, DatabaseConnection, DbBackend, EntityTrait, Set, TransactionTrait, + entity::ActiveValue, query::QueryTrait, sea_query::query::OnConflict, ConnectionTrait, + DatabaseConnection, DbBackend, EntityTrait, TransactionTrait, }, solana_sdk::program_option::COption, spl_token::state::AccountState, @@ -27,6 +28,7 @@ pub async fn handle_token_program_account<'a, 'b>( ) -> ProgramTransformerResult<()> { let account_key = account_info.pubkey.to_bytes().to_vec(); let account_owner = account_info.owner.to_bytes().to_vec(); + let slot = account_info.slot as i64; match &parsing_result { TokenProgramAccount::TokenAccount(ta) => { let mint = ta.mint.to_bytes().to_vec(); @@ -44,9 +46,10 @@ pub async fn handle_token_program_account<'a, 'b>( frozen: ActiveValue::Set(frozen), delegated_amount: ActiveValue::Set(ta.delegated_amount as i64), token_program: ActiveValue::Set(account_owner.clone()), - slot_updated: ActiveValue::Set(account_info.slot as i64), + slot_updated: ActiveValue::Set(slot), amount: ActiveValue::Set(ta.amount as i64), close_authority: ActiveValue::Set(None), + extensions: ActiveValue::Set(None), }; let mut query = token_accounts::Entity::insert(model) @@ -71,30 +74,29 @@ pub async fn handle_token_program_account<'a, 'b>( query.sql ); db.execute(query).await?; - let txn = db.begin().await?; - let asset_update: Option = asset::Entity::find_by_id(mint.clone()) - .filter(asset::Column::OwnerType.eq("single")) - .one(&txn) + + let token = tokens::Entity::find_by_id(mint.clone()).one(db).await?; + + let is_non_fungible = token.map(|t| t.is_non_fungible()).unwrap_or(false); + + if is_non_fungible { + let txn = db.begin().await?; + + upsert_assets_token_account_columns( + AssetTokenAccountColumns { + mint: mint.clone(), + owner: Some(owner.clone()), + frozen, + delegate, + slot_updated_token_account: Some(slot), + }, + &txn, + ) .await?; - if let Some(_asset) = asset_update { - // will only update owner if token account balance is non-zero - // since the asset is marked as single then the token account balance can only be 1. Greater implies a fungible token in which case no si - // TODO: this does not guarantee in case when wallet receives an amount of 1 for a token but its supply is more. is unlikely since mints often have a decimal - if ta.amount == 1 { - upsert_assets_token_account_columns( - AssetTokenAccountColumns { - mint: mint.clone(), - owner: Some(owner.clone()), - frozen, - delegate, - slot_updated_token_account: Some(account_info.slot as i64), - }, - &txn, - ) - .await?; - } + + txn.commit().await?; } - txn.commit().await?; + Ok(()) } TokenProgramAccount::Mint(m) => { @@ -141,29 +143,21 @@ pub async fn handle_token_program_account<'a, 'b>( ); db.execute(query).await?; - let asset_update: Option = asset::Entity::find_by_id(account_key.clone()) - .filter( - asset::Column::OwnerType - .eq(OwnerType::Single) - .or(asset::Column::OwnerType - .eq(OwnerType::Unknown) - .and(asset::Column::Supply.eq(1))), - ) - .one(db) - .await?; - if let Some(_asset) = asset_update { - upsert_assets_mint_account_columns( - AssetMintAccountColumns { - mint: account_key.clone(), - supply_mint: Some(account_key), - supply: m.supply.into(), - slot_updated_mint_account: account_info.slot, - }, - db, - ) - .await?; - } + let txn = db.begin().await?; + upsert_assets_mint_account_columns( + AssetMintAccountColumns { + mint: account_key.clone(), + supply: m.supply.into(), + slot_updated_mint_account: slot, + extensions: None, + }, + m.is_non_fungible(), + &txn, + ) + .await?; + + txn.commit().await?; Ok(()) } } diff --git a/program_transformers/src/token_extensions/mint.rs b/program_transformers/src/token_extensions/mint.rs deleted file mode 100644 index a0343fd55..000000000 --- a/program_transformers/src/token_extensions/mint.rs +++ /dev/null @@ -1,330 +0,0 @@ -use crate::{ - error::IngesterError, - program_transformers::{ - asset_upserts::{upsert_assets_token_account_columns, AssetTokenAccountColumns}, - utils::find_model_with_retry, - }, - tasks::{DownloadMetadata, IntoTaskData, TaskData}, -}; -use blockbuster::programs::token_extensions::{extension::ShadowMetadata, MintAccount}; -use chrono::Utc; -use digital_asset_types::dao::{ - asset, asset_authority, asset_data, - sea_orm_active_enums::{ - ChainMutability, OwnerType, SpecificationAssetClass, SpecificationVersions, - }, - token_accounts, tokens, -}; -use log::warn; -use plerkle_serialization::AccountInfo; -use sea_orm::{ - entity::*, query::*, sea_query::OnConflict, ActiveValue::Set, ConnectionTrait, - DatabaseConnection, DatabaseTransaction, DbBackend, DbErr, EntityTrait, -}; -use solana_sdk::{program_option::COption, pubkey::Pubkey}; - -const RETRY_INTERVALS: &[u64] = &[0, 5, 10]; - -pub async fn handle_token2022_mint_account<'a, 'b, 'c>( - m: &MintAccount, - account_update: &'a AccountInfo<'a>, - db: &'c DatabaseConnection, -) -> Result, IngesterError> { - let key = *account_update.pubkey().unwrap(); - let key_bytes = key.0.to_vec(); - let spl_token_program = account_update.owner().unwrap().0.to_vec(); - - let mut task: Option = None; - - let txn = db.begin().await?; - - insert_into_tokens_table( - m, - key_bytes.clone(), - spl_token_program, - account_update.slot() as i64, - &txn, - ) - .await?; - - if let Some(metadata) = &m.extensions.metadata { - upsert_asset_data( - metadata, - key_bytes.clone(), - account_update.slot() as i64, - &txn, - ) - .await?; - - task = Some(create_task(metadata, key_bytes.clone())?); - } - - if should_upsert_asset(m) { - upsert_asset(m, key_bytes.clone(), account_update.slot() as i64, db, &txn).await?; - } - - txn.commit().await?; - - Ok(task) -} - -fn should_upsert_asset(m: &MintAccount) -> bool { - is_token_nft(m) || m.extensions.metadata.is_some() -} - -fn is_token_nft(m: &MintAccount) -> bool { - m.account.supply == 1 && m.account.decimals == 0 -} - -async fn insert_into_tokens_table( - m: &MintAccount, - key_bytes: Vec, - spl_token_program: Vec, - slot: i64, - txn: &DatabaseTransaction, -) -> Result<(), IngesterError> { - let extensions = serde_json::to_value(m.extensions.clone()) - .map_err(|e| IngesterError::SerializatonError(e.to_string()))?; - let freeze_auth: Option> = match m.account.freeze_authority { - COption::Some(d) => Some(d.to_bytes().to_vec()), - COption::None => None, - }; - let mint_auth: Option> = match m.account.mint_authority { - COption::Some(d) => Some(d.to_bytes().to_vec()), - COption::None => None, - }; - let tokens_model = tokens::ActiveModel { - mint: Set(key_bytes.clone()), - token_program: Set(spl_token_program), - slot_updated: Set(slot), - supply: Set(m.account.supply as i64), - decimals: Set(m.account.decimals as i32), - close_authority: Set(None), - extension_data: Set(None), - mint_authority: Set(mint_auth), - freeze_authority: Set(freeze_auth), - extensions: Set(Some(extensions.clone())), - }; - - let mut tokens_query = tokens::Entity::insert(tokens_model) - .on_conflict( - OnConflict::columns([tokens::Column::Mint]) - .update_columns([ - tokens::Column::Supply, - tokens::Column::TokenProgram, - tokens::Column::MintAuthority, - tokens::Column::CloseAuthority, - tokens::Column::Extensions, - tokens::Column::SlotUpdated, - tokens::Column::Decimals, - tokens::Column::FreezeAuthority, - ]) - .to_owned(), - ) - .build(DbBackend::Postgres); - tokens_query.sql = format!( - "{} WHERE excluded.slot_updated >= tokens.slot_updated", - tokens_query.sql - ); - - txn.execute(tokens_query) - .await - .map_err(|db_err| IngesterError::AssetIndexError(db_err.to_string()))?; - - Ok(()) -} - -async fn upsert_asset_data( - metadata: &ShadowMetadata, - key_bytes: Vec, - slot: i64, - txn: &DatabaseTransaction, -) -> Result<(), IngesterError> { - let metadata_json = serde_json::to_value(metadata.clone()) - .map_err(|e| IngesterError::SerializatonError(e.to_string()))?; - let asset_data_model = asset_data::ActiveModel { - metadata_url: Set(metadata.uri.clone()), - metadata: Set(JsonValue::String("processing".to_string())), - id: Set(key_bytes.clone()), - chain_data_mutability: Set(ChainMutability::Mutable), - chain_data: Set(metadata_json), - slot_updated: Set(slot), - base_info_seq: Set(Some(0)), - raw_name: Set(Some(metadata.name.clone().into_bytes().to_vec())), - raw_symbol: Set(Some(metadata.symbol.clone().into_bytes().to_vec())), - ..Default::default() - }; - let mut asset_data_query = asset_data::Entity::insert(asset_data_model) - .on_conflict( - OnConflict::columns([asset_data::Column::Id]) - .update_columns([ - asset_data::Column::ChainDataMutability, - asset_data::Column::ChainData, - asset_data::Column::MetadataUrl, - asset_data::Column::SlotUpdated, - asset_data::Column::BaseInfoSeq, - ]) - .to_owned(), - ) - .build(DbBackend::Postgres); - asset_data_query.sql = format!( - "{} WHERE excluded.slot_updated >= asset_data.slot_updated", - asset_data_query.sql - ); - txn.execute(asset_data_query) - .await - .map_err(|db_err| IngesterError::AssetIndexError(db_err.to_string()))?; - Ok(()) -} - -async fn upsert_asset( - m: &MintAccount, - key_bytes: Vec, - slot: i64, - db: &DatabaseConnection, - txn: &DatabaseTransaction, -) -> Result<(), IngesterError> { - let is_nft = is_token_nft(m); - let owner_type = match is_nft { - true => OwnerType::Single, - false => OwnerType::Token, - }; - if is_nft { - let token_account: Option = find_model_with_retry( - db, - "token_accounts", - &token_accounts::Entity::find() - .filter(token_accounts::Column::Mint.eq(key_bytes.clone())) - .filter(token_accounts::Column::Amount.gt(0)) - .order_by(token_accounts::Column::SlotUpdated, Order::Desc), - RETRY_INTERVALS, - ) - .await - .map_err(|e: DbErr| IngesterError::DatabaseError(e.to_string()))?; - - match token_account { - Some(ta) => { - upsert_assets_token_account_columns( - AssetTokenAccountColumns { - mint: key_bytes.clone(), - owner: ta.owner, - frozen: ta.frozen, - delegate: ta.delegate, - slot_updated_token_account: Some(ta.slot_updated), - }, - txn, - ) - .await? - } - None => { - if m.account.supply == 1 { - warn!( - target: "Account not found", - "Token acc not found in 'token_accounts' table for mint {}", - bs58::encode(&key_bytes).into_string() - ); - } - } - } - - let extensions = serde_json::to_value(m.extensions.clone()) - .map_err(|e| IngesterError::SerializatonError(e.to_string()))?; - - let class = match is_nft { - true => SpecificationAssetClass::Nft, - false => SpecificationAssetClass::FungibleToken, - }; - - let mut asset_model = asset::ActiveModel { - id: Set(key_bytes.clone()), - owner_type: Set(owner_type), - supply: Set(m.account.supply as i64), - supply_mint: Set(Some(key_bytes.clone())), - specification_version: Set(Some(SpecificationVersions::V1)), - specification_asset_class: Set(Some(class)), - nonce: Set(Some(0)), - seq: Set(Some(0)), - compressed: Set(false), - compressible: Set(false), - asset_data: Set(Some(key_bytes.clone())), - slot_updated: Set(Some(slot)), - burnt: Set(false), - mint_extensions: Set(Some(extensions)), - ..Default::default() - }; - - let auth_address: Option> = m.extensions.metadata.clone().and_then(|m| { - let auth_pubkey: Option = m.update_authority.into(); - auth_pubkey.map(|value| value.to_bytes().to_vec()) - }); - - if let Some(authority) = auth_address { - let model = asset_authority::ActiveModel { - asset_id: Set(key_bytes.clone()), - authority: Set(authority), - seq: Set(0), - slot_updated: Set(slot), - ..Default::default() - }; - - let mut query = asset_authority::Entity::insert(model) - .on_conflict( - OnConflict::columns([asset_authority::Column::AssetId]) - .update_columns([ - asset_authority::Column::Authority, - asset_authority::Column::Seq, - asset_authority::Column::SlotUpdated, - ]) - .to_owned(), - ) - .build(DbBackend::Postgres); - query.sql = format!( - "{} WHERE excluded.slot_updated > asset_authority.slot_updated", - query.sql - ); - txn.execute(query) - .await - .map_err(|db_err| IngesterError::AssetIndexError(db_err.to_string()))?; - } - - let mut asset_query = asset::Entity::insert(asset_model) - .on_conflict( - OnConflict::columns([asset::Column::Id]) - .update_columns(vec![ - asset::Column::OwnerType, - asset::Column::Supply, - asset::Column::SupplyMint, - asset::Column::SpecificationVersion, - asset::Column::SpecificationAssetClass, - asset::Column::Nonce, - asset::Column::Seq, - asset::Column::Compressed, - asset::Column::Compressible, - asset::Column::AssetData, - asset::Column::SlotUpdated, - asset::Column::Burnt, - ]) - .to_owned(), - ) - .build(DbBackend::Postgres); - asset_query.sql = format!( - "{} WHERE excluded.slot_updated_mint_account >= asset.slot_updated_mint_account OR asset.slot_updated_mint_account IS NULL", - asset_query.sql - ); - txn.execute(asset_query) - .await - .map_err(|db_err| IngesterError::AssetIndexError(db_err.to_string()))?; - } - Ok(()) -} - -fn create_task(metadata: &ShadowMetadata, key_bytes: Vec) -> Result { - let mut dm = DownloadMetadata { - asset_data_id: key_bytes.clone(), - uri: metadata.uri.clone(), - created_at: Some(Utc::now().naive_utc()), - }; - dm.sanitize(); - let td = dm.into_task_data()?; - Ok(td) -} diff --git a/program_transformers/src/token_extensions/mod.rs b/program_transformers/src/token_extensions/mod.rs index 599bc47b0..b226fec5b 100644 --- a/program_transformers/src/token_extensions/mod.rs +++ b/program_transformers/src/token_extensions/mod.rs @@ -1,35 +1,248 @@ -mod mint; -mod token_account; -use crate::{ - error::{ProgramTransformerError, ProgramTransformerResult}, - tasks::TaskData, +use { + crate::{ + asset_upserts::{ + upsert_assets_mint_account_columns, upsert_assets_token_account_columns, + AssetMintAccountColumns, AssetTokenAccountColumns, + }, + error::{ProgramTransformerError, ProgramTransformerResult}, + filter_non_null_fields, AccountInfo, + }, + blockbuster::programs::token_extensions::{ + extension::ShadowMetadata, IsNonFungible, MintAccount, TokenAccount, + TokenExtensionsProgramAccount, + }, + digital_asset_types::dao::{ + asset_data, + sea_orm_active_enums::ChainMutability, + token_accounts, + tokens::{self, IsNonFungible as IsNonFungibleModel}, + }, + sea_orm::{ + entity::ActiveValue, query::QueryTrait, sea_query::query::OnConflict, ConnectionTrait, + DatabaseConnection, DbBackend, EntityTrait, TransactionTrait, + }, + serde_json::Value, + solana_sdk::program_option::COption, + spl_token_2022::state::AccountState, }; -use blockbuster::programs::token_extensions::TokenExtensionsProgramAccount; -use plerkle_serialization::AccountInfo; -use sea_orm::DatabaseConnection; -use tokio::sync::mpsc::UnboundedSender; - -use self::{mint::handle_token2022_mint_account, token_account::handle_token2022_token_account}; pub async fn handle_token_extensions_program_account<'a, 'b, 'c>( - account_update: &'a AccountInfo<'a>, + account_info: &'a AccountInfo, parsing_result: &'b TokenExtensionsProgramAccount, db: &'c DatabaseConnection, - task_manager: &UnboundedSender, ) -> ProgramTransformerResult<()> { - match &parsing_result { + let account_key = account_info.pubkey.to_bytes().to_vec(); + let account_owner = account_info.owner.to_bytes().to_vec(); + let slot = account_info.slot as i64; + match parsing_result { TokenExtensionsProgramAccount::TokenAccount(ta) => { - handle_token2022_token_account(ta, account_update, db).await?; + let TokenAccount { + account, + extensions, + } = ta; + let ta = account; + + let extensions: Option = if extensions.is_some() { + filter_non_null_fields( + serde_json::to_value(extensions.clone()) + .map_err(|e| ProgramTransformerError::SerializatonError(e.to_string()))?, + ) + } else { + None + }; + + let mint = ta.mint.to_bytes().to_vec(); + let delegate: Option> = match ta.delegate { + COption::Some(d) => Some(d.to_bytes().to_vec()), + COption::None => None, + }; + let frozen = matches!(ta.state, AccountState::Frozen); + let owner = ta.owner.to_bytes().to_vec(); + let model = token_accounts::ActiveModel { + pubkey: ActiveValue::Set(account_key.clone()), + mint: ActiveValue::Set(mint.clone()), + delegate: ActiveValue::Set(delegate.clone()), + owner: ActiveValue::Set(owner.clone()), + frozen: ActiveValue::Set(frozen), + delegated_amount: ActiveValue::Set(ta.delegated_amount as i64), + token_program: ActiveValue::Set(account_owner.clone()), + slot_updated: ActiveValue::Set(slot), + amount: ActiveValue::Set(ta.amount as i64), + close_authority: ActiveValue::Set(None), + extensions: ActiveValue::Set(extensions.clone()), + }; + + let mut query = token_accounts::Entity::insert(model) + .on_conflict( + OnConflict::columns([token_accounts::Column::Pubkey]) + .update_columns([ + token_accounts::Column::Mint, + token_accounts::Column::DelegatedAmount, + token_accounts::Column::Delegate, + token_accounts::Column::Amount, + token_accounts::Column::Frozen, + token_accounts::Column::TokenProgram, + token_accounts::Column::Owner, + token_accounts::Column::CloseAuthority, + token_accounts::Column::SlotUpdated, + token_accounts::Column::Extensions, + ]) + .to_owned(), + ) + .build(DbBackend::Postgres); + query.sql = format!( + "{} WHERE excluded.slot_updated > token_accounts.slot_updated", + query.sql + ); + db.execute(query).await?; + + let token = tokens::Entity::find_by_id(mint.clone()).one(db).await?; + + let is_non_fungible = token.map(|t| t.is_non_fungible()).unwrap_or(false); + + if is_non_fungible { + let txn = db.begin().await?; + + upsert_assets_token_account_columns( + AssetTokenAccountColumns { + mint: mint.clone(), + owner: Some(owner.clone()), + frozen, + delegate, + slot_updated_token_account: Some(slot), + }, + &txn, + ) + .await?; + + txn.commit().await?; + } + Ok(()) } TokenExtensionsProgramAccount::MintAccount(m) => { - let task = handle_token2022_mint_account(m, account_update, db).await?; - if let Some(t) = task { - task_manager.send(t)?; - } + println!("Mint account extensions: {:#?}", m.extensions); + let MintAccount { + account, + extensions, + } = m; + + let extensions: Option = if extensions.is_some() { + if let Some(metadata) = &m.extensions.metadata { + upsert_asset_data(metadata, account_key.clone(), slot, db).await?; + } + + filter_non_null_fields( + serde_json::to_value(extensions.clone()) + .map_err(|e| ProgramTransformerError::SerializatonError(e.to_string()))?, + ) + } else { + None + }; + + let m = account; + let freeze_auth: Option> = match m.freeze_authority { + COption::Some(d) => Some(d.to_bytes().to_vec()), + COption::None => None, + }; + let mint_auth: Option> = match m.mint_authority { + COption::Some(d) => Some(d.to_bytes().to_vec()), + COption::None => None, + }; + let model = tokens::ActiveModel { + mint: ActiveValue::Set(account_key.clone()), + token_program: ActiveValue::Set(account_owner), + slot_updated: ActiveValue::Set(slot), + supply: ActiveValue::Set(m.supply.into()), + decimals: ActiveValue::Set(m.decimals as i32), + close_authority: ActiveValue::Set(None), + extension_data: ActiveValue::Set(None), + mint_authority: ActiveValue::Set(mint_auth), + freeze_authority: ActiveValue::Set(freeze_auth), + extensions: ActiveValue::Set(extensions.clone()), + }; + + let mut query = tokens::Entity::insert(model) + .on_conflict( + OnConflict::columns([tokens::Column::Mint]) + .update_columns([ + tokens::Column::Supply, + tokens::Column::TokenProgram, + tokens::Column::MintAuthority, + tokens::Column::CloseAuthority, + tokens::Column::ExtensionData, + tokens::Column::SlotUpdated, + tokens::Column::Decimals, + tokens::Column::FreezeAuthority, + tokens::Column::Extensions, + ]) + .to_owned(), + ) + .build(DbBackend::Postgres); + query.sql = format!( + "{} WHERE excluded.slot_updated >= tokens.slot_updated", + query.sql + ); + db.execute(query).await?; + let txn = db.begin().await?; + + upsert_assets_mint_account_columns( + AssetMintAccountColumns { + mint: account_key.clone(), + supply: m.supply.into(), + slot_updated_mint_account: slot, + extensions: extensions.clone(), + }, + m.is_non_fungible(), + &txn, + ) + .await?; + + txn.commit().await?; + Ok(()) } _ => Err(ProgramTransformerError::NotImplemented), - }?; + } +} + +async fn upsert_asset_data( + metadata: &ShadowMetadata, + key_bytes: Vec, + slot: i64, + db: &DatabaseConnection, +) -> ProgramTransformerResult<()> { + let metadata_json = serde_json::to_value(metadata.clone()) + .map_err(|e| ProgramTransformerError::SerializatonError(e.to_string()))?; + let asset_data_model = asset_data::ActiveModel { + metadata_url: ActiveValue::Set(metadata.uri.clone()), + metadata: ActiveValue::Set(Value::String("processing".to_string())), + id: ActiveValue::Set(key_bytes.clone()), + chain_data_mutability: ActiveValue::Set(ChainMutability::Mutable), + chain_data: ActiveValue::Set(metadata_json), + slot_updated: ActiveValue::Set(slot), + base_info_seq: ActiveValue::Set(Some(0)), + raw_name: ActiveValue::Set(Some(metadata.name.clone().into_bytes().to_vec())), + raw_symbol: ActiveValue::Set(Some(metadata.symbol.clone().into_bytes().to_vec())), + ..Default::default() + }; + let mut asset_data_query = asset_data::Entity::insert(asset_data_model) + .on_conflict( + OnConflict::columns([asset_data::Column::Id]) + .update_columns([ + asset_data::Column::ChainDataMutability, + asset_data::Column::ChainData, + asset_data::Column::MetadataUrl, + asset_data::Column::SlotUpdated, + asset_data::Column::BaseInfoSeq, + ]) + .to_owned(), + ) + .build(DbBackend::Postgres); + asset_data_query.sql = format!( + "{} WHERE excluded.slot_updated >= asset_data.slot_updated", + asset_data_query.sql + ); + db.execute(asset_data_query).await?; Ok(()) } diff --git a/program_transformers/src/token_extensions/token_account.rs b/program_transformers/src/token_extensions/token_account.rs deleted file mode 100644 index 7f5df68fa..000000000 --- a/program_transformers/src/token_extensions/token_account.rs +++ /dev/null @@ -1,136 +0,0 @@ -use crate::{ - error::IngesterError, - metric, - program_transformers::{ - asset_upserts::{upsert_assets_token_account_columns, AssetTokenAccountColumns}, - token::upsert_owner_for_token_account, - }, -}; -use blockbuster::programs::token_extensions::TokenAccount; -use cadence_macros::{is_global_default_set, statsd_count}; -use digital_asset_types::dao::asset; -use plerkle_serialization::AccountInfo; -use sea_orm::{entity::*, query::*, ActiveValue::Set, DatabaseConnection, EntityTrait}; -use solana_sdk::program_option::COption; -use spl_token_2022::state::AccountState; - -pub async fn handle_token2022_token_account<'a, 'b, 'c>( - ta: &TokenAccount, - account_update: &'a AccountInfo<'a>, - db: &'c DatabaseConnection, -) -> Result<(), IngesterError> { - let key = *account_update.pubkey().unwrap(); - let key_bytes = key.0.to_vec(); - let spl_token_program = account_update.owner().unwrap().0.to_vec(); - - let mint = ta.account.mint.to_bytes().to_vec(); - let delegate: Option> = match ta.account.delegate { - COption::Some(d) => Some(d.to_bytes().to_vec()), - COption::None => None, - }; - let frozen = match ta.account.state { - AccountState::Frozen => true, - _ => false, - }; - let owner = ta.account.owner.to_bytes().to_vec(); - - upsert_owner_for_token_account( - db, - mint.clone(), - key_bytes, - owner.clone(), - delegate.clone(), - account_update.slot() as i64, - frozen, - ta.account.amount, - ta.account.delegated_amount as i64, - spl_token_program, - ) - .await?; - - // Metrics - let mut token_owner_update = false; - let mut token_delegate_update = false; - let mut token_freeze_update = false; - - let txn = db.begin().await?; - let asset_update = asset::Entity::find_by_id(mint.clone()) - .filter( - asset::Column::OwnerType.eq("single").and( - asset::Column::SlotUpdated - .is_null() - .or(asset::Column::SlotUpdated.lte(account_update.slot() as i64)), - ), - ) - .one(&txn) - .await?; - - if let Some(asset) = asset_update { - // Only handle token account updates for NFTs (supply=1) - let asset_clone = asset.clone(); - if asset_clone.supply == 1 { - let mut save_required = false; - let mut active: asset::ActiveModel = asset.into(); - - // Handle ownership updates - let old_owner = asset_clone.owner.clone(); - let new_owner = owner.clone(); - if ta.account.amount > 0 && Some(new_owner) != old_owner { - active.owner = Set(Some(owner.clone())); - token_owner_update = true; - save_required = true; - } - - // Handle delegate updates - if ta.account.amount > 0 && delegate.clone() != asset_clone.delegate { - active.delegate = Set(delegate.clone()); - token_delegate_update = true; - save_required = true; - } - - // Handle freeze updates - if ta.account.amount > 0 && frozen != asset_clone.frozen { - active.frozen = Set(frozen); - token_freeze_update = true; - save_required = true; - } - - let token_extensions = serde_json::to_value(ta.extensions.clone()) - .map_err(|e| IngesterError::SerializatonError(e.to_string()))?; - - if save_required { - upsert_assets_token_account_columns( - AssetTokenAccountColumns { - mint, - owner: Some(owner), - frozen, - delegate, - slot_updated_token_account: Some(account_update.slot() as i64), - }, - &txn, - ) - .await?; - } - } - } - txn.commit().await?; - - // Publish metrics outside of the txn to reduce txn latency. - if token_owner_update { - metric! { - statsd_count!("token_account.owner_update", 1); - } - } - if token_delegate_update { - metric! { - statsd_count!("token_account.delegate_update", 1); - } - } - if token_freeze_update { - metric! { - statsd_count!("token_account.freeze_update", 1); - } - } - - Ok(()) -} diff --git a/program_transformers/src/token_metadata/v1_asset.rs b/program_transformers/src/token_metadata/v1_asset.rs index f303d3e4a..81db41d68 100644 --- a/program_transformers/src/token_metadata/v1_asset.rs +++ b/program_transformers/src/token_metadata/v1_asset.rs @@ -20,7 +20,8 @@ use { ChainMutability, Mutability, OwnerType, SpecificationAssetClass, SpecificationVersions, V1AccountAttachments, }, - token_accounts, tokens, + token_accounts, + tokens::{self, IsNonFungible}, }, json::ChainDataV1, }, @@ -80,14 +81,17 @@ pub async fn index_and_fetch_mint_data( ) .await?; + let is_non_fungible = token.as_ref().map(|t| t.is_non_fungible()).unwrap_or(false); + if let Some(token) = token { upsert_assets_mint_account_columns( AssetMintAccountColumns { mint: mint_pubkey_vec.clone(), - supply_mint: Some(token.mint.clone()), supply: token.supply, - slot_updated_mint_account: token.slot_updated as u64, + slot_updated_mint_account: token.slot_updated, + extensions: token.extensions.clone(), }, + is_non_fungible, conn, ) .await diff --git a/program_transformers/src/utils.rs b/program_transformers/src/utils.rs deleted file mode 100644 index ca549a707..000000000 --- a/program_transformers/src/utils.rs +++ /dev/null @@ -1,37 +0,0 @@ -use cadence_macros::{is_global_default_set, statsd_count}; -use sea_orm::{query::*, ConnectionTrait, DbErr, EntityTrait}; -use std::time::Duration; -use tokio::time::sleep; - -pub async fn find_model_with_retry( - conn: &T, - model_name: &str, - select: &Select, - retry_intervals: &[u64], -) -> Result, DbErr> { - let mut retries = 0; - let metric_name = format!("{}_found", model_name); - - for interval in retry_intervals { - let interval_duration = Duration::from_millis(interval.to_owned()); - sleep(interval_duration).await; - - let model = select.clone().one(conn).await?; - if let Some(m) = model { - record_metric(&metric_name, true, retries); - return Ok(Some(m)); - } - retries += 1; - } - - record_metric(&metric_name, false, retries - 1); - Ok(None) -} - -fn record_metric(metric_name: &str, success: bool, retries: u32) { - let retry_count = &retries.to_string(); - let success = if success { "true" } else { "false" }; - metric! { - statsd_count!(metric_name, 1, "success" => success, "retry_count" => retry_count); - } -} From db11fd685614c1ba34d998f7379e4447d2e3238b Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Mon, 11 Nov 2024 19:22:56 +0530 Subject: [PATCH 04/20] chore: cleanup --- blockbuster/src/programs/token_account/mod.rs | 2 +- blockbuster/src/programs/token_extensions/mod.rs | 2 +- digital_asset_types/src/dao/generated/tokens.rs | 2 +- program_transformers/src/asset_upserts.rs | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/blockbuster/src/programs/token_account/mod.rs b/blockbuster/src/programs/token_account/mod.rs index 455552935..46a0690ed 100644 --- a/blockbuster/src/programs/token_account/mod.rs +++ b/blockbuster/src/programs/token_account/mod.rs @@ -82,6 +82,6 @@ pub trait IsNonFungible { impl IsNonFungible for Mint { fn is_non_fungible(&self) -> bool { - self.decimals == 0 && self.mint_authority.is_none() + self.decimals == 0 && self.mint_authority.is_none() && self.supply == 1 } } diff --git a/blockbuster/src/programs/token_extensions/mod.rs b/blockbuster/src/programs/token_extensions/mod.rs index b8c5afe08..13fb8d172 100644 --- a/blockbuster/src/programs/token_extensions/mod.rs +++ b/blockbuster/src/programs/token_extensions/mod.rs @@ -244,6 +244,6 @@ pub trait IsNonFungible { impl IsNonFungible for Mint { fn is_non_fungible(&self) -> bool { - self.decimals == 0 && self.mint_authority.is_none() + self.decimals == 0 && self.mint_authority.is_none() && self.supply == 1 } } diff --git a/digital_asset_types/src/dao/generated/tokens.rs b/digital_asset_types/src/dao/generated/tokens.rs index de8a0e352..7d1435545 100644 --- a/digital_asset_types/src/dao/generated/tokens.rs +++ b/digital_asset_types/src/dao/generated/tokens.rs @@ -87,6 +87,6 @@ pub trait IsNonFungible { impl IsNonFungible for Model { fn is_non_fungible(&self) -> bool { - self.decimals == 0 && self.mint_authority.is_none() + self.decimals == 0 && self.mint_authority.is_none() && self.supply == 1.into() } } diff --git a/program_transformers/src/asset_upserts.rs b/program_transformers/src/asset_upserts.rs index e9dcea0b9..7f527ebcd 100644 --- a/program_transformers/src/asset_upserts.rs +++ b/program_transformers/src/asset_upserts.rs @@ -68,8 +68,8 @@ pub async fn upsert_assets_mint_account_columns Date: Mon, 11 Nov 2024 20:12:21 +0530 Subject: [PATCH 05/20] fix: token extensions integration tests --- digital_asset_types/src/dapi/common/asset.rs | 10 --- ...ons_tests__token_extensions_get_asset.snap | 19 ++--- program_transformers/src/asset_upserts.rs | 1 + .../src/token_extensions/mod.rs | 70 +++++++++++++++++-- 4 files changed, 69 insertions(+), 31 deletions(-) diff --git a/digital_asset_types/src/dapi/common/asset.rs b/digital_asset_types/src/dapi/common/asset.rs index e7d331956..674345640 100644 --- a/digital_asset_types/src/dapi/common/asset.rs +++ b/digital_asset_types/src/dapi/common/asset.rs @@ -378,16 +378,6 @@ pub fn asset_to_rpc(asset: FullAsset, options: &Options) -> Result None, }; - if interface == Interface::FungibleToken { - return Ok(RpcAsset { - interface: interface.clone(), - id: bs58::encode(asset.id).into_string(), - content: Some(content), - mint_extensions: asset.mint_extensions, - ..Default::default() - }); - } - Ok(RpcAsset { interface: interface.clone(), id: bs58::encode(asset.id).into_string(), diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__token_extensions_tests__token_extensions_get_asset.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__token_extensions_tests__token_extensions_get_asset.snap index 104152bb8..e605fed8a 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__token_extensions_tests__token_extensions_get_asset.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__token_extensions_tests__token_extensions_get_asset.snap @@ -1,9 +1,10 @@ --- source: integration_tests/tests/integration_tests/token_extensions_tests.rs expression: response +snapshot_kind: text --- { - "interface": "V1_NFT", + "interface": "FungibleToken", "id": "BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y", "content": { "$schema": "https://schema.metaplex.com/nft1.0.json", @@ -15,14 +16,7 @@ expression: response }, "links": {} }, - "authorities": [ - { - "address": "Em34oqDQYQZ9b6ycPHD28K47mttrRsdNu1S1pgK6NtPL", - "scopes": [ - "full" - ] - } - ], + "authorities": [], "compression": { "eligible": false, "compressed": false, @@ -48,12 +42,7 @@ expression: response "delegated": false, "delegate": null, "ownership_model": "single", - "owner": "Em34oqDQYQZ9b6ycPHD28K47mttrRsdNu1S1pgK6NtPL" - }, - "supply": { - "print_max_supply": 0, - "print_current_supply": 0, - "edition_nonce": null + "owner": "" }, "mutable": true, "burnt": false, diff --git a/program_transformers/src/asset_upserts.rs b/program_transformers/src/asset_upserts.rs index 7f527ebcd..7ea102437 100644 --- a/program_transformers/src/asset_upserts.rs +++ b/program_transformers/src/asset_upserts.rs @@ -91,6 +91,7 @@ pub async fn upsert_assets_mint_account_columns( Ok(()) } TokenExtensionsProgramAccount::MintAccount(m) => { - println!("Mint account extensions: {:#?}", m.extensions); let MintAccount { account, extensions, } = m; + let is_non_fungible = m.account.is_non_fungible(); + let extensions: Option = if extensions.is_some() { if let Some(metadata) = &m.extensions.metadata { - upsert_asset_data(metadata, account_key.clone(), slot, db).await?; + upsert_asset_data(metadata, account_key.clone(), slot, db, is_non_fungible) + .await?; } filter_non_null_fields( @@ -193,7 +196,7 @@ pub async fn handle_token_extensions_program_account<'a, 'b, 'c>( slot_updated_mint_account: slot, extensions: extensions.clone(), }, - m.is_non_fungible(), + is_non_fungible, &txn, ) .await?; @@ -211,6 +214,7 @@ async fn upsert_asset_data( key_bytes: Vec, slot: i64, db: &DatabaseConnection, + is_non_fungible: bool, ) -> ProgramTransformerResult<()> { let metadata_json = serde_json::to_value(metadata.clone()) .map_err(|e| ProgramTransformerError::SerializatonError(e.to_string()))?; @@ -244,5 +248,59 @@ async fn upsert_asset_data( asset_data_query.sql ); db.execute(asset_data_query).await?; + + if !is_non_fungible { + let txn = db.begin().await?; + upsert_assets_metadata_cols( + AssetMetadataAccountCols { + mint: key_bytes.clone(), + slot_updated_metadata_account: slot, + }, + &txn, + ) + .await?; + + txn.commit().await?; + } + + Ok(()) +} + +struct AssetMetadataAccountCols { + mint: Vec, + slot_updated_metadata_account: i64, +} + +async fn upsert_assets_metadata_cols( + metadata: AssetMetadataAccountCols, + db: &DatabaseTransaction, +) -> Result<(), DbErr> { + let asset = asset::ActiveModel { + id: ActiveValue::Set(metadata.mint.clone()), + specification_asset_class: Set(Some(SpecificationAssetClass::FungibleToken)), + specification_version: Set(Some(SpecificationVersions::V0)), + slot_updated_metadata_account: Set(Some(metadata.slot_updated_metadata_account)), + ..Default::default() + }; + + let mut asset_query = asset::Entity::insert(asset) + .on_conflict( + OnConflict::columns([asset::Column::Id]) + .update_columns([ + asset::Column::SpecificationAssetClass, + asset::Column::SpecificationVersion, + asset::Column::SlotUpdatedMetadataAccount, + ]) + .to_owned(), + ) + .build(DbBackend::Postgres); + + asset_query.sql = format!( + "{} WHERE excluded.slot_updated_metadata_account >= asset.slot_updated_metadata_account OR asset.slot_updated_metadata_account IS NULL", + asset_query.sql + ); + + db.execute(asset_query).await?; + Ok(()) } From 08a7ba14a04183e78e3aba0e069ec1fcd0be7055 Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Tue, 12 Nov 2024 11:21:37 +0530 Subject: [PATCH 06/20] change is_non_fungible condition checks --- blockbuster/src/programs/token_account/mod.rs | 2 +- blockbuster/src/programs/token_extensions/mod.rs | 2 +- digital_asset_types/src/dao/generated/tokens.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/blockbuster/src/programs/token_account/mod.rs b/blockbuster/src/programs/token_account/mod.rs index 46a0690ed..7e35ffbc2 100644 --- a/blockbuster/src/programs/token_account/mod.rs +++ b/blockbuster/src/programs/token_account/mod.rs @@ -82,6 +82,6 @@ pub trait IsNonFungible { impl IsNonFungible for Mint { fn is_non_fungible(&self) -> bool { - self.decimals == 0 && self.mint_authority.is_none() && self.supply == 1 + self.decimals == 0 && self.supply == 1 } } diff --git a/blockbuster/src/programs/token_extensions/mod.rs b/blockbuster/src/programs/token_extensions/mod.rs index 13fb8d172..3e32cb5ee 100644 --- a/blockbuster/src/programs/token_extensions/mod.rs +++ b/blockbuster/src/programs/token_extensions/mod.rs @@ -244,6 +244,6 @@ pub trait IsNonFungible { impl IsNonFungible for Mint { fn is_non_fungible(&self) -> bool { - self.decimals == 0 && self.mint_authority.is_none() && self.supply == 1 + self.decimals == 0 && self.supply == 1 } } diff --git a/digital_asset_types/src/dao/generated/tokens.rs b/digital_asset_types/src/dao/generated/tokens.rs index 7d1435545..ed1e5598d 100644 --- a/digital_asset_types/src/dao/generated/tokens.rs +++ b/digital_asset_types/src/dao/generated/tokens.rs @@ -87,6 +87,6 @@ pub trait IsNonFungible { impl IsNonFungible for Model { fn is_non_fungible(&self) -> bool { - self.decimals == 0 && self.mint_authority.is_none() && self.supply == 1.into() + self.decimals == 0 && self.supply == 1.into() } } From 76cd8a7fc0911c19310ac0b99a9659bc83e94752 Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Tue, 12 Nov 2024 16:40:18 +0530 Subject: [PATCH 07/20] chore: cleanup --- blockbuster/src/programs/token_account/mod.rs | 10 ------ .../src/programs/token_extensions/mod.rs | 10 ------ program_transformers/src/asset_upserts.rs | 13 ++------ .../src/mpl_core_program/v1_asset.rs | 1 - program_transformers/src/token/mod.rs | 5 ++- .../src/token_extensions/mod.rs | 32 +++++++------------ .../src/token_metadata/v1_asset.rs | 1 - 7 files changed, 17 insertions(+), 55 deletions(-) diff --git a/blockbuster/src/programs/token_account/mod.rs b/blockbuster/src/programs/token_account/mod.rs index 7e35ffbc2..298fa3336 100644 --- a/blockbuster/src/programs/token_account/mod.rs +++ b/blockbuster/src/programs/token_account/mod.rs @@ -75,13 +75,3 @@ impl ProgramParser for TokenAccountParser { Ok(Box::new(account_type)) } } - -pub trait IsNonFungible { - fn is_non_fungible(&self) -> bool; -} - -impl IsNonFungible for Mint { - fn is_non_fungible(&self) -> bool { - self.decimals == 0 && self.supply == 1 - } -} diff --git a/blockbuster/src/programs/token_extensions/mod.rs b/blockbuster/src/programs/token_extensions/mod.rs index 3e32cb5ee..d890e5dbc 100644 --- a/blockbuster/src/programs/token_extensions/mod.rs +++ b/blockbuster/src/programs/token_extensions/mod.rs @@ -237,13 +237,3 @@ impl ProgramParser for Token2022AccountParser { Ok(Box::new(result)) } } - -pub trait IsNonFungible { - fn is_non_fungible(&self) -> bool; -} - -impl IsNonFungible for Mint { - fn is_non_fungible(&self) -> bool { - self.decimals == 0 && self.supply == 1 - } -} diff --git a/program_transformers/src/asset_upserts.rs b/program_transformers/src/asset_upserts.rs index 7ea102437..b86e274a8 100644 --- a/program_transformers/src/asset_upserts.rs +++ b/program_transformers/src/asset_upserts.rs @@ -62,25 +62,18 @@ pub struct AssetMintAccountColumns { pub async fn upsert_assets_mint_account_columns( columns: AssetMintAccountColumns, - is_non_fungible: bool, txn_or_conn: &T, ) -> Result<(), DbErr> { - let specification_asset_class = if is_non_fungible { - None - } else { - // If token is not fungible then - // we assume that the asset is fungibleToken and later update based on token metadata - Some(SpecificationAssetClass::FungibleToken) - }; - let active_model = asset::ActiveModel { id: Set(columns.mint.clone()), supply: Set(columns.supply), supply_mint: Set(Some(columns.mint.clone())), slot_updated_mint_account: Set(Some(columns.slot_updated_mint_account)), + slot_updated: Set(Some(columns.slot_updated_mint_account)), mint_extensions: Set(columns.extensions), asset_data: Set(Some(columns.mint)), - specification_asset_class: Set(specification_asset_class), + // assume every token is a fungible token when mint account is created + specification_asset_class: Set(Some(SpecificationAssetClass::FungibleToken)), ..Default::default() }; let mut query = asset::Entity::insert(active_model) diff --git a/program_transformers/src/mpl_core_program/v1_asset.rs b/program_transformers/src/mpl_core_program/v1_asset.rs index fb3929915..a022bc67e 100644 --- a/program_transformers/src/mpl_core_program/v1_asset.rs +++ b/program_transformers/src/mpl_core_program/v1_asset.rs @@ -320,7 +320,6 @@ pub async fn save_v1_asset( slot_updated_mint_account: slot as i64, extensions: None, }, - true, &txn, ) .await?; diff --git a/program_transformers/src/token/mod.rs b/program_transformers/src/token/mod.rs index 2969b7bae..2abd30666 100644 --- a/program_transformers/src/token/mod.rs +++ b/program_transformers/src/token/mod.rs @@ -7,10 +7,10 @@ use { error::ProgramTransformerResult, AccountInfo, DownloadMetadataNotifier, }, - blockbuster::programs::token_account::{IsNonFungible, TokenProgramAccount}, + blockbuster::programs::token_account::TokenProgramAccount, digital_asset_types::dao::{ token_accounts, - tokens::{self, IsNonFungible as IsNonFungibleModel}, + tokens::{self, IsNonFungible}, }, sea_orm::{ entity::ActiveValue, query::QueryTrait, sea_query::query::OnConflict, ConnectionTrait, @@ -152,7 +152,6 @@ pub async fn handle_token_program_account<'a, 'b>( slot_updated_mint_account: slot, extensions: None, }, - m.is_non_fungible(), &txn, ) .await?; diff --git a/program_transformers/src/token_extensions/mod.rs b/program_transformers/src/token_extensions/mod.rs index a4d5a7879..f61132429 100644 --- a/program_transformers/src/token_extensions/mod.rs +++ b/program_transformers/src/token_extensions/mod.rs @@ -8,8 +8,7 @@ use { filter_non_null_fields, AccountInfo, }, blockbuster::programs::token_extensions::{ - extension::ShadowMetadata, IsNonFungible, MintAccount, TokenAccount, - TokenExtensionsProgramAccount, + extension::ShadowMetadata, MintAccount, TokenAccount, TokenExtensionsProgramAccount, }, digital_asset_types::dao::{ asset, asset_data, @@ -127,12 +126,9 @@ pub async fn handle_token_extensions_program_account<'a, 'b, 'c>( extensions, } = m; - let is_non_fungible = m.account.is_non_fungible(); - let extensions: Option = if extensions.is_some() { if let Some(metadata) = &m.extensions.metadata { - upsert_asset_data(metadata, account_key.clone(), slot, db, is_non_fungible) - .await?; + upsert_asset_data(metadata, account_key.clone(), slot, db).await?; } filter_non_null_fields( @@ -196,7 +192,6 @@ pub async fn handle_token_extensions_program_account<'a, 'b, 'c>( slot_updated_mint_account: slot, extensions: extensions.clone(), }, - is_non_fungible, &txn, ) .await?; @@ -214,7 +209,6 @@ async fn upsert_asset_data( key_bytes: Vec, slot: i64, db: &DatabaseConnection, - is_non_fungible: bool, ) -> ProgramTransformerResult<()> { let metadata_json = serde_json::to_value(metadata.clone()) .map_err(|e| ProgramTransformerError::SerializatonError(e.to_string()))?; @@ -249,19 +243,17 @@ async fn upsert_asset_data( ); db.execute(asset_data_query).await?; - if !is_non_fungible { - let txn = db.begin().await?; - upsert_assets_metadata_cols( - AssetMetadataAccountCols { - mint: key_bytes.clone(), - slot_updated_metadata_account: slot, - }, - &txn, - ) - .await?; + let txn = db.begin().await?; + upsert_assets_metadata_cols( + AssetMetadataAccountCols { + mint: key_bytes.clone(), + slot_updated_metadata_account: slot, + }, + &txn, + ) + .await?; - txn.commit().await?; - } + txn.commit().await?; Ok(()) } diff --git a/program_transformers/src/token_metadata/v1_asset.rs b/program_transformers/src/token_metadata/v1_asset.rs index 81db41d68..8b968ec9d 100644 --- a/program_transformers/src/token_metadata/v1_asset.rs +++ b/program_transformers/src/token_metadata/v1_asset.rs @@ -91,7 +91,6 @@ pub async fn index_and_fetch_mint_data( slot_updated_mint_account: token.slot_updated, extensions: token.extensions.clone(), }, - is_non_fungible, conn, ) .await From ab179cd6f6c12798d16219511bda01b3b6920911 Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Thu, 14 Nov 2024 18:40:44 +0530 Subject: [PATCH 08/20] WIP : showFungible --- digital_asset_types/src/dao/scopes/asset.rs | 44 ++++++++++++++++--- .../src/dapi/assets_by_owner.rs | 2 +- digital_asset_types/src/dapi/get_asset.rs | 4 +- digital_asset_types/src/rpc/options.rs | 2 + 4 files changed, 43 insertions(+), 9 deletions(-) diff --git a/digital_asset_types/src/dao/scopes/asset.rs b/digital_asset_types/src/dao/scopes/asset.rs index 58e4cbbaf..60e01abc2 100644 --- a/digital_asset_types/src/dao/scopes/asset.rs +++ b/digital_asset_types/src/dao/scopes/asset.rs @@ -3,10 +3,10 @@ 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, SpecificationAssetClass}, Cursor, FullAsset, GroupingSize, Pagination, }, - rpc::filter::AssetSortDirection, + rpc::{filter::AssetSortDirection, options::Options}, }; use indexmap::IndexMap; use sea_orm::{entity::*, query::*, ConnectionTrait, DbErr, Order}; @@ -149,11 +149,21 @@ pub async fn get_assets_by_owner( sort_direction: Order, pagination: &Pagination, limit: u64, - show_unverified_collections: bool, + options: &Options, ) -> Result, DbErr> { - let cond = Condition::all() + let mut cond = Condition::all() .add(asset::Column::Owner.eq(owner)) .add(asset::Column::Supply.gt(0)); + + if options.show_fungible { + cond = cond.add( + asset::Column::SpecificationAssetClass + .eq(SpecificationAssetClass::FungibleToken) + .or(asset::Column::SpecificationAssetClass + .eq(SpecificationAssetClass::FungibleAsset)), + ); + } + get_assets_by_condition( conn, cond, @@ -162,7 +172,7 @@ pub async fn get_assets_by_owner( sort_direction, pagination, limit, - show_unverified_collections, + options.show_unverified_collections, ) .await } @@ -172,10 +182,21 @@ pub async fn get_assets( asset_ids: Vec>, pagination: &Pagination, limit: u64, + options: &Options, ) -> Result, DbErr> { - let cond = Condition::all() + let mut cond = Condition::all() .add(asset::Column::Id.is_in(asset_ids)) .add(asset::Column::Supply.gt(0)); + + if options.show_fungible { + cond = cond.add( + asset::Column::SpecificationAssetClass + .eq(SpecificationAssetClass::FungibleToken) + .or(asset::Column::SpecificationAssetClass + .eq(SpecificationAssetClass::FungibleAsset)), + ); + } + get_assets_by_condition( conn, cond, @@ -385,12 +406,23 @@ pub async fn get_by_id( conn: &impl ConnectionTrait, asset_id: Vec, include_no_supply: bool, + options: &Options, ) -> Result { let mut asset_data = asset::Entity::find_by_id(asset_id.clone()).find_also_related(asset_data::Entity); if !include_no_supply { asset_data = asset_data.filter(Condition::all().add(asset::Column::Supply.gt(0))); } + + if options.show_fungible { + asset_data = asset_data.filter( + asset::Column::SpecificationAssetClass + .eq(SpecificationAssetClass::FungibleToken) + .or(asset::Column::SpecificationAssetClass + .eq(SpecificationAssetClass::FungibleAsset)), + ); + } + let asset_data: (asset::Model, asset_data::Model) = asset_data.one(conn).await.and_then(|o| match o { Some((a, Some(d))) => Ok((a, d)), diff --git a/digital_asset_types/src/dapi/assets_by_owner.rs b/digital_asset_types/src/dapi/assets_by_owner.rs index c3c4da3a5..5f342fe9a 100644 --- a/digital_asset_types/src/dapi/assets_by_owner.rs +++ b/digital_asset_types/src/dapi/assets_by_owner.rs @@ -24,7 +24,7 @@ pub async fn get_assets_by_owner( sort_direction, &pagination, page_options.limit, - options.show_unverified_collections, + options, ) .await?; Ok(build_asset_response( diff --git a/digital_asset_types/src/dapi/get_asset.rs b/digital_asset_types/src/dapi/get_asset.rs index 3740562c3..2ec7d9006 100644 --- a/digital_asset_types/src/dapi/get_asset.rs +++ b/digital_asset_types/src/dapi/get_asset.rs @@ -11,7 +11,7 @@ pub async fn get_asset( id: Vec, options: &Options, ) -> Result { - let asset = scopes::asset::get_by_id(db, id, false).await?; + let asset = scopes::asset::get_by_id(db, id, false, options).await?; asset_to_rpc(asset, options) } @@ -22,7 +22,7 @@ pub async fn get_assets( options: &Options, ) -> Result, DbErr> { let pagination = Pagination::Page { page: 1 }; - let assets = scopes::asset::get_assets(db, ids, &pagination, limit).await?; + let assets = scopes::asset::get_assets(db, ids, &pagination, limit, options).await?; let asset_list = build_asset_response(assets, limit, &pagination, options); let asset_map = asset_list .items diff --git a/digital_asset_types/src/rpc/options.rs b/digital_asset_types/src/rpc/options.rs index a1fafa2c4..161ffba8b 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_fungible: bool, } From 2de5bc05fece8bb0bb90191bc5fc51f29dbb4922 Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Fri, 15 Nov 2024 12:28:09 +0530 Subject: [PATCH 09/20] chore: cleanup --- digital_asset_types/src/dao/full_asset.rs | 3 ++ digital_asset_types/src/dao/scopes/asset.rs | 56 +++++++++----------- digital_asset_types/src/dapi/common/asset.rs | 20 +++++++ digital_asset_types/src/dapi/get_asset.rs | 2 +- digital_asset_types/src/rpc/asset.rs | 13 +++++ 5 files changed, 61 insertions(+), 33 deletions(-) diff --git a/digital_asset_types/src/dao/full_asset.rs b/digital_asset_types/src/dao/full_asset.rs index fda932d21..e1fb25d54 100644 --- a/digital_asset_types/src/dao/full_asset.rs +++ b/digital_asset_types/src/dao/full_asset.rs @@ -1,9 +1,12 @@ use crate::dao::{asset, asset_authority, asset_creators, asset_data, asset_grouping}; +use super::tokens; + #[derive(Clone, Debug, PartialEq)] pub struct FullAsset { pub asset: asset::Model, pub data: asset_data::Model, + pub token_info: Option, pub authorities: Vec, pub creators: Vec, pub groups: Vec, diff --git a/digital_asset_types/src/dao/scopes/asset.rs b/digital_asset_types/src/dao/scopes/asset.rs index 60e01abc2..fd7cc6d2e 100644 --- a/digital_asset_types/src/dao/scopes/asset.rs +++ b/digital_asset_types/src/dao/scopes/asset.rs @@ -3,8 +3,8 @@ use crate::{ asset::{self}, asset_authority, asset_creators, asset_data, asset_grouping, cl_audits_v2, extensions::{self, instruction::PascalCase}, - sea_orm_active_enums::{Instruction, SpecificationAssetClass}, - Cursor, FullAsset, GroupingSize, Pagination, + sea_orm_active_enums::Instruction, + tokens, Cursor, FullAsset, GroupingSize, Pagination, }, rpc::{filter::AssetSortDirection, options::Options}, }; @@ -151,19 +151,10 @@ pub async fn get_assets_by_owner( limit: u64, options: &Options, ) -> Result, DbErr> { - let mut cond = Condition::all() + let cond = Condition::all() .add(asset::Column::Owner.eq(owner)) .add(asset::Column::Supply.gt(0)); - if options.show_fungible { - cond = cond.add( - asset::Column::SpecificationAssetClass - .eq(SpecificationAssetClass::FungibleToken) - .or(asset::Column::SpecificationAssetClass - .eq(SpecificationAssetClass::FungibleAsset)), - ); - } - get_assets_by_condition( conn, cond, @@ -182,21 +173,11 @@ pub async fn get_assets( asset_ids: Vec>, pagination: &Pagination, limit: u64, - options: &Options, ) -> Result, DbErr> { - let mut cond = Condition::all() + let cond = Condition::all() .add(asset::Column::Id.is_in(asset_ids)) .add(asset::Column::Supply.gt(0)); - if options.show_fungible { - cond = cond.add( - asset::Column::SpecificationAssetClass - .eq(SpecificationAssetClass::FungibleToken) - .or(asset::Column::SpecificationAssetClass - .eq(SpecificationAssetClass::FungibleAsset)), - ); - } - get_assets_by_condition( conn, cond, @@ -299,6 +280,7 @@ pub async fn get_related_for_assets( authorities: vec![], creators: vec![], groups: vec![], + token_info: None, }; acc.insert(id, fa); }; @@ -414,15 +396,11 @@ pub async fn get_by_id( asset_data = asset_data.filter(Condition::all().add(asset::Column::Supply.gt(0))); } - if options.show_fungible { - asset_data = asset_data.filter( - asset::Column::SpecificationAssetClass - .eq(SpecificationAssetClass::FungibleToken) - .or(asset::Column::SpecificationAssetClass - .eq(SpecificationAssetClass::FungibleAsset)), - ); - } - + let token_info = if options.show_fungible { + get_token_by_id(conn, asset_id.clone()).await.ok() + } else { + None + }; let asset_data: (asset::Model, asset_data::Model) = asset_data.one(conn).await.and_then(|o| match o { Some((a, Some(d))) => Ok((a, d)), @@ -462,6 +440,7 @@ pub async fn get_by_id( authorities, creators, groups: grouping, + token_info, }) } @@ -585,3 +564,16 @@ fn filter_out_stale_creators(creators: &mut Vec) { } } } + +pub async fn get_token_by_id( + conn: &impl ConnectionTrait, + id: Vec, +) -> Result { + tokens::Entity::find_by_id(id) + .one(conn) + .await + .and_then(|o| match o { + Some(t) => Ok(t), + _ => Err(DbErr::RecordNotFound("Token Not Found".to_string())), + }) +} diff --git a/digital_asset_types/src/dapi/common/asset.rs b/digital_asset_types/src/dapi/common/asset.rs index c9a9dd486..74c86862a 100644 --- a/digital_asset_types/src/dapi/common/asset.rs +++ b/digital_asset_types/src/dapi/common/asset.rs @@ -7,6 +7,7 @@ use crate::rpc::filter::{AssetSortBy, AssetSortDirection, AssetSorting}; use crate::rpc::options::Options; use crate::rpc::response::TransactionSignatureList; use crate::rpc::response::{AssetError, AssetList}; +use crate::rpc::TokenInfo; use crate::rpc::{ Asset as RpcAsset, Authority, Compression, Content, Creator, File, Group, Interface, MetadataMap, MplCoreInfo, Ownership, Royalty, Scope, Supply, Uses, @@ -355,6 +356,7 @@ pub fn asset_to_rpc(asset: FullAsset, options: &Options) -> Result Result None, }; + let token_info = if options.show_fungible && token_info.is_some() { + let token_info = token_info.unwrap(); + Some(TokenInfo { + supply: token_info.supply.try_into().unwrap_or(0), + decimals: token_info.decimals as u8, + mint_authority: token_info + .mint_authority + .map(|s| bs58::encode(s).into_string()), + freeze_authority: token_info + .freeze_authority + .map(|s| bs58::encode(s).into_string()), + token_program: bs58::encode(token_info.token_program).into_string(), + }) + } else { + None + }; + Ok(RpcAsset { interface: interface.clone(), id: bs58::encode(asset.id).into_string(), @@ -444,6 +463,7 @@ pub fn asset_to_rpc(asset: FullAsset, options: &Options) -> Result Result, DbErr> { let pagination = Pagination::Page { page: 1 }; - let assets = scopes::asset::get_assets(db, ids, &pagination, limit, options).await?; + let assets = scopes::asset::get_assets(db, ids, &pagination, limit).await?; let asset_list = build_asset_response(assets, limit, &pagination, options); let asset_map = asset_list .items diff --git a/digital_asset_types/src/rpc/asset.rs b/digital_asset_types/src/rpc/asset.rs index 751ef3841..18c7bdd3c 100644 --- a/digital_asset_types/src/rpc/asset.rs +++ b/digital_asset_types/src/rpc/asset.rs @@ -366,6 +366,17 @@ pub struct MplCoreInfo { pub plugins_json_version: Option, } +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct TokenInfo { + pub supply: u64, + pub decimals: u8, + pub token_program: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub mint_authority: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub freeze_authority: Option, +} + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct Asset { pub interface: Interface, @@ -389,6 +400,8 @@ pub struct Asset { pub mutable: bool, pub burnt: bool, #[serde(skip_serializing_if = "Option::is_none")] + pub token_info: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub plugins: Option, #[serde(skip_serializing_if = "Option::is_none")] pub unknown_plugins: Option, From 6d708a62aa42632494248631a698e26b59ac0f52 Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Wed, 20 Nov 2024 13:49:04 +0530 Subject: [PATCH 10/20] resolve comments --- .../src/dao/extensions/asset.rs | 2 +- digital_asset_types/src/dapi/common/asset.rs | 17 ++--- digital_asset_types/src/rpc/asset.rs | 16 +++-- ...Kwjfsx6qpiw3RkwUbQZgjm9t6cpf6gnvGmNJPunerx | Bin 312 -> 0 bytes ...U5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y | Bin 0 -> 496 bytes ...bpJAQGNpkgBaYBZQBR1t7yFdvaYVp2vCQQfKKEN4tM | Bin 0 -> 760 bytes ...token_extensions_get_asset_scenario1.snap} | 12 +--- ..._token_extensions_get_asset_scenario2.snap | 68 ++++++++++++++++++ .../token_extensions_tests.rs | 37 ++++++++-- migration/src/lib.rs | 2 + ...241120_075326_change_owner_type_default.rs | 41 +++++++++++ program_transformers/src/asset_upserts.rs | 4 +- program_transformers/src/lib.rs | 6 +- .../src/token_extensions/mod.rs | 24 +++---- .../src/token_metadata/v1_asset.rs | 10 +-- 15 files changed, 178 insertions(+), 61 deletions(-) delete mode 100644 integration_tests/tests/data/accounts/token_extensions_get_asset/AXKwjfsx6qpiw3RkwUbQZgjm9t6cpf6gnvGmNJPunerx create mode 100644 integration_tests/tests/data/accounts/token_extensions_get_asset_scenario1/BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y create mode 100644 integration_tests/tests/data/accounts/token_extensions_get_asset_scenario2/HVbpJAQGNpkgBaYBZQBR1t7yFdvaYVp2vCQQfKKEN4tM rename integration_tests/tests/integration_tests/snapshots/{integration_tests__token_extensions_tests__token_extensions_get_asset.snap => integration_tests__token_extensions_tests__token_extensions_get_asset_scenario1.snap} (82%) create mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__token_extensions_tests__token_extensions_get_asset_scenario2.snap create mode 100644 migration/src/m20241120_075326_change_owner_type_default.rs diff --git a/digital_asset_types/src/dao/extensions/asset.rs b/digital_asset_types/src/dao/extensions/asset.rs index 6628b234b..ace692d7e 100644 --- a/digital_asset_types/src/dao/extensions/asset.rs +++ b/digital_asset_types/src/dao/extensions/asset.rs @@ -76,7 +76,7 @@ impl Default for asset::Model { specification_version: None, specification_asset_class: None, owner: None, - owner_type: OwnerType::Single, + owner_type: OwnerType::Unknown, delegate: None, frozen: Default::default(), supply: Default::default(), diff --git a/digital_asset_types/src/dapi/common/asset.rs b/digital_asset_types/src/dapi/common/asset.rs index 674345640..c2b29d73b 100644 --- a/digital_asset_types/src/dapi/common/asset.rs +++ b/digital_asset_types/src/dapi/common/asset.rs @@ -278,13 +278,13 @@ pub fn v1_content_from_json(asset_data: &asset_data::Model) -> Result Result { +pub fn get_content(asset: &asset::Model, data: &asset_data::Model) -> Option { match asset.specification_version { Some(SpecificationVersions::V1) | Some(SpecificationVersions::V0) => { - v1_content_from_json(data) + v1_content_from_json(data).ok() } - Some(_) => Err(DbErr::Custom("Version Not Implemented".to_string())), - None => Err(DbErr::Custom("Specification version not found".to_string())), + Some(_) => None, + None => None, } } @@ -334,10 +334,7 @@ pub fn to_grouping( pub fn get_interface(asset: &asset::Model) -> Result { Ok(Interface::from(( - asset - .specification_version - .as_ref() - .ok_or(DbErr::Custom("Specification version not found".to_string()))?, + asset.specification_version.as_ref(), asset .specification_asset_class .as_ref() @@ -360,7 +357,7 @@ pub fn asset_to_rpc(asset: FullAsset, options: &Options) -> Result Result for Interface { - fn from(i: (&SpecificationVersions, &SpecificationAssetClass)) -> Self { +impl From<(Option<&SpecificationVersions>, &SpecificationAssetClass)> for Interface { + fn from(i: (Option<&SpecificationVersions>, &SpecificationAssetClass)) -> Self { match i { - (SpecificationVersions::V1, SpecificationAssetClass::Nft) => Interface::V1NFT, - (SpecificationVersions::V1, SpecificationAssetClass::PrintableNft) => Interface::V1NFT, - (SpecificationVersions::V0, SpecificationAssetClass::Nft) => Interface::LEGACY_NFT, - (SpecificationVersions::V1, SpecificationAssetClass::ProgrammableNft) => { + (Some(SpecificationVersions::V1), SpecificationAssetClass::Nft) => Interface::V1NFT, + (Some(SpecificationVersions::V1), SpecificationAssetClass::PrintableNft) => { + Interface::V1NFT + } + (Some(SpecificationVersions::V0), SpecificationAssetClass::Nft) => { + Interface::LEGACY_NFT + } + (Some(SpecificationVersions::V1), SpecificationAssetClass::ProgrammableNft) => { Interface::ProgrammableNFT } (_, SpecificationAssetClass::MplCoreAsset) => Interface::MplCoreAsset, diff --git a/integration_tests/tests/data/accounts/token_extensions_get_asset/AXKwjfsx6qpiw3RkwUbQZgjm9t6cpf6gnvGmNJPunerx b/integration_tests/tests/data/accounts/token_extensions_get_asset/AXKwjfsx6qpiw3RkwUbQZgjm9t6cpf6gnvGmNJPunerx deleted file mode 100644 index 4134dad7e63f443d165ab067e2367317593db757..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 312 zcmY#jfB*@G3p*mPvm7 zv-jKKU(-HiPV!~D`|aVo(*AoAPO*EQ@AF=dhi4)_{gn4#WYB-_+%C;;rsV|(_HB87Di~-C(SQ`SD26hzgSh~z C6I=lR diff --git a/integration_tests/tests/data/accounts/token_extensions_get_asset_scenario1/BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y b/integration_tests/tests/data/accounts/token_extensions_get_asset_scenario1/BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y new file mode 100644 index 0000000000000000000000000000000000000000..c864c008977b17f7eaa20a720a369e61334c33d2 GIT binary patch literal 496 zcmY#jfB*@G3eYws-;VJdtF72Lx%-&gT7jO& z(Os`MziO5JSbLf6?ze~UO8f6gIK}RHl5_UfHmN_p%{zJ3|Ly&$absckACQ>|2F5^= zf#E+CY!8kQ0r90iczR4`WMD`FVjyBTlYhyc_j#|!!!r?|e#-kVGU&f|ZkOga)AE7? z`?fqk6%0}X25<&UfKD`{5Q76jR}u;_VTKZl&0q(5*u^ne!6mhf8N!qTQW+&B1;tkS a`iaT8sd~xzx%w%ox%qlo#rb)V@BsiME20hn literal 0 HcmV?d00001 diff --git a/integration_tests/tests/data/accounts/token_extensions_get_asset_scenario2/HVbpJAQGNpkgBaYBZQBR1t7yFdvaYVp2vCQQfKKEN4tM b/integration_tests/tests/data/accounts/token_extensions_get_asset_scenario2/HVbpJAQGNpkgBaYBZQBR1t7yFdvaYVp2vCQQfKKEN4tM new file mode 100644 index 0000000000000000000000000000000000000000..a4c739eb46d55c67f75a738b7e75d6ede7f4579f GIT binary patch literal 760 zcmY#jfB*@G3brr2hCe@8nhgxA&*UjfLHRKxRI$^aqj* z4F93vQ46~eh=1^&yT@ck28Jvq1_mI-;M)DkL?q{AyV+Df2J`$B-r~1wlTVn>PF;ID zx+(wCW6=_26G zP#Z8ZGbj+Wmxl;7EDVkW%^~P`J_ZMh4G|*33_?jjm|-Fbx|XQ$@r=BAb;rX-dm>J=nb = seed_accounts([ - "BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y", - "AXKwjfsx6qpiw3RkwUbQZgjm9t6cpf6gnvGmNJPunerx", - ]); + let seeds: Vec = seed_accounts(["BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y"]); apply_migrations_and_delete_data(setup.db.clone()).await; index_seed_events(&setup, seeds.iter().collect_vec()).await; @@ -40,3 +37,33 @@ async fn test_token_extensions_get_asset() { insta::assert_json_snapshot!(name, response); } + +#[tokio::test] +#[serial] +#[named] +async fn test_token_extensions_get_asset_scenario2() { + 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(["HVbpJAQGNpkgBaYBZQBR1t7yFdvaYVp2vCQQfKKEN4tM"]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "id": "HVbpJAQGNpkgBaYBZQBR1t7yFdvaYVp2vCQQfKKEN4tM" + } + "#; + + let request: api::GetAsset = serde_json::from_str(request).unwrap(); + let response = setup.das_api.get_asset(request).await.unwrap(); + + insta::assert_json_snapshot!(name, response); +} diff --git a/migration/src/lib.rs b/migration/src/lib.rs index d2d5c9051..1fb7a4365 100644 --- a/migration/src/lib.rs +++ b/migration/src/lib.rs @@ -44,6 +44,7 @@ mod m20240319_120101_add_mpl_core_enum_vals; mod m20240320_120101_add_mpl_core_info_items; mod m20240520_120101_add_mpl_core_external_plugins_columns; mod m20240718_161232_change_supply_columns_to_numeric; +mod m20241120_075326_change_owner_type_default; pub mod model; @@ -97,6 +98,7 @@ impl MigratorTrait for Migrator { Box::new(m20240320_120101_add_mpl_core_info_items::Migration), Box::new(m20240520_120101_add_mpl_core_external_plugins_columns::Migration), Box::new(m20240718_161232_change_supply_columns_to_numeric::Migration), + Box::new(m20241120_075326_change_owner_type_default::Migration), ] } } diff --git a/migration/src/m20241120_075326_change_owner_type_default.rs b/migration/src/m20241120_075326_change_owner_type_default.rs new file mode 100644 index 000000000..75c6ebb94 --- /dev/null +++ b/migration/src/m20241120_075326_change_owner_type_default.rs @@ -0,0 +1,41 @@ +use sea_orm_migration::prelude::*; + +use crate::model::table::Asset; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .alter_table( + Table::alter() + .table(Asset::Table) + .modify_column( + ColumnDef::new(Asset::OwnerType) + .string() + .not_null() + .default("Unknown"), + ) + .to_owned(), + ) + .await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .alter_table( + Table::alter() + .table(Asset::Table) + .modify_column( + ColumnDef::new(Asset::OwnerType) + .string() + .not_null() + .default("Single"), + ) + .to_owned(), + ) + .await + } +} diff --git a/program_transformers/src/asset_upserts.rs b/program_transformers/src/asset_upserts.rs index b86e274a8..09fe09be0 100644 --- a/program_transformers/src/asset_upserts.rs +++ b/program_transformers/src/asset_upserts.rs @@ -71,9 +71,11 @@ pub async fn upsert_assets_mint_account_columns Self { - info!("Initializing Program Transformer"); let mut parsers: HashMap> = HashMap::with_capacity(5); let bgum = BubblegumParser {}; let token_metadata = TokenMetadataParser {}; @@ -137,7 +136,6 @@ impl ProgramTransformer { &self, tx_info: &TransactionInfo, ) -> ProgramTransformerResult<()> { - info!("Handling Transaction: {:?}", tx_info.signature); let instructions = self.break_transaction(tx_info); let mut not_impl = 0; let ixlen = instructions.len(); @@ -217,7 +215,6 @@ impl ProgramTransformer { &self, account_info: &AccountInfo, ) -> ProgramTransformerResult<()> { - info!("Handling Account Update: {:?}", account_info.pubkey); if let Some(program) = self.match_program(&account_info.owner) { let result = program.handle_account(&account_info.data)?; match result.result_type() { @@ -240,7 +237,6 @@ impl ProgramTransformer { .await } ProgramParseResult::TokenExtensionsProgramAccount(parsing_result) => { - info!("Handling Token Extensions Program Account"); handle_token_extensions_program_account( account_info, parsing_result, diff --git a/program_transformers/src/token_extensions/mod.rs b/program_transformers/src/token_extensions/mod.rs index f61132429..a9d8df5a7 100644 --- a/program_transformers/src/token_extensions/mod.rs +++ b/program_transformers/src/token_extensions/mod.rs @@ -12,7 +12,7 @@ use { }, digital_asset_types::dao::{ asset, asset_data, - sea_orm_active_enums::{ChainMutability, SpecificationAssetClass, SpecificationVersions}, + sea_orm_active_enums::ChainMutability, token_accounts, tokens::{self, IsNonFungible as IsNonFungibleModel}, }, @@ -126,11 +126,7 @@ pub async fn handle_token_extensions_program_account<'a, 'b, 'c>( extensions, } = m; - let extensions: Option = if extensions.is_some() { - if let Some(metadata) = &m.extensions.metadata { - upsert_asset_data(metadata, account_key.clone(), slot, db).await?; - } - + let mint_extensions: Option = if extensions.is_some() { filter_non_null_fields( serde_json::to_value(extensions.clone()) .map_err(|e| ProgramTransformerError::SerializatonError(e.to_string()))?, @@ -158,7 +154,7 @@ pub async fn handle_token_extensions_program_account<'a, 'b, 'c>( extension_data: ActiveValue::Set(None), mint_authority: ActiveValue::Set(mint_auth), freeze_authority: ActiveValue::Set(freeze_auth), - extensions: ActiveValue::Set(extensions.clone()), + extensions: ActiveValue::Set(mint_extensions.clone()), }; let mut query = tokens::Entity::insert(model) @@ -190,7 +186,7 @@ pub async fn handle_token_extensions_program_account<'a, 'b, 'c>( mint: account_key.clone(), supply: m.supply.into(), slot_updated_mint_account: slot, - extensions: extensions.clone(), + extensions: mint_extensions.clone(), }, &txn, ) @@ -198,6 +194,10 @@ pub async fn handle_token_extensions_program_account<'a, 'b, 'c>( txn.commit().await?; + if let Some(metadata) = &extensions.metadata { + upsert_asset_data(metadata, account_key.clone(), slot, db).await?; + } + Ok(()) } _ => Err(ProgramTransformerError::NotImplemented), @@ -269,8 +269,6 @@ async fn upsert_assets_metadata_cols( ) -> Result<(), DbErr> { let asset = asset::ActiveModel { id: ActiveValue::Set(metadata.mint.clone()), - specification_asset_class: Set(Some(SpecificationAssetClass::FungibleToken)), - specification_version: Set(Some(SpecificationVersions::V0)), slot_updated_metadata_account: Set(Some(metadata.slot_updated_metadata_account)), ..Default::default() }; @@ -278,11 +276,7 @@ async fn upsert_assets_metadata_cols( let mut asset_query = asset::Entity::insert(asset) .on_conflict( OnConflict::columns([asset::Column::Id]) - .update_columns([ - asset::Column::SpecificationAssetClass, - asset::Column::SpecificationVersion, - asset::Column::SlotUpdatedMetadataAccount, - ]) + .update_columns([asset::Column::SlotUpdatedMetadataAccount]) .to_owned(), ) .build(DbBackend::Postgres); diff --git a/program_transformers/src/token_metadata/v1_asset.rs b/program_transformers/src/token_metadata/v1_asset.rs index 8b968ec9d..0781fc2b4 100644 --- a/program_transformers/src/token_metadata/v1_asset.rs +++ b/program_transformers/src/token_metadata/v1_asset.rs @@ -21,7 +21,7 @@ use { SpecificationVersions, V1AccountAttachments, }, token_accounts, - tokens::{self, IsNonFungible}, + tokens::{self}, }, json::ChainDataV1, }, @@ -81,8 +81,6 @@ pub async fn index_and_fetch_mint_data( ) .await?; - let is_non_fungible = token.as_ref().map(|t| t.is_non_fungible()).unwrap_or(false); - if let Some(token) = token { upsert_assets_mint_account_columns( AssetMintAccountColumns { @@ -176,10 +174,8 @@ pub async fn save_v1_asset( let mut ownership_type = match class { SpecificationAssetClass::FungibleAsset => OwnerType::Token, SpecificationAssetClass::FungibleToken => OwnerType::Token, - SpecificationAssetClass::Nft | SpecificationAssetClass::ProgrammableNft => { - OwnerType::Single - } - _ => OwnerType::Unknown, + SpecificationAssetClass::Unknown => OwnerType::Unknown, + _ => OwnerType::Single, }; // Wrapped Solana is a special token that has supply 0 (infinite). From 6aa175d5c4ad33a95e77e2a08bf1392d7958e054 Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Wed, 20 Nov 2024 16:14:03 +0530 Subject: [PATCH 11/20] fix tests and snapshots --- ...count_update_tests__account_updates-metadata-updated.snap | 2 +- ..._account_update_tests__account_updates-token-updated.snap | 2 +- ...count_update_tests__account_updates-with-all-updates.snap | 2 +- ...gration_tests__account_update_tests__account_updates.snap | 2 +- ...gration_tests__general_scenario_tests__asset_parsing.snap | 2 +- ...n_tests__general_scenario_tests__creators_reordering.snap | 2 +- ...ion_tests__mpl_core_tests__mpl_core_autograph_plugin.snap | 3 +-- ...core_tests__mpl_core_autograph_plugin_with_signature.snap | 3 +-- ...ntegration_tests__mpl_core_tests__mpl_core_get_asset.snap | 3 +-- ...pp_data_with_binary_data_and_owner_is_data_authority.snap | 3 +-- ...ith_json_data_and_update_authority_is_data_authority.snap | 3 +-- ...ata_with_msg_pack_data_and_address_is_data_authority.snap | 3 +-- ...pl_core_get_asset_with_data_section_with_binary_data.snap | 3 +-- ..._mpl_core_get_asset_with_data_section_with_json_data.snap | 3 +-- ..._core_get_asset_with_data_section_with_msg_pack_data.snap | 3 +-- ...sts__mpl_core_tests__mpl_core_get_asset_with_edition.snap | 3 +-- ...et_asset_with_multiple_internal_and_external_plugins.snap | 3 +-- ...et_with_oracle_custom_offset_and_base_address_config.snap | 3 +-- ..._get_asset_with_oracle_external_plugin_on_collection.snap | 3 +-- ...core_get_asset_with_oracle_multiple_lifecycle_events.snap | 3 +-- ...core_tests__mpl_core_get_asset_with_oracle_no_offset.snap | 3 +-- ...re_tests__mpl_core_get_asset_with_pubkey_in_rule_set.snap | 3 +-- ..._mpl_core_get_asset_with_two_oracle_external_plugins.snap | 3 +-- ...ts__mpl_core_tests__mpl_core_get_assets_by_authority.snap | 4 +--- ..._tests__mpl_core_tests__mpl_core_get_assets_by_group.snap | 5 +---- ...assets_by_group_with_oracle_and_custom_pda_all_seeds.snap | 3 +-- ..._tests__mpl_core_tests__mpl_core_get_assets_by_owner.snap | 3 +-- ...ation_tests__mpl_core_tests__mpl_core_get_collection.snap | 3 +-- ..._data_with_binary_data_and_address_is_data_authority.snap | 3 +-- ..._app_data_with_json_data_and_owner_is_data_authority.snap | 3 +-- ...msg_pack_data_and_update_authority_is_data_authority.snap | 3 +-- ...s__mpl_core_tests__mpl_core_verified_creators_plugin.snap | 3 +-- ...ts__mpl_core_verified_creators_plugin_with_signature.snap | 3 +-- .../integration_tests__regular_nft_tests__reg_get_asset.snap | 2 +- ...lar_nft_tests__reg_get_asset_batch-2-and-a-missing-1.snap | 3 +-- ...ar_nft_tests__reg_get_asset_batch-only-2-different-2.snap | 3 +-- ...tests__regular_nft_tests__reg_get_asset_batch-only-2.snap | 3 +-- ...ion_tests__regular_nft_tests__reg_get_asset_by_group.snap | 2 +- ...egration_tests__regular_nft_tests__reg_search_assets.snap | 1 - 39 files changed, 38 insertions(+), 72 deletions(-) diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__account_update_tests__account_updates-metadata-updated.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__account_update_tests__account_updates-metadata-updated.snap index fe306fab3..7ede46288 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__account_update_tests__account_updates-metadata-updated.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__account_update_tests__account_updates-metadata-updated.snap @@ -1,6 +1,7 @@ --- source: integration_tests/tests/integration_tests/account_update_tests.rs expression: response_new_slot +snapshot_kind: text --- { "interface": "ProgrammableNFT", @@ -62,7 +63,6 @@ expression: response_new_slot "ownership_model": "single", "owner": "BzbdvwEkQKeghTY53aZxTYjUienhdbkNVkgrLV6cErke" }, - "supply": null, "mutable": false, "burnt": false } diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__account_update_tests__account_updates-token-updated.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__account_update_tests__account_updates-token-updated.snap index 5dac7346d..90985a04a 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__account_update_tests__account_updates-token-updated.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__account_update_tests__account_updates-token-updated.snap @@ -1,6 +1,7 @@ --- source: integration_tests/tests/integration_tests/account_update_tests.rs expression: response_new_slot +snapshot_kind: text --- { "interface": "ProgrammableNFT", @@ -62,7 +63,6 @@ expression: response_new_slot "ownership_model": "single", "owner": "1111111QLbz7JHiBTspS962RLKV8GndWFwiEaqKM" }, - "supply": null, "mutable": true, "burnt": false } diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__account_update_tests__account_updates-with-all-updates.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__account_update_tests__account_updates-with-all-updates.snap index d0978550e..4a314f738 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__account_update_tests__account_updates-with-all-updates.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__account_update_tests__account_updates-with-all-updates.snap @@ -1,6 +1,7 @@ --- source: integration_tests/tests/integration_tests/account_update_tests.rs expression: setup.das_api.get_asset(request.clone()).await.unwrap() +snapshot_kind: text --- { "interface": "ProgrammableNFT", @@ -62,7 +63,6 @@ expression: setup.das_api.get_asset(request.clone()).await.unwrap() "ownership_model": "single", "owner": "1111111QLbz7JHiBTspS962RLKV8GndWFwiEaqKM" }, - "supply": null, "mutable": false, "burnt": false } diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__account_update_tests__account_updates.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__account_update_tests__account_updates.snap index 2deeb3b43..e37b12286 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__account_update_tests__account_updates.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__account_update_tests__account_updates.snap @@ -1,6 +1,7 @@ --- source: integration_tests/tests/integration_tests/account_update_tests.rs expression: response +snapshot_kind: text --- { "interface": "ProgrammableNFT", @@ -62,7 +63,6 @@ expression: response "ownership_model": "single", "owner": "BzbdvwEkQKeghTY53aZxTYjUienhdbkNVkgrLV6cErke" }, - "supply": null, "mutable": true, "burnt": false } diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__general_scenario_tests__asset_parsing.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__general_scenario_tests__asset_parsing.snap index 27d495e3a..9843eb6b3 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__general_scenario_tests__asset_parsing.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__general_scenario_tests__asset_parsing.snap @@ -1,6 +1,7 @@ --- source: integration_tests/tests/integration_tests/general_scenario_tests.rs expression: response +snapshot_kind: text --- { "interface": "ProgrammableNFT", @@ -62,7 +63,6 @@ expression: response "ownership_model": "single", "owner": "BzbdvwEkQKeghTY53aZxTYjUienhdbkNVkgrLV6cErke" }, - "supply": null, "mutable": true, "burnt": false } diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__general_scenario_tests__creators_reordering.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__general_scenario_tests__creators_reordering.snap index 2ed4bf732..7b50b3a93 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__general_scenario_tests__creators_reordering.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__general_scenario_tests__creators_reordering.snap @@ -1,6 +1,7 @@ --- source: integration_tests/tests/integration_tests/general_scenario_tests.rs expression: response +snapshot_kind: text --- { "interface": "ProgrammableNFT", @@ -77,7 +78,6 @@ expression: response "ownership_model": "single", "owner": "AZgXpkRSetUJHy6C3NBvG6jNe49MpgrkZ2RkdMkjCjkW" }, - "supply": null, "mutable": true, "burnt": false } diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_autograph_plugin.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_autograph_plugin.snap index 1a8cfd344..552549a56 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_autograph_plugin.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_autograph_plugin.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 487 expression: response +snapshot_kind: text --- { "interface": "MplCoreAsset", @@ -51,7 +51,6 @@ expression: response "ownership_model": "single", "owner": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7" }, - "supply": null, "mutable": true, "burnt": false, "plugins": { diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_autograph_plugin_with_signature.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_autograph_plugin_with_signature.snap index 4277369f1..2753ea8e2 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_autograph_plugin_with_signature.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_autograph_plugin_with_signature.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 516 expression: response +snapshot_kind: text --- { "interface": "MplCoreAsset", @@ -51,7 +51,6 @@ expression: response "ownership_model": "single", "owner": "ACxrDWeCPic6voU6a8vyadpL8nSW15Un5vT76LDpxD4N" }, - "supply": null, "mutable": true, "burnt": false, "plugins": { diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset.snap index 0b9a6039f..a72d1bfc8 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 37 expression: response +snapshot_kind: text --- { "interface": "MplCoreAsset", @@ -62,7 +62,6 @@ expression: response "ownership_model": "single", "owner": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7" }, - "supply": null, "mutable": true, "burnt": false, "plugins": { diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_app_data_with_binary_data_and_owner_is_data_authority.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_app_data_with_binary_data_and_owner_is_data_authority.snap index b0d613582..e48244c90 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_app_data_with_binary_data_and_owner_is_data_authority.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_app_data_with_binary_data_and_owner_is_data_authority.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 603 expression: response +snapshot_kind: text --- { "interface": "MplCoreAsset", @@ -51,7 +51,6 @@ expression: response "ownership_model": "single", "owner": "HKwwF4sPVYFPgqEgxth4GZRZjJ9o4E3wA8eu2QM5Vt3H" }, - "supply": null, "mutable": true, "burnt": false, "plugins": {}, diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_app_data_with_json_data_and_update_authority_is_data_authority.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_app_data_with_json_data_and_update_authority_is_data_authority.snap index ba7f6bca3..d7f66a390 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_app_data_with_json_data_and_update_authority_is_data_authority.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_app_data_with_json_data_and_update_authority_is_data_authority.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 633 expression: response +snapshot_kind: text --- { "interface": "MplCoreAsset", @@ -51,7 +51,6 @@ expression: response "ownership_model": "single", "owner": "HKwwF4sPVYFPgqEgxth4GZRZjJ9o4E3wA8eu2QM5Vt3H" }, - "supply": null, "mutable": true, "burnt": false, "plugins": {}, diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_app_data_with_msg_pack_data_and_address_is_data_authority.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_app_data_with_msg_pack_data_and_address_is_data_authority.snap index 2031b1797..38619bc7f 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_app_data_with_msg_pack_data_and_address_is_data_authority.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_app_data_with_msg_pack_data_and_address_is_data_authority.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 662 expression: response +snapshot_kind: text --- { "interface": "MplCoreAsset", @@ -51,7 +51,6 @@ expression: response "ownership_model": "single", "owner": "HKwwF4sPVYFPgqEgxth4GZRZjJ9o4E3wA8eu2QM5Vt3H" }, - "supply": null, "mutable": true, "burnt": false, "plugins": {}, diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_data_section_with_binary_data.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_data_section_with_binary_data.snap index 85e72340b..3fe19c33d 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_data_section_with_binary_data.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_data_section_with_binary_data.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 721 expression: response +snapshot_kind: text --- { "interface": "MplCoreAsset", @@ -56,7 +56,6 @@ expression: response "ownership_model": "single", "owner": "HKwwF4sPVYFPgqEgxth4GZRZjJ9o4E3wA8eu2QM5Vt3H" }, - "supply": null, "mutable": true, "burnt": false, "plugins": {}, diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_data_section_with_json_data.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_data_section_with_json_data.snap index 9524d637f..410235155 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_data_section_with_json_data.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_data_section_with_json_data.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 780 expression: response +snapshot_kind: text --- { "interface": "MplCoreAsset", @@ -56,7 +56,6 @@ expression: response "ownership_model": "single", "owner": "HKwwF4sPVYFPgqEgxth4GZRZjJ9o4E3wA8eu2QM5Vt3H" }, - "supply": null, "mutable": true, "burnt": false, "plugins": {}, diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_data_section_with_msg_pack_data.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_data_section_with_msg_pack_data.snap index 840e75768..0294d65bf 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_data_section_with_msg_pack_data.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_data_section_with_msg_pack_data.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 839 expression: response +snapshot_kind: text --- { "interface": "MplCoreAsset", @@ -56,7 +56,6 @@ expression: response "ownership_model": "single", "owner": "HKwwF4sPVYFPgqEgxth4GZRZjJ9o4E3wA8eu2QM5Vt3H" }, - "supply": null, "mutable": true, "burnt": false, "plugins": {}, diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_edition.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_edition.snap index 6333a1260..f86780213 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_edition.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_edition.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 216 expression: response +snapshot_kind: text --- { "interface": "MplCoreAsset", @@ -51,7 +51,6 @@ expression: response "ownership_model": "single", "owner": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7" }, - "supply": null, "mutable": true, "burnt": false, "plugins": { diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_multiple_internal_and_external_plugins.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_multiple_internal_and_external_plugins.snap index 60e77e446..a941b9087 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_multiple_internal_and_external_plugins.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_multiple_internal_and_external_plugins.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 458 expression: response +snapshot_kind: text --- { "interface": "MplCoreAsset", @@ -57,7 +57,6 @@ expression: response "ownership_model": "single", "owner": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7" }, - "supply": null, "mutable": true, "burnt": false, "plugins": { diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_oracle_custom_offset_and_base_address_config.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_oracle_custom_offset_and_base_address_config.snap index ac19d3d3a..08ad3c6dd 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_oracle_custom_offset_and_base_address_config.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_oracle_custom_offset_and_base_address_config.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 361 expression: response +snapshot_kind: text --- { "interface": "MplCoreAsset", @@ -51,7 +51,6 @@ expression: response "ownership_model": "single", "owner": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7" }, - "supply": null, "mutable": true, "burnt": false, "plugins": {}, diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_oracle_external_plugin_on_collection.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_oracle_external_plugin_on_collection.snap index 40802d2a6..520d97d9b 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_oracle_external_plugin_on_collection.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_oracle_external_plugin_on_collection.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 274 expression: response +snapshot_kind: text --- { "interface": "MplCoreCollection", @@ -51,7 +51,6 @@ expression: response "ownership_model": "single", "owner": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7" }, - "supply": null, "mutable": true, "burnt": false, "plugins": {}, diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_oracle_multiple_lifecycle_events.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_oracle_multiple_lifecycle_events.snap index f42fdf792..9bf617915 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_oracle_multiple_lifecycle_events.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_oracle_multiple_lifecycle_events.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 332 expression: response +snapshot_kind: text --- { "interface": "MplCoreAsset", @@ -51,7 +51,6 @@ expression: response "ownership_model": "single", "owner": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7" }, - "supply": null, "mutable": true, "burnt": false, "plugins": {}, diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_oracle_no_offset.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_oracle_no_offset.snap index 51d44c25c..fcbfab1d2 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_oracle_no_offset.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_oracle_no_offset.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 390 expression: response +snapshot_kind: text --- { "interface": "MplCoreAsset", @@ -51,7 +51,6 @@ expression: response "ownership_model": "single", "owner": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7" }, - "supply": null, "mutable": true, "burnt": false, "plugins": {}, diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_pubkey_in_rule_set.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_pubkey_in_rule_set.snap index bfbe6538e..05acfc8ac 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_pubkey_in_rule_set.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_pubkey_in_rule_set.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 245 expression: response +snapshot_kind: text --- { "interface": "MplCoreAsset", @@ -62,7 +62,6 @@ expression: response "ownership_model": "single", "owner": "8LsUNkb7bLaAcZ7NjRKPuvcyRGTWbm9BxzUpVKjqdV8o" }, - "supply": null, "mutable": true, "burnt": false, "plugins": { diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_two_oracle_external_plugins.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_two_oracle_external_plugins.snap index b9d26a436..1da1d1281 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_two_oracle_external_plugins.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_two_oracle_external_plugins.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 274 expression: response +snapshot_kind: text --- { "interface": "MplCoreAsset", @@ -51,7 +51,6 @@ expression: response "ownership_model": "single", "owner": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7" }, - "supply": null, "mutable": true, "burnt": false, "plugins": {}, diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_assets_by_authority.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_assets_by_authority.snap index 5acbdeb5d..53017c8fe 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_assets_by_authority.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_assets_by_authority.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 108 expression: response +snapshot_kind: text --- { "total": 2, @@ -61,7 +61,6 @@ expression: response "ownership_model": "single", "owner": "GzYvuu9aUYXmnardj4svbAcCNmefiaGu2E3knGw9NJQQ" }, - "supply": null, "mutable": true, "burnt": false, "plugins": {}, @@ -118,7 +117,6 @@ expression: response "ownership_model": "single", "owner": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7" }, - "supply": null, "mutable": true, "burnt": false, "plugins": {}, diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_assets_by_group.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_assets_by_group.snap index 431a64ec4..f338c6fb7 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_assets_by_group.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_assets_by_group.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 149 expression: response +snapshot_kind: text --- { "total": 3, @@ -61,7 +61,6 @@ expression: response "ownership_model": "single", "owner": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7" }, - "supply": null, "mutable": true, "burnt": false, "plugins": {}, @@ -123,7 +122,6 @@ expression: response "ownership_model": "single", "owner": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7" }, - "supply": null, "mutable": true, "burnt": false, "plugins": {}, @@ -185,7 +183,6 @@ expression: response "ownership_model": "single", "owner": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7" }, - "supply": null, "mutable": true, "burnt": false, "plugins": {}, diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_assets_by_group_with_oracle_and_custom_pda_all_seeds.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_assets_by_group_with_oracle_and_custom_pda_all_seeds.snap index f9cea5683..a4236f53d 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_assets_by_group_with_oracle_and_custom_pda_all_seeds.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_assets_by_group_with_oracle_and_custom_pda_all_seeds.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 429 expression: response +snapshot_kind: text --- { "total": 1, @@ -61,7 +61,6 @@ expression: response "ownership_model": "single", "owner": "FAe4nM85BQ8b1nWEc5TTeogQGnNDWsuGYU84vuiPc7kE" }, - "supply": null, "mutable": true, "burnt": false, "plugins": {}, diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_assets_by_owner.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_assets_by_owner.snap index 7b190b8a9..946d8a9af 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_assets_by_owner.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_assets_by_owner.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 187 expression: response +snapshot_kind: text --- { "total": 1, @@ -61,7 +61,6 @@ expression: response "ownership_model": "single", "owner": "7uScVQiT4vArB88dHrZoeVKWbtsRJmNp9r5Gce5VQpXS" }, - "supply": null, "mutable": true, "burnt": false, "plugins": {}, diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_collection.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_collection.snap index 1d854ee47..14a95dbb2 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_collection.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_collection.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 66 expression: response +snapshot_kind: text --- { "interface": "MplCoreCollection", @@ -51,7 +51,6 @@ expression: response "ownership_model": "single", "owner": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7" }, - "supply": null, "mutable": true, "burnt": false, "plugins": { diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_collection_with_linked_app_data_with_binary_data_and_address_is_data_authority.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_collection_with_linked_app_data_with_binary_data_and_address_is_data_authority.snap index 38d0e3771..4e3b7c0c2 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_collection_with_linked_app_data_with_binary_data_and_address_is_data_authority.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_collection_with_linked_app_data_with_binary_data_and_address_is_data_authority.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 692 expression: response +snapshot_kind: text --- { "interface": "MplCoreCollection", @@ -51,7 +51,6 @@ expression: response "ownership_model": "single", "owner": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7" }, - "supply": null, "mutable": true, "burnt": false, "plugins": {}, diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_collection_with_linked_app_data_with_json_data_and_owner_is_data_authority.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_collection_with_linked_app_data_with_json_data_and_owner_is_data_authority.snap index b7ef57f77..2ed4afdc1 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_collection_with_linked_app_data_with_json_data_and_owner_is_data_authority.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_collection_with_linked_app_data_with_json_data_and_owner_is_data_authority.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 751 expression: response +snapshot_kind: text --- { "interface": "MplCoreCollection", @@ -51,7 +51,6 @@ expression: response "ownership_model": "single", "owner": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7" }, - "supply": null, "mutable": true, "burnt": false, "plugins": {}, diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_collection_with_linked_app_data_with_msg_pack_data_and_update_authority_is_data_authority.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_collection_with_linked_app_data_with_msg_pack_data_and_update_authority_is_data_authority.snap index ff0cfbdbf..526a7a545 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_collection_with_linked_app_data_with_msg_pack_data_and_update_authority_is_data_authority.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_collection_with_linked_app_data_with_msg_pack_data_and_update_authority_is_data_authority.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 810 expression: response +snapshot_kind: text --- { "interface": "MplCoreCollection", @@ -51,7 +51,6 @@ expression: response "ownership_model": "single", "owner": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7" }, - "supply": null, "mutable": true, "burnt": false, "plugins": {}, diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_verified_creators_plugin.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_verified_creators_plugin.snap index 6387d404c..cbd495062 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_verified_creators_plugin.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_verified_creators_plugin.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 545 expression: response +snapshot_kind: text --- { "interface": "MplCoreAsset", @@ -51,7 +51,6 @@ expression: response "ownership_model": "single", "owner": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7" }, - "supply": null, "mutable": true, "burnt": false, "plugins": { diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_verified_creators_plugin_with_signature.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_verified_creators_plugin_with_signature.snap index 96428d6a1..36b1cd541 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_verified_creators_plugin_with_signature.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_verified_creators_plugin_with_signature.snap @@ -1,7 +1,7 @@ --- source: integration_tests/tests/integration_tests/mpl_core_tests.rs -assertion_line: 574 expression: response +snapshot_kind: text --- { "interface": "MplCoreAsset", @@ -51,7 +51,6 @@ expression: response "ownership_model": "single", "owner": "D9SSaw4tz5AGpfWynYJ66jDCVNTsbLBkqT8rxQFenqj4" }, - "supply": null, "mutable": true, "burnt": false, "plugins": { diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__regular_nft_tests__reg_get_asset.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__regular_nft_tests__reg_get_asset.snap index c62b3de1c..befc56b19 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__regular_nft_tests__reg_get_asset.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__regular_nft_tests__reg_get_asset.snap @@ -1,6 +1,7 @@ --- source: integration_tests/tests/integration_tests/regular_nft_tests.rs expression: response +snapshot_kind: text --- { "interface": "ProgrammableNFT", @@ -67,7 +68,6 @@ expression: response "ownership_model": "single", "owner": "A59E2tNJEqNN9TDnzgGnmLmnTsdRDoPocGx3n1w2dqZw" }, - "supply": null, "mutable": true, "burnt": false } diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__regular_nft_tests__reg_get_asset_batch-2-and-a-missing-1.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__regular_nft_tests__reg_get_asset_batch-2-and-a-missing-1.snap index 0825ec1b2..2f859cbb6 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__regular_nft_tests__reg_get_asset_batch-2-and-a-missing-1.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__regular_nft_tests__reg_get_asset_batch-2-and-a-missing-1.snap @@ -1,6 +1,7 @@ --- source: integration_tests/tests/integration_tests/regular_nft_tests.rs expression: response +snapshot_kind: text --- [ { @@ -68,7 +69,6 @@ expression: response "ownership_model": "single", "owner": "9PacVenjPyQYiWBha89UYRM1nn6mf9bGY7vi32zY6DLn" }, - "supply": null, "mutable": true, "burnt": false }, @@ -138,7 +138,6 @@ expression: response "ownership_model": "single", "owner": "3H3d3hfpZVVdVwuFAxDtDSFN2AdR7kwiDA3ynbnbkhc9" }, - "supply": null, "mutable": true, "burnt": false } diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__regular_nft_tests__reg_get_asset_batch-only-2-different-2.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__regular_nft_tests__reg_get_asset_batch-only-2-different-2.snap index 36c9961f9..565f843d4 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__regular_nft_tests__reg_get_asset_batch-only-2-different-2.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__regular_nft_tests__reg_get_asset_batch-only-2-different-2.snap @@ -1,6 +1,7 @@ --- source: integration_tests/tests/integration_tests/regular_nft_tests.rs expression: response +snapshot_kind: text --- [ { @@ -68,7 +69,6 @@ expression: response "ownership_model": "single", "owner": "9PacVenjPyQYiWBha89UYRM1nn6mf9bGY7vi32zY6DLn" }, - "supply": null, "mutable": true, "burnt": false }, @@ -137,7 +137,6 @@ expression: response "ownership_model": "single", "owner": "3H3d3hfpZVVdVwuFAxDtDSFN2AdR7kwiDA3ynbnbkhc9" }, - "supply": null, "mutable": true, "burnt": false } diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__regular_nft_tests__reg_get_asset_batch-only-2.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__regular_nft_tests__reg_get_asset_batch-only-2.snap index f07052af1..7647ef26c 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__regular_nft_tests__reg_get_asset_batch-only-2.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__regular_nft_tests__reg_get_asset_batch-only-2.snap @@ -1,6 +1,7 @@ --- source: integration_tests/tests/integration_tests/regular_nft_tests.rs expression: response +snapshot_kind: text --- [ { @@ -68,7 +69,6 @@ expression: response "ownership_model": "single", "owner": "BaBQKh34KrqZzd4ifSHQYMf86HiBGASN6TWUi1ZwfyKv" }, - "supply": null, "mutable": true, "burnt": false }, @@ -137,7 +137,6 @@ expression: response "ownership_model": "single", "owner": "9PacVenjPyQYiWBha89UYRM1nn6mf9bGY7vi32zY6DLn" }, - "supply": null, "mutable": true, "burnt": false } diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__regular_nft_tests__reg_get_asset_by_group.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__regular_nft_tests__reg_get_asset_by_group.snap index 87920f33b..ce44d4bc4 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__regular_nft_tests__reg_get_asset_by_group.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__regular_nft_tests__reg_get_asset_by_group.snap @@ -1,6 +1,7 @@ --- source: integration_tests/tests/integration_tests/regular_nft_tests.rs expression: response +snapshot_kind: text --- { "total": 1, @@ -77,7 +78,6 @@ expression: response "ownership_model": "single", "owner": "9qUcfdADyrrTSetFjNjF9Ro7LKAqzJkzZV6WKLHfv5MU" }, - "supply": null, "mutable": true, "burnt": false } diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__regular_nft_tests__reg_search_assets.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__regular_nft_tests__reg_search_assets.snap index bd321f698..415fdbb43 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__regular_nft_tests__reg_search_assets.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__regular_nft_tests__reg_search_assets.snap @@ -72,7 +72,6 @@ expression: response "ownership_model": "single", "owner": "6Cr66AabRYymhZgYQSfTCo6FVpH18wXrMZswAbcErpyX" }, - "supply": null, "mutable": true, "burnt": false } From bb2f67e1a7c9cac4569f5e988a7c8af9c6135449 Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Wed, 20 Nov 2024 18:04:57 +0530 Subject: [PATCH 12/20] add more scenarios --- digital_asset_types/src/dao/full_asset.rs | 2 +- digital_asset_types/src/dao/scopes/asset.rs | 6 +- digital_asset_types/src/dapi/common/asset.rs | 57 ++--- ...38Kp4hvdomTCnCrAny4UtMUt5rQBdB6px2K1Ui45Wq | Bin 0 -> 824 bytes ...jFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v | Bin 0 -> 224 bytes ...38Kp4hvdomTCnCrAny4UtMUt5rQBdB6px2K1Ui45Wq | Bin 0 -> 824 bytes ...jFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v | Bin 0 -> 224 bytes ...KocBVvHQoVaiwWoCs9JYSVye4YZRrv5Cucf7fDqnz1 | Bin 0 -> 224 bytes ...U5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y | Bin 0 -> 496 bytes ...bpJAQGNpkgBaYBZQBR1t7yFdvaYVp2vCQQfKKEN4tM | Bin 0 -> 760 bytes ...1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo | Bin 0 -> 1008 bytes .../fungibles_and_token_extensions_tests.rs | 162 ++++++++++++++ .../tests/integration_tests/main.rs | 2 +- ...sions_tests__fungible_token_get_asset.snap | 56 +++++ ...__fungible_token_get_asset_scenario_1.snap | 56 +++++ ...__fungible_token_get_asset_scenario_2.snap | 39 ++++ ..._token_extensions_get_asset_scenario1.snap | 63 ++++++ ..._token_extensions_get_asset_scenario2.snap | 78 +++++++ ...token_extensions_get_asset_scenario_1.snap | 63 ++++++ ...token_extensions_get_asset_scenario_2.snap | 78 +++++++ ...token_extensions_get_asset_scenario_3.snap | 197 ++++++++++++++++++ .../token_extensions_tests.rs | 69 ------ migration/src/lib.rs | 2 - ...241120_075326_change_owner_type_default.rs | 41 ---- 24 files changed, 826 insertions(+), 145 deletions(-) create mode 100644 integration_tests/tests/data/accounts/fungible_token_get_asset/5x38Kp4hvdomTCnCrAny4UtMUt5rQBdB6px2K1Ui45Wq create mode 100644 integration_tests/tests/data/accounts/fungible_token_get_asset/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v create mode 100644 integration_tests/tests/data/accounts/fungible_token_get_asset_scenario_1/5x38Kp4hvdomTCnCrAny4UtMUt5rQBdB6px2K1Ui45Wq create mode 100644 integration_tests/tests/data/accounts/fungible_token_get_asset_scenario_1/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v create mode 100644 integration_tests/tests/data/accounts/fungible_token_get_asset_scenario_2/wKocBVvHQoVaiwWoCs9JYSVye4YZRrv5Cucf7fDqnz1 create mode 100644 integration_tests/tests/data/accounts/token_extensions_get_asset_scenario_1/BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y create mode 100644 integration_tests/tests/data/accounts/token_extensions_get_asset_scenario_2/HVbpJAQGNpkgBaYBZQBR1t7yFdvaYVp2vCQQfKKEN4tM create mode 100644 integration_tests/tests/data/accounts/token_extensions_get_asset_scenario_3/2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo create mode 100644 integration_tests/tests/integration_tests/fungibles_and_token_extensions_tests.rs create mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__fungible_token_get_asset.snap create mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__fungible_token_get_asset_scenario_1.snap create mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__fungible_token_get_asset_scenario_2.snap create mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario1.snap create mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario2.snap create mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario_1.snap create mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario_2.snap create mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario_3.snap delete mode 100644 integration_tests/tests/integration_tests/token_extensions_tests.rs delete mode 100644 migration/src/m20241120_075326_change_owner_type_default.rs diff --git a/digital_asset_types/src/dao/full_asset.rs b/digital_asset_types/src/dao/full_asset.rs index fda932d21..1d901c2ce 100644 --- a/digital_asset_types/src/dao/full_asset.rs +++ b/digital_asset_types/src/dao/full_asset.rs @@ -3,7 +3,7 @@ use crate::dao::{asset, asset_authority, asset_creators, asset_data, asset_group #[derive(Clone, Debug, PartialEq)] pub struct FullAsset { pub asset: asset::Model, - pub data: asset_data::Model, + pub data: Option, pub authorities: Vec, pub creators: Vec, pub groups: Vec, diff --git a/digital_asset_types/src/dao/scopes/asset.rs b/digital_asset_types/src/dao/scopes/asset.rs index 58e4cbbaf..b0e6b3c20 100644 --- a/digital_asset_types/src/dao/scopes/asset.rs +++ b/digital_asset_types/src/dao/scopes/asset.rs @@ -274,7 +274,7 @@ pub async fn get_related_for_assets( let id = asset.id.clone(); let fa = FullAsset { asset, - data: ad.clone(), + data: Some(ad.clone()), authorities: vec![], creators: vec![], groups: vec![], @@ -391,9 +391,9 @@ pub async fn get_by_id( if !include_no_supply { asset_data = asset_data.filter(Condition::all().add(asset::Column::Supply.gt(0))); } - let asset_data: (asset::Model, asset_data::Model) = + let asset_data: (asset::Model, Option) = asset_data.one(conn).await.and_then(|o| match o { - Some((a, Some(d))) => Ok((a, d)), + Some((a, d)) => Ok((a, d)), _ => Err(DbErr::RecordNotFound("Asset Not Found".to_string())), })?; diff --git a/digital_asset_types/src/dapi/common/asset.rs b/digital_asset_types/src/dapi/common/asset.rs index c2b29d73b..0aa47413c 100644 --- a/digital_asset_types/src/dapi/common/asset.rs +++ b/digital_asset_types/src/dapi/common/asset.rs @@ -1,4 +1,3 @@ -use crate::dao::sea_orm_active_enums::SpecificationVersions; use crate::dao::FullAsset; use crate::dao::PageOptions; use crate::dao::Pagination; @@ -278,14 +277,8 @@ pub fn v1_content_from_json(asset_data: &asset_data::Model) -> Result Option { - match asset.specification_version { - Some(SpecificationVersions::V1) | Some(SpecificationVersions::V0) => { - v1_content_from_json(data).ok() - } - Some(_) => None, - None => None, - } +pub fn get_content(data: &asset_data::Model) -> Option { + v1_content_from_json(data).ok() } pub fn to_authority(authority: Vec) -> Vec { @@ -357,14 +350,31 @@ pub fn asset_to_rpc(asset: FullAsset, options: &Options) -> Result Some(MplCoreInfo { @@ -380,7 +390,7 @@ pub fn asset_to_rpc(asset: FullAsset, options: &Options) -> Result Result None, }, - uses: data.chain_data.get("uses").map(|u| Uses { - use_method: u - .get("use_method") - .and_then(|s| s.as_str()) - .unwrap_or("Single") - .to_string() - .into(), - total: u.get("total").and_then(|t| t.as_u64()).unwrap_or(0), - remaining: u.get("remaining").and_then(|t| t.as_u64()).unwrap_or(0), - }), + uses, burnt: asset.burnt, mint_extensions: asset.mint_extensions, plugins: asset.mpl_core_plugins, diff --git a/integration_tests/tests/data/accounts/fungible_token_get_asset/5x38Kp4hvdomTCnCrAny4UtMUt5rQBdB6px2K1Ui45Wq b/integration_tests/tests/data/accounts/fungible_token_get_asset/5x38Kp4hvdomTCnCrAny4UtMUt5rQBdB6px2K1Ui45Wq new file mode 100644 index 0000000000000000000000000000000000000000..a6006eeb7b89d1f63e6995e6db760c7d6ecb91e7 GIT binary patch literal 824 zcmY#jfB*@G90nE!4+a$=H-NzfNJap00)qsQ^z4vWJ0r8`dyU|(_V&if>DTl+RleQM z&c0lG+(-Xrq7`>R>c+WQpO%-A@i(`u5;S%`zrtSN+&T1)xEp!7d8U`I&h@ eCRV@&6a}hrhDe^ks%Gd4GBW-dx{eHjEUJ*KQ@u=?ze~6Qx{IYdHSK-x!09zWVW=vjgK~;Xw~zzweCN|N|2cuUen%s z0qOrx(4@p61mrR(m4|vxW@KOp0DTl+RleQM z&c0lG+(-Xrq7`>R>c+fzhlO={5cRx9F>Dz-RHOrWoUG-xV6@UhX2D>OY=V#^t enOFfAP!y=f86tTCtD2!J$jJC-=sJF=xEuf~9a#SW literal 0 HcmV?d00001 diff --git a/integration_tests/tests/data/accounts/fungible_token_get_asset_scenario_1/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v b/integration_tests/tests/data/accounts/fungible_token_get_asset_scenario_1/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v new file mode 100644 index 0000000000000000000000000000000000000000..3ffad1cc084755abda1e5f0355c8e01bd555f2e8 GIT binary patch literal 224 zcmY#jfB*@G3HjEUJ*KQ@u=?ze~6Qx{IYdHSK-x!09zWVW=vjgK~;Xw~zzweCN|N|2cuUen%s z0qOrxu-=$M2*_nvb-BoMG9v>+5ReU|7-sxyd(k`l(W~x*XO^^gYjzxR_^REavVRNT z#YJ~d$4SnfV84C6k`ylk8zV?{Qo*XO$fHwOw*(^b literal 0 HcmV?d00001 diff --git a/integration_tests/tests/data/accounts/fungible_token_get_asset_scenario_2/wKocBVvHQoVaiwWoCs9JYSVye4YZRrv5Cucf7fDqnz1 b/integration_tests/tests/data/accounts/fungible_token_get_asset_scenario_2/wKocBVvHQoVaiwWoCs9JYSVye4YZRrv5Cucf7fDqnz1 new file mode 100644 index 0000000000000000000000000000000000000000..49c0c5373e0b96a3d918b6bdfe9bf5e8052fc5cf GIT binary patch literal 224 zcmY#jfB*@G3s-NKbc(mR7`=hC+=4P}x#(pf|eJ?fZQNb0p WEWehSa~TAdUU>mj#|2VM1ONcC%tojH literal 0 HcmV?d00001 diff --git a/integration_tests/tests/data/accounts/token_extensions_get_asset_scenario_1/BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y b/integration_tests/tests/data/accounts/token_extensions_get_asset_scenario_1/BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y new file mode 100644 index 0000000000000000000000000000000000000000..8058983764f2be14cf887cecc70ffa876876fcf7 GIT binary patch literal 496 zcmY#jfB*@G3eYws-;VJdtF72Lx%-&gT7jO& z(Os`MziO5JSbLf6?ze~UO8f6gIK}RHl5_UfHmN_p%{zJ3|Ly&$absckACQ>|2F5^= zf#E+CY?X)<0rAf_qbrr2hCe@8nhgxA&*UjfLHRKxRI$^aqj* z4F93PN|!?j#J}C2?m3x}fgy{DfdNP{xORUs5y?5(ZZ_4A!8|{OxA^Va( zZpy#(ShPghcycgM9UCJ^wRo#h;`^)}!CL7bg4?3j8fw~~XFo5*wRPvhaJG=%1KL0( z)CP>q3W>`(o9fZu_0{S)}u|mNmKPM-# zhy}brr2hCe@8nhgxA&*UjfLHRKxXb?wBiL) z4F93PRF^{t#1Cmr_ngegz>vhuzyPEe`27=9wcZFbdF!k9`aOFdWW1V7OZg7hT-oAh z5ohM@nq4D$`S`gB3=C|HAl2fnMv3pUb_8pse+X`iT5G6jf1drk5ZBh73&Yt$dJkxW zY@jk=WM)txXfF>DY8V-E2%1Bz|6-ZYeTgZ;!r(~IK6Fzs_yP=#1Pzfff97mm%yPG> zxatY-?C#G;=1248c&@l=tg-ni+XR_#P{dIL_!t}rI)ab|LO?T`N<@v7x6Xc__q``1 zPa(&#qk4*ZZp!-w{T`pMH(9^9K`7k|GpwW73@)HU0}?9(5_1$ngI!obyhtF!AIQik zDJdwn($_D^&rZ$L%}p&yOi3(B)GJ7=$S>AQ&d=2^s4Oi`iHAw(7Zl~E=ojbbB<3Ze NN$F)3=jTB}1OOa}Bjx}A literal 0 HcmV?d00001 diff --git a/integration_tests/tests/integration_tests/fungibles_and_token_extensions_tests.rs b/integration_tests/tests/integration_tests/fungibles_and_token_extensions_tests.rs new file mode 100644 index 000000000..6115b3103 --- /dev/null +++ b/integration_tests/tests/integration_tests/fungibles_and_token_extensions_tests.rs @@ -0,0 +1,162 @@ +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_token_extensions_get_asset_scenario_1() { + let name = trim_test_name(function_name!()); + let setup = TestSetup::new_with_options( + name.clone(), + TestSetupOptions { + network: Some(Network::Devnet), + }, + ) + .await; + + let seeds: Vec = seed_accounts(["BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y"]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "id": "BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y" + } + "#; + + let request: api::GetAsset = serde_json::from_str(request).unwrap(); + let response = setup.das_api.get_asset(request).await.unwrap(); + + insta::assert_json_snapshot!(name, response); +} + +#[tokio::test] +#[serial] +#[named] +async fn test_token_extensions_get_asset_scenario_2() { + 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(["HVbpJAQGNpkgBaYBZQBR1t7yFdvaYVp2vCQQfKKEN4tM"]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "id": "HVbpJAQGNpkgBaYBZQBR1t7yFdvaYVp2vCQQfKKEN4tM" + } + "#; + + let request: api::GetAsset = serde_json::from_str(request).unwrap(); + let response = setup.das_api.get_asset(request).await.unwrap(); + + insta::assert_json_snapshot!(name, response); +} + +#[tokio::test] +#[serial] +#[named] +async fn test_token_extensions_get_asset_scenario_3() { + 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(["2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo"]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "id": "2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo" + } + "#; + + let request: api::GetAsset = serde_json::from_str(request).unwrap(); + let response = setup.das_api.get_asset(request).await.unwrap(); + + insta::assert_json_snapshot!(name, response); +} + +#[tokio::test] +#[serial] +#[named] +async fn test_fungible_token_get_asset_scenario_1() { + 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([ + "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + "5x38Kp4hvdomTCnCrAny4UtMUt5rQBdB6px2K1Ui45Wq", + ]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "id": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" + } + "#; + + let request: api::GetAsset = serde_json::from_str(request).unwrap(); + let response = setup.das_api.get_asset(request).await.unwrap(); + + insta::assert_json_snapshot!(name, response); +} + +#[tokio::test] +#[serial] +#[named] +async fn test_fungible_token_get_asset_scenario_2() { + let name = trim_test_name(function_name!()); + let setup = TestSetup::new_with_options( + name.clone(), + TestSetupOptions { + network: Some(Network::Devnet), + }, + ) + .await; + + let seeds: Vec = seed_accounts(["wKocBVvHQoVaiwWoCs9JYSVye4YZRrv5Cucf7fDqnz1"]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "id": "wKocBVvHQoVaiwWoCs9JYSVye4YZRrv5Cucf7fDqnz1" + } + "#; + + let request: api::GetAsset = serde_json::from_str(request).unwrap(); + let response = setup.das_api.get_asset(request).await.unwrap(); + + insta::assert_json_snapshot!(name, response); +} diff --git a/integration_tests/tests/integration_tests/main.rs b/integration_tests/tests/integration_tests/main.rs index d29115eb9..399b6e583 100644 --- a/integration_tests/tests/integration_tests/main.rs +++ b/integration_tests/tests/integration_tests/main.rs @@ -1,7 +1,7 @@ mod account_update_tests; mod cnft_tests; mod common; +mod fungibles_and_token_extensions_tests; mod general_scenario_tests; mod mpl_core_tests; mod regular_nft_tests; -mod token_extensions_tests; diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__fungible_token_get_asset.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__fungible_token_get_asset.snap new file mode 100644 index 000000000..56928469a --- /dev/null +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__fungible_token_get_asset.snap @@ -0,0 +1,56 @@ +--- +source: integration_tests/tests/integration_tests/fungibles_and_token_extensions_tests.rs +expression: response +snapshot_kind: text +--- +{ + "interface": "Custom", + "id": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + "content": { + "$schema": "https://schema.metaplex.com/nft1.0.json", + "json_uri": "", + "files": [], + "metadata": { + "name": "USD Coin", + "symbol": "USDC" + }, + "links": {} + }, + "authorities": [ + { + "address": "2wmVCSfPxGPjrnMMn7rchp4uaeoTqN39mXFC2zhPdri9", + "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": false, + "locked": false + }, + "creators": [], + "ownership": { + "frozen": false, + "delegated": false, + "delegate": null, + "ownership_model": "token", + "owner": "" + }, + "mutable": true, + "burnt": false +} diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__fungible_token_get_asset_scenario_1.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__fungible_token_get_asset_scenario_1.snap new file mode 100644 index 000000000..56928469a --- /dev/null +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__fungible_token_get_asset_scenario_1.snap @@ -0,0 +1,56 @@ +--- +source: integration_tests/tests/integration_tests/fungibles_and_token_extensions_tests.rs +expression: response +snapshot_kind: text +--- +{ + "interface": "Custom", + "id": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + "content": { + "$schema": "https://schema.metaplex.com/nft1.0.json", + "json_uri": "", + "files": [], + "metadata": { + "name": "USD Coin", + "symbol": "USDC" + }, + "links": {} + }, + "authorities": [ + { + "address": "2wmVCSfPxGPjrnMMn7rchp4uaeoTqN39mXFC2zhPdri9", + "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": false, + "locked": false + }, + "creators": [], + "ownership": { + "frozen": false, + "delegated": false, + "delegate": null, + "ownership_model": "token", + "owner": "" + }, + "mutable": true, + "burnt": false +} diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__fungible_token_get_asset_scenario_2.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__fungible_token_get_asset_scenario_2.snap new file mode 100644 index 000000000..2357ddf57 --- /dev/null +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__fungible_token_get_asset_scenario_2.snap @@ -0,0 +1,39 @@ +--- +source: integration_tests/tests/integration_tests/fungibles_and_token_extensions_tests.rs +expression: response +snapshot_kind: text +--- +{ + "interface": "FungibleToken", + "id": "wKocBVvHQoVaiwWoCs9JYSVye4YZRrv5Cucf7fDqnz1", + "authorities": [], + "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": false, + "locked": false + }, + "creators": [], + "ownership": { + "frozen": false, + "delegated": false, + "delegate": null, + "ownership_model": "token", + "owner": "" + }, + "mutable": false, + "burnt": false +} diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario1.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario1.snap new file mode 100644 index 000000000..edaf78071 --- /dev/null +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario1.snap @@ -0,0 +1,63 @@ +--- +source: integration_tests/tests/integration_tests/fungibles_and_token_extensions_tests.rs +expression: response +snapshot_kind: text +--- +{ + "interface": "FungibleToken", + "id": "BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y", + "content": { + "$schema": "https://schema.metaplex.com/nft1.0.json", + "json_uri": "https://acme.com/demo.json", + "files": [], + "metadata": { + "name": "DAS Dev", + "symbol": "DAS" + }, + "links": {} + }, + "authorities": [], + "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": false, + "locked": false + }, + "creators": [], + "ownership": { + "frozen": false, + "delegated": false, + "delegate": null, + "ownership_model": "token", + "owner": "" + }, + "mutable": true, + "burnt": false, + "mint_extensions": { + "metadata": { + "uri": "https://acme.com/demo.json", + "mint": "BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y", + "name": "DAS Dev", + "symbol": "DAS", + "update_authority": "Em34oqDQYQZ9b6ycPHD28K47mttrRsdNu1S1pgK6NtPL", + "additional_metadata": [] + }, + "metadata_pointer": { + "authority": "Em34oqDQYQZ9b6ycPHD28K47mttrRsdNu1S1pgK6NtPL", + "metadata_address": "BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y" + } + } +} diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario2.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario2.snap new file mode 100644 index 000000000..3ac4fdcb9 --- /dev/null +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario2.snap @@ -0,0 +1,78 @@ +--- +source: integration_tests/tests/integration_tests/fungibles_and_token_extensions_tests.rs +expression: response +snapshot_kind: text +--- +{ + "interface": "FungibleToken", + "id": "HVbpJAQGNpkgBaYBZQBR1t7yFdvaYVp2vCQQfKKEN4tM", + "content": { + "$schema": "https://schema.metaplex.com/nft1.0.json", + "json_uri": "https://token-metadata.paxos.com/usdp_metadata/prod/solana/usdp_metadata.json", + "files": [], + "metadata": { + "name": "Pax Dollar", + "symbol": "USDP" + }, + "links": {} + }, + "authorities": [], + "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": false, + "locked": false + }, + "creators": [], + "ownership": { + "frozen": false, + "delegated": false, + "delegate": null, + "ownership_model": "token", + "owner": "" + }, + "mutable": true, + "burnt": false, + "mint_extensions": { + "metadata": { + "uri": "https://token-metadata.paxos.com/usdp_metadata/prod/solana/usdp_metadata.json", + "mint": "HVbpJAQGNpkgBaYBZQBR1t7yFdvaYVp2vCQQfKKEN4tM", + "name": "Pax Dollar", + "symbol": "USDP", + "update_authority": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk", + "additional_metadata": [] + }, + "transfer_hook": { + "authority": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk", + "program_id": null + }, + "metadata_pointer": { + "authority": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk", + "metadata_address": "HVbpJAQGNpkgBaYBZQBR1t7yFdvaYVp2vCQQfKKEN4tM" + }, + "permanent_delegate": { + "delegate": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk" + }, + "mint_close_authority": { + "close_authority": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk" + }, + "confidential_transfer_mint": { + "authority": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk", + "auditor_elgamal_pubkey": null, + "auto_approve_new_accounts": false + } + } +} diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario_1.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario_1.snap new file mode 100644 index 000000000..edaf78071 --- /dev/null +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario_1.snap @@ -0,0 +1,63 @@ +--- +source: integration_tests/tests/integration_tests/fungibles_and_token_extensions_tests.rs +expression: response +snapshot_kind: text +--- +{ + "interface": "FungibleToken", + "id": "BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y", + "content": { + "$schema": "https://schema.metaplex.com/nft1.0.json", + "json_uri": "https://acme.com/demo.json", + "files": [], + "metadata": { + "name": "DAS Dev", + "symbol": "DAS" + }, + "links": {} + }, + "authorities": [], + "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": false, + "locked": false + }, + "creators": [], + "ownership": { + "frozen": false, + "delegated": false, + "delegate": null, + "ownership_model": "token", + "owner": "" + }, + "mutable": true, + "burnt": false, + "mint_extensions": { + "metadata": { + "uri": "https://acme.com/demo.json", + "mint": "BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y", + "name": "DAS Dev", + "symbol": "DAS", + "update_authority": "Em34oqDQYQZ9b6ycPHD28K47mttrRsdNu1S1pgK6NtPL", + "additional_metadata": [] + }, + "metadata_pointer": { + "authority": "Em34oqDQYQZ9b6ycPHD28K47mttrRsdNu1S1pgK6NtPL", + "metadata_address": "BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y" + } + } +} diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario_2.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario_2.snap new file mode 100644 index 000000000..3ac4fdcb9 --- /dev/null +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario_2.snap @@ -0,0 +1,78 @@ +--- +source: integration_tests/tests/integration_tests/fungibles_and_token_extensions_tests.rs +expression: response +snapshot_kind: text +--- +{ + "interface": "FungibleToken", + "id": "HVbpJAQGNpkgBaYBZQBR1t7yFdvaYVp2vCQQfKKEN4tM", + "content": { + "$schema": "https://schema.metaplex.com/nft1.0.json", + "json_uri": "https://token-metadata.paxos.com/usdp_metadata/prod/solana/usdp_metadata.json", + "files": [], + "metadata": { + "name": "Pax Dollar", + "symbol": "USDP" + }, + "links": {} + }, + "authorities": [], + "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": false, + "locked": false + }, + "creators": [], + "ownership": { + "frozen": false, + "delegated": false, + "delegate": null, + "ownership_model": "token", + "owner": "" + }, + "mutable": true, + "burnt": false, + "mint_extensions": { + "metadata": { + "uri": "https://token-metadata.paxos.com/usdp_metadata/prod/solana/usdp_metadata.json", + "mint": "HVbpJAQGNpkgBaYBZQBR1t7yFdvaYVp2vCQQfKKEN4tM", + "name": "Pax Dollar", + "symbol": "USDP", + "update_authority": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk", + "additional_metadata": [] + }, + "transfer_hook": { + "authority": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk", + "program_id": null + }, + "metadata_pointer": { + "authority": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk", + "metadata_address": "HVbpJAQGNpkgBaYBZQBR1t7yFdvaYVp2vCQQfKKEN4tM" + }, + "permanent_delegate": { + "delegate": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk" + }, + "mint_close_authority": { + "close_authority": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk" + }, + "confidential_transfer_mint": { + "authority": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk", + "auditor_elgamal_pubkey": null, + "auto_approve_new_accounts": false + } + } +} diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario_3.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario_3.snap new file mode 100644 index 000000000..3484f3ce6 --- /dev/null +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario_3.snap @@ -0,0 +1,197 @@ +--- +source: integration_tests/tests/integration_tests/fungibles_and_token_extensions_tests.rs +expression: response +snapshot_kind: text +--- +{ + "interface": "FungibleToken", + "id": "2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo", + "content": { + "$schema": "https://schema.metaplex.com/nft1.0.json", + "json_uri": "https://token-metadata.paxos.com/pyusd_metadata/prod/solana/pyusd_metadata.json", + "files": [], + "metadata": { + "name": "PayPal USD", + "symbol": "PYUSD" + }, + "links": {} + }, + "authorities": [], + "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": false, + "locked": false + }, + "creators": [], + "ownership": { + "frozen": false, + "delegated": false, + "delegate": null, + "ownership_model": "token", + "owner": "" + }, + "mutable": true, + "burnt": false, + "mint_extensions": { + "metadata": { + "uri": "https://token-metadata.paxos.com/pyusd_metadata/prod/solana/pyusd_metadata.json", + "mint": "2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo", + "name": "PayPal USD", + "symbol": "PYUSD", + "update_authority": "9nEfZqzTP3dfVWmzQy54TzsZqSQqDFVW4PhXdG9vYCVD", + "additional_metadata": [] + }, + "transfer_hook": { + "authority": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk", + "program_id": null + }, + "metadata_pointer": { + "authority": "9nEfZqzTP3dfVWmzQy54TzsZqSQqDFVW4PhXdG9vYCVD", + "metadata_address": "2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo" + }, + "permanent_delegate": { + "delegate": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk" + }, + "transfer_fee_config": { + "withheld_amount": 0, + "newer_transfer_fee": { + "epoch": 605, + "maximum_fee": 0, + "transfer_fee_basis_points": 0 + }, + "older_transfer_fee": { + "epoch": 605, + "maximum_fee": 0, + "transfer_fee_basis_points": 0 + }, + "withdraw_withheld_authority": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk", + "transfer_fee_config_authority": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk" + }, + "mint_close_authority": { + "close_authority": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk" + }, + "confidential_transfer_mint": { + "authority": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk", + "auditor_elgamal_pubkey": null, + "auto_approve_new_accounts": false + }, + "confidential_transfer_fee_config": { + "authority": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk", + "withheld_amount": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "harvest_to_mint_enabled": true, + "withdraw_withheld_authority_elgamal_pubkey": [ + 28, + 55, + 230, + 67, + 59, + 115, + 4, + 221, + 130, + 115, + 122, + 228, + 13, + 155, + 139, + 243, + 196, + 159, + 91, + 14, + 108, + 73, + 168, + 213, + 51, + 40, + 179, + 229, + 6, + 144, + 28, + 87 + ] + } + } +} diff --git a/integration_tests/tests/integration_tests/token_extensions_tests.rs b/integration_tests/tests/integration_tests/token_extensions_tests.rs deleted file mode 100644 index 77ce75a08..000000000 --- a/integration_tests/tests/integration_tests/token_extensions_tests.rs +++ /dev/null @@ -1,69 +0,0 @@ -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_token_extensions_get_asset_scenario1() { - let name = trim_test_name(function_name!()); - let setup = TestSetup::new_with_options( - name.clone(), - TestSetupOptions { - network: Some(Network::Devnet), - }, - ) - .await; - - let seeds: Vec = seed_accounts(["BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y"]); - - apply_migrations_and_delete_data(setup.db.clone()).await; - index_seed_events(&setup, seeds.iter().collect_vec()).await; - - let request = r#" - { - "id": "BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y" - } - "#; - - let request: api::GetAsset = serde_json::from_str(request).unwrap(); - let response = setup.das_api.get_asset(request).await.unwrap(); - - insta::assert_json_snapshot!(name, response); -} - -#[tokio::test] -#[serial] -#[named] -async fn test_token_extensions_get_asset_scenario2() { - 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(["HVbpJAQGNpkgBaYBZQBR1t7yFdvaYVp2vCQQfKKEN4tM"]); - - apply_migrations_and_delete_data(setup.db.clone()).await; - index_seed_events(&setup, seeds.iter().collect_vec()).await; - - let request = r#" - { - "id": "HVbpJAQGNpkgBaYBZQBR1t7yFdvaYVp2vCQQfKKEN4tM" - } - "#; - - let request: api::GetAsset = serde_json::from_str(request).unwrap(); - let response = setup.das_api.get_asset(request).await.unwrap(); - - insta::assert_json_snapshot!(name, response); -} diff --git a/migration/src/lib.rs b/migration/src/lib.rs index 1fb7a4365..d2d5c9051 100644 --- a/migration/src/lib.rs +++ b/migration/src/lib.rs @@ -44,7 +44,6 @@ mod m20240319_120101_add_mpl_core_enum_vals; mod m20240320_120101_add_mpl_core_info_items; mod m20240520_120101_add_mpl_core_external_plugins_columns; mod m20240718_161232_change_supply_columns_to_numeric; -mod m20241120_075326_change_owner_type_default; pub mod model; @@ -98,7 +97,6 @@ impl MigratorTrait for Migrator { Box::new(m20240320_120101_add_mpl_core_info_items::Migration), Box::new(m20240520_120101_add_mpl_core_external_plugins_columns::Migration), Box::new(m20240718_161232_change_supply_columns_to_numeric::Migration), - Box::new(m20241120_075326_change_owner_type_default::Migration), ] } } diff --git a/migration/src/m20241120_075326_change_owner_type_default.rs b/migration/src/m20241120_075326_change_owner_type_default.rs deleted file mode 100644 index 75c6ebb94..000000000 --- a/migration/src/m20241120_075326_change_owner_type_default.rs +++ /dev/null @@ -1,41 +0,0 @@ -use sea_orm_migration::prelude::*; - -use crate::model::table::Asset; - -#[derive(DeriveMigrationName)] -pub struct Migration; - -#[async_trait::async_trait] -impl MigrationTrait for Migration { - async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { - manager - .alter_table( - Table::alter() - .table(Asset::Table) - .modify_column( - ColumnDef::new(Asset::OwnerType) - .string() - .not_null() - .default("Unknown"), - ) - .to_owned(), - ) - .await - } - - async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { - manager - .alter_table( - Table::alter() - .table(Asset::Table) - .modify_column( - ColumnDef::new(Asset::OwnerType) - .string() - .not_null() - .default("Single"), - ) - .to_owned(), - ) - .await - } -} From 45cefbc6151e1229175199b2c5ec599f5ef91b24 Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Thu, 21 Nov 2024 17:21:42 +0530 Subject: [PATCH 13/20] add integration tests for showFungible --- ...6b5TE4WX4mgcQjuNBTDxK4SE75sbgEg5WWJwoUeie8 | Bin 0 -> 824 bytes ...84nWhQu41DMRnjdhRrLZty1i9txepMhAhz5qLLGcBw | Bin 0 -> 224 bytes ...XKY9tPpvYsdbSNyesUqo27WYC6ZsBEULdtngGHqLCK | Bin 0 -> 824 bytes ...6wj7T8Ke5nbukjtcobjjs1CDWUcQxndtnLkKAdrSrM | Bin 0 -> 224 bytes .../tests/integration_tests/main.rs | 1 + .../show_fungible_flag_tests.rs | 82 ++++++++++++++++++ ...t_asset_with_show_fungible_scenario_1.snap | 81 +++++++++++++++++ ...t_asset_with_show_fungible_scenario_2.snap | 81 +++++++++++++++++ 8 files changed, 245 insertions(+) create mode 100644 integration_tests/tests/data/accounts/get_asset_with_show_fungible_scenario_1/7z6b5TE4WX4mgcQjuNBTDxK4SE75sbgEg5WWJwoUeie8 create mode 100644 integration_tests/tests/data/accounts/get_asset_with_show_fungible_scenario_1/Ca84nWhQu41DMRnjdhRrLZty1i9txepMhAhz5qLLGcBw create mode 100644 integration_tests/tests/data/accounts/get_asset_with_show_fungible_scenario_2/7fXKY9tPpvYsdbSNyesUqo27WYC6ZsBEULdtngGHqLCK create mode 100644 integration_tests/tests/data/accounts/get_asset_with_show_fungible_scenario_2/AH6wj7T8Ke5nbukjtcobjjs1CDWUcQxndtnLkKAdrSrM create mode 100644 integration_tests/tests/integration_tests/show_fungible_flag_tests.rs create mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_with_show_fungible_scenario_1.snap create mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_with_show_fungible_scenario_2.snap diff --git a/integration_tests/tests/data/accounts/get_asset_with_show_fungible_scenario_1/7z6b5TE4WX4mgcQjuNBTDxK4SE75sbgEg5WWJwoUeie8 b/integration_tests/tests/data/accounts/get_asset_with_show_fungible_scenario_1/7z6b5TE4WX4mgcQjuNBTDxK4SE75sbgEg5WWJwoUeie8 new file mode 100644 index 0000000000000000000000000000000000000000..7670328beb682cce5d5e745d6c627eb805b56488 GIT binary patch literal 824 zcmY#jfB*@G90nE!4+a$=H-NzfNJap00)qsQOh4AW?Bj_UyN@oez3Sn(xp3iv=D@nr zpR>-ZXf-(K{!HaANZt7OVvVcC+@ShwmcwTwcH|UGE%>|DbKAu|%s({UG(cu<2?df2 z4F91(vX@H;#6Pz#(|0l>h{eFLoQZ*fWt!&3**w;(8efq4Gk>KK&B%BE+E^*)6X9wbOK0al#~<{Tj}fPrIi$y4ATmr`lX2;R`Rbj#F-Go%^90UX%&p${r&8HYBx{mHu#JNX zBZIu3JE0-!qv56~+g%mtXC@z<6%{$NU!u7#J8C7&+UNS|1m3O}HvM&zWO7wsC`8y?J81W4$FTURSP>+0yzpKH7YuRnOPfy8jF-L1rfSiUCOm zhW}6?*~=va;?G@|={uQ`fguRU22u>?r2?9-F)8FvbgH=ay6k~u;a-7vHiwE$!`_^@ SrEorX2S^PVFcPDhfdK#+8B?49 literal 0 HcmV?d00001 diff --git a/integration_tests/tests/data/accounts/get_asset_with_show_fungible_scenario_2/7fXKY9tPpvYsdbSNyesUqo27WYC6ZsBEULdtngGHqLCK b/integration_tests/tests/data/accounts/get_asset_with_show_fungible_scenario_2/7fXKY9tPpvYsdbSNyesUqo27WYC6ZsBEULdtngGHqLCK new file mode 100644 index 0000000000000000000000000000000000000000..de4e24d36a9d687132dd70bda212e8b157db469f GIT binary patch literal 824 zcmY#jfB*@G90nE!4+a$=H-NzfNJap00)qsQOlGO` z@E;1Kdbxx^{P4}0zLOb2ECz<AH-%>0>Jeph3QgDGEM`Da8uP zhL#q_Afr(M7m(}g2=XKdoB-mCl9GaAD}DXk#FQMMM!jNVz0zXc^3>uIT_e53+{CK< zyu|Wiz2y8{{jB2rJbjS4dLS0qguz2BVPpgbB7<|(lLW7jM2kZwJ&iu?EVgUzb~U-P zs_mdfcbFaSqdty!FrAuorKD>KE<=>IP6GBvS F2>>GrrEmZM literal 0 HcmV?d00001 diff --git a/integration_tests/tests/data/accounts/get_asset_with_show_fungible_scenario_2/AH6wj7T8Ke5nbukjtcobjjs1CDWUcQxndtnLkKAdrSrM b/integration_tests/tests/data/accounts/get_asset_with_show_fungible_scenario_2/AH6wj7T8Ke5nbukjtcobjjs1CDWUcQxndtnLkKAdrSrM new file mode 100644 index 0000000000000000000000000000000000000000..4922084e34595c8e872697eecac9e2a03394cf46 GIT binary patch literal 224 zcmY#jfB*@G3XDLVx7%&o}nt=fTL1 = seed_accounts([ + "Ca84nWhQu41DMRnjdhRrLZty1i9txepMhAhz5qLLGcBw", + "7z6b5TE4WX4mgcQjuNBTDxK4SE75sbgEg5WWJwoUeie8", + ]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "id": "Ca84nWhQu41DMRnjdhRrLZty1i9txepMhAhz5qLLGcBw", + "displayOptions": { + "showFungible": true + } + + } + "#; + + let request: api::GetAsset = serde_json::from_str(request).unwrap(); + let response = setup.das_api.get_asset(request).await.unwrap(); + + insta::assert_json_snapshot!(name, response); +} + +#[tokio::test] +#[serial] +#[named] +async fn test_get_asset_with_show_fungible_scenario_2() { + 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([ + "AH6wj7T8Ke5nbukjtcobjjs1CDWUcQxndtnLkKAdrSrM", + "7fXKY9tPpvYsdbSNyesUqo27WYC6ZsBEULdtngGHqLCK", + ]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "id": "AH6wj7T8Ke5nbukjtcobjjs1CDWUcQxndtnLkKAdrSrM", + "displayOptions": { + "showFungible": true + } + } + "#; + + let request: api::GetAsset = serde_json::from_str(request).unwrap(); + let response = setup.das_api.get_asset(request).await.unwrap(); + + insta::assert_json_snapshot!(name, response); +} diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_with_show_fungible_scenario_1.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_with_show_fungible_scenario_1.snap new file mode 100644 index 000000000..feef27799 --- /dev/null +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_with_show_fungible_scenario_1.snap @@ -0,0 +1,81 @@ +--- +source: integration_tests/tests/integration_tests/show_fungible_flag_tests.rs +expression: response +snapshot_kind: text +--- +{ + "interface": "ProgrammableNFT", + "id": "Ca84nWhQu41DMRnjdhRrLZty1i9txepMhAhz5qLLGcBw", + "content": { + "$schema": "https://schema.metaplex.com/nft1.0.json", + "json_uri": "https://nftstorage.link/ipfs/bafkreibmdapcawep5fb77lvcuvoivft3w3wsnc4qworrntjbg6abc5vwti", + "files": [], + "metadata": { + "name": "Claynosaurz #1096", + "symbol": "DINO", + "token_standard": "ProgrammableNonFungible" + }, + "links": {} + }, + "authorities": [ + { + "address": "B7B2g3WbdZMDV3YcDGRGhEt5KyWqDJZFwRR8zpWVEkUF", + "scopes": [ + "full" + ] + } + ], + "compression": { + "eligible": false, + "compressed": false, + "data_hash": "", + "creator_hash": "", + "asset_hash": "", + "tree": "", + "seq": 0, + "leaf_id": 0 + }, + "grouping": [ + { + "group_key": "collection", + "group_value": "6mszaj17KSfVqADrQj3o4W3zoLMTykgmV37W4QadCczK" + } + ], + "royalty": { + "royalty_model": "creators", + "target": null, + "percent": 0.05, + "basis_points": 500, + "primary_sale_happened": true, + "locked": false + }, + "creators": [ + { + "address": "AoebZtN5iKpVyUBc82aouWhugVknLzjUmEEUezxviYNo", + "share": 0, + "verified": true + }, + { + "address": "36tfiBtaDGjAMKd6smPacHQhe4MXycLL6f9ww9CD1naT", + "share": 100, + "verified": false + } + ], + "ownership": { + "frozen": false, + "delegated": false, + "delegate": null, + "ownership_model": "single", + "owner": "" + }, + "supply": null, + "mutable": true, + "burnt": false, + "token_info": { + "supply": 1, + "decimals": 0, + "token_program": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", + "mint_authority": "EwSfdqoZPBW6JJN1SBkM2pPgpihDVbByuxKdmiXurxYF", + "freeze_authority": "EwSfdqoZPBW6JJN1SBkM2pPgpihDVbByuxKdmiXurxYF" + } +} diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_with_show_fungible_scenario_2.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_with_show_fungible_scenario_2.snap new file mode 100644 index 000000000..f8e438126 --- /dev/null +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_with_show_fungible_scenario_2.snap @@ -0,0 +1,81 @@ +--- +source: integration_tests/tests/integration_tests/show_fungible_flag_tests.rs +expression: response +snapshot_kind: text +--- +{ + "interface": "ProgrammableNFT", + "id": "AH6wj7T8Ke5nbukjtcobjjs1CDWUcQxndtnLkKAdrSrM", + "content": { + "$schema": "https://schema.metaplex.com/nft1.0.json", + "json_uri": "https://madlads.s3.us-west-2.amazonaws.com/json/1983.json", + "files": [], + "metadata": { + "name": "Mad Lads #1983", + "symbol": "MAD", + "token_standard": "ProgrammableNonFungible" + }, + "links": {} + }, + "authorities": [ + { + "address": "2RtGg6fsFiiF1EQzHqbd66AhW7R5bWeQGpTbv2UMkCdW", + "scopes": [ + "full" + ] + } + ], + "compression": { + "eligible": false, + "compressed": false, + "data_hash": "", + "creator_hash": "", + "asset_hash": "", + "tree": "", + "seq": 0, + "leaf_id": 0 + }, + "grouping": [ + { + "group_key": "collection", + "group_value": "J1S9H3QjnRtBbbuD4HjPV6RpRhwuk4zKbxsnCHuTgh9w" + } + ], + "royalty": { + "royalty_model": "creators", + "target": null, + "percent": 0.042, + "basis_points": 420, + "primary_sale_happened": true, + "locked": false + }, + "creators": [ + { + "address": "5XvhfmRjwXkGp3jHGmaKpqeerNYjkuZZBYLVQYdeVcRv", + "share": 0, + "verified": true + }, + { + "address": "2RtGg6fsFiiF1EQzHqbd66AhW7R5bWeQGpTbv2UMkCdW", + "share": 100, + "verified": true + } + ], + "ownership": { + "frozen": false, + "delegated": false, + "delegate": null, + "ownership_model": "single", + "owner": "" + }, + "supply": null, + "mutable": true, + "burnt": false, + "token_info": { + "supply": 1, + "decimals": 0, + "token_program": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", + "mint_authority": "FAzbjKo66M3tKhkKqegmWFaYr93FB74B1ChEBdFyKcip", + "freeze_authority": "FAzbjKo66M3tKhkKqegmWFaYr93FB74B1ChEBdFyKcip" + } +} From fc78fa46faac236b4429ead76796414df289cb08 Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Thu, 28 Nov 2024 11:33:36 +0530 Subject: [PATCH 14/20] resolve commenst and add token_accounts for indexing in test fixtures --- digital_asset_types/src/dapi/common/asset.rs | 5 ++--- .../8myaCN6KcKVkMqroXuLJq6QsqRcPbvme4wV5Ubfr5mDC | Bin 0 -> 312 bytes .../8Xv3SpX94HHf32Apg4TeSeS3i2p6wuXeE8FBZr168Hti | Bin 0 -> 312 bytes .../integration_tests/show_fungible_flag_tests.rs | 2 ++ ...__get_asset_with_show_fungible_scenario_1.snap | 4 ++-- ...__get_asset_with_show_fungible_scenario_2.snap | 8 ++++---- 6 files changed, 10 insertions(+), 9 deletions(-) create mode 100644 integration_tests/tests/data/accounts/get_asset_with_show_fungible_scenario_1/8myaCN6KcKVkMqroXuLJq6QsqRcPbvme4wV5Ubfr5mDC create mode 100644 integration_tests/tests/data/accounts/get_asset_with_show_fungible_scenario_2/8Xv3SpX94HHf32Apg4TeSeS3i2p6wuXeE8FBZr168Hti diff --git a/digital_asset_types/src/dapi/common/asset.rs b/digital_asset_types/src/dapi/common/asset.rs index 74c86862a..da82aa9aa 100644 --- a/digital_asset_types/src/dapi/common/asset.rs +++ b/digital_asset_types/src/dapi/common/asset.rs @@ -379,9 +379,8 @@ pub fn asset_to_rpc(asset: FullAsset, options: &Options) -> Result None, }; - let token_info = if options.show_fungible && token_info.is_some() { - let token_info = token_info.unwrap(); - Some(TokenInfo { + let token_info = if options.show_fungible { + token_info.map(|token_info| TokenInfo { supply: token_info.supply.try_into().unwrap_or(0), decimals: token_info.decimals as u8, mint_authority: token_info diff --git a/integration_tests/tests/data/accounts/get_asset_with_show_fungible_scenario_1/8myaCN6KcKVkMqroXuLJq6QsqRcPbvme4wV5Ubfr5mDC b/integration_tests/tests/data/accounts/get_asset_with_show_fungible_scenario_1/8myaCN6KcKVkMqroXuLJq6QsqRcPbvme4wV5Ubfr5mDC new file mode 100644 index 0000000000000000000000000000000000000000..69f99d0d50f77ef379f58d19ca2340073a73c8a0 GIT binary patch literal 312 zcmY#jfB*@G90nE!4+a$=H-NzfNJap00)qsQEN%~3GNbAH;+aogZ9KWl@&9$DY#+N1 z@wJ8K8#tv-`zN#A{r2#B>cYu4Pd{`!_quY8%$C--@zLfJt$Mz;*8OK#sR1X CX;jDn literal 0 HcmV?d00001 diff --git a/integration_tests/tests/data/accounts/get_asset_with_show_fungible_scenario_2/8Xv3SpX94HHf32Apg4TeSeS3i2p6wuXeE8FBZr168Hti b/integration_tests/tests/data/accounts/get_asset_with_show_fungible_scenario_2/8Xv3SpX94HHf32Apg4TeSeS3i2p6wuXeE8FBZr168Hti new file mode 100644 index 0000000000000000000000000000000000000000..3ffe5ac43105262bc1150bf5b3c911ed3ad51384 GIT binary patch literal 312 zcmY#jfB*@G90nE!4+a$=H-NzfNJap00)qsQ%ztaDbFVke^QO+S9HEuhcs#SZ6V6T8 z_;3DN6VAv9PV?FBetUR5b>ZZjryshVdtJFkW=rea_-ONqRy|)^>;5yW)Bu|CK~^3} zGBEsyf|b|hg+Tn5!Lfyt89^)thNVE)Cj;lzOB@gH%w+;u3Ii~WFg^hq09DUno&W#< literal 0 HcmV?d00001 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 4fb2bf636..113e4ab22 100644 --- a/integration_tests/tests/integration_tests/show_fungible_flag_tests.rs +++ b/integration_tests/tests/integration_tests/show_fungible_flag_tests.rs @@ -24,6 +24,7 @@ async fn test_get_asset_with_show_fungible_scenario_1() { let seeds: Vec = seed_accounts([ "Ca84nWhQu41DMRnjdhRrLZty1i9txepMhAhz5qLLGcBw", "7z6b5TE4WX4mgcQjuNBTDxK4SE75sbgEg5WWJwoUeie8", + "8myaCN6KcKVkMqroXuLJq6QsqRcPbvme4wV5Ubfr5mDC", ]); apply_migrations_and_delete_data(setup.db.clone()).await; @@ -61,6 +62,7 @@ async fn test_get_asset_with_show_fungible_scenario_2() { let seeds: Vec = seed_accounts([ "AH6wj7T8Ke5nbukjtcobjjs1CDWUcQxndtnLkKAdrSrM", "7fXKY9tPpvYsdbSNyesUqo27WYC6ZsBEULdtngGHqLCK", + "8Xv3SpX94HHf32Apg4TeSeS3i2p6wuXeE8FBZr168Hti", ]); apply_migrations_and_delete_data(setup.db.clone()).await; diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_with_show_fungible_scenario_1.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_with_show_fungible_scenario_1.snap index feef27799..3af1b4d31 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_with_show_fungible_scenario_1.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_with_show_fungible_scenario_1.snap @@ -62,11 +62,11 @@ snapshot_kind: text } ], "ownership": { - "frozen": false, + "frozen": true, "delegated": false, "delegate": null, "ownership_model": "single", - "owner": "" + "owner": "J1ep1LizHMU3Bf1GKkWePGHU3Qwwzw6FvwW5ySFWdCkn" }, "supply": null, "mutable": true, diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_with_show_fungible_scenario_2.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_with_show_fungible_scenario_2.snap index f8e438126..c2d2edaba 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_with_show_fungible_scenario_2.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_with_show_fungible_scenario_2.snap @@ -62,11 +62,11 @@ snapshot_kind: text } ], "ownership": { - "frozen": false, - "delegated": false, - "delegate": null, + "frozen": true, + "delegated": true, + "delegate": "BPB5idZgbA1DG4XEmnKs62AADRZFf3jY7Kr9mpMGyKPi", "ownership_model": "single", - "owner": "" + "owner": "GqPnSDXwp4JFtKS7YZ2HERgBbYLKpKVYy9TpVunzLRa9" }, "supply": null, "mutable": true, From 8d592c7f919b5f5d978d9a4cf6c44d1d22e6f636 Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Thu, 28 Nov 2024 12:06:17 +0530 Subject: [PATCH 15/20] resolve comments and fix fixtures --- ...sions_tests__fungible_token_get_asset.snap | 56 ------------- ...__fungible_token_get_asset_scenario_1.snap | 2 +- ..._token_extensions_get_asset_scenario1.snap | 63 --------------- ..._token_extensions_get_asset_scenario2.snap | 78 ------------------- .../src/token_metadata/v1_asset.rs | 8 ++ 5 files changed, 9 insertions(+), 198 deletions(-) delete mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__fungible_token_get_asset.snap delete mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario1.snap delete mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario2.snap diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__fungible_token_get_asset.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__fungible_token_get_asset.snap deleted file mode 100644 index 56928469a..000000000 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__fungible_token_get_asset.snap +++ /dev/null @@ -1,56 +0,0 @@ ---- -source: integration_tests/tests/integration_tests/fungibles_and_token_extensions_tests.rs -expression: response -snapshot_kind: text ---- -{ - "interface": "Custom", - "id": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", - "content": { - "$schema": "https://schema.metaplex.com/nft1.0.json", - "json_uri": "", - "files": [], - "metadata": { - "name": "USD Coin", - "symbol": "USDC" - }, - "links": {} - }, - "authorities": [ - { - "address": "2wmVCSfPxGPjrnMMn7rchp4uaeoTqN39mXFC2zhPdri9", - "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": false, - "locked": false - }, - "creators": [], - "ownership": { - "frozen": false, - "delegated": false, - "delegate": null, - "ownership_model": "token", - "owner": "" - }, - "mutable": true, - "burnt": false -} diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__fungible_token_get_asset_scenario_1.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__fungible_token_get_asset_scenario_1.snap index 56928469a..16be64a22 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__fungible_token_get_asset_scenario_1.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__fungible_token_get_asset_scenario_1.snap @@ -4,7 +4,7 @@ expression: response snapshot_kind: text --- { - "interface": "Custom", + "interface": "FungibleToken", "id": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "content": { "$schema": "https://schema.metaplex.com/nft1.0.json", diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario1.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario1.snap deleted file mode 100644 index edaf78071..000000000 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario1.snap +++ /dev/null @@ -1,63 +0,0 @@ ---- -source: integration_tests/tests/integration_tests/fungibles_and_token_extensions_tests.rs -expression: response -snapshot_kind: text ---- -{ - "interface": "FungibleToken", - "id": "BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y", - "content": { - "$schema": "https://schema.metaplex.com/nft1.0.json", - "json_uri": "https://acme.com/demo.json", - "files": [], - "metadata": { - "name": "DAS Dev", - "symbol": "DAS" - }, - "links": {} - }, - "authorities": [], - "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": false, - "locked": false - }, - "creators": [], - "ownership": { - "frozen": false, - "delegated": false, - "delegate": null, - "ownership_model": "token", - "owner": "" - }, - "mutable": true, - "burnt": false, - "mint_extensions": { - "metadata": { - "uri": "https://acme.com/demo.json", - "mint": "BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y", - "name": "DAS Dev", - "symbol": "DAS", - "update_authority": "Em34oqDQYQZ9b6ycPHD28K47mttrRsdNu1S1pgK6NtPL", - "additional_metadata": [] - }, - "metadata_pointer": { - "authority": "Em34oqDQYQZ9b6ycPHD28K47mttrRsdNu1S1pgK6NtPL", - "metadata_address": "BPU5vrAHafRuVeK33CgfdwTKSsmC4p6t3aqyav3cFF7Y" - } - } -} diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario2.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario2.snap deleted file mode 100644 index 3ac4fdcb9..000000000 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__fungibles_and_token_extensions_tests__token_extensions_get_asset_scenario2.snap +++ /dev/null @@ -1,78 +0,0 @@ ---- -source: integration_tests/tests/integration_tests/fungibles_and_token_extensions_tests.rs -expression: response -snapshot_kind: text ---- -{ - "interface": "FungibleToken", - "id": "HVbpJAQGNpkgBaYBZQBR1t7yFdvaYVp2vCQQfKKEN4tM", - "content": { - "$schema": "https://schema.metaplex.com/nft1.0.json", - "json_uri": "https://token-metadata.paxos.com/usdp_metadata/prod/solana/usdp_metadata.json", - "files": [], - "metadata": { - "name": "Pax Dollar", - "symbol": "USDP" - }, - "links": {} - }, - "authorities": [], - "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": false, - "locked": false - }, - "creators": [], - "ownership": { - "frozen": false, - "delegated": false, - "delegate": null, - "ownership_model": "token", - "owner": "" - }, - "mutable": true, - "burnt": false, - "mint_extensions": { - "metadata": { - "uri": "https://token-metadata.paxos.com/usdp_metadata/prod/solana/usdp_metadata.json", - "mint": "HVbpJAQGNpkgBaYBZQBR1t7yFdvaYVp2vCQQfKKEN4tM", - "name": "Pax Dollar", - "symbol": "USDP", - "update_authority": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk", - "additional_metadata": [] - }, - "transfer_hook": { - "authority": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk", - "program_id": null - }, - "metadata_pointer": { - "authority": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk", - "metadata_address": "HVbpJAQGNpkgBaYBZQBR1t7yFdvaYVp2vCQQfKKEN4tM" - }, - "permanent_delegate": { - "delegate": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk" - }, - "mint_close_authority": { - "close_authority": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk" - }, - "confidential_transfer_mint": { - "authority": "2apBGMsS6ti9RyF5TwQTDswXBWskiJP2LD4cUEDqYJjk", - "auditor_elgamal_pubkey": null, - "auto_approve_new_accounts": false - } - } -} diff --git a/program_transformers/src/token_metadata/v1_asset.rs b/program_transformers/src/token_metadata/v1_asset.rs index 0781fc2b4..dd40df218 100644 --- a/program_transformers/src/token_metadata/v1_asset.rs +++ b/program_transformers/src/token_metadata/v1_asset.rs @@ -199,6 +199,14 @@ pub async fn save_v1_asset( }; }; + //Map specification asset class based on the supply. + if class == SpecificationAssetClass::Unknown { + class = match supply { + s if s > Decimal::from(1) => SpecificationAssetClass::FungibleToken, + _ => SpecificationAssetClass::Unknown, + }; + }; + if (ownership_type == OwnerType::Single) | (ownership_type == OwnerType::Unknown) { index_token_account_data(conn, mint_pubkey_vec.clone()).await?; } From 2c483c589f02cdc8514ee0b49e024909d27b851b Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Mon, 9 Dec 2024 10:29:54 +0530 Subject: [PATCH 16/20] chore : resolve comments --- digital_asset_types/src/rpc/asset.rs | 4 ++-- program_transformers/src/token_extensions/mod.rs | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/digital_asset_types/src/rpc/asset.rs b/digital_asset_types/src/rpc/asset.rs index 4d0f4fa8c..01dd5d71a 100644 --- a/digital_asset_types/src/rpc/asset.rs +++ b/digital_asset_types/src/rpc/asset.rs @@ -29,7 +29,7 @@ pub enum Interface { V1PRINT, #[serde(rename = "V2_NFT")] Nft, - // TODO: change on version bump\ + // TODO: change on version bump #[serde(rename = "LEGACY_NFT")] #[allow(non_camel_case_types)] LEGACY_NFT, @@ -97,7 +97,7 @@ impl From for (SpecificationVersions, SpecificationAssetClass) { SpecificationAssetClass::MplCoreCollection, ), Interface::FungibleToken => ( - SpecificationVersions::V0, + SpecificationVersions::V1, SpecificationAssetClass::FungibleToken, ), _ => (SpecificationVersions::V1, SpecificationAssetClass::Unknown), diff --git a/program_transformers/src/token_extensions/mod.rs b/program_transformers/src/token_extensions/mod.rs index a9d8df5a7..8fa8dcdd3 100644 --- a/program_transformers/src/token_extensions/mod.rs +++ b/program_transformers/src/token_extensions/mod.rs @@ -233,6 +233,8 @@ async fn upsert_asset_data( asset_data::Column::MetadataUrl, asset_data::Column::SlotUpdated, asset_data::Column::BaseInfoSeq, + asset_data::Column::RawName, + asset_data::Column::RawSymbol, ]) .to_owned(), ) From 1a4e5f72afadb9369c569c7da0a90ba53c8c0605 Mon Sep 17 00:00:00 2001 From: Ahzam Akhtar <94620460+AhzamAkhtar@users.noreply.github.com> Date: Thu, 26 Dec 2024 20:30:19 +0530 Subject: [PATCH 17/20] GetAssetByOwner skipping fungible-assets when using show_fungible option bug fixed (#197) * fungible tokens skipped when using showFungible option bug fixed in getAssetByOwner * test-case and test-snapshot added * cleanup --- .../src/dao/extensions/asset.rs | 12 ++++ digital_asset_types/src/dao/extensions/mod.rs | 1 + .../src/dao/extensions/token_accounts.rs | 25 +++++++ digital_asset_types/src/dao/scopes/asset.rs | 25 +++++-- ...RNfDfdq1nKyU1TQiCEQLWyPtD8EwUH9Kt2ahsbidUx | Bin 0 -> 312 bytes ...ajpcYgnxmWK91RhrfsdB3Tm83PcDwPvMC8ZinvtTY6 | Bin 0 -> 824 bytes ...YnhQoR9YM3N7UoaKRoA44Uy8JeaZV3qyouov87awMs | Bin 0 -> 224 bytes .../show_fungible_flag_tests.rs | 37 ++++++++++ ..._by_owner_with_show_fungible_scenario.snap | 65 ++++++++++++++++++ 9 files changed, 161 insertions(+), 4 deletions(-) create mode 100644 digital_asset_types/src/dao/extensions/token_accounts.rs create mode 100644 integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible_scenario/6BRNfDfdq1nKyU1TQiCEQLWyPtD8EwUH9Kt2ahsbidUx create mode 100644 integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible_scenario/7BajpcYgnxmWK91RhrfsdB3Tm83PcDwPvMC8ZinvtTY6 create mode 100644 integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible_scenario/7EYnhQoR9YM3N7UoaKRoA44Uy8JeaZV3qyouov87awMs create mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_by_owner_with_show_fungible_scenario.snap diff --git a/digital_asset_types/src/dao/extensions/asset.rs b/digital_asset_types/src/dao/extensions/asset.rs index 18525e39e..3ac3f724f 100644 --- a/digital_asset_types/src/dao/extensions/asset.rs +++ b/digital_asset_types/src/dao/extensions/asset.rs @@ -4,6 +4,7 @@ use crate::dao::{ asset, asset_authority, asset_creators, asset_data, asset_grouping, asset_v1_account_attachments, sea_orm_active_enums::{OwnerType, RoyaltyTargetType}, + token_accounts, }; #[derive(Copy, Clone, Debug, EnumIter)] @@ -13,6 +14,7 @@ pub enum Relation { AssetAuthority, AssetCreators, AssetGrouping, + TokenAccounts, } impl RelationTrait for Relation { @@ -22,6 +24,10 @@ impl RelationTrait for Relation { .from(asset::Column::AssetData) .to(asset_data::Column::Id) .into(), + Self::TokenAccounts => asset::Entity::belongs_to(token_accounts::Entity) + .from(asset::Column::Id) + .to(token_accounts::Column::Mint) + .into(), Self::AssetV1AccountAttachments => { asset::Entity::has_many(asset_v1_account_attachments::Entity).into() } @@ -62,6 +68,12 @@ impl Related for asset::Entity { } } +impl Related for asset::Entity { + fn to() -> RelationDef { + Relation::TokenAccounts.def() + } +} + impl Default for RoyaltyTargetType { fn default() -> Self { Self::Creators diff --git a/digital_asset_types/src/dao/extensions/mod.rs b/digital_asset_types/src/dao/extensions/mod.rs index bcfc3e130..af3baad66 100644 --- a/digital_asset_types/src/dao/extensions/mod.rs +++ b/digital_asset_types/src/dao/extensions/mod.rs @@ -5,3 +5,4 @@ pub mod asset_data; pub mod asset_grouping; pub mod asset_v1_account_attachment; pub mod instruction; +pub mod token_accounts; diff --git a/digital_asset_types/src/dao/extensions/token_accounts.rs b/digital_asset_types/src/dao/extensions/token_accounts.rs new file mode 100644 index 000000000..e48408f74 --- /dev/null +++ b/digital_asset_types/src/dao/extensions/token_accounts.rs @@ -0,0 +1,25 @@ +use sea_orm::{EntityTrait, EnumIter, Related, RelationDef, RelationTrait}; + +use crate::dao::{asset, token_accounts}; + +#[derive(Copy, Clone, Debug, EnumIter)] +pub enum Relation { + Asset, +} + +impl RelationTrait for Relation { + fn def(&self) -> RelationDef { + match self { + Self::Asset => token_accounts::Entity::belongs_to(asset::Entity) + .from(token_accounts::Column::Mint) + .to(asset::Column::Id) + .into(), + } + } +} + +impl Related for token_accounts::Entity { + fn to() -> RelationDef { + Relation::Asset.def() + } +} diff --git a/digital_asset_types/src/dao/scopes/asset.rs b/digital_asset_types/src/dao/scopes/asset.rs index fd7cc6d2e..0e4cb699d 100644 --- a/digital_asset_types/src/dao/scopes/asset.rs +++ b/digital_asset_types/src/dao/scopes/asset.rs @@ -4,11 +4,12 @@ use crate::{ asset_authority, asset_creators, asset_data, asset_grouping, cl_audits_v2, extensions::{self, instruction::PascalCase}, sea_orm_active_enums::Instruction, - tokens, Cursor, FullAsset, GroupingSize, Pagination, + token_accounts, tokens, Cursor, FullAsset, GroupingSize, Pagination, }, rpc::{filter::AssetSortDirection, options::Options}, }; use indexmap::IndexMap; +use sea_orm::sea_query::{Expr, IntoCondition}; use sea_orm::{entity::*, query::*, ConnectionTrait, DbErr, Order}; use std::collections::HashMap; @@ -151,14 +152,30 @@ pub async fn get_assets_by_owner( limit: u64, options: &Options, ) -> Result, DbErr> { - let cond = Condition::all() - .add(asset::Column::Owner.eq(owner)) + let mut joins = Vec::new(); + let mut cond = Condition::all() + .add(asset::Column::Owner.eq(owner.clone())) .add(asset::Column::Supply.gt(0)); + if options.show_fungible { + cond = Condition::all().add(token_accounts::Column::Owner.eq(owner.clone())); + + 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); + } + get_assets_by_condition( conn, cond, - vec![], + joins, sort_by, sort_direction, pagination, diff --git a/integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible_scenario/6BRNfDfdq1nKyU1TQiCEQLWyPtD8EwUH9Kt2ahsbidUx b/integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible_scenario/6BRNfDfdq1nKyU1TQiCEQLWyPtD8EwUH9Kt2ahsbidUx new file mode 100644 index 0000000000000000000000000000000000000000..035a8fc7eb66e42ec8ed229a9c6ca806c5590f51 GIT binary patch literal 312 zcmY#jfB*@G90nE!4+a$=H-NzfNJap00)qsQ^!a+$_0g5xjz_QDue^WuW!dxf{hF%2 zHoA{B?^T}N_F*mC-ER-Cr!Jg)^YlZvbFVAc$ZTnS8y{^x(W>WbYu$f_l^Q@ZKFG=g zNd|`hP@tw&ECk}$TIK$n%m`vJFf0Y)n0a&K7jw3Govm$@xU6PqbFaGXzQn`nlf0NE z^8d}Zt&%!#nz%OPZ=RdVX|D&>|DO4skZJq8<)c^+XGh|Tg%a8f-wNc!z@`xEX`>c+bCn552sJ^VwTANH{Z5O0ccQgW=>9}f=f|i zdVU_rV06F*6bSb8@reXWoB)y;B_##LR{Hwsi6yD!iIsYpMU};R6_r)`0TvNvCI#-L zC6y7Tsg)rGfw_fIMaCW`@jitaxdxt*6-B1Ol~rzTeyQ2$whR!Tk&*EqBQPXK0WCuS E0EE78Hvj+t literal 0 HcmV?d00001 diff --git a/integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible_scenario/7EYnhQoR9YM3N7UoaKRoA44Uy8JeaZV3qyouov87awMs b/integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible_scenario/7EYnhQoR9YM3N7UoaKRoA44Uy8JeaZV3qyouov87awMs new file mode 100644 index 0000000000000000000000000000000000000000..07a90f4b0710003caf51f95ec025031b1460aa24 GIT binary patch literal 224 zcmY#jfB*@G34$FTURSP>+0yzpKH7YuRnOPfy8jF-L1zB1-nCp4 zL_>k9RP=7D W*V*pzo2|MdAvog!FDFnBF#rG!K}l%< literal 0 HcmV?d00001 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 113e4ab22..944dea10b 100644 --- a/integration_tests/tests/integration_tests/show_fungible_flag_tests.rs +++ b/integration_tests/tests/integration_tests/show_fungible_flag_tests.rs @@ -82,3 +82,40 @@ async fn test_get_asset_with_show_fungible_scenario_2() { insta::assert_json_snapshot!(name, response); } + +#[tokio::test] +#[serial] +#[named] +async fn test_get_asset_by_owner_with_show_fungible_scenario() { + 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); +} diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_by_owner_with_show_fungible_scenario.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_by_owner_with_show_fungible_scenario.snap new file mode 100644 index 000000000..607c278e5 --- /dev/null +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_by_owner_with_show_fungible_scenario.snap @@ -0,0 +1,65 @@ +--- +source: integration_tests/tests/integration_tests/show_fungible_flag_tests.rs +expression: response +snapshot_kind: text +--- +{ + "total": 1, + "limit": 1000, + "cursor": "7EYnhQoR9YM3N7UoaKRoA44Uy8JeaZV3qyouov87awMs", + "items": [ + { + "interface": "Custom", + "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": "" + }, + "supply": null, + "mutable": true, + "burnt": false + } + ] +} From a213893371fed17bd22338542ccd25c69e0259ef Mon Sep 17 00:00:00 2001 From: Ahzam Akhtar <94620460+AhzamAkhtar@users.noreply.github.com> Date: Thu, 26 Dec 2024 21:18:40 +0530 Subject: [PATCH 18/20] Added coverage to show token_info in other rpc calls (#200) * added coverage to show token_info in other rpc calls * old snapshot removed --- digital_asset_types/src/dao/scopes/asset.rs | 8 ++ ...XKY9tPpvYsdbSNyesUqo27WYC6ZsBEULdtngGHqLCK | Bin 0 -> 824 bytes ...v3SpX94HHf32Apg4TeSeS3i2p6wuXeE8FBZr168Hti | Bin 0 -> 312 bytes ...6wj7T8Ke5nbukjtcobjjs1CDWUcQxndtnLkKAdrSrM | Bin 0 -> 224 bytes ...XKY9tPpvYsdbSNyesUqo27WYC6ZsBEULdtngGHqLCK | Bin 0 -> 824 bytes ...v3SpX94HHf32Apg4TeSeS3i2p6wuXeE8FBZr168Hti | Bin 0 -> 312 bytes ...6wj7T8Ke5nbukjtcobjjs1CDWUcQxndtnLkKAdrSrM | Bin 0 -> 224 bytes ...XKY9tPpvYsdbSNyesUqo27WYC6ZsBEULdtngGHqLCK | Bin 0 -> 824 bytes ...v3SpX94HHf32Apg4TeSeS3i2p6wuXeE8FBZr168Hti | Bin 0 -> 312 bytes ...6wj7T8Ke5nbukjtcobjjs1CDWUcQxndtnLkKAdrSrM | Bin 0 -> 224 bytes .../show_fungible_flag_tests.rs | 88 +++++++++++++++++- ...asset_by_authority_with_show_fungible.snap | 88 ++++++++++++++++++ ...t_asset_by_creator_with_show_fungible.snap | 88 ++++++++++++++++++ ...get_asset_by_owner_with_show_fungible.snap | 88 ++++++++++++++++++ ..._by_owner_with_show_fungible_scenario.snap | 65 ------------- 15 files changed, 355 insertions(+), 70 deletions(-) create mode 100644 integration_tests/tests/data/accounts/get_asset_by_authority_with_show_fungible/7fXKY9tPpvYsdbSNyesUqo27WYC6ZsBEULdtngGHqLCK create mode 100644 integration_tests/tests/data/accounts/get_asset_by_authority_with_show_fungible/8Xv3SpX94HHf32Apg4TeSeS3i2p6wuXeE8FBZr168Hti create mode 100644 integration_tests/tests/data/accounts/get_asset_by_authority_with_show_fungible/AH6wj7T8Ke5nbukjtcobjjs1CDWUcQxndtnLkKAdrSrM create mode 100644 integration_tests/tests/data/accounts/get_asset_by_creator_with_show_fungible/7fXKY9tPpvYsdbSNyesUqo27WYC6ZsBEULdtngGHqLCK create mode 100644 integration_tests/tests/data/accounts/get_asset_by_creator_with_show_fungible/8Xv3SpX94HHf32Apg4TeSeS3i2p6wuXeE8FBZr168Hti create mode 100644 integration_tests/tests/data/accounts/get_asset_by_creator_with_show_fungible/AH6wj7T8Ke5nbukjtcobjjs1CDWUcQxndtnLkKAdrSrM create mode 100644 integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible/7fXKY9tPpvYsdbSNyesUqo27WYC6ZsBEULdtngGHqLCK create mode 100644 integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible/8Xv3SpX94HHf32Apg4TeSeS3i2p6wuXeE8FBZr168Hti create mode 100644 integration_tests/tests/data/accounts/get_asset_by_owner_with_show_fungible/AH6wj7T8Ke5nbukjtcobjjs1CDWUcQxndtnLkKAdrSrM create mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_by_authority_with_show_fungible.snap create mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_by_creator_with_show_fungible.snap create mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_by_owner_with_show_fungible.snap delete mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_by_owner_with_show_fungible_scenario.snap diff --git a/digital_asset_types/src/dao/scopes/asset.rs b/digital_asset_types/src/dao/scopes/asset.rs index 0e4cb699d..cf75f78a2 100644 --- a/digital_asset_types/src/dao/scopes/asset.rs +++ b/digital_asset_types/src/dao/scopes/asset.rs @@ -345,6 +345,14 @@ pub async fn get_related_for_assets( } } + for id in ids.clone() { + if let Ok(t) = get_token_by_id(conn, id.clone()).await { + if let Some(asset) = assets_map.get_mut(&id) { + asset.token_info = Some(t); + } + } + } + let cond = if show_unverified_collections { Condition::all() } else { diff --git a/integration_tests/tests/data/accounts/get_asset_by_authority_with_show_fungible/7fXKY9tPpvYsdbSNyesUqo27WYC6ZsBEULdtngGHqLCK b/integration_tests/tests/data/accounts/get_asset_by_authority_with_show_fungible/7fXKY9tPpvYsdbSNyesUqo27WYC6ZsBEULdtngGHqLCK new file mode 100644 index 0000000000000000000000000000000000000000..a4776424f52d8ccd1eef3760f0a628e44823a6f9 GIT binary patch literal 824 zcmY#jfB*@G90nE!4+a$=H-NzfNJap00)qsQOlGO` z@E;1qG%JNbd?6W8<|&LI76Zd_CI$u;QR|r;pKGii6)Y)`nSWlz=x@}vsT}h820rG- zuWQ-eGdph@Nic4baYzi^s$u!&>-K$6a}Belwt*C zLrV)|kkP1s3&{0#1bGq!P5^O6Nl8JmmA-y%VoDBBqh7JGUTLvzd1`Tqu9041Zemq_ zUSfH%UUGh}epYdQo<7K2JrE0Q!r&p6FfsxIk-<6YNrG2MqQ#+;o<^T`7TYy^J-VmRU$7#JBCIop(49~W{>xGFo(o$21JxmREQJ+Y?o(xo*QAKpEo^6$vt2_Y)E F1OPU)qy7K@ literal 0 HcmV?d00001 diff --git a/integration_tests/tests/data/accounts/get_asset_by_authority_with_show_fungible/8Xv3SpX94HHf32Apg4TeSeS3i2p6wuXeE8FBZr168Hti b/integration_tests/tests/data/accounts/get_asset_by_authority_with_show_fungible/8Xv3SpX94HHf32Apg4TeSeS3i2p6wuXeE8FBZr168Hti new file mode 100644 index 0000000000000000000000000000000000000000..1470bf74a12e69e60a77de1400c6c7b3974f3b97 GIT binary patch literal 312 zcmY#jfB*@G90nE!4+a$=H-NzfNJap00)qsQ%ztaDbFVke^QO+S9HEuhcs#SZ6V6T8 z_;3DN6VAv9PV?FBetUR5b>ZZjryshVdtJFkW=rea_-ONqRy|)^>;5yW)Bu|CK~^3} zGBEsy0twAZArOD5j41OIMi2|g2I9_}MiPvhWE>I$c3io{x_!C-(ziQXTcg4gHeHud zH+^jN+U4VNv6pXaHQL$Jv=Wzp3RY3t$ELbSxZ~^VHlyXDLVx7%&o}nt=fT4WL>V literal 0 HcmV?d00001 diff --git a/integration_tests/tests/data/accounts/get_asset_by_creator_with_show_fungible/7fXKY9tPpvYsdbSNyesUqo27WYC6ZsBEULdtngGHqLCK b/integration_tests/tests/data/accounts/get_asset_by_creator_with_show_fungible/7fXKY9tPpvYsdbSNyesUqo27WYC6ZsBEULdtngGHqLCK new file mode 100644 index 0000000000000000000000000000000000000000..eee1c6f44f9f406ba88a89b65180507df0639266 GIT binary patch literal 824 zcmY#jfB*@G90nE!4+a$=H-NzfNJap00)qsQOlGO` z@E;0nv?_(b0>8zWr!az949l4q7+6HDXL5Y5v3^vrq(El=c@?9-QQM|+$mbjQm>a*Y zWp~f)ylEuCxJkw#F<{4)ORU?M`!9XFv$ZuUJYmyy8FkagRti9~d=pa?d=gWN6_gDv zEsPVpHI5)pg1`wN&L}Ayig(vx)KFq&) zjZ6$j90LO*10!dfQtRVFt_fFV=eaZ8n>F|9%fBbqG+w&2=HkPZZjryshVdtJFkW=rea_-ONqRy|)^>;5yW)Bu|CK~^3} zGBEsy0voMLArOD*Z!zX6j35?}4aA){jU*U1$v7ki?6`7?b^CJvrEhn(wnl{~Y`QL^ zZu;2jwadrlVlUs;YP7SbX(cZI6s)4Ok4<%vaL3ozZARtgT~MPKK=dqU?$Z(G3kr|O mO` z@E-~+wJL=`{KsF#n5Qs;SPTrynHU&YM6G9Xe6F#6RIsE#X8w5&+NQuB*C~z#vw6a$CXR0+n4(-@H7Yz|({&kj)5lf{K!bb}Qxtp>Q;HRo z4J|E<*CIbx<-15xrtTz zd5Pu4ddc~@`dP*KdHNu8^*}7J34@1N!pH~=LZZjryshVdtJFkW=rea_-ONqRy|)^>;5yW)Bu|CK~^3} zGBEsy0xPXbArL?Ln;7#HMi7gEVJQ%I-ZYY6+$7_W7_j5YCD!fB{g=Mo+1eTvp0Me< zjJoM#tJf|cmy5l8TdUE|o~D(!{8O-s(mpoTMZz6lU$+^Rmv=#pVgS*zoVia&m@gXDLVx7%&o}nt=fTT?1O` literal 0 HcmV?d00001 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 944dea10b..d09af32d6 100644 --- a/integration_tests/tests/integration_tests/show_fungible_flag_tests.rs +++ b/integration_tests/tests/integration_tests/show_fungible_flag_tests.rs @@ -86,7 +86,7 @@ async fn test_get_asset_with_show_fungible_scenario_2() { #[tokio::test] #[serial] #[named] -async fn test_get_asset_by_owner_with_show_fungible_scenario() { +async fn test_get_asset_by_owner_with_show_fungible() { let name = trim_test_name(function_name!()); let setup = TestSetup::new_with_options( name.clone(), @@ -97,9 +97,9 @@ async fn test_get_asset_by_owner_with_show_fungible_scenario() { .await; let seeds: Vec = seed_accounts([ - "7EYnhQoR9YM3N7UoaKRoA44Uy8JeaZV3qyouov87awMs", - "7BajpcYgnxmWK91RhrfsdB3Tm83PcDwPvMC8ZinvtTY6", - "6BRNfDfdq1nKyU1TQiCEQLWyPtD8EwUH9Kt2ahsbidUx", + "AH6wj7T8Ke5nbukjtcobjjs1CDWUcQxndtnLkKAdrSrM", + "7fXKY9tPpvYsdbSNyesUqo27WYC6ZsBEULdtngGHqLCK", + "8Xv3SpX94HHf32Apg4TeSeS3i2p6wuXeE8FBZr168Hti", ]); apply_migrations_and_delete_data(setup.db.clone()).await; @@ -107,7 +107,7 @@ async fn test_get_asset_by_owner_with_show_fungible_scenario() { let request = r#" { - "ownerAddress": "2oerfxddTpK5hWAmCMYB6fr9WvNrjEH54CHCWK8sAq7g", + "ownerAddress": "GqPnSDXwp4JFtKS7YZ2HERgBbYLKpKVYy9TpVunzLRa9", "displayOptions": { "showFungible": true } @@ -119,3 +119,81 @@ async fn test_get_asset_by_owner_with_show_fungible_scenario() { insta::assert_json_snapshot!(name, response); } + +#[tokio::test] +#[serial] +#[named] +async fn test_get_asset_by_authority_with_show_fungible() { + 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([ + "AH6wj7T8Ke5nbukjtcobjjs1CDWUcQxndtnLkKAdrSrM", + "7fXKY9tPpvYsdbSNyesUqo27WYC6ZsBEULdtngGHqLCK", + "8Xv3SpX94HHf32Apg4TeSeS3i2p6wuXeE8FBZr168Hti", + ]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "authorityAddress": "2RtGg6fsFiiF1EQzHqbd66AhW7R5bWeQGpTbv2UMkCdW", + "displayOptions": { + "showFungible": true + } + } + "#; + + let request: api::GetAssetsByAuthority = serde_json::from_str(request).unwrap(); + let response = setup + .das_api + .get_assets_by_authority(request) + .await + .unwrap(); + + insta::assert_json_snapshot!(name, response); +} + +#[tokio::test] +#[serial] +#[named] +async fn test_get_asset_by_creator_with_show_fungible() { + 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([ + "AH6wj7T8Ke5nbukjtcobjjs1CDWUcQxndtnLkKAdrSrM", + "7fXKY9tPpvYsdbSNyesUqo27WYC6ZsBEULdtngGHqLCK", + "8Xv3SpX94HHf32Apg4TeSeS3i2p6wuXeE8FBZr168Hti", + ]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "creatorAddress": "5XvhfmRjwXkGp3jHGmaKpqeerNYjkuZZBYLVQYdeVcRv", + "displayOptions": { + "showFungible": true + } + } + "#; + + let request: api::GetAssetsByCreator = serde_json::from_str(request).unwrap(); + let response = setup.das_api.get_assets_by_creator(request).await.unwrap(); + + insta::assert_json_snapshot!(name, response); +} diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_by_authority_with_show_fungible.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_by_authority_with_show_fungible.snap new file mode 100644 index 000000000..6648a6141 --- /dev/null +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_by_authority_with_show_fungible.snap @@ -0,0 +1,88 @@ +--- +source: integration_tests/tests/integration_tests/show_fungible_flag_tests.rs +expression: response +snapshot_kind: text +--- +{ + "total": 1, + "limit": 1000, + "cursor": "AH6wj7T8Ke5nbukjtcobjjs1CDWUcQxndtnLkKAdrSrM", + "items": [ + { + "interface": "ProgrammableNFT", + "id": "AH6wj7T8Ke5nbukjtcobjjs1CDWUcQxndtnLkKAdrSrM", + "content": { + "$schema": "https://schema.metaplex.com/nft1.0.json", + "json_uri": "https://madlads.s3.us-west-2.amazonaws.com/json/1983.json", + "files": [], + "metadata": { + "name": "Mad Lads #1983", + "symbol": "MAD", + "token_standard": "ProgrammableNonFungible" + }, + "links": {} + }, + "authorities": [ + { + "address": "2RtGg6fsFiiF1EQzHqbd66AhW7R5bWeQGpTbv2UMkCdW", + "scopes": [ + "full" + ] + } + ], + "compression": { + "eligible": false, + "compressed": false, + "data_hash": "", + "creator_hash": "", + "asset_hash": "", + "tree": "", + "seq": 0, + "leaf_id": 0 + }, + "grouping": [ + { + "group_key": "collection", + "group_value": "J1S9H3QjnRtBbbuD4HjPV6RpRhwuk4zKbxsnCHuTgh9w" + } + ], + "royalty": { + "royalty_model": "creators", + "target": null, + "percent": 0.042, + "basis_points": 420, + "primary_sale_happened": true, + "locked": false + }, + "creators": [ + { + "address": "5XvhfmRjwXkGp3jHGmaKpqeerNYjkuZZBYLVQYdeVcRv", + "share": 0, + "verified": true + }, + { + "address": "2RtGg6fsFiiF1EQzHqbd66AhW7R5bWeQGpTbv2UMkCdW", + "share": 100, + "verified": true + } + ], + "ownership": { + "frozen": true, + "delegated": true, + "delegate": "BPB5idZgbA1DG4XEmnKs62AADRZFf3jY7Kr9mpMGyKPi", + "ownership_model": "single", + "owner": "GqPnSDXwp4JFtKS7YZ2HERgBbYLKpKVYy9TpVunzLRa9" + }, + "supply": null, + "mutable": true, + "burnt": false, + "token_info": { + "supply": 1, + "decimals": 0, + "token_program": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", + "mint_authority": "FAzbjKo66M3tKhkKqegmWFaYr93FB74B1ChEBdFyKcip", + "freeze_authority": "FAzbjKo66M3tKhkKqegmWFaYr93FB74B1ChEBdFyKcip" + } + } + ] +} diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_by_creator_with_show_fungible.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_by_creator_with_show_fungible.snap new file mode 100644 index 000000000..6648a6141 --- /dev/null +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_by_creator_with_show_fungible.snap @@ -0,0 +1,88 @@ +--- +source: integration_tests/tests/integration_tests/show_fungible_flag_tests.rs +expression: response +snapshot_kind: text +--- +{ + "total": 1, + "limit": 1000, + "cursor": "AH6wj7T8Ke5nbukjtcobjjs1CDWUcQxndtnLkKAdrSrM", + "items": [ + { + "interface": "ProgrammableNFT", + "id": "AH6wj7T8Ke5nbukjtcobjjs1CDWUcQxndtnLkKAdrSrM", + "content": { + "$schema": "https://schema.metaplex.com/nft1.0.json", + "json_uri": "https://madlads.s3.us-west-2.amazonaws.com/json/1983.json", + "files": [], + "metadata": { + "name": "Mad Lads #1983", + "symbol": "MAD", + "token_standard": "ProgrammableNonFungible" + }, + "links": {} + }, + "authorities": [ + { + "address": "2RtGg6fsFiiF1EQzHqbd66AhW7R5bWeQGpTbv2UMkCdW", + "scopes": [ + "full" + ] + } + ], + "compression": { + "eligible": false, + "compressed": false, + "data_hash": "", + "creator_hash": "", + "asset_hash": "", + "tree": "", + "seq": 0, + "leaf_id": 0 + }, + "grouping": [ + { + "group_key": "collection", + "group_value": "J1S9H3QjnRtBbbuD4HjPV6RpRhwuk4zKbxsnCHuTgh9w" + } + ], + "royalty": { + "royalty_model": "creators", + "target": null, + "percent": 0.042, + "basis_points": 420, + "primary_sale_happened": true, + "locked": false + }, + "creators": [ + { + "address": "5XvhfmRjwXkGp3jHGmaKpqeerNYjkuZZBYLVQYdeVcRv", + "share": 0, + "verified": true + }, + { + "address": "2RtGg6fsFiiF1EQzHqbd66AhW7R5bWeQGpTbv2UMkCdW", + "share": 100, + "verified": true + } + ], + "ownership": { + "frozen": true, + "delegated": true, + "delegate": "BPB5idZgbA1DG4XEmnKs62AADRZFf3jY7Kr9mpMGyKPi", + "ownership_model": "single", + "owner": "GqPnSDXwp4JFtKS7YZ2HERgBbYLKpKVYy9TpVunzLRa9" + }, + "supply": null, + "mutable": true, + "burnt": false, + "token_info": { + "supply": 1, + "decimals": 0, + "token_program": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", + "mint_authority": "FAzbjKo66M3tKhkKqegmWFaYr93FB74B1ChEBdFyKcip", + "freeze_authority": "FAzbjKo66M3tKhkKqegmWFaYr93FB74B1ChEBdFyKcip" + } + } + ] +} diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_by_owner_with_show_fungible.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_by_owner_with_show_fungible.snap new file mode 100644 index 000000000..6648a6141 --- /dev/null +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_by_owner_with_show_fungible.snap @@ -0,0 +1,88 @@ +--- +source: integration_tests/tests/integration_tests/show_fungible_flag_tests.rs +expression: response +snapshot_kind: text +--- +{ + "total": 1, + "limit": 1000, + "cursor": "AH6wj7T8Ke5nbukjtcobjjs1CDWUcQxndtnLkKAdrSrM", + "items": [ + { + "interface": "ProgrammableNFT", + "id": "AH6wj7T8Ke5nbukjtcobjjs1CDWUcQxndtnLkKAdrSrM", + "content": { + "$schema": "https://schema.metaplex.com/nft1.0.json", + "json_uri": "https://madlads.s3.us-west-2.amazonaws.com/json/1983.json", + "files": [], + "metadata": { + "name": "Mad Lads #1983", + "symbol": "MAD", + "token_standard": "ProgrammableNonFungible" + }, + "links": {} + }, + "authorities": [ + { + "address": "2RtGg6fsFiiF1EQzHqbd66AhW7R5bWeQGpTbv2UMkCdW", + "scopes": [ + "full" + ] + } + ], + "compression": { + "eligible": false, + "compressed": false, + "data_hash": "", + "creator_hash": "", + "asset_hash": "", + "tree": "", + "seq": 0, + "leaf_id": 0 + }, + "grouping": [ + { + "group_key": "collection", + "group_value": "J1S9H3QjnRtBbbuD4HjPV6RpRhwuk4zKbxsnCHuTgh9w" + } + ], + "royalty": { + "royalty_model": "creators", + "target": null, + "percent": 0.042, + "basis_points": 420, + "primary_sale_happened": true, + "locked": false + }, + "creators": [ + { + "address": "5XvhfmRjwXkGp3jHGmaKpqeerNYjkuZZBYLVQYdeVcRv", + "share": 0, + "verified": true + }, + { + "address": "2RtGg6fsFiiF1EQzHqbd66AhW7R5bWeQGpTbv2UMkCdW", + "share": 100, + "verified": true + } + ], + "ownership": { + "frozen": true, + "delegated": true, + "delegate": "BPB5idZgbA1DG4XEmnKs62AADRZFf3jY7Kr9mpMGyKPi", + "ownership_model": "single", + "owner": "GqPnSDXwp4JFtKS7YZ2HERgBbYLKpKVYy9TpVunzLRa9" + }, + "supply": null, + "mutable": true, + "burnt": false, + "token_info": { + "supply": 1, + "decimals": 0, + "token_program": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", + "mint_authority": "FAzbjKo66M3tKhkKqegmWFaYr93FB74B1ChEBdFyKcip", + "freeze_authority": "FAzbjKo66M3tKhkKqegmWFaYr93FB74B1ChEBdFyKcip" + } + } + ] +} diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_by_owner_with_show_fungible_scenario.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_by_owner_with_show_fungible_scenario.snap deleted file mode 100644 index 607c278e5..000000000 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_by_owner_with_show_fungible_scenario.snap +++ /dev/null @@ -1,65 +0,0 @@ ---- -source: integration_tests/tests/integration_tests/show_fungible_flag_tests.rs -expression: response -snapshot_kind: text ---- -{ - "total": 1, - "limit": 1000, - "cursor": "7EYnhQoR9YM3N7UoaKRoA44Uy8JeaZV3qyouov87awMs", - "items": [ - { - "interface": "Custom", - "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": "" - }, - "supply": null, - "mutable": true, - "burnt": false - } - ] -} From 66258899a204d9da4b4d84278f31c94c6acf8963 Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Fri, 27 Dec 2024 18:12:24 +0530 Subject: [PATCH 19/20] fix tests --- ...n5oqFMwYA8SgGqWwKq1Hia8aM5gh1DWmHEL34hMqBX | Bin 0 -> 824 bytes .../show_fungible_flag_tests.rs | 5 +++- ...t_asset_with_show_fungible_scenario_4.snap | 22 ++++++++++++++++-- 3 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 integration_tests/tests/data/accounts/get_asset_with_show_fungible_scenario_4/8yn5oqFMwYA8SgGqWwKq1Hia8aM5gh1DWmHEL34hMqBX diff --git a/integration_tests/tests/data/accounts/get_asset_with_show_fungible_scenario_4/8yn5oqFMwYA8SgGqWwKq1Hia8aM5gh1DWmHEL34hMqBX b/integration_tests/tests/data/accounts/get_asset_with_show_fungible_scenario_4/8yn5oqFMwYA8SgGqWwKq1Hia8aM5gh1DWmHEL34hMqBX new file mode 100644 index 0000000000000000000000000000000000000000..4e6e98e0e0e76764d8a813bd4ba3d4e6da966308 GIT binary patch literal 824 zcmY#jfB*@G90nE!4+a$=H-NzfNJap00)qsQEbH}GQ*euK(w0BaE6cpuQ*63=EbqLA zv%34Xmt3Bkv531Mb>riUHLezOgX*(c4xf$Kky9+S;O|z?Z5Q`2|Il>P0GYWZ6i6~K z{D*>=pc)|%pG{DiV+tdP#lWzfiGhLTh!3}OQ^5Vrx3iX;zFYi-BZOJxs; = seed_accounts(["J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn"]); + let seeds: Vec = seed_accounts([ + "J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn", + "8yn5oqFMwYA8SgGqWwKq1Hia8aM5gh1DWmHEL34hMqBX", + ]); apply_migrations_and_delete_data(setup.db.clone()).await; index_seed_events(&setup, seeds.iter().collect_vec()).await; diff --git a/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_with_show_fungible_scenario_4.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_with_show_fungible_scenario_4.snap index c7ef56f97..f2605ec84 100644 --- a/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_with_show_fungible_scenario_4.snap +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__show_fungible_flag_tests__get_asset_with_show_fungible_scenario_4.snap @@ -6,7 +6,25 @@ snapshot_kind: text { "interface": "FungibleToken", "id": "J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn", - "authorities": [], + "content": { + "$schema": "https://schema.metaplex.com/nft1.0.json", + "json_uri": "https://storage.googleapis.com/token-metadata/JitoSOL.json", + "files": [], + "metadata": { + "name": "Jito Staked SOL", + "symbol": "JitoSOL", + "token_standard": "Fungible" + }, + "links": {} + }, + "authorities": [ + { + "address": "EDGARWktv3nDxRYjufjdbZmryqGXceaFPoPpbUzdpqED", + "scopes": [ + "full" + ] + } + ], "compression": { "eligible": false, "compressed": false, @@ -34,7 +52,7 @@ snapshot_kind: text "ownership_model": "token", "owner": "" }, - "mutable": false, + "mutable": true, "burnt": false, "token_info": { "supply": 12434210592536617, From c9f376bbb30acfacb0a1e9aa1b4ae5305b5ef507 Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Wed, 1 Jan 2025 16:33:32 +0530 Subject: [PATCH 20/20] remove showing token_acc data inside asset data --- digital_asset_types/src/dao/scopes/asset.rs | 23 +++------------------ 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/digital_asset_types/src/dao/scopes/asset.rs b/digital_asset_types/src/dao/scopes/asset.rs index cb7bf0323..02b7956c5 100644 --- a/digital_asset_types/src/dao/scopes/asset.rs +++ b/digital_asset_types/src/dao/scopes/asset.rs @@ -4,12 +4,11 @@ use crate::{ asset_authority, asset_creators, asset_data, asset_grouping, cl_audits_v2, extensions::{self, instruction::PascalCase}, sea_orm_active_enums::Instruction, - token_accounts, tokens, Cursor, FullAsset, GroupingSize, Pagination, + tokens, Cursor, FullAsset, GroupingSize, Pagination, }, rpc::{filter::AssetSortDirection, options::Options}, }; use indexmap::IndexMap; -use sea_orm::sea_query::{Expr, IntoCondition}; use sea_orm::{entity::*, query::*, ConnectionTrait, DbErr, Order}; use std::collections::HashMap; @@ -152,30 +151,14 @@ pub async fn get_assets_by_owner( limit: u64, options: &Options, ) -> Result, DbErr> { - let mut joins = Vec::new(); - let mut cond = Condition::all() + let cond = Condition::all() .add(asset::Column::Owner.eq(owner.clone())) .add(asset::Column::Supply.gt(0)); - if options.show_fungible { - cond = Condition::all().add(token_accounts::Column::Owner.eq(owner.clone())); - - 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); - } - get_assets_by_condition( conn, cond, - joins, + vec![], sort_by, sort_direction, pagination,