diff --git a/Architecture.md b/Architecture.md index c4a04579..cd2e5504 100644 --- a/Architecture.md +++ b/Architecture.md @@ -279,7 +279,7 @@ The non-fungible token implementation is designed to be compatible with existing ### WASM Compilation -- **Target**: `wasm32-unknown-unknown` +- **Target**: `wasm32v1-none` - **Optimization**: Release builds with size optimization - **No-std Environment**: Minimal runtime footprint diff --git a/README.md b/README.md index 280b5408..604460a9 100644 --- a/README.md +++ b/README.md @@ -41,8 +41,8 @@ We provide a set of example contracts that demonstrate how to use the library. Y 2. `cd stellar-contracts/examples` 3. Take a look at the current folder, and select an example contract you are interested in. We will go with the `fungible-pausable` in this guide. 4. `cd fungible-pausable` -5. `cargo build --target wasm32-unknown-unknown --release` -6. Now, the `target/wasm32-unknown-unknown/release/` directory will contain the compiled contracts. In this case, `target/wasm32-unknown-unknown/release/fungible_pausable_example.wasm` is the compiled wasm file. +5. `cargo build --target wasm32v1-none --release` +6. Now, the `target/wasm32v1-none/release/` directory will contain the compiled contracts. In this case, `target/wasm32v1-none/release/fungible_pausable_example.wasm` is the compiled wasm file. 7. Deploying to the testnet is no different than any other contract. You can follow the instructions in the [Stellar documentation](https://developers.stellar.org/docs/build/smart-contracts/getting-started/deploy-to-testnet). diff --git a/packages/test-utils/default-impl-macro-test/Cargo.toml b/packages/test-utils/default-impl-macro-test/Cargo.toml index 8ade76c3..ed8b9c22 100644 --- a/packages/test-utils/default-impl-macro-test/Cargo.toml +++ b/packages/test-utils/default-impl-macro-test/Cargo.toml @@ -7,11 +7,11 @@ publish = false version.workspace = true [lib] -crate-type = ["lib", "cdylib"] +crate-type = ["lib"] doctest = false - -[dev-dependencies] +# This crate is only used for testing, and not compatible with `wasm32` targets. +[target.'cfg(not(target_family = "wasm"))'.dev-dependencies] soroban-sdk = { workspace = true, features = ["testutils"] } stellar-access = { workspace = true } stellar-macros = { workspace = true } diff --git a/packages/test-utils/default-impl-macro-test/src/lib.rs b/packages/test-utils/default-impl-macro-test/src/lib.rs index 56d6e1b5..79362b89 100644 --- a/packages/test-utils/default-impl-macro-test/src/lib.rs +++ b/packages/test-utils/default-impl-macro-test/src/lib.rs @@ -5,3 +5,8 @@ //! //! This crate is not intended for use in any other context. And this `lib.rs` //! file is empty on purpose. + +// A conditional attribute that applies `no_std` only for wasm targets. +// This prevents Cargo from implicitly injecting std::prelude imports into empty crates +// when building for wasm targets that don't support std (like wasm32v1-none). +#![cfg_attr(target_family = "wasm", no_std)] diff --git a/packages/test-utils/event-assertion/Cargo.toml b/packages/test-utils/event-assertion/Cargo.toml index d7b6fe9c..73435ae9 100644 --- a/packages/test-utils/event-assertion/Cargo.toml +++ b/packages/test-utils/event-assertion/Cargo.toml @@ -6,10 +6,11 @@ repository.workspace = true publish = false version.workspace = true -# This crate is only used for testing, and not compatible with `wasm32` targets. -[target.'cfg(not(target_arch = "wasm32"))'.dependencies.soroban-sdk] -workspace = true -features = ["testutils"] +[lib] +crate-type = ["lib"] +doctest = false -[dependencies] +# This crate is only used for testing, and not compatible with `wasm32` targets. +[target.'cfg(not(target_family = "wasm"))'.dependencies] +soroban-sdk = { workspace = true, features = ["testutils"] } stellar-tokens = { workspace = true } diff --git a/packages/test-utils/event-assertion/src/lib.rs b/packages/test-utils/event-assertion/src/lib.rs index ed1deaf3..399f80e4 100644 --- a/packages/test-utils/event-assertion/src/lib.rs +++ b/packages/test-utils/event-assertion/src/lib.rs @@ -1,339 +1,368 @@ -#![cfg(not(target_arch = "wasm32"))] - -use std::collections::HashSet; - -use soroban_sdk::{symbol_short, testutils::Events, Address, Env, IntoVal, Map, Symbol, Val, Vec}; - -pub struct EventAssertion<'a> { - env: &'a Env, - contract: Address, - processed_events: HashSet, -} - -impl<'a> EventAssertion<'a> { - pub fn new(env: &'a Env, contract: Address) -> Self { - Self { env, contract, processed_events: HashSet::new() } +// A conditional attribute that applies `no_std` only for wasm targets. +// This prevents Cargo from implicitly injecting std::prelude imports into empty +// crates when building for wasm targets that don't support std (like +// wasm32v1-none). +#![cfg_attr(target_family = "wasm", no_std)] + +// The entire implementation is only compiled for non-wasm targets. +// This is a test utility crate that's not needed in wasm environments. +#[cfg(not(target_family = "wasm"))] +mod implementation { + use std::collections::HashSet; + + use soroban_sdk::{ + symbol_short, testutils::Events, Address, Env, IntoVal, Map, Symbol, Val, Vec, + }; + + pub struct EventAssertion<'a> { + env: &'a Env, + contract: Address, + processed_events: HashSet, } - fn find_event_by_symbol(&mut self, symbol_name: &str) -> Option<(Address, Vec, Val)> { - let events = self.env.events().all(); + impl<'a> EventAssertion<'a> { + pub fn new(env: &'a Env, contract: Address) -> Self { + Self { env, contract, processed_events: HashSet::new() } + } + + fn find_event_by_symbol(&mut self, symbol_name: &str) -> Option<(Address, Vec, Val)> { + let events = self.env.events().all(); - let target_symbol = match symbol_name { - "transfer" => symbol_short!("transfer"), - "mint" => symbol_short!("mint"), - "burn" => symbol_short!("burn"), - "approve" => symbol_short!("approve"), - _ => Symbol::new(self.env, symbol_name), - }; + let target_symbol = match symbol_name { + "transfer" => symbol_short!("transfer"), + "mint" => symbol_short!("mint"), + "burn" => symbol_short!("burn"), + "approve" => symbol_short!("approve"), + _ => Symbol::new(self.env, symbol_name), + }; - for (index, event) in events.iter().enumerate() { - let index_u32 = index as u32; + for (index, event) in events.iter().enumerate() { + let index_u32 = index as u32; - if self.processed_events.contains(&index_u32) { - continue; - } + if self.processed_events.contains(&index_u32) { + continue; + } - let (contract, topics, data) = event; + let (contract, topics, data) = event; - let topics_clone = topics.clone(); + let topics_clone = topics.clone(); - if let Some(first_topic) = topics_clone.first() { - let topic_symbol: Symbol = first_topic.into_val(self.env); + if let Some(first_topic) = topics_clone.first() { + let topic_symbol: Symbol = first_topic.into_val(self.env); - if topic_symbol == target_symbol { - self.processed_events.insert(index_u32); - return Some((contract.clone(), topics_clone, data)); + if topic_symbol == target_symbol { + self.processed_events.insert(index_u32); + return Some((contract.clone(), topics_clone, data)); + } } } + None } - None - } - - pub fn assert_fungible_transfer(&mut self, from: &Address, to: &Address, amount: i128) { - let transfer_event = self.find_event_by_symbol("transfer"); - - assert!(transfer_event.is_some(), "Transfer event not found in event log"); - - let (contract, topics, data) = transfer_event.unwrap(); - assert_eq!(contract, self.contract, "Event from wrong contract"); - - let topics: Vec = topics.clone(); - assert_eq!(topics.len(), 3, "Transfer event should have 3 topics"); - - let topic_symbol: Symbol = topics.get_unchecked(0).into_val(self.env); - assert_eq!(topic_symbol, symbol_short!("transfer")); - - let event_from: Address = topics.get_unchecked(1).into_val(self.env); - let event_to: Address = topics.get_unchecked(2).into_val(self.env); - - let data_map: Map = data.into_val(self.env); - let event_amount = data_map.get(Symbol::new(self.env, "amount")).unwrap(); - - assert_eq!(&event_from, from, "Transfer event has wrong from address"); - assert_eq!(&event_to, to, "Transfer event has wrong to address"); - assert_eq!(event_amount, amount, "Transfer event has wrong amount"); - } - - pub fn assert_non_fungible_transfer(&mut self, from: &Address, to: &Address, token_id: u32) { - let transfer_event = self.find_event_by_symbol("transfer"); - - assert!(transfer_event.is_some(), "Transfer event not found in event log"); - - let (contract, topics, data) = transfer_event.unwrap(); - assert_eq!(contract, self.contract, "Event from wrong contract"); - - let topics: Vec = topics.clone(); - assert_eq!(topics.len(), 3, "Transfer event should have 3 topics"); - let topic_symbol: Symbol = topics.get_unchecked(0).into_val(self.env); - assert_eq!(topic_symbol, symbol_short!("transfer")); + pub fn assert_fungible_transfer(&mut self, from: &Address, to: &Address, amount: i128) { + let transfer_event = self.find_event_by_symbol("transfer"); - let event_from: Address = topics.get_unchecked(1).into_val(self.env); - let event_to: Address = topics.get_unchecked(2).into_val(self.env); + assert!(transfer_event.is_some(), "Transfer event not found in event log"); - let data_map: Map = data.into_val(self.env); - let event_token_id = data_map.get(Symbol::new(self.env, "token_id")).unwrap(); + let (contract, topics, data) = transfer_event.unwrap(); + assert_eq!(contract, self.contract, "Event from wrong contract"); - assert_eq!(&event_from, from, "Transfer event has wrong from address"); - assert_eq!(&event_to, to, "Transfer event has wrong to address"); - assert_eq!(event_token_id, token_id, "Transfer event has wrong amount"); - } - - pub fn assert_fungible_mint(&mut self, to: &Address, amount: i128) { - let mint_event = self.find_event_by_symbol("mint"); - - assert!(mint_event.is_some(), "Mint event not found in event log"); + let topics: Vec = topics.clone(); + assert_eq!(topics.len(), 3, "Transfer event should have 3 topics"); - let (contract, topics, data) = mint_event.unwrap(); - assert_eq!(contract, self.contract, "Event from wrong contract"); + let topic_symbol: Symbol = topics.get_unchecked(0).into_val(self.env); + assert_eq!(topic_symbol, symbol_short!("transfer")); - let topics: Vec = topics.clone(); - assert_eq!(topics.len(), 2, "Mint event should have 2 topics"); + let event_from: Address = topics.get_unchecked(1).into_val(self.env); + let event_to: Address = topics.get_unchecked(2).into_val(self.env); - let topic_symbol: Symbol = topics.get_unchecked(0).into_val(self.env); - assert_eq!(topic_symbol, symbol_short!("mint")); + let data_map: Map = data.into_val(self.env); + let event_amount = data_map.get(Symbol::new(self.env, "amount")).unwrap(); - let event_to: Address = topics.get_unchecked(1).into_val(self.env); + assert_eq!(&event_from, from, "Transfer event has wrong from address"); + assert_eq!(&event_to, to, "Transfer event has wrong to address"); + assert_eq!(event_amount, amount, "Transfer event has wrong amount"); + } - let data_map: Map = data.into_val(self.env); - let event_amount = data_map.get(Symbol::new(self.env, "amount")).unwrap(); + pub fn assert_non_fungible_transfer( + &mut self, + from: &Address, + to: &Address, + token_id: u32, + ) { + let transfer_event = self.find_event_by_symbol("transfer"); - assert_eq!(&event_to, to, "Mint event has wrong to address"); - assert_eq!(event_amount, amount, "Mint event has wrong amount"); - } + assert!(transfer_event.is_some(), "Transfer event not found in event log"); - pub fn assert_non_fungible_mint(&mut self, to: &Address, token_id: u32) { - let mint_event = self.find_event_by_symbol("mint"); + let (contract, topics, data) = transfer_event.unwrap(); + assert_eq!(contract, self.contract, "Event from wrong contract"); - assert!(mint_event.is_some(), "Mint event not found in event log"); + let topics: Vec = topics.clone(); + assert_eq!(topics.len(), 3, "Transfer event should have 3 topics"); - let (contract, topics, data) = mint_event.unwrap(); - assert_eq!(contract, self.contract, "Event from wrong contract"); + let topic_symbol: Symbol = topics.get_unchecked(0).into_val(self.env); + assert_eq!(topic_symbol, symbol_short!("transfer")); - let topics: Vec = topics.clone(); - assert_eq!(topics.len(), 2, "Mint event should have 2 topics"); + let event_from: Address = topics.get_unchecked(1).into_val(self.env); + let event_to: Address = topics.get_unchecked(2).into_val(self.env); - let topic_symbol: Symbol = topics.get_unchecked(0).into_val(self.env); - assert_eq!(topic_symbol, symbol_short!("mint")); + let data_map: Map = data.into_val(self.env); + let event_token_id = data_map.get(Symbol::new(self.env, "token_id")).unwrap(); - let event_to: Address = topics.get_unchecked(1).into_val(self.env); + assert_eq!(&event_from, from, "Transfer event has wrong from address"); + assert_eq!(&event_to, to, "Transfer event has wrong to address"); + assert_eq!(event_token_id, token_id, "Transfer event has wrong amount"); + } - let data_map: Map = data.into_val(self.env); - let event_token_id = data_map.get(Symbol::new(self.env, "token_id")).unwrap(); + pub fn assert_fungible_mint(&mut self, to: &Address, amount: i128) { + let mint_event = self.find_event_by_symbol("mint"); - assert_eq!(&event_to, to, "Mint event has wrong to address"); - assert_eq!(event_token_id, token_id, "Mint event has wrong token_id"); - } + assert!(mint_event.is_some(), "Mint event not found in event log"); - pub fn assert_fungible_burn(&mut self, from: &Address, amount: i128) { - let burn_event = self.find_event_by_symbol("burn"); + let (contract, topics, data) = mint_event.unwrap(); + assert_eq!(contract, self.contract, "Event from wrong contract"); - assert!(burn_event.is_some(), "Burn event not found in event log"); + let topics: Vec = topics.clone(); + assert_eq!(topics.len(), 2, "Mint event should have 2 topics"); - let (contract, topics, data) = burn_event.unwrap(); - assert_eq!(contract, self.contract, "Event from wrong contract"); + let topic_symbol: Symbol = topics.get_unchecked(0).into_val(self.env); + assert_eq!(topic_symbol, symbol_short!("mint")); - let topics: Vec = topics.clone(); - assert_eq!(topics.len(), 2, "Burn event should have 2 topics"); + let event_to: Address = topics.get_unchecked(1).into_val(self.env); - let topic_symbol: Symbol = topics.get_unchecked(0).into_val(self.env); - assert_eq!(topic_symbol, symbol_short!("burn")); + let data_map: Map = data.into_val(self.env); + let event_amount = data_map.get(Symbol::new(self.env, "amount")).unwrap(); - let event_from: Address = topics.get_unchecked(1).into_val(self.env); + assert_eq!(&event_to, to, "Mint event has wrong to address"); + assert_eq!(event_amount, amount, "Mint event has wrong amount"); + } - let data_map: Map = data.into_val(self.env); - let event_amount = data_map.get(Symbol::new(self.env, "amount")).unwrap(); + pub fn assert_non_fungible_mint(&mut self, to: &Address, token_id: u32) { + let mint_event = self.find_event_by_symbol("mint"); - assert_eq!(&event_from, from, "Burn event has wrong from address"); - assert_eq!(event_amount, amount, "Burn event has wrong amount"); - } + assert!(mint_event.is_some(), "Mint event not found in event log"); - pub fn assert_non_fungible_burn(&mut self, from: &Address, token_id: u32) { - let burn_event = self.find_event_by_symbol("burn"); + let (contract, topics, data) = mint_event.unwrap(); + assert_eq!(contract, self.contract, "Event from wrong contract"); - assert!(burn_event.is_some(), "Burn event not found in event log"); + let topics: Vec = topics.clone(); + assert_eq!(topics.len(), 2, "Mint event should have 2 topics"); - let (contract, topics, data) = burn_event.unwrap(); - assert_eq!(contract, self.contract, "Event from wrong contract"); + let topic_symbol: Symbol = topics.get_unchecked(0).into_val(self.env); + assert_eq!(topic_symbol, symbol_short!("mint")); - let topics: Vec = topics.clone(); - assert_eq!(topics.len(), 2, "Burn event should have 2 topics"); + let event_to: Address = topics.get_unchecked(1).into_val(self.env); - let topic_symbol: Symbol = topics.get_unchecked(0).into_val(self.env); - assert_eq!(topic_symbol, symbol_short!("burn")); + let data_map: Map = data.into_val(self.env); + let event_token_id = data_map.get(Symbol::new(self.env, "token_id")).unwrap(); - let event_from: Address = topics.get_unchecked(1).into_val(self.env); + assert_eq!(&event_to, to, "Mint event has wrong to address"); + assert_eq!(event_token_id, token_id, "Mint event has wrong token_id"); + } - let data_map: Map = data.into_val(self.env); - let event_token_id = data_map.get(Symbol::new(self.env, "token_id")).unwrap(); + pub fn assert_fungible_burn(&mut self, from: &Address, amount: i128) { + let burn_event = self.find_event_by_symbol("burn"); - assert_eq!(&event_from, from, "Burn event has wrong from address"); - assert_eq!(event_token_id, token_id, "Burn event has wrong token_id"); - } + assert!(burn_event.is_some(), "Burn event not found in event log"); - pub fn assert_event_count(&self, expected: usize) { - let events = self.env.events().all(); - assert_eq!( - events.len() as usize, - expected, - "Expected {} events, found {}", - expected, - events.len() - ); - } + let (contract, topics, data) = burn_event.unwrap(); + assert_eq!(contract, self.contract, "Event from wrong contract"); - pub fn assert_fungible_approve( - &mut self, - owner: &Address, - spender: &Address, - amount: i128, - live_until_ledger: u32, - ) { - let approve_event = self.find_event_by_symbol("approve"); + let topics: Vec = topics.clone(); + assert_eq!(topics.len(), 2, "Burn event should have 2 topics"); - assert!(approve_event.is_some(), "Approve event not found in event log"); + let topic_symbol: Symbol = topics.get_unchecked(0).into_val(self.env); + assert_eq!(topic_symbol, symbol_short!("burn")); - let (contract, topics, data) = approve_event.unwrap(); - assert_eq!(contract, self.contract, "Event from wrong contract"); + let event_from: Address = topics.get_unchecked(1).into_val(self.env); - let topics: Vec = topics.clone(); - assert_eq!(topics.len(), 3, "Approve event should have 3 topics"); + let data_map: Map = data.into_val(self.env); + let event_amount = data_map.get(Symbol::new(self.env, "amount")).unwrap(); - let topic_symbol: Symbol = topics.get_unchecked(0).into_val(self.env); - assert_eq!(topic_symbol, symbol_short!("approve")); + assert_eq!(&event_from, from, "Burn event has wrong from address"); + assert_eq!(event_amount, amount, "Burn event has wrong amount"); + } - let event_owner: Address = topics.get_unchecked(1).into_val(self.env); - let event_spender: Address = topics.get_unchecked(2).into_val(self.env); + pub fn assert_non_fungible_burn(&mut self, from: &Address, token_id: u32) { + let burn_event = self.find_event_by_symbol("burn"); - let data_map: Map = data.into_val(self.env); - let event_amount: i128 = - data_map.get(Symbol::new(self.env, "amount")).unwrap().into_val(self.env); - let event_live_until_ledger: u32 = - data_map.get(Symbol::new(self.env, "live_until_ledger")).unwrap().into_val(self.env); - let event_data = (event_amount, event_live_until_ledger); + assert!(burn_event.is_some(), "Burn event not found in event log"); - assert_eq!(&event_owner, owner, "Approve event has wrong owner address"); - assert_eq!(&event_spender, spender, "Approve event has wrong spender address"); - assert_eq!(event_data.0, amount, "Approve event has wrong amount"); - assert_eq!(event_data.1, live_until_ledger, "Approve event has wrong live_until_ledger"); - } + let (contract, topics, data) = burn_event.unwrap(); + assert_eq!(contract, self.contract, "Event from wrong contract"); - pub fn assert_non_fungible_approve( - &mut self, - owner: &Address, - spender: &Address, - token_id: u32, - live_until_ledger: u32, - ) { - let approve_event = self.find_event_by_symbol("approve"); - - assert!(approve_event.is_some(), "Approve event not found in event log"); - - let (contract, topics, data) = approve_event.unwrap(); - assert_eq!(contract, self.contract, "Event from wrong contract"); - - let topics: Vec = topics.clone(); - assert_eq!(topics.len(), 3, "Approve event should have 3 topics"); - - let topic_symbol: Symbol = topics.get_unchecked(0).into_val(self.env); - assert_eq!(topic_symbol, symbol_short!("approve")); - - let event_owner: Address = topics.get_unchecked(1).into_val(self.env); - let event_token_id: u32 = topics.get_unchecked(2).into_val(self.env); - - let data_map: Map = data.into_val(self.env); - let event_approved: Address = - data_map.get(Symbol::new(self.env, "approved")).unwrap().into_val(self.env); - let event_live_until_ledger: u32 = - data_map.get(Symbol::new(self.env, "live_until_ledger")).unwrap().into_val(self.env); - - assert_eq!(&event_owner, owner, "Approve event has wrong owner address"); - assert_eq!(event_token_id, token_id, "Approve event has wrong token_id"); - assert_eq!(event_approved, *spender, "Approve event has wrong approved address"); - assert_eq!( - event_live_until_ledger, live_until_ledger, - "Approve event has wrong live_until_ledger" - ); - } + let topics: Vec = topics.clone(); + assert_eq!(topics.len(), 2, "Burn event should have 2 topics"); - pub fn assert_approve_for_all( - &mut self, - owner: &Address, - operator: &Address, - live_until_ledger: u32, - ) { - let approve_event = self.find_event_by_symbol("approve_for_all"); + let topic_symbol: Symbol = topics.get_unchecked(0).into_val(self.env); + assert_eq!(topic_symbol, symbol_short!("burn")); - assert!(approve_event.is_some(), "ApproveForAll event not found in event log"); + let event_from: Address = topics.get_unchecked(1).into_val(self.env); - let (contract, topics, data) = approve_event.unwrap(); - assert_eq!(contract, self.contract, "Event from wrong contract"); + let data_map: Map = data.into_val(self.env); + let event_token_id = data_map.get(Symbol::new(self.env, "token_id")).unwrap(); - let topics: Vec = topics.clone(); - assert_eq!(topics.len(), 2, "ApproveForAll event should have 2 topics"); + assert_eq!(&event_from, from, "Burn event has wrong from address"); + assert_eq!(event_token_id, token_id, "Burn event has wrong token_id"); + } - let topic_symbol: Symbol = topics.get_unchecked(0).into_val(self.env); - assert_eq!(topic_symbol, Symbol::new(self.env, "approve_for_all")); + pub fn assert_event_count(&self, expected: usize) { + let events = self.env.events().all(); + assert_eq!( + events.len() as usize, + expected, + "Expected {} events, found {}", + expected, + events.len() + ); + } - let event_owner: Address = topics.get_unchecked(1).into_val(self.env); + pub fn assert_fungible_approve( + &mut self, + owner: &Address, + spender: &Address, + amount: i128, + live_until_ledger: u32, + ) { + let approve_event = self.find_event_by_symbol("approve"); + + assert!(approve_event.is_some(), "Approve event not found in event log"); + + let (contract, topics, data) = approve_event.unwrap(); + assert_eq!(contract, self.contract, "Event from wrong contract"); + + let topics: Vec = topics.clone(); + assert_eq!(topics.len(), 3, "Approve event should have 3 topics"); + + let topic_symbol: Symbol = topics.get_unchecked(0).into_val(self.env); + assert_eq!(topic_symbol, symbol_short!("approve")); + + let event_owner: Address = topics.get_unchecked(1).into_val(self.env); + let event_spender: Address = topics.get_unchecked(2).into_val(self.env); + + let data_map: Map = data.into_val(self.env); + let event_amount: i128 = + data_map.get(Symbol::new(self.env, "amount")).unwrap().into_val(self.env); + let event_live_until_ledger: u32 = data_map + .get(Symbol::new(self.env, "live_until_ledger")) + .unwrap() + .into_val(self.env); + let event_data = (event_amount, event_live_until_ledger); + + assert_eq!(&event_owner, owner, "Approve event has wrong owner address"); + assert_eq!(&event_spender, spender, "Approve event has wrong spender address"); + assert_eq!(event_data.0, amount, "Approve event has wrong amount"); + assert_eq!( + event_data.1, live_until_ledger, + "Approve event has wrong live_until_ledger" + ); + } - let data_map: Map = data.into_val(self.env); - let event_operator: Address = - data_map.get(Symbol::new(self.env, "operator")).unwrap().into_val(self.env); - let event_live_until_ledger: u32 = - data_map.get(Symbol::new(self.env, "live_until_ledger")).unwrap().into_val(self.env); + pub fn assert_non_fungible_approve( + &mut self, + owner: &Address, + spender: &Address, + token_id: u32, + live_until_ledger: u32, + ) { + let approve_event = self.find_event_by_symbol("approve"); + + assert!(approve_event.is_some(), "Approve event not found in event log"); + + let (contract, topics, data) = approve_event.unwrap(); + assert_eq!(contract, self.contract, "Event from wrong contract"); + + let topics: Vec = topics.clone(); + assert_eq!(topics.len(), 3, "Approve event should have 3 topics"); + + let topic_symbol: Symbol = topics.get_unchecked(0).into_val(self.env); + assert_eq!(topic_symbol, symbol_short!("approve")); + + let event_owner: Address = topics.get_unchecked(1).into_val(self.env); + let event_token_id: u32 = topics.get_unchecked(2).into_val(self.env); + + let data_map: Map = data.into_val(self.env); + let event_approved: Address = + data_map.get(Symbol::new(self.env, "approved")).unwrap().into_val(self.env); + let event_live_until_ledger: u32 = data_map + .get(Symbol::new(self.env, "live_until_ledger")) + .unwrap() + .into_val(self.env); + + assert_eq!(&event_owner, owner, "Approve event has wrong owner address"); + assert_eq!(event_token_id, token_id, "Approve event has wrong token_id"); + assert_eq!(event_approved, *spender, "Approve event has wrong approved address"); + assert_eq!( + event_live_until_ledger, live_until_ledger, + "Approve event has wrong live_until_ledger" + ); + } - assert_eq!(&event_owner, owner, "ApproveForAll event has wrong owner address"); - assert_eq!(event_operator, *operator, "ApproveForAll event has wrong operator address"); - assert_eq!( - event_live_until_ledger, live_until_ledger, - "ApproveForAll event has wrong live_until_ledger" - ); - } + pub fn assert_approve_for_all( + &mut self, + owner: &Address, + operator: &Address, + live_until_ledger: u32, + ) { + let approve_event = self.find_event_by_symbol("approve_for_all"); + + assert!(approve_event.is_some(), "ApproveForAll event not found in event log"); + + let (contract, topics, data) = approve_event.unwrap(); + assert_eq!(contract, self.contract, "Event from wrong contract"); + + let topics: Vec = topics.clone(); + assert_eq!(topics.len(), 2, "ApproveForAll event should have 2 topics"); + + let topic_symbol: Symbol = topics.get_unchecked(0).into_val(self.env); + assert_eq!(topic_symbol, Symbol::new(self.env, "approve_for_all")); + + let event_owner: Address = topics.get_unchecked(1).into_val(self.env); + + let data_map: Map = data.into_val(self.env); + let event_operator: Address = + data_map.get(Symbol::new(self.env, "operator")).unwrap().into_val(self.env); + let event_live_until_ledger: u32 = data_map + .get(Symbol::new(self.env, "live_until_ledger")) + .unwrap() + .into_val(self.env); + + assert_eq!(&event_owner, owner, "ApproveForAll event has wrong owner address"); + assert_eq!(event_operator, *operator, "ApproveForAll event has wrong operator address"); + assert_eq!( + event_live_until_ledger, live_until_ledger, + "ApproveForAll event has wrong live_until_ledger" + ); + } - pub fn assert_consecutive_mint(&mut self, to: &Address, from_id: u32, to_id: u32) { - let event = self.find_event_by_symbol("consecutive_mint"); + pub fn assert_consecutive_mint(&mut self, to: &Address, from_id: u32, to_id: u32) { + let event = self.find_event_by_symbol("consecutive_mint"); - assert!(event.is_some(), "ConsecutiveMint event not found in event log"); + assert!(event.is_some(), "ConsecutiveMint event not found in event log"); - let (contract, topics, data) = event.unwrap(); - assert_eq!(contract, self.contract, "Event from wrong contract"); + let (contract, topics, data) = event.unwrap(); + assert_eq!(contract, self.contract, "Event from wrong contract"); - let topics: Vec = topics.clone(); - assert_eq!(topics.len(), 2, "ConsecutiveMint event should have 2 topics"); + let topics: Vec = topics.clone(); + assert_eq!(topics.len(), 2, "ConsecutiveMint event should have 2 topics"); - let topic_symbol: Symbol = topics.get_unchecked(0).into_val(self.env); - assert_eq!(topic_symbol, Symbol::new(self.env, "consecutive_mint")); + let topic_symbol: Symbol = topics.get_unchecked(0).into_val(self.env); + assert_eq!(topic_symbol, Symbol::new(self.env, "consecutive_mint")); - let event_to: Address = topics.get_unchecked(1).into_val(self.env); + let event_to: Address = topics.get_unchecked(1).into_val(self.env); - let data_map: Map = data.into_val(self.env); - let from_token_id_val = data_map.get(Symbol::new(self.env, "from_token_id")).unwrap(); - let to_token_id_val = data_map.get(Symbol::new(self.env, "to_token_id")).unwrap(); - let event_data = (from_token_id_val, to_token_id_val); + let data_map: Map = data.into_val(self.env); + let from_token_id_val = data_map.get(Symbol::new(self.env, "from_token_id")).unwrap(); + let to_token_id_val = data_map.get(Symbol::new(self.env, "to_token_id")).unwrap(); + let event_data = (from_token_id_val, to_token_id_val); - assert_eq!(&event_to, to, "ConsecutiveMint event has wrong to address"); - assert_eq!(event_data.0, from_id, "ConsecutiveMint event has wrong from_token_id"); - assert_eq!(event_data.1, to_id, "ConsecutiveMint event has wrong to_token_id"); + assert_eq!(&event_to, to, "ConsecutiveMint event has wrong to address"); + assert_eq!(event_data.0, from_id, "ConsecutiveMint event has wrong from_token_id"); + assert_eq!(event_data.1, to_id, "ConsecutiveMint event has wrong to_token_id"); + } } } + +// Re-export for non-wasm targets +#[cfg(not(target_family = "wasm"))] +pub use implementation::*; diff --git a/rust-toolchain.toml b/rust-toolchain.toml index e19af848..11bcc00a 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] channel = "stable" -targets = ["wasm32-unknown-unknown"] +targets = ["wasm32v1-none"] components = ["rustfmt", "clippy", "rust-src"]