From 7c94c94c0c5d9574b9f1c4148399ad308a8716b3 Mon Sep 17 00:00:00 2001 From: Michael Danenberg <56533526+danenbm@users.noreply.github.com> Date: Tue, 28 May 2024 13:39:29 -0700 Subject: [PATCH] Add mpl-core external plugins (#194) * Add migration for mpl-core external plugins db columns * Regenerate SeaORM types * Add code to index mpl-core external plugins * Add external plugins to DAS API response * Remove extra nested JSON for ext plugins * Add mpl-core oracle (external plugin) test * Update test with asset that contains two Oracles * Update code that removes nesting to work with array * Update integ test results * Add more oracle tests * Add test with multiple internal and external plugins * Update mpl-core Rust client --- Cargo.lock | 146 ++++++++---- Cargo.toml | 2 +- .../src/dao/extensions/asset.rs | 2 + .../src/dao/generated/asset.rs | 6 + digital_asset_types/src/dapi/common/asset.rs | 2 + digital_asset_types/src/rpc/asset.rs | 4 + digital_asset_types/tests/common.rs | 2 + ...7KSaeRECbjLW7BYTUtMwGkaiAGhxrQxdLnpLYRnmbB | Bin 0 -> 504 bytes ...2H5sDBXKmYkGHebfaWwdgBWuMTBVWQom3QeEcV8oJj | Bin 0 -> 336 bytes ...dg2FjMEndC4jxF2MJgKCaj5omLLZ19LNfD4p9oXkpE | Bin 0 -> 312 bytes ...uHPHUHFXxhS7qPQa5YYTngzPbetoWbu7y2UxxB6xrF | Bin 0 -> 336 bytes ...ZpUiBiyMdwLFTKRshVMHK8anQK2W8XXbfUfyxR8yvc | Bin 0 -> 328 bytes ...arnaiMVtGEp5nToRqBEUGtqY2F1gW2V8bBQe1rN5V9 | Bin 0 -> 384 bytes ...JDcrzxSDE7FeNRzMK1aSia7qoaUPrrGQ81E7vkQpq4 | Bin 0 -> 400 bytes ...7rVGmVNa9wjsKNyjoa5phqriLER6HCqUQm5zyoTX3f | Bin 0 -> 240 bytes .../tests/integration_tests/mpl_core_tests.rs | 213 ++++++++++++++++++ ...s__mpl_core_tests__mpl_core_get_asset.snap | 3 +- ...ests__mpl_core_get_asset_with_edition.snap | 3 +- ...ultiple_internal_and_external_plugins.snap | 152 +++++++++++++ ...custom_offset_and_base_address_config.snap | 89 ++++++++ ..._oracle_external_plugin_on_collection.snap | 84 +++++++ ...with_oracle_multiple_lifecycle_events.snap | 85 +++++++ ..._core_get_asset_with_oracle_no_offset.snap | 82 +++++++ ...ore_get_asset_with_pubkey_in_rule_set.snap | 3 +- ...sset_with_two_oracle_external_plugins.snap | 101 +++++++++ ...sts__mpl_core_get_assets_by_authority.snap | 6 +- ...e_tests__mpl_core_get_assets_by_group.snap | 9 +- ..._with_oracle_and_custom_pda_all_seeds.snap | 131 +++++++++++ ...e_tests__mpl_core_get_assets_by_owner.snap | 3 +- ...l_core_tests__mpl_core_get_collection.snap | 3 +- migration/src/lib.rs | 2 + ...1_add_mpl_core_external_plugins_columns.rs | 51 +++++ migration/src/model/table.rs | 2 + program_transformers/src/asset_upserts.rs | 14 +- .../src/mpl_core_program/v1_asset.rs | 80 +++++-- .../src/token_metadata/v1_asset.rs | 6 +- 36 files changed, 1202 insertions(+), 84 deletions(-) create mode 100644 integration_tests/tests/data/accounts/mpl_core_get_asset_with_multiple_internal_and_external_plugins/Aw7KSaeRECbjLW7BYTUtMwGkaiAGhxrQxdLnpLYRnmbB create mode 100644 integration_tests/tests/data/accounts/mpl_core_get_asset_with_oracle_custom_offset_and_base_address_config/9v2H5sDBXKmYkGHebfaWwdgBWuMTBVWQom3QeEcV8oJj create mode 100644 integration_tests/tests/data/accounts/mpl_core_get_asset_with_oracle_external_plugin_on_collection/Hvdg2FjMEndC4jxF2MJgKCaj5omLLZ19LNfD4p9oXkpE create mode 100644 integration_tests/tests/data/accounts/mpl_core_get_asset_with_oracle_multiple_lifecycle_events/3puHPHUHFXxhS7qPQa5YYTngzPbetoWbu7y2UxxB6xrF create mode 100644 integration_tests/tests/data/accounts/mpl_core_get_asset_with_oracle_no_offset/2TZpUiBiyMdwLFTKRshVMHK8anQK2W8XXbfUfyxR8yvc create mode 100644 integration_tests/tests/data/accounts/mpl_core_get_asset_with_two_oracle_external_plugins/4aarnaiMVtGEp5nToRqBEUGtqY2F1gW2V8bBQe1rN5V9 create mode 100644 integration_tests/tests/data/accounts/mpl_core_get_assets_by_group_with_oracle_and_custom_pda_all_seeds/CWJDcrzxSDE7FeNRzMK1aSia7qoaUPrrGQ81E7vkQpq4 create mode 100644 integration_tests/tests/data/accounts/mpl_core_get_assets_by_group_with_oracle_and_custom_pda_all_seeds/Do7rVGmVNa9wjsKNyjoa5phqriLER6HCqUQm5zyoTX3f create mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_multiple_internal_and_external_plugins.snap create mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_oracle_custom_offset_and_base_address_config.snap create mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_oracle_external_plugin_on_collection.snap create mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_oracle_multiple_lifecycle_events.snap create mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_oracle_no_offset.snap create mode 100644 integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_two_oracle_external_plugins.snap create mode 100644 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 create mode 100644 migration/src/m20240520_120101_add_mpl_core_external_plugins_columns.rs diff --git a/Cargo.lock b/Cargo.lock index 4c3eef17f..5563779d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -774,7 +774,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -791,7 +791,7 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -1260,7 +1260,7 @@ checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -1419,7 +1419,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -1696,7 +1696,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.10.0", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -1707,7 +1707,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -1971,7 +1971,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -1994,7 +1994,7 @@ checksum = "a6cbae11b3de8fce2a456e8ea3dada226b35fe791f0dc1d360c0941f0bb681f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -2091,7 +2091,7 @@ checksum = "eecf8589574ce9b895052fa12d69af7a233f99e6107f5cb8dd1044f2a17bfdcb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -2417,7 +2417,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -3444,6 +3444,27 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "modular-bitfield" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a53d79ba8304ac1c4f9eb3b9d281f21f7be9d4626f72ce7df4ad8fbde4f38a74" +dependencies = [ + "modular-bitfield-impl", + "static_assertions", +] + +[[package]] +name = "modular-bitfield-impl" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a7d5f7076603ebc68de2dc6a650ec331a062a13abaa346975be747bbfa4b789" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "mpl-bubblegum" version = "1.2.0" @@ -3460,15 +3481,18 @@ dependencies = [ [[package]] name = "mpl-core" -version = "0.5.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5c11b334e9243b0953095358b7f1e9b17b197a1a3ec9f1ece4be340bcb6b6f2" +checksum = "69b314fcf76dc22cc42a02a208231c667d0c533ce140d6ba9985df5a2a50b0aa" dependencies = [ "base64 0.22.0", "borsh 0.10.3", + "modular-bitfield", "num-derive 0.3.3", "num-traits", + "rmp-serde", "serde", + "serde_json", "serde_with 3.6.1", "solana-program", "thiserror", @@ -3645,7 +3669,7 @@ checksum = "cfb77679af88f8b125209d354a202862602672222e7f2313fdd6dc349bad4712" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -3727,7 +3751,7 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -3739,7 +3763,7 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -3825,7 +3849,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -3979,7 +4003,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -4023,7 +4047,7 @@ checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -4223,9 +4247,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" dependencies = [ "unicode-ident", ] @@ -4238,7 +4262,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", "version_check", "yansi", ] @@ -4336,7 +4360,7 @@ checksum = "9e2e25ee72f5b24d773cae88422baddefff7714f97aab68d96fe2b6fc4a28fb2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -4389,9 +4413,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -4769,6 +4793,28 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "rmp" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" +dependencies = [ + "byteorder", + "num-traits", + "paste", +] + +[[package]] +name = "rmp-serde" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db" +dependencies = [ + "byteorder", + "rmp", + "serde", +] + [[package]] name = "rpassword" version = "7.3.1" @@ -5005,7 +5051,7 @@ checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -5237,9 +5283,9 @@ checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0" [[package]] name = "serde" -version = "1.0.188" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" dependencies = [ "serde_derive", ] @@ -5255,13 +5301,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -5345,7 +5391,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -5357,7 +5403,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -5395,7 +5441,7 @@ checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -5727,7 +5773,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -6117,7 +6163,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -6403,7 +6449,7 @@ checksum = "fadbefec4f3c678215ca72bd71862697bb06b41fd77c0088902dd3203354387b" dependencies = [ "quote", "spl-discriminator-syn", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -6415,7 +6461,7 @@ dependencies = [ "proc-macro2", "quote", "sha2 0.10.8", - "syn 2.0.38", + "syn 2.0.66", "thiserror", ] @@ -6474,7 +6520,7 @@ dependencies = [ "proc-macro2", "quote", "sha2 0.10.8", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -6704,6 +6750,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "stretto" version = "0.8.4" @@ -6767,9 +6819,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.38" +version = "2.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" dependencies = [ "proc-macro2", "quote", @@ -6869,7 +6921,7 @@ checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -6983,7 +7035,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -7174,7 +7226,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -7565,7 +7617,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", "wasm-bindgen-shared", ] @@ -7599,7 +7651,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -8015,7 +8067,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] @@ -8035,7 +8087,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.66", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index c3d8a06fc..98d55ecff 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.5.0", features = ["serde"]} +mpl-core = {version = "0.7.0", features = ["serde"]} mpl-token-metadata = "4.1.1" nft_ingester = {path = "nft_ingester"} num-derive = "0.3.3" diff --git a/digital_asset_types/src/dao/extensions/asset.rs b/digital_asset_types/src/dao/extensions/asset.rs index 65d71350c..18525e39e 100644 --- a/digital_asset_types/src/dao/extensions/asset.rs +++ b/digital_asset_types/src/dao/extensions/asset.rs @@ -108,6 +108,8 @@ impl Default for asset::Model { mpl_core_collection_current_size: None, mpl_core_collection_num_minted: None, mpl_core_plugins_json_version: None, + mpl_core_external_plugins: None, + mpl_core_unknown_external_plugins: None, } } } diff --git a/digital_asset_types/src/dao/generated/asset.rs b/digital_asset_types/src/dao/generated/asset.rs index b114df215..e4f4ab0ac 100644 --- a/digital_asset_types/src/dao/generated/asset.rs +++ b/digital_asset_types/src/dao/generated/asset.rs @@ -55,6 +55,8 @@ pub struct Model { pub mpl_core_collection_num_minted: Option, pub mpl_core_collection_current_size: Option, pub mpl_core_plugins_json_version: Option, + pub mpl_core_external_plugins: Option, + pub mpl_core_unknown_external_plugins: Option, } #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] @@ -96,6 +98,8 @@ pub enum Column { MplCoreCollectionNumMinted, MplCoreCollectionCurrentSize, MplCorePluginsJsonVersion, + MplCoreExternalPlugins, + MplCoreUnknownExternalPlugins, } #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] @@ -154,6 +158,8 @@ impl ColumnTrait for Column { Self::MplCoreCollectionNumMinted => ColumnType::Integer.def().null(), Self::MplCoreCollectionCurrentSize => ColumnType::Integer.def().null(), Self::MplCorePluginsJsonVersion => ColumnType::Integer.def().null(), + Self::MplCoreExternalPlugins => ColumnType::JsonBinary.def().null(), + Self::MplCoreUnknownExternalPlugins => 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 202b01032..c9a9dd486 100644 --- a/digital_asset_types/src/dapi/common/asset.rs +++ b/digital_asset_types/src/dapi/common/asset.rs @@ -447,6 +447,8 @@ pub fn asset_to_rpc(asset: FullAsset, options: &Options) -> Result, #[serde(skip_serializing_if = "Option::is_none")] pub mpl_core_info: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub external_plugins: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub unknown_external_plugins: Option, } diff --git a/digital_asset_types/tests/common.rs b/digital_asset_types/tests/common.rs index 083236a29..f5b4664bc 100644 --- a/digital_asset_types/tests/common.rs +++ b/digital_asset_types/tests/common.rs @@ -167,6 +167,8 @@ pub fn create_asset( mpl_core_collection_current_size: None, mpl_core_collection_num_minted: None, mpl_core_plugins_json_version: None, + mpl_core_external_plugins: None, + mpl_core_unknown_external_plugins: None, }, ) } diff --git a/integration_tests/tests/data/accounts/mpl_core_get_asset_with_multiple_internal_and_external_plugins/Aw7KSaeRECbjLW7BYTUtMwGkaiAGhxrQxdLnpLYRnmbB b/integration_tests/tests/data/accounts/mpl_core_get_asset_with_multiple_internal_and_external_plugins/Aw7KSaeRECbjLW7BYTUtMwGkaiAGhxrQxdLnpLYRnmbB new file mode 100644 index 0000000000000000000000000000000000000000..b702505604e7e519fa66082443f6d8a8ea0050f5 GIT binary patch literal 504 zcmY#jfB*@G90nE!4+a$=H-NzfNJap00)qsQoIG{I4ll>= z``xWsr+ZvaeG*$AvRYv8^rcP<=6&Bhqw_A$n@AI4hZRa)qH?%RCZrJiR_1Qz&h`@~$M zWUcqiaqcRD3b=qKg`^gjC^!}urz&LgGm70mZ2X2 literal 0 HcmV?d00001 diff --git a/integration_tests/tests/data/accounts/mpl_core_get_asset_with_oracle_custom_offset_and_base_address_config/9v2H5sDBXKmYkGHebfaWwdgBWuMTBVWQom3QeEcV8oJj b/integration_tests/tests/data/accounts/mpl_core_get_asset_with_oracle_custom_offset_and_base_address_config/9v2H5sDBXKmYkGHebfaWwdgBWuMTBVWQom3QeEcV8oJj new file mode 100644 index 0000000000000000000000000000000000000000..89ef10e90c389dc63b3c977c51550fee0bad1458 GIT binary patch literal 336 zcmY#jfB*@G35k%8d|kj>aV`F|K|iC1Z%FcLfB<2?6r0ON-=jtaG7pImmFfRp4 zg8-w^UBBypPao`?#~!gX{%f8^==7;AES$2^RmrwW&a*BlFtRW(Fd0A;0|N=91%#Ox NK@>Acpd5%H003{}a8dvO literal 0 HcmV?d00001 diff --git a/integration_tests/tests/data/accounts/mpl_core_get_asset_with_oracle_external_plugin_on_collection/Hvdg2FjMEndC4jxF2MJgKCaj5omLLZ19LNfD4p9oXkpE b/integration_tests/tests/data/accounts/mpl_core_get_asset_with_oracle_external_plugin_on_collection/Hvdg2FjMEndC4jxF2MJgKCaj5omLLZ19LNfD4p9oXkpE new file mode 100644 index 0000000000000000000000000000000000000000..41eb31b3622f7c991c44d30c24b09dedcda5a19b GIT binary patch literal 312 zcmY#jfB*@G3LPll@iDgXoK zE+~W1+<3_p{q;&LmUbc&?&MwP`WP-9I>T4>&0Pa6`2zJ9+zgB?Af-T8F)%VQf+!}C JKspe^0RRg1VEX_7 literal 0 HcmV?d00001 diff --git a/integration_tests/tests/data/accounts/mpl_core_get_asset_with_oracle_multiple_lifecycle_events/3puHPHUHFXxhS7qPQa5YYTngzPbetoWbu7y2UxxB6xrF b/integration_tests/tests/data/accounts/mpl_core_get_asset_with_oracle_multiple_lifecycle_events/3puHPHUHFXxhS7qPQa5YYTngzPbetoWbu7y2UxxB6xrF new file mode 100644 index 0000000000000000000000000000000000000000..9c0e136de0e6eaf2f81b1c120ce3fcd7f6e3b491 GIT binary patch literal 336 zcmY#jfB*@G90nE!4+a$=H-NzfNJap00)qsQ)ckXDlg`rAPt%@t{m1 zr~ECfhr>h*j+(QFs2E$4V z5XtZ#3ak&m5CriTvj3jb&j?~MFzf?j#_q}g!&pnaN(&v&eVcE))bq@VzyiN*pO|Zu zto5Eb&Rs=N0TXaO2J^CpJd^Z7X@b&EVe3^!YOyy%`u;!0JG1nHZTsY>)t0 Jv>e2P0ss^YcEV$ZCPT)0a9enD>42jLy3}m!~W_^YZ?(vnT8J=_*Gr_W+qGplAUk z85sUU0pGnBf*}43BjvgMj0_Arfo#U^$^XMxOT0=89nXE6Z@bj<%!$APzipqGYm}_@ zo;l84MNk13(3FtW;t~bN;^Nd2Ngywyq@vCI3nzuB}w-mct#9Y3vclyQUv5I(+GbM$ffiM#zh++Z>lmjsw F008R2a#H{R literal 0 HcmV?d00001 diff --git a/integration_tests/tests/data/accounts/mpl_core_get_asset_with_two_oracle_external_plugins/4aarnaiMVtGEp5nToRqBEUGtqY2F1gW2V8bBQe1rN5V9 b/integration_tests/tests/data/accounts/mpl_core_get_asset_with_two_oracle_external_plugins/4aarnaiMVtGEp5nToRqBEUGtqY2F1gW2V8bBQe1rN5V9 new file mode 100644 index 0000000000000000000000000000000000000000..cf6ab66c3d485e69b1785ae19e1520ac42a58563 GIT binary patch literal 384 zcmY#jfB*@G3U+T1A-uKNjI`8sap0ec3%lpgDo~+xas~o-D17zj_Jv$)D z!0;amOjbP;1o6LozBaR;k%8e8kj>aV`F|K|iC1Z%FcLfB<2?6r0ON-=jtaG7pImmFz*FQ zg8-v<=zH0%C99aS@?(v!_3g|s541l0j9tP=gPlh~RGI%a10$oa?(>Kh*7kLOT@o+V znbdk_3!K^_pz5ag&>H}dERbrKO>06!0;D{881~IWV?2Qdv?T=_oXcVnrii?&Z{}F_q*7O zz#{FiT@Pk6?UUI$Rqu(mHTUDlL;MC!yS5m=I`L7iT$SrlhLurfFcTNhl#tZo5(UTN z;?xpJATOh&q@dVJUq7`XF}ENmRWCU|S3eOX$-sOMC=CLPMtA+L|2=)MZytNZ()h1= z7NOIpwy?S@Dml-(q`=6^23E(!%<@xe^=Xmd+~;}4R`ySla^8JRaPoC8>f%1; uI`8k_;z=5;LO_*JyL5|FQ&V)4Doav}LAJ1f%>c2O7(t!}3zUNdVE_P*HigF3 zxhmJA3@f9|V5apUs|EH>U+T1A-uKNjI`8sap0ec3%lpgDo~+xas~o-DLj!2Wg301Q zl7Znr6qJ2UriwV1eJZPs}w+ z)_Ttz=dR)hDhf$0E>UpK&&f$mF3HT#lLHE6l#~<{Tj}ekRwU*Y = seed_accounts(["4aarnaiMVtGEp5nToRqBEUGtqY2F1gW2V8bBQe1rN5V9"]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "id": "4aarnaiMVtGEp5nToRqBEUGtqY2F1gW2V8bBQe1rN5V9" + } + "#; + + 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_oracle_external_plugin_on_collection() { + 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(["Hvdg2FjMEndC4jxF2MJgKCaj5omLLZ19LNfD4p9oXkpE"]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "id": "Hvdg2FjMEndC4jxF2MJgKCaj5omLLZ19LNfD4p9oXkpE" + } + "#; + + 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_oracle_multiple_lifecycle_events() { + 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(["3puHPHUHFXxhS7qPQa5YYTngzPbetoWbu7y2UxxB6xrF"]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "id": "3puHPHUHFXxhS7qPQa5YYTngzPbetoWbu7y2UxxB6xrF" + } + "#; + + 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_oracle_custom_offset_and_base_address_config() { + 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(["9v2H5sDBXKmYkGHebfaWwdgBWuMTBVWQom3QeEcV8oJj"]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "id": "9v2H5sDBXKmYkGHebfaWwdgBWuMTBVWQom3QeEcV8oJj" + } + "#; + + 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_oracle_no_offset() { + 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(["2TZpUiBiyMdwLFTKRshVMHK8anQK2W8XXbfUfyxR8yvc"]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "id": "2TZpUiBiyMdwLFTKRshVMHK8anQK2W8XXbfUfyxR8yvc" + } + "#; + + 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_assets_by_group_with_oracle_and_custom_pda_all_seeds() { + 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([ + "Do7rVGmVNa9wjsKNyjoa5phqriLER6HCqUQm5zyoTX3f", + "CWJDcrzxSDE7FeNRzMK1aSia7qoaUPrrGQ81E7vkQpq4", + ]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "groupKey": "collection", + "groupValue": "Do7rVGmVNa9wjsKNyjoa5phqriLER6HCqUQm5zyoTX3f", + "sortBy": { + "sortBy": "updated", + "sortDirection": "asc" + }, + "page": 1, + "limit": 50 + } + "#; + + let request: api::GetAssetsByGroup = serde_json::from_str(request).unwrap(); + let response = setup.das_api.get_assets_by_group(request).await.unwrap(); + insta::assert_json_snapshot!(name, response); +} + +#[tokio::test] +#[serial] +#[named] +async fn test_mpl_core_get_asset_with_multiple_internal_and_external_plugins() { + 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(["Aw7KSaeRECbjLW7BYTUtMwGkaiAGhxrQxdLnpLYRnmbB"]); + + apply_migrations_and_delete_data(setup.db.clone()).await; + index_seed_events(&setup, seeds.iter().collect_vec()).await; + + let request = r#" + { + "id": "Aw7KSaeRECbjLW7BYTUtMwGkaiAGhxrQxdLnpLYRnmbB" + } + "#; + + 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.snap b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset.snap index a5fd81406..0b9a6039f 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 @@ -107,5 +107,6 @@ expression: response }, "mpl_core_info": { "plugins_json_version": 1 - } + }, + "external_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 e85099bdd..6333a1260 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 @@ -69,5 +69,6 @@ expression: response }, "mpl_core_info": { "plugins_json_version": 1 - } + }, + "external_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 new file mode 100644 index 000000000..60e77e446 --- /dev/null +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_multiple_internal_and_external_plugins.snap @@ -0,0 +1,152 @@ +--- +source: integration_tests/tests/integration_tests/mpl_core_tests.rs +assertion_line: 458 +expression: response +--- +{ + "interface": "MplCoreAsset", + "id": "Aw7KSaeRECbjLW7BYTUtMwGkaiAGhxrQxdLnpLYRnmbB", + "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.0005, + "basis_points": 5, + "primary_sale_happened": false, + "locked": false + }, + "creators": [ + { + "address": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7", + "share": 100, + "verified": true + } + ], + "ownership": { + "frozen": false, + "delegated": true, + "delegate": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7", + "ownership_model": "single", + "owner": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7" + }, + "supply": null, + "mutable": true, + "burnt": false, + "plugins": { + "royalties": { + "data": { + "creators": [ + { + "address": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7", + "percentage": 100 + } + ], + "rule_set": "None", + "basis_points": 5 + }, + "index": 2, + "offset": 155, + "authority": { + "type": "UpdateAuthority", + "address": null + } + }, + "freeze_delegate": { + "data": { + "frozen": false + }, + "index": 4, + "offset": 231, + "authority": { + "type": "Address", + "address": "JDnbeBUv9MaMGg28sGjUjfo7aUwBwHAFQHkvYZGA1aPh" + } + }, + "transfer_delegate": { + "data": {}, + "index": 0, + "offset": 119, + "authority": { + "type": "Owner", + "address": null + } + } + }, + "mpl_core_info": { + "plugins_json_version": 1 + }, + "external_plugins": [ + { + "type": "Oracle", + "index": 1, + "offset": 120, + "authority": { + "type": "UpdateAuthority", + "address": null + }, + "adapter_config": { + "base_address": "4dbE64e2ALgNGMJLRBTei2qjzR5SKApKmvoLnA1aqPZB", + "results_offset": "Anchor", + "base_address_config": null + }, + "lifecycle_checks": { + "create": [ + "CanReject" + ], + "transfer": [ + "CanReject" + ] + } + }, + { + "type": "Oracle", + "index": 3, + "offset": 196, + "authority": { + "type": "UpdateAuthority", + "address": null + }, + "adapter_config": { + "base_address": "8v4xtK8C69wEGhfpGm7LN8dsWBwyEYLamHEYjcKfqdCg", + "results_offset": "Anchor", + "base_address_config": null + }, + "lifecycle_checks": { + "burn": [ + "CanReject" + ], + "update": [ + "CanReject" + ] + } + } + ] +} 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 new file mode 100644 index 000000000..ac19d3d3a --- /dev/null +++ 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 @@ -0,0 +1,89 @@ +--- +source: integration_tests/tests/integration_tests/mpl_core_tests.rs +assertion_line: 361 +expression: response +--- +{ + "interface": "MplCoreAsset", + "id": "9v2H5sDBXKmYkGHebfaWwdgBWuMTBVWQom3QeEcV8oJj", + "content": { + "$schema": "https://schema.metaplex.com/nft1.0.json", + "json_uri": "https://example.com/asset", + "files": [], + "metadata": { + "name": "new name 2", + "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": { + "plugins_json_version": 1 + }, + "external_plugins": [ + { + "type": "Oracle", + "index": 0, + "offset": 119, + "authority": { + "type": "UpdateAuthority", + "address": null + }, + "adapter_config": { + "base_address": "4RZ7RhXeL4oz4kVX5fpRfkNQ3nz1n4eruqBn2AGPQepo", + "results_offset": { + "custom": 48 + }, + "base_address_config": { + "preconfigured_asset": { + "is_signer": false, + "is_writable": false + } + } + }, + "lifecycle_checks": { + "update": [ + "CanReject" + ] + } + } + ] +} 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 new file mode 100644 index 000000000..40802d2a6 --- /dev/null +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_oracle_external_plugin_on_collection.snap @@ -0,0 +1,84 @@ +--- +source: integration_tests/tests/integration_tests/mpl_core_tests.rs +assertion_line: 274 +expression: response +--- +{ + "interface": "MplCoreCollection", + "id": "Hvdg2FjMEndC4jxF2MJgKCaj5omLLZ19LNfD4p9oXkpE", + "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": 0, + "current_size": 0, + "plugins_json_version": 1 + }, + "external_plugins": [ + { + "type": "Oracle", + "index": 0, + "offset": 103, + "authority": { + "type": "UpdateAuthority", + "address": null + }, + "adapter_config": { + "base_address": "4iV6bzDfTrpvfeovNwwKFkdLneb5GWSLv8nz7F3mdHfG", + "results_offset": "Anchor", + "base_address_config": null + }, + "lifecycle_checks": { + "burn": [ + "CanReject" + ] + } + } + ] +} 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 new file mode 100644 index 000000000..f42fdf792 --- /dev/null +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_oracle_multiple_lifecycle_events.snap @@ -0,0 +1,85 @@ +--- +source: integration_tests/tests/integration_tests/mpl_core_tests.rs +assertion_line: 332 +expression: response +--- +{ + "interface": "MplCoreAsset", + "id": "3puHPHUHFXxhS7qPQa5YYTngzPbetoWbu7y2UxxB6xrF", + "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": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7" + }, + "supply": null, + "mutable": true, + "burnt": false, + "plugins": {}, + "mpl_core_info": { + "plugins_json_version": 1 + }, + "external_plugins": [ + { + "type": "Oracle", + "index": 0, + "offset": 119, + "authority": { + "type": "UpdateAuthority", + "address": null + }, + "adapter_config": { + "base_address": "4LDi2mR1JPsvdfwHhjmW4ZAZMbWE9rtBPUL6uQAgmWLz", + "results_offset": "Anchor", + "base_address_config": null + }, + "lifecycle_checks": { + "create": [ + "CanReject" + ], + "transfer": [ + "CanReject" + ] + } + } + ] +} 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 new file mode 100644 index 000000000..51d44c25c --- /dev/null +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_oracle_no_offset.snap @@ -0,0 +1,82 @@ +--- +source: integration_tests/tests/integration_tests/mpl_core_tests.rs +assertion_line: 390 +expression: response +--- +{ + "interface": "MplCoreAsset", + "id": "2TZpUiBiyMdwLFTKRshVMHK8anQK2W8XXbfUfyxR8yvc", + "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": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7" + }, + "supply": null, + "mutable": true, + "burnt": false, + "plugins": {}, + "mpl_core_info": { + "plugins_json_version": 1 + }, + "external_plugins": [ + { + "type": "Oracle", + "index": 0, + "offset": 119, + "authority": { + "type": "UpdateAuthority", + "address": null + }, + "adapter_config": { + "base_address": "J9JBrE7Jravcpc7Px1iWSXTdvA2Kgt5yB5kQoWSvoQFo", + "results_offset": "NoOffset", + "base_address_config": null + }, + "lifecycle_checks": { + "burn": [ + "CanReject" + ] + } + } + ] +} 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 28b0331b7..bfbe6538e 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 @@ -91,5 +91,6 @@ expression: response }, "mpl_core_info": { "plugins_json_version": 1 - } + }, + "external_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 new file mode 100644 index 000000000..b9d26a436 --- /dev/null +++ b/integration_tests/tests/integration_tests/snapshots/integration_tests__mpl_core_tests__mpl_core_get_asset_with_two_oracle_external_plugins.snap @@ -0,0 +1,101 @@ +--- +source: integration_tests/tests/integration_tests/mpl_core_tests.rs +assertion_line: 274 +expression: response +--- +{ + "interface": "MplCoreAsset", + "id": "4aarnaiMVtGEp5nToRqBEUGtqY2F1gW2V8bBQe1rN5V9", + "content": { + "$schema": "https://schema.metaplex.com/nft1.0.json", + "json_uri": "https://example.com/asset", + "files": [], + "metadata": { + "name": "new name 2", + "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": { + "plugins_json_version": 1 + }, + "external_plugins": [ + { + "type": "Oracle", + "index": 0, + "offset": 119, + "authority": { + "type": "UpdateAuthority", + "address": null + }, + "adapter_config": { + "base_address": "655aWrKDz4hNFGaSzxmT9xuwxTKPrvb5SMDohCfVFCXL", + "results_offset": "Anchor", + "base_address_config": null + }, + "lifecycle_checks": { + "update": [ + "CanReject" + ] + } + }, + { + "type": "Oracle", + "index": 1, + "offset": 154, + "authority": { + "type": "UpdateAuthority", + "address": null + }, + "adapter_config": { + "base_address": "6CGzRzs53RppPfSimeEjEYhKMagP9rT9zZrEVVgjSq7A", + "results_offset": "Anchor", + "base_address_config": null + }, + "lifecycle_checks": { + "update": [ + "CanReject" + ] + } + } + ] +} 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 35b9ea8a1..5acbdeb5d 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 @@ -67,7 +67,8 @@ expression: response "plugins": {}, "mpl_core_info": { "plugins_json_version": 1 - } + }, + "external_plugins": [] }, { "interface": "MplCoreCollection", @@ -125,7 +126,8 @@ expression: response "num_minted": 1, "current_size": 1, "plugins_json_version": 1 - } + }, + "external_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 99c59f4d6..431a64ec4 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 @@ -67,7 +67,8 @@ expression: response "plugins": {}, "mpl_core_info": { "plugins_json_version": 1 - } + }, + "external_plugins": [] }, { "interface": "MplCoreAsset", @@ -128,7 +129,8 @@ expression: response "plugins": {}, "mpl_core_info": { "plugins_json_version": 1 - } + }, + "external_plugins": [] }, { "interface": "MplCoreAsset", @@ -189,7 +191,8 @@ expression: response "plugins": {}, "mpl_core_info": { "plugins_json_version": 1 - } + }, + "external_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 new file mode 100644 index 000000000..f9cea5683 --- /dev/null +++ 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 @@ -0,0 +1,131 @@ +--- +source: integration_tests/tests/integration_tests/mpl_core_tests.rs +assertion_line: 429 +expression: response +--- +{ + "total": 1, + "limit": 50, + "page": 1, + "items": [ + { + "interface": "MplCoreAsset", + "id": "CWJDcrzxSDE7FeNRzMK1aSia7qoaUPrrGQ81E7vkQpq4", + "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": [ + { + "group_key": "collection", + "group_value": "Do7rVGmVNa9wjsKNyjoa5phqriLER6HCqUQm5zyoTX3f" + } + ], + "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": "FAe4nM85BQ8b1nWEc5TTeogQGnNDWsuGYU84vuiPc7kE" + }, + "supply": null, + "mutable": true, + "burnt": false, + "plugins": {}, + "mpl_core_info": { + "plugins_json_version": 1 + }, + "external_plugins": [ + { + "type": "Oracle", + "index": 0, + "offset": 119, + "authority": { + "type": "UpdateAuthority", + "address": null + }, + "adapter_config": { + "base_address": "4RZ7RhXeL4oz4kVX5fpRfkNQ3nz1n4eruqBn2AGPQepo", + "results_offset": "Anchor", + "base_address_config": { + "custom_pda": { + "seeds": [ + "Collection", + "Owner", + "Recipient", + "Asset", + { + "address": "HmQ75Sraz5HoTzVGpMuepXVgxwfiKyN5Mar8NxDqL9dh" + }, + { + "bytes": [ + 101, + 120, + 97, + 109, + 112, + 108, + 101, + 45, + 115, + 101, + 101, + 100, + 45, + 98, + 121, + 116, + 101, + 115 + ] + } + ], + "is_signer": false, + "is_writable": false, + "custom_program_id": null + } + } + }, + "lifecycle_checks": { + "transfer": [ + "CanReject" + ] + } + } + ] + } + ] +} 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 029dfeab4..7b190b8a9 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 @@ -67,7 +67,8 @@ expression: response "plugins": {}, "mpl_core_info": { "plugins_json_version": 1 - } + }, + "external_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 65a32e47c..1d854ee47 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 @@ -71,5 +71,6 @@ expression: response "num_minted": 1, "current_size": 1, "plugins_json_version": 1 - } + }, + "external_plugins": [] } diff --git a/migration/src/lib.rs b/migration/src/lib.rs index 9703755bc..9b4689126 100644 --- a/migration/src/lib.rs +++ b/migration/src/lib.rs @@ -41,6 +41,7 @@ mod m20240124_181900_add_slot_updated_column_per_update_type; 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; pub mod model; @@ -91,6 +92,7 @@ impl MigratorTrait for Migrator { 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), + Box::new(m20240520_120101_add_mpl_core_external_plugins_columns::Migration), ] } } diff --git a/migration/src/m20240520_120101_add_mpl_core_external_plugins_columns.rs b/migration/src/m20240520_120101_add_mpl_core_external_plugins_columns.rs new file mode 100644 index 000000000..a217a97e5 --- /dev/null +++ b/migration/src/m20240520_120101_add_mpl_core_external_plugins_columns.rs @@ -0,0 +1,51 @@ +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) + .add_column(ColumnDef::new(Asset::MplCoreExternalPlugins).json_binary()) + .to_owned(), + ) + .await?; + manager + .alter_table( + Table::alter() + .table(Asset::Table) + .add_column(ColumnDef::new(Asset::MplCoreUnknownExternalPlugins).json_binary()) + .to_owned(), + ) + .await?; + + Ok(()) + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .alter_table( + Table::alter() + .table(Asset::Table) + .drop_column(Asset::MplCoreExternalPlugins) + .to_owned(), + ) + .await?; + manager + .alter_table( + Table::alter() + .table(Asset::Table) + .drop_column(Asset::MplCoreUnknownExternalPlugins) + .to_owned(), + ) + .await?; + + Ok(()) + } +} diff --git a/migration/src/model/table.rs b/migration/src/model/table.rs index 839b5f0d8..eec2313b5 100644 --- a/migration/src/model/table.rs +++ b/migration/src/model/table.rs @@ -89,6 +89,8 @@ pub enum Asset { MplCoreCollectionNumMinted, MplCoreCollectionCurrentSize, MplCorePluginsJsonVersion, + MplCoreExternalPlugins, + MplCoreUnknownExternalPlugins, } #[derive(Copy, Clone, Iden)] diff --git a/program_transformers/src/asset_upserts.rs b/program_transformers/src/asset_upserts.rs index 03f666ae3..a82923a9f 100644 --- a/program_transformers/src/asset_upserts.rs +++ b/program_transformers/src/asset_upserts.rs @@ -96,11 +96,13 @@ pub struct AssetMetadataAccountColumns { pub royalty_amount: i32, pub asset_data: Option>, pub slot_updated_metadata_account: u64, - pub plugins: Option, - pub unknown_plugins: Option, + pub mpl_core_plugins: Option, + pub mpl_core_unknown_plugins: Option, pub mpl_core_collection_num_minted: Option, pub mpl_core_collection_current_size: Option, pub mpl_core_plugins_json_version: Option, + pub mpl_core_external_plugins: Option, + pub mpl_core_unknown_external_plugins: Option, } pub async fn upsert_assets_metadata_account_columns( @@ -126,11 +128,13 @@ pub async fn upsert_assets_metadata_account_columns( .map_err(|e| ProgramTransformerError::DeserializationError(e.to_string()))?; // Improve JSON output. - remove_plugins_nesting(&mut plugins_json); + remove_plugins_nesting(&mut plugins_json, "data"); transform_plugins_authority(&mut plugins_json); convert_keys_to_snake_case(&mut plugins_json); @@ -265,6 +265,30 @@ pub async fn save_v1_asset( None }; + // Serialize known external plugins into JSON. + let mut external_plugins_json = serde_json::to_value(&asset.external_plugins) + .map_err(|e| ProgramTransformerError::DeserializationError(e.to_string()))?; + + // Improve JSON output. + remove_plugins_nesting(&mut external_plugins_json, "adapter_config"); + transform_plugins_authority(&mut external_plugins_json); + convert_keys_to_snake_case(&mut external_plugins_json); + + // Serialize any unknown external plugins into JSON. + let unknown_external_plugins_json = if !asset.unknown_external_plugins.is_empty() { + let mut unknown_external_plugins_json = + serde_json::to_value(&asset.unknown_external_plugins) + .map_err(|e| ProgramTransformerError::DeserializationError(e.to_string()))?; + + // Improve JSON output. + transform_plugins_authority(&mut unknown_external_plugins_json); + convert_keys_to_snake_case(&mut unknown_external_plugins_json); + + Some(unknown_external_plugins_json) + } else { + None + }; + upsert_assets_metadata_account_columns( AssetMetadataAccountColumns { mint: id_vec.clone(), @@ -273,11 +297,13 @@ pub async fn save_v1_asset( royalty_amount: royalty_amount as i32, asset_data: Some(id_vec.clone()), slot_updated_metadata_account: slot, - plugins: Some(plugins_json), - unknown_plugins: unknown_plugins_json, + mpl_core_plugins: Some(plugins_json), + mpl_core_unknown_plugins: unknown_plugins_json, mpl_core_collection_num_minted: asset.num_minted.map(|val| val as i32), mpl_core_collection_current_size: asset.current_size.map(|val| val as i32), mpl_core_plugins_json_version: Some(1), + mpl_core_external_plugins: Some(external_plugins_json), + mpl_core_unknown_external_plugins: unknown_external_plugins_json, }, &txn, ) @@ -437,33 +463,47 @@ pub async fn save_v1_asset( Ok(Some(DownloadMetadataInfo::new(id_vec.clone(), uri))) } -// Modify the JSON structure to remove the `Plugin`` name and just display its data. +// Modify the JSON structure to remove the `Plugin` name and just display its data. // For example, this will transform `FreezeDelegate` JSON from: // "data":{"freeze_delegate":{"frozen":false}}} // to: // "data":{"frozen":false} -fn remove_plugins_nesting(plugins_json: &mut Value) { - if let Some(plugins) = plugins_json.as_object_mut() { - for (_, plugin) in plugins.iter_mut() { - if let Some(Value::Object(data)) = plugin.get_mut("data") { - // Extract the plugin data and remove it. - if let Some((_, inner_plugin_data)) = data.iter().next() { - let inner_plugin_data_clone = inner_plugin_data.clone(); - // Clear the "data" object. - data.clear(); - // Move the plugin data fields to the top level of "data". - if let Value::Object(inner_plugin_data) = inner_plugin_data_clone { - for (field_name, field_value) in inner_plugin_data.iter() { - data.insert(field_name.clone(), field_value.clone()); - } - } +fn remove_plugins_nesting(plugins_json: &mut Value, nested_key: &str) { + match plugins_json { + Value::Object(plugins) => { + // Handle the case where plugins_json is an object. + for (_, plugin) in plugins.iter_mut() { + remove_nesting_from_plugin(plugin, nested_key); + } + } + Value::Array(plugins_array) => { + // Handle the case where plugins_json is an array. + for plugin in plugins_array.iter_mut() { + remove_nesting_from_plugin(plugin, nested_key); + } + } + _ => {} + } +} + +fn remove_nesting_from_plugin(plugin: &mut Value, nested_key: &str) { + if let Some(Value::Object(nested_key)) = plugin.get_mut(nested_key) { + // Extract the plugin data and remove it. + if let Some((_, inner_plugin_data)) = nested_key.iter().next() { + let inner_plugin_data_clone = inner_plugin_data.clone(); + // Clear the `nested_key` object. + nested_key.clear(); + // Move the plugin data fields to the top level of `nested_key`. + if let Value::Object(inner_plugin_data) = inner_plugin_data_clone { + for (field_name, field_value) in inner_plugin_data.iter() { + nested_key.insert(field_name.clone(), field_value.clone()); } } } } } -// Modify the JSON for `PluginAuthority`` to have consistent output no matter the enum type. +// Modify the JSON for `PluginAuthority` to have consistent output no matter the enum type. // For example, from: // "authority":{"Address":{"address":"D7whDWAP5gN9x4Ff6T9MyQEkotyzmNWtfYhCEWjbUDBM"}} // to: diff --git a/program_transformers/src/token_metadata/v1_asset.rs b/program_transformers/src/token_metadata/v1_asset.rs index 14738741c..59f4edd42 100644 --- a/program_transformers/src/token_metadata/v1_asset.rs +++ b/program_transformers/src/token_metadata/v1_asset.rs @@ -268,11 +268,13 @@ pub async fn save_v1_asset( royalty_amount: metadata.seller_fee_basis_points as i32, asset_data: Some(mint_pubkey_vec.clone()), slot_updated_metadata_account: slot_i as u64, - plugins: None, - unknown_plugins: None, + mpl_core_plugins: None, + mpl_core_unknown_plugins: None, mpl_core_collection_num_minted: None, mpl_core_collection_current_size: None, mpl_core_plugins_json_version: None, + mpl_core_external_plugins: None, + mpl_core_unknown_external_plugins: None, }, &txn, )