diff --git a/CHANGELOG.md b/CHANGELOG.md index 188faf8e..1f9cddc0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,11 +12,11 @@ Description of the upcoming release here. ### Added - [#259](https://github.com/FuelLabs/sway-libs/pull/259) Adds a new upgradability library, including associated tests and documentation. +- [#265](https://github.com/FuelLabs/sway-libs/pull/265) Adds the `SetMetadataEvent` and emits `SetMetadataEvent` when the `_set_metadata()` function is called. ### Changed -- Something changed here 1 -- Something changed here 2 +- [#265](https://github.com/FuelLabs/sway-libs/pull/265) Enables the metadata events now that the Rust SDK supports wrapped heap types. ### Fixed diff --git a/libs/src/asset/metadata.sw b/libs/src/asset/metadata.sw index ae3a4bd7..4af81c82 100644 --- a/libs/src/asset/metadata.sw +++ b/libs/src/asset/metadata.sw @@ -2,6 +2,7 @@ library; use standards::src7::Metadata; use std::{ + auth::msg_sender, bytes::Bytes, hash::{ Hash, @@ -18,6 +19,18 @@ use std::{ string::String, }; +/// The event emitted when metadata is set via the `_set_metadata()` function. +pub struct SetMetadataEvent { + /// The asset for which metadata is set. + asset: AssetId, + /// The `Identity` of the caller that set the metadata. + sender: Identity, + /// The Metadata that is set. + metadata: Metadata, + /// The key used for the metadata. + key: String, +} + /// A persistent storage type to store the SRC-7; Metadata Standard type. /// /// # Additional Information @@ -166,6 +179,12 @@ pub fn _set_metadata( key: String, metadata: Metadata, ) { + log(SetMetadataEvent { + asset, + sender: msg_sender().unwrap(), + metadata, + key, + }); metadata_key.insert(asset, key, metadata); } diff --git a/tests/src/native_asset/tests/functions/metadata.rs b/tests/src/native_asset/tests/functions/metadata.rs index bdaa5773..19a7c5a0 100644 --- a/tests/src/native_asset/tests/functions/metadata.rs +++ b/tests/src/native_asset/tests/functions/metadata.rs @@ -8,7 +8,6 @@ mod success { use super::*; - #[ignore] #[tokio::test] async fn gets_one_asset() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; @@ -26,7 +25,6 @@ mod success { ); } - #[ignore] #[tokio::test] async fn gets_multiple_assets() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; @@ -60,7 +58,6 @@ mod success { ); } - #[ignore] #[tokio::test] async fn gets_multiple_types() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; @@ -68,8 +65,10 @@ mod success { defaults(id, owner_wallet, other_wallet.clone()); let metadata1 = Metadata::String(String::from("Fuel NFT Metadata 1")); let metadata2 = Metadata::Int(1); - let metadata3 = - Metadata::Bytes(Bytes::from_hex_str("bytes").expect("failed to conver to bytes")); + let metadata3 = Metadata::Bytes( + Bytes::from_hex_str("0101010101010101010101010101010101010101010101010101010101010101") + .expect("failed to convert to bytes"), + ); let key1 = String::from("key1"); let key2 = String::from("key2"); let key3 = String::from("key3"); diff --git a/tests/src/native_asset/tests/functions/set_metadata.rs b/tests/src/native_asset/tests/functions/set_metadata.rs index 56bc276d..6b257ca1 100644 --- a/tests/src/native_asset/tests/functions/set_metadata.rs +++ b/tests/src/native_asset/tests/functions/set_metadata.rs @@ -1,85 +1,157 @@ use crate::native_asset::tests::utils::{ interface::{metadata, set_metadata}, - setup::{defaults, get_asset_id, setup, Metadata}, + setup::{defaults, get_asset_id, setup, Metadata, SetMetadataEvent}, }; -use fuels::types::{Bytes, Bytes32}; +use fuels::types::{Bytes, Bytes32, Identity}; mod success { use super::*; - #[ignore] #[tokio::test] async fn sets_one_asset() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, _asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = - defaults(id, owner_wallet, other_wallet.clone()); + defaults(id, owner_wallet.clone(), other_wallet.clone()); let metadata1 = Metadata::String(String::from("Fuel NFT Metadata")); let key = String::from("key1"); assert_eq!(metadata(&instance_1, asset_id_1, key.clone()).await, None); - set_metadata(&instance_1, asset_id_1, key.clone(), metadata1.clone()).await; + let response = set_metadata(&instance_1, asset_id_1, key.clone(), metadata1.clone()).await; assert_eq!( - metadata(&instance_1, asset_id_1, key).await, - Some(metadata1) + metadata(&instance_1, asset_id_1, key.clone()).await, + Some(metadata1.clone()) + ); + + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + + assert_eq!( + *event, + SetMetadataEvent { + asset: asset_id_1, + sender: Identity::Address(owner_wallet.address().into()), + metadata: metadata1, + key: key + } ); } - #[ignore] #[tokio::test] async fn sets_multiple_assets() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = - defaults(id, owner_wallet, other_wallet.clone()); + defaults(id, owner_wallet.clone(), other_wallet.clone()); let metadata1 = Metadata::String(String::from("Fuel NFT Metadata 1")); let metadata2 = Metadata::String(String::from("Fuel NFT Metadata 2")); let metadata3 = Metadata::String(String::from("Fuel NFT Metadata 3")); let key = String::from("key1"); assert_eq!(metadata(&instance_1, asset_id_1, key.clone()).await, None); - set_metadata(&instance_1, asset_id_1, key.clone(), metadata1.clone()).await; + let response = set_metadata(&instance_1, asset_id_1, key.clone(), metadata1.clone()).await; assert_eq!( metadata(&instance_1, asset_id_1, key.clone()).await, - Some(metadata1) + Some(metadata1.clone()) + ); + + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + + assert_eq!( + *event, + SetMetadataEvent { + asset: asset_id_1, + sender: Identity::Address(owner_wallet.address().into()), + metadata: metadata1, + key: key.clone() + } ); assert_eq!(metadata(&instance_1, asset_id_2, key.clone()).await, None); - set_metadata(&instance_1, asset_id_2, key.clone(), metadata2.clone()).await; + let response = set_metadata(&instance_1, asset_id_2, key.clone(), metadata2.clone()).await; assert_eq!( metadata(&instance_1, asset_id_2, key.clone()).await, - Some(metadata2) + Some(metadata2.clone()) + ); + + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + + assert_eq!( + *event, + SetMetadataEvent { + asset: asset_id_2, + sender: Identity::Address(owner_wallet.address().into()), + metadata: metadata2, + key: key.clone() + } ); let asset_id_3 = get_asset_id(Bytes32::from([3u8; 32]), id); assert_eq!(metadata(&instance_1, asset_id_3, key.clone()).await, None); - set_metadata(&instance_1, asset_id_3, key.clone(), metadata3.clone()).await; + let response = set_metadata(&instance_1, asset_id_3, key.clone(), metadata3.clone()).await; + assert_eq!( + metadata(&instance_1, asset_id_3, key.clone()).await, + Some(metadata3.clone()) + ); + + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( - metadata(&instance_1, asset_id_3, key).await, - Some(metadata3) + *event, + SetMetadataEvent { + asset: asset_id_3, + sender: Identity::Address(owner_wallet.address().into()), + metadata: metadata3, + key: key + } ); } - #[ignore] #[tokio::test] async fn does_not_overwrite_other_names() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = - defaults(id, owner_wallet, other_wallet.clone()); + defaults(id, owner_wallet.clone(), other_wallet.clone()); let metadata1 = Metadata::String(String::from("Fuel NFT Metadata 1")); let metadata2 = Metadata::String(String::from("Fuel NFT Metadata 2")); let metadata3 = Metadata::String(String::from("Fuel NFT Metadata 3")); let key = String::from("key1"); assert_eq!(metadata(&instance_1, asset_id_1, key.clone()).await, None); - set_metadata(&instance_1, asset_id_1, key.clone(), metadata1.clone()).await; + let response = set_metadata(&instance_1, asset_id_1, key.clone(), metadata1.clone()).await; assert_eq!( metadata(&instance_1, asset_id_1.clone(), key.clone()).await, Some(metadata1.clone()) ); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + + assert_eq!( + *event, + SetMetadataEvent { + asset: asset_id_1, + sender: Identity::Address(owner_wallet.address().into()), + metadata: metadata1.clone(), + key: key.clone() + } + ); + assert_eq!(metadata(&instance_1, asset_id_2, key.clone()).await, None); - set_metadata(&instance_1, asset_id_2, key.clone(), metadata2.clone()).await; + let response = set_metadata(&instance_1, asset_id_2, key.clone(), metadata2.clone()).await; assert_eq!( metadata(&instance_1, asset_id_1, key.clone()).await, @@ -90,9 +162,24 @@ mod success { Some(metadata2.clone()) ); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + + assert_eq!( + *event, + SetMetadataEvent { + asset: asset_id_2, + sender: Identity::Address(owner_wallet.address().into()), + metadata: metadata2.clone(), + key: key.clone() + } + ); + let asset_id_3 = get_asset_id(Bytes32::from([3u8; 32]), id); assert_eq!(metadata(&instance_1, asset_id_3, key.clone()).await, None); - set_metadata(&instance_1, asset_id_3, key.clone(), metadata3.clone()).await; + let response = set_metadata(&instance_1, asset_id_3, key.clone(), metadata3.clone()).await; assert_eq!( metadata(&instance_1, asset_id_1, key.clone()).await, @@ -103,34 +190,65 @@ mod success { Some(metadata2) ); assert_eq!( - metadata(&instance_1, asset_id_3, key).await, - Some(metadata3) + metadata(&instance_1, asset_id_3, key.clone()).await, + Some(metadata3.clone()) + ); + + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + + assert_eq!( + *event, + SetMetadataEvent { + asset: asset_id_3, + sender: Identity::Address(owner_wallet.address().into()), + metadata: metadata3, + key: key + } ); } - #[ignore] #[tokio::test] async fn sets_multiple_types() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, _asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = - defaults(id, owner_wallet, other_wallet.clone()); + defaults(id, owner_wallet.clone(), other_wallet.clone()); let metadata1 = Metadata::String(String::from("Fuel NFT Metadata 1")); let metadata2 = Metadata::Int(1); - let metadata3 = - Metadata::Bytes(Bytes::from_hex_str("bytes").expect("failed to conver to bytes")); + let metadata3 = Metadata::Bytes( + Bytes::from_hex_str("0101010101010101010101010101010101010101010101010101010101010101") + .expect("failed to convert to bytes"), + ); let key1 = String::from("key1"); let key2 = String::from("key2"); let key3 = String::from("key3"); assert_eq!(metadata(&instance_1, asset_id_1, key1.clone()).await, None); - set_metadata(&instance_1, asset_id_1, key1.clone(), metadata1.clone()).await; + let response = set_metadata(&instance_1, asset_id_1, key1.clone(), metadata1.clone()).await; assert_eq!( metadata(&instance_1, asset_id_1, key1.clone()).await, Some(metadata1.clone()) ); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + + assert_eq!( + *event, + SetMetadataEvent { + asset: asset_id_1, + sender: Identity::Address(owner_wallet.address().into()), + metadata: metadata1.clone(), + key: key1.clone() + } + ); + assert_eq!(metadata(&instance_1, asset_id_1, key2.clone()).await, None); - set_metadata(&instance_1, asset_id_1, key2.clone(), metadata2.clone()).await; + let response = set_metadata(&instance_1, asset_id_1, key2.clone(), metadata2.clone()).await; assert_eq!( metadata(&instance_1, asset_id_1, key2.clone()).await, Some(metadata2.clone()) @@ -140,11 +258,26 @@ mod success { Some(metadata1.clone()) ); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + + assert_eq!( + *event, + SetMetadataEvent { + asset: asset_id_1, + sender: Identity::Address(owner_wallet.address().into()), + metadata: metadata2.clone(), + key: key2.clone() + } + ); + assert_eq!(metadata(&instance_1, asset_id_1, key3.clone()).await, None); - set_metadata(&instance_1, asset_id_1, key3.clone(), metadata3.clone()).await; + let response = set_metadata(&instance_1, asset_id_1, key3.clone(), metadata3.clone()).await; assert_eq!( - metadata(&instance_1, asset_id_1, key3).await, - Some(metadata3) + metadata(&instance_1, asset_id_1, key3.clone()).await, + Some(metadata3.clone()) ); assert_eq!( metadata(&instance_1, asset_id_1, key2.clone()).await, @@ -154,5 +287,20 @@ mod success { metadata(&instance_1, asset_id_1, key1.clone()).await, Some(metadata1) ); + + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + + assert_eq!( + *event, + SetMetadataEvent { + asset: asset_id_1, + sender: Identity::Address(owner_wallet.address().into()), + metadata: metadata3, + key: key3 + } + ); } }