difftreelog
feat add ApproveForAll to Eth and Sub
in: master
39 files changed
client/rpc/src/lib.rsdiffbeforeafterboth247 at: Option<BlockHash>,247 at: Option<BlockHash>,248 ) -> Result<Option<String>>;248 ) -> Result<Option<String>>;249250 /// Get whether an operator is approved by a given owner.251 #[method(name = "unique_isApprovedForAll")]252 fn is_approved_for_all(253 &self,254 collection: CollectionId,255 owner: CrossAccountId,256 operator: CrossAccountId,257 at: Option<BlockHash>,258 ) -> Result<bool>;249}259}250260251mod app_promotion_unique_rpc {261mod app_promotion_unique_rpc {569 pass_method!(effective_collection_limits(collection_id: CollectionId) -> Option<CollectionLimits>, unique_api);579 pass_method!(effective_collection_limits(collection_id: CollectionId) -> Option<CollectionLimits>, unique_api);570 pass_method!(total_pieces(collection_id: CollectionId, token_id: TokenId) -> Option<String> => |o| o.map(|number| number.to_string()) , unique_api);580 pass_method!(total_pieces(collection_id: CollectionId, token_id: TokenId) -> Option<String> => |o| o.map(|number| number.to_string()) , unique_api);571 pass_method!(token_owners(collection: CollectionId, token: TokenId) -> Vec<CrossAccountId>, unique_api);581 pass_method!(token_owners(collection: CollectionId, token: TokenId) -> Vec<CrossAccountId>, unique_api);582 pass_method!(is_approved_for_all(collection: CollectionId, owner: CrossAccountId, operator: CrossAccountId) -> bool, unique_api);572}583}573584574impl<C, Block, BlockNumber, CrossAccountId, AccountId>585impl<C, Block, BlockNumber, CrossAccountId, AccountId>pallets/common/src/lib.rsdiffbeforeafterboth472 u128,472 u128,473 ),473 ),474475 /// Amount pieces of token owned by `sender` was approved for `spender`.476 ApprovedForAll(477 /// Id of collection to which item is belong.478 CollectionId,479 /// Owner of a wallet.480 T::CrossAccountId,481 /// Id for which operator status was granted or rewoked.482 T::CrossAccountId,483 /// Is operator status was granted or rewoked.484 bool,485 ),474486475 /// The colletion property has been added or edited.487 /// The colletion property has been added or edited.476 CollectionPropertySet(488 CollectionPropertySet(1522 /// The price of retrieving token owner1534 /// The price of retrieving token owner1523 fn token_owner() -> Weight;1535 fn token_owner() -> Weight;15361537 /// The price of setting approval for all1538 fn set_approval_for_all() -> Weight;1524}1539}152515401526/// Weight info extension trait for refungible pallet.1541/// Weight info extension trait for refungible pallet.1829 /// Get extension for RFT collection.1844 /// Get extension for RFT collection.1830 fn refungible_extensions(&self) -> Option<&dyn RefungibleExtensions<T>>;1845 fn refungible_extensions(&self) -> Option<&dyn RefungibleExtensions<T>>;18461847 /// An operator is allowed to transfer all tokens of the sender on their behalf.1848 /// * `owner` - Token owner1849 /// * `operator` - Operator1850 /// * `approve` - Is operator enabled or disabled1851 fn set_approval_for_all(1852 &self,1853 owner: T::CrossAccountId,1854 operator: T::CrossAccountId,1855 approve: bool,1856 ) -> DispatchResultWithPostInfo;18571858 /// Tells whether an operator is approved by a given owner.1859 fn is_approved_for_all(&self, owner: T::CrossAccountId, operator: T::CrossAccountId) -> bool;1831}1860}183218611833/// Extension for RFT collection.1862/// Extension for RFT collection.pallets/fungible/src/common.rsdiffbeforeafterboth108 Weight::zero()108 Weight::zero()109 }109 }110111 fn set_approval_for_all() -> Weight {112 Weight::zero()113 }110}114}111115112/// Implementation of `CommonCollectionOperations` for `FungibleHandle`. It wraps FungibleHandle Pallete116/// Implementation of `CommonCollectionOperations` for `FungibleHandle`. It wraps FungibleHandle Pallete425 <TotalSupply<T>>::try_get(self.id).ok()429 <TotalSupply<T>>::try_get(self.id).ok()426 }430 }431432 fn set_approval_for_all(433 &self,434 _owner: T::CrossAccountId,435 _operator: T::CrossAccountId,436 _approve: bool,437 ) -> DispatchResultWithPostInfo {438 fail!(<Error<T>>::SettingApprovalForAllNotAllowed)439 }440441 fn is_approved_for_all(&self, _owner: T::CrossAccountId, _operator: T::CrossAccountId) -> bool {442 false443 }427}444}428445pallets/fungible/src/lib.rsdiffbeforeafterboth127 FungibleDisallowsNesting,127 FungibleDisallowsNesting,128 /// Setting item properties is not allowed.128 /// Setting item properties is not allowed.129 SettingPropertiesNotAllowed,129 SettingPropertiesNotAllowed,130 /// Setting approval for all is not allowed.131 SettingApprovalForAllNotAllowed,130 }132 }131133132 #[pallet::config]134 #[pallet::config]pallets/nonfungible/src/benchmarking.rsdiffbeforeafterboth223223224 }: {collection.token_owner(item)}224 }: {collection.token_owner(item)}225226 set_approval_for_all {227 bench_init!{228 owner: sub; collection: collection(owner);229 operator: cross_from_sub(owner); owner: cross_sub;230 };231 }: {<Pallet<T>>::set_approval_for_all(&collection, &owner, &operator, true)}232233 is_approved_for_all {234 bench_init!{235 owner: sub; collection: collection(owner);236 operator: cross_from_sub(owner); owner: cross_sub;237 };238 }: {<Pallet<T>>::is_approved_for_all(&collection, &owner, &operator)}225}239}226240pallets/nonfungible/src/common.rsdiffbeforeafterboth123 <SelfWeightOf<T>>::token_owner()123 <SelfWeightOf<T>>::token_owner()124 }124 }125126 fn set_approval_for_all() -> Weight {127 <SelfWeightOf<T>>::set_approval_for_all()128 }125}129}126130127fn map_create_data<T: Config>(131fn map_create_data<T: Config>(513 }517 }514 }518 }519520 fn set_approval_for_all(521 &self,522 owner: T::CrossAccountId,523 operator: T::CrossAccountId,524 approve: bool,525 ) -> DispatchResultWithPostInfo {526 with_weight(527 <Pallet<T>>::set_approval_for_all(self, &owner, &operator, approve),528 <CommonWeights<T>>::set_approval_for_all(),529 )530 }531532 fn is_approved_for_all(&self, owner: T::CrossAccountId, operator: T::CrossAccountId) -> bool {533 <Pallet<T>>::is_approved_for_all(self, &owner, &operator)534 }515}535}516536pallets/nonfungible/src/erc.rsdiffbeforeafterboth469 Ok(())469 Ok(())470 }470 }471471472 /// @notice Sets or unsets the approval of a given operator.473 /// An operator is allowed to transfer all tokens of the sender on their behalf.472 /// @dev Not implemented474 /// @param operator Operator475 /// @param approved Is operator enabled or disabled476 #[weight(<SelfWeightOf<T>>::set_approval_for_all())]473 fn set_approval_for_all(477 fn set_approval_for_all(474 &mut self,478 &mut self,475 _caller: caller,479 caller: caller,476 _operator: address,480 operator: address,477 _approved: bool,481 approved: bool,478 ) -> Result<void> {482 ) -> Result<void> {479 // TODO: Not implemetable483 let caller = T::CrossAccountId::from_eth(caller);484 let operator = T::CrossAccountId::from_eth(operator);485486 <Pallet<T>>::set_approval_for_all(self, &caller, &operator, approved)480 Err("not implemented".into())487 .map_err(dispatch_to_evm::<T>)?;488 Ok(())481 }489 }482490483 /// @dev Not implemented491 /// @dev Not implemented486 Err("not implemented".into())494 Err("not implemented".into())487 }495 }488496489 /// @dev Not implemented497 /// @notice Tells whether an operator is approved by a given owner.498 #[weight(<SelfWeightOf<T>>::is_approved_for_all())]490 fn is_approved_for_all(&self, _owner: address, _operator: address) -> Result<address> {499 fn is_approved_for_all(&self, owner: address, operator: address) -> Result<bool> {491 // TODO: Not implemetable500 let owner = T::CrossAccountId::from_eth(owner);501 let operator = T::CrossAccountId::from_eth(operator);502492 Err("not implemented".into())503 Ok(<Pallet<T>>::is_approved_for_all(self, &owner, &operator))493 }504 }494505495 /// @notice Returns collection helper contract address506 /// @notice Returns collection helper contract addresspallets/nonfungible/src/lib.rsdiffbeforeafterboth272 QueryKind = OptionQuery,272 QueryKind = OptionQuery,273 >;273 >;274275 /// Operator set by a wallet owner that could perform certain transactions on all tokens in the wallet.276 #[pallet::storage]277 pub type WalletOperator<T: Config> = StorageNMap<278 Key = (279 Key<Twox64Concat, CollectionId>,280 Key<Blake2_128Concat, T::CrossAccountId>,281 Key<Blake2_128Concat, T::CrossAccountId>,282 ),283 Value = bool,284 QueryKind = OptionQuery,285 >;274286275 /// Upgrade from the old schema to properties.287 /// Upgrade from the old schema to properties.276 #[pallet::hooks]288 #[pallet::hooks]438 <TokensBurnt<T>>::remove(id);450 <TokensBurnt<T>>::remove(id);439 let _ = <Allowance<T>>::clear_prefix((id,), u32::MAX, None);451 let _ = <Allowance<T>>::clear_prefix((id,), u32::MAX, None);440 let _ = <AccountBalance<T>>::clear_prefix((id,), u32::MAX, None);452 let _ = <AccountBalance<T>>::clear_prefix((id,), u32::MAX, None);453 let _ = <WalletOperator<T>>::clear_prefix((id,), u32::MAX, None);441 Ok(())454 Ok(())442 }455 }4434561193 if <Allowance<T>>::get((collection.id, token)).as_ref() == Some(spender) {1206 if <Allowance<T>>::get((collection.id, token)).as_ref() == Some(spender) {1194 return Ok(());1207 return Ok(());1195 }1208 }1209 if <WalletOperator<T>>::get((collection.id, from, spender)) == Some(true) {1210 return Ok(());1211 }1196 ensure!(1212 ensure!(1197 collection.ignores_allowance(spender),1213 collection.ignores_allowance(spender),1198 <CommonError<T>>::ApprovedValueTooLow1214 <CommonError<T>>::ApprovedValueTooLow1327 Self::create_multiple_items(collection, sender, vec![data], nesting_budget)1343 Self::create_multiple_items(collection, sender, vec![data], nesting_budget)1328 }1344 }13451346 /// Sets or unsets the approval of a given operator.1347 ///1348 /// An operator is allowed to transfer all token pieces of the sender on their behalf.1349 /// - `owner`: Token owner1350 /// - `operator`: Operator1351 /// - `approve`: Is operator enabled or disabled1352 pub fn set_approval_for_all(1353 collection: &NonfungibleHandle<T>,1354 owner: &T::CrossAccountId,1355 operator: &T::CrossAccountId,1356 approve: bool,1357 ) -> DispatchResult {1358 if collection.permissions.access() == AccessMode::AllowList {1359 collection.check_allowlist(owner)?;1360 collection.check_allowlist(operator)?;1361 }13621363 <PalletCommon<T>>::ensure_correct_receiver(operator)?;13641365 // =========13661367 <WalletOperator<T>>::insert((collection.id, owner, operator), approve);1368 <PalletEvm<T>>::deposit_log(1369 ERC721Events::ApprovalForAll {1370 owner: *owner.as_eth(),1371 operator: *operator.as_eth(),1372 approved: approve,1373 }1374 .to_log(collection_id_to_address(collection.id)),1375 );1376 <PalletCommon<T>>::deposit_event(CommonEvent::ApprovedForAll(1377 collection.id,1378 owner.clone(),1379 operator.clone(),1380 approve,1381 ));1382 Ok(())1383 }13841385 /// Tells whether an operator is approved by a given owner.1386 pub fn is_approved_for_all(1387 collection: &NonfungibleHandle<T>,1388 owner: &T::CrossAccountId,1389 operator: &T::CrossAccountId,1390 ) -> bool {1391 <WalletOperator<T>>::get((collection.id, owner, operator)).unwrap_or(false)1392 }1329}1393}13301394pallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterbothbinary blob — no preview
pallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth1020 dummy = 0;1020 dummy = 0;1021 }1021 }102210221023 /// @notice Sets or unsets the approval of a given operator.1024 /// An operator is allowed to transfer all tokens of the sender on their behalf.1023 /// @dev Not implemented1025 /// @param operator Operator1026 /// @param approved Is operator enabled or disabled1024 /// @dev EVM selector for this function is: 0xa22cb465,1027 /// @dev EVM selector for this function is: 0xa22cb465,1025 /// or in textual repr: setApprovalForAll(address,bool)1028 /// or in textual repr: setApprovalForAll(address,bool)1026 function setApprovalForAll(address operator, bool approved) public {1029 function setApprovalForAll(address operator, bool approved) public {1040 return 0x0000000000000000000000000000000000000000;1043 return 0x0000000000000000000000000000000000000000;1041 }1044 }104210451043 /// @dev Not implemented1046 /// @notice Tells whether an operator is approved by a given owner.1044 /// @dev EVM selector for this function is: 0xe985e9c5,1047 /// @dev EVM selector for this function is: 0xe985e9c5,1045 /// or in textual repr: isApprovedForAll(address,address)1048 /// or in textual repr: isApprovedForAll(address,address)1046 function isApprovedForAll(address owner, address operator) public view returns (address) {1049 function isApprovedForAll(address owner, address operator) public view returns (bool) {1047 require(false, stub_error);1050 require(false, stub_error);1048 owner;1051 owner;1049 operator;1052 operator;1050 dummy;1053 dummy;1051 return 0x0000000000000000000000000000000000000000;1054 return false;1052 }1055 }105310561054 /// @notice Returns collection helper contract address1057 /// @notice Returns collection helper contract addresspallets/nonfungible/src/weights.rsdiffbeforeafterboth26#![cfg_attr(rustfmt, rustfmt_skip)]26#![cfg_attr(rustfmt, rustfmt_skip)]27#![allow(unused_parens)]27#![allow(unused_parens)]28#![allow(unused_imports)]28#![allow(unused_imports)]29#![allow(missing_docs)]29#![allow(clippy::unnecessary_cast)]30#![allow(clippy::unnecessary_cast)]303131use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};32use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};47 fn set_token_properties(b: u32, ) -> Weight;48 fn set_token_properties(b: u32, ) -> Weight;48 fn delete_token_properties(b: u32, ) -> Weight;49 fn delete_token_properties(b: u32, ) -> Weight;49 fn token_owner() -> Weight;50 fn token_owner() -> Weight;51 fn set_approval_for_all() -> Weight;52 fn is_approved_for_all() -> Weight;50}53}515452/// Weights for pallet_nonfungible using the Substrate node and recommended hardware.55/// Weights for pallet_nonfungible using the Substrate node and recommended hardware.195 Weight::from_ref_time(4_366_000)198 Weight::from_ref_time(4_366_000)196 .saturating_add(T::DbWeight::get().reads(1 as u64))199 .saturating_add(T::DbWeight::get().reads(1 as u64))197 }200 }201 // Storage: Nonfungible WalletOperator (r:0 w:1)202 fn set_approval_for_all() -> Weight {203 Weight::from_ref_time(16_231_000 as u64)204 .saturating_add(T::DbWeight::get().writes(1 as u64))205 }206 // Storage: Nonfungible WalletOperator (r:1 w:0)207 fn is_approved_for_all() -> Weight {208 Weight::from_ref_time(6_161_000 as u64)209 .saturating_add(T::DbWeight::get().reads(1 as u64))210 }198}211}199212200// For backwards compatibility and tests213// For backwards compatibility and tests342 Weight::from_ref_time(4_366_000)355 Weight::from_ref_time(4_366_000)343 .saturating_add(RocksDbWeight::get().reads(1 as u64))356 .saturating_add(RocksDbWeight::get().reads(1 as u64))344 }357 }358 // Storage: Nonfungible WalletOperator (r:0 w:1)359 fn set_approval_for_all() -> Weight {360 Weight::from_ref_time(16_231_000 as u64)361 .saturating_add(RocksDbWeight::get().writes(1 as u64))362 }363 // Storage: Nonfungible WalletOperator (r:1 w:0)364 fn is_approved_for_all() -> Weight {365 Weight::from_ref_time(6_161_000 as u64)366 .saturating_add(RocksDbWeight::get().reads(1 as u64))367 }345}368}346369pallets/refungible/src/benchmarking.rsdiffbeforeafterboth291 let item = create_max_item(&collection, &sender, [(owner.clone(), 100)])?;291 let item = create_max_item(&collection, &sender, [(owner.clone(), 100)])?;292 }: {<Pallet<T>>::token_owner(collection.id, item)}292 }: {<Pallet<T>>::token_owner(collection.id, item)}293294 set_approval_for_all {295 bench_init!{296 owner: sub; collection: collection(owner);297 operator: cross_from_sub(owner); owner: cross_sub;298 };299 }: {<Pallet<T>>::set_approval_for_all(&collection, &owner, &operator, true)}300301 is_approved_for_all {302 bench_init!{303 owner: sub; collection: collection(owner);304 operator: cross_from_sub(owner); owner: cross_sub;305 };306 }: {<Pallet<T>>::is_approved_for_all(&collection, &owner, &operator)}293}307}294308pallets/refungible/src/common.rsdiffbeforeafterboth153 <SelfWeightOf<T>>::token_owner()153 <SelfWeightOf<T>>::token_owner()154 }154 }155156 fn set_approval_for_all() -> Weight {157 <SelfWeightOf<T>>::set_approval_for_all()158 }155}159}156160157fn map_create_data<T: Config>(161fn map_create_data<T: Config>(517 <Pallet<T>>::total_pieces(self.id, token)521 <Pallet<T>>::total_pieces(self.id, token)518 }522 }523524 fn set_approval_for_all(525 &self,526 owner: T::CrossAccountId,527 operator: T::CrossAccountId,528 approve: bool,529 ) -> DispatchResultWithPostInfo {530 with_weight(531 <Pallet<T>>::set_approval_for_all(self, &owner, &operator, approve),532 <CommonWeights<T>>::set_approval_for_all(),533 )534 }535536 fn is_approved_for_all(&self, owner: T::CrossAccountId, operator: T::CrossAccountId) -> bool {537 <Pallet<T>>::is_approved_for_all(self, &owner, &operator)538 }519}539}520540521impl<T: Config> RefungibleExtensions<T> for RefungibleHandle<T> {541impl<T: Config> RefungibleExtensions<T> for RefungibleHandle<T> {pallets/refungible/src/erc.rsdiffbeforeafterboth461 Err("not implemented".into())461 Err("not implemented".into())462 }462 }463463464 /// @notice Sets or unsets the approval of a given operator.465 /// An operator is allowed to transfer all tokens of the sender on their behalf.464 /// @dev Not implemented466 /// @param operator Operator467 /// @param approved Is operator enabled or disabled468 #[weight(<SelfWeightOf<T>>::set_approval_for_all())]465 fn set_approval_for_all(469 fn set_approval_for_all(466 &mut self,470 &mut self,467 _caller: caller,471 caller: caller,468 _operator: address,472 operator: address,469 _approved: bool,473 approved: bool,470 ) -> Result<void> {474 ) -> Result<void> {471 // TODO: Not implemetable475 let caller = T::CrossAccountId::from_eth(caller);476 let operator = T::CrossAccountId::from_eth(operator);477478 <Pallet<T>>::set_approval_for_all(self, &caller, &operator, approved)472 Err("not implemented".into())479 .map_err(dispatch_to_evm::<T>)?;480 Ok(())473 }481 }474482475 /// @dev Not implemented483 /// @dev Not implemented478 Err("not implemented".into())486 Err("not implemented".into())479 }487 }480488481 /// @dev Not implemented489 /// @notice Tells whether an operator is approved by a given owner.490 #[weight(<SelfWeightOf<T>>::is_approved_for_all())]482 fn is_approved_for_all(&self, _owner: address, _operator: address) -> Result<address> {491 fn is_approved_for_all(&self, owner: address, operator: address) -> Result<bool> {483 // TODO: Not implemetable492 let owner = T::CrossAccountId::from_eth(owner);493 let operator = T::CrossAccountId::from_eth(operator);494484 Err("not implemented".into())495 Ok(<Pallet<T>>::is_approved_for_all(self, &owner, &operator))485 }496 }486497487 /// @notice Returns collection helper contract address498 /// @notice Returns collection helper contract addresspallets/refungible/src/lib.rsdiffbeforeafterboth273 QueryKind = ValueQuery,273 QueryKind = ValueQuery,274 >;274 >;275276 /// Operator set by a wallet owner that could perform certain transactions on all tokens in the wallet.277 #[pallet::storage]278 pub type WalletOperator<T: Config> = StorageNMap<279 Key = (280 Key<Twox64Concat, CollectionId>,281 Key<Blake2_128Concat, T::CrossAccountId>,282 Key<Blake2_128Concat, T::CrossAccountId>,283 ),284 Value = bool,285 QueryKind = OptionQuery,286 >;275287276 #[pallet::hooks]288 #[pallet::hooks]277 impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {289 impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {1162 let allowance =1174 let allowance =1163 <Allowance<T>>::get((collection.id, token, from, &spender)).checked_sub(amount);1175 <Allowance<T>>::get((collection.id, token, from, &spender)).checked_sub(amount);11761177 // Allowance if any would be reduced if spender is also wallet operator1178 if <WalletOperator<T>>::get((collection.id, from, spender)) == Some(true) {1179 return Ok(allowance);1180 }11811164 if allowance.is_none() {1182 if allowance.is_none() {1165 ensure!(1183 ensure!(1388 }1406 }1389 }1407 }14081409 /// Sets or unsets the approval of a given operator.1410 ///1411 /// An operator is allowed to transfer all tokens of the sender on their behalf.1412 /// - `owner`: Token owner1413 /// - `operator`: Operator1414 /// - `approve`: Is operator enabled or disabled1415 pub fn set_approval_for_all(1416 collection: &RefungibleHandle<T>,1417 owner: &T::CrossAccountId,1418 operator: &T::CrossAccountId,1419 approve: bool,1420 ) -> DispatchResult {1421 if collection.permissions.access() == AccessMode::AllowList {1422 collection.check_allowlist(owner)?;1423 collection.check_allowlist(operator)?;1424 }14251426 <PalletCommon<T>>::ensure_correct_receiver(operator)?;14271428 // =========14291430 <WalletOperator<T>>::insert((collection.id, owner, operator), approve);1431 <PalletEvm<T>>::deposit_log(1432 ERC721Events::ApprovalForAll {1433 owner: *owner.as_eth(),1434 operator: *operator.as_eth(),1435 approved: approve,1436 }1437 .to_log(collection_id_to_address(collection.id)),1438 );1439 <PalletCommon<T>>::deposit_event(CommonEvent::ApprovedForAll(1440 collection.id,1441 owner.clone(),1442 operator.clone(),1443 approve,1444 ));1445 Ok(())1446 }14471448 /// Tells whether an operator is approved by a given owner.1449 pub fn is_approved_for_all(1450 collection: &RefungibleHandle<T>,1451 owner: &T::CrossAccountId,1452 operator: &T::CrossAccountId,1453 ) -> bool {1454 <WalletOperator<T>>::get((collection.id, owner, operator)).unwrap_or(false)1455 }1390}1456}13911457pallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth1017 dummy = 0;1017 dummy = 0;1018 }1018 }101910191020 /// @notice Sets or unsets the approval of a given operator.1021 /// An operator is allowed to transfer all tokens of the sender on their behalf.1020 /// @dev Not implemented1022 /// @param operator Operator1023 /// @param approved Is operator enabled or disabled1021 /// @dev EVM selector for this function is: 0xa22cb465,1024 /// @dev EVM selector for this function is: 0xa22cb465,1022 /// or in textual repr: setApprovalForAll(address,bool)1025 /// or in textual repr: setApprovalForAll(address,bool)1023 function setApprovalForAll(address operator, bool approved) public {1026 function setApprovalForAll(address operator, bool approved) public {1037 return 0x0000000000000000000000000000000000000000;1040 return 0x0000000000000000000000000000000000000000;1038 }1041 }103910421040 /// @dev Not implemented1043 /// @notice Tells whether an operator is approved by a given owner.1041 /// @dev EVM selector for this function is: 0xe985e9c5,1044 /// @dev EVM selector for this function is: 0xe985e9c5,1042 /// or in textual repr: isApprovedForAll(address,address)1045 /// or in textual repr: isApprovedForAll(address,address)1043 function isApprovedForAll(address owner, address operator) public view returns (address) {1046 function isApprovedForAll(address owner, address operator) public view returns (bool) {1044 require(false, stub_error);1047 require(false, stub_error);1045 owner;1048 owner;1046 operator;1049 operator;1047 dummy;1050 dummy;1048 return 0x0000000000000000000000000000000000000000;1051 return false;1049 }1052 }105010531051 /// @notice Returns collection helper contract address1054 /// @notice Returns collection helper contract addresspallets/refungible/src/weights.rsdiffbeforeafterboth3//! Autogenerated weights for pallet_refungible3//! Autogenerated weights for pallet_refungible4//!4//!5//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev5//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev6//! DATE: 2022-08-15, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`6//! DATE: 2022-11-25, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`7//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 10247//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024889// Executed Command:9// Executed Command:26#![cfg_attr(rustfmt, rustfmt_skip)]26#![cfg_attr(rustfmt, rustfmt_skip)]27#![allow(unused_parens)]27#![allow(unused_parens)]28#![allow(unused_imports)]28#![allow(unused_imports)]29#![allow(missing_docs)]29#![allow(clippy::unnecessary_cast)]30#![allow(clippy::unnecessary_cast)]303131use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};32use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};54 fn delete_token_properties(b: u32, ) -> Weight;55 fn delete_token_properties(b: u32, ) -> Weight;55 fn repartition_item() -> Weight;56 fn repartition_item() -> Weight;56 fn token_owner() -> Weight;57 fn token_owner() -> Weight;58 fn set_approval_for_all() -> Weight;59 fn is_approved_for_all() -> Weight;57}60}586159/// Weights for pallet_refungible using the Substrate node and recommended hardware.62/// Weights for pallet_refungible using the Substrate node and recommended hardware.259 Weight::from_ref_time(9_431_000)262 Weight::from_ref_time(9_431_000)260 .saturating_add(T::DbWeight::get().reads(2 as u64))263 .saturating_add(T::DbWeight::get().reads(2 as u64))261 }264 }265 // Storage: Refungible WalletOperator (r:0 w:1)266 fn set_approval_for_all() -> Weight {267 Weight::from_ref_time(16_150_000 as u64)268 .saturating_add(T::DbWeight::get().writes(1 as u64))269 }270 // Storage: Refungible WalletOperator (r:1 w:0)271 fn is_approved_for_all() -> Weight {272 Weight::from_ref_time(5_901_000 as u64)273 .saturating_add(T::DbWeight::get().reads(1 as u64))274 }262}275}263276264// For backwards compatibility and tests277// For backwards compatibility and tests463 Weight::from_ref_time(9_431_000)476 Weight::from_ref_time(9_431_000)464 .saturating_add(RocksDbWeight::get().reads(2 as u64))477 .saturating_add(RocksDbWeight::get().reads(2 as u64))465 }478 }479 // Storage: Refungible WalletOperator (r:0 w:1)480 fn set_approval_for_all() -> Weight {481 Weight::from_ref_time(16_150_000 as u64)482 .saturating_add(RocksDbWeight::get().writes(1 as u64))483 }484 // Storage: Refungible WalletOperator (r:1 w:0)485 fn is_approved_for_all() -> Weight {486 Weight::from_ref_time(5_901_000 as u64)487 .saturating_add(RocksDbWeight::get().reads(1 as u64))488 }466}489}467490pallets/unique/src/lib.rsdiffbeforeafterboth1127 })1127 })1128 }1128 }11291130 /// Sets or unsets the approval of a given operator.1131 ///1132 /// An operator is allowed to transfer all tokens of the sender on their behalf.1133 ///1134 /// # Arguments1135 ///1136 /// * `owner`: Token owner1137 /// * `operator`: Operator1138 /// * `approve`: Is operator enabled or disabled1139 #[weight = T::CommonWeightInfo::set_approval_for_all()]1140 pub fn set_approval_for_all(1141 origin,1142 collection_id: CollectionId,1143 operator: T::CrossAccountId,1144 approve: bool,1145 ) -> DispatchResultWithPostInfo {1146 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);1147 dispatch_tx::<T, _>(collection_id, |d| {1148 d.set_approval_for_all(sender, operator, approve)1149 })1150 }1129 }1151 }1130}1152}11311153primitives/rpc/src/lib.rsdiffbeforeafterboth133133134 fn token_owners(collection: CollectionId, token: TokenId) -> Result<Vec<CrossAccountId>>;134 fn token_owners(collection: CollectionId, token: TokenId) -> Result<Vec<CrossAccountId>>;135136 /// Get whether an operator is approved by a given owner.137 fn is_approved_for_all(collection: CollectionId, owner: CrossAccountId, operator: CrossAccountId) -> Result<bool>;135 }138 }136}139}137140runtime/common/runtime_apis.rsdiffbeforeafterboth188 dispatch_unique_runtime!(collection.total_pieces(token_id))188 dispatch_unique_runtime!(collection.total_pieces(token_id))189 }189 }190191 fn is_approved_for_all(collection: CollectionId, owner: CrossAccountId, operator: CrossAccountId) -> Result<bool, DispatchError> {192 dispatch_unique_runtime!(collection.is_approved_for_all(owner, operator))193 }190 }194 }191195192 impl app_promotion_rpc::AppPromotionApi<Block, BlockNumber, CrossAccountId, AccountId> for Runtime {196 impl app_promotion_rpc::AppPromotionApi<Block, BlockNumber, CrossAccountId, AccountId> for Runtime {runtime/common/weights.rsdiffbeforeafterboth121 max_weight_of!(token_owner())121 max_weight_of!(token_owner())122 }122 }123124 fn set_approval_for_all() -> Weight {125 max_weight_of!(set_approval_for_all())126 }123}127}124128125#[cfg(feature = "refungible")]129#[cfg(feature = "refungible")]tests/src/approve.test.tsdiffbeforeafterboth604 });604 });605});605});606607describe('Normal user can approve other users to be wallet operator:', () => {608 let alice: IKeyringPair;609 let bob: IKeyringPair;610611 before(async () => {612 await usingPlaygrounds(async (helper, privateKey) => {613 const donor = await privateKey({filename: __filename});614 [alice, bob] = await helper.arrange.createAccounts([100n, 100n], donor);615 });616 });617618 itSub('[nft] Enable and disable approval', async ({helper}) => {619 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});620 await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});621 const checkBeforeApprovalTx = () => helper.nft.isApprovedForAll(collectionId, {Substrate: alice.address}, {Substrate: bob.address});622 expect(await checkBeforeApprovalTx()).to.be.false;623 await helper.nft.setApprovalForAll(alice, collectionId, {Substrate: bob.address}, true);624 const checkAfterApprovalTx = () => helper.nft.isApprovedForAll(collectionId, {Substrate: alice.address}, {Substrate: bob.address});625 expect(await checkAfterApprovalTx()).to.be.true;626 await helper.nft.setApprovalForAll(alice, collectionId, {Substrate: bob.address}, false);627 const checkAfterDisapprovalTx = () => helper.nft.isApprovedForAll(collectionId, {Substrate: alice.address}, {Substrate: bob.address});628 expect(await checkAfterDisapprovalTx()).to.be.false;629 });630631 itSub.ifWithPallets('[rft] Enable and disable approval', [Pallets.ReFungible], async ({helper}) => {632 const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});633 const checkBeforeApprovalTx = () => helper.rft.isApprovedForAll(collectionId, {Substrate: alice.address}, {Substrate: bob.address});634 expect(await checkBeforeApprovalTx()).to.be.false;635 await helper.rft.setApprovalForAll(alice, collectionId, {Substrate: bob.address}, true);636 const checkAfterApprovalTx = () => helper.rft.isApprovedForAll(collectionId, {Substrate: alice.address}, {Substrate: bob.address});637 expect(await checkAfterApprovalTx()).to.be.true;638 await helper.rft.setApprovalForAll(alice, collectionId, {Substrate: bob.address}, false);639 const checkAfterDisapprovalTx = () => helper.rft.isApprovedForAll(collectionId, {Substrate: alice.address}, {Substrate: bob.address});640 expect(await checkAfterDisapprovalTx()).to.be.false;641 });642});606643tests/src/eth/abi/nonFungible.jsondiffbeforeafterboth384 { "internalType": "address", "name": "operator", "type": "address" }384 { "internalType": "address", "name": "operator", "type": "address" }385 ],385 ],386 "name": "isApprovedForAll",386 "name": "isApprovedForAll",387 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],387 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],388 "stateMutability": "view",388 "stateMutability": "view",389 "type": "function"389 "type": "function"390 },390 },tests/src/eth/abi/reFungible.jsondiffbeforeafterboth366 { "internalType": "address", "name": "operator", "type": "address" }366 { "internalType": "address", "name": "operator", "type": "address" }367 ],367 ],368 "name": "isApprovedForAll",368 "name": "isApprovedForAll",369 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],369 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],370 "stateMutability": "view",370 "stateMutability": "view",371 "type": "function"371 "type": "function"372 },372 },tests/src/eth/api/UniqueNFT.soldiffbeforeafterboth671 /// or in textual repr: approve(address,uint256)671 /// or in textual repr: approve(address,uint256)672 function approve(address approved, uint256 tokenId) external;672 function approve(address approved, uint256 tokenId) external;673673674 /// @notice Sets or unsets the approval of a given operator.675 /// An operator is allowed to transfer all tokens of the sender on their behalf.674 /// @dev Not implemented676 /// @param operator Operator677 /// @param approved Is operator enabled or disabled675 /// @dev EVM selector for this function is: 0xa22cb465,678 /// @dev EVM selector for this function is: 0xa22cb465,676 /// or in textual repr: setApprovalForAll(address,bool)679 /// or in textual repr: setApprovalForAll(address,bool)677 function setApprovalForAll(address operator, bool approved) external;680 function setApprovalForAll(address operator, bool approved) external;681 /// or in textual repr: getApproved(uint256)684 /// or in textual repr: getApproved(uint256)682 function getApproved(uint256 tokenId) external view returns (address);685 function getApproved(uint256 tokenId) external view returns (address);683686684 /// @dev Not implemented687 /// @notice Tells whether an operator is approved by a given owner.685 /// @dev EVM selector for this function is: 0xe985e9c5,688 /// @dev EVM selector for this function is: 0xe985e9c5,686 /// or in textual repr: isApprovedForAll(address,address)689 /// or in textual repr: isApprovedForAll(address,address)687 function isApprovedForAll(address owner, address operator) external view returns (address);690 function isApprovedForAll(address owner, address operator) external view returns (bool);688691689 /// @notice Returns collection helper contract address692 /// @notice Returns collection helper contract address690 /// @dev EVM selector for this function is: 0x1896cce6,693 /// @dev EVM selector for this function is: 0x1896cce6,tests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth668 /// or in textual repr: approve(address,uint256)668 /// or in textual repr: approve(address,uint256)669 function approve(address approved, uint256 tokenId) external;669 function approve(address approved, uint256 tokenId) external;670670671 /// @notice Sets or unsets the approval of a given operator.672 /// An operator is allowed to transfer all tokens of the sender on their behalf.671 /// @dev Not implemented673 /// @param operator Operator674 /// @param approved Is operator enabled or disabled672 /// @dev EVM selector for this function is: 0xa22cb465,675 /// @dev EVM selector for this function is: 0xa22cb465,673 /// or in textual repr: setApprovalForAll(address,bool)676 /// or in textual repr: setApprovalForAll(address,bool)674 function setApprovalForAll(address operator, bool approved) external;677 function setApprovalForAll(address operator, bool approved) external;678 /// or in textual repr: getApproved(uint256)681 /// or in textual repr: getApproved(uint256)679 function getApproved(uint256 tokenId) external view returns (address);682 function getApproved(uint256 tokenId) external view returns (address);680683681 /// @dev Not implemented684 /// @notice Tells whether an operator is approved by a given owner.682 /// @dev EVM selector for this function is: 0xe985e9c5,685 /// @dev EVM selector for this function is: 0xe985e9c5,683 /// or in textual repr: isApprovedForAll(address,address)686 /// or in textual repr: isApprovedForAll(address,address)684 function isApprovedForAll(address owner, address operator) external view returns (address);687 function isApprovedForAll(address owner, address operator) external view returns (bool);685688686 /// @notice Returns collection helper contract address689 /// @notice Returns collection helper contract address687 /// @dev EVM selector for this function is: 0x1896cce6,690 /// @dev EVM selector for this function is: 0x1896cce6,tests/src/eth/nonFungible.test.tsdiffbeforeafterboth249 }249 }250 });250 });251252 itEth('Can perform setApprovalForAll()', async ({helper}) => {253 const owner = await helper.eth.createAccountWithBalance(donor);254 const operator = helper.eth.createAccount();255256 const collection = await helper.nft.mintCollection(minter, {});257258 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);259 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);260261 const approvedBefore = await contract.methods.isApprovedForAll(owner, operator).call();262 expect(approvedBefore).to.be.equal(false);263264 {265 const result = await contract.methods.setApprovalForAll(operator, true).send({from: owner});266267 expect(result.events.ApprovalForAll).to.be.like({268 address: collectionAddress,269 event: 'ApprovalForAll',270 returnValues: {271 owner,272 operator,273 approved: true,274 },275 });276277 const approvedAfter = await contract.methods.isApprovedForAll(owner, operator).call();278 expect(approvedAfter).to.be.equal(true);279 }280281 {282 const result = await contract.methods.setApprovalForAll(operator, false).send({from: owner});283284 expect(result.events.ApprovalForAll).to.be.like({285 address: collectionAddress,286 event: 'ApprovalForAll',287 returnValues: {288 owner,289 operator,290 approved: false,291 },292 });293294 const approvedAfter = await contract.methods.isApprovedForAll(owner, operator).call();295 expect(approvedAfter).to.be.equal(false);296 }297 });298299 itEth('Can perform burn with ApprovalForAll', async ({helper}) => {300 const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});301302 const owner = await helper.eth.createAccountWithBalance(donor);303 const operator = await helper.eth.createAccountWithBalance(donor, 100n);304305 const token = await collection.mintToken(minter, {Ethereum: owner});306307 const address = helper.ethAddress.fromCollectionId(collection.collectionId);308 const contract = helper.ethNativeContract.collection(address, 'nft');309310 {311 await contract.methods.setApprovalForAll(operator, true).send({from: owner});312 const ownerCross = helper.ethCrossAccount.fromAddress(owner);313 const result = await contract.methods.burnFromCross(ownerCross, token.tokenId).send({from: operator});314 const events = result.events.Transfer;315316 expect(events).to.be.like({317 address,318 event: 'Transfer',319 returnValues: {320 from: owner,321 to: '0x0000000000000000000000000000000000000000',322 tokenId: token.tokenId.toString(),323 },324 });325 }326 });327 328 itEth('Can perform transfer with ApprovalForAll', async ({helper}) => {329 const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});330331 const owner = await helper.eth.createAccountWithBalance(donor);332 const operator = await helper.eth.createAccountWithBalance(donor);333 const receiver = charlie;334335 const token = await collection.mintToken(minter, {Ethereum: owner});336337 const address = helper.ethAddress.fromCollectionId(collection.collectionId);338 const contract = helper.ethNativeContract.collection(address, 'nft');339340 {341 await contract.methods.setApprovalForAll(operator, true).send({from: owner});342 const ownerCross = helper.ethCrossAccount.fromAddress(owner);343 const recieverCross = helper.ethCrossAccount.fromKeyringPair(receiver);344 const result = await contract.methods.transferFromCross(ownerCross, recieverCross, token.tokenId).send({from: operator});345 const event = result.events.Transfer;346 expect(event).to.be.like({347 address: helper.ethAddress.fromCollectionId(collection.collectionId),348 event: 'Transfer',349 returnValues: {350 from: owner,351 to: helper.address.substrateToEth(receiver.address),352 tokenId: token.tokenId.toString(),353 },354 });355 }356357 expect(await token.getOwner()).to.be.like({Substrate: receiver.address});358 });251359252 itEth('Can perform burnFromCross()', async ({helper}) => {360 itEth('Can perform burnFromCross()', async ({helper}) => {253 const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});361 const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});823 });931 });824});932});933934describe('Negative tests', () => {935 let donor: IKeyringPair;936 let minter: IKeyringPair;937 let alice: IKeyringPair;938 let bob: IKeyringPair;939940 before(async function() {941 await usingEthPlaygrounds(async (helper, privateKey) => {942 donor = await privateKey({filename: __filename});943 [minter, alice, bob] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);944 });945 });946947 itEth('[negative] Cant perform burn without approval', async ({helper}) => {948 const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});949950 const owner = bob;951 const spender = await helper.eth.createAccountWithBalance(donor, 100n);952953 const token = await collection.mintToken(minter, {Substrate: owner.address});954955 const address = helper.ethAddress.fromCollectionId(collection.collectionId);956 const contract = helper.ethNativeContract.collection(address, 'nft');957958 {959 const ownerCross = helper.ethCrossAccount.fromKeyringPair(owner);960 await expect(contract.methods.burnFromCross(ownerCross, token.tokenId).send({from: spender})).to.be.rejected;961 }962 });963964 itEth('[negative] Cant perform transfer without approval', async ({helper}) => {965 const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});966 const owner = bob;967 const receiver = alice;968969 const spender = await helper.eth.createAccountWithBalance(donor, 100n);970971 const token = await collection.mintToken(minter, {Substrate: owner.address});972973 const address = helper.ethAddress.fromCollectionId(collection.collectionId);974 const contract = helper.ethNativeContract.collection(address, 'nft');975976 {977 const ownerCross = helper.ethCrossAccount.fromKeyringPair(owner);978 const recieverCross = helper.ethCrossAccount.fromKeyringPair(receiver);979 await expect(contract.methods.transferFromCross(ownerCross, recieverCross, token.tokenId).send({from: spender})).to.be.rejected;980 }981 });982});825983tests/src/eth/reFungible.test.tsdiffbeforeafterboth169 }169 }170 });170 });171172 itEth('Can perform setApprovalForAll()', async ({helper}) => {173 const owner = await helper.eth.createAccountWithBalance(donor);174 const operator = helper.eth.createAccount();175176 const collection = await helper.rft.mintCollection(minter, {});177178 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);179 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);180181 const approvedBefore = await contract.methods.isApprovedForAll(owner, operator).call();182 expect(approvedBefore).to.be.equal(false);183184 {185 const result = await contract.methods.setApprovalForAll(operator, true).send({from: owner});186187 expect(result.events.ApprovalForAll).to.be.like({188 address: collectionAddress,189 event: 'ApprovalForAll',190 returnValues: {191 owner,192 operator,193 approved: true,194 },195 });196197 const approvedAfter = await contract.methods.isApprovedForAll(owner, operator).call();198 expect(approvedAfter).to.be.equal(true);199 }200201 {202 const result = await contract.methods.setApprovalForAll(operator, false).send({from: owner});203204 expect(result.events.ApprovalForAll).to.be.like({205 address: collectionAddress,206 event: 'ApprovalForAll',207 returnValues: {208 owner,209 operator,210 approved: false,211 },212 });213214 const approvedAfter = await contract.methods.isApprovedForAll(owner, operator).call();215 expect(approvedAfter).to.be.equal(false);216 }217 });218219 itEth('Can perform burn with ApprovalForAll', async ({helper}) => {220 const collection = await helper.rft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});221222 const owner = await helper.eth.createAccountWithBalance(donor);223 const operator = await helper.eth.createAccountWithBalance(donor, 100n);224225 const token = await collection.mintToken(minter, 100n, {Ethereum: owner});226227 const address = helper.ethAddress.fromCollectionId(collection.collectionId);228 const contract = helper.ethNativeContract.collection(address, 'rft');229230 {231 await contract.methods.setApprovalForAll(operator, true).send({from: owner});232 const ownerCross = helper.ethCrossAccount.fromAddress(owner);233 const result = await contract.methods.burnFromCross(ownerCross, token.tokenId).send({from: operator});234 const events = result.events.Transfer;235236 expect(events).to.be.like({237 address,238 event: 'Transfer',239 returnValues: {240 from: owner,241 to: '0x0000000000000000000000000000000000000000',242 tokenId: token.tokenId.toString(),243 },244 });245 }246 });247248 itEth('Can perform burn with approve and approvalForAll', async ({helper}) => {249 const collection = await helper.rft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});250251 const owner = await helper.eth.createAccountWithBalance(donor);252 const operator = await helper.eth.createAccountWithBalance(donor, 100n);253254 const token = await collection.mintToken(minter, 100n, {Ethereum: owner});255256 const address = helper.ethAddress.fromCollectionId(collection.collectionId);257 const contract = helper.ethNativeContract.collection(address, 'rft');258259 const rftToken = helper.ethNativeContract.rftTokenById(token.collectionId, token.tokenId, owner);260261 {262 await rftToken.methods.approve(operator, 15n).send({from: owner});263 await contract.methods.setApprovalForAll(operator, true).send({from: owner});264 await rftToken.methods.burnFrom(owner, 10n).send({from: operator});265 const allowance = await rftToken.methods.allowance(owner, operator).call();266 expect(allowance).to.be.equal('5');267 }268 });269 270 itEth('Can perform transfer with ApprovalForAll', async ({helper}) => {271 const collection = await helper.rft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});272273 const owner = await helper.eth.createAccountWithBalance(donor);274 const operator = await helper.eth.createAccountWithBalance(donor);275 const receiver = charlie;276277 const token = await collection.mintToken(minter, 100n, {Ethereum: owner});278279 const address = helper.ethAddress.fromCollectionId(collection.collectionId);280 const contract = helper.ethNativeContract.collection(address, 'rft');281282 {283 await contract.methods.setApprovalForAll(operator, true).send({from: owner});284 const ownerCross = helper.ethCrossAccount.fromAddress(owner);285 const recieverCross = helper.ethCrossAccount.fromKeyringPair(receiver);286 const result = await contract.methods.transferFromCross(ownerCross, recieverCross, token.tokenId).send({from: operator});287 const event = result.events.Transfer;288 expect(event).to.be.like({289 address: helper.ethAddress.fromCollectionId(collection.collectionId),290 event: 'Transfer',291 returnValues: {292 from: owner,293 to: helper.address.substrateToEth(receiver.address),294 tokenId: token.tokenId.toString(),295 },296 });297 }298299 expect(await token.getTop10Owners()).to.be.like([{Substrate: receiver.address}]);300 });171301172 itEth('Can perform burn()', async ({helper}) => {302 itEth('Can perform burn()', async ({helper}) => {173 const caller = await helper.eth.createAccountWithBalance(donor);303 const caller = await helper.eth.createAccountWithBalance(donor);595 });725 });596});726});727728describe('Negative tests', () => {729 let donor: IKeyringPair;730 let minter: IKeyringPair;731 let alice: IKeyringPair;732733 before(async function() {734 await usingEthPlaygrounds(async (helper, privateKey) => {735 donor = await privateKey({filename: __filename});736 [minter, alice] = await helper.arrange.createAccounts([100n, 100n], donor);737 });738 });739740 itEth('[negative] Cant perform burn without approval', async ({helper}) => {741 const collection = await helper.rft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});742743 const owner = await helper.eth.createAccountWithBalance(donor, 100n);744 const spender = await helper.eth.createAccountWithBalance(donor, 100n);745746 const token = await collection.mintToken(minter, 100n, {Ethereum: owner});747748 const address = helper.ethAddress.fromCollectionId(collection.collectionId);749 const contract = helper.ethNativeContract.collection(address, 'rft');750751 {752 const ownerCross = helper.ethCrossAccount.fromAddress(owner);753 await expect(contract.methods.burnFromCross(ownerCross, token.tokenId).send({from: spender})).to.be.rejected;754 }755 });756757 itEth('[negative] Cant perform transfer without approval', async ({helper}) => {758 const collection = await helper.rft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});759 const owner = await helper.eth.createAccountWithBalance(donor, 100n);760 const receiver = alice;761762 const spender = await helper.eth.createAccountWithBalance(donor, 100n);763764 const token = await collection.mintToken(minter, 100n, {Ethereum: owner});765766 const address = helper.ethAddress.fromCollectionId(collection.collectionId);767 const contract = helper.ethNativeContract.collection(address, 'rft');768769 {770 const ownerCross = helper.ethCrossAccount.fromAddress(owner);771 const recieverCross = helper.ethCrossAccount.fromKeyringPair(receiver);772 await expect(contract.methods.transferFromCross(ownerCross, recieverCross, token.tokenId).send({from: spender})).to.be.rejected;773 }774 });775});597776tests/src/interfaces/augment-api-errors.tsdiffbeforeafterboth385 * Not Fungible item data used to mint in Fungible collection.385 * Not Fungible item data used to mint in Fungible collection.386 **/386 **/387 NotFungibleDataUsedToMintFungibleCollectionToken: AugmentedError<ApiType>;387 NotFungibleDataUsedToMintFungibleCollectionToken: AugmentedError<ApiType>;388 /**389 * Setting approval for all is not allowed.390 **/391 SettingApprovalForAllNotAllowed: AugmentedError<ApiType>;388 /**392 /**389 * Setting item properties is not allowed.393 * Setting item properties is not allowed.390 **/394 **/tests/src/interfaces/augment-api-events.tsdiffbeforeafterboth106 * Amount pieces of token owned by `sender` was approved for `spender`.106 * Amount pieces of token owned by `sender` was approved for `spender`.107 **/107 **/108 Approved: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;108 Approved: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;109 /**110 * Amount pieces of token owned by `sender` was approved for `spender`.111 **/112 ApprovedForAll: AugmentedEvent<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, bool]>;109 /**113 /**110 * New collection was created114 * New collection was created111 **/115 **/tests/src/interfaces/augment-api-query.tsdiffbeforeafterboth441 * Total amount of minted tokens in a collection.441 * Total amount of minted tokens in a collection.442 **/442 **/443 tokensMinted: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<u32>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;443 tokensMinted: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<u32>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;444 /**445 * Operator set by a wallet owner that could perform certain transactions on all tokens in the wallet.446 **/447 walletOperator: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, arg3: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array) => Observable<Option<bool>>, [u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr]> & QueryableStorageEntry<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr]>;444 /**448 /**445 * Generic query449 * Generic query446 **/450 **/644 * Total amount of pieces for token648 * Total amount of pieces for token645 **/649 **/646 totalSupply: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array) => Observable<u128>, [u32, u32]> & QueryableStorageEntry<ApiType, [u32, u32]>;650 totalSupply: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array) => Observable<u128>, [u32, u32]> & QueryableStorageEntry<ApiType, [u32, u32]>;651 /**652 * Operator set by a wallet owner that could perform certain transactions on all tokens in the wallet.653 **/654 walletOperator: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, arg3: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array) => Observable<Option<bool>>, [u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr]> & QueryableStorageEntry<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr]>;647 /**655 /**648 * Generic query656 * Generic query649 **/657 **/tests/src/interfaces/augment-api-rpc.tsdiffbeforeafterboth719 * Get effective collection limits719 * Get effective collection limits720 **/720 **/721 effectiveCollectionLimits: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<UpDataStructsCollectionLimits>>>;721 effectiveCollectionLimits: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<UpDataStructsCollectionLimits>>>;722 /**723 * Tells whether an operator is approved by a given owner.724 **/725 isApprovedForAll: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, owner: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, operator: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<bool>>>;722 /**726 /**723 * Get the last token ID created in a collection727 * Get the last token ID created in a collection724 **/728 **/tests/src/interfaces/augment-api-tx.tsdiffbeforeafterboth1544 * * `amount`: New number of parts/pieces into which the token shall be partitioned.1544 * * `amount`: New number of parts/pieces into which the token shall be partitioned.1545 **/1545 **/1546 repartition: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, amount: u128 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, u32, u128]>;1546 repartition: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, amount: u128 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, u32, u128]>;1547 /**1548 * Sets or unsets the approval of a given operator.1549 * 1550 * An operator is allowed to transfer all tokens of the sender on their behalf.1551 * 1552 * # Arguments1553 * 1554 * * `owner`: Token owner1555 * * `operator`: Operator1556 * * `approve`: Is operator enabled or disabled1557 **/1558 setApprovalForAll: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, operator: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, approve: bool | boolean | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, PalletEvmAccountBasicCrossAccountIdRepr, bool]>;1547 /**1559 /**1548 * Set specific limits of a collection. Empty, or None fields mean chain default.1560 * Set specific limits of a collection. Empty, or None fields mean chain default.1549 * 1561 * tests/src/interfaces/default/types.tsdiffbeforeafterboth1286 readonly asTransfer: ITuple<[u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;1286 readonly asTransfer: ITuple<[u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;1287 readonly isApproved: boolean;1287 readonly isApproved: boolean;1288 readonly asApproved: ITuple<[u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;1288 readonly asApproved: ITuple<[u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;1289 readonly isApprovedForAll: boolean;1290 readonly asApprovedForAll: ITuple<[u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, bool]>;1289 readonly isCollectionPropertySet: boolean;1291 readonly isCollectionPropertySet: boolean;1290 readonly asCollectionPropertySet: ITuple<[u32, Bytes]>;1292 readonly asCollectionPropertySet: ITuple<[u32, Bytes]>;1291 readonly isCollectionPropertyDeleted: boolean;1293 readonly isCollectionPropertyDeleted: boolean;1296 readonly asTokenPropertyDeleted: ITuple<[u32, u32, Bytes]>;1298 readonly asTokenPropertyDeleted: ITuple<[u32, u32, Bytes]>;1297 readonly isPropertyPermissionSet: boolean;1299 readonly isPropertyPermissionSet: boolean;1298 readonly asPropertyPermissionSet: ITuple<[u32, Bytes]>;1300 readonly asPropertyPermissionSet: ITuple<[u32, Bytes]>;1299 readonly type: 'CollectionCreated' | 'CollectionDestroyed' | 'ItemCreated' | 'ItemDestroyed' | 'Transfer' | 'Approved' | 'CollectionPropertySet' | 'CollectionPropertyDeleted' | 'TokenPropertySet' | 'TokenPropertyDeleted' | 'PropertyPermissionSet';1301 readonly type: 'CollectionCreated' | 'CollectionDestroyed' | 'ItemCreated' | 'ItemDestroyed' | 'Transfer' | 'Approved' | 'ApprovedForAll' | 'CollectionPropertySet' | 'CollectionPropertyDeleted' | 'TokenPropertySet' | 'TokenPropertyDeleted' | 'PropertyPermissionSet';1300}1302}130113031302/** @name PalletConfigurationCall */1304/** @name PalletConfigurationCall */1603 readonly isFungibleItemsDontHaveData: boolean;1605 readonly isFungibleItemsDontHaveData: boolean;1604 readonly isFungibleDisallowsNesting: boolean;1606 readonly isFungibleDisallowsNesting: boolean;1605 readonly isSettingPropertiesNotAllowed: boolean;1607 readonly isSettingPropertiesNotAllowed: boolean;1608 readonly isSettingApprovalForAllNotAllowed: boolean;1606 readonly type: 'NotFungibleDataUsedToMintFungibleCollectionToken' | 'FungibleItemsHaveNoId' | 'FungibleItemsDontHaveData' | 'FungibleDisallowsNesting' | 'SettingPropertiesNotAllowed';1609 readonly type: 'NotFungibleDataUsedToMintFungibleCollectionToken' | 'FungibleItemsHaveNoId' | 'FungibleItemsDontHaveData' | 'FungibleDisallowsNesting' | 'SettingPropertiesNotAllowed' | 'SettingApprovalForAllNotAllowed';1607}1610}160816111609/** @name PalletInflationCall */1612/** @name PalletInflationCall */2309 readonly tokenId: u32;2312 readonly tokenId: u32;2310 readonly amount: u128;2313 readonly amount: u128;2311 } & Struct;2314 } & Struct;2315 readonly isSetApprovalForAll: boolean;2316 readonly asSetApprovalForAll: {2317 readonly collectionId: u32;2318 readonly operator: PalletEvmAccountBasicCrossAccountIdRepr;2319 readonly approve: bool;2320 } & Struct;2312 readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'SetCollectionProperties' | 'DeleteCollectionProperties' | 'SetTokenProperties' | 'DeleteTokenProperties' | 'SetTokenPropertyPermissions' | 'CreateMultipleItemsEx' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetCollectionLimits' | 'SetCollectionPermissions' | 'Repartition';2321 readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'SetCollectionProperties' | 'DeleteCollectionProperties' | 'SetTokenProperties' | 'DeleteTokenProperties' | 'SetTokenPropertyPermissions' | 'CreateMultipleItemsEx' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetCollectionLimits' | 'SetCollectionPermissions' | 'Repartition' | 'SetApprovalForAll';2313}2322}231423232315/** @name PalletUniqueError */2324/** @name PalletUniqueError */tests/src/interfaces/lookup.tsdiffbeforeafterboth1046 ItemDestroyed: '(u32,u32,PalletEvmAccountBasicCrossAccountIdRepr,u128)',1046 ItemDestroyed: '(u32,u32,PalletEvmAccountBasicCrossAccountIdRepr,u128)',1047 Transfer: '(u32,u32,PalletEvmAccountBasicCrossAccountIdRepr,PalletEvmAccountBasicCrossAccountIdRepr,u128)',1047 Transfer: '(u32,u32,PalletEvmAccountBasicCrossAccountIdRepr,PalletEvmAccountBasicCrossAccountIdRepr,u128)',1048 Approved: '(u32,u32,PalletEvmAccountBasicCrossAccountIdRepr,PalletEvmAccountBasicCrossAccountIdRepr,u128)',1048 Approved: '(u32,u32,PalletEvmAccountBasicCrossAccountIdRepr,PalletEvmAccountBasicCrossAccountIdRepr,u128)',1049 ApprovedForAll: '(u32,PalletEvmAccountBasicCrossAccountIdRepr,PalletEvmAccountBasicCrossAccountIdRepr,bool)',1049 CollectionPropertySet: '(u32,Bytes)',1050 CollectionPropertySet: '(u32,Bytes)',1050 CollectionPropertyDeleted: '(u32,Bytes)',1051 CollectionPropertyDeleted: '(u32,Bytes)',1051 TokenPropertySet: '(u32,u32,Bytes)',1052 TokenPropertySet: '(u32,u32,Bytes)',1052 TokenPropertyDeleted: '(u32,u32,Bytes)',1053 TokenPropertyDeleted: '(u32,u32,Bytes)',1053 PropertyPermissionSet: '(u32,Bytes)'1054 PropertyPermissionSet: '(u32,Bytes)'1054 }1055 }1055 },1056 },1056 /**1057 /**1057 * Lookup99: pallet_structure::pallet::Event<T>1058 * Lookup100: pallet_structure::pallet::Event<T>1058 **/1059 **/1059 PalletStructureEvent: {1060 PalletStructureEvent: {1060 _enum: {1061 _enum: {1061 Executed: 'Result<Null, SpRuntimeDispatchError>'1062 Executed: 'Result<Null, SpRuntimeDispatchError>'1062 }1063 }1063 },1064 },1064 /**1065 /**1065 * Lookup100: pallet_rmrk_core::pallet::Event<T>1066 * Lookup101: pallet_rmrk_core::pallet::Event<T>1066 **/1067 **/1067 PalletRmrkCoreEvent: {1068 PalletRmrkCoreEvent: {1068 _enum: {1069 _enum: {1069 CollectionCreated: {1070 CollectionCreated: {1138 }1139 }1139 }1140 }1140 },1141 },1141 /**1142 /**1142 * Lookup101: rmrk_traits::nft::AccountIdOrCollectionNftTuple<sp_core::crypto::AccountId32>1143 * Lookup102: rmrk_traits::nft::AccountIdOrCollectionNftTuple<sp_core::crypto::AccountId32>1143 **/1144 **/1144 RmrkTraitsNftAccountIdOrCollectionNftTuple: {1145 RmrkTraitsNftAccountIdOrCollectionNftTuple: {1145 _enum: {1146 _enum: {1146 AccountId: 'AccountId32',1147 AccountId: 'AccountId32',2303 collectionId: 'u32',2304 collectionId: 'u32',2304 tokenId: 'u32',2305 tokenId: 'u32',2305 amount: 'u128'2306 amount: 'u128',2306 }2307 },2308 set_approval_for_all: {2309 collectionId: 'u32',2310 operator: 'PalletEvmAccountBasicCrossAccountIdRepr',2311 approve: 'bool'2312 }2307 }2313 }2308 },2314 },2309 /**2315 /**3445 * Lookup430: pallet_fungible::pallet::Error<T>3451 * Lookup430: pallet_fungible::pallet::Error<T>3446 **/3452 **/3447 PalletFungibleError: {3453 PalletFungibleError: {3448 _enum: ['NotFungibleDataUsedToMintFungibleCollectionToken', 'FungibleItemsHaveNoId', 'FungibleItemsDontHaveData', 'FungibleDisallowsNesting', 'SettingPropertiesNotAllowed']3454 _enum: ['NotFungibleDataUsedToMintFungibleCollectionToken', 'FungibleItemsHaveNoId', 'FungibleItemsDontHaveData', 'FungibleDisallowsNesting', 'SettingPropertiesNotAllowed', 'SettingApprovalForAllNotAllowed']3449 },3455 },3450 /**3456 /**3451 * Lookup431: pallet_refungible::ItemData3457 * Lookup431: pallet_refungible::ItemDatatests/src/interfaces/types-lookup.tsdiffbeforeafterboth1182 readonly asTransfer: ITuple<[u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;1182 readonly asTransfer: ITuple<[u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;1183 readonly isApproved: boolean;1183 readonly isApproved: boolean;1184 readonly asApproved: ITuple<[u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;1184 readonly asApproved: ITuple<[u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;1185 readonly isApprovedForAll: boolean;1186 readonly asApprovedForAll: ITuple<[u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, bool]>;1185 readonly isCollectionPropertySet: boolean;1187 readonly isCollectionPropertySet: boolean;1186 readonly asCollectionPropertySet: ITuple<[u32, Bytes]>;1188 readonly asCollectionPropertySet: ITuple<[u32, Bytes]>;1187 readonly isCollectionPropertyDeleted: boolean;1189 readonly isCollectionPropertyDeleted: boolean;1192 readonly asTokenPropertyDeleted: ITuple<[u32, u32, Bytes]>;1194 readonly asTokenPropertyDeleted: ITuple<[u32, u32, Bytes]>;1193 readonly isPropertyPermissionSet: boolean;1195 readonly isPropertyPermissionSet: boolean;1194 readonly asPropertyPermissionSet: ITuple<[u32, Bytes]>;1196 readonly asPropertyPermissionSet: ITuple<[u32, Bytes]>;1195 readonly type: 'CollectionCreated' | 'CollectionDestroyed' | 'ItemCreated' | 'ItemDestroyed' | 'Transfer' | 'Approved' | 'CollectionPropertySet' | 'CollectionPropertyDeleted' | 'TokenPropertySet' | 'TokenPropertyDeleted' | 'PropertyPermissionSet';1197 readonly type: 'CollectionCreated' | 'CollectionDestroyed' | 'ItemCreated' | 'ItemDestroyed' | 'Transfer' | 'Approved' | 'ApprovedForAll' | 'CollectionPropertySet' | 'CollectionPropertyDeleted' | 'TokenPropertySet' | 'TokenPropertyDeleted' | 'PropertyPermissionSet';1196 }1198 }119711991198 /** @name PalletStructureEvent (99) */1200 /** @name PalletStructureEvent (100) */1199 interface PalletStructureEvent extends Enum {1201 interface PalletStructureEvent extends Enum {1200 readonly isExecuted: boolean;1202 readonly isExecuted: boolean;1201 readonly asExecuted: Result<Null, SpRuntimeDispatchError>;1203 readonly asExecuted: Result<Null, SpRuntimeDispatchError>;1202 readonly type: 'Executed';1204 readonly type: 'Executed';1203 }1205 }120412061205 /** @name PalletRmrkCoreEvent (100) */1207 /** @name PalletRmrkCoreEvent (101) */1206 interface PalletRmrkCoreEvent extends Enum {1208 interface PalletRmrkCoreEvent extends Enum {1207 readonly isCollectionCreated: boolean;1209 readonly isCollectionCreated: boolean;1208 readonly asCollectionCreated: {1210 readonly asCollectionCreated: {1292 readonly type: 'CollectionCreated' | 'CollectionDestroyed' | 'IssuerChanged' | 'CollectionLocked' | 'NftMinted' | 'NftBurned' | 'NftSent' | 'NftAccepted' | 'NftRejected' | 'PropertySet' | 'ResourceAdded' | 'ResourceRemoval' | 'ResourceAccepted' | 'ResourceRemovalAccepted' | 'PrioritySet';1294 readonly type: 'CollectionCreated' | 'CollectionDestroyed' | 'IssuerChanged' | 'CollectionLocked' | 'NftMinted' | 'NftBurned' | 'NftSent' | 'NftAccepted' | 'NftRejected' | 'PropertySet' | 'ResourceAdded' | 'ResourceRemoval' | 'ResourceAccepted' | 'ResourceRemovalAccepted' | 'PrioritySet';1293 }1295 }129412961295 /** @name RmrkTraitsNftAccountIdOrCollectionNftTuple (101) */1297 /** @name RmrkTraitsNftAccountIdOrCollectionNftTuple (102) */1296 interface RmrkTraitsNftAccountIdOrCollectionNftTuple extends Enum {1298 interface RmrkTraitsNftAccountIdOrCollectionNftTuple extends Enum {1297 readonly isAccountId: boolean;1299 readonly isAccountId: boolean;1298 readonly asAccountId: AccountId32;1300 readonly asAccountId: AccountId32;2539 readonly tokenId: u32;2541 readonly tokenId: u32;2540 readonly amount: u128;2542 readonly amount: u128;2541 } & Struct;2543 } & Struct;2544 readonly isSetApprovalForAll: boolean;2545 readonly asSetApprovalForAll: {2546 readonly collectionId: u32;2547 readonly operator: PalletEvmAccountBasicCrossAccountIdRepr;2548 readonly approve: bool;2549 } & Struct;2542 readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'SetCollectionProperties' | 'DeleteCollectionProperties' | 'SetTokenProperties' | 'DeleteTokenProperties' | 'SetTokenPropertyPermissions' | 'CreateMultipleItemsEx' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetCollectionLimits' | 'SetCollectionPermissions' | 'Repartition';2550 readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'SetCollectionProperties' | 'DeleteCollectionProperties' | 'SetTokenProperties' | 'DeleteTokenProperties' | 'SetTokenPropertyPermissions' | 'CreateMultipleItemsEx' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetCollectionLimits' | 'SetCollectionPermissions' | 'Repartition' | 'SetApprovalForAll';2543 }2551 }254425522545 /** @name UpDataStructsCollectionMode (240) */2553 /** @name UpDataStructsCollectionMode (240) */3655 readonly isFungibleItemsDontHaveData: boolean;3663 readonly isFungibleItemsDontHaveData: boolean;3656 readonly isFungibleDisallowsNesting: boolean;3664 readonly isFungibleDisallowsNesting: boolean;3657 readonly isSettingPropertiesNotAllowed: boolean;3665 readonly isSettingPropertiesNotAllowed: boolean;3666 readonly isSettingApprovalForAllNotAllowed: boolean;3658 readonly type: 'NotFungibleDataUsedToMintFungibleCollectionToken' | 'FungibleItemsHaveNoId' | 'FungibleItemsDontHaveData' | 'FungibleDisallowsNesting' | 'SettingPropertiesNotAllowed';3667 readonly type: 'NotFungibleDataUsedToMintFungibleCollectionToken' | 'FungibleItemsHaveNoId' | 'FungibleItemsDontHaveData' | 'FungibleDisallowsNesting' | 'SettingPropertiesNotAllowed' | 'SettingApprovalForAllNotAllowed';3659 }3668 }366036693661 /** @name PalletRefungibleItemData (431) */3670 /** @name PalletRefungibleItemData (431) */tests/src/interfaces/unique/definitions.tsdiffbeforeafterboth175 [collectionParam, tokenParam], 175 [collectionParam, tokenParam], 176 'Option<u128>',176 'Option<u128>',177 ),177 ),178 isApprovedForAll: fun(179 'Tells whether an operator is approved by a given owner.', 180 [collectionParam, crossAccountParam('owner'), crossAccountParam('operator')], 181 'Option<bool>',182 ),178 },183 },179};184};180185tests/src/util/playgrounds/unique.tsdiffbeforeafterboth1414 return null;1414 return null;1415 }1415 }14161417 /**1418 * Tells whether an operator is approved by a given owner.1419 * @param collectionId ID of collection1420 * @param owner owner address1421 * @param operator operator addrees1422 * @returns true if operator is enabled1423 */1424 async isApprovedForAll(collectionId: number, owner: ICrossAccountId, operator: ICrossAccountId): Promise<boolean> {1425 return (await this.helper.callRpc('api.rpc.unique.isApprovedForAll', [collectionId, owner, operator])).toJSON();1426 }14271428 /** Sets or unsets the approval of a given operator.1429 * An operator is allowed to transfer all tokens of the sender on their behalf.1430 * @param operator Operator1431 * @param approved Is operator enabled or disabled1432 * @returns ```true``` if extrinsic success, otherwise ```false```1433 */1434 async setApprovalForAll(signer: TSigner, collectionId: number, operator: ICrossAccountId, approved: boolean): Promise<boolean> {1435 const result = await this.helper.executeExtrinsic(1436 signer,1437 'api.tx.unique.setApprovalForAll', [collectionId, operator, approved],1438 true,1439 );1440 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'ApprovedForAll');1441 }1416}1442}1417144314181444