From 20460a2a119d03140bc9e35ce96b1ea2d6362843 Mon Sep 17 00:00:00 2001 From: Kyle Espinola Date: Wed, 31 Jul 2024 11:15:13 +0200 Subject: [PATCH 1/2] fix: u64 out of range for bigint postgres column type (#201) --- .../src/dao/generated/asset.rs | 2 +- .../src/dao/generated/tokens.rs | 2 +- digital_asset_types/tests/common.rs | 4 +- migration/src/lib.rs | 2 + ...161232_change_supply_columns_to_numeric.rs | 47 +++++++++++++++++++ program_transformers/src/asset_upserts.rs | 5 +- program_transformers/src/bubblegum/db.rs | 5 +- .../src/mpl_core_program/v1_asset.rs | 3 +- program_transformers/src/token/mod.rs | 4 +- .../src/token_metadata/master_edition.rs | 3 +- .../src/token_metadata/v1_asset.rs | 18 +++---- 11 files changed, 74 insertions(+), 21 deletions(-) create mode 100644 migration/src/m20240718_161232_change_supply_columns_to_numeric.rs diff --git a/digital_asset_types/src/dao/generated/asset.rs b/digital_asset_types/src/dao/generated/asset.rs index e4f4ab0ac..f70e0b383 100644 --- a/digital_asset_types/src/dao/generated/asset.rs +++ b/digital_asset_types/src/dao/generated/asset.rs @@ -26,7 +26,7 @@ pub struct Model { pub owner_type: OwnerType, pub delegate: Option>, pub frozen: bool, - pub supply: i64, + pub supply: Decimal, pub supply_mint: Option>, pub compressed: bool, pub compressible: bool, diff --git a/digital_asset_types/src/dao/generated/tokens.rs b/digital_asset_types/src/dao/generated/tokens.rs index 35fcad502..326b8d968 100644 --- a/digital_asset_types/src/dao/generated/tokens.rs +++ b/digital_asset_types/src/dao/generated/tokens.rs @@ -15,7 +15,7 @@ impl EntityName for Entity { #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Serialize, Deserialize)] pub struct Model { pub mint: Vec, - pub supply: i64, + pub supply: Decimal, pub decimals: i32, pub token_program: Vec, pub mint_authority: Option>, diff --git a/digital_asset_types/tests/common.rs b/digital_asset_types/tests/common.rs index f5b4664bc..0dcad71ef 100644 --- a/digital_asset_types/tests/common.rs +++ b/digital_asset_types/tests/common.rs @@ -116,7 +116,7 @@ pub fn create_asset( owner_type: Set(owner_type.clone()), delegate: Set(delegate.clone()), frozen: Set(frozen), - supply: Set(supply), + supply: Set(supply.into()), supply_mint: Set(supply_mint.clone()), compressed: Set(compressed), compressible: Set(compressible), @@ -135,7 +135,7 @@ pub fn create_asset( owner_type, delegate, frozen, - supply, + supply: supply.into(), supply_mint, compressed, compressible, diff --git a/migration/src/lib.rs b/migration/src/lib.rs index 9b4689126..7cee77f5e 100644 --- a/migration/src/lib.rs +++ b/migration/src/lib.rs @@ -42,6 +42,7 @@ mod m20240313_120101_add_mpl_core_plugins_columns; 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; pub mod model; @@ -93,6 +94,7 @@ impl MigratorTrait for Migrator { Box::new(m20240319_120101_add_mpl_core_enum_vals::Migration), 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), ] } } diff --git a/migration/src/m20240718_161232_change_supply_columns_to_numeric.rs b/migration/src/m20240718_161232_change_supply_columns_to_numeric.rs new file mode 100644 index 000000000..e7adc3522 --- /dev/null +++ b/migration/src/m20240718_161232_change_supply_columns_to_numeric.rs @@ -0,0 +1,47 @@ +use crate::model::table::{Asset, Tokens}; +use sea_orm_migration::prelude::*; + +#[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::Supply).decimal_len(20, 0).not_null()) + .to_owned(), + ) + .await?; + manager + .alter_table( + Table::alter() + .table(Tokens::Table) + .modify_column(ColumnDef::new(Tokens::Supply).decimal_len(20, 0).not_null()) + .to_owned(), + ) + .await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .alter_table( + Table::alter() + .table(Asset::Table) + .modify_column(ColumnDef::new(Asset::Supply).big_integer().not_null()) + .to_owned(), + ) + .await?; + + manager + .alter_table( + Table::alter() + .table(Tokens::Table) + .modify_column(ColumnDef::new(Tokens::Supply).big_integer().not_null()) + .to_owned(), + ) + .await + } +} diff --git a/program_transformers/src/asset_upserts.rs b/program_transformers/src/asset_upserts.rs index a82923a9f..5561ff5fd 100644 --- a/program_transformers/src/asset_upserts.rs +++ b/program_transformers/src/asset_upserts.rs @@ -10,6 +10,7 @@ use { TransactionTrait, }, serde_json::value::Value, + sqlx::types::Decimal, }; pub struct AssetTokenAccountColumns { @@ -54,7 +55,7 @@ pub async fn upsert_assets_token_account_columns, - pub supply: u64, + pub supply: Decimal, pub supply_mint: Option>, pub slot_updated_mint_account: u64, } @@ -65,7 +66,7 @@ pub async fn upsert_assets_mint_account_columns Result<(), DbErr> { let active_model = asset::ActiveModel { id: Set(columns.mint), - supply: Set(columns.supply as i64), + supply: Set(columns.supply), supply_mint: Set(columns.supply_mint), slot_updated_mint_account: Set(Some(columns.slot_updated_mint_account as i64)), ..Default::default() diff --git a/program_transformers/src/bubblegum/db.rs b/program_transformers/src/bubblegum/db.rs index 0c0922775..b086c6de8 100644 --- a/program_transformers/src/bubblegum/db.rs +++ b/program_transformers/src/bubblegum/db.rs @@ -11,6 +11,7 @@ use { mpl_bubblegum::types::{Collection, Creator}, sea_orm::{ entity::{ActiveValue, ColumnTrait, EntityTrait}, + prelude::*, query::{JsonValue, QueryFilter, QuerySelect, QueryTrait}, sea_query::query::OnConflict, ConnectionTrait, DbBackend, TransactionTrait, @@ -269,7 +270,7 @@ pub async fn upsert_asset_with_compression_info( id: Vec, compressed: bool, compressible: bool, - supply: i64, + supply: u64, supply_mint: Option>, ) -> ProgramTransformerResult<()> where @@ -279,7 +280,7 @@ where id: ActiveValue::Set(id), compressed: ActiveValue::Set(compressed), compressible: ActiveValue::Set(compressible), - supply: ActiveValue::Set(supply), + supply: ActiveValue::Set(Decimal::from(supply)), supply_mint: ActiveValue::Set(supply_mint), ..Default::default() }; diff --git a/program_transformers/src/mpl_core_program/v1_asset.rs b/program_transformers/src/mpl_core_program/v1_asset.rs index 67145086c..bfebe88e7 100644 --- a/program_transformers/src/mpl_core_program/v1_asset.rs +++ b/program_transformers/src/mpl_core_program/v1_asset.rs @@ -24,6 +24,7 @@ use { heck::ToSnakeCase, sea_orm::{ entity::{ActiveValue, ColumnTrait, EntityTrait}, + prelude::*, query::{JsonValue, QueryFilter, QueryTrait}, sea_query::query::OnConflict, sea_query::Expr, @@ -309,7 +310,7 @@ pub async fn save_v1_asset( ) .await?; - let supply = 1; + let supply = Decimal::from(1); // Note: these need to be separate for Token Metadata but here could be one upsert. upsert_assets_mint_account_columns( diff --git a/program_transformers/src/token/mod.rs b/program_transformers/src/token/mod.rs index 7cb70c4fa..d46360317 100644 --- a/program_transformers/src/token/mod.rs +++ b/program_transformers/src/token/mod.rs @@ -110,7 +110,7 @@ pub async fn handle_token_program_account<'a, 'b>( mint: ActiveValue::Set(account_key.clone()), token_program: ActiveValue::Set(account_owner), slot_updated: ActiveValue::Set(account_info.slot as i64), - supply: ActiveValue::Set(m.supply as i64), + supply: ActiveValue::Set(m.supply.into()), decimals: ActiveValue::Set(m.decimals as i32), close_authority: ActiveValue::Set(None), extension_data: ActiveValue::Set(None), @@ -155,7 +155,7 @@ pub async fn handle_token_program_account<'a, 'b>( AssetMintAccountColumns { mint: account_key.clone(), supply_mint: Some(account_key), - supply: m.supply, + supply: m.supply.into(), slot_updated_mint_account: account_info.slot, }, db, diff --git a/program_transformers/src/token_metadata/master_edition.rs b/program_transformers/src/token_metadata/master_edition.rs index 7f76fa4b0..791368af6 100644 --- a/program_transformers/src/token_metadata/master_edition.rs +++ b/program_transformers/src/token_metadata/master_edition.rs @@ -10,6 +10,7 @@ use { }, sea_orm::{ entity::{ActiveModelTrait, ActiveValue, EntityTrait, RelationTrait}, + prelude::*, query::{JoinType, QuerySelect, QueryTrait}, sea_query::query::OnConflict, ConnectionTrait, DatabaseTransaction, DbBackend, @@ -86,7 +87,7 @@ pub async fn save_master_edition( if let Some((_me, Some(asset))) = master_edition { let mut updatable: asset::ActiveModel = asset.into(); - updatable.supply = ActiveValue::Set(1); + updatable.supply = ActiveValue::Set(Decimal::from(1)); updatable.specification_asset_class = ActiveValue::Set(Some(SpecificationAssetClass::Nft)); updatable.update(txn).await?; } diff --git a/program_transformers/src/token_metadata/v1_asset.rs b/program_transformers/src/token_metadata/v1_asset.rs index 59f4edd42..7c45b68b7 100644 --- a/program_transformers/src/token_metadata/v1_asset.rs +++ b/program_transformers/src/token_metadata/v1_asset.rs @@ -30,13 +30,14 @@ use { sea_query::query::OnConflict, ConnectionTrait, DbBackend, DbErr, TransactionTrait, }, - solana_sdk::{pubkey, pubkey::Pubkey}, + solana_sdk::pubkey, + sqlx::types::Decimal, tracing::warn, }; pub async fn burn_v1_asset( conn: &T, - id: Pubkey, + id: pubkey::Pubkey, slot: u64, ) -> ProgramTransformerResult<()> { let slot_i = slot as i64; @@ -62,7 +63,7 @@ pub async fn burn_v1_asset( } const RETRY_INTERVALS: &[u64] = &[0, 5, 10]; -static WSOL_PUBKEY: Pubkey = pubkey!("So11111111111111111111111111111111111111112"); +static WSOL_PUBKEY: pubkey::Pubkey = pubkey!("So11111111111111111111111111111111111111112"); pub async fn index_and_fetch_mint_data( conn: &T, @@ -84,7 +85,7 @@ pub async fn index_and_fetch_mint_data( AssetMintAccountColumns { mint: mint_pubkey_vec.clone(), supply_mint: Some(token.mint.clone()), - supply: token.supply as u64, + supply: token.supply, slot_updated_mint_account: token.slot_updated as u64, }, conn, @@ -189,13 +190,12 @@ pub async fn save_v1_asset( index_and_fetch_mint_data(conn, mint_pubkey_vec.clone()).await?; // get supply of token, default to 1 since most cases will be NFTs. Token mint ingester will properly set supply if token_result is None - let supply = token.map(|t| t.supply).unwrap_or(1); - + let supply = token.map(|t| t.supply).unwrap_or_else(|| Decimal::from(1)); // Map unknown ownership types based on the supply. if ownership_type == OwnerType::Unknown { - ownership_type = match supply.cmp(&1) { - std::cmp::Ordering::Equal => OwnerType::Single, - std::cmp::Ordering::Greater => OwnerType::Token, + ownership_type = match supply { + s if s == Decimal::from(1) => OwnerType::Single, + s if s > Decimal::from(1) => OwnerType::Token, _ => OwnerType::Unknown, }; }; From 6875b16a3831688f8562f6485a16719cf99b608b Mon Sep 17 00:00:00 2001 From: Michael Danenberg <56533526+danenbm@users.noreply.github.com> Date: Fri, 2 Aug 2024 10:34:41 -0700 Subject: [PATCH 2/2] Update mpl-core crate and indexing for `AppData` external plugin (#202) * Update docker build * Add initial AppData tests * Update mpl-core version * Add LinkedAppData and DataSection tests and results * Transform DataAuthority and LinkedAppData parent key * Update test results * Update to mpl-core beta crate --- Builder.Dockerfile | 2 +- Cargo.lock | 4 +- Cargo.toml | 2 +- Migrator.Dockerfile | 2 +- Proxy.Dockerfile | 2 +- ...qX4RuPCoD9dVKEJ51jykwBwjKh6runcHJSuSHpDPJU | Bin 0 -> 320 bytes ...XrhcVGuyq4HwTarxMCwDEMFtPBY5Nctxrvpvpdpe3g | Bin 0 -> 336 bytes ...Y3t29uxpBotbmKbCsQNjYfML5DBoBshDgB7hpHu3XA | Bin 0 -> 368 bytes ...jK8uvqUuH5YU6ThX6A7gznx2xi8BxshawbuFe1Y5Vr | Bin 0 -> 352 bytes ...qNxe6M6t7PYo1gXrY18hVgDvCpouHSZ6vdDEFbybeA | Bin 0 -> 344 bytes ...XEcqHhF9jPxV9CKB5hjHC2TRo3xprdgk5vJTc9qRaY | Bin 0 -> 336 bytes ...thppJ4z9HnBNbFMLnztXS7seqBptYV1jG8UhxR4vK8 | Bin 0 -> 304 bytes ...Un89GKuSjfYTeCH6GL1Y6CiUYqjvcgZehFGDJbhNeW | Bin 0 -> 272 bytes ...q1PCBy5KgzZfoHu6bnLWQFVmJtKyceP8DqNMhXWUaA | Bin 0 -> 272 bytes .../tests/integration_tests/mpl_core_tests.rs | 265 ++++++++++++++++++ ...nary_data_and_owner_is_data_authority.snap | 82 ++++++ ...nd_update_authority_is_data_authority.snap | 85 ++++++ ...ck_data_and_address_is_data_authority.snap | 85 ++++++ ...et_with_data_section_with_binary_data.snap | 89 ++++++ ...sset_with_data_section_with_json_data.snap | 92 ++++++ ..._with_data_section_with_msg_pack_data.snap | 92 ++++++ ...ry_data_and_address_is_data_authority.snap | 81 ++++++ ...json_data_and_owner_is_data_authority.snap | 81 ++++++ ...nd_update_authority_is_data_authority.snap | 81 ++++++ .../src/mpl_core_program/v1_asset.rs | 54 +++- 25 files changed, 1084 insertions(+), 15 deletions(-) create mode 100644 integration_tests/tests/data/accounts/mpl_core_get_asset_with_app_data_with_binary_data_and_owner_is_data_authority/6tqX4RuPCoD9dVKEJ51jykwBwjKh6runcHJSuSHpDPJU create mode 100644 integration_tests/tests/data/accounts/mpl_core_get_asset_with_app_data_with_json_data_and_update_authority_is_data_authority/39XrhcVGuyq4HwTarxMCwDEMFtPBY5Nctxrvpvpdpe3g create mode 100644 integration_tests/tests/data/accounts/mpl_core_get_asset_with_app_data_with_msg_pack_data_and_address_is_data_authority/2pY3t29uxpBotbmKbCsQNjYfML5DBoBshDgB7hpHu3XA create mode 100644 integration_tests/tests/data/accounts/mpl_core_get_asset_with_data_section_with_binary_data/BVjK8uvqUuH5YU6ThX6A7gznx2xi8BxshawbuFe1Y5Vr create mode 100644 integration_tests/tests/data/accounts/mpl_core_get_asset_with_data_section_with_json_data/9vqNxe6M6t7PYo1gXrY18hVgDvCpouHSZ6vdDEFbybeA create mode 100644 integration_tests/tests/data/accounts/mpl_core_get_asset_with_data_section_with_msg_pack_data/EuXEcqHhF9jPxV9CKB5hjHC2TRo3xprdgk5vJTc9qRaY create mode 100644 integration_tests/tests/data/accounts/mpl_core_get_collection_with_linked_app_data_with_binary_data_and_address_is_data_authority/41thppJ4z9HnBNbFMLnztXS7seqBptYV1jG8UhxR4vK8 create mode 100644 integration_tests/tests/data/accounts/mpl_core_get_collection_with_linked_app_data_with_json_data_and_owner_is_data_authority/2aUn89GKuSjfYTeCH6GL1Y6CiUYqjvcgZehFGDJbhNeW create mode 100644 integration_tests/tests/data/accounts/mpl_core_get_collection_with_linked_app_data_with_msg_pack_data_and_update_authority_is_data_authority/53q1PCBy5KgzZfoHu6bnLWQFVmJtKyceP8DqNMhXWUaA create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_data_section_with_binary_data.snap create mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_data_section_with_json_data.snap create mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_data_section_with_msg_pack_data.snap create mode 100644 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 create mode 100644 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 create mode 100644 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 diff --git a/Builder.Dockerfile b/Builder.Dockerfile index 4ea85b7c9..6b2b4b1bb 100644 --- a/Builder.Dockerfile +++ b/Builder.Dockerfile @@ -1,4 +1,4 @@ -FROM rust:1.75-bullseye AS builder +FROM rust:1.76-bullseye AS builder RUN apt-get update -y && \ apt-get install -y build-essential make git diff --git a/Cargo.lock b/Cargo.lock index c294f301a..f2a48155b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3481,9 +3481,9 @@ dependencies = [ [[package]] name = "mpl-core" -version = "0.7.1" +version = "0.8.0-beta.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cefa4362d05dec8fb97ebebf20fb2dc5224228c8c9550d9da8f2d1b657b49954" +checksum = "1178d8a405352e2a2478abf5b62e2a4d6a91ed6f0470307ab6732614662dbf85" dependencies = [ "base64 0.22.0", "borsh 0.10.3", diff --git a/Cargo.toml b/Cargo.toml index 4d0b859c9..a643f1f99 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -68,7 +68,7 @@ metrics = "0.20.1" migration = {path = "migration"} mime_guess = "2.0.4" mpl-bubblegum = "1.2.0" -mpl-core = {version = "0.7.1", features = ["serde"]} +mpl-core = {version = "0.8.0-beta.1", features = ["serde"]} mpl-token-metadata = "4.1.1" nft_ingester = {path = "nft_ingester"} num-derive = "0.3.3" diff --git a/Migrator.Dockerfile b/Migrator.Dockerfile index d275aa7d6..63c72bc3d 100644 --- a/Migrator.Dockerfile +++ b/Migrator.Dockerfile @@ -1,6 +1,6 @@ FROM das-api/builder AS files -FROM rust:1.75-bullseye +FROM rust:1.76-bullseye COPY init.sql /init.sql ENV INIT_FILE_PATH=/init.sql COPY --from=files /das/migration /bins/migration diff --git a/Proxy.Dockerfile b/Proxy.Dockerfile index 9679a632e..52e35de55 100644 --- a/Proxy.Dockerfile +++ b/Proxy.Dockerfile @@ -1,4 +1,4 @@ -FROM rust:1.75-bullseye AS builder +FROM rust:1.76-bullseye AS builder RUN cargo install wasm-pack RUN mkdir /rust diff --git a/integration_tests/tests/data/accounts/mpl_core_get_asset_with_app_data_with_binary_data_and_owner_is_data_authority/6tqX4RuPCoD9dVKEJ51jykwBwjKh6runcHJSuSHpDPJU b/integration_tests/tests/data/accounts/mpl_core_get_asset_with_app_data_with_binary_data_and_owner_is_data_authority/6tqX4RuPCoD9dVKEJ51jykwBwjKh6runcHJSuSHpDPJU new file mode 100644 index 0000000000000000000000000000000000000000..3e01e588fefdba7e670e58e9de09b874fb868d9c GIT binary patch literal 320 zcmY#jfB*@G90nE!4+a$=H-NzfNJap00)qsQ44?QaQ|*B76oz-7`*O;fHVRl6Dkw+a zc3O2lyR>Wi583r0s|EH>U+T1A-uKNjI`8sap0ec3%lpgDo~+xas~o-DLj!2WgMYH8){3>p#tZK4 ztM>1@HAR52d-DG<))KGMLdSF8=G!jyJaZzjz;D|p<{Bkyy=RVdS8)MN2}vz3QE)6S zPA!oH@-j+F3W}}t^;0Vna|?1(^^)^*^%Fso49x97X%JvyWbjDM$;sDID9r>h*j+yi8$f{!JT zWMKFY1$D){g+Tnnaw2ahFfuS40kRoCP3@nw`drIg?ggAy)%&ZnG~-z-)*2fxxVNv` zzw6c%0mkmh|HD{Iyh;ll&wZP3yVUc{iNFHCZJ(HHl&tlhInG_h1vDijwYWsVvA8(3 zL=wo$C@Co@w$j&6tw_u*$Vt^p&d=3P1W7V5&jU(>0232qwNh?sadBdLs*;tGM`}(^ tzLJhoNn%lYY6(!FJijO>MX8nrq!#E>pn8UK5E}>>s~|K3Bgl^+0072+acBSl literal 0 HcmV?d00001 diff --git a/integration_tests/tests/data/accounts/mpl_core_get_asset_with_app_data_with_msg_pack_data_and_address_is_data_authority/2pY3t29uxpBotbmKbCsQNjYfML5DBoBshDgB7hpHu3XA b/integration_tests/tests/data/accounts/mpl_core_get_asset_with_app_data_with_msg_pack_data_and_address_is_data_authority/2pY3t29uxpBotbmKbCsQNjYfML5DBoBshDgB7hpHu3XA new file mode 100644 index 0000000000000000000000000000000000000000..19a2a13e16b5168cb1c41540c709755c25021e4c GIT binary patch literal 368 zcmY#jfB*@G90nE!4+a$=H-NzfNJap00)qsQl;#va(O|keP4}?lrkvw5Zr*lb?z`jS zo?!8}QTD=Y=eg@cRtxN%zSL>KyziT5bl&B;JY~t5m-m;QJz2L;S2=pQhX&9L27Vh5 z$?zWvBFlCQf%s4CB;HP71hE(x?g265r>XsuR-bE`%e{cps(OEQmS#L_#ad(I1^4z< z`*+=%BEZ-^`F|K|iC1Z%?$GBfm#e3j7M@SH)bK3wV{V!od_dJCoeOA6NNRD3f@5)U zYKbI}mr+tuP;8~IpIVWaTac5gmzSt)+N~c+p~kgBQ+-{Uq_)lzbGd~kp-j+UyJ*b-Qp)5%+vYw)@iT7 zlXmu2U&&*qS%lYztQOcieW}xedEYnB=)B8wdCHPAFYhlqd$Mkyu5$Ep4-Jr+>6So} zf#E+CFdW$}1mb`H*ztA(BZ$Soa1@9cKTYkQwEA4jT+Rz739@>-+C(dYE0AxXypYXD*;AA*sbB3Xa9a zsU?y?UPehtL9vy-eriQxZb43}UUGh}ej-Scfq6bq8U$Dw85ygUa#M?o6Vp?btdu-b vb8_;Pbd*XGi_%j|fCATutZ{Jd literal 0 HcmV?d00001 diff --git a/integration_tests/tests/data/accounts/mpl_core_get_asset_with_data_section_with_msg_pack_data/EuXEcqHhF9jPxV9CKB5hjHC2TRo3xprdgk5vJTc9qRaY b/integration_tests/tests/data/accounts/mpl_core_get_asset_with_data_section_with_msg_pack_data/EuXEcqHhF9jPxV9CKB5hjHC2TRo3xprdgk5vJTc9qRaY new file mode 100644 index 0000000000000000000000000000000000000000..f2168012e9022d120731a85dba6130a5307403a5 GIT binary patch literal 336 zcmY#jfB*@G90nE!4+a$=H-NzfNJap00)qsQJU1tBTIjWTW~VBCf4nQ)Ab93)@x1cT zpGnP*d$zl8mA$z>WVOKF=}Vm!%=^B1M(16g%Ttz|d3k@?*^_nqbd{r*duRa7FgRiX zBpDd~L&5#yyM;jfkjZ^-CoqCo3=I2$nDNup{zOrBZcPzjve7U&;r?Vz=_~6k8}{GZAQn+y{X0DseR7XSbN literal 0 HcmV?d00001 diff --git a/integration_tests/tests/data/accounts/mpl_core_get_collection_with_linked_app_data_with_binary_data_and_address_is_data_authority/41thppJ4z9HnBNbFMLnztXS7seqBptYV1jG8UhxR4vK8 b/integration_tests/tests/data/accounts/mpl_core_get_collection_with_linked_app_data_with_binary_data_and_address_is_data_authority/41thppJ4z9HnBNbFMLnztXS7seqBptYV1jG8UhxR4vK8 new file mode 100644 index 0000000000000000000000000000000000000000..99cc761260bad6b24cd567e27cb381f0280755a7 GIT binary patch literal 304 zcmY#jfB*@G90nE!4+a$=H-NzfNJap00)qsQ)H&OFq*J$2 zWcUvSKlkhw0`VjE*1es;2x2iXEC6EG?#chdSWCQ03mwmWn{T_+^UR6B0>5pam}``* z^`1G-UBwSn6p~t8qTrmLlarcUl9`_eGC8B9q@dVJUq7`XF}ENmRWCU|S3eo90%QRQ zGj{5pam}``* z^`1G-UBwSn6p~t8qTrmLlarcUl9`_;2NcREDJdwn($`O|NX#wBN!3fv&(%+cs{mO5 Z!pvDf0t8r?m{>qGNRWkzAsxg90{|UjR8Rl_ literal 0 HcmV?d00001 diff --git a/integration_tests/tests/integration_tests/mpl_core_tests.rs b/integration_tests/tests/integration_tests/mpl_core_tests.rs index 5affe048a..547f28b47 100644 --- a/integration_tests/tests/integration_tests/mpl_core_tests.rs +++ b/integration_tests/tests/integration_tests/mpl_core_tests.rs @@ -573,3 +573,268 @@ async fn test_mpl_core_verified_creators_plugin_with_signature() { let response = setup.das_api.get_asset(request).await.unwrap(); insta::assert_json_snapshot!(name, response); } + +#[tokio::test] +#[serial] +#[named] +async fn test_mpl_core_get_asset_with_app_data_with_binary_data_and_owner_is_data_authority() { + 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(["6tqX4RuPCoD9dVKEJ51jykwBwjKh6runcHJSuSHpDPJU"]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "id": "6tqX4RuPCoD9dVKEJ51jykwBwjKh6runcHJSuSHpDPJU" + } + "#; + + 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_mpl_core_get_asset_with_app_data_with_json_data_and_update_authority_is_data_authority( +) { + 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(["39XrhcVGuyq4HwTarxMCwDEMFtPBY5Nctxrvpvpdpe3g"]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "id": "39XrhcVGuyq4HwTarxMCwDEMFtPBY5Nctxrvpvpdpe3g" + } + "#; + + 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_mpl_core_get_asset_with_app_data_with_msg_pack_data_and_address_is_data_authority() { + 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(["2pY3t29uxpBotbmKbCsQNjYfML5DBoBshDgB7hpHu3XA"]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "id": "2pY3t29uxpBotbmKbCsQNjYfML5DBoBshDgB7hpHu3XA" + } + "#; + + 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_mpl_core_get_collection_with_linked_app_data_with_binary_data_and_address_is_data_authority( +) { + 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(["41thppJ4z9HnBNbFMLnztXS7seqBptYV1jG8UhxR4vK8"]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "id": "41thppJ4z9HnBNbFMLnztXS7seqBptYV1jG8UhxR4vK8" + } + "#; + + 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_mpl_core_get_asset_with_data_section_with_binary_data() { + 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(["BVjK8uvqUuH5YU6ThX6A7gznx2xi8BxshawbuFe1Y5Vr"]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "id": "BVjK8uvqUuH5YU6ThX6A7gznx2xi8BxshawbuFe1Y5Vr" + } + "#; + + 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_mpl_core_get_collection_with_linked_app_data_with_json_data_and_owner_is_data_authority( +) { + 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(["2aUn89GKuSjfYTeCH6GL1Y6CiUYqjvcgZehFGDJbhNeW"]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "id": "2aUn89GKuSjfYTeCH6GL1Y6CiUYqjvcgZehFGDJbhNeW" + } + "#; + + 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_mpl_core_get_asset_with_data_section_with_json_data() { + 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(["9vqNxe6M6t7PYo1gXrY18hVgDvCpouHSZ6vdDEFbybeA"]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "id": "9vqNxe6M6t7PYo1gXrY18hVgDvCpouHSZ6vdDEFbybeA" + } + "#; + + 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_mpl_core_get_collection_with_linked_app_data_with_msg_pack_data_and_update_authority_is_data_authority( +) { + 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(["53q1PCBy5KgzZfoHu6bnLWQFVmJtKyceP8DqNMhXWUaA"]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "id": "53q1PCBy5KgzZfoHu6bnLWQFVmJtKyceP8DqNMhXWUaA" + } + "#; + + 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_mpl_core_get_asset_with_data_section_with_msg_pack_data() { + 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(["EuXEcqHhF9jPxV9CKB5hjHC2TRo3xprdgk5vJTc9qRaY"]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "id": "EuXEcqHhF9jPxV9CKB5hjHC2TRo3xprdgk5vJTc9qRaY" + } + "#; + + 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__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 new file mode 100644 index 000000000..b0d613582 --- /dev/null +++ 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 @@ -0,0 +1,82 @@ +--- +source: integration_tests/tests/integration_tests/mpl_core_tests.rs +assertion_line: 603 +expression: response +--- +{ + "interface": "MplCoreAsset", + "id": "6tqX4RuPCoD9dVKEJ51jykwBwjKh6runcHJSuSHpDPJU", + "content": { + "$schema": "https://schema.metaplex.com/nft1.0.json", + "json_uri": "https://example.com/asset", + "files": [], + "metadata": { + "name": "Test Asset", + "symbol": "" + }, + "links": {} + }, + "authorities": [ + { + "address": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7", + "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": "single", + "owner": "HKwwF4sPVYFPgqEgxth4GZRZjJ9o4E3wA8eu2QM5Vt3H" + }, + "supply": null, + "mutable": true, + "burnt": false, + "plugins": {}, + "mpl_core_info": { + "plugins_json_version": 1 + }, + "external_plugins": [ + { + "data": "SGVsbG8sIHdvcmxkIQ==", + "type": "AppData", + "index": 0, + "offset": 119, + "data_len": 13, + "authority": { + "type": "UpdateAuthority", + "address": null + }, + "data_offset": 122, + "adapter_config": { + "schema": "Binary", + "data_authority": { + "type": "Owner", + "address": null + } + } + } + ] +} 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 new file mode 100644 index 000000000..ba7f6bca3 --- /dev/null +++ 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 @@ -0,0 +1,85 @@ +--- +source: integration_tests/tests/integration_tests/mpl_core_tests.rs +assertion_line: 633 +expression: response +--- +{ + "interface": "MplCoreAsset", + "id": "39XrhcVGuyq4HwTarxMCwDEMFtPBY5Nctxrvpvpdpe3g", + "content": { + "$schema": "https://schema.metaplex.com/nft1.0.json", + "json_uri": "https://example.com/asset", + "files": [], + "metadata": { + "name": "Test Asset", + "symbol": "" + }, + "links": {} + }, + "authorities": [ + { + "address": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7", + "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": "single", + "owner": "HKwwF4sPVYFPgqEgxth4GZRZjJ9o4E3wA8eu2QM5Vt3H" + }, + "supply": null, + "mutable": true, + "burnt": false, + "plugins": {}, + "mpl_core_info": { + "plugins_json_version": 1 + }, + "external_plugins": [ + { + "data": { + "target": "world", + "message": "Hello" + }, + "type": "AppData", + "index": 0, + "offset": 119, + "data_len": 36, + "authority": { + "type": "UpdateAuthority", + "address": null + }, + "data_offset": 122, + "adapter_config": { + "schema": "Json", + "data_authority": { + "type": "UpdateAuthority", + "address": null + } + } + } + ] +} 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 new file mode 100644 index 000000000..2031b1797 --- /dev/null +++ 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 @@ -0,0 +1,85 @@ +--- +source: integration_tests/tests/integration_tests/mpl_core_tests.rs +assertion_line: 662 +expression: response +--- +{ + "interface": "MplCoreAsset", + "id": "2pY3t29uxpBotbmKbCsQNjYfML5DBoBshDgB7hpHu3XA", + "content": { + "$schema": "https://schema.metaplex.com/nft1.0.json", + "json_uri": "https://example.com/asset", + "files": [], + "metadata": { + "name": "Test Asset", + "symbol": "" + }, + "links": {} + }, + "authorities": [ + { + "address": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7", + "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": "single", + "owner": "HKwwF4sPVYFPgqEgxth4GZRZjJ9o4E3wA8eu2QM5Vt3H" + }, + "supply": null, + "mutable": true, + "burnt": false, + "plugins": {}, + "mpl_core_info": { + "plugins_json_version": 1 + }, + "external_plugins": [ + { + "data": { + "target": "msgpack", + "message": "Hello" + }, + "type": "AppData", + "index": 0, + "offset": 119, + "data_len": 30, + "authority": { + "type": "UpdateAuthority", + "address": null + }, + "data_offset": 154, + "adapter_config": { + "schema": "MsgPack", + "data_authority": { + "type": "Address", + "address": "CYHj4vYrPnuQ1pyqrjeRBJJ4QA4LfyoFaaRgSow16Ziw" + } + } + } + ] +} 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 new file mode 100644 index 000000000..85e72340b --- /dev/null +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_data_section_with_binary_data.snap @@ -0,0 +1,89 @@ +--- +source: integration_tests/tests/integration_tests/mpl_core_tests.rs +assertion_line: 721 +expression: response +--- +{ + "interface": "MplCoreAsset", + "id": "BVjK8uvqUuH5YU6ThX6A7gznx2xi8BxshawbuFe1Y5Vr", + "content": { + "$schema": "https://schema.metaplex.com/nft1.0.json", + "json_uri": "https://example.com/asset", + "files": [], + "metadata": { + "name": "Test Asset", + "symbol": "" + }, + "links": {} + }, + "authorities": [ + { + "address": "", + "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": "41thppJ4z9HnBNbFMLnztXS7seqBptYV1jG8UhxR4vK8" + } + ], + "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": "single", + "owner": "HKwwF4sPVYFPgqEgxth4GZRZjJ9o4E3wA8eu2QM5Vt3H" + }, + "supply": null, + "mutable": true, + "burnt": false, + "plugins": {}, + "mpl_core_info": { + "plugins_json_version": 1 + }, + "external_plugins": [ + { + "data": "SGVsbG8sIHdvcmxkIQ==", + "type": "DataSection", + "index": 0, + "offset": 119, + "data_len": 13, + "authority": { + "type": "None", + "address": null + }, + "data_offset": 155, + "adapter_config": { + "schema": "Binary", + "parent_key": { + "linked_app_data": { + "type": "Address", + "address": "CYHj4vYrPnuQ1pyqrjeRBJJ4QA4LfyoFaaRgSow16Ziw" + } + } + } + } + ] +} 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 new file mode 100644 index 000000000..9524d637f --- /dev/null +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_data_section_with_json_data.snap @@ -0,0 +1,92 @@ +--- +source: integration_tests/tests/integration_tests/mpl_core_tests.rs +assertion_line: 780 +expression: response +--- +{ + "interface": "MplCoreAsset", + "id": "9vqNxe6M6t7PYo1gXrY18hVgDvCpouHSZ6vdDEFbybeA", + "content": { + "$schema": "https://schema.metaplex.com/nft1.0.json", + "json_uri": "https://example.com/asset", + "files": [], + "metadata": { + "name": "Test Asset", + "symbol": "" + }, + "links": {} + }, + "authorities": [ + { + "address": "", + "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": "2aUn89GKuSjfYTeCH6GL1Y6CiUYqjvcgZehFGDJbhNeW" + } + ], + "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": "single", + "owner": "HKwwF4sPVYFPgqEgxth4GZRZjJ9o4E3wA8eu2QM5Vt3H" + }, + "supply": null, + "mutable": true, + "burnt": false, + "plugins": {}, + "mpl_core_info": { + "plugins_json_version": 1 + }, + "external_plugins": [ + { + "data": { + "target": "world", + "message": "Hello" + }, + "type": "DataSection", + "index": 0, + "offset": 119, + "data_len": 36, + "authority": { + "type": "None", + "address": null + }, + "data_offset": 123, + "adapter_config": { + "schema": "Json", + "parent_key": { + "linked_app_data": { + "type": "Owner", + "address": null + } + } + } + } + ] +} 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 new file mode 100644 index 000000000..840e75768 --- /dev/null +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_data_section_with_msg_pack_data.snap @@ -0,0 +1,92 @@ +--- +source: integration_tests/tests/integration_tests/mpl_core_tests.rs +assertion_line: 839 +expression: response +--- +{ + "interface": "MplCoreAsset", + "id": "EuXEcqHhF9jPxV9CKB5hjHC2TRo3xprdgk5vJTc9qRaY", + "content": { + "$schema": "https://schema.metaplex.com/nft1.0.json", + "json_uri": "https://example.com/asset", + "files": [], + "metadata": { + "name": "Test Asset", + "symbol": "" + }, + "links": {} + }, + "authorities": [ + { + "address": "", + "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": "53q1PCBy5KgzZfoHu6bnLWQFVmJtKyceP8DqNMhXWUaA" + } + ], + "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": "single", + "owner": "HKwwF4sPVYFPgqEgxth4GZRZjJ9o4E3wA8eu2QM5Vt3H" + }, + "supply": null, + "mutable": true, + "burnt": false, + "plugins": {}, + "mpl_core_info": { + "plugins_json_version": 1 + }, + "external_plugins": [ + { + "data": { + "target": "msgpack", + "message": "Hello" + }, + "type": "DataSection", + "index": 0, + "offset": 119, + "data_len": 30, + "authority": { + "type": "None", + "address": null + }, + "data_offset": 123, + "adapter_config": { + "schema": "MsgPack", + "parent_key": { + "linked_app_data": { + "type": "UpdateAuthority", + "address": null + } + } + } + } + ] +} 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 new file mode 100644 index 000000000..38d0e3771 --- /dev/null +++ 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 @@ -0,0 +1,81 @@ +--- +source: integration_tests/tests/integration_tests/mpl_core_tests.rs +assertion_line: 692 +expression: response +--- +{ + "interface": "MplCoreCollection", + "id": "41thppJ4z9HnBNbFMLnztXS7seqBptYV1jG8UhxR4vK8", + "content": { + "$schema": "https://schema.metaplex.com/nft1.0.json", + "json_uri": "https://example.com/collection", + "files": [], + "metadata": { + "name": "Test Collection", + "symbol": "" + }, + "links": {} + }, + "authorities": [ + { + "address": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7", + "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": "single", + "owner": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7" + }, + "supply": null, + "mutable": true, + "burnt": false, + "plugins": {}, + "mpl_core_info": { + "num_minted": 1, + "current_size": 1, + "plugins_json_version": 1 + }, + "external_plugins": [ + { + "type": "LinkedAppData", + "index": 0, + "offset": 103, + "authority": { + "type": "UpdateAuthority", + "address": null + }, + "adapter_config": { + "schema": "Binary", + "data_authority": { + "type": "Address", + "address": "CYHj4vYrPnuQ1pyqrjeRBJJ4QA4LfyoFaaRgSow16Ziw" + } + } + } + ] +} 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 new file mode 100644 index 000000000..b7ef57f77 --- /dev/null +++ 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 @@ -0,0 +1,81 @@ +--- +source: integration_tests/tests/integration_tests/mpl_core_tests.rs +assertion_line: 751 +expression: response +--- +{ + "interface": "MplCoreCollection", + "id": "2aUn89GKuSjfYTeCH6GL1Y6CiUYqjvcgZehFGDJbhNeW", + "content": { + "$schema": "https://schema.metaplex.com/nft1.0.json", + "json_uri": "https://example.com/collection", + "files": [], + "metadata": { + "name": "Test Collection", + "symbol": "" + }, + "links": {} + }, + "authorities": [ + { + "address": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7", + "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": "single", + "owner": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7" + }, + "supply": null, + "mutable": true, + "burnt": false, + "plugins": {}, + "mpl_core_info": { + "num_minted": 1, + "current_size": 1, + "plugins_json_version": 1 + }, + "external_plugins": [ + { + "type": "LinkedAppData", + "index": 0, + "offset": 103, + "authority": { + "type": "UpdateAuthority", + "address": null + }, + "adapter_config": { + "schema": "Json", + "data_authority": { + "type": "Owner", + "address": null + } + } + } + ] +} 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 new file mode 100644 index 000000000..ff0cfbdbf --- /dev/null +++ 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 @@ -0,0 +1,81 @@ +--- +source: integration_tests/tests/integration_tests/mpl_core_tests.rs +assertion_line: 810 +expression: response +--- +{ + "interface": "MplCoreCollection", + "id": "53q1PCBy5KgzZfoHu6bnLWQFVmJtKyceP8DqNMhXWUaA", + "content": { + "$schema": "https://schema.metaplex.com/nft1.0.json", + "json_uri": "https://example.com/collection", + "files": [], + "metadata": { + "name": "Test Collection", + "symbol": "" + }, + "links": {} + }, + "authorities": [ + { + "address": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7", + "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": "single", + "owner": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7" + }, + "supply": null, + "mutable": true, + "burnt": false, + "plugins": {}, + "mpl_core_info": { + "num_minted": 1, + "current_size": 1, + "plugins_json_version": 1 + }, + "external_plugins": [ + { + "type": "LinkedAppData", + "index": 0, + "offset": 103, + "authority": { + "type": "UpdateAuthority", + "address": null + }, + "adapter_config": { + "schema": "MsgPack", + "data_authority": { + "type": "UpdateAuthority", + "address": null + } + } + } + ] +} diff --git a/program_transformers/src/mpl_core_program/v1_asset.rs b/program_transformers/src/mpl_core_program/v1_asset.rs index bfebe88e7..42e449286 100644 --- a/program_transformers/src/mpl_core_program/v1_asset.rs +++ b/program_transformers/src/mpl_core_program/v1_asset.rs @@ -520,6 +520,8 @@ fn transform_plugins_authority(plugins_json: &mut Value) { for (_, plugin) in plugins.iter_mut() { if let Some(plugin_obj) = plugin.as_object_mut() { transform_authority_in_object(plugin_obj); + transform_data_authority_in_object(plugin_obj); + transform_linked_app_data_parent_key_in_object(plugin_obj); } } } @@ -528,6 +530,8 @@ fn transform_plugins_authority(plugins_json: &mut Value) { for plugin in plugins_array.iter_mut() { if let Some(plugin_obj) = plugin.as_object_mut() { transform_authority_in_object(plugin_obj); + transform_data_authority_in_object(plugin_obj); + transform_linked_app_data_parent_key_in_object(plugin_obj); } } } @@ -535,26 +539,58 @@ fn transform_plugins_authority(plugins_json: &mut Value) { } } -// Helper for `transform_plugins_authority` logic. fn transform_authority_in_object(plugin: &mut Map) { - match plugin.get_mut("authority") { - Some(Value::Object(authority)) => { - if let Some(authority_type) = authority.keys().next().cloned() { + if let Some(authority) = plugin.get_mut("authority") { + transform_authority(authority); + } +} + +fn transform_data_authority_in_object(plugin: &mut Map) { + if let Some(adapter_config) = plugin.get_mut("adapter_config") { + if let Some(data_authority) = adapter_config + .as_object_mut() + .and_then(|o| o.get_mut("data_authority")) + { + transform_authority(data_authority); + } + } +} + +fn transform_linked_app_data_parent_key_in_object(plugin: &mut Map) { + if let Some(adapter_config) = plugin.get_mut("adapter_config") { + if let Some(parent_key) = adapter_config + .as_object_mut() + .and_then(|o| o.get_mut("parent_key")) + { + if let Some(linked_app_data) = parent_key + .as_object_mut() + .and_then(|o| o.get_mut("LinkedAppData")) + { + transform_authority(linked_app_data); + } + } + } +} + +fn transform_authority(authority: &mut Value) { + match authority { + Value::Object(authority_obj) => { + if let Some(authority_type) = authority_obj.keys().next().cloned() { // Replace the nested JSON objects with desired format. - if let Some(Value::Object(pubkey_obj)) = authority.remove(&authority_type) { + if let Some(Value::Object(pubkey_obj)) = authority_obj.remove(&authority_type) { if let Some(address_value) = pubkey_obj.get("address") { - authority.insert("type".to_string(), Value::from(authority_type)); - authority.insert("address".to_string(), address_value.clone()); + authority_obj.insert("type".to_string(), Value::from(authority_type)); + authority_obj.insert("address".to_string(), address_value.clone()); } } } } - Some(Value::String(authority_type)) => { + Value::String(authority_type) => { // Handle the case where authority is a string. let mut authority_obj = Map::new(); authority_obj.insert("type".to_string(), Value::String(authority_type.clone())); authority_obj.insert("address".to_string(), Value::Null); - plugin.insert("authority".to_string(), Value::Object(authority_obj)); + *authority = Value::Object(authority_obj); } _ => {} }