From f1df725b14c147d0e238d533b99675ddc12f8b9a Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Wed, 22 May 2024 19:15:49 +0200 Subject: [PATCH] visibility --- pop-api/examples/fungibles/expanded.rs | 2766 +++++++++++++++++ pop-api/examples/fungibles/lib.rs | 107 +- pop-api/src/lib.rs | 6 +- pop-api/src/v0/assets/fungibles.rs | 288 +- pop-api/src/v0/contracts.rs | 156 + pop-api/src/v0/mod.rs | 1 + .../src/extensions/tests/local_fungibles.rs | 349 ++- runtime/devnet/src/extensions/tests/mod.rs | 18 +- 8 files changed, 3387 insertions(+), 304 deletions(-) create mode 100644 pop-api/examples/fungibles/expanded.rs create mode 100644 pop-api/src/v0/contracts.rs diff --git a/pop-api/examples/fungibles/expanded.rs b/pop-api/examples/fungibles/expanded.rs new file mode 100644 index 00000000..c73cdeb7 --- /dev/null +++ b/pop-api/examples/fungibles/expanded.rs @@ -0,0 +1,2766 @@ +#![feature(prelude_import)] +#[prelude_import] +use std::prelude::rust_2021::*; +#[macro_use] +extern crate std; +use pop_api::{ + primitives::{AccountId as AccountId32, AssetId}, + assets::fungibles::*, +}; +pub enum FungiblesError { + /// Not enough balance to fulfill a request is available. + InsufficientBalance, + /// Not enough allowance to fulfill a request is available. + InsufficientAllowance, + /// The asset status is not the expected status. + IncorrectStatus, + /// The asset ID is already taken. + InUse, + /// Minimum balance should be non-zero. + MinBalanceZero, + /// The signing account has no permission to do the operation. + NoPermission, + /// The given asset ID is unknown. + Unknown, + /// Recipient's address is zero. + ZeroRecipientAddress, + /// Sender's address is zero. + ZeroSenderAddress, +} +#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] +const _: () = { + impl ::scale_info::TypeInfo for FungiblesError { + type Identity = Self; + fn type_info() -> ::scale_info::Type { + ::scale_info::Type::builder() + .path( + ::scale_info::Path::new_with_replace( + "FungiblesError", + "fungibles", + &[], + ), + ) + .type_params(::alloc::vec::Vec::new()) + .variant( + ::scale_info::build::Variants::new() + .variant( + "InsufficientBalance", + |v| { + v + .index(0usize as ::core::primitive::u8) + .docs( + &["Not enough balance to fulfill a request is available."], + ) + }, + ) + .variant( + "InsufficientAllowance", + |v| { + v + .index(1usize as ::core::primitive::u8) + .docs( + &["Not enough allowance to fulfill a request is available."], + ) + }, + ) + .variant( + "IncorrectStatus", + |v| { + v + .index(2usize as ::core::primitive::u8) + .docs(&["The asset status is not the expected status."]) + }, + ) + .variant( + "InUse", + |v| { + v + .index(3usize as ::core::primitive::u8) + .docs(&["The asset ID is already taken."]) + }, + ) + .variant( + "MinBalanceZero", + |v| { + v + .index(4usize as ::core::primitive::u8) + .docs(&["Minimum balance should be non-zero."]) + }, + ) + .variant( + "NoPermission", + |v| { + v + .index(5usize as ::core::primitive::u8) + .docs( + &[ + "The signing account has no permission to do the operation.", + ], + ) + }, + ) + .variant( + "Unknown", + |v| { + v + .index(6usize as ::core::primitive::u8) + .docs(&["The given asset ID is unknown."]) + }, + ) + .variant( + "ZeroRecipientAddress", + |v| { + v + .index(7usize as ::core::primitive::u8) + .docs(&["Recipient's address is zero."]) + }, + ) + .variant( + "ZeroSenderAddress", + |v| { + v + .index(8usize as ::core::primitive::u8) + .docs(&["Sender's address is zero."]) + }, + ), + ) + } + } +}; +#[automatically_derived] +impl ::core::fmt::Debug for FungiblesError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + FungiblesError::InsufficientBalance => "InsufficientBalance", + FungiblesError::InsufficientAllowance => "InsufficientAllowance", + FungiblesError::IncorrectStatus => "IncorrectStatus", + FungiblesError::InUse => "InUse", + FungiblesError::MinBalanceZero => "MinBalanceZero", + FungiblesError::NoPermission => "NoPermission", + FungiblesError::Unknown => "Unknown", + FungiblesError::ZeroRecipientAddress => "ZeroRecipientAddress", + FungiblesError::ZeroSenderAddress => "ZeroSenderAddress", + }, + ) + } +} +#[automatically_derived] +impl ::core::marker::Copy for FungiblesError {} +#[automatically_derived] +impl ::core::clone::Clone for FungiblesError { + #[inline] + fn clone(&self) -> FungiblesError { + *self + } +} +#[automatically_derived] +impl ::core::marker::StructuralPartialEq for FungiblesError {} +#[automatically_derived] +impl ::core::cmp::PartialEq for FungiblesError { + #[inline] + fn eq(&self, other: &FungiblesError) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + } +} +#[automatically_derived] +impl ::core::cmp::Eq for FungiblesError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} +} +#[allow(deprecated)] +const _: () = { + #[automatically_derived] + impl ::scale::Encode for FungiblesError { + fn size_hint(&self) -> usize { + 1_usize + + match *self { + FungiblesError::InsufficientBalance => 0_usize, + FungiblesError::InsufficientAllowance => 0_usize, + FungiblesError::IncorrectStatus => 0_usize, + FungiblesError::InUse => 0_usize, + FungiblesError::MinBalanceZero => 0_usize, + FungiblesError::NoPermission => 0_usize, + FungiblesError::Unknown => 0_usize, + FungiblesError::ZeroRecipientAddress => 0_usize, + FungiblesError::ZeroSenderAddress => 0_usize, + _ => 0_usize, + } + } + fn encode_to<__CodecOutputEdqy: ::scale::Output + ?::core::marker::Sized>( + &self, + __codec_dest_edqy: &mut __CodecOutputEdqy, + ) { + match *self { + FungiblesError::InsufficientBalance => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(0usize as ::core::primitive::u8); + } + FungiblesError::InsufficientAllowance => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(1usize as ::core::primitive::u8); + } + FungiblesError::IncorrectStatus => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(2usize as ::core::primitive::u8); + } + FungiblesError::InUse => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(3usize as ::core::primitive::u8); + } + FungiblesError::MinBalanceZero => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(4usize as ::core::primitive::u8); + } + FungiblesError::NoPermission => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(5usize as ::core::primitive::u8); + } + FungiblesError::Unknown => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(6usize as ::core::primitive::u8); + } + FungiblesError::ZeroRecipientAddress => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(7usize as ::core::primitive::u8); + } + FungiblesError::ZeroSenderAddress => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(8usize as ::core::primitive::u8); + } + _ => {} + } + } + } + #[automatically_derived] + impl ::scale::EncodeLike for FungiblesError {} +}; +#[allow(deprecated)] +const _: () = { + #[automatically_derived] + impl ::scale::Decode for FungiblesError { + fn decode<__CodecInputEdqy: ::scale::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + match __codec_input_edqy + .read_byte() + .map_err(|e| { + e + .chain( + "Could not decode `FungiblesError`, failed to read variant byte", + ) + })? + { + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy == 0usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(FungiblesError::InsufficientBalance) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy == 1usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(FungiblesError::InsufficientAllowance) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy == 2usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(FungiblesError::IncorrectStatus) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy == 3usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(FungiblesError::InUse) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy == 4usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(FungiblesError::MinBalanceZero) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy == 5usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(FungiblesError::NoPermission) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy == 6usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(FungiblesError::Unknown) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy == 7usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(FungiblesError::ZeroRecipientAddress) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy == 8usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(FungiblesError::ZeroSenderAddress) + })(); + } + _ => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Err( + <_ as ::core::convert::Into< + _, + >>::into( + "Could not decode `FungiblesError`, variant doesn't exist", + ), + ) + })(); + } + } + } + } +}; +impl From for FungiblesError { + fn from(error: Error) -> Self { + match error { + Error::InUse => FungiblesError::InUse, + Error::MinBalanceZero => FungiblesError::MinBalanceZero, + Error::Unknown => FungiblesError::Unknown, + _ => ::core::panicking::panic("not yet implemented"), + } + } +} +/// The fungibles result type. +pub type Result = core::result::Result; +mod fungibles { + impl ::ink::env::ContractEnv for Fungibles { + type Env = pop_api::Environment; + } + type Environment = ::Env; + type AccountId = <::Env as ::ink::env::Environment>::AccountId; + type Balance = <::Env as ::ink::env::Environment>::Balance; + type Hash = <::Env as ::ink::env::Environment>::Hash; + type Timestamp = <::Env as ::ink::env::Environment>::Timestamp; + type BlockNumber = <::Env as ::ink::env::Environment>::BlockNumber; + type ChainExtension = <::Env as ::ink::env::Environment>::ChainExtension; + const MAX_EVENT_TOPICS: usize = <::Env as ::ink::env::Environment>::MAX_EVENT_TOPICS; + const _: () = { + struct Check { + salt: (), + } + }; + #[scale_info(crate = ::ink::scale_info)] + #[cfg(not(feature = "__ink_dylint_Storage"))] + pub struct Fungibles {} + const _: () = { + impl< + __ink_generic_salt: ::ink::storage::traits::StorageKey, + > ::ink::storage::traits::StorableHint<__ink_generic_salt> for Fungibles { + type Type = Fungibles; + type PreferredKey = ::ink::storage::traits::AutoKey; + } + }; + const _: () = { + impl ::ink::storage::traits::StorageKey for Fungibles { + const KEY: ::ink::primitives::Key = <() as ::ink::storage::traits::StorageKey>::KEY; + } + }; + const _: () = { + impl ::ink::storage::traits::Storable for Fungibles { + #[inline(always)] + #[allow(non_camel_case_types)] + fn decode<__ink_I: ::ink::scale::Input>( + __input: &mut __ink_I, + ) -> ::core::result::Result { + ::core::result::Result::Ok(Fungibles {}) + } + #[inline(always)] + #[allow(non_camel_case_types)] + fn encode<__ink_O: ::ink::scale::Output + ?::core::marker::Sized>( + &self, + __dest: &mut __ink_O, + ) { + match self { + Fungibles {} => {} + } + } + #[inline(always)] + #[allow(non_camel_case_types)] + fn encoded_size(&self) -> ::core::primitive::usize { + match self { + Fungibles {} => ::core::primitive::usize::MIN, + } + } + } + }; + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + impl ::ink::scale_info::TypeInfo for Fungibles { + type Identity = Self; + fn type_info() -> ::ink::scale_info::Type { + ::ink::scale_info::Type::builder() + .path( + ::ink::scale_info::Path::new_with_replace( + "Fungibles", + "fungibles::fungibles", + &[], + ), + ) + .type_params(::alloc::vec::Vec::new()) + .composite(::ink::scale_info::build::Fields::named()) + } + } + }; + const _: () = { + impl ::ink::storage::traits::StorageLayout for Fungibles { + fn layout( + __key: &::ink::primitives::Key, + ) -> ::ink::metadata::layout::Layout { + ::ink::metadata::layout::Layout::Struct( + ::ink::metadata::layout::StructLayout::new("Fungibles", []), + ) + } + } + }; + #[automatically_derived] + impl ::core::default::Default for Fungibles { + #[inline] + fn default() -> Fungibles { + Fungibles {} + } + } + const _: () = { + impl ::ink::reflect::ContractName for Fungibles { + const NAME: &'static str = "Fungibles"; + } + }; + const _: () = { + impl<'a> ::ink::codegen::Env for &'a Fungibles { + type EnvAccess = ::ink::EnvAccess< + 'a, + ::Env, + >; + fn env(self) -> Self::EnvAccess { + <::EnvAccess as ::core::default::Default>::default() + } + } + impl<'a> ::ink::codegen::StaticEnv for Fungibles { + type EnvAccess = ::ink::EnvAccess< + 'static, + ::Env, + >; + fn env() -> Self::EnvAccess { + <::EnvAccess as ::core::default::Default>::default() + } + } + }; + const _: () = { + #[allow(unused_imports)] + use ::ink::codegen::{Env as _, StaticEnv as _}; + }; + impl ::ink::reflect::DispatchableConstructorInfo<0x9BAE9D5E_u32> for Fungibles { + type Input = (); + type Output = Self; + type Storage = Fungibles; + type Error = <::ink::reflect::ConstructorOutputValue< + Self, + > as ::ink::reflect::ConstructorOutput>::Error; + const IS_RESULT: ::core::primitive::bool = <::ink::reflect::ConstructorOutputValue< + Self, + > as ::ink::reflect::ConstructorOutput>::IS_RESULT; + const CALLABLE: fn(Self::Input) -> Self::Output = |_| { Fungibles::new() }; + const PAYABLE: ::core::primitive::bool = true; + const SELECTOR: [::core::primitive::u8; 4usize] = [ + 0x9B_u8, + 0xAE_u8, + 0x9D_u8, + 0x5E_u8, + ]; + const LABEL: &'static ::core::primitive::str = "new"; + } + impl ::ink::reflect::DispatchableMessageInfo<0xDB6375A8_u32> for Fungibles { + type Input = AssetId; + type Output = Result; + type Storage = Fungibles; + const CALLABLE: fn(&mut Self::Storage, Self::Input) -> Self::Output = | + storage, + __ink_binding_0| + { Fungibles::total_supply(storage, __ink_binding_0) }; + const SELECTOR: [::core::primitive::u8; 4usize] = [ + 0xDB_u8, + 0x63_u8, + 0x75_u8, + 0xA8_u8, + ]; + const PAYABLE: ::core::primitive::bool = false; + const MUTATES: ::core::primitive::bool = false; + const LABEL: &'static ::core::primitive::str = "total_supply"; + } + impl ::ink::reflect::DispatchableMessageInfo<0x0F755A56_u32> for Fungibles { + type Input = (AssetId, AccountId32); + type Output = Result; + type Storage = Fungibles; + const CALLABLE: fn(&mut Self::Storage, Self::Input) -> Self::Output = | + storage, + (__ink_binding_0, __ink_binding_1)| + { Fungibles::balance_of(storage, __ink_binding_0, __ink_binding_1) }; + const SELECTOR: [::core::primitive::u8; 4usize] = [ + 0x0F_u8, + 0x75_u8, + 0x5A_u8, + 0x56_u8, + ]; + const PAYABLE: ::core::primitive::bool = false; + const MUTATES: ::core::primitive::bool = false; + const LABEL: &'static ::core::primitive::str = "balance_of"; + } + impl ::ink::reflect::DispatchableMessageInfo<0x6A00165E_u32> for Fungibles { + type Input = (AssetId, AccountId32, AccountId32); + type Output = Result; + type Storage = Fungibles; + const CALLABLE: fn(&mut Self::Storage, Self::Input) -> Self::Output = | + storage, + (__ink_binding_0, __ink_binding_1, __ink_binding_2)| + { + Fungibles::allowance( + storage, + __ink_binding_0, + __ink_binding_1, + __ink_binding_2, + ) + }; + const SELECTOR: [::core::primitive::u8; 4usize] = [ + 0x6A_u8, + 0x00_u8, + 0x16_u8, + 0x5E_u8, + ]; + const PAYABLE: ::core::primitive::bool = false; + const MUTATES: ::core::primitive::bool = false; + const LABEL: &'static ::core::primitive::str = "allowance"; + } + impl ::ink::reflect::DispatchableMessageInfo<0xAA6B65DB_u32> for Fungibles { + type Input = AssetId; + type Output = Result; + type Storage = Fungibles; + const CALLABLE: fn(&mut Self::Storage, Self::Input) -> Self::Output = | + storage, + __ink_binding_0| + { Fungibles::asset_exists(storage, __ink_binding_0) }; + const SELECTOR: [::core::primitive::u8; 4usize] = [ + 0xAA_u8, + 0x6B_u8, + 0x65_u8, + 0xDB_u8, + ]; + const PAYABLE: ::core::primitive::bool = false; + const MUTATES: ::core::primitive::bool = false; + const LABEL: &'static ::core::primitive::str = "asset_exists"; + } + impl ::ink::reflect::DispatchableMessageInfo<0x1F8E8E22_u32> for Fungibles { + type Input = (u32, AccountId32, Balance); + type Output = Result<()>; + type Storage = Fungibles; + const CALLABLE: fn(&mut Self::Storage, Self::Input) -> Self::Output = | + storage, + (__ink_binding_0, __ink_binding_1, __ink_binding_2)| + { + Fungibles::mint_asset( + storage, + __ink_binding_0, + __ink_binding_1, + __ink_binding_2, + ) + }; + const SELECTOR: [::core::primitive::u8; 4usize] = [ + 0x1F_u8, + 0x8E_u8, + 0x8E_u8, + 0x22_u8, + ]; + const PAYABLE: ::core::primitive::bool = false; + const MUTATES: ::core::primitive::bool = false; + const LABEL: &'static ::core::primitive::str = "mint_asset"; + } + const _: () = { + #[allow(non_camel_case_types)] + pub enum __ink_ConstructorDecoder { + Constructor0( + >::Input, + ), + } + impl ::ink::reflect::DecodeDispatch for __ink_ConstructorDecoder { + fn decode_dispatch( + input: &mut I, + ) -> ::core::result::Result + where + I: ::ink::scale::Input, + { + const CONSTRUCTOR_0: [::core::primitive::u8; 4usize] = >::SELECTOR; + match <[::core::primitive::u8; 4usize] as ::ink::scale::Decode>::decode( + input, + ) + .map_err(|_| ::ink::reflect::DispatchError::InvalidSelector)? + { + CONSTRUCTOR_0 => { + ::core::result::Result::Ok( + Self::Constructor0( + <>::Input as ::ink::scale::Decode>::decode(input) + .map_err(|_| { + ::ink::reflect::DispatchError::InvalidParameters + })?, + ), + ) + } + _invalid => { + ::core::result::Result::Err( + ::ink::reflect::DispatchError::UnknownSelector, + ) + } + } + } + } + impl ::ink::scale::Decode for __ink_ConstructorDecoder { + fn decode( + input: &mut I, + ) -> ::core::result::Result + where + I: ::ink::scale::Input, + { + ::decode_dispatch(input) + .map_err(::core::convert::Into::into) + } + } + impl ::ink::reflect::ExecuteDispatchable for __ink_ConstructorDecoder { + #[allow(clippy::nonminimal_bool)] + fn execute_dispatchable( + self, + ) -> ::core::result::Result<(), ::ink::reflect::DispatchError> { + match self { + Self::Constructor0(input) => { + if { + false + || { + let constructor_0 = false; + let constructor_0 = >::PAYABLE; + constructor_0 + } + } + && !>::PAYABLE + { + ::ink::codegen::deny_payment::< + ::Env, + >()?; + } + let result: >::Output = >::CALLABLE(input); + let output_value = ::ink::reflect::ConstructorOutputValue::new( + result, + ); + let output_result = <::ink::reflect::ConstructorOutputValue< + >::Output, + > as ::ink::reflect::ConstructorOutput< + Fungibles, + >>::as_result(&output_value); + if let ::core::result::Result::Ok(contract) = output_result + .as_ref() + { + ::ink::env::set_contract_storage::< + ::ink::primitives::Key, + Fungibles, + >( + &::KEY, + contract, + ); + } + let mut flag = ::ink::env::ReturnFlags::empty(); + if output_result.is_err() { + flag = ::ink::env::ReturnFlags::REVERT; + } + ::ink::env::return_value::< + ::ink::ConstructorResult< + ::core::result::Result< + (), + &<::ink::reflect::ConstructorOutputValue< + >::Output, + > as ::ink::reflect::ConstructorOutput>::Error, + >, + >, + >( + flag, + &::ink::ConstructorResult::Ok(output_result.map(|_| ())), + ); + } + } + } + } + impl ::ink::reflect::ContractConstructorDecoder for Fungibles { + type Type = __ink_ConstructorDecoder; + } + }; + const _: () = { + #[allow(non_camel_case_types)] + pub enum __ink_MessageDecoder { + Message0( + >::Input, + ), + Message1( + >::Input, + ), + Message2( + >::Input, + ), + Message3( + >::Input, + ), + Message4( + >::Input, + ), + } + impl ::ink::reflect::DecodeDispatch for __ink_MessageDecoder { + fn decode_dispatch( + input: &mut I, + ) -> ::core::result::Result + where + I: ::ink::scale::Input, + { + const MESSAGE_0: [::core::primitive::u8; 4usize] = >::SELECTOR; + const MESSAGE_1: [::core::primitive::u8; 4usize] = >::SELECTOR; + const MESSAGE_2: [::core::primitive::u8; 4usize] = >::SELECTOR; + const MESSAGE_3: [::core::primitive::u8; 4usize] = >::SELECTOR; + const MESSAGE_4: [::core::primitive::u8; 4usize] = >::SELECTOR; + match <[::core::primitive::u8; 4usize] as ::ink::scale::Decode>::decode( + input, + ) + .map_err(|_| ::ink::reflect::DispatchError::InvalidSelector)? + { + MESSAGE_0 => { + ::core::result::Result::Ok( + Self::Message0( + <>::Input as ::ink::scale::Decode>::decode(input) + .map_err(|_| { + ::ink::reflect::DispatchError::InvalidParameters + })?, + ), + ) + } + MESSAGE_1 => { + ::core::result::Result::Ok( + Self::Message1( + <>::Input as ::ink::scale::Decode>::decode(input) + .map_err(|_| { + ::ink::reflect::DispatchError::InvalidParameters + })?, + ), + ) + } + MESSAGE_2 => { + ::core::result::Result::Ok( + Self::Message2( + <>::Input as ::ink::scale::Decode>::decode(input) + .map_err(|_| { + ::ink::reflect::DispatchError::InvalidParameters + })?, + ), + ) + } + MESSAGE_3 => { + ::core::result::Result::Ok( + Self::Message3( + <>::Input as ::ink::scale::Decode>::decode(input) + .map_err(|_| { + ::ink::reflect::DispatchError::InvalidParameters + })?, + ), + ) + } + MESSAGE_4 => { + ::core::result::Result::Ok( + Self::Message4( + <>::Input as ::ink::scale::Decode>::decode(input) + .map_err(|_| { + ::ink::reflect::DispatchError::InvalidParameters + })?, + ), + ) + } + _invalid => { + ::core::result::Result::Err( + ::ink::reflect::DispatchError::UnknownSelector, + ) + } + } + } + } + impl ::ink::scale::Decode for __ink_MessageDecoder { + fn decode( + input: &mut I, + ) -> ::core::result::Result + where + I: ::ink::scale::Input, + { + ::decode_dispatch(input) + .map_err(::core::convert::Into::into) + } + } + fn push_contract(contract: ::core::mem::ManuallyDrop, mutates: bool) { + if mutates { + ::ink::env::set_contract_storage::< + ::ink::primitives::Key, + Fungibles, + >(&::KEY, &contract); + } + } + impl ::ink::reflect::ExecuteDispatchable for __ink_MessageDecoder { + #[allow(clippy::nonminimal_bool, clippy::let_unit_value)] + fn execute_dispatchable( + self, + ) -> ::core::result::Result<(), ::ink::reflect::DispatchError> { + let key = ::KEY; + let mut contract: ::core::mem::ManuallyDrop = ::core::mem::ManuallyDrop::new( + match ::ink::env::get_contract_storage(&key) { + ::core::result::Result::Ok( + ::core::option::Option::Some(value), + ) => value, + ::core::result::Result::Ok(::core::option::Option::None) => { + ::core::panicking::panic_fmt( + format_args!("storage entry was empty"), + ); + } + ::core::result::Result::Err(_) => { + ::core::panicking::panic_fmt( + format_args!("could not properly decode storage entry"), + ); + } + }, + ); + match self { + Self::Message0(input) => { + if { + false + || { + let message_0 = false; + let message_0 = >::PAYABLE; + message_0 + } + || { + let message_1 = false; + let message_1 = >::PAYABLE; + message_1 + } + || { + let message_2 = false; + let message_2 = >::PAYABLE; + message_2 + } + || { + let message_3 = false; + let message_3 = >::PAYABLE; + message_3 + } + || { + let message_4 = false; + let message_4 = >::PAYABLE; + message_4 + } + } + && !>::PAYABLE + { + ::ink::codegen::deny_payment::< + ::Env, + >()?; + } + let result: >::Output = >::CALLABLE(&mut contract, input); + let is_reverted = { + #[allow(unused_imports)] + use ::ink::result_info::IsResultTypeFallback as _; + ::ink::result_info::IsResultType::< + >::Output, + >::VALUE + } + && { + #[allow(unused_imports)] + use ::ink::result_info::IsResultErrFallback as _; + ::ink::result_info::IsResultErr(&result).value() + }; + let mut flag = ::ink::env::ReturnFlags::REVERT; + if !is_reverted { + flag = ::ink::env::ReturnFlags::empty(); + push_contract( + contract, + >::MUTATES, + ); + } + ::ink::env::return_value::< + ::ink::MessageResult< + >::Output, + >, + >(flag, &::ink::MessageResult::Ok(result)) + } + Self::Message1(input) => { + if { + false + || { + let message_0 = false; + let message_0 = >::PAYABLE; + message_0 + } + || { + let message_1 = false; + let message_1 = >::PAYABLE; + message_1 + } + || { + let message_2 = false; + let message_2 = >::PAYABLE; + message_2 + } + || { + let message_3 = false; + let message_3 = >::PAYABLE; + message_3 + } + || { + let message_4 = false; + let message_4 = >::PAYABLE; + message_4 + } + } + && !>::PAYABLE + { + ::ink::codegen::deny_payment::< + ::Env, + >()?; + } + let result: >::Output = >::CALLABLE(&mut contract, input); + let is_reverted = { + #[allow(unused_imports)] + use ::ink::result_info::IsResultTypeFallback as _; + ::ink::result_info::IsResultType::< + >::Output, + >::VALUE + } + && { + #[allow(unused_imports)] + use ::ink::result_info::IsResultErrFallback as _; + ::ink::result_info::IsResultErr(&result).value() + }; + let mut flag = ::ink::env::ReturnFlags::REVERT; + if !is_reverted { + flag = ::ink::env::ReturnFlags::empty(); + push_contract( + contract, + >::MUTATES, + ); + } + ::ink::env::return_value::< + ::ink::MessageResult< + >::Output, + >, + >(flag, &::ink::MessageResult::Ok(result)) + } + Self::Message2(input) => { + if { + false + || { + let message_0 = false; + let message_0 = >::PAYABLE; + message_0 + } + || { + let message_1 = false; + let message_1 = >::PAYABLE; + message_1 + } + || { + let message_2 = false; + let message_2 = >::PAYABLE; + message_2 + } + || { + let message_3 = false; + let message_3 = >::PAYABLE; + message_3 + } + || { + let message_4 = false; + let message_4 = >::PAYABLE; + message_4 + } + } + && !>::PAYABLE + { + ::ink::codegen::deny_payment::< + ::Env, + >()?; + } + let result: >::Output = >::CALLABLE(&mut contract, input); + let is_reverted = { + #[allow(unused_imports)] + use ::ink::result_info::IsResultTypeFallback as _; + ::ink::result_info::IsResultType::< + >::Output, + >::VALUE + } + && { + #[allow(unused_imports)] + use ::ink::result_info::IsResultErrFallback as _; + ::ink::result_info::IsResultErr(&result).value() + }; + let mut flag = ::ink::env::ReturnFlags::REVERT; + if !is_reverted { + flag = ::ink::env::ReturnFlags::empty(); + push_contract( + contract, + >::MUTATES, + ); + } + ::ink::env::return_value::< + ::ink::MessageResult< + >::Output, + >, + >(flag, &::ink::MessageResult::Ok(result)) + } + Self::Message3(input) => { + if { + false + || { + let message_0 = false; + let message_0 = >::PAYABLE; + message_0 + } + || { + let message_1 = false; + let message_1 = >::PAYABLE; + message_1 + } + || { + let message_2 = false; + let message_2 = >::PAYABLE; + message_2 + } + || { + let message_3 = false; + let message_3 = >::PAYABLE; + message_3 + } + || { + let message_4 = false; + let message_4 = >::PAYABLE; + message_4 + } + } + && !>::PAYABLE + { + ::ink::codegen::deny_payment::< + ::Env, + >()?; + } + let result: >::Output = >::CALLABLE(&mut contract, input); + let is_reverted = { + #[allow(unused_imports)] + use ::ink::result_info::IsResultTypeFallback as _; + ::ink::result_info::IsResultType::< + >::Output, + >::VALUE + } + && { + #[allow(unused_imports)] + use ::ink::result_info::IsResultErrFallback as _; + ::ink::result_info::IsResultErr(&result).value() + }; + let mut flag = ::ink::env::ReturnFlags::REVERT; + if !is_reverted { + flag = ::ink::env::ReturnFlags::empty(); + push_contract( + contract, + >::MUTATES, + ); + } + ::ink::env::return_value::< + ::ink::MessageResult< + >::Output, + >, + >(flag, &::ink::MessageResult::Ok(result)) + } + Self::Message4(input) => { + if { + false + || { + let message_0 = false; + let message_0 = >::PAYABLE; + message_0 + } + || { + let message_1 = false; + let message_1 = >::PAYABLE; + message_1 + } + || { + let message_2 = false; + let message_2 = >::PAYABLE; + message_2 + } + || { + let message_3 = false; + let message_3 = >::PAYABLE; + message_3 + } + || { + let message_4 = false; + let message_4 = >::PAYABLE; + message_4 + } + } + && !>::PAYABLE + { + ::ink::codegen::deny_payment::< + ::Env, + >()?; + } + let result: >::Output = >::CALLABLE(&mut contract, input); + let is_reverted = { + #[allow(unused_imports)] + use ::ink::result_info::IsResultTypeFallback as _; + ::ink::result_info::IsResultType::< + >::Output, + >::VALUE + } + && { + #[allow(unused_imports)] + use ::ink::result_info::IsResultErrFallback as _; + ::ink::result_info::IsResultErr(&result).value() + }; + let mut flag = ::ink::env::ReturnFlags::REVERT; + if !is_reverted { + flag = ::ink::env::ReturnFlags::empty(); + push_contract( + contract, + >::MUTATES, + ); + } + ::ink::env::return_value::< + ::ink::MessageResult< + >::Output, + >, + >(flag, &::ink::MessageResult::Ok(result)) + } + }; + } + } + impl ::ink::reflect::ContractMessageDecoder for Fungibles { + type Type = __ink_MessageDecoder; + } + }; + const _: () = { + use ::ink::codegen::{Env as _, StaticEnv as _}; + const _: ::ink::codegen::utils::IsSameType = ::ink::codegen::utils::IsSameType::< + Fungibles, + >::new(); + impl Fungibles { + #[cfg(not(feature = "__ink_dylint_Constructor"))] + pub fn new() -> Self { + ::ink_env::debug_message( + &{ + let res = ::alloc::fmt::format( + format_args!( + "{0}\n", + { + let res = ::alloc::fmt::format( + format_args!("PopApiAssetsExample::new"), + ); + res + }, + ), + ); + res + }, + ); + Default::default() + } + pub fn total_supply(&self, id: AssetId) -> Result { + total_supply(id).map_err(From::from) + } + pub fn balance_of( + &self, + id: AssetId, + owner: AccountId32, + ) -> Result { + balance_of(id, owner).map_err(From::from) + } + pub fn allowance( + &self, + id: AssetId, + owner: AccountId32, + spender: AccountId32, + ) -> Result { + allowance(id, owner, spender).map_err(From::from) + } + pub fn asset_exists(&self, id: AssetId) -> Result { + asset_exists(id).map_err(From::from) + } + pub fn mint_asset( + &self, + id: u32, + beneficiary: AccountId32, + amount: Balance, + ) -> Result<()> { + ::ink_env::debug_message( + &{ + let res = ::alloc::fmt::format( + format_args!( + "{0}\n", + { + let res = ::alloc::fmt::format( + format_args!( + "PopApiAssetsExample::mint_asset_through_runtime: id: {0:?} beneficiary: {1:?} amount: {2:?}", + id, + beneficiary, + amount, + ), + ); + res + }, + ), + ); + res + }, + ); + let result = mint(id, beneficiary, amount)?; + ::ink_env::debug_message( + &{ + let res = ::alloc::fmt::format( + format_args!( + "{0}\n", + { + let res = ::alloc::fmt::format( + format_args!("Result: {0:?}", result), + ); + res + }, + ), + ); + res + }, + ); + Ok(()) + } + } + const _: () = { + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchInput, + >(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchOutput>, + >(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchInput, + >(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchInput, + >(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchOutput>, + >(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchInput, + >(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchInput, + >(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchInput, + >(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchOutput>, + >(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchInput, + >(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchOutput>, + >(); + ::ink::codegen::utils::consume_type::<::ink::codegen::DispatchInput>(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchInput, + >(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchInput, + >(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchOutput>, + >(); + }; + }; + const _: () = { + #[codec(crate = ::ink::scale)] + #[scale_info(crate = ::ink::scale_info)] + /// The ink! smart contract's call builder. + /// + /// Implements the underlying on-chain calling of the ink! smart contract + /// messages and trait implementations in a type safe way. + #[repr(transparent)] + pub struct CallBuilder { + account_id: AccountId, + } + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + impl ::ink::scale_info::TypeInfo for CallBuilder { + type Identity = Self; + fn type_info() -> ::ink::scale_info::Type { + ::ink::scale_info::Type::builder() + .path( + ::ink::scale_info::Path::new_with_replace( + "CallBuilder", + "fungibles::fungibles", + &[], + ), + ) + .type_params(::alloc::vec::Vec::new()) + .docs( + &[ + "The ink! smart contract's call builder.", + "", + "Implements the underlying on-chain calling of the ink! smart contract", + "messages and trait implementations in a type safe way.", + ], + ) + .composite( + ::ink::scale_info::build::Fields::named() + .field(|f| { + f + .ty::() + .name("account_id") + .type_name("AccountId") + }), + ) + } + } + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::ink::scale::Decode for CallBuilder { + fn decode<__CodecInputEdqy: ::ink::scale::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + ::core::result::Result::Ok(CallBuilder { + account_id: { + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `CallBuilder::account_id`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + }) + } + fn decode_into<__CodecInputEdqy: ::ink::scale::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + dst_: &mut ::core::mem::MaybeUninit, + ) -> ::core::result::Result< + ::ink::scale::DecodeFinished, + ::ink::scale::Error, + > { + match ( + &::core::mem::size_of::(), + &::core::mem::size_of::(), + ) { + (left_val, right_val) => { + if !(*left_val == *right_val) { + let kind = ::core::panicking::AssertKind::Eq; + ::core::panicking::assert_failed( + kind, + &*left_val, + &*right_val, + ::core::option::Option::None, + ); + } + } + }; + if !(if ::core::mem::size_of::() > 0 { 1 } else { 0 } + <= 1) + { + ::core::panicking::panic( + "assertion failed: if ::core::mem::size_of::() > 0 { 1 } else { 0 } <= 1", + ) + } + { + let dst_: &mut ::core::mem::MaybeUninit = dst_; + let dst_: &mut ::core::mem::MaybeUninit = unsafe { + &mut *dst_ + .as_mut_ptr() + .cast::<::core::mem::MaybeUninit>() + }; + ::decode_into( + __codec_input_edqy, + dst_, + )?; + } + unsafe { + ::core::result::Result::Ok( + ::ink::scale::DecodeFinished::assert_decoding_finished(), + ) + } + } + } + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::ink::scale::Encode for CallBuilder { + fn size_hint(&self) -> usize { + ::ink::scale::Encode::size_hint(&&self.account_id) + } + fn encode_to< + __CodecOutputEdqy: ::ink::scale::Output + ?::core::marker::Sized, + >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { + ::ink::scale::Encode::encode_to(&&self.account_id, __codec_dest_edqy) + } + fn encode( + &self, + ) -> ::ink::scale::alloc::vec::Vec<::core::primitive::u8> { + ::ink::scale::Encode::encode(&&self.account_id) + } + fn using_encoded< + __CodecOutputReturn, + __CodecUsingEncodedCallback: ::core::ops::FnOnce( + &[::core::primitive::u8], + ) -> __CodecOutputReturn, + >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { + ::ink::scale::Encode::using_encoded(&&self.account_id, f) + } + } + #[automatically_derived] + impl ::ink::scale::EncodeLike for CallBuilder {} + }; + #[automatically_derived] + impl ::core::fmt::Debug for CallBuilder { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "CallBuilder", + "account_id", + &&self.account_id, + ) + } + } + #[automatically_derived] + impl ::core::hash::Hash for CallBuilder { + #[inline] + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + ::core::hash::Hash::hash(&self.account_id, state) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for CallBuilder {} + #[automatically_derived] + impl ::core::cmp::PartialEq for CallBuilder { + #[inline] + fn eq(&self, other: &CallBuilder) -> bool { + self.account_id == other.account_id + } + } + #[automatically_derived] + impl ::core::cmp::Eq for CallBuilder { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::clone::Clone for CallBuilder { + #[inline] + fn clone(&self) -> CallBuilder { + CallBuilder { + account_id: ::core::clone::Clone::clone(&self.account_id), + } + } + } + const _: () = { + impl ::ink::storage::traits::StorageLayout for CallBuilder { + fn layout( + __key: &::ink::primitives::Key, + ) -> ::ink::metadata::layout::Layout { + ::ink::metadata::layout::Layout::Struct( + ::ink::metadata::layout::StructLayout::new( + "CallBuilder", + [ + ::ink::metadata::layout::FieldLayout::new( + "account_id", + ::layout( + __key, + ), + ), + ], + ), + ) + } + } + }; + const _: () = { + impl ::ink::codegen::ContractCallBuilder for Fungibles { + type Type = CallBuilder; + } + impl ::ink::env::ContractEnv for CallBuilder { + type Env = ::Env; + } + }; + impl ::ink::env::call::FromAccountId for CallBuilder { + #[inline] + fn from_account_id(account_id: AccountId) -> Self { + Self { account_id } + } + } + impl ::ink::ToAccountId for CallBuilder { + #[inline] + fn to_account_id(&self) -> AccountId { + ::clone(&self.account_id) + } + } + impl ::core::convert::AsRef for CallBuilder { + fn as_ref(&self) -> &AccountId { + &self.account_id + } + } + impl ::core::convert::AsMut for CallBuilder { + fn as_mut(&mut self) -> &mut AccountId { + &mut self.account_id + } + } + impl CallBuilder { + #[allow(clippy::type_complexity)] + #[inline] + pub fn total_supply( + &self, + __ink_binding_0: AssetId, + ) -> ::ink::env::call::CallBuilder< + Environment, + ::ink::env::call::utils::Set<::ink::env::call::Call>, + ::ink::env::call::utils::Set< + ::ink::env::call::ExecutionInput< + ::ink::env::call::utils::ArgumentList< + ::ink::env::call::utils::Argument, + ::ink::env::call::utils::EmptyArgumentList, + >, + >, + >, + ::ink::env::call::utils::Set< + ::ink::env::call::utils::ReturnType>, + >, + > { + ::ink::env::call::build_call::() + .call(::ink::ToAccountId::to_account_id(self)) + .exec_input( + ::ink::env::call::ExecutionInput::new( + ::ink::env::call::Selector::new([ + 0xDB_u8, + 0x63_u8, + 0x75_u8, + 0xA8_u8, + ]), + ) + .push_arg(__ink_binding_0), + ) + .returns::>() + } + #[allow(clippy::type_complexity)] + #[inline] + pub fn balance_of( + &self, + __ink_binding_0: AssetId, + __ink_binding_1: AccountId32, + ) -> ::ink::env::call::CallBuilder< + Environment, + ::ink::env::call::utils::Set<::ink::env::call::Call>, + ::ink::env::call::utils::Set< + ::ink::env::call::ExecutionInput< + ::ink::env::call::utils::ArgumentList< + ::ink::env::call::utils::Argument, + ::ink::env::call::utils::ArgumentList< + ::ink::env::call::utils::Argument, + ::ink::env::call::utils::EmptyArgumentList, + >, + >, + >, + >, + ::ink::env::call::utils::Set< + ::ink::env::call::utils::ReturnType>, + >, + > { + ::ink::env::call::build_call::() + .call(::ink::ToAccountId::to_account_id(self)) + .exec_input( + ::ink::env::call::ExecutionInput::new( + ::ink::env::call::Selector::new([ + 0x0F_u8, + 0x75_u8, + 0x5A_u8, + 0x56_u8, + ]), + ) + .push_arg(__ink_binding_0) + .push_arg(__ink_binding_1), + ) + .returns::>() + } + #[allow(clippy::type_complexity)] + #[inline] + pub fn allowance( + &self, + __ink_binding_0: AssetId, + __ink_binding_1: AccountId32, + __ink_binding_2: AccountId32, + ) -> ::ink::env::call::CallBuilder< + Environment, + ::ink::env::call::utils::Set<::ink::env::call::Call>, + ::ink::env::call::utils::Set< + ::ink::env::call::ExecutionInput< + ::ink::env::call::utils::ArgumentList< + ::ink::env::call::utils::Argument, + ::ink::env::call::utils::ArgumentList< + ::ink::env::call::utils::Argument, + ::ink::env::call::utils::ArgumentList< + ::ink::env::call::utils::Argument, + ::ink::env::call::utils::EmptyArgumentList, + >, + >, + >, + >, + >, + ::ink::env::call::utils::Set< + ::ink::env::call::utils::ReturnType>, + >, + > { + ::ink::env::call::build_call::() + .call(::ink::ToAccountId::to_account_id(self)) + .exec_input( + ::ink::env::call::ExecutionInput::new( + ::ink::env::call::Selector::new([ + 0x6A_u8, + 0x00_u8, + 0x16_u8, + 0x5E_u8, + ]), + ) + .push_arg(__ink_binding_0) + .push_arg(__ink_binding_1) + .push_arg(__ink_binding_2), + ) + .returns::>() + } + #[allow(clippy::type_complexity)] + #[inline] + pub fn asset_exists( + &self, + __ink_binding_0: AssetId, + ) -> ::ink::env::call::CallBuilder< + Environment, + ::ink::env::call::utils::Set<::ink::env::call::Call>, + ::ink::env::call::utils::Set< + ::ink::env::call::ExecutionInput< + ::ink::env::call::utils::ArgumentList< + ::ink::env::call::utils::Argument, + ::ink::env::call::utils::EmptyArgumentList, + >, + >, + >, + ::ink::env::call::utils::Set< + ::ink::env::call::utils::ReturnType>, + >, + > { + ::ink::env::call::build_call::() + .call(::ink::ToAccountId::to_account_id(self)) + .exec_input( + ::ink::env::call::ExecutionInput::new( + ::ink::env::call::Selector::new([ + 0xAA_u8, + 0x6B_u8, + 0x65_u8, + 0xDB_u8, + ]), + ) + .push_arg(__ink_binding_0), + ) + .returns::>() + } + #[allow(clippy::type_complexity)] + #[inline] + pub fn mint_asset( + &self, + __ink_binding_0: u32, + __ink_binding_1: AccountId32, + __ink_binding_2: Balance, + ) -> ::ink::env::call::CallBuilder< + Environment, + ::ink::env::call::utils::Set<::ink::env::call::Call>, + ::ink::env::call::utils::Set< + ::ink::env::call::ExecutionInput< + ::ink::env::call::utils::ArgumentList< + ::ink::env::call::utils::Argument, + ::ink::env::call::utils::ArgumentList< + ::ink::env::call::utils::Argument, + ::ink::env::call::utils::ArgumentList< + ::ink::env::call::utils::Argument, + ::ink::env::call::utils::EmptyArgumentList, + >, + >, + >, + >, + >, + ::ink::env::call::utils::Set< + ::ink::env::call::utils::ReturnType>, + >, + > { + ::ink::env::call::build_call::() + .call(::ink::ToAccountId::to_account_id(self)) + .exec_input( + ::ink::env::call::ExecutionInput::new( + ::ink::env::call::Selector::new([ + 0x1F_u8, + 0x8E_u8, + 0x8E_u8, + 0x22_u8, + ]), + ) + .push_arg(__ink_binding_0) + .push_arg(__ink_binding_1) + .push_arg(__ink_binding_2), + ) + .returns::>() + } + } + }; + #[codec(crate = ::ink::scale)] + #[scale_info(crate = ::ink::scale_info)] + pub struct FungiblesRef { + inner: ::Type, + } + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + impl ::ink::scale_info::TypeInfo for FungiblesRef { + type Identity = Self; + fn type_info() -> ::ink::scale_info::Type { + ::ink::scale_info::Type::builder() + .path( + ::ink::scale_info::Path::new_with_replace( + "FungiblesRef", + "fungibles::fungibles", + &[], + ), + ) + .type_params(::alloc::vec::Vec::new()) + .composite( + ::ink::scale_info::build::Fields::named() + .field(|f| { + f + .ty::< + ::Type, + >() + .name("inner") + .type_name( + "::Type", + ) + }), + ) + } + } + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::ink::scale::Decode for FungiblesRef { + fn decode<__CodecInputEdqy: ::ink::scale::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + ::core::result::Result::Ok(FungiblesRef { + inner: { + let __codec_res_edqy = <::Type as ::ink::scale::Decode>::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `FungiblesRef::inner`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + }) + } + } + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::ink::scale::Encode for FungiblesRef { + fn size_hint(&self) -> usize { + ::ink::scale::Encode::size_hint(&&self.inner) + } + fn encode_to< + __CodecOutputEdqy: ::ink::scale::Output + ?::core::marker::Sized, + >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { + ::ink::scale::Encode::encode_to(&&self.inner, __codec_dest_edqy) + } + fn encode(&self) -> ::ink::scale::alloc::vec::Vec<::core::primitive::u8> { + ::ink::scale::Encode::encode(&&self.inner) + } + fn using_encoded< + __CodecOutputReturn, + __CodecUsingEncodedCallback: ::core::ops::FnOnce( + &[::core::primitive::u8], + ) -> __CodecOutputReturn, + >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { + ::ink::scale::Encode::using_encoded(&&self.inner, f) + } + } + #[automatically_derived] + impl ::ink::scale::EncodeLike for FungiblesRef {} + }; + #[automatically_derived] + impl ::core::fmt::Debug for FungiblesRef { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "FungiblesRef", + "inner", + &&self.inner, + ) + } + } + #[automatically_derived] + impl ::core::hash::Hash for FungiblesRef { + #[inline] + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + ::core::hash::Hash::hash(&self.inner, state) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for FungiblesRef {} + #[automatically_derived] + impl ::core::cmp::PartialEq for FungiblesRef { + #[inline] + fn eq(&self, other: &FungiblesRef) -> bool { + self.inner == other.inner + } + } + #[automatically_derived] + impl ::core::cmp::Eq for FungiblesRef { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq< + ::Type, + >; + } + } + #[automatically_derived] + impl ::core::clone::Clone for FungiblesRef { + #[inline] + fn clone(&self) -> FungiblesRef { + FungiblesRef { + inner: ::core::clone::Clone::clone(&self.inner), + } + } + } + const _: () = { + impl ::ink::storage::traits::StorageLayout for FungiblesRef { + fn layout( + __key: &::ink::primitives::Key, + ) -> ::ink::metadata::layout::Layout { + ::ink::metadata::layout::Layout::Struct( + ::ink::metadata::layout::StructLayout::new( + "FungiblesRef", + [ + ::ink::metadata::layout::FieldLayout::new( + "inner", + <::Type as ::ink::storage::traits::StorageLayout>::layout( + __key, + ), + ), + ], + ), + ) + } + } + }; + const _: () = { + impl ::ink::env::ContractReference for Fungibles { + type Type = FungiblesRef; + } + impl ::ink::env::call::ConstructorReturnType for Fungibles { + type Output = FungiblesRef; + type Error = (); + fn ok(value: FungiblesRef) -> Self::Output { + value + } + } + impl ::ink::env::call::ConstructorReturnType + for ::core::result::Result + where + E: ::ink::scale::Decode, + { + const IS_RESULT: bool = true; + type Output = ::core::result::Result; + type Error = E; + fn ok(value: FungiblesRef) -> Self::Output { + ::core::result::Result::Ok(value) + } + fn err(err: Self::Error) -> ::core::option::Option { + ::core::option::Option::Some(::core::result::Result::Err(err)) + } + } + impl ::ink::env::ContractEnv for FungiblesRef { + type Env = ::Env; + } + }; + impl FungiblesRef { + #[inline] + #[allow(clippy::type_complexity)] + pub fn new() -> ::ink::env::call::CreateBuilder< + Environment, + Self, + ::ink::env::call::utils::Unset, + ::ink::env::call::utils::Set< + ::ink::env::call::LimitParamsV2< + ::Env, + >, + >, + ::ink::env::call::utils::Unset, + ::ink::env::call::utils::Set< + ::ink::env::call::ExecutionInput< + ::ink::env::call::utils::EmptyArgumentList, + >, + >, + ::ink::env::call::utils::Unset<::ink::env::call::state::Salt>, + ::ink::env::call::utils::Set<::ink::env::call::utils::ReturnType>, + > { + ::ink::env::call::build_create::() + .exec_input( + ::ink::env::call::ExecutionInput::new( + ::ink::env::call::Selector::new([ + 0x9B_u8, + 0xAE_u8, + 0x9D_u8, + 0x5E_u8, + ]), + ), + ) + .returns::() + } + #[inline] + pub fn total_supply(&self, id: AssetId) -> Result { + self.try_total_supply(id) + .unwrap_or_else(|error| { + ::core::panicking::panic_fmt( + format_args!( + "encountered error while calling {0}::{1}: {2:?}", + "Fungibles", + "total_supply", + error, + ), + ); + }) + } + #[inline] + pub fn try_total_supply( + &self, + id: AssetId, + ) -> ::ink::MessageResult> { + ::call(self) + .total_supply(id) + .try_invoke() + .unwrap_or_else(|error| { + ::core::panicking::panic_fmt( + format_args!( + "encountered error while calling {0}::{1}: {2:?}", + "Fungibles", + "total_supply", + error, + ), + ); + }) + } + #[inline] + pub fn balance_of(&self, id: AssetId, owner: AccountId32) -> Result { + self.try_balance_of(id, owner) + .unwrap_or_else(|error| { + ::core::panicking::panic_fmt( + format_args!( + "encountered error while calling {0}::{1}: {2:?}", + "Fungibles", + "balance_of", + error, + ), + ); + }) + } + #[inline] + pub fn try_balance_of( + &self, + id: AssetId, + owner: AccountId32, + ) -> ::ink::MessageResult> { + ::call(self) + .balance_of(id, owner) + .try_invoke() + .unwrap_or_else(|error| { + ::core::panicking::panic_fmt( + format_args!( + "encountered error while calling {0}::{1}: {2:?}", + "Fungibles", + "balance_of", + error, + ), + ); + }) + } + #[inline] + pub fn allowance( + &self, + id: AssetId, + owner: AccountId32, + spender: AccountId32, + ) -> Result { + self.try_allowance(id, owner, spender) + .unwrap_or_else(|error| { + ::core::panicking::panic_fmt( + format_args!( + "encountered error while calling {0}::{1}: {2:?}", + "Fungibles", + "allowance", + error, + ), + ); + }) + } + #[inline] + pub fn try_allowance( + &self, + id: AssetId, + owner: AccountId32, + spender: AccountId32, + ) -> ::ink::MessageResult> { + ::call(self) + .allowance(id, owner, spender) + .try_invoke() + .unwrap_or_else(|error| { + ::core::panicking::panic_fmt( + format_args!( + "encountered error while calling {0}::{1}: {2:?}", + "Fungibles", + "allowance", + error, + ), + ); + }) + } + #[inline] + pub fn asset_exists(&self, id: AssetId) -> Result { + self.try_asset_exists(id) + .unwrap_or_else(|error| { + ::core::panicking::panic_fmt( + format_args!( + "encountered error while calling {0}::{1}: {2:?}", + "Fungibles", + "asset_exists", + error, + ), + ); + }) + } + #[inline] + pub fn try_asset_exists( + &self, + id: AssetId, + ) -> ::ink::MessageResult> { + ::call(self) + .asset_exists(id) + .try_invoke() + .unwrap_or_else(|error| { + ::core::panicking::panic_fmt( + format_args!( + "encountered error while calling {0}::{1}: {2:?}", + "Fungibles", + "asset_exists", + error, + ), + ); + }) + } + #[inline] + pub fn mint_asset( + &self, + id: u32, + beneficiary: AccountId32, + amount: Balance, + ) -> Result<()> { + self.try_mint_asset(id, beneficiary, amount) + .unwrap_or_else(|error| { + ::core::panicking::panic_fmt( + format_args!( + "encountered error while calling {0}::{1}: {2:?}", + "Fungibles", + "mint_asset", + error, + ), + ); + }) + } + #[inline] + pub fn try_mint_asset( + &self, + id: u32, + beneficiary: AccountId32, + amount: Balance, + ) -> ::ink::MessageResult> { + ::call(self) + .mint_asset(id, beneficiary, amount) + .try_invoke() + .unwrap_or_else(|error| { + ::core::panicking::panic_fmt( + format_args!( + "encountered error while calling {0}::{1}: {2:?}", + "Fungibles", + "mint_asset", + error, + ), + ); + }) + } + } + const _: () = { + impl ::ink::codegen::TraitCallBuilder for FungiblesRef { + type Builder = ::Type; + #[inline] + fn call(&self) -> &Self::Builder { + &self.inner + } + #[inline] + fn call_mut(&mut self) -> &mut Self::Builder { + &mut self.inner + } + } + }; + impl ::ink::env::call::FromAccountId for FungiblesRef { + #[inline] + fn from_account_id(account_id: AccountId) -> Self { + Self { + inner: <::Type as ::ink::env::call::FromAccountId< + Environment, + >>::from_account_id(account_id), + } + } + } + impl ::ink::ToAccountId for FungiblesRef { + #[inline] + fn to_account_id(&self) -> AccountId { + <::Type as ::ink::ToAccountId< + Environment, + >>::to_account_id(&self.inner) + } + } + impl ::core::convert::AsRef for FungiblesRef { + fn as_ref(&self) -> &AccountId { + <_ as ::core::convert::AsRef>::as_ref(&self.inner) + } + } + impl ::core::convert::AsMut for FungiblesRef { + fn as_mut(&mut self) -> &mut AccountId { + <_ as ::core::convert::AsMut>::as_mut(&mut self.inner) + } + } + #[cfg(feature = "std")] + #[cfg(not(feature = "ink-as-dependency"))] + const _: () = { + #[no_mangle] + pub fn __ink_generate_metadata() -> ::ink::metadata::InkProject { + let layout = ::ink::metadata::layout::Layout::Root( + ::ink::metadata::layout::RootLayout::new( + <::ink::metadata::layout::LayoutKey as ::core::convert::From< + ::ink::primitives::Key, + >>::from(::KEY), + ::layout( + &::KEY, + ), + ::ink::scale_info::meta_type::(), + ), + ); + ::ink::metadata::layout::ValidateLayout::validate(&layout) + .unwrap_or_else(|error| { + { + ::core::panicking::panic_fmt( + format_args!("metadata ink! generation failed: {0}", error), + ); + } + }); + ::ink::metadata::InkProject::new( + layout, + ::ink::metadata::ContractSpec::new() + .constructors([ + ::ink::metadata::ConstructorSpec::from_label("new") + .selector([0x9B_u8, 0xAE_u8, 0x9D_u8, 0x5E_u8]) + .args([]) + .payable(true) + .default(false) + .returns( + ::ink::metadata::ReturnTypeSpec::new( + if >::IS_RESULT { + ::ink::metadata::TypeSpec::with_name_str::< + ::ink::ConstructorResult< + ::core::result::Result< + (), + >::Error, + >, + >, + >("ink_primitives::ConstructorResult") + } else { + ::ink::metadata::TypeSpec::with_name_str::< + ::ink::ConstructorResult<()>, + >("ink_primitives::ConstructorResult") + }, + ), + ) + .docs([]) + .done(), + ]) + .messages([ + ::ink::metadata::MessageSpec::from_label("total_supply") + .selector([0xDB_u8, 0x63_u8, 0x75_u8, 0xA8_u8]) + .args([ + ::ink::metadata::MessageParamSpec::new("id") + .of_type( + ::ink::metadata::TypeSpec::with_name_segs::< + AssetId, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["AssetId"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .done(), + ]) + .returns( + ::ink::metadata::ReturnTypeSpec::new( + ::ink::metadata::TypeSpec::with_name_segs::< + ::ink::MessageResult>, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter([ + "ink", + "MessageResult", + ]), + ::core::convert::AsRef::as_ref, + ), + ), + ), + ) + .mutates(false) + .payable(false) + .default(false) + .docs([]) + .done(), + ::ink::metadata::MessageSpec::from_label("balance_of") + .selector([0x0F_u8, 0x75_u8, 0x5A_u8, 0x56_u8]) + .args([ + ::ink::metadata::MessageParamSpec::new("id") + .of_type( + ::ink::metadata::TypeSpec::with_name_segs::< + AssetId, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["AssetId"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .done(), + ::ink::metadata::MessageParamSpec::new("owner") + .of_type( + ::ink::metadata::TypeSpec::with_name_segs::< + AccountId32, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["AccountId32"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .done(), + ]) + .returns( + ::ink::metadata::ReturnTypeSpec::new( + ::ink::metadata::TypeSpec::with_name_segs::< + ::ink::MessageResult>, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter([ + "ink", + "MessageResult", + ]), + ::core::convert::AsRef::as_ref, + ), + ), + ), + ) + .mutates(false) + .payable(false) + .default(false) + .docs([]) + .done(), + ::ink::metadata::MessageSpec::from_label("allowance") + .selector([0x6A_u8, 0x00_u8, 0x16_u8, 0x5E_u8]) + .args([ + ::ink::metadata::MessageParamSpec::new("id") + .of_type( + ::ink::metadata::TypeSpec::with_name_segs::< + AssetId, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["AssetId"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .done(), + ::ink::metadata::MessageParamSpec::new("owner") + .of_type( + ::ink::metadata::TypeSpec::with_name_segs::< + AccountId32, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["AccountId32"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .done(), + ::ink::metadata::MessageParamSpec::new("spender") + .of_type( + ::ink::metadata::TypeSpec::with_name_segs::< + AccountId32, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["AccountId32"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .done(), + ]) + .returns( + ::ink::metadata::ReturnTypeSpec::new( + ::ink::metadata::TypeSpec::with_name_segs::< + ::ink::MessageResult>, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter([ + "ink", + "MessageResult", + ]), + ::core::convert::AsRef::as_ref, + ), + ), + ), + ) + .mutates(false) + .payable(false) + .default(false) + .docs([]) + .done(), + ::ink::metadata::MessageSpec::from_label("asset_exists") + .selector([0xAA_u8, 0x6B_u8, 0x65_u8, 0xDB_u8]) + .args([ + ::ink::metadata::MessageParamSpec::new("id") + .of_type( + ::ink::metadata::TypeSpec::with_name_segs::< + AssetId, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["AssetId"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .done(), + ]) + .returns( + ::ink::metadata::ReturnTypeSpec::new( + ::ink::metadata::TypeSpec::with_name_segs::< + ::ink::MessageResult>, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter([ + "ink", + "MessageResult", + ]), + ::core::convert::AsRef::as_ref, + ), + ), + ), + ) + .mutates(false) + .payable(false) + .default(false) + .docs([]) + .done(), + ::ink::metadata::MessageSpec::from_label("mint_asset") + .selector([0x1F_u8, 0x8E_u8, 0x8E_u8, 0x22_u8]) + .args([ + ::ink::metadata::MessageParamSpec::new("id") + .of_type( + ::ink::metadata::TypeSpec::with_name_segs::< + u32, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["u32"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .done(), + ::ink::metadata::MessageParamSpec::new("beneficiary") + .of_type( + ::ink::metadata::TypeSpec::with_name_segs::< + AccountId32, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["AccountId32"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .done(), + ::ink::metadata::MessageParamSpec::new("amount") + .of_type( + ::ink::metadata::TypeSpec::with_name_segs::< + Balance, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["Balance"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .done(), + ]) + .returns( + ::ink::metadata::ReturnTypeSpec::new( + ::ink::metadata::TypeSpec::with_name_segs::< + ::ink::MessageResult>, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter([ + "ink", + "MessageResult", + ]), + ::core::convert::AsRef::as_ref, + ), + ), + ), + ) + .mutates(false) + .payable(false) + .default(false) + .docs([]) + .done(), + ]) + .collect_events() + .docs([]) + .lang_error( + ::ink::metadata::TypeSpec::with_name_segs::< + ::ink::LangError, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["ink", "LangError"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .environment( + ::ink::metadata::EnvironmentSpec::new() + .account_id( + ::ink::metadata::TypeSpec::with_name_segs::< + AccountId, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["AccountId"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .balance( + ::ink::metadata::TypeSpec::with_name_segs::< + Balance, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["Balance"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .hash( + ::ink::metadata::TypeSpec::with_name_segs::< + Hash, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["Hash"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .timestamp( + ::ink::metadata::TypeSpec::with_name_segs::< + Timestamp, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["Timestamp"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .block_number( + ::ink::metadata::TypeSpec::with_name_segs::< + BlockNumber, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["BlockNumber"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .chain_extension( + ::ink::metadata::TypeSpec::with_name_segs::< + ChainExtension, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["ChainExtension"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .max_event_topics(MAX_EVENT_TOPICS) + .static_buffer_size(::ink::env::BUFFER_SIZE) + .done(), + ) + .done(), + ) + } + }; + use super::*; +} diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index ff64298e..78c88b70 100755 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -1,7 +1,11 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] // Fungibles wrapper contract to allow contracts to interact with local fungibles without the pop api. -use pop_api::{primitives::{AccountId as AccountId32, AssetId}, assets::fungibles::*}; +use ink::prelude::vec::Vec; +use pop_api::{ + assets::fungibles::*, + primitives::{AccountId as AccountId32, AssetId}, +}; #[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] @@ -31,6 +35,7 @@ pub enum FungiblesError { ZeroRecipientAddress, /// Sender's address is zero. ZeroSenderAddress, + UndefinedError, } impl From for FungiblesError { @@ -40,7 +45,7 @@ impl From for FungiblesError { Error::InUse => FungiblesError::InUse, Error::MinBalanceZero => FungiblesError::MinBalanceZero, Error::Unknown => FungiblesError::Unknown, - _ => todo!() + _ => FungiblesError::UndefinedError, } } } @@ -74,41 +79,79 @@ mod fungibles { } #[ink(message)] - pub fn allowance(&self, id: AssetId, owner: AccountId32, spender: AccountId32) -> Result { + pub fn allowance( + &self, + id: AssetId, + owner: AccountId32, + spender: AccountId32, + ) -> Result { allowance(id, owner, spender).map_err(From::from) } + #[ink(message)] + pub fn asset_exists(&self, id: AssetId) -> Result { + asset_exists(id).map_err(From::from) + } + + #[ink(message)] + pub fn create(&self, id: AssetId, admin: AccountId32, min_balance: Balance) -> Result<()> { + // create(id, admin, min_balance).map_err(From::from) + ink::env::debug_println!( + "PopApiAssetsExample::create: id: {:?} admin: {:?} min_balance: {:?}", + id, + admin, + min_balance, + ); + let result = create(id, admin, min_balance); + ink::env::debug_println!("Result: {:?}", result); + result.map_err(From::from) + } + + #[ink(message)] + pub fn set_metadata( + &self, + id: AssetId, + name: Vec, + symbol: Vec, + decimals: u8, + ) -> Result<()> { + // set_metadata(id, name, symbol, decimals).map_err(From::from) + ink::env::debug_println!( + "PopApiAssetsExample::set_metadata: id: {:?} name: {:?} symbol: {:?}, decimals: {:?}", + id, + name, + symbol, + decimals, + ); + let result = set_metadata(id, name, symbol, decimals); + ink::env::debug_println!("Result: {:?}", result); + result.map_err(From::from) + } + // #[ink(message)] - // pub fn token_name(id: AssetId) -> Result>> { - // token_name(id) - // } + // pub fn transfer( + // &self, + // id: u32, + // beneficiary: AccountId32, + // amount: Balance, + // ) -> Result<()> { + // ink::env::debug_println!( + // "PopApiAssetsExample::mint_asset_through_runtime: id: {:?} beneficiary: {:?} amount: {:?}", + // id, + // beneficiary, + // amount + // ); + // + // // Check if asset doesn't exist. + // // if !asset_exists(id)? { + // // return Err(FungiblesError::UnknownAsset); + // // } // - // #[ink(message)] - // pub fn mint_asset( - // &mut self, - // id: u32, - // beneficiary: AccountId, - // amount: Balance, - // ) -> Result<()> { - // ink::env::debug_println!( - // "PopApiAssetsExample::mint_asset_through_runtime: id: {:?} beneficiary: {:?} amount: {:?}", - // id, - // beneficiary, - // amount - // ); - // - // // Check if asset doesn't exist. - // if !asset_exists(id)? { - // return Err(FungiblesError::UnknownAsset); - // } - // - // // Mint asset via pop api. - // mint(id, beneficiary, amount)?; - // ink::env::debug_println!( - // "PopApiAssetsExample::mint_asset_through_runtime: asset(s) minted successfully" - // ); - // Ok(()) - // } + // // Mint asset via pop api. + // let result = mint(id, beneficiary, amount)?; + // ink::env::debug_println!("Result: {:?}", result); + // Ok(()) + // } } #[cfg(test)] diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index 8df381de..85da77ac 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -3,12 +3,12 @@ pub mod primitives; pub mod v0; -use crate::PopApiError::{Balances, Nfts, Assets, UnknownStatusCode}; +use crate::PopApiError::{Balances, Contracts, Nfts, Assets, UnknownStatusCode}; use ink::{prelude::vec::Vec, ChainExtensionInstance}; use primitives::{AccountId as AccountId32, cross_chain::*, storage_keys::*}; pub use sp_runtime::{BoundedVec, MultiAddress, MultiSignature}; use v0::RuntimeCall; -pub use v0::{balances, cross_chain, nfts, relay_chain_block_number, state, assets}; +pub use v0::{balances, contracts, cross_chain, nfts, relay_chain_block_number, state, assets}; // type AccountId = ::AccountId; type AccountId = AccountId32; @@ -26,6 +26,7 @@ pub enum PopApiError { DecodingFailed, SystemCallFiltered, Balances(balances::Error), + Contracts(contracts::Error), Nfts(nfts::Error), Assets(assets::fungibles::Error), Xcm(cross_chain::Error), @@ -38,6 +39,7 @@ impl ink::env::chain_extension::FromStatusCode for PopApiError { // CallFiltered originates from `frame_system` with pallet-index 0. The CallFiltered error is at index 5 5 => Err(PopApiError::SystemCallFiltered), 10_000..=10_999 => Err(Balances((status_code - 10_000).try_into()?)), + 40_000..=40_999 => Err(Contracts((status_code - 40_000).try_into()?)), 50_000..=50_999 => Err(Nfts((status_code - 50_000).try_into()?)), 52_000..=52_999 => Err(Assets((status_code - 52_000).try_into()?)), _ => Err(UnknownStatusCode(status_code)), diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs index b7cfef8f..2d4e2730 100644 --- a/pop-api/src/v0/assets/fungibles.rs +++ b/pop-api/src/v0/assets/fungibles.rs @@ -1,7 +1,6 @@ -#![allow(warnings, unused)] -use crate::{Balance, PopApiError::UnknownStatusCode, RuntimeCall, *}; +use crate::{AccountId, Balance, PopApiError::UnknownStatusCode, RuntimeCall, *}; use ink::prelude::vec::Vec; -use primitives::{AssetId, MultiAddress}; +use primitives::AssetId; use scale::{Compact, Encode}; type Result = core::result::Result; @@ -59,6 +58,24 @@ pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result>, min_balance: Balance) -> Result<()> { +pub fn create(id: AssetId, admin: AccountId, min_balance: Balance) -> Result<()> { + Ok(dispatch(RuntimeCall::Assets(AssetsCall::Create { + id: id.into(), + admin: admin.into(), + min_balance: Compact(min_balance), + }))?) +} + /// Transfers `value` amount of tokens from the caller's account to account `to`, with additional /// `data` in unspecified format. /// @@ -69,25 +86,25 @@ pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result>, - value: Balance, -) -> Result<()> { - todo!() - // TODO: transfer or transfer_keep_alive - // Ok(dispatch(RuntimeCall::Assets(AssetsCall::Transfer { - // id: id.into(), - // target: target.into(), - // amount: Compact(amount), - // }))?) - // Ok(dispatch(RuntimeCall::Assets(AssetsCall::TransferKeepAlive { - // id: id.into(), - // target: target.into(), - // amount: Compact(amount), - // }))?) -} +// #[allow(unused_variables)] +// pub fn transfer( +// id: AssetId, +// to: impl Into>, +// value: Balance, +// ) -> Result<()> { +// todo!() +// // TODO: transfer or transfer_keep_alive +// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::Transfer { +// // id: id.into(), +// // target: target.into(), +// // amount: Compact(amount), +// // }))?) +// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::TransferKeepAlive { +// // id: id.into(), +// // target: target.into(), +// // amount: Compact(amount), +// // }))?) +// } /// Transfers `value` tokens on the behalf of `from` to the account `to` with additional `data` /// in unspecified format. This can be used to allow a contract to transfer tokens on ones behalf @@ -101,32 +118,45 @@ pub fn transfer( /// /// # Returns /// Returns `Ok(())` if successful, or an error if the transfer fails. -#[allow(unused_variables)] -pub fn transfer_from( - id: AssetId, - from: impl Into>, - to: impl Into>, - value: Balance, -) -> Result<()> { - todo!() - // TODO: depending on `from` and `to`, decide whether to mint, burn or transfer_approved. - // Ok(dispatch(RuntimeCall::Assets(AssetsCall::Mint { - // id: id.into(), - // beneficiary: beneficiary.into(), - // amount: Compact(amount), - // }))?) - // Ok(dispatch(RuntimeCall::Assets(AssetsCall::Burn { - // id: id.into(), - // who: who.into(), - // amount: Compact(amount), - // }))?) - // Ok(dispatch(RuntimeCall::Assets(AssetsCall::TransferApproved { - // id: id.into(), - // owner: from.into(), - // destination: to.into(), - // amount: Compact(value), - // }))?) -} +// #[allow(unused_variables)] +// pub fn transfer_from( +// id: AssetId, +// from: impl Into>, +// to: impl Into>, +// value: Balance, +// ) -> Result<()> { +// todo!() +// // TODO: depending on `from` and `to`, decide whether to mint, burn or transfer_approved. +// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::Mint { +// // id: id.into(), +// // beneficiary: beneficiary.into(), +// // amount: Compact(amount), +// // }))?) +// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::Burn { +// // id: id.into(), +// // who: who.into(), +// // amount: Compact(amount), +// // }))?) +// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::TransferApproved { +// // id: id.into(), +// // owner: from.into(), +// // destination: to.into(), +// // amount: Compact(value), +// // }))?) +// } + +/// Mint assets of a particular class. +// pub fn mint( +// id: AssetId, +// beneficiary: impl Into>, +// amount: Balance, +// ) -> Result<()> { +// Ok(dispatch(RuntimeCall::Assets(AssetsCall::Mint { +// id: id.into(), +// beneficiary: beneficiary.into(), +// amount: Compact(amount), +// }))?) +// } /// Approves an account to spend a specified number of tokens on behalf of the caller. /// @@ -137,16 +167,16 @@ pub fn transfer_from( /// /// # Returns /// Returns `Ok(())` if successful, or an error if the approval fails. -#[allow(unused_variables)] -fn approve(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { - todo!() - // TODO: read allowance and increase or decrease. - // Ok(dispatch(RuntimeCall::Assets(AssetsCall::ApproveTransfer { - // id: id.into(), - // delegate: spender.into(), - // amount: Compact(value), - // }))?) -} +// #[allow(unused_variables)] +// fn approve(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { +// todo!() +// // TODO: read allowance and increase or decrease. +// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::ApproveTransfer { +// // id: id.into(), +// // delegate: spender.into(), +// // amount: Compact(value), +// // }))?) +// } /// Increases the allowance of a spender. /// @@ -157,13 +187,13 @@ fn approve(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { /// /// # Returns /// Returns `Ok(())` if successful, or an error if the operation fails. -fn increase_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { - Ok(dispatch(RuntimeCall::Assets(AssetsCall::ApproveTransfer { - id: id.into(), - delegate: spender.into(), - amount: Compact(value), - }))?) -} +// fn increase_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { +// Ok(dispatch(RuntimeCall::Assets(AssetsCall::ApproveTransfer { +// id: id.into(), +// delegate: spender.into(), +// amount: Compact(value), +// }))?) +// } /// Decreases the allowance of a spender. /// @@ -174,20 +204,20 @@ fn increase_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result /// /// # Returns /// Returns `Ok(())` if successful, or an error if the operation fails. -#[allow(unused_variables)] -fn decrease_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { - todo!() - // TODO: cancel_approval + approve_transfer - // Ok(dispatch(RuntimeCall::Assets(AssetsCall::CancelApproval { - // id: id.into(), - // delegate: delegate.into(), - // }))?) - // Ok(dispatch(RuntimeCall::Assets(AssetsCall::ApproveTransfer { - // id: id.into(), - // delegate: spender.into(), - // amount: Compact(value), - // }))?) -} +// #[allow(unused_variables)] +// fn decrease_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { +// todo!() +// // TODO: cancel_approval + approve_transfer +// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::CancelApproval { +// // id: id.into(), +// // delegate: delegate.into(), +// // }))?) +// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::ApproveTransfer { +// // id: id.into(), +// // delegate: spender.into(), +// // amount: Compact(value), +// // }))?) +// } /// 2. PSP-22 Metadata Interface: /// - token_name @@ -201,11 +231,11 @@ fn decrease_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result /// /// # Returns /// The name of the token as a byte vector, or an error if the operation fails. -#[allow(unused_variables)] -pub fn token_name(id: AssetId) -> Result>> { - todo!() - // Ok(state::read(RuntimeStateKeys::Assets(AssetsKeys::TokenName(id)))?) -} +// #[allow(unused_variables)] +// pub fn token_name(id: AssetId) -> Result>> { +// todo!() +// // Ok(state::read(RuntimeStateKeys::Assets(AssetsKeys::TokenName(id)))?) +// } /// Returns the token symbol for a given asset ID. /// @@ -214,10 +244,10 @@ pub fn token_name(id: AssetId) -> Result>> { /// /// # Returns /// The symbol of the token as a byte vector, or an error if the operation fails. -#[allow(unused_variables)] -fn token_symbol(id: AssetId) -> Result>> { - todo!() -} +// #[allow(unused_variables)] +// fn token_symbol(id: AssetId) -> Result>> { +// todo!() +// } /// Returns the token decimals for a given asset ID. /// @@ -226,10 +256,10 @@ fn token_symbol(id: AssetId) -> Result>> { /// /// # Returns /// The number of decimals of the token as a byte vector, or an error if the operation fails. -#[allow(unused_variables)] -fn token_decimals(id: AssetId) -> Result>> { - todo!() -} +// #[allow(unused_variables)] +// fn token_decimals(id: AssetId) -> Result>> { +// todo!() +// } /// 3. Asset Management: /// - create @@ -240,23 +270,6 @@ fn token_decimals(id: AssetId) -> Result>> { /// - set_metadata /// - clear_metadata -/// Create a new token with a given asset ID. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// * `admin` - The account that will administer the asset. -/// * `min_balance` - The minimum balance required for accounts holding this asset. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the creation fails. -fn create(id: AssetId, admin: AccountId, min_balance: Balance) -> Result<()> { - Ok(dispatch(RuntimeCall::Assets(AssetsCall::Create { - id: id.into(), - admin: admin.into(), - min_balance: Compact(min_balance), - }))?) -} - /// Start the process of destroying a token with a given asset ID. /// /// # Arguments @@ -264,11 +277,11 @@ fn create(id: AssetId, admin: AccountId, min_balance: Balance) -> Result<()> { /// /// # Returns /// Returns `Ok(())` if successful, or an error if the operation fails. -fn start_destroy(id: AssetId) -> Result<()> { - Ok(dispatch(RuntimeCall::Assets(AssetsCall::StartDestroy { - id: id.into(), - }))?) -} +// fn start_destroy(id: AssetId) -> Result<()> { +// Ok(dispatch(RuntimeCall::Assets(AssetsCall::StartDestroy { +// id: id.into(), +// }))?) +// } /// Destroy all accounts associated with a token with a given asset ID. /// @@ -277,11 +290,11 @@ fn start_destroy(id: AssetId) -> Result<()> { /// /// # Returns /// Returns `Ok(())` if successful, or an error if the operation fails. -fn destroy_accounts(id: AssetId) -> Result<()> { - Ok(dispatch(RuntimeCall::Assets(AssetsCall::DestroyAccounts { - id: id.into(), - }))?) -} +// fn destroy_accounts(id: AssetId) -> Result<()> { +// Ok(dispatch(RuntimeCall::Assets(AssetsCall::DestroyAccounts { +// id: id.into(), +// }))?) +// } /// Destroy all approvals associated with a token with a given asset ID. /// @@ -290,11 +303,11 @@ fn destroy_accounts(id: AssetId) -> Result<()> { /// /// # Returns /// Returns `Ok(())` if successful, or an error if the operation fails. -fn destroy_approvals(id: AssetId) -> Result<()> { - Ok(dispatch(RuntimeCall::Assets(AssetsCall::DestroyApprovals { - id: id.into(), - }))?) -} +// fn destroy_approvals(id: AssetId) -> Result<()> { +// Ok(dispatch(RuntimeCall::Assets(AssetsCall::DestroyApprovals { +// id: id.into(), +// }))?) +// } /// Complete the process of destroying a token with a given asset ID. /// @@ -303,11 +316,11 @@ fn destroy_approvals(id: AssetId) -> Result<()> { /// /// # Returns /// Returns `Ok(())` if successful, or an error if the operation fails. -fn finish_destroy(id: AssetId) -> Result<()> { - Ok(dispatch(RuntimeCall::Assets(AssetsCall::FinishDestroy { - id: id.into(), - }))?) -} +// fn finish_destroy(id: AssetId) -> Result<()> { +// Ok(dispatch(RuntimeCall::Assets(AssetsCall::FinishDestroy { +// id: id.into(), +// }))?) +// } /// Set the metadata for a token with a given asset ID. /// @@ -316,7 +329,7 @@ fn finish_destroy(id: AssetId) -> Result<()> { /// /// # Returns /// Returns `Ok(())` if successful, or an error if the operation fails. -fn set_metadata(id: AssetId, name: Vec, symbol: Vec, decimals: u8) -> Result<()> { +pub fn set_metadata(id: AssetId, name: Vec, symbol: Vec, decimals: u8) -> Result<()> { Ok(dispatch(RuntimeCall::Assets(AssetsCall::SetMetadata { id: id.into(), name, @@ -332,11 +345,11 @@ fn set_metadata(id: AssetId, name: Vec, symbol: Vec, decimals: u8) -> Re /// /// # Returns /// Returns `Ok(())` if successful, or an error if the operation fails. -fn clear_metadata(id: AssetId) -> Result<()> { - Ok(dispatch(RuntimeCall::Assets(AssetsCall::ClearMetadata { - id: id.into(), - }))?) -} +// fn clear_metadata(id: AssetId) -> Result<()> { +// Ok(dispatch(RuntimeCall::Assets(AssetsCall::ClearMetadata { +// id: id.into(), +// }))?) +// } pub fn asset_exists(id: AssetId) -> Result { Ok(state::read(RuntimeStateKeys::Assets(AssetsKeys::AssetExists(id)))?) @@ -352,6 +365,7 @@ type AssetIdParameter = Compact; // Balance amount that is compact encoded. type BalanceParameter = Compact; +#[allow(warnings, unused)] #[derive(Encode)] pub(crate) enum AssetsCall { #[codec(index = 0)] @@ -529,6 +543,10 @@ impl From for Error { fn from(error: PopApiError) -> Self { match error { PopApiError::Assets(e) => e, + PopApiError::Balances(_e) => todo!("balances"), + PopApiError::Contracts(_e) => todo!("contracts"), + // PopApiError::SystemCallFiltered => 100, + // PopApiError::UnknownStatusCode(u) => u, _ => panic!("Unexpected pallet assets error. This error is unknown to pallet assets"), } } diff --git a/pop-api/src/v0/contracts.rs b/pop-api/src/v0/contracts.rs new file mode 100644 index 00000000..d7a1a5dd --- /dev/null +++ b/pop-api/src/v0/contracts.rs @@ -0,0 +1,156 @@ +use crate::{ + PopApiError, + PopApiError::UnknownStatusCode, +}; + +#[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] +#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +pub enum Error { + /// Invalid schedule supplied, e.g. with zero weight of a basic operation. + InvalidSchedule, + /// Invalid combination of flags supplied to `seal_call` or `seal_delegate_call`. + InvalidCallFlags, + /// The executed contract exhausted its gas limit. + OutOfGas, + /// The output buffer supplied to a contract API call was too small. + OutputBufferTooSmall, + /// Performing the requested transfer failed. Probably because there isn't enough + /// free balance in the sender's account. + TransferFailed, + /// Performing a call was denied because the calling depth reached the limit + /// of what is specified in the schedule. + MaxCallDepthReached, + /// No contract was found at the specified address. + ContractNotFound, + /// The code supplied to `instantiate_with_code` exceeds the limit specified in the + /// current schedule. + CodeTooLarge, + /// No code could be found at the supplied code hash. + CodeNotFound, + /// No code info could be found at the supplied code hash. + CodeInfoNotFound, + /// A buffer outside of sandbox memory was passed to a contract API function. + OutOfBounds, + /// Input passed to a contract API function failed to decode as expected type. + DecodingFailed, + /// Contract trapped during execution. + ContractTrapped, + /// The size defined in `T::MaxValueSize` was exceeded. + ValueTooLarge, + /// Termination of a contract is not allowed while the contract is already + /// on the call stack. Can be triggered by `seal_terminate`. + TerminatedWhileReentrant, + /// `seal_call` forwarded this contracts input. It therefore is no longer available. + InputForwarded, + /// The subject passed to `seal_random` exceeds the limit. + RandomSubjectTooLong, + /// The amount of topics passed to `seal_deposit_events` exceeds the limit. + TooManyTopics, + /// The chain does not provide a chain extension. Calling the chain extension results + /// in this error. Note that this usually shouldn't happen as deploying such contracts + /// is rejected. + NoChainExtension, + /// Failed to decode the XCM program. + XCMDecodeFailed, + /// A contract with the same AccountId already exists. + DuplicateContract, + /// A contract self destructed in its constructor. + /// + /// This can be triggered by a call to `seal_terminate`. + TerminatedInConstructor, + /// A call tried to invoke a contract that is flagged as non-reentrant. + /// The only other cause is that a call from a contract into the runtime tried to call back + /// into `pallet-contracts`. This would make the whole pallet reentrant with regard to + /// contract code execution which is not supported. + ReentranceDenied, + /// Origin doesn't have enough balance to pay the required storage deposits. + StorageDepositNotEnoughFunds, + /// More storage was created than allowed by the storage deposit limit. + StorageDepositLimitExhausted, + /// Code removal was denied because the code is still in use by at least one contract. + CodeInUse, + /// The contract ran to completion but decided to revert its storage changes. + /// Please note that this error is only returned from extrinsics. When called directly + /// or via RPC an `Ok` will be returned. In this case the caller needs to inspect the flags + /// to determine whether a reversion has taken place. + ContractReverted, + /// The contract's code was found to be invalid during validation. + /// + /// The most likely cause of this is that an API was used which is not supported by the + /// node. This happens if an older node is used with a new version of ink!. Try updating + /// your node to the newest available version. + /// + /// A more detailed error can be found on the node console if debug messages are enabled + /// by supplying `-lruntime::contracts=debug`. + CodeRejected, + /// An indeterministic code was used in a context where this is not permitted. + Indeterministic, + /// A pending migration needs to complete before the extrinsic can be called. + MigrationInProgress, + /// Migrate dispatch call was attempted but no migration was performed. + NoMigrationPerformed, + /// The contract has reached its maximum number of delegate dependencies. + MaxDelegateDependenciesReached, + /// The dependency was not found in the contract's delegate dependencies. + DelegateDependencyNotFound, + /// The contract already depends on the given delegate dependency. + DelegateDependencyAlreadyExists, + /// Can not add a delegate dependency to the code hash of the contract itself. + CannotAddSelfAsDelegateDependency, +} + + +impl TryFrom for Error { + type Error = PopApiError; + + fn try_from(status_code: u32) -> core::result::Result { + use Error::*; + match status_code { + 0 => Ok(InvalidSchedule), + 1 => Ok(InvalidCallFlags), + 2 => Ok(OutOfGas), + 3 => Ok(OutputBufferTooSmall), + 4 => Ok(TransferFailed), + 5 => Ok(MaxCallDepthReached), + 6 => Ok(ContractNotFound), + 7 => Ok(CodeTooLarge), + 8 => Ok(CodeNotFound), + 9 => Ok(CodeInfoNotFound), + 10 => Ok(OutOfBounds), + 11 => Ok(DecodingFailed), + 12 => Ok(ContractTrapped), + 13 => Ok(ValueTooLarge), + 14 => Ok(TerminatedWhileReentrant), + 15 => Ok(InputForwarded), + 16 => Ok(RandomSubjectTooLong), + 17 => Ok(TooManyTopics), + 18 => Ok(NoChainExtension), + 19 => Ok(XCMDecodeFailed), + 20 => Ok(DuplicateContract), + 21 => Ok(TerminatedInConstructor), + 22 => Ok(ReentranceDenied), + 23 => Ok(StorageDepositNotEnoughFunds), + 24 => Ok(StorageDepositLimitExhausted), + 25 => Ok(CodeInUse), + 26 => Ok(ContractReverted), + 27 => Ok(CodeRejected), + 28 => Ok(Indeterministic), + 29 => Ok(MigrationInProgress), + 30 => Ok(NoMigrationPerformed), + 31 => Ok(MaxDelegateDependenciesReached), + 32 => Ok(DelegateDependencyNotFound), + 33 => Ok(DelegateDependencyAlreadyExists), + 34 => Ok(CannotAddSelfAsDelegateDependency), + _ => Err(UnknownStatusCode(status_code)), + } + } +} + +impl From for Error { + fn from(error: PopApiError) -> Self { + match error { + PopApiError::Contracts(e) => e, + _ => panic!("expected balances error"), + } + } +} \ No newline at end of file diff --git a/pop-api/src/v0/mod.rs b/pop-api/src/v0/mod.rs index 2360c6d3..def37e55 100644 --- a/pop-api/src/v0/mod.rs +++ b/pop-api/src/v0/mod.rs @@ -4,6 +4,7 @@ use crate::{ }; pub mod balances; +pub mod contracts; pub mod cross_chain; pub mod nfts; pub mod state; diff --git a/runtime/devnet/src/extensions/tests/local_fungibles.rs b/runtime/devnet/src/extensions/tests/local_fungibles.rs index 8bb5c6ab..6ba3afd7 100644 --- a/runtime/devnet/src/extensions/tests/local_fungibles.rs +++ b/runtime/devnet/src/extensions/tests/local_fungibles.rs @@ -3,7 +3,12 @@ use super::*; const ASSET_ID: u32 = 1; -fn allowance(addr: AccountId32, asset_id: u32, owner: AccountId32, spender: AccountId32) -> ExecReturnValue { +fn allowance( + addr: AccountId32, + asset_id: u32, + owner: AccountId32, + spender: AccountId32, +) -> ExecReturnValue { let function = function_selector("allowance"); let params = [function, asset_id.encode(), owner.encode(), spender.encode()].concat(); do_bare_call(addr, params, 0).expect("should work") @@ -23,35 +28,65 @@ fn total_supply(addr: AccountId32, asset_id: u32) -> ExecReturnValue { do_bare_call(addr, params, 0).expect("should work") } +fn asset_exists(addr: AccountId32, asset_id: u32) -> ExecReturnValue { + let function = function_selector("asset_exists"); + let params = [function, asset_id.encode()].concat(); + do_bare_call(addr, params, 0).expect("should work") +} + +fn create( + addr: AccountId32, + asset_id: u32, + admin: AccountId32, + min_balance: u128, +) -> Result { + let function = function_selector("create"); + let params = [function, asset_id.encode(), admin.encode(), min_balance.encode()].concat(); + do_bare_call(addr, params, 0) +} + +fn set_metadata( + addr: AccountId32, + asset_id: u32, + name: Vec, + symbol: Vec, + decimals: u8, +) -> Result { + let function = function_selector("set_metadata"); + let params = + [function, asset_id.encode(), name.encode(), symbol.encode(), decimals.encode()].concat(); + do_bare_call(addr, params, 0) +} + // Create an asset and mint to owner. -fn create_asset_and_mint_to(asset_id: u32, owner: AccountId32, value: u128) { +fn create_asset(asset_id: u32) { assert_eq!( - Assets::force_create( - RuntimeOrigin::root(), - asset_id.into(), - owner.clone().into(), - true, - 1, - ), + Assets::force_create(RuntimeOrigin::root(), asset_id.into(), ALICE.into(), true, 1,), Ok(()) ); +} + +// Create an asset and mint to owner. +fn create_asset_and_mint_to(asset_id: u32, to: AccountId32, value: u128) { + create_asset(asset_id); assert_eq!( - Assets::mint( - RuntimeOrigin::signed(owner.clone().into()), - asset_id.into(), - owner.into(), - value, - ), + Assets::mint(RuntimeOrigin::signed(ALICE.into()), asset_id.into(), to.into(), value,), Ok(()) ); } // Create an asset, mints to, and approves spender. -fn create_asset_mint_and_approve(asset_id: u32, owner: AccountId32, mint: u128, spender: AccountId32, approve: u128) { - create_asset_and_mint_to(asset_id, owner.clone(), mint); +fn create_asset_mint_and_approve( + asset_id: u32, + to: AccountId32, + mint: u128, + spender: AccountId32, + approve: u128, +) { + create_asset_and_mint_to(asset_id, to.clone(), mint); assert_eq!( Assets::approve_transfer( - RuntimeOrigin::signed(owner.into()), + RuntimeOrigin::signed(to.into()), asset_id.into(), spender.into(), approve, @@ -60,7 +95,6 @@ fn create_asset_mint_and_approve(asset_id: u32, owner: AccountId32, mint: u128, ); } - #[test] #[ignore] fn total_supply_works() { @@ -76,10 +110,7 @@ fn total_supply_works() { // Tokens in circulation. create_asset_and_mint_to(ASSET_ID, BOB, 100); - assert_eq!( - Assets::total_supply(ASSET_ID).encode(), - total_supply(addr, ASSET_ID).data[2..] - ); + assert_eq!(Assets::total_supply(ASSET_ID).encode(), total_supply(addr, ASSET_ID).data[2..]); }); } @@ -127,106 +158,172 @@ fn allowance_works() { }); } -// #[test] -// #[ignore] -// fn dispatch_mint_asset_from_contract_works() { -// new_test_ext().execute_with(|| { -// let _ = env_logger::try_init(); -// -// let (wasm_binary, _) = load_wasm_module::( -// "../../pop-api/examples/assets/target/ink/fungibles.wasm", -// ) -// .unwrap(); -// -// let init_value = 100; -// -// let result = Contracts::bare_instantiate( -// ALICE, -// init_value, -// GAS_LIMIT, -// None, -// Code::Upload(wasm_binary), -// function_selector("new"), -// vec![], -// DEBUG_OUTPUT, -// pallet_contracts::CollectEvents::Skip, -// ) -// .result -// .unwrap(); -// -// assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); -// let addr = result.account_id; -// -// let asset_id: u32 = 1; -// let min_balance = 1; -// let amount: u128 = 100 * UNIT; -// let function = function_selector("mint_asset_through_runtime"); -// let params = [function, asset_id.encode(), BOB.encode(), amount.encode()].concat(); -// -// // Mint asset which does not exist. -// let result = Contracts::bare_call( -// ALICE, -// addr.clone(), -// 0, -// GAS_LIMIT, -// None, -// params.clone(), -// DEBUG_OUTPUT, -// pallet_contracts::CollectEvents::Skip, -// pallet_contracts::Determinism::Enforced, -// ); -// -// if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { -// log::debug!( -// "Contract debug buffer - {:?}", -// String::from_utf8(result.debug_message.clone()) -// ); -// log::debug!("result: {:?}", result); -// } -// -// // Check for revert. -// assert!(result.result.unwrap().did_revert(), "Contract should have been reverted!"); -// -// // Create asset with contract as owner. -// assert_eq!( -// Assets::force_create( -// RuntimeOrigin::root(), -// asset_id.into(), -// addr.clone().into(), -// true, -// min_balance, -// ), -// Ok(()) -// ); -// -// // Check Bob's asset balance before minting through contract. -// let bob_balance_before = Assets::balance(asset_id, &BOB); -// assert_eq!(bob_balance_before, 0); -// -// let result = Contracts::bare_call( -// ALICE, -// addr.clone(), -// 0, -// GAS_LIMIT, -// None, -// params, -// DEBUG_OUTPUT, -// pallet_contracts::CollectEvents::Skip, -// pallet_contracts::Determinism::Enforced, -// ); -// -// if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { -// log::debug!( -// "Contract debug buffer - {:?}", -// String::from_utf8(result.debug_message.clone()) -// ); -// log::debug!("result: {:?}", result); -// } -// -// // Check for revert -// assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); -// -// let bob_balance_after = Assets::balance(asset_id, &BOB); -// assert_eq!(bob_balance_after, bob_balance_before + amount); -// }); -// } +#[test] +#[ignore] +fn asset_exists_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = instantiate("../../pop-api/examples/fungibles/target/ink/fungibles.wasm"); + + // No tokens in circulation. + assert_eq!( + Assets::asset_exists(ASSET_ID).encode(), + asset_exists(addr.clone(), ASSET_ID).data[2..] + ); + + // Tokens in circulation. + create_asset(ASSET_ID); + assert_eq!(Assets::asset_exists(ASSET_ID).encode(), asset_exists(addr, ASSET_ID).data[2..]); + }); +} + +#[test] +#[ignore] +fn create_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = instantiate("../../pop-api/examples/fungibles/target/ink/fungibles.wasm"); + let new_asset = 2; + + // badorigin + // lookup + // Error `InUse`. + // create_asset(ASSET_ID); + // let result = create(addr.clone(), ASSET_ID, BOB, 1); + + // Error `MinBalanceZero`. + // let result = create(addr.clone(), new_asset, BOB, 0); + // Reserve error + // let result = create(addr.clone(), new_asset, BOB, 1); + // Calback + let result = create(addr.clone(), new_asset, BOB, 1); + }); +} + +#[test] +#[ignore] +fn set_metadata_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = instantiate("../../pop-api/examples/fungibles/target/ink/fungibles.wasm"); + + // create_asset(ASSET_ID); + assert_eq!( + Assets::force_create( + RuntimeOrigin::root(), + ASSET_ID.into(), + addr.clone().into(), + true, + 1, + ), + Ok(()) + ); + + let result = set_metadata(addr.clone(), ASSET_ID, vec![12], vec![12], 12); + assert!(!result.unwrap().did_revert(), "Contract should have been reverted!"); + }); +} + +#[test] +#[ignore] +fn dispatch_mint_asset_from_contract_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + + let (wasm_binary, _) = load_wasm_module::( + "../../pop-api/examples/fungibles/target/ink/fungibles.wasm", + ) + .unwrap(); + + let init_value = 100; + + let result = Contracts::bare_instantiate( + ALICE, + init_value, + GAS_LIMIT, + None, + Code::Upload(wasm_binary), + function_selector("new"), + vec![], + DEBUG_OUTPUT, + pallet_contracts::CollectEvents::Skip, + ) + .result + .unwrap(); + + assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); + let addr = result.account_id; + + let asset_id: u32 = 1; + let min_balance = 1; + let amount: u128 = 100 * UNIT; + let function = function_selector("mint_asset_through_runtime"); + let params = [function, asset_id.encode(), BOB.encode(), amount.encode()].concat(); + + // Mint asset which does not exist. + let result = Contracts::bare_call( + ALICE, + addr.clone(), + 0, + GAS_LIMIT, + None, + params.clone(), + DEBUG_OUTPUT, + pallet_contracts::CollectEvents::Skip, + pallet_contracts::Determinism::Enforced, + ); + + if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { + log::debug!( + "Contract debug buffer - {:?}", + String::from_utf8(result.debug_message.clone()) + ); + log::debug!("result: {:?}", result); + } + + // Check for revert. + assert!(result.result.unwrap().did_revert(), "Contract should have been reverted!"); + + // Create asset with contract as owner. + assert_eq!( + Assets::force_create( + RuntimeOrigin::root(), + asset_id.into(), + addr.clone().into(), + true, + min_balance, + ), + Ok(()) + ); + + // Check Bob's asset balance before minting through contract. + let bob_balance_before = Assets::balance(asset_id, &BOB); + assert_eq!(bob_balance_before, 0); + + let result = Contracts::bare_call( + ALICE, + addr.clone(), + 0, + GAS_LIMIT, + None, + params, + DEBUG_OUTPUT, + pallet_contracts::CollectEvents::Skip, + pallet_contracts::Determinism::Enforced, + ); + + if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { + log::debug!( + "Contract debug buffer - {:?}", + String::from_utf8(result.debug_message.clone()) + ); + log::debug!("result: {:?}", result); + } + + // Check for revert + assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); + + let bob_balance_after = Assets::balance(asset_id, &BOB); + assert_eq!(bob_balance_after, bob_balance_before + amount); + }); +} diff --git a/runtime/devnet/src/extensions/tests/mod.rs b/runtime/devnet/src/extensions/tests/mod.rs index 3607bc90..fcfc84dd 100644 --- a/runtime/devnet/src/extensions/tests/mod.rs +++ b/runtime/devnet/src/extensions/tests/mod.rs @@ -1,7 +1,7 @@ #![cfg(test)] use super::*; use crate::{Assets, Contracts, Runtime, System}; -use pallet_contracts::{ExecReturnValue, CollectEvents, Code, Determinism}; +use pallet_contracts::{Code, CollectEvents, Determinism, ExecReturnValue}; use sp_runtime::{traits::Hash, AccountId32, BuildStorage}; mod local_fungibles; @@ -59,20 +59,18 @@ fn do_bare_call( CollectEvents::Skip, Determinism::Enforced, ); - log::debug!( - "Contract debug buffer - {:?}", - String::from_utf8(result.debug_message.clone()) - ); + log::debug!("Contract debug buffer - {:?}", String::from_utf8(result.debug_message.clone())); log::debug!("result: {:?}", result); result.result } // Deploy, instantiate and return contract address. fn instantiate(contract: &str) -> AccountId32 { - let (wasm_binary, _) = load_wasm_module::(contract).expect("could not read .wasm file"); + let (wasm_binary, _) = + load_wasm_module::(contract).expect("could not read .wasm file"); let result = Contracts::bare_instantiate( ALICE, - 1000, + 100_000 * UNIT, GAS_LIMIT, None, Code::Upload(wasm_binary), @@ -80,7 +78,9 @@ fn instantiate(contract: &str) -> AccountId32 { vec![], DEBUG_OUTPUT, CollectEvents::Skip, - ).result.unwrap(); + ) + .result + .unwrap(); assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); result.account_id -} \ No newline at end of file +}