difftreelog
feat add ApproveForAll to Eth and Sub
in: master
39 files changed
client/rpc/src/lib.rsdiffbeforeafterboth--- a/client/rpc/src/lib.rs
+++ b/client/rpc/src/lib.rs
@@ -246,6 +246,16 @@
token_id: TokenId,
at: Option<BlockHash>,
) -> Result<Option<String>>;
+
+ /// Get whether an operator is approved by a given owner.
+ #[method(name = "unique_isApprovedForAll")]
+ fn is_approved_for_all(
+ &self,
+ collection: CollectionId,
+ owner: CrossAccountId,
+ operator: CrossAccountId,
+ at: Option<BlockHash>,
+ ) -> Result<bool>;
}
mod app_promotion_unique_rpc {
@@ -569,6 +579,7 @@
pass_method!(effective_collection_limits(collection_id: CollectionId) -> Option<CollectionLimits>, unique_api);
pass_method!(total_pieces(collection_id: CollectionId, token_id: TokenId) -> Option<String> => |o| o.map(|number| number.to_string()) , unique_api);
pass_method!(token_owners(collection: CollectionId, token: TokenId) -> Vec<CrossAccountId>, unique_api);
+ pass_method!(is_approved_for_all(collection: CollectionId, owner: CrossAccountId, operator: CrossAccountId) -> bool, unique_api);
}
impl<C, Block, BlockNumber, CrossAccountId, AccountId>
pallets/common/src/lib.rsdiffbeforeafterboth--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -472,6 +472,18 @@
u128,
),
+ /// Amount pieces of token owned by `sender` was approved for `spender`.
+ ApprovedForAll(
+ /// Id of collection to which item is belong.
+ CollectionId,
+ /// Owner of a wallet.
+ T::CrossAccountId,
+ /// Id for which operator status was granted or rewoked.
+ T::CrossAccountId,
+ /// Is operator status was granted or rewoked.
+ bool,
+ ),
+
/// The colletion property has been added or edited.
CollectionPropertySet(
/// Id of collection to which property has been set.
@@ -1521,6 +1533,9 @@
/// The price of retrieving token owner
fn token_owner() -> Weight;
+
+ /// The price of setting approval for all
+ fn set_approval_for_all() -> Weight;
}
/// Weight info extension trait for refungible pallet.
@@ -1828,6 +1843,20 @@
/// Get extension for RFT collection.
fn refungible_extensions(&self) -> Option<&dyn RefungibleExtensions<T>>;
+
+ /// An operator is allowed to transfer all tokens of the sender on their behalf.
+ /// * `owner` - Token owner
+ /// * `operator` - Operator
+ /// * `approve` - Is operator enabled or disabled
+ fn set_approval_for_all(
+ &self,
+ owner: T::CrossAccountId,
+ operator: T::CrossAccountId,
+ approve: bool,
+ ) -> DispatchResultWithPostInfo;
+
+ /// Tells whether an operator is approved by a given owner.
+ fn is_approved_for_all(&self, owner: T::CrossAccountId, operator: T::CrossAccountId) -> bool;
}
/// Extension for RFT collection.
pallets/fungible/src/common.rsdiffbeforeafterboth--- a/pallets/fungible/src/common.rs
+++ b/pallets/fungible/src/common.rs
@@ -107,6 +107,10 @@
fn token_owner() -> Weight {
Weight::zero()
}
+
+ fn set_approval_for_all() -> Weight {
+ Weight::zero()
+ }
}
/// Implementation of `CommonCollectionOperations` for `FungibleHandle`. It wraps FungibleHandle Pallete
@@ -424,4 +428,17 @@
}
<TotalSupply<T>>::try_get(self.id).ok()
}
+
+ fn set_approval_for_all(
+ &self,
+ _owner: T::CrossAccountId,
+ _operator: T::CrossAccountId,
+ _approve: bool,
+ ) -> DispatchResultWithPostInfo {
+ fail!(<Error<T>>::SettingApprovalForAllNotAllowed)
+ }
+
+ fn is_approved_for_all(&self, _owner: T::CrossAccountId, _operator: T::CrossAccountId) -> bool {
+ false
+ }
}
pallets/fungible/src/lib.rsdiffbeforeafterboth--- a/pallets/fungible/src/lib.rs
+++ b/pallets/fungible/src/lib.rs
@@ -127,6 +127,8 @@
FungibleDisallowsNesting,
/// Setting item properties is not allowed.
SettingPropertiesNotAllowed,
+ /// Setting approval for all is not allowed.
+ SettingApprovalForAllNotAllowed,
}
#[pallet::config]
pallets/nonfungible/src/benchmarking.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/benchmarking.rs
+++ b/pallets/nonfungible/src/benchmarking.rs
@@ -222,4 +222,18 @@
let item = create_max_item(&collection, &owner, owner.clone())?;
}: {collection.token_owner(item)}
+
+ set_approval_for_all {
+ bench_init!{
+ owner: sub; collection: collection(owner);
+ operator: cross_from_sub(owner); owner: cross_sub;
+ };
+ }: {<Pallet<T>>::set_approval_for_all(&collection, &owner, &operator, true)}
+
+ is_approved_for_all {
+ bench_init!{
+ owner: sub; collection: collection(owner);
+ operator: cross_from_sub(owner); owner: cross_sub;
+ };
+ }: {<Pallet<T>>::is_approved_for_all(&collection, &owner, &operator)}
}
pallets/nonfungible/src/common.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/common.rs
+++ b/pallets/nonfungible/src/common.rs
@@ -122,6 +122,10 @@
fn token_owner() -> Weight {
<SelfWeightOf<T>>::token_owner()
}
+
+ fn set_approval_for_all() -> Weight {
+ <SelfWeightOf<T>>::set_approval_for_all()
+ }
}
fn map_create_data<T: Config>(
@@ -512,4 +516,20 @@
None
}
}
+
+ fn set_approval_for_all(
+ &self,
+ owner: T::CrossAccountId,
+ operator: T::CrossAccountId,
+ approve: bool,
+ ) -> DispatchResultWithPostInfo {
+ with_weight(
+ <Pallet<T>>::set_approval_for_all(self, &owner, &operator, approve),
+ <CommonWeights<T>>::set_approval_for_all(),
+ )
+ }
+
+ fn is_approved_for_all(&self, owner: T::CrossAccountId, operator: T::CrossAccountId) -> bool {
+ <Pallet<T>>::is_approved_for_all(self, &owner, &operator)
+ }
}
pallets/nonfungible/src/erc.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -469,15 +469,23 @@
Ok(())
}
- /// @dev Not implemented
+ /// @notice Sets or unsets the approval of a given operator.
+ /// An operator is allowed to transfer all tokens of the sender on their behalf.
+ /// @param operator Operator
+ /// @param approved Is operator enabled or disabled
+ #[weight(<SelfWeightOf<T>>::set_approval_for_all())]
fn set_approval_for_all(
&mut self,
- _caller: caller,
- _operator: address,
- _approved: bool,
+ caller: caller,
+ operator: address,
+ approved: bool,
) -> Result<void> {
- // TODO: Not implemetable
- Err("not implemented".into())
+ let caller = T::CrossAccountId::from_eth(caller);
+ let operator = T::CrossAccountId::from_eth(operator);
+
+ <Pallet<T>>::set_approval_for_all(self, &caller, &operator, approved)
+ .map_err(dispatch_to_evm::<T>)?;
+ Ok(())
}
/// @dev Not implemented
@@ -486,10 +494,13 @@
Err("not implemented".into())
}
- /// @dev Not implemented
- fn is_approved_for_all(&self, _owner: address, _operator: address) -> Result<address> {
- // TODO: Not implemetable
- Err("not implemented".into())
+ /// @notice Tells whether an operator is approved by a given owner.
+ #[weight(<SelfWeightOf<T>>::is_approved_for_all())]
+ fn is_approved_for_all(&self, owner: address, operator: address) -> Result<bool> {
+ let owner = T::CrossAccountId::from_eth(owner);
+ let operator = T::CrossAccountId::from_eth(operator);
+
+ Ok(<Pallet<T>>::is_approved_for_all(self, &owner, &operator))
}
/// @notice Returns collection helper contract address
pallets/nonfungible/src/lib.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/lib.rs
+++ b/pallets/nonfungible/src/lib.rs
@@ -272,6 +272,18 @@
QueryKind = OptionQuery,
>;
+ /// Operator set by a wallet owner that could perform certain transactions on all tokens in the wallet.
+ #[pallet::storage]
+ pub type WalletOperator<T: Config> = StorageNMap<
+ Key = (
+ Key<Twox64Concat, CollectionId>,
+ Key<Blake2_128Concat, T::CrossAccountId>,
+ Key<Blake2_128Concat, T::CrossAccountId>,
+ ),
+ Value = bool,
+ QueryKind = OptionQuery,
+ >;
+
/// Upgrade from the old schema to properties.
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
@@ -438,6 +450,7 @@
<TokensBurnt<T>>::remove(id);
let _ = <Allowance<T>>::clear_prefix((id,), u32::MAX, None);
let _ = <AccountBalance<T>>::clear_prefix((id,), u32::MAX, None);
+ let _ = <WalletOperator<T>>::clear_prefix((id,), u32::MAX, None);
Ok(())
}
@@ -1193,6 +1206,9 @@
if <Allowance<T>>::get((collection.id, token)).as_ref() == Some(spender) {
return Ok(());
}
+ if <WalletOperator<T>>::get((collection.id, from, spender)) == Some(true) {
+ return Ok(());
+ }
ensure!(
collection.ignores_allowance(spender),
<CommonError<T>>::ApprovedValueTooLow
@@ -1326,4 +1342,52 @@
) -> DispatchResult {
Self::create_multiple_items(collection, sender, vec![data], nesting_budget)
}
+
+ /// Sets or unsets the approval of a given operator.
+ ///
+ /// An operator is allowed to transfer all token pieces of the sender on their behalf.
+ /// - `owner`: Token owner
+ /// - `operator`: Operator
+ /// - `approve`: Is operator enabled or disabled
+ pub fn set_approval_for_all(
+ collection: &NonfungibleHandle<T>,
+ owner: &T::CrossAccountId,
+ operator: &T::CrossAccountId,
+ approve: bool,
+ ) -> DispatchResult {
+ if collection.permissions.access() == AccessMode::AllowList {
+ collection.check_allowlist(owner)?;
+ collection.check_allowlist(operator)?;
+ }
+
+ <PalletCommon<T>>::ensure_correct_receiver(operator)?;
+
+ // =========
+
+ <WalletOperator<T>>::insert((collection.id, owner, operator), approve);
+ <PalletEvm<T>>::deposit_log(
+ ERC721Events::ApprovalForAll {
+ owner: *owner.as_eth(),
+ operator: *operator.as_eth(),
+ approved: approve,
+ }
+ .to_log(collection_id_to_address(collection.id)),
+ );
+ <PalletCommon<T>>::deposit_event(CommonEvent::ApprovedForAll(
+ collection.id,
+ owner.clone(),
+ operator.clone(),
+ approve,
+ ));
+ Ok(())
+ }
+
+ /// Tells whether an operator is approved by a given owner.
+ pub fn is_approved_for_all(
+ collection: &NonfungibleHandle<T>,
+ owner: &T::CrossAccountId,
+ operator: &T::CrossAccountId,
+ ) -> bool {
+ <WalletOperator<T>>::get((collection.id, owner, operator)).unwrap_or(false)
+ }
}
pallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterbothbinary blob — no preview
pallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth--- a/pallets/nonfungible/src/stubs/UniqueNFT.sol
+++ b/pallets/nonfungible/src/stubs/UniqueNFT.sol
@@ -1020,7 +1020,10 @@
dummy = 0;
}
- /// @dev Not implemented
+ /// @notice Sets or unsets the approval of a given operator.
+ /// An operator is allowed to transfer all tokens of the sender on their behalf.
+ /// @param operator Operator
+ /// @param approved Is operator enabled or disabled
/// @dev EVM selector for this function is: 0xa22cb465,
/// or in textual repr: setApprovalForAll(address,bool)
function setApprovalForAll(address operator, bool approved) public {
@@ -1040,15 +1043,15 @@
return 0x0000000000000000000000000000000000000000;
}
- /// @dev Not implemented
+ /// @notice Tells whether an operator is approved by a given owner.
/// @dev EVM selector for this function is: 0xe985e9c5,
/// or in textual repr: isApprovedForAll(address,address)
- function isApprovedForAll(address owner, address operator) public view returns (address) {
+ function isApprovedForAll(address owner, address operator) public view returns (bool) {
require(false, stub_error);
owner;
operator;
dummy;
- return 0x0000000000000000000000000000000000000000;
+ return false;
}
/// @notice Returns collection helper contract address
pallets/nonfungible/src/weights.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/weights.rs
+++ b/pallets/nonfungible/src/weights.rs
@@ -26,6 +26,7 @@
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)]
#![allow(unused_imports)]
+#![allow(missing_docs)]
#![allow(clippy::unnecessary_cast)]
use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
@@ -47,6 +48,8 @@
fn set_token_properties(b: u32, ) -> Weight;
fn delete_token_properties(b: u32, ) -> Weight;
fn token_owner() -> Weight;
+ fn set_approval_for_all() -> Weight;
+ fn is_approved_for_all() -> Weight;
}
/// Weights for pallet_nonfungible using the Substrate node and recommended hardware.
@@ -195,6 +198,16 @@
Weight::from_ref_time(4_366_000)
.saturating_add(T::DbWeight::get().reads(1 as u64))
}
+ // Storage: Nonfungible WalletOperator (r:0 w:1)
+ fn set_approval_for_all() -> Weight {
+ Weight::from_ref_time(16_231_000 as u64)
+ .saturating_add(T::DbWeight::get().writes(1 as u64))
+ }
+ // Storage: Nonfungible WalletOperator (r:1 w:0)
+ fn is_approved_for_all() -> Weight {
+ Weight::from_ref_time(6_161_000 as u64)
+ .saturating_add(T::DbWeight::get().reads(1 as u64))
+ }
}
// For backwards compatibility and tests
@@ -342,4 +355,14 @@
Weight::from_ref_time(4_366_000)
.saturating_add(RocksDbWeight::get().reads(1 as u64))
}
+ // Storage: Nonfungible WalletOperator (r:0 w:1)
+ fn set_approval_for_all() -> Weight {
+ Weight::from_ref_time(16_231_000 as u64)
+ .saturating_add(RocksDbWeight::get().writes(1 as u64))
+ }
+ // Storage: Nonfungible WalletOperator (r:1 w:0)
+ fn is_approved_for_all() -> Weight {
+ Weight::from_ref_time(6_161_000 as u64)
+ .saturating_add(RocksDbWeight::get().reads(1 as u64))
+ }
}
pallets/refungible/src/benchmarking.rsdiffbeforeafterboth--- a/pallets/refungible/src/benchmarking.rs
+++ b/pallets/refungible/src/benchmarking.rs
@@ -290,4 +290,18 @@
};
let item = create_max_item(&collection, &sender, [(owner.clone(), 100)])?;
}: {<Pallet<T>>::token_owner(collection.id, item)}
+
+ set_approval_for_all {
+ bench_init!{
+ owner: sub; collection: collection(owner);
+ operator: cross_from_sub(owner); owner: cross_sub;
+ };
+ }: {<Pallet<T>>::set_approval_for_all(&collection, &owner, &operator, true)}
+
+ is_approved_for_all {
+ bench_init!{
+ owner: sub; collection: collection(owner);
+ operator: cross_from_sub(owner); owner: cross_sub;
+ };
+ }: {<Pallet<T>>::is_approved_for_all(&collection, &owner, &operator)}
}
pallets/refungible/src/common.rsdiffbeforeafterboth--- a/pallets/refungible/src/common.rs
+++ b/pallets/refungible/src/common.rs
@@ -152,6 +152,10 @@
fn token_owner() -> Weight {
<SelfWeightOf<T>>::token_owner()
}
+
+ fn set_approval_for_all() -> Weight {
+ <SelfWeightOf<T>>::set_approval_for_all()
+ }
}
fn map_create_data<T: Config>(
@@ -516,6 +520,22 @@
fn total_pieces(&self, token: TokenId) -> Option<u128> {
<Pallet<T>>::total_pieces(self.id, token)
}
+
+ fn set_approval_for_all(
+ &self,
+ owner: T::CrossAccountId,
+ operator: T::CrossAccountId,
+ approve: bool,
+ ) -> DispatchResultWithPostInfo {
+ with_weight(
+ <Pallet<T>>::set_approval_for_all(self, &owner, &operator, approve),
+ <CommonWeights<T>>::set_approval_for_all(),
+ )
+ }
+
+ fn is_approved_for_all(&self, owner: T::CrossAccountId, operator: T::CrossAccountId) -> bool {
+ <Pallet<T>>::is_approved_for_all(self, &owner, &operator)
+ }
}
impl<T: Config> RefungibleExtensions<T> for RefungibleHandle<T> {
pallets/refungible/src/erc.rsdiffbeforeafterboth--- a/pallets/refungible/src/erc.rs
+++ b/pallets/refungible/src/erc.rs
@@ -461,15 +461,23 @@
Err("not implemented".into())
}
- /// @dev Not implemented
+ /// @notice Sets or unsets the approval of a given operator.
+ /// An operator is allowed to transfer all tokens of the sender on their behalf.
+ /// @param operator Operator
+ /// @param approved Is operator enabled or disabled
+ #[weight(<SelfWeightOf<T>>::set_approval_for_all())]
fn set_approval_for_all(
&mut self,
- _caller: caller,
- _operator: address,
- _approved: bool,
+ caller: caller,
+ operator: address,
+ approved: bool,
) -> Result<void> {
- // TODO: Not implemetable
- Err("not implemented".into())
+ let caller = T::CrossAccountId::from_eth(caller);
+ let operator = T::CrossAccountId::from_eth(operator);
+
+ <Pallet<T>>::set_approval_for_all(self, &caller, &operator, approved)
+ .map_err(dispatch_to_evm::<T>)?;
+ Ok(())
}
/// @dev Not implemented
@@ -478,10 +486,13 @@
Err("not implemented".into())
}
- /// @dev Not implemented
- fn is_approved_for_all(&self, _owner: address, _operator: address) -> Result<address> {
- // TODO: Not implemetable
- Err("not implemented".into())
+ /// @notice Tells whether an operator is approved by a given owner.
+ #[weight(<SelfWeightOf<T>>::is_approved_for_all())]
+ fn is_approved_for_all(&self, owner: address, operator: address) -> Result<bool> {
+ let owner = T::CrossAccountId::from_eth(owner);
+ let operator = T::CrossAccountId::from_eth(operator);
+
+ Ok(<Pallet<T>>::is_approved_for_all(self, &owner, &operator))
}
/// @notice Returns collection helper contract address
pallets/refungible/src/lib.rsdiffbeforeafterboth--- a/pallets/refungible/src/lib.rs
+++ b/pallets/refungible/src/lib.rs
@@ -273,6 +273,18 @@
QueryKind = ValueQuery,
>;
+ /// Operator set by a wallet owner that could perform certain transactions on all tokens in the wallet.
+ #[pallet::storage]
+ pub type WalletOperator<T: Config> = StorageNMap<
+ Key = (
+ Key<Twox64Concat, CollectionId>,
+ Key<Blake2_128Concat, T::CrossAccountId>,
+ Key<Blake2_128Concat, T::CrossAccountId>,
+ ),
+ Value = bool,
+ QueryKind = OptionQuery,
+ >;
+
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
fn on_runtime_upgrade() -> Weight {
@@ -1161,6 +1173,12 @@
}
let allowance =
<Allowance<T>>::get((collection.id, token, from, &spender)).checked_sub(amount);
+
+ // Allowance if any would be reduced if spender is also wallet operator
+ if <WalletOperator<T>>::get((collection.id, from, spender)) == Some(true) {
+ return Ok(allowance);
+ }
+
if allowance.is_none() {
ensure!(
collection.ignores_allowance(spender),
@@ -1387,4 +1405,52 @@
Some(res)
}
}
+
+ /// Sets or unsets the approval of a given operator.
+ ///
+ /// An operator is allowed to transfer all tokens of the sender on their behalf.
+ /// - `owner`: Token owner
+ /// - `operator`: Operator
+ /// - `approve`: Is operator enabled or disabled
+ pub fn set_approval_for_all(
+ collection: &RefungibleHandle<T>,
+ owner: &T::CrossAccountId,
+ operator: &T::CrossAccountId,
+ approve: bool,
+ ) -> DispatchResult {
+ if collection.permissions.access() == AccessMode::AllowList {
+ collection.check_allowlist(owner)?;
+ collection.check_allowlist(operator)?;
+ }
+
+ <PalletCommon<T>>::ensure_correct_receiver(operator)?;
+
+ // =========
+
+ <WalletOperator<T>>::insert((collection.id, owner, operator), approve);
+ <PalletEvm<T>>::deposit_log(
+ ERC721Events::ApprovalForAll {
+ owner: *owner.as_eth(),
+ operator: *operator.as_eth(),
+ approved: approve,
+ }
+ .to_log(collection_id_to_address(collection.id)),
+ );
+ <PalletCommon<T>>::deposit_event(CommonEvent::ApprovedForAll(
+ collection.id,
+ owner.clone(),
+ operator.clone(),
+ approve,
+ ));
+ Ok(())
+ }
+
+ /// Tells whether an operator is approved by a given owner.
+ pub fn is_approved_for_all(
+ collection: &RefungibleHandle<T>,
+ owner: &T::CrossAccountId,
+ operator: &T::CrossAccountId,
+ ) -> bool {
+ <WalletOperator<T>>::get((collection.id, owner, operator)).unwrap_or(false)
+ }
}
pallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth--- a/pallets/refungible/src/stubs/UniqueRefungible.sol
+++ b/pallets/refungible/src/stubs/UniqueRefungible.sol
@@ -1017,7 +1017,10 @@
dummy = 0;
}
- /// @dev Not implemented
+ /// @notice Sets or unsets the approval of a given operator.
+ /// An operator is allowed to transfer all tokens of the sender on their behalf.
+ /// @param operator Operator
+ /// @param approved Is operator enabled or disabled
/// @dev EVM selector for this function is: 0xa22cb465,
/// or in textual repr: setApprovalForAll(address,bool)
function setApprovalForAll(address operator, bool approved) public {
@@ -1037,15 +1040,15 @@
return 0x0000000000000000000000000000000000000000;
}
- /// @dev Not implemented
+ /// @notice Tells whether an operator is approved by a given owner.
/// @dev EVM selector for this function is: 0xe985e9c5,
/// or in textual repr: isApprovedForAll(address,address)
- function isApprovedForAll(address owner, address operator) public view returns (address) {
+ function isApprovedForAll(address owner, address operator) public view returns (bool) {
require(false, stub_error);
owner;
operator;
dummy;
- return 0x0000000000000000000000000000000000000000;
+ return false;
}
/// @notice Returns collection helper contract address
pallets/refungible/src/weights.rsdiffbeforeafterboth--- a/pallets/refungible/src/weights.rs
+++ b/pallets/refungible/src/weights.rs
@@ -3,7 +3,7 @@
//! Autogenerated weights for pallet_refungible
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2022-08-15, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2022-11-25, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024
// Executed Command:
@@ -26,6 +26,7 @@
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)]
#![allow(unused_imports)]
+#![allow(missing_docs)]
#![allow(clippy::unnecessary_cast)]
use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
@@ -54,6 +55,8 @@
fn delete_token_properties(b: u32, ) -> Weight;
fn repartition_item() -> Weight;
fn token_owner() -> Weight;
+ fn set_approval_for_all() -> Weight;
+ fn is_approved_for_all() -> Weight;
}
/// Weights for pallet_refungible using the Substrate node and recommended hardware.
@@ -259,6 +262,16 @@
Weight::from_ref_time(9_431_000)
.saturating_add(T::DbWeight::get().reads(2 as u64))
}
+ // Storage: Refungible WalletOperator (r:0 w:1)
+ fn set_approval_for_all() -> Weight {
+ Weight::from_ref_time(16_150_000 as u64)
+ .saturating_add(T::DbWeight::get().writes(1 as u64))
+ }
+ // Storage: Refungible WalletOperator (r:1 w:0)
+ fn is_approved_for_all() -> Weight {
+ Weight::from_ref_time(5_901_000 as u64)
+ .saturating_add(T::DbWeight::get().reads(1 as u64))
+ }
}
// For backwards compatibility and tests
@@ -463,4 +476,14 @@
Weight::from_ref_time(9_431_000)
.saturating_add(RocksDbWeight::get().reads(2 as u64))
}
+ // Storage: Refungible WalletOperator (r:0 w:1)
+ fn set_approval_for_all() -> Weight {
+ Weight::from_ref_time(16_150_000 as u64)
+ .saturating_add(RocksDbWeight::get().writes(1 as u64))
+ }
+ // Storage: Refungible WalletOperator (r:1 w:0)
+ fn is_approved_for_all() -> Weight {
+ Weight::from_ref_time(5_901_000 as u64)
+ .saturating_add(RocksDbWeight::get().reads(1 as u64))
+ }
}
pallets/unique/src/lib.rsdiffbeforeafterboth--- a/pallets/unique/src/lib.rs
+++ b/pallets/unique/src/lib.rs
@@ -1126,6 +1126,28 @@
}
})
}
+
+ /// Sets or unsets the approval of a given operator.
+ ///
+ /// An operator is allowed to transfer all tokens of the sender on their behalf.
+ ///
+ /// # Arguments
+ ///
+ /// * `owner`: Token owner
+ /// * `operator`: Operator
+ /// * `approve`: Is operator enabled or disabled
+ #[weight = T::CommonWeightInfo::set_approval_for_all()]
+ pub fn set_approval_for_all(
+ origin,
+ collection_id: CollectionId,
+ operator: T::CrossAccountId,
+ approve: bool,
+ ) -> DispatchResultWithPostInfo {
+ let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
+ dispatch_tx::<T, _>(collection_id, |d| {
+ d.set_approval_for_all(sender, operator, approve)
+ })
+ }
}
}
primitives/rpc/src/lib.rsdiffbeforeafterboth--- a/primitives/rpc/src/lib.rs
+++ b/primitives/rpc/src/lib.rs
@@ -132,5 +132,8 @@
fn total_pieces(collection_id: CollectionId, token_id: TokenId) -> Result<Option<u128>>;
fn token_owners(collection: CollectionId, token: TokenId) -> Result<Vec<CrossAccountId>>;
+
+ /// Get whether an operator is approved by a given owner.
+ fn is_approved_for_all(collection: CollectionId, owner: CrossAccountId, operator: CrossAccountId) -> Result<bool>;
}
}
runtime/common/runtime_apis.rsdiffbeforeafterboth--- a/runtime/common/runtime_apis.rs
+++ b/runtime/common/runtime_apis.rs
@@ -187,6 +187,10 @@
fn total_pieces(collection: CollectionId, token_id: TokenId) -> Result<Option<u128>, DispatchError> {
dispatch_unique_runtime!(collection.total_pieces(token_id))
}
+
+ fn is_approved_for_all(collection: CollectionId, owner: CrossAccountId, operator: CrossAccountId) -> Result<bool, DispatchError> {
+ dispatch_unique_runtime!(collection.is_approved_for_all(owner, operator))
+ }
}
impl app_promotion_rpc::AppPromotionApi<Block, BlockNumber, CrossAccountId, AccountId> for Runtime {
runtime/common/weights.rsdiffbeforeafterboth--- a/runtime/common/weights.rs
+++ b/runtime/common/weights.rs
@@ -120,6 +120,10 @@
fn token_owner() -> Weight {
max_weight_of!(token_owner())
}
+
+ fn set_approval_for_all() -> Weight {
+ max_weight_of!(set_approval_for_all())
+ }
}
#[cfg(feature = "refungible")]
tests/src/approve.test.tsdiffbeforeafterboth--- a/tests/src/approve.test.ts
+++ b/tests/src/approve.test.ts
@@ -603,3 +603,40 @@
await expect(approveTx()).to.be.rejected;
});
});
+
+describe('Normal user can approve other users to be wallet operator:', () => {
+ let alice: IKeyringPair;
+ let bob: IKeyringPair;
+
+ before(async () => {
+ await usingPlaygrounds(async (helper, privateKey) => {
+ const donor = await privateKey({filename: __filename});
+ [alice, bob] = await helper.arrange.createAccounts([100n, 100n], donor);
+ });
+ });
+
+ itSub('[nft] Enable and disable approval', async ({helper}) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});
+ const checkBeforeApprovalTx = () => helper.nft.isApprovedForAll(collectionId, {Substrate: alice.address}, {Substrate: bob.address});
+ expect(await checkBeforeApprovalTx()).to.be.false;
+ await helper.nft.setApprovalForAll(alice, collectionId, {Substrate: bob.address}, true);
+ const checkAfterApprovalTx = () => helper.nft.isApprovedForAll(collectionId, {Substrate: alice.address}, {Substrate: bob.address});
+ expect(await checkAfterApprovalTx()).to.be.true;
+ await helper.nft.setApprovalForAll(alice, collectionId, {Substrate: bob.address}, false);
+ const checkAfterDisapprovalTx = () => helper.nft.isApprovedForAll(collectionId, {Substrate: alice.address}, {Substrate: bob.address});
+ expect(await checkAfterDisapprovalTx()).to.be.false;
+ });
+
+ itSub.ifWithPallets('[rft] Enable and disable approval', [Pallets.ReFungible], async ({helper}) => {
+ const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const checkBeforeApprovalTx = () => helper.rft.isApprovedForAll(collectionId, {Substrate: alice.address}, {Substrate: bob.address});
+ expect(await checkBeforeApprovalTx()).to.be.false;
+ await helper.rft.setApprovalForAll(alice, collectionId, {Substrate: bob.address}, true);
+ const checkAfterApprovalTx = () => helper.rft.isApprovedForAll(collectionId, {Substrate: alice.address}, {Substrate: bob.address});
+ expect(await checkAfterApprovalTx()).to.be.true;
+ await helper.rft.setApprovalForAll(alice, collectionId, {Substrate: bob.address}, false);
+ const checkAfterDisapprovalTx = () => helper.rft.isApprovedForAll(collectionId, {Substrate: alice.address}, {Substrate: bob.address});
+ expect(await checkAfterDisapprovalTx()).to.be.false;
+ });
+});
tests/src/eth/abi/nonFungible.jsondiffbeforeafterboth--- a/tests/src/eth/abi/nonFungible.json
+++ b/tests/src/eth/abi/nonFungible.json
@@ -384,7 +384,7 @@
{ "internalType": "address", "name": "operator", "type": "address" }
],
"name": "isApprovedForAll",
- "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
+ "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
tests/src/eth/abi/reFungible.jsondiffbeforeafterboth--- a/tests/src/eth/abi/reFungible.json
+++ b/tests/src/eth/abi/reFungible.json
@@ -366,7 +366,7 @@
{ "internalType": "address", "name": "operator", "type": "address" }
],
"name": "isApprovedForAll",
- "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
+ "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
tests/src/eth/api/UniqueNFT.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueNFT.sol
+++ b/tests/src/eth/api/UniqueNFT.sol
@@ -671,7 +671,10 @@
/// or in textual repr: approve(address,uint256)
function approve(address approved, uint256 tokenId) external;
- /// @dev Not implemented
+ /// @notice Sets or unsets the approval of a given operator.
+ /// An operator is allowed to transfer all tokens of the sender on their behalf.
+ /// @param operator Operator
+ /// @param approved Is operator enabled or disabled
/// @dev EVM selector for this function is: 0xa22cb465,
/// or in textual repr: setApprovalForAll(address,bool)
function setApprovalForAll(address operator, bool approved) external;
@@ -681,10 +684,10 @@
/// or in textual repr: getApproved(uint256)
function getApproved(uint256 tokenId) external view returns (address);
- /// @dev Not implemented
+ /// @notice Tells whether an operator is approved by a given owner.
/// @dev EVM selector for this function is: 0xe985e9c5,
/// or in textual repr: isApprovedForAll(address,address)
- function isApprovedForAll(address owner, address operator) external view returns (address);
+ function isApprovedForAll(address owner, address operator) external view returns (bool);
/// @notice Returns collection helper contract address
/// @dev EVM selector for this function is: 0x1896cce6,
tests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueRefungible.sol
+++ b/tests/src/eth/api/UniqueRefungible.sol
@@ -668,7 +668,10 @@
/// or in textual repr: approve(address,uint256)
function approve(address approved, uint256 tokenId) external;
- /// @dev Not implemented
+ /// @notice Sets or unsets the approval of a given operator.
+ /// An operator is allowed to transfer all tokens of the sender on their behalf.
+ /// @param operator Operator
+ /// @param approved Is operator enabled or disabled
/// @dev EVM selector for this function is: 0xa22cb465,
/// or in textual repr: setApprovalForAll(address,bool)
function setApprovalForAll(address operator, bool approved) external;
@@ -678,10 +681,10 @@
/// or in textual repr: getApproved(uint256)
function getApproved(uint256 tokenId) external view returns (address);
- /// @dev Not implemented
+ /// @notice Tells whether an operator is approved by a given owner.
/// @dev EVM selector for this function is: 0xe985e9c5,
/// or in textual repr: isApprovedForAll(address,address)
- function isApprovedForAll(address owner, address operator) external view returns (address);
+ function isApprovedForAll(address owner, address operator) external view returns (bool);
/// @notice Returns collection helper contract address
/// @dev EVM selector for this function is: 0x1896cce6,
tests/src/eth/nonFungible.test.tsdiffbeforeafterboth--- a/tests/src/eth/nonFungible.test.ts
+++ b/tests/src/eth/nonFungible.test.ts
@@ -249,6 +249,114 @@
}
});
+ itEth('Can perform setApprovalForAll()', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const operator = helper.eth.createAccount();
+
+ const collection = await helper.nft.mintCollection(minter, {});
+
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
+
+ const approvedBefore = await contract.methods.isApprovedForAll(owner, operator).call();
+ expect(approvedBefore).to.be.equal(false);
+
+ {
+ const result = await contract.methods.setApprovalForAll(operator, true).send({from: owner});
+
+ expect(result.events.ApprovalForAll).to.be.like({
+ address: collectionAddress,
+ event: 'ApprovalForAll',
+ returnValues: {
+ owner,
+ operator,
+ approved: true,
+ },
+ });
+
+ const approvedAfter = await contract.methods.isApprovedForAll(owner, operator).call();
+ expect(approvedAfter).to.be.equal(true);
+ }
+
+ {
+ const result = await contract.methods.setApprovalForAll(operator, false).send({from: owner});
+
+ expect(result.events.ApprovalForAll).to.be.like({
+ address: collectionAddress,
+ event: 'ApprovalForAll',
+ returnValues: {
+ owner,
+ operator,
+ approved: false,
+ },
+ });
+
+ const approvedAfter = await contract.methods.isApprovedForAll(owner, operator).call();
+ expect(approvedAfter).to.be.equal(false);
+ }
+ });
+
+ itEth('Can perform burn with ApprovalForAll', async ({helper}) => {
+ const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});
+
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const operator = await helper.eth.createAccountWithBalance(donor, 100n);
+
+ const token = await collection.mintToken(minter, {Ethereum: owner});
+
+ const address = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(address, 'nft');
+
+ {
+ await contract.methods.setApprovalForAll(operator, true).send({from: owner});
+ const ownerCross = helper.ethCrossAccount.fromAddress(owner);
+ const result = await contract.methods.burnFromCross(ownerCross, token.tokenId).send({from: operator});
+ const events = result.events.Transfer;
+
+ expect(events).to.be.like({
+ address,
+ event: 'Transfer',
+ returnValues: {
+ from: owner,
+ to: '0x0000000000000000000000000000000000000000',
+ tokenId: token.tokenId.toString(),
+ },
+ });
+ }
+ });
+
+ itEth('Can perform transfer with ApprovalForAll', async ({helper}) => {
+ const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});
+
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const operator = await helper.eth.createAccountWithBalance(donor);
+ const receiver = charlie;
+
+ const token = await collection.mintToken(minter, {Ethereum: owner});
+
+ const address = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(address, 'nft');
+
+ {
+ await contract.methods.setApprovalForAll(operator, true).send({from: owner});
+ const ownerCross = helper.ethCrossAccount.fromAddress(owner);
+ const recieverCross = helper.ethCrossAccount.fromKeyringPair(receiver);
+ const result = await contract.methods.transferFromCross(ownerCross, recieverCross, token.tokenId).send({from: operator});
+ const event = result.events.Transfer;
+ expect(event).to.be.like({
+ address: helper.ethAddress.fromCollectionId(collection.collectionId),
+ event: 'Transfer',
+ returnValues: {
+ from: owner,
+ to: helper.address.substrateToEth(receiver.address),
+ tokenId: token.tokenId.toString(),
+ },
+ });
+ }
+
+ expect(await token.getOwner()).to.be.like({Substrate: receiver.address});
+ });
+
itEth('Can perform burnFromCross()', async ({helper}) => {
const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});
const ownerSub = bob;
@@ -822,3 +930,53 @@
expect(symbol).to.equal('CHANGE');
});
});
+
+describe('Negative tests', () => {
+ let donor: IKeyringPair;
+ let minter: IKeyringPair;
+ let alice: IKeyringPair;
+ let bob: IKeyringPair;
+
+ before(async function() {
+ await usingEthPlaygrounds(async (helper, privateKey) => {
+ donor = await privateKey({filename: __filename});
+ [minter, alice, bob] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);
+ });
+ });
+
+ itEth('[negative] Cant perform burn without approval', async ({helper}) => {
+ const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});
+
+ const owner = bob;
+ const spender = await helper.eth.createAccountWithBalance(donor, 100n);
+
+ const token = await collection.mintToken(minter, {Substrate: owner.address});
+
+ const address = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(address, 'nft');
+
+ {
+ const ownerCross = helper.ethCrossAccount.fromKeyringPair(owner);
+ await expect(contract.methods.burnFromCross(ownerCross, token.tokenId).send({from: spender})).to.be.rejected;
+ }
+ });
+
+ itEth('[negative] Cant perform transfer without approval', async ({helper}) => {
+ const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});
+ const owner = bob;
+ const receiver = alice;
+
+ const spender = await helper.eth.createAccountWithBalance(donor, 100n);
+
+ const token = await collection.mintToken(minter, {Substrate: owner.address});
+
+ const address = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(address, 'nft');
+
+ {
+ const ownerCross = helper.ethCrossAccount.fromKeyringPair(owner);
+ const recieverCross = helper.ethCrossAccount.fromKeyringPair(receiver);
+ await expect(contract.methods.transferFromCross(ownerCross, recieverCross, token.tokenId).send({from: spender})).to.be.rejected;
+ }
+ });
+});
tests/src/eth/reFungible.test.tsdiffbeforeafterboth--- a/tests/src/eth/reFungible.test.ts
+++ b/tests/src/eth/reFungible.test.ts
@@ -169,6 +169,136 @@
}
});
+ itEth('Can perform setApprovalForAll()', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const operator = helper.eth.createAccount();
+
+ const collection = await helper.rft.mintCollection(minter, {});
+
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);
+
+ const approvedBefore = await contract.methods.isApprovedForAll(owner, operator).call();
+ expect(approvedBefore).to.be.equal(false);
+
+ {
+ const result = await contract.methods.setApprovalForAll(operator, true).send({from: owner});
+
+ expect(result.events.ApprovalForAll).to.be.like({
+ address: collectionAddress,
+ event: 'ApprovalForAll',
+ returnValues: {
+ owner,
+ operator,
+ approved: true,
+ },
+ });
+
+ const approvedAfter = await contract.methods.isApprovedForAll(owner, operator).call();
+ expect(approvedAfter).to.be.equal(true);
+ }
+
+ {
+ const result = await contract.methods.setApprovalForAll(operator, false).send({from: owner});
+
+ expect(result.events.ApprovalForAll).to.be.like({
+ address: collectionAddress,
+ event: 'ApprovalForAll',
+ returnValues: {
+ owner,
+ operator,
+ approved: false,
+ },
+ });
+
+ const approvedAfter = await contract.methods.isApprovedForAll(owner, operator).call();
+ expect(approvedAfter).to.be.equal(false);
+ }
+ });
+
+ itEth('Can perform burn with ApprovalForAll', async ({helper}) => {
+ const collection = await helper.rft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});
+
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const operator = await helper.eth.createAccountWithBalance(donor, 100n);
+
+ const token = await collection.mintToken(minter, 100n, {Ethereum: owner});
+
+ const address = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(address, 'rft');
+
+ {
+ await contract.methods.setApprovalForAll(operator, true).send({from: owner});
+ const ownerCross = helper.ethCrossAccount.fromAddress(owner);
+ const result = await contract.methods.burnFromCross(ownerCross, token.tokenId).send({from: operator});
+ const events = result.events.Transfer;
+
+ expect(events).to.be.like({
+ address,
+ event: 'Transfer',
+ returnValues: {
+ from: owner,
+ to: '0x0000000000000000000000000000000000000000',
+ tokenId: token.tokenId.toString(),
+ },
+ });
+ }
+ });
+
+ itEth('Can perform burn with approve and approvalForAll', async ({helper}) => {
+ const collection = await helper.rft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});
+
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const operator = await helper.eth.createAccountWithBalance(donor, 100n);
+
+ const token = await collection.mintToken(minter, 100n, {Ethereum: owner});
+
+ const address = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(address, 'rft');
+
+ const rftToken = helper.ethNativeContract.rftTokenById(token.collectionId, token.tokenId, owner);
+
+ {
+ await rftToken.methods.approve(operator, 15n).send({from: owner});
+ await contract.methods.setApprovalForAll(operator, true).send({from: owner});
+ await rftToken.methods.burnFrom(owner, 10n).send({from: operator});
+ const allowance = await rftToken.methods.allowance(owner, operator).call();
+ expect(allowance).to.be.equal('5');
+ }
+ });
+
+ itEth('Can perform transfer with ApprovalForAll', async ({helper}) => {
+ const collection = await helper.rft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});
+
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const operator = await helper.eth.createAccountWithBalance(donor);
+ const receiver = charlie;
+
+ const token = await collection.mintToken(minter, 100n, {Ethereum: owner});
+
+ const address = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(address, 'rft');
+
+ {
+ await contract.methods.setApprovalForAll(operator, true).send({from: owner});
+ const ownerCross = helper.ethCrossAccount.fromAddress(owner);
+ const recieverCross = helper.ethCrossAccount.fromKeyringPair(receiver);
+ const result = await contract.methods.transferFromCross(ownerCross, recieverCross, token.tokenId).send({from: operator});
+ const event = result.events.Transfer;
+ expect(event).to.be.like({
+ address: helper.ethAddress.fromCollectionId(collection.collectionId),
+ event: 'Transfer',
+ returnValues: {
+ from: owner,
+ to: helper.address.substrateToEth(receiver.address),
+ tokenId: token.tokenId.toString(),
+ },
+ });
+ }
+
+ expect(await token.getTop10Owners()).to.be.like([{Substrate: receiver.address}]);
+ });
+
itEth('Can perform burn()', async ({helper}) => {
const caller = await helper.eth.createAccountWithBalance(donor);
const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'Burny', '6', '6');
@@ -594,3 +724,52 @@
expect(symbol).to.equal('12');
});
});
+
+describe('Negative tests', () => {
+ let donor: IKeyringPair;
+ let minter: IKeyringPair;
+ let alice: IKeyringPair;
+
+ before(async function() {
+ await usingEthPlaygrounds(async (helper, privateKey) => {
+ donor = await privateKey({filename: __filename});
+ [minter, alice] = await helper.arrange.createAccounts([100n, 100n], donor);
+ });
+ });
+
+ itEth('[negative] Cant perform burn without approval', async ({helper}) => {
+ const collection = await helper.rft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});
+
+ const owner = await helper.eth.createAccountWithBalance(donor, 100n);
+ const spender = await helper.eth.createAccountWithBalance(donor, 100n);
+
+ const token = await collection.mintToken(minter, 100n, {Ethereum: owner});
+
+ const address = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(address, 'rft');
+
+ {
+ const ownerCross = helper.ethCrossAccount.fromAddress(owner);
+ await expect(contract.methods.burnFromCross(ownerCross, token.tokenId).send({from: spender})).to.be.rejected;
+ }
+ });
+
+ itEth('[negative] Cant perform transfer without approval', async ({helper}) => {
+ const collection = await helper.rft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});
+ const owner = await helper.eth.createAccountWithBalance(donor, 100n);
+ const receiver = alice;
+
+ const spender = await helper.eth.createAccountWithBalance(donor, 100n);
+
+ const token = await collection.mintToken(minter, 100n, {Ethereum: owner});
+
+ const address = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(address, 'rft');
+
+ {
+ const ownerCross = helper.ethCrossAccount.fromAddress(owner);
+ const recieverCross = helper.ethCrossAccount.fromKeyringPair(receiver);
+ await expect(contract.methods.transferFromCross(ownerCross, recieverCross, token.tokenId).send({from: spender})).to.be.rejected;
+ }
+ });
+});
tests/src/interfaces/augment-api-errors.tsdiffbeforeafterboth--- a/tests/src/interfaces/augment-api-errors.ts
+++ b/tests/src/interfaces/augment-api-errors.ts
@@ -386,6 +386,10 @@
**/
NotFungibleDataUsedToMintFungibleCollectionToken: AugmentedError<ApiType>;
/**
+ * Setting approval for all is not allowed.
+ **/
+ SettingApprovalForAllNotAllowed: AugmentedError<ApiType>;
+ /**
* Setting item properties is not allowed.
**/
SettingPropertiesNotAllowed: AugmentedError<ApiType>;
tests/src/interfaces/augment-api-events.tsdiffbeforeafterboth1// Auto-generated via `yarn polkadot-types-from-chain`, do not edit2/* eslint-disable */34// import type lookup before we augment - in some environments5// this is required to allow for ambient/previous definitions6import '@polkadot/api-base/types/events';78import type { ApiTypes, AugmentedEvent } from '@polkadot/api-base/types';9import type { Bytes, Null, Option, Result, U8aFixed, bool, u128, u32, u64, u8 } from '@polkadot/types-codec';10import type { ITuple } from '@polkadot/types-codec/types';11import type { AccountId32, H160, H256, Weight } from '@polkadot/types/interfaces/runtime';12import type { EthereumLog, EvmCoreErrorExitReason, FrameSupportDispatchDispatchInfo, FrameSupportTokensMiscBalanceStatus, OrmlVestingVestingSchedule, PalletEvmAccountBasicCrossAccountIdRepr, PalletForeignAssetsAssetIds, PalletForeignAssetsModuleAssetMetadata, RmrkTraitsNftAccountIdOrCollectionNftTuple, SpRuntimeDispatchError, XcmV1MultiAsset, XcmV1MultiLocation, XcmV1MultiassetMultiAssets, XcmV2Response, XcmV2TraitsError, XcmV2TraitsOutcome, XcmV2Xcm, XcmVersionedMultiAssets, XcmVersionedMultiLocation } from '@polkadot/types/lookup';1314export type __AugmentedEvent<ApiType extends ApiTypes> = AugmentedEvent<ApiType>;1516declare module '@polkadot/api-base/types/events' {17 interface AugmentedEvents<ApiType extends ApiTypes> {18 appPromotion: {19 /**20 * The admin was set21 * 22 * # Arguments23 * * AccountId: account address of the admin24 **/25 SetAdmin: AugmentedEvent<ApiType, [AccountId32]>;26 /**27 * Staking was performed28 * 29 * # Arguments30 * * AccountId: account of the staker31 * * Balance : staking amount32 **/33 Stake: AugmentedEvent<ApiType, [AccountId32, u128]>;34 /**35 * Staking recalculation was performed36 * 37 * # Arguments38 * * AccountId: account of the staker.39 * * Balance : recalculation base40 * * Balance : total income41 **/42 StakingRecalculation: AugmentedEvent<ApiType, [AccountId32, u128, u128]>;43 /**44 * Unstaking was performed45 * 46 * # Arguments47 * * AccountId: account of the staker48 * * Balance : unstaking amount49 **/50 Unstake: AugmentedEvent<ApiType, [AccountId32, u128]>;51 /**52 * Generic event53 **/54 [key: string]: AugmentedEvent<ApiType>;55 };56 balances: {57 /**58 * A balance was set by root.59 **/60 BalanceSet: AugmentedEvent<ApiType, [who: AccountId32, free: u128, reserved: u128], { who: AccountId32, free: u128, reserved: u128 }>;61 /**62 * Some amount was deposited (e.g. for transaction fees).63 **/64 Deposit: AugmentedEvent<ApiType, [who: AccountId32, amount: u128], { who: AccountId32, amount: u128 }>;65 /**66 * An account was removed whose balance was non-zero but below ExistentialDeposit,67 * resulting in an outright loss.68 **/69 DustLost: AugmentedEvent<ApiType, [account: AccountId32, amount: u128], { account: AccountId32, amount: u128 }>;70 /**71 * An account was created with some free balance.72 **/73 Endowed: AugmentedEvent<ApiType, [account: AccountId32, freeBalance: u128], { account: AccountId32, freeBalance: u128 }>;74 /**75 * Some balance was reserved (moved from free to reserved).76 **/77 Reserved: AugmentedEvent<ApiType, [who: AccountId32, amount: u128], { who: AccountId32, amount: u128 }>;78 /**79 * Some balance was moved from the reserve of the first account to the second account.80 * Final argument indicates the destination balance type.81 **/82 ReserveRepatriated: AugmentedEvent<ApiType, [from: AccountId32, to: AccountId32, amount: u128, destinationStatus: FrameSupportTokensMiscBalanceStatus], { from: AccountId32, to: AccountId32, amount: u128, destinationStatus: FrameSupportTokensMiscBalanceStatus }>;83 /**84 * Some amount was removed from the account (e.g. for misbehavior).85 **/86 Slashed: AugmentedEvent<ApiType, [who: AccountId32, amount: u128], { who: AccountId32, amount: u128 }>;87 /**88 * Transfer succeeded.89 **/90 Transfer: AugmentedEvent<ApiType, [from: AccountId32, to: AccountId32, amount: u128], { from: AccountId32, to: AccountId32, amount: u128 }>;91 /**92 * Some balance was unreserved (moved from reserved to free).93 **/94 Unreserved: AugmentedEvent<ApiType, [who: AccountId32, amount: u128], { who: AccountId32, amount: u128 }>;95 /**96 * Some amount was withdrawn from the account (e.g. for transaction fees).97 **/98 Withdraw: AugmentedEvent<ApiType, [who: AccountId32, amount: u128], { who: AccountId32, amount: u128 }>;99 /**100 * Generic event101 **/102 [key: string]: AugmentedEvent<ApiType>;103 };104 common: {105 /**106 * Amount pieces of token owned by `sender` was approved for `spender`.107 **/108 Approved: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;109 /**110 * New collection was created111 **/112 CollectionCreated: AugmentedEvent<ApiType, [u32, u8, AccountId32]>;113 /**114 * New collection was destroyed115 **/116 CollectionDestroyed: AugmentedEvent<ApiType, [u32]>;117 /**118 * The property has been deleted.119 **/120 CollectionPropertyDeleted: AugmentedEvent<ApiType, [u32, Bytes]>;121 /**122 * The colletion property has been added or edited.123 **/124 CollectionPropertySet: AugmentedEvent<ApiType, [u32, Bytes]>;125 /**126 * New item was created.127 **/128 ItemCreated: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;129 /**130 * Collection item was burned.131 **/132 ItemDestroyed: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;133 /**134 * The token property permission of a collection has been set.135 **/136 PropertyPermissionSet: AugmentedEvent<ApiType, [u32, Bytes]>;137 /**138 * The token property has been deleted.139 **/140 TokenPropertyDeleted: AugmentedEvent<ApiType, [u32, u32, Bytes]>;141 /**142 * The token property has been added or edited.143 **/144 TokenPropertySet: AugmentedEvent<ApiType, [u32, u32, Bytes]>;145 /**146 * Item was transferred147 **/148 Transfer: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;149 /**150 * Generic event151 **/152 [key: string]: AugmentedEvent<ApiType>;153 };154 cumulusXcm: {155 /**156 * Downward message executed with the given outcome.157 * \[ id, outcome \]158 **/159 ExecutedDownward: AugmentedEvent<ApiType, [U8aFixed, XcmV2TraitsOutcome]>;160 /**161 * Downward message is invalid XCM.162 * \[ id \]163 **/164 InvalidFormat: AugmentedEvent<ApiType, [U8aFixed]>;165 /**166 * Downward message is unsupported version of XCM.167 * \[ id \]168 **/169 UnsupportedVersion: AugmentedEvent<ApiType, [U8aFixed]>;170 /**171 * Generic event172 **/173 [key: string]: AugmentedEvent<ApiType>;174 };175 dmpQueue: {176 /**177 * Downward message executed with the given outcome.178 **/179 ExecutedDownward: AugmentedEvent<ApiType, [messageId: U8aFixed, outcome: XcmV2TraitsOutcome], { messageId: U8aFixed, outcome: XcmV2TraitsOutcome }>;180 /**181 * Downward message is invalid XCM.182 **/183 InvalidFormat: AugmentedEvent<ApiType, [messageId: U8aFixed], { messageId: U8aFixed }>;184 /**185 * Downward message is overweight and was placed in the overweight queue.186 **/187 OverweightEnqueued: AugmentedEvent<ApiType, [messageId: U8aFixed, overweightIndex: u64, requiredWeight: Weight], { messageId: U8aFixed, overweightIndex: u64, requiredWeight: Weight }>;188 /**189 * Downward message from the overweight queue was executed.190 **/191 OverweightServiced: AugmentedEvent<ApiType, [overweightIndex: u64, weightUsed: Weight], { overweightIndex: u64, weightUsed: Weight }>;192 /**193 * Downward message is unsupported version of XCM.194 **/195 UnsupportedVersion: AugmentedEvent<ApiType, [messageId: U8aFixed], { messageId: U8aFixed }>;196 /**197 * The weight limit for handling downward messages was reached.198 **/199 WeightExhausted: AugmentedEvent<ApiType, [messageId: U8aFixed, remainingWeight: Weight, requiredWeight: Weight], { messageId: U8aFixed, remainingWeight: Weight, requiredWeight: Weight }>;200 /**201 * Generic event202 **/203 [key: string]: AugmentedEvent<ApiType>;204 };205 ethereum: {206 /**207 * An ethereum transaction was successfully executed.208 **/209 Executed: AugmentedEvent<ApiType, [from: H160, to: H160, transactionHash: H256, exitReason: EvmCoreErrorExitReason], { from: H160, to: H160, transactionHash: H256, exitReason: EvmCoreErrorExitReason }>;210 /**211 * Generic event212 **/213 [key: string]: AugmentedEvent<ApiType>;214 };215 evm: {216 /**217 * A contract has been created at given address.218 **/219 Created: AugmentedEvent<ApiType, [address: H160], { address: H160 }>;220 /**221 * A contract was attempted to be created, but the execution failed.222 **/223 CreatedFailed: AugmentedEvent<ApiType, [address: H160], { address: H160 }>;224 /**225 * A contract has been executed successfully with states applied.226 **/227 Executed: AugmentedEvent<ApiType, [address: H160], { address: H160 }>;228 /**229 * A contract has been executed with errors. States are reverted with only gas fees applied.230 **/231 ExecutedFailed: AugmentedEvent<ApiType, [address: H160], { address: H160 }>;232 /**233 * Ethereum events from contracts.234 **/235 Log: AugmentedEvent<ApiType, [log: EthereumLog], { log: EthereumLog }>;236 /**237 * Generic event238 **/239 [key: string]: AugmentedEvent<ApiType>;240 };241 evmContractHelpers: {242 /**243 * Collection sponsor was removed.244 **/245 ContractSponsorRemoved: AugmentedEvent<ApiType, [H160]>;246 /**247 * Contract sponsor was set.248 **/249 ContractSponsorSet: AugmentedEvent<ApiType, [H160, AccountId32]>;250 /**251 * New sponsor was confirm.252 **/253 ContractSponsorshipConfirmed: AugmentedEvent<ApiType, [H160, AccountId32]>;254 /**255 * Generic event256 **/257 [key: string]: AugmentedEvent<ApiType>;258 };259 evmMigration: {260 /**261 * This event is used in benchmarking and can be used for tests262 **/263 TestEvent: AugmentedEvent<ApiType, []>;264 /**265 * Generic event266 **/267 [key: string]: AugmentedEvent<ApiType>;268 };269 foreignAssets: {270 /**271 * The asset registered.272 **/273 AssetRegistered: AugmentedEvent<ApiType, [assetId: PalletForeignAssetsAssetIds, metadata: PalletForeignAssetsModuleAssetMetadata], { assetId: PalletForeignAssetsAssetIds, metadata: PalletForeignAssetsModuleAssetMetadata }>;274 /**275 * The asset updated.276 **/277 AssetUpdated: AugmentedEvent<ApiType, [assetId: PalletForeignAssetsAssetIds, metadata: PalletForeignAssetsModuleAssetMetadata], { assetId: PalletForeignAssetsAssetIds, metadata: PalletForeignAssetsModuleAssetMetadata }>;278 /**279 * The foreign asset registered.280 **/281 ForeignAssetRegistered: AugmentedEvent<ApiType, [assetId: u32, assetAddress: XcmV1MultiLocation, metadata: PalletForeignAssetsModuleAssetMetadata], { assetId: u32, assetAddress: XcmV1MultiLocation, metadata: PalletForeignAssetsModuleAssetMetadata }>;282 /**283 * The foreign asset updated.284 **/285 ForeignAssetUpdated: AugmentedEvent<ApiType, [assetId: u32, assetAddress: XcmV1MultiLocation, metadata: PalletForeignAssetsModuleAssetMetadata], { assetId: u32, assetAddress: XcmV1MultiLocation, metadata: PalletForeignAssetsModuleAssetMetadata }>;286 /**287 * Generic event288 **/289 [key: string]: AugmentedEvent<ApiType>;290 };291 maintenance: {292 MaintenanceDisabled: AugmentedEvent<ApiType, []>;293 MaintenanceEnabled: AugmentedEvent<ApiType, []>;294 /**295 * Generic event296 **/297 [key: string]: AugmentedEvent<ApiType>;298 };299 parachainSystem: {300 /**301 * Downward messages were processed using the given weight.302 **/303 DownwardMessagesProcessed: AugmentedEvent<ApiType, [weightUsed: Weight, dmqHead: H256], { weightUsed: Weight, dmqHead: H256 }>;304 /**305 * Some downward messages have been received and will be processed.306 **/307 DownwardMessagesReceived: AugmentedEvent<ApiType, [count: u32], { count: u32 }>;308 /**309 * An upgrade has been authorized.310 **/311 UpgradeAuthorized: AugmentedEvent<ApiType, [codeHash: H256], { codeHash: H256 }>;312 /**313 * The validation function was applied as of the contained relay chain block number.314 **/315 ValidationFunctionApplied: AugmentedEvent<ApiType, [relayChainBlockNum: u32], { relayChainBlockNum: u32 }>;316 /**317 * The relay-chain aborted the upgrade process.318 **/319 ValidationFunctionDiscarded: AugmentedEvent<ApiType, []>;320 /**321 * The validation function has been scheduled to apply.322 **/323 ValidationFunctionStored: AugmentedEvent<ApiType, []>;324 /**325 * Generic event326 **/327 [key: string]: AugmentedEvent<ApiType>;328 };329 polkadotXcm: {330 /**331 * Some assets have been placed in an asset trap.332 * 333 * \[ hash, origin, assets \]334 **/335 AssetsTrapped: AugmentedEvent<ApiType, [H256, XcmV1MultiLocation, XcmVersionedMultiAssets]>;336 /**337 * Execution of an XCM message was attempted.338 * 339 * \[ outcome \]340 **/341 Attempted: AugmentedEvent<ApiType, [XcmV2TraitsOutcome]>;342 /**343 * Expected query response has been received but the origin location of the response does344 * not match that expected. The query remains registered for a later, valid, response to345 * be received and acted upon.346 * 347 * \[ origin location, id, expected location \]348 **/349 InvalidResponder: AugmentedEvent<ApiType, [XcmV1MultiLocation, u64, Option<XcmV1MultiLocation>]>;350 /**351 * Expected query response has been received but the expected origin location placed in352 * storage by this runtime previously cannot be decoded. The query remains registered.353 * 354 * This is unexpected (since a location placed in storage in a previously executing355 * runtime should be readable prior to query timeout) and dangerous since the possibly356 * valid response will be dropped. Manual governance intervention is probably going to be357 * needed.358 * 359 * \[ origin location, id \]360 **/361 InvalidResponderVersion: AugmentedEvent<ApiType, [XcmV1MultiLocation, u64]>;362 /**363 * Query response has been received and query is removed. The registered notification has364 * been dispatched and executed successfully.365 * 366 * \[ id, pallet index, call index \]367 **/368 Notified: AugmentedEvent<ApiType, [u64, u8, u8]>;369 /**370 * Query response has been received and query is removed. The dispatch was unable to be371 * decoded into a `Call`; this might be due to dispatch function having a signature which372 * is not `(origin, QueryId, Response)`.373 * 374 * \[ id, pallet index, call index \]375 **/376 NotifyDecodeFailed: AugmentedEvent<ApiType, [u64, u8, u8]>;377 /**378 * Query response has been received and query is removed. There was a general error with379 * dispatching the notification call.380 * 381 * \[ id, pallet index, call index \]382 **/383 NotifyDispatchError: AugmentedEvent<ApiType, [u64, u8, u8]>;384 /**385 * Query response has been received and query is removed. The registered notification could386 * not be dispatched because the dispatch weight is greater than the maximum weight387 * originally budgeted by this runtime for the query result.388 * 389 * \[ id, pallet index, call index, actual weight, max budgeted weight \]390 **/391 NotifyOverweight: AugmentedEvent<ApiType, [u64, u8, u8, Weight, Weight]>;392 /**393 * A given location which had a version change subscription was dropped owing to an error394 * migrating the location to our new XCM format.395 * 396 * \[ location, query ID \]397 **/398 NotifyTargetMigrationFail: AugmentedEvent<ApiType, [XcmVersionedMultiLocation, u64]>;399 /**400 * A given location which had a version change subscription was dropped owing to an error401 * sending the notification to it.402 * 403 * \[ location, query ID, error \]404 **/405 NotifyTargetSendFail: AugmentedEvent<ApiType, [XcmV1MultiLocation, u64, XcmV2TraitsError]>;406 /**407 * Query response has been received and is ready for taking with `take_response`. There is408 * no registered notification call.409 * 410 * \[ id, response \]411 **/412 ResponseReady: AugmentedEvent<ApiType, [u64, XcmV2Response]>;413 /**414 * Received query response has been read and removed.415 * 416 * \[ id \]417 **/418 ResponseTaken: AugmentedEvent<ApiType, [u64]>;419 /**420 * A XCM message was sent.421 * 422 * \[ origin, destination, message \]423 **/424 Sent: AugmentedEvent<ApiType, [XcmV1MultiLocation, XcmV1MultiLocation, XcmV2Xcm]>;425 /**426 * The supported version of a location has been changed. This might be through an427 * automatic notification or a manual intervention.428 * 429 * \[ location, XCM version \]430 **/431 SupportedVersionChanged: AugmentedEvent<ApiType, [XcmV1MultiLocation, u32]>;432 /**433 * Query response received which does not match a registered query. This may be because a434 * matching query was never registered, it may be because it is a duplicate response, or435 * because the query timed out.436 * 437 * \[ origin location, id \]438 **/439 UnexpectedResponse: AugmentedEvent<ApiType, [XcmV1MultiLocation, u64]>;440 /**441 * An XCM version change notification message has been attempted to be sent.442 * 443 * \[ destination, result \]444 **/445 VersionChangeNotified: AugmentedEvent<ApiType, [XcmV1MultiLocation, u32]>;446 /**447 * Generic event448 **/449 [key: string]: AugmentedEvent<ApiType>;450 };451 rmrkCore: {452 CollectionCreated: AugmentedEvent<ApiType, [issuer: AccountId32, collectionId: u32], { issuer: AccountId32, collectionId: u32 }>;453 CollectionDestroyed: AugmentedEvent<ApiType, [issuer: AccountId32, collectionId: u32], { issuer: AccountId32, collectionId: u32 }>;454 CollectionLocked: AugmentedEvent<ApiType, [issuer: AccountId32, collectionId: u32], { issuer: AccountId32, collectionId: u32 }>;455 IssuerChanged: AugmentedEvent<ApiType, [oldIssuer: AccountId32, newIssuer: AccountId32, collectionId: u32], { oldIssuer: AccountId32, newIssuer: AccountId32, collectionId: u32 }>;456 NFTAccepted: AugmentedEvent<ApiType, [sender: AccountId32, recipient: RmrkTraitsNftAccountIdOrCollectionNftTuple, collectionId: u32, nftId: u32], { sender: AccountId32, recipient: RmrkTraitsNftAccountIdOrCollectionNftTuple, collectionId: u32, nftId: u32 }>;457 NFTBurned: AugmentedEvent<ApiType, [owner: AccountId32, nftId: u32], { owner: AccountId32, nftId: u32 }>;458 NftMinted: AugmentedEvent<ApiType, [owner: AccountId32, collectionId: u32, nftId: u32], { owner: AccountId32, collectionId: u32, nftId: u32 }>;459 NFTRejected: AugmentedEvent<ApiType, [sender: AccountId32, collectionId: u32, nftId: u32], { sender: AccountId32, collectionId: u32, nftId: u32 }>;460 NFTSent: AugmentedEvent<ApiType, [sender: AccountId32, recipient: RmrkTraitsNftAccountIdOrCollectionNftTuple, collectionId: u32, nftId: u32, approvalRequired: bool], { sender: AccountId32, recipient: RmrkTraitsNftAccountIdOrCollectionNftTuple, collectionId: u32, nftId: u32, approvalRequired: bool }>;461 PrioritySet: AugmentedEvent<ApiType, [collectionId: u32, nftId: u32], { collectionId: u32, nftId: u32 }>;462 PropertySet: AugmentedEvent<ApiType, [collectionId: u32, maybeNftId: Option<u32>, key: Bytes, value: Bytes], { collectionId: u32, maybeNftId: Option<u32>, key: Bytes, value: Bytes }>;463 ResourceAccepted: AugmentedEvent<ApiType, [nftId: u32, resourceId: u32], { nftId: u32, resourceId: u32 }>;464 ResourceAdded: AugmentedEvent<ApiType, [nftId: u32, resourceId: u32], { nftId: u32, resourceId: u32 }>;465 ResourceRemoval: AugmentedEvent<ApiType, [nftId: u32, resourceId: u32], { nftId: u32, resourceId: u32 }>;466 ResourceRemovalAccepted: AugmentedEvent<ApiType, [nftId: u32, resourceId: u32], { nftId: u32, resourceId: u32 }>;467 /**468 * Generic event469 **/470 [key: string]: AugmentedEvent<ApiType>;471 };472 rmrkEquip: {473 BaseCreated: AugmentedEvent<ApiType, [issuer: AccountId32, baseId: u32], { issuer: AccountId32, baseId: u32 }>;474 EquippablesUpdated: AugmentedEvent<ApiType, [baseId: u32, slotId: u32], { baseId: u32, slotId: u32 }>;475 /**476 * Generic event477 **/478 [key: string]: AugmentedEvent<ApiType>;479 };480 scheduler: {481 /**482 * The call for the provided hash was not found so the task has been aborted.483 **/484 CallUnavailable: AugmentedEvent<ApiType, [task: ITuple<[u32, u32]>, id: Option<U8aFixed>], { task: ITuple<[u32, u32]>, id: Option<U8aFixed> }>;485 /**486 * Canceled some task.487 **/488 Canceled: AugmentedEvent<ApiType, [when: u32, index: u32], { when: u32, index: u32 }>;489 /**490 * Dispatched some task.491 **/492 Dispatched: AugmentedEvent<ApiType, [task: ITuple<[u32, u32]>, id: Option<U8aFixed>, result: Result<Null, SpRuntimeDispatchError>], { task: ITuple<[u32, u32]>, id: Option<U8aFixed>, result: Result<Null, SpRuntimeDispatchError> }>;493 /**494 * The given task can never be executed since it is overweight.495 **/496 PermanentlyOverweight: AugmentedEvent<ApiType, [task: ITuple<[u32, u32]>, id: Option<U8aFixed>], { task: ITuple<[u32, u32]>, id: Option<U8aFixed> }>;497 /**498 * Scheduled task's priority has changed499 **/500 PriorityChanged: AugmentedEvent<ApiType, [task: ITuple<[u32, u32]>, priority: u8], { task: ITuple<[u32, u32]>, priority: u8 }>;501 /**502 * Scheduled some task.503 **/504 Scheduled: AugmentedEvent<ApiType, [when: u32, index: u32], { when: u32, index: u32 }>;505 /**506 * Generic event507 **/508 [key: string]: AugmentedEvent<ApiType>;509 };510 structure: {511 /**512 * Executed call on behalf of the token.513 **/514 Executed: AugmentedEvent<ApiType, [Result<Null, SpRuntimeDispatchError>]>;515 /**516 * Generic event517 **/518 [key: string]: AugmentedEvent<ApiType>;519 };520 sudo: {521 /**522 * The \[sudoer\] just switched identity; the old key is supplied if one existed.523 **/524 KeyChanged: AugmentedEvent<ApiType, [oldSudoer: Option<AccountId32>], { oldSudoer: Option<AccountId32> }>;525 /**526 * A sudo just took place. \[result\]527 **/528 Sudid: AugmentedEvent<ApiType, [sudoResult: Result<Null, SpRuntimeDispatchError>], { sudoResult: Result<Null, SpRuntimeDispatchError> }>;529 /**530 * A sudo just took place. \[result\]531 **/532 SudoAsDone: AugmentedEvent<ApiType, [sudoResult: Result<Null, SpRuntimeDispatchError>], { sudoResult: Result<Null, SpRuntimeDispatchError> }>;533 /**534 * Generic event535 **/536 [key: string]: AugmentedEvent<ApiType>;537 };538 system: {539 /**540 * `:code` was updated.541 **/542 CodeUpdated: AugmentedEvent<ApiType, []>;543 /**544 * An extrinsic failed.545 **/546 ExtrinsicFailed: AugmentedEvent<ApiType, [dispatchError: SpRuntimeDispatchError, dispatchInfo: FrameSupportDispatchDispatchInfo], { dispatchError: SpRuntimeDispatchError, dispatchInfo: FrameSupportDispatchDispatchInfo }>;547 /**548 * An extrinsic completed successfully.549 **/550 ExtrinsicSuccess: AugmentedEvent<ApiType, [dispatchInfo: FrameSupportDispatchDispatchInfo], { dispatchInfo: FrameSupportDispatchDispatchInfo }>;551 /**552 * An account was reaped.553 **/554 KilledAccount: AugmentedEvent<ApiType, [account: AccountId32], { account: AccountId32 }>;555 /**556 * A new account was created.557 **/558 NewAccount: AugmentedEvent<ApiType, [account: AccountId32], { account: AccountId32 }>;559 /**560 * On on-chain remark happened.561 **/562 Remarked: AugmentedEvent<ApiType, [sender: AccountId32, hash_: H256], { sender: AccountId32, hash_: H256 }>;563 /**564 * Generic event565 **/566 [key: string]: AugmentedEvent<ApiType>;567 };568 testUtils: {569 BatchCompleted: AugmentedEvent<ApiType, []>;570 ShouldRollback: AugmentedEvent<ApiType, []>;571 ValueIsSet: AugmentedEvent<ApiType, []>;572 /**573 * Generic event574 **/575 [key: string]: AugmentedEvent<ApiType>;576 };577 tokens: {578 /**579 * A balance was set by root.580 **/581 BalanceSet: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, free: u128, reserved: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, free: u128, reserved: u128 }>;582 /**583 * Deposited some balance into an account584 **/585 Deposited: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;586 /**587 * An account was removed whose balance was non-zero but below588 * ExistentialDeposit, resulting in an outright loss.589 **/590 DustLost: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;591 /**592 * An account was created with some free balance.593 **/594 Endowed: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;595 /**596 * Some locked funds were unlocked597 **/598 LockRemoved: AugmentedEvent<ApiType, [lockId: U8aFixed, currencyId: PalletForeignAssetsAssetIds, who: AccountId32], { lockId: U8aFixed, currencyId: PalletForeignAssetsAssetIds, who: AccountId32 }>;599 /**600 * Some funds are locked601 **/602 LockSet: AugmentedEvent<ApiType, [lockId: U8aFixed, currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { lockId: U8aFixed, currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;603 /**604 * Some balance was reserved (moved from free to reserved).605 **/606 Reserved: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;607 /**608 * Some reserved balance was repatriated (moved from reserved to609 * another account).610 **/611 ReserveRepatriated: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, from: AccountId32, to: AccountId32, amount: u128, status: FrameSupportTokensMiscBalanceStatus], { currencyId: PalletForeignAssetsAssetIds, from: AccountId32, to: AccountId32, amount: u128, status: FrameSupportTokensMiscBalanceStatus }>;612 /**613 * Some balances were slashed (e.g. due to mis-behavior)614 **/615 Slashed: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, freeAmount: u128, reservedAmount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, freeAmount: u128, reservedAmount: u128 }>;616 /**617 * The total issuance of an currency has been set618 **/619 TotalIssuanceSet: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, amount: u128], { currencyId: PalletForeignAssetsAssetIds, amount: u128 }>;620 /**621 * Transfer succeeded.622 **/623 Transfer: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, from: AccountId32, to: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, from: AccountId32, to: AccountId32, amount: u128 }>;624 /**625 * Some balance was unreserved (moved from reserved to free).626 **/627 Unreserved: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;628 /**629 * Some balances were withdrawn (e.g. pay for transaction fee)630 **/631 Withdrawn: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;632 /**633 * Generic event634 **/635 [key: string]: AugmentedEvent<ApiType>;636 };637 transactionPayment: {638 /**639 * A transaction fee `actual_fee`, of which `tip` was added to the minimum inclusion fee,640 * has been paid by `who`.641 **/642 TransactionFeePaid: AugmentedEvent<ApiType, [who: AccountId32, actualFee: u128, tip: u128], { who: AccountId32, actualFee: u128, tip: u128 }>;643 /**644 * Generic event645 **/646 [key: string]: AugmentedEvent<ApiType>;647 };648 treasury: {649 /**650 * Some funds have been allocated.651 **/652 Awarded: AugmentedEvent<ApiType, [proposalIndex: u32, award: u128, account: AccountId32], { proposalIndex: u32, award: u128, account: AccountId32 }>;653 /**654 * Some of our funds have been burnt.655 **/656 Burnt: AugmentedEvent<ApiType, [burntFunds: u128], { burntFunds: u128 }>;657 /**658 * Some funds have been deposited.659 **/660 Deposit: AugmentedEvent<ApiType, [value: u128], { value: u128 }>;661 /**662 * New proposal.663 **/664 Proposed: AugmentedEvent<ApiType, [proposalIndex: u32], { proposalIndex: u32 }>;665 /**666 * A proposal was rejected; funds were slashed.667 **/668 Rejected: AugmentedEvent<ApiType, [proposalIndex: u32, slashed: u128], { proposalIndex: u32, slashed: u128 }>;669 /**670 * Spending has finished; this is the amount that rolls over until next spend.671 **/672 Rollover: AugmentedEvent<ApiType, [rolloverBalance: u128], { rolloverBalance: u128 }>;673 /**674 * A new spend proposal has been approved.675 **/676 SpendApproved: AugmentedEvent<ApiType, [proposalIndex: u32, amount: u128, beneficiary: AccountId32], { proposalIndex: u32, amount: u128, beneficiary: AccountId32 }>;677 /**678 * We have ended a spend period and will now allocate funds.679 **/680 Spending: AugmentedEvent<ApiType, [budgetRemaining: u128], { budgetRemaining: u128 }>;681 /**682 * Generic event683 **/684 [key: string]: AugmentedEvent<ApiType>;685 };686 unique: {687 /**688 * Address was added to the allow list689 * 690 * # Arguments691 * * collection_id: ID of the affected collection.692 * * user: Address of the added account.693 **/694 AllowListAddressAdded: AugmentedEvent<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;695 /**696 * Address was removed from the allow list697 * 698 * # Arguments699 * * collection_id: ID of the affected collection.700 * * user: Address of the removed account.701 **/702 AllowListAddressRemoved: AugmentedEvent<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;703 /**704 * Collection admin was added705 * 706 * # Arguments707 * * collection_id: ID of the affected collection.708 * * admin: Admin address.709 **/710 CollectionAdminAdded: AugmentedEvent<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;711 /**712 * Collection admin was removed713 * 714 * # Arguments715 * * collection_id: ID of the affected collection.716 * * admin: Removed admin address.717 **/718 CollectionAdminRemoved: AugmentedEvent<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;719 /**720 * Collection limits were set721 * 722 * # Arguments723 * * collection_id: ID of the affected collection.724 **/725 CollectionLimitSet: AugmentedEvent<ApiType, [u32]>;726 /**727 * Collection owned was changed728 * 729 * # Arguments730 * * collection_id: ID of the affected collection.731 * * owner: New owner address.732 **/733 CollectionOwnedChanged: AugmentedEvent<ApiType, [u32, AccountId32]>;734 /**735 * Collection permissions were set736 * 737 * # Arguments738 * * collection_id: ID of the affected collection.739 **/740 CollectionPermissionSet: AugmentedEvent<ApiType, [u32]>;741 /**742 * Collection sponsor was removed743 * 744 * # Arguments745 * * collection_id: ID of the affected collection.746 **/747 CollectionSponsorRemoved: AugmentedEvent<ApiType, [u32]>;748 /**749 * Collection sponsor was set750 * 751 * # Arguments752 * * collection_id: ID of the affected collection.753 * * owner: New sponsor address.754 **/755 CollectionSponsorSet: AugmentedEvent<ApiType, [u32, AccountId32]>;756 /**757 * New sponsor was confirm758 * 759 * # Arguments760 * * collection_id: ID of the affected collection.761 * * sponsor: New sponsor address.762 **/763 SponsorshipConfirmed: AugmentedEvent<ApiType, [u32, AccountId32]>;764 /**765 * Generic event766 **/767 [key: string]: AugmentedEvent<ApiType>;768 };769 vesting: {770 /**771 * Claimed vesting.772 **/773 Claimed: AugmentedEvent<ApiType, [who: AccountId32, amount: u128], { who: AccountId32, amount: u128 }>;774 /**775 * Added new vesting schedule.776 **/777 VestingScheduleAdded: AugmentedEvent<ApiType, [from: AccountId32, to: AccountId32, vestingSchedule: OrmlVestingVestingSchedule], { from: AccountId32, to: AccountId32, vestingSchedule: OrmlVestingVestingSchedule }>;778 /**779 * Updated vesting schedules.780 **/781 VestingSchedulesUpdated: AugmentedEvent<ApiType, [who: AccountId32], { who: AccountId32 }>;782 /**783 * Generic event784 **/785 [key: string]: AugmentedEvent<ApiType>;786 };787 xcmpQueue: {788 /**789 * Bad XCM format used.790 **/791 BadFormat: AugmentedEvent<ApiType, [messageHash: Option<H256>], { messageHash: Option<H256> }>;792 /**793 * Bad XCM version used.794 **/795 BadVersion: AugmentedEvent<ApiType, [messageHash: Option<H256>], { messageHash: Option<H256> }>;796 /**797 * Some XCM failed.798 **/799 Fail: AugmentedEvent<ApiType, [messageHash: Option<H256>, error: XcmV2TraitsError, weight: Weight], { messageHash: Option<H256>, error: XcmV2TraitsError, weight: Weight }>;800 /**801 * An XCM exceeded the individual message weight budget.802 **/803 OverweightEnqueued: AugmentedEvent<ApiType, [sender: u32, sentAt: u32, index: u64, required: Weight], { sender: u32, sentAt: u32, index: u64, required: Weight }>;804 /**805 * An XCM from the overweight queue was executed with the given actual weight used.806 **/807 OverweightServiced: AugmentedEvent<ApiType, [index: u64, used: Weight], { index: u64, used: Weight }>;808 /**809 * Some XCM was executed ok.810 **/811 Success: AugmentedEvent<ApiType, [messageHash: Option<H256>, weight: Weight], { messageHash: Option<H256>, weight: Weight }>;812 /**813 * An upward message was sent to the relay chain.814 **/815 UpwardMessageSent: AugmentedEvent<ApiType, [messageHash: Option<H256>], { messageHash: Option<H256> }>;816 /**817 * An HRMP message was sent to a sibling parachain.818 **/819 XcmpMessageSent: AugmentedEvent<ApiType, [messageHash: Option<H256>], { messageHash: Option<H256> }>;820 /**821 * Generic event822 **/823 [key: string]: AugmentedEvent<ApiType>;824 };825 xTokens: {826 /**827 * Transferred `MultiAsset` with fee.828 **/829 TransferredMultiAssets: AugmentedEvent<ApiType, [sender: AccountId32, assets: XcmV1MultiassetMultiAssets, fee: XcmV1MultiAsset, dest: XcmV1MultiLocation], { sender: AccountId32, assets: XcmV1MultiassetMultiAssets, fee: XcmV1MultiAsset, dest: XcmV1MultiLocation }>;830 /**831 * Generic event832 **/833 [key: string]: AugmentedEvent<ApiType>;834 };835 } // AugmentedEvents836} // declare module1// Auto-generated via `yarn polkadot-types-from-chain`, do not edit2/* eslint-disable */34// import type lookup before we augment - in some environments5// this is required to allow for ambient/previous definitions6import '@polkadot/api-base/types/events';78import type { ApiTypes, AugmentedEvent } from '@polkadot/api-base/types';9import type { Bytes, Null, Option, Result, U8aFixed, bool, u128, u32, u64, u8 } from '@polkadot/types-codec';10import type { ITuple } from '@polkadot/types-codec/types';11import type { AccountId32, H160, H256, Weight } from '@polkadot/types/interfaces/runtime';12import type { EthereumLog, EvmCoreErrorExitReason, FrameSupportDispatchDispatchInfo, FrameSupportTokensMiscBalanceStatus, OrmlVestingVestingSchedule, PalletEvmAccountBasicCrossAccountIdRepr, PalletForeignAssetsAssetIds, PalletForeignAssetsModuleAssetMetadata, RmrkTraitsNftAccountIdOrCollectionNftTuple, SpRuntimeDispatchError, XcmV1MultiAsset, XcmV1MultiLocation, XcmV1MultiassetMultiAssets, XcmV2Response, XcmV2TraitsError, XcmV2TraitsOutcome, XcmV2Xcm, XcmVersionedMultiAssets, XcmVersionedMultiLocation } from '@polkadot/types/lookup';1314export type __AugmentedEvent<ApiType extends ApiTypes> = AugmentedEvent<ApiType>;1516declare module '@polkadot/api-base/types/events' {17 interface AugmentedEvents<ApiType extends ApiTypes> {18 appPromotion: {19 /**20 * The admin was set21 * 22 * # Arguments23 * * AccountId: account address of the admin24 **/25 SetAdmin: AugmentedEvent<ApiType, [AccountId32]>;26 /**27 * Staking was performed28 * 29 * # Arguments30 * * AccountId: account of the staker31 * * Balance : staking amount32 **/33 Stake: AugmentedEvent<ApiType, [AccountId32, u128]>;34 /**35 * Staking recalculation was performed36 * 37 * # Arguments38 * * AccountId: account of the staker.39 * * Balance : recalculation base40 * * Balance : total income41 **/42 StakingRecalculation: AugmentedEvent<ApiType, [AccountId32, u128, u128]>;43 /**44 * Unstaking was performed45 * 46 * # Arguments47 * * AccountId: account of the staker48 * * Balance : unstaking amount49 **/50 Unstake: AugmentedEvent<ApiType, [AccountId32, u128]>;51 /**52 * Generic event53 **/54 [key: string]: AugmentedEvent<ApiType>;55 };56 balances: {57 /**58 * A balance was set by root.59 **/60 BalanceSet: AugmentedEvent<ApiType, [who: AccountId32, free: u128, reserved: u128], { who: AccountId32, free: u128, reserved: u128 }>;61 /**62 * Some amount was deposited (e.g. for transaction fees).63 **/64 Deposit: AugmentedEvent<ApiType, [who: AccountId32, amount: u128], { who: AccountId32, amount: u128 }>;65 /**66 * An account was removed whose balance was non-zero but below ExistentialDeposit,67 * resulting in an outright loss.68 **/69 DustLost: AugmentedEvent<ApiType, [account: AccountId32, amount: u128], { account: AccountId32, amount: u128 }>;70 /**71 * An account was created with some free balance.72 **/73 Endowed: AugmentedEvent<ApiType, [account: AccountId32, freeBalance: u128], { account: AccountId32, freeBalance: u128 }>;74 /**75 * Some balance was reserved (moved from free to reserved).76 **/77 Reserved: AugmentedEvent<ApiType, [who: AccountId32, amount: u128], { who: AccountId32, amount: u128 }>;78 /**79 * Some balance was moved from the reserve of the first account to the second account.80 * Final argument indicates the destination balance type.81 **/82 ReserveRepatriated: AugmentedEvent<ApiType, [from: AccountId32, to: AccountId32, amount: u128, destinationStatus: FrameSupportTokensMiscBalanceStatus], { from: AccountId32, to: AccountId32, amount: u128, destinationStatus: FrameSupportTokensMiscBalanceStatus }>;83 /**84 * Some amount was removed from the account (e.g. for misbehavior).85 **/86 Slashed: AugmentedEvent<ApiType, [who: AccountId32, amount: u128], { who: AccountId32, amount: u128 }>;87 /**88 * Transfer succeeded.89 **/90 Transfer: AugmentedEvent<ApiType, [from: AccountId32, to: AccountId32, amount: u128], { from: AccountId32, to: AccountId32, amount: u128 }>;91 /**92 * Some balance was unreserved (moved from reserved to free).93 **/94 Unreserved: AugmentedEvent<ApiType, [who: AccountId32, amount: u128], { who: AccountId32, amount: u128 }>;95 /**96 * Some amount was withdrawn from the account (e.g. for transaction fees).97 **/98 Withdraw: AugmentedEvent<ApiType, [who: AccountId32, amount: u128], { who: AccountId32, amount: u128 }>;99 /**100 * Generic event101 **/102 [key: string]: AugmentedEvent<ApiType>;103 };104 common: {105 /**106 * Amount pieces of token owned by `sender` was approved for `spender`.107 **/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]>;113 /**114 * New collection was created115 **/116 CollectionCreated: AugmentedEvent<ApiType, [u32, u8, AccountId32]>;117 /**118 * New collection was destroyed119 **/120 CollectionDestroyed: AugmentedEvent<ApiType, [u32]>;121 /**122 * The property has been deleted.123 **/124 CollectionPropertyDeleted: AugmentedEvent<ApiType, [u32, Bytes]>;125 /**126 * The colletion property has been added or edited.127 **/128 CollectionPropertySet: AugmentedEvent<ApiType, [u32, Bytes]>;129 /**130 * New item was created.131 **/132 ItemCreated: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;133 /**134 * Collection item was burned.135 **/136 ItemDestroyed: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;137 /**138 * The token property permission of a collection has been set.139 **/140 PropertyPermissionSet: AugmentedEvent<ApiType, [u32, Bytes]>;141 /**142 * The token property has been deleted.143 **/144 TokenPropertyDeleted: AugmentedEvent<ApiType, [u32, u32, Bytes]>;145 /**146 * The token property has been added or edited.147 **/148 TokenPropertySet: AugmentedEvent<ApiType, [u32, u32, Bytes]>;149 /**150 * Item was transferred151 **/152 Transfer: AugmentedEvent<ApiType, [u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;153 /**154 * Generic event155 **/156 [key: string]: AugmentedEvent<ApiType>;157 };158 cumulusXcm: {159 /**160 * Downward message executed with the given outcome.161 * \[ id, outcome \]162 **/163 ExecutedDownward: AugmentedEvent<ApiType, [U8aFixed, XcmV2TraitsOutcome]>;164 /**165 * Downward message is invalid XCM.166 * \[ id \]167 **/168 InvalidFormat: AugmentedEvent<ApiType, [U8aFixed]>;169 /**170 * Downward message is unsupported version of XCM.171 * \[ id \]172 **/173 UnsupportedVersion: AugmentedEvent<ApiType, [U8aFixed]>;174 /**175 * Generic event176 **/177 [key: string]: AugmentedEvent<ApiType>;178 };179 dmpQueue: {180 /**181 * Downward message executed with the given outcome.182 **/183 ExecutedDownward: AugmentedEvent<ApiType, [messageId: U8aFixed, outcome: XcmV2TraitsOutcome], { messageId: U8aFixed, outcome: XcmV2TraitsOutcome }>;184 /**185 * Downward message is invalid XCM.186 **/187 InvalidFormat: AugmentedEvent<ApiType, [messageId: U8aFixed], { messageId: U8aFixed }>;188 /**189 * Downward message is overweight and was placed in the overweight queue.190 **/191 OverweightEnqueued: AugmentedEvent<ApiType, [messageId: U8aFixed, overweightIndex: u64, requiredWeight: Weight], { messageId: U8aFixed, overweightIndex: u64, requiredWeight: Weight }>;192 /**193 * Downward message from the overweight queue was executed.194 **/195 OverweightServiced: AugmentedEvent<ApiType, [overweightIndex: u64, weightUsed: Weight], { overweightIndex: u64, weightUsed: Weight }>;196 /**197 * Downward message is unsupported version of XCM.198 **/199 UnsupportedVersion: AugmentedEvent<ApiType, [messageId: U8aFixed], { messageId: U8aFixed }>;200 /**201 * The weight limit for handling downward messages was reached.202 **/203 WeightExhausted: AugmentedEvent<ApiType, [messageId: U8aFixed, remainingWeight: Weight, requiredWeight: Weight], { messageId: U8aFixed, remainingWeight: Weight, requiredWeight: Weight }>;204 /**205 * Generic event206 **/207 [key: string]: AugmentedEvent<ApiType>;208 };209 ethereum: {210 /**211 * An ethereum transaction was successfully executed.212 **/213 Executed: AugmentedEvent<ApiType, [from: H160, to: H160, transactionHash: H256, exitReason: EvmCoreErrorExitReason], { from: H160, to: H160, transactionHash: H256, exitReason: EvmCoreErrorExitReason }>;214 /**215 * Generic event216 **/217 [key: string]: AugmentedEvent<ApiType>;218 };219 evm: {220 /**221 * A contract has been created at given address.222 **/223 Created: AugmentedEvent<ApiType, [address: H160], { address: H160 }>;224 /**225 * A contract was attempted to be created, but the execution failed.226 **/227 CreatedFailed: AugmentedEvent<ApiType, [address: H160], { address: H160 }>;228 /**229 * A contract has been executed successfully with states applied.230 **/231 Executed: AugmentedEvent<ApiType, [address: H160], { address: H160 }>;232 /**233 * A contract has been executed with errors. States are reverted with only gas fees applied.234 **/235 ExecutedFailed: AugmentedEvent<ApiType, [address: H160], { address: H160 }>;236 /**237 * Ethereum events from contracts.238 **/239 Log: AugmentedEvent<ApiType, [log: EthereumLog], { log: EthereumLog }>;240 /**241 * Generic event242 **/243 [key: string]: AugmentedEvent<ApiType>;244 };245 evmContractHelpers: {246 /**247 * Collection sponsor was removed.248 **/249 ContractSponsorRemoved: AugmentedEvent<ApiType, [H160]>;250 /**251 * Contract sponsor was set.252 **/253 ContractSponsorSet: AugmentedEvent<ApiType, [H160, AccountId32]>;254 /**255 * New sponsor was confirm.256 **/257 ContractSponsorshipConfirmed: AugmentedEvent<ApiType, [H160, AccountId32]>;258 /**259 * Generic event260 **/261 [key: string]: AugmentedEvent<ApiType>;262 };263 evmMigration: {264 /**265 * This event is used in benchmarking and can be used for tests266 **/267 TestEvent: AugmentedEvent<ApiType, []>;268 /**269 * Generic event270 **/271 [key: string]: AugmentedEvent<ApiType>;272 };273 foreignAssets: {274 /**275 * The asset registered.276 **/277 AssetRegistered: AugmentedEvent<ApiType, [assetId: PalletForeignAssetsAssetIds, metadata: PalletForeignAssetsModuleAssetMetadata], { assetId: PalletForeignAssetsAssetIds, metadata: PalletForeignAssetsModuleAssetMetadata }>;278 /**279 * The asset updated.280 **/281 AssetUpdated: AugmentedEvent<ApiType, [assetId: PalletForeignAssetsAssetIds, metadata: PalletForeignAssetsModuleAssetMetadata], { assetId: PalletForeignAssetsAssetIds, metadata: PalletForeignAssetsModuleAssetMetadata }>;282 /**283 * The foreign asset registered.284 **/285 ForeignAssetRegistered: AugmentedEvent<ApiType, [assetId: u32, assetAddress: XcmV1MultiLocation, metadata: PalletForeignAssetsModuleAssetMetadata], { assetId: u32, assetAddress: XcmV1MultiLocation, metadata: PalletForeignAssetsModuleAssetMetadata }>;286 /**287 * The foreign asset updated.288 **/289 ForeignAssetUpdated: AugmentedEvent<ApiType, [assetId: u32, assetAddress: XcmV1MultiLocation, metadata: PalletForeignAssetsModuleAssetMetadata], { assetId: u32, assetAddress: XcmV1MultiLocation, metadata: PalletForeignAssetsModuleAssetMetadata }>;290 /**291 * Generic event292 **/293 [key: string]: AugmentedEvent<ApiType>;294 };295 maintenance: {296 MaintenanceDisabled: AugmentedEvent<ApiType, []>;297 MaintenanceEnabled: AugmentedEvent<ApiType, []>;298 /**299 * Generic event300 **/301 [key: string]: AugmentedEvent<ApiType>;302 };303 parachainSystem: {304 /**305 * Downward messages were processed using the given weight.306 **/307 DownwardMessagesProcessed: AugmentedEvent<ApiType, [weightUsed: Weight, dmqHead: H256], { weightUsed: Weight, dmqHead: H256 }>;308 /**309 * Some downward messages have been received and will be processed.310 **/311 DownwardMessagesReceived: AugmentedEvent<ApiType, [count: u32], { count: u32 }>;312 /**313 * An upgrade has been authorized.314 **/315 UpgradeAuthorized: AugmentedEvent<ApiType, [codeHash: H256], { codeHash: H256 }>;316 /**317 * The validation function was applied as of the contained relay chain block number.318 **/319 ValidationFunctionApplied: AugmentedEvent<ApiType, [relayChainBlockNum: u32], { relayChainBlockNum: u32 }>;320 /**321 * The relay-chain aborted the upgrade process.322 **/323 ValidationFunctionDiscarded: AugmentedEvent<ApiType, []>;324 /**325 * The validation function has been scheduled to apply.326 **/327 ValidationFunctionStored: AugmentedEvent<ApiType, []>;328 /**329 * Generic event330 **/331 [key: string]: AugmentedEvent<ApiType>;332 };333 polkadotXcm: {334 /**335 * Some assets have been placed in an asset trap.336 * 337 * \[ hash, origin, assets \]338 **/339 AssetsTrapped: AugmentedEvent<ApiType, [H256, XcmV1MultiLocation, XcmVersionedMultiAssets]>;340 /**341 * Execution of an XCM message was attempted.342 * 343 * \[ outcome \]344 **/345 Attempted: AugmentedEvent<ApiType, [XcmV2TraitsOutcome]>;346 /**347 * Expected query response has been received but the origin location of the response does348 * not match that expected. The query remains registered for a later, valid, response to349 * be received and acted upon.350 * 351 * \[ origin location, id, expected location \]352 **/353 InvalidResponder: AugmentedEvent<ApiType, [XcmV1MultiLocation, u64, Option<XcmV1MultiLocation>]>;354 /**355 * Expected query response has been received but the expected origin location placed in356 * storage by this runtime previously cannot be decoded. The query remains registered.357 * 358 * This is unexpected (since a location placed in storage in a previously executing359 * runtime should be readable prior to query timeout) and dangerous since the possibly360 * valid response will be dropped. Manual governance intervention is probably going to be361 * needed.362 * 363 * \[ origin location, id \]364 **/365 InvalidResponderVersion: AugmentedEvent<ApiType, [XcmV1MultiLocation, u64]>;366 /**367 * Query response has been received and query is removed. The registered notification has368 * been dispatched and executed successfully.369 * 370 * \[ id, pallet index, call index \]371 **/372 Notified: AugmentedEvent<ApiType, [u64, u8, u8]>;373 /**374 * Query response has been received and query is removed. The dispatch was unable to be375 * decoded into a `Call`; this might be due to dispatch function having a signature which376 * is not `(origin, QueryId, Response)`.377 * 378 * \[ id, pallet index, call index \]379 **/380 NotifyDecodeFailed: AugmentedEvent<ApiType, [u64, u8, u8]>;381 /**382 * Query response has been received and query is removed. There was a general error with383 * dispatching the notification call.384 * 385 * \[ id, pallet index, call index \]386 **/387 NotifyDispatchError: AugmentedEvent<ApiType, [u64, u8, u8]>;388 /**389 * Query response has been received and query is removed. The registered notification could390 * not be dispatched because the dispatch weight is greater than the maximum weight391 * originally budgeted by this runtime for the query result.392 * 393 * \[ id, pallet index, call index, actual weight, max budgeted weight \]394 **/395 NotifyOverweight: AugmentedEvent<ApiType, [u64, u8, u8, Weight, Weight]>;396 /**397 * A given location which had a version change subscription was dropped owing to an error398 * migrating the location to our new XCM format.399 * 400 * \[ location, query ID \]401 **/402 NotifyTargetMigrationFail: AugmentedEvent<ApiType, [XcmVersionedMultiLocation, u64]>;403 /**404 * A given location which had a version change subscription was dropped owing to an error405 * sending the notification to it.406 * 407 * \[ location, query ID, error \]408 **/409 NotifyTargetSendFail: AugmentedEvent<ApiType, [XcmV1MultiLocation, u64, XcmV2TraitsError]>;410 /**411 * Query response has been received and is ready for taking with `take_response`. There is412 * no registered notification call.413 * 414 * \[ id, response \]415 **/416 ResponseReady: AugmentedEvent<ApiType, [u64, XcmV2Response]>;417 /**418 * Received query response has been read and removed.419 * 420 * \[ id \]421 **/422 ResponseTaken: AugmentedEvent<ApiType, [u64]>;423 /**424 * A XCM message was sent.425 * 426 * \[ origin, destination, message \]427 **/428 Sent: AugmentedEvent<ApiType, [XcmV1MultiLocation, XcmV1MultiLocation, XcmV2Xcm]>;429 /**430 * The supported version of a location has been changed. This might be through an431 * automatic notification or a manual intervention.432 * 433 * \[ location, XCM version \]434 **/435 SupportedVersionChanged: AugmentedEvent<ApiType, [XcmV1MultiLocation, u32]>;436 /**437 * Query response received which does not match a registered query. This may be because a438 * matching query was never registered, it may be because it is a duplicate response, or439 * because the query timed out.440 * 441 * \[ origin location, id \]442 **/443 UnexpectedResponse: AugmentedEvent<ApiType, [XcmV1MultiLocation, u64]>;444 /**445 * An XCM version change notification message has been attempted to be sent.446 * 447 * \[ destination, result \]448 **/449 VersionChangeNotified: AugmentedEvent<ApiType, [XcmV1MultiLocation, u32]>;450 /**451 * Generic event452 **/453 [key: string]: AugmentedEvent<ApiType>;454 };455 rmrkCore: {456 CollectionCreated: AugmentedEvent<ApiType, [issuer: AccountId32, collectionId: u32], { issuer: AccountId32, collectionId: u32 }>;457 CollectionDestroyed: AugmentedEvent<ApiType, [issuer: AccountId32, collectionId: u32], { issuer: AccountId32, collectionId: u32 }>;458 CollectionLocked: AugmentedEvent<ApiType, [issuer: AccountId32, collectionId: u32], { issuer: AccountId32, collectionId: u32 }>;459 IssuerChanged: AugmentedEvent<ApiType, [oldIssuer: AccountId32, newIssuer: AccountId32, collectionId: u32], { oldIssuer: AccountId32, newIssuer: AccountId32, collectionId: u32 }>;460 NFTAccepted: AugmentedEvent<ApiType, [sender: AccountId32, recipient: RmrkTraitsNftAccountIdOrCollectionNftTuple, collectionId: u32, nftId: u32], { sender: AccountId32, recipient: RmrkTraitsNftAccountIdOrCollectionNftTuple, collectionId: u32, nftId: u32 }>;461 NFTBurned: AugmentedEvent<ApiType, [owner: AccountId32, nftId: u32], { owner: AccountId32, nftId: u32 }>;462 NftMinted: AugmentedEvent<ApiType, [owner: AccountId32, collectionId: u32, nftId: u32], { owner: AccountId32, collectionId: u32, nftId: u32 }>;463 NFTRejected: AugmentedEvent<ApiType, [sender: AccountId32, collectionId: u32, nftId: u32], { sender: AccountId32, collectionId: u32, nftId: u32 }>;464 NFTSent: AugmentedEvent<ApiType, [sender: AccountId32, recipient: RmrkTraitsNftAccountIdOrCollectionNftTuple, collectionId: u32, nftId: u32, approvalRequired: bool], { sender: AccountId32, recipient: RmrkTraitsNftAccountIdOrCollectionNftTuple, collectionId: u32, nftId: u32, approvalRequired: bool }>;465 PrioritySet: AugmentedEvent<ApiType, [collectionId: u32, nftId: u32], { collectionId: u32, nftId: u32 }>;466 PropertySet: AugmentedEvent<ApiType, [collectionId: u32, maybeNftId: Option<u32>, key: Bytes, value: Bytes], { collectionId: u32, maybeNftId: Option<u32>, key: Bytes, value: Bytes }>;467 ResourceAccepted: AugmentedEvent<ApiType, [nftId: u32, resourceId: u32], { nftId: u32, resourceId: u32 }>;468 ResourceAdded: AugmentedEvent<ApiType, [nftId: u32, resourceId: u32], { nftId: u32, resourceId: u32 }>;469 ResourceRemoval: AugmentedEvent<ApiType, [nftId: u32, resourceId: u32], { nftId: u32, resourceId: u32 }>;470 ResourceRemovalAccepted: AugmentedEvent<ApiType, [nftId: u32, resourceId: u32], { nftId: u32, resourceId: u32 }>;471 /**472 * Generic event473 **/474 [key: string]: AugmentedEvent<ApiType>;475 };476 rmrkEquip: {477 BaseCreated: AugmentedEvent<ApiType, [issuer: AccountId32, baseId: u32], { issuer: AccountId32, baseId: u32 }>;478 EquippablesUpdated: AugmentedEvent<ApiType, [baseId: u32, slotId: u32], { baseId: u32, slotId: u32 }>;479 /**480 * Generic event481 **/482 [key: string]: AugmentedEvent<ApiType>;483 };484 scheduler: {485 /**486 * The call for the provided hash was not found so the task has been aborted.487 **/488 CallUnavailable: AugmentedEvent<ApiType, [task: ITuple<[u32, u32]>, id: Option<U8aFixed>], { task: ITuple<[u32, u32]>, id: Option<U8aFixed> }>;489 /**490 * Canceled some task.491 **/492 Canceled: AugmentedEvent<ApiType, [when: u32, index: u32], { when: u32, index: u32 }>;493 /**494 * Dispatched some task.495 **/496 Dispatched: AugmentedEvent<ApiType, [task: ITuple<[u32, u32]>, id: Option<U8aFixed>, result: Result<Null, SpRuntimeDispatchError>], { task: ITuple<[u32, u32]>, id: Option<U8aFixed>, result: Result<Null, SpRuntimeDispatchError> }>;497 /**498 * The given task can never be executed since it is overweight.499 **/500 PermanentlyOverweight: AugmentedEvent<ApiType, [task: ITuple<[u32, u32]>, id: Option<U8aFixed>], { task: ITuple<[u32, u32]>, id: Option<U8aFixed> }>;501 /**502 * Scheduled task's priority has changed503 **/504 PriorityChanged: AugmentedEvent<ApiType, [task: ITuple<[u32, u32]>, priority: u8], { task: ITuple<[u32, u32]>, priority: u8 }>;505 /**506 * Scheduled some task.507 **/508 Scheduled: AugmentedEvent<ApiType, [when: u32, index: u32], { when: u32, index: u32 }>;509 /**510 * Generic event511 **/512 [key: string]: AugmentedEvent<ApiType>;513 };514 structure: {515 /**516 * Executed call on behalf of the token.517 **/518 Executed: AugmentedEvent<ApiType, [Result<Null, SpRuntimeDispatchError>]>;519 /**520 * Generic event521 **/522 [key: string]: AugmentedEvent<ApiType>;523 };524 sudo: {525 /**526 * The \[sudoer\] just switched identity; the old key is supplied if one existed.527 **/528 KeyChanged: AugmentedEvent<ApiType, [oldSudoer: Option<AccountId32>], { oldSudoer: Option<AccountId32> }>;529 /**530 * A sudo just took place. \[result\]531 **/532 Sudid: AugmentedEvent<ApiType, [sudoResult: Result<Null, SpRuntimeDispatchError>], { sudoResult: Result<Null, SpRuntimeDispatchError> }>;533 /**534 * A sudo just took place. \[result\]535 **/536 SudoAsDone: AugmentedEvent<ApiType, [sudoResult: Result<Null, SpRuntimeDispatchError>], { sudoResult: Result<Null, SpRuntimeDispatchError> }>;537 /**538 * Generic event539 **/540 [key: string]: AugmentedEvent<ApiType>;541 };542 system: {543 /**544 * `:code` was updated.545 **/546 CodeUpdated: AugmentedEvent<ApiType, []>;547 /**548 * An extrinsic failed.549 **/550 ExtrinsicFailed: AugmentedEvent<ApiType, [dispatchError: SpRuntimeDispatchError, dispatchInfo: FrameSupportDispatchDispatchInfo], { dispatchError: SpRuntimeDispatchError, dispatchInfo: FrameSupportDispatchDispatchInfo }>;551 /**552 * An extrinsic completed successfully.553 **/554 ExtrinsicSuccess: AugmentedEvent<ApiType, [dispatchInfo: FrameSupportDispatchDispatchInfo], { dispatchInfo: FrameSupportDispatchDispatchInfo }>;555 /**556 * An account was reaped.557 **/558 KilledAccount: AugmentedEvent<ApiType, [account: AccountId32], { account: AccountId32 }>;559 /**560 * A new account was created.561 **/562 NewAccount: AugmentedEvent<ApiType, [account: AccountId32], { account: AccountId32 }>;563 /**564 * On on-chain remark happened.565 **/566 Remarked: AugmentedEvent<ApiType, [sender: AccountId32, hash_: H256], { sender: AccountId32, hash_: H256 }>;567 /**568 * Generic event569 **/570 [key: string]: AugmentedEvent<ApiType>;571 };572 testUtils: {573 BatchCompleted: AugmentedEvent<ApiType, []>;574 ShouldRollback: AugmentedEvent<ApiType, []>;575 ValueIsSet: AugmentedEvent<ApiType, []>;576 /**577 * Generic event578 **/579 [key: string]: AugmentedEvent<ApiType>;580 };581 tokens: {582 /**583 * A balance was set by root.584 **/585 BalanceSet: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, free: u128, reserved: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, free: u128, reserved: u128 }>;586 /**587 * Deposited some balance into an account588 **/589 Deposited: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;590 /**591 * An account was removed whose balance was non-zero but below592 * ExistentialDeposit, resulting in an outright loss.593 **/594 DustLost: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;595 /**596 * An account was created with some free balance.597 **/598 Endowed: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;599 /**600 * Some locked funds were unlocked601 **/602 LockRemoved: AugmentedEvent<ApiType, [lockId: U8aFixed, currencyId: PalletForeignAssetsAssetIds, who: AccountId32], { lockId: U8aFixed, currencyId: PalletForeignAssetsAssetIds, who: AccountId32 }>;603 /**604 * Some funds are locked605 **/606 LockSet: AugmentedEvent<ApiType, [lockId: U8aFixed, currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { lockId: U8aFixed, currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;607 /**608 * Some balance was reserved (moved from free to reserved).609 **/610 Reserved: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;611 /**612 * Some reserved balance was repatriated (moved from reserved to613 * another account).614 **/615 ReserveRepatriated: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, from: AccountId32, to: AccountId32, amount: u128, status: FrameSupportTokensMiscBalanceStatus], { currencyId: PalletForeignAssetsAssetIds, from: AccountId32, to: AccountId32, amount: u128, status: FrameSupportTokensMiscBalanceStatus }>;616 /**617 * Some balances were slashed (e.g. due to mis-behavior)618 **/619 Slashed: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, freeAmount: u128, reservedAmount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, freeAmount: u128, reservedAmount: u128 }>;620 /**621 * The total issuance of an currency has been set622 **/623 TotalIssuanceSet: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, amount: u128], { currencyId: PalletForeignAssetsAssetIds, amount: u128 }>;624 /**625 * Transfer succeeded.626 **/627 Transfer: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, from: AccountId32, to: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, from: AccountId32, to: AccountId32, amount: u128 }>;628 /**629 * Some balance was unreserved (moved from reserved to free).630 **/631 Unreserved: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;632 /**633 * Some balances were withdrawn (e.g. pay for transaction fee)634 **/635 Withdrawn: AugmentedEvent<ApiType, [currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128], { currencyId: PalletForeignAssetsAssetIds, who: AccountId32, amount: u128 }>;636 /**637 * Generic event638 **/639 [key: string]: AugmentedEvent<ApiType>;640 };641 transactionPayment: {642 /**643 * A transaction fee `actual_fee`, of which `tip` was added to the minimum inclusion fee,644 * has been paid by `who`.645 **/646 TransactionFeePaid: AugmentedEvent<ApiType, [who: AccountId32, actualFee: u128, tip: u128], { who: AccountId32, actualFee: u128, tip: u128 }>;647 /**648 * Generic event649 **/650 [key: string]: AugmentedEvent<ApiType>;651 };652 treasury: {653 /**654 * Some funds have been allocated.655 **/656 Awarded: AugmentedEvent<ApiType, [proposalIndex: u32, award: u128, account: AccountId32], { proposalIndex: u32, award: u128, account: AccountId32 }>;657 /**658 * Some of our funds have been burnt.659 **/660 Burnt: AugmentedEvent<ApiType, [burntFunds: u128], { burntFunds: u128 }>;661 /**662 * Some funds have been deposited.663 **/664 Deposit: AugmentedEvent<ApiType, [value: u128], { value: u128 }>;665 /**666 * New proposal.667 **/668 Proposed: AugmentedEvent<ApiType, [proposalIndex: u32], { proposalIndex: u32 }>;669 /**670 * A proposal was rejected; funds were slashed.671 **/672 Rejected: AugmentedEvent<ApiType, [proposalIndex: u32, slashed: u128], { proposalIndex: u32, slashed: u128 }>;673 /**674 * Spending has finished; this is the amount that rolls over until next spend.675 **/676 Rollover: AugmentedEvent<ApiType, [rolloverBalance: u128], { rolloverBalance: u128 }>;677 /**678 * A new spend proposal has been approved.679 **/680 SpendApproved: AugmentedEvent<ApiType, [proposalIndex: u32, amount: u128, beneficiary: AccountId32], { proposalIndex: u32, amount: u128, beneficiary: AccountId32 }>;681 /**682 * We have ended a spend period and will now allocate funds.683 **/684 Spending: AugmentedEvent<ApiType, [budgetRemaining: u128], { budgetRemaining: u128 }>;685 /**686 * Generic event687 **/688 [key: string]: AugmentedEvent<ApiType>;689 };690 unique: {691 /**692 * Address was added to the allow list693 * 694 * # Arguments695 * * collection_id: ID of the affected collection.696 * * user: Address of the added account.697 **/698 AllowListAddressAdded: AugmentedEvent<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;699 /**700 * Address was removed from the allow list701 * 702 * # Arguments703 * * collection_id: ID of the affected collection.704 * * user: Address of the removed account.705 **/706 AllowListAddressRemoved: AugmentedEvent<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;707 /**708 * Collection admin was added709 * 710 * # Arguments711 * * collection_id: ID of the affected collection.712 * * admin: Admin address.713 **/714 CollectionAdminAdded: AugmentedEvent<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;715 /**716 * Collection admin was removed717 * 718 * # Arguments719 * * collection_id: ID of the affected collection.720 * * admin: Removed admin address.721 **/722 CollectionAdminRemoved: AugmentedEvent<ApiType, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;723 /**724 * Collection limits were set725 * 726 * # Arguments727 * * collection_id: ID of the affected collection.728 **/729 CollectionLimitSet: AugmentedEvent<ApiType, [u32]>;730 /**731 * Collection owned was changed732 * 733 * # Arguments734 * * collection_id: ID of the affected collection.735 * * owner: New owner address.736 **/737 CollectionOwnedChanged: AugmentedEvent<ApiType, [u32, AccountId32]>;738 /**739 * Collection permissions were set740 * 741 * # Arguments742 * * collection_id: ID of the affected collection.743 **/744 CollectionPermissionSet: AugmentedEvent<ApiType, [u32]>;745 /**746 * Collection sponsor was removed747 * 748 * # Arguments749 * * collection_id: ID of the affected collection.750 **/751 CollectionSponsorRemoved: AugmentedEvent<ApiType, [u32]>;752 /**753 * Collection sponsor was set754 * 755 * # Arguments756 * * collection_id: ID of the affected collection.757 * * owner: New sponsor address.758 **/759 CollectionSponsorSet: AugmentedEvent<ApiType, [u32, AccountId32]>;760 /**761 * New sponsor was confirm762 * 763 * # Arguments764 * * collection_id: ID of the affected collection.765 * * sponsor: New sponsor address.766 **/767 SponsorshipConfirmed: AugmentedEvent<ApiType, [u32, AccountId32]>;768 /**769 * Generic event770 **/771 [key: string]: AugmentedEvent<ApiType>;772 };773 vesting: {774 /**775 * Claimed vesting.776 **/777 Claimed: AugmentedEvent<ApiType, [who: AccountId32, amount: u128], { who: AccountId32, amount: u128 }>;778 /**779 * Added new vesting schedule.780 **/781 VestingScheduleAdded: AugmentedEvent<ApiType, [from: AccountId32, to: AccountId32, vestingSchedule: OrmlVestingVestingSchedule], { from: AccountId32, to: AccountId32, vestingSchedule: OrmlVestingVestingSchedule }>;782 /**783 * Updated vesting schedules.784 **/785 VestingSchedulesUpdated: AugmentedEvent<ApiType, [who: AccountId32], { who: AccountId32 }>;786 /**787 * Generic event788 **/789 [key: string]: AugmentedEvent<ApiType>;790 };791 xcmpQueue: {792 /**793 * Bad XCM format used.794 **/795 BadFormat: AugmentedEvent<ApiType, [messageHash: Option<H256>], { messageHash: Option<H256> }>;796 /**797 * Bad XCM version used.798 **/799 BadVersion: AugmentedEvent<ApiType, [messageHash: Option<H256>], { messageHash: Option<H256> }>;800 /**801 * Some XCM failed.802 **/803 Fail: AugmentedEvent<ApiType, [messageHash: Option<H256>, error: XcmV2TraitsError, weight: Weight], { messageHash: Option<H256>, error: XcmV2TraitsError, weight: Weight }>;804 /**805 * An XCM exceeded the individual message weight budget.806 **/807 OverweightEnqueued: AugmentedEvent<ApiType, [sender: u32, sentAt: u32, index: u64, required: Weight], { sender: u32, sentAt: u32, index: u64, required: Weight }>;808 /**809 * An XCM from the overweight queue was executed with the given actual weight used.810 **/811 OverweightServiced: AugmentedEvent<ApiType, [index: u64, used: Weight], { index: u64, used: Weight }>;812 /**813 * Some XCM was executed ok.814 **/815 Success: AugmentedEvent<ApiType, [messageHash: Option<H256>, weight: Weight], { messageHash: Option<H256>, weight: Weight }>;816 /**817 * An upward message was sent to the relay chain.818 **/819 UpwardMessageSent: AugmentedEvent<ApiType, [messageHash: Option<H256>], { messageHash: Option<H256> }>;820 /**821 * An HRMP message was sent to a sibling parachain.822 **/823 XcmpMessageSent: AugmentedEvent<ApiType, [messageHash: Option<H256>], { messageHash: Option<H256> }>;824 /**825 * Generic event826 **/827 [key: string]: AugmentedEvent<ApiType>;828 };829 xTokens: {830 /**831 * Transferred `MultiAsset` with fee.832 **/833 TransferredMultiAssets: AugmentedEvent<ApiType, [sender: AccountId32, assets: XcmV1MultiassetMultiAssets, fee: XcmV1MultiAsset, dest: XcmV1MultiLocation], { sender: AccountId32, assets: XcmV1MultiassetMultiAssets, fee: XcmV1MultiAsset, dest: XcmV1MultiLocation }>;834 /**835 * Generic event836 **/837 [key: string]: AugmentedEvent<ApiType>;838 };839 } // AugmentedEvents840} // declare moduletests/src/interfaces/augment-api-query.tsdiffbeforeafterboth--- a/tests/src/interfaces/augment-api-query.ts
+++ b/tests/src/interfaces/augment-api-query.ts
@@ -442,6 +442,10 @@
**/
tokensMinted: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<u32>, [u32]> & QueryableStorageEntry<ApiType, [u32]>;
/**
+ * Operator set by a wallet owner that could perform certain transactions on all tokens in the wallet.
+ **/
+ 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]>;
+ /**
* Generic query
**/
[key: string]: QueryableStorageEntry<ApiType>;
@@ -645,6 +649,10 @@
**/
totalSupply: AugmentedQuery<ApiType, (arg1: u32 | AnyNumber | Uint8Array, arg2: u32 | AnyNumber | Uint8Array) => Observable<u128>, [u32, u32]> & QueryableStorageEntry<ApiType, [u32, u32]>;
/**
+ * Operator set by a wallet owner that could perform certain transactions on all tokens in the wallet.
+ **/
+ 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]>;
+ /**
* Generic query
**/
[key: string]: QueryableStorageEntry<ApiType>;
tests/src/interfaces/augment-api-rpc.tsdiffbeforeafterboth--- a/tests/src/interfaces/augment-api-rpc.ts
+++ b/tests/src/interfaces/augment-api-rpc.ts
@@ -720,6 +720,10 @@
**/
effectiveCollectionLimits: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<UpDataStructsCollectionLimits>>>;
/**
+ * Tells whether an operator is approved by a given owner.
+ **/
+ 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>>>;
+ /**
* Get the last token ID created in a collection
**/
lastTokenId: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<u32>>;
tests/src/interfaces/augment-api-tx.tsdiffbeforeafterboth--- a/tests/src/interfaces/augment-api-tx.ts
+++ b/tests/src/interfaces/augment-api-tx.ts
@@ -1545,6 +1545,18 @@
**/
repartition: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, amount: u128 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, u32, u128]>;
/**
+ * Sets or unsets the approval of a given operator.
+ *
+ * An operator is allowed to transfer all tokens of the sender on their behalf.
+ *
+ * # Arguments
+ *
+ * * `owner`: Token owner
+ * * `operator`: Operator
+ * * `approve`: Is operator enabled or disabled
+ **/
+ setApprovalForAll: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, operator: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array, approve: bool | boolean | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, PalletEvmAccountBasicCrossAccountIdRepr, bool]>;
+ /**
* Set specific limits of a collection. Empty, or None fields mean chain default.
*
* # Permissions
tests/src/interfaces/default/types.tsdiffbeforeafterboth--- a/tests/src/interfaces/default/types.ts
+++ b/tests/src/interfaces/default/types.ts
@@ -1286,6 +1286,8 @@
readonly asTransfer: ITuple<[u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;
readonly isApproved: boolean;
readonly asApproved: ITuple<[u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;
+ readonly isApprovedForAll: boolean;
+ readonly asApprovedForAll: ITuple<[u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, bool]>;
readonly isCollectionPropertySet: boolean;
readonly asCollectionPropertySet: ITuple<[u32, Bytes]>;
readonly isCollectionPropertyDeleted: boolean;
@@ -1296,7 +1298,7 @@
readonly asTokenPropertyDeleted: ITuple<[u32, u32, Bytes]>;
readonly isPropertyPermissionSet: boolean;
readonly asPropertyPermissionSet: ITuple<[u32, Bytes]>;
- readonly type: 'CollectionCreated' | 'CollectionDestroyed' | 'ItemCreated' | 'ItemDestroyed' | 'Transfer' | 'Approved' | 'CollectionPropertySet' | 'CollectionPropertyDeleted' | 'TokenPropertySet' | 'TokenPropertyDeleted' | 'PropertyPermissionSet';
+ readonly type: 'CollectionCreated' | 'CollectionDestroyed' | 'ItemCreated' | 'ItemDestroyed' | 'Transfer' | 'Approved' | 'ApprovedForAll' | 'CollectionPropertySet' | 'CollectionPropertyDeleted' | 'TokenPropertySet' | 'TokenPropertyDeleted' | 'PropertyPermissionSet';
}
/** @name PalletConfigurationCall */
@@ -1603,7 +1605,8 @@
readonly isFungibleItemsDontHaveData: boolean;
readonly isFungibleDisallowsNesting: boolean;
readonly isSettingPropertiesNotAllowed: boolean;
- readonly type: 'NotFungibleDataUsedToMintFungibleCollectionToken' | 'FungibleItemsHaveNoId' | 'FungibleItemsDontHaveData' | 'FungibleDisallowsNesting' | 'SettingPropertiesNotAllowed';
+ readonly isSettingApprovalForAllNotAllowed: boolean;
+ readonly type: 'NotFungibleDataUsedToMintFungibleCollectionToken' | 'FungibleItemsHaveNoId' | 'FungibleItemsDontHaveData' | 'FungibleDisallowsNesting' | 'SettingPropertiesNotAllowed' | 'SettingApprovalForAllNotAllowed';
}
/** @name PalletInflationCall */
@@ -2309,7 +2312,13 @@
readonly tokenId: u32;
readonly amount: u128;
} & Struct;
- 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';
+ readonly isSetApprovalForAll: boolean;
+ readonly asSetApprovalForAll: {
+ readonly collectionId: u32;
+ readonly operator: PalletEvmAccountBasicCrossAccountIdRepr;
+ readonly approve: bool;
+ } & Struct;
+ 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';
}
/** @name PalletUniqueError */
tests/src/interfaces/lookup.tsdiffbeforeafterboth--- a/tests/src/interfaces/lookup.ts
+++ b/tests/src/interfaces/lookup.ts
@@ -1046,6 +1046,7 @@
ItemDestroyed: '(u32,u32,PalletEvmAccountBasicCrossAccountIdRepr,u128)',
Transfer: '(u32,u32,PalletEvmAccountBasicCrossAccountIdRepr,PalletEvmAccountBasicCrossAccountIdRepr,u128)',
Approved: '(u32,u32,PalletEvmAccountBasicCrossAccountIdRepr,PalletEvmAccountBasicCrossAccountIdRepr,u128)',
+ ApprovedForAll: '(u32,PalletEvmAccountBasicCrossAccountIdRepr,PalletEvmAccountBasicCrossAccountIdRepr,bool)',
CollectionPropertySet: '(u32,Bytes)',
CollectionPropertyDeleted: '(u32,Bytes)',
TokenPropertySet: '(u32,u32,Bytes)',
@@ -1054,7 +1055,7 @@
}
},
/**
- * Lookup99: pallet_structure::pallet::Event<T>
+ * Lookup100: pallet_structure::pallet::Event<T>
**/
PalletStructureEvent: {
_enum: {
@@ -1062,7 +1063,7 @@
}
},
/**
- * Lookup100: pallet_rmrk_core::pallet::Event<T>
+ * Lookup101: pallet_rmrk_core::pallet::Event<T>
**/
PalletRmrkCoreEvent: {
_enum: {
@@ -1139,7 +1140,7 @@
}
},
/**
- * Lookup101: rmrk_traits::nft::AccountIdOrCollectionNftTuple<sp_core::crypto::AccountId32>
+ * Lookup102: rmrk_traits::nft::AccountIdOrCollectionNftTuple<sp_core::crypto::AccountId32>
**/
RmrkTraitsNftAccountIdOrCollectionNftTuple: {
_enum: {
@@ -2302,7 +2303,12 @@
repartition: {
collectionId: 'u32',
tokenId: 'u32',
- amount: 'u128'
+ amount: 'u128',
+ },
+ set_approval_for_all: {
+ collectionId: 'u32',
+ operator: 'PalletEvmAccountBasicCrossAccountIdRepr',
+ approve: 'bool'
}
}
},
@@ -3445,7 +3451,7 @@
* Lookup430: pallet_fungible::pallet::Error<T>
**/
PalletFungibleError: {
- _enum: ['NotFungibleDataUsedToMintFungibleCollectionToken', 'FungibleItemsHaveNoId', 'FungibleItemsDontHaveData', 'FungibleDisallowsNesting', 'SettingPropertiesNotAllowed']
+ _enum: ['NotFungibleDataUsedToMintFungibleCollectionToken', 'FungibleItemsHaveNoId', 'FungibleItemsDontHaveData', 'FungibleDisallowsNesting', 'SettingPropertiesNotAllowed', 'SettingApprovalForAllNotAllowed']
},
/**
* Lookup431: pallet_refungible::ItemData
tests/src/interfaces/types-lookup.tsdiffbeforeafterboth--- a/tests/src/interfaces/types-lookup.ts
+++ b/tests/src/interfaces/types-lookup.ts
@@ -1182,6 +1182,8 @@
readonly asTransfer: ITuple<[u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;
readonly isApproved: boolean;
readonly asApproved: ITuple<[u32, u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, u128]>;
+ readonly isApprovedForAll: boolean;
+ readonly asApprovedForAll: ITuple<[u32, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmAccountBasicCrossAccountIdRepr, bool]>;
readonly isCollectionPropertySet: boolean;
readonly asCollectionPropertySet: ITuple<[u32, Bytes]>;
readonly isCollectionPropertyDeleted: boolean;
@@ -1192,17 +1194,17 @@
readonly asTokenPropertyDeleted: ITuple<[u32, u32, Bytes]>;
readonly isPropertyPermissionSet: boolean;
readonly asPropertyPermissionSet: ITuple<[u32, Bytes]>;
- readonly type: 'CollectionCreated' | 'CollectionDestroyed' | 'ItemCreated' | 'ItemDestroyed' | 'Transfer' | 'Approved' | 'CollectionPropertySet' | 'CollectionPropertyDeleted' | 'TokenPropertySet' | 'TokenPropertyDeleted' | 'PropertyPermissionSet';
+ readonly type: 'CollectionCreated' | 'CollectionDestroyed' | 'ItemCreated' | 'ItemDestroyed' | 'Transfer' | 'Approved' | 'ApprovedForAll' | 'CollectionPropertySet' | 'CollectionPropertyDeleted' | 'TokenPropertySet' | 'TokenPropertyDeleted' | 'PropertyPermissionSet';
}
- /** @name PalletStructureEvent (99) */
+ /** @name PalletStructureEvent (100) */
interface PalletStructureEvent extends Enum {
readonly isExecuted: boolean;
readonly asExecuted: Result<Null, SpRuntimeDispatchError>;
readonly type: 'Executed';
}
- /** @name PalletRmrkCoreEvent (100) */
+ /** @name PalletRmrkCoreEvent (101) */
interface PalletRmrkCoreEvent extends Enum {
readonly isCollectionCreated: boolean;
readonly asCollectionCreated: {
@@ -1292,7 +1294,7 @@
readonly type: 'CollectionCreated' | 'CollectionDestroyed' | 'IssuerChanged' | 'CollectionLocked' | 'NftMinted' | 'NftBurned' | 'NftSent' | 'NftAccepted' | 'NftRejected' | 'PropertySet' | 'ResourceAdded' | 'ResourceRemoval' | 'ResourceAccepted' | 'ResourceRemovalAccepted' | 'PrioritySet';
}
- /** @name RmrkTraitsNftAccountIdOrCollectionNftTuple (101) */
+ /** @name RmrkTraitsNftAccountIdOrCollectionNftTuple (102) */
interface RmrkTraitsNftAccountIdOrCollectionNftTuple extends Enum {
readonly isAccountId: boolean;
readonly asAccountId: AccountId32;
@@ -2539,7 +2541,13 @@
readonly tokenId: u32;
readonly amount: u128;
} & Struct;
- 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';
+ readonly isSetApprovalForAll: boolean;
+ readonly asSetApprovalForAll: {
+ readonly collectionId: u32;
+ readonly operator: PalletEvmAccountBasicCrossAccountIdRepr;
+ readonly approve: bool;
+ } & Struct;
+ 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';
}
/** @name UpDataStructsCollectionMode (240) */
@@ -3655,7 +3663,8 @@
readonly isFungibleItemsDontHaveData: boolean;
readonly isFungibleDisallowsNesting: boolean;
readonly isSettingPropertiesNotAllowed: boolean;
- readonly type: 'NotFungibleDataUsedToMintFungibleCollectionToken' | 'FungibleItemsHaveNoId' | 'FungibleItemsDontHaveData' | 'FungibleDisallowsNesting' | 'SettingPropertiesNotAllowed';
+ readonly isSettingApprovalForAllNotAllowed: boolean;
+ readonly type: 'NotFungibleDataUsedToMintFungibleCollectionToken' | 'FungibleItemsHaveNoId' | 'FungibleItemsDontHaveData' | 'FungibleDisallowsNesting' | 'SettingPropertiesNotAllowed' | 'SettingApprovalForAllNotAllowed';
}
/** @name PalletRefungibleItemData (431) */
tests/src/interfaces/unique/definitions.tsdiffbeforeafterboth--- a/tests/src/interfaces/unique/definitions.ts
+++ b/tests/src/interfaces/unique/definitions.ts
@@ -175,5 +175,10 @@
[collectionParam, tokenParam],
'Option<u128>',
),
+ isApprovedForAll: fun(
+ 'Tells whether an operator is approved by a given owner.',
+ [collectionParam, crossAccountParam('owner'), crossAccountParam('operator')],
+ 'Option<bool>',
+ ),
},
};
tests/src/util/playgrounds/unique.tsdiffbeforeafterboth--- a/tests/src/util/playgrounds/unique.ts
+++ b/tests/src/util/playgrounds/unique.ts
@@ -1413,6 +1413,32 @@
getTokenObject(_collectionId: number, _tokenId: number): any {
return null;
}
+
+ /**
+ * Tells whether an operator is approved by a given owner.
+ * @param collectionId ID of collection
+ * @param owner owner address
+ * @param operator operator addrees
+ * @returns true if operator is enabled
+ */
+ async isApprovedForAll(collectionId: number, owner: ICrossAccountId, operator: ICrossAccountId): Promise<boolean> {
+ return (await this.helper.callRpc('api.rpc.unique.isApprovedForAll', [collectionId, owner, operator])).toJSON();
+ }
+
+ /** Sets or unsets the approval of a given operator.
+ * An operator is allowed to transfer all tokens of the sender on their behalf.
+ * @param operator Operator
+ * @param approved Is operator enabled or disabled
+ * @returns ```true``` if extrinsic success, otherwise ```false```
+ */
+ async setApprovalForAll(signer: TSigner, collectionId: number, operator: ICrossAccountId, approved: boolean): Promise<boolean> {
+ const result = await this.helper.executeExtrinsic(
+ signer,
+ 'api.tx.unique.setApprovalForAll', [collectionId, operator, approved],
+ true,
+ );
+ return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'ApprovedForAll');
+ }
}