difftreelog
feat Add `collection_admins` method to eth collection.
in: master
19 files changed
pallets/common/src/erc.rsdiffbeforeafterboth--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -580,7 +580,7 @@
/// Get collection owner.
///
- /// @return Tuble with sponsor address and his substrate mirror.
+ /// @return Tuple with sponsor address and his substrate mirror.
/// If address is canonical then substrate mirror is zero and vice versa.
fn collection_owner(&self) -> Result<(address, uint256)> {
Ok(convert_cross_account_to_tuple::<T>(
@@ -616,13 +616,16 @@
// .map_err(dispatch_to_evm::<T>)
// }
- // TODO: need implement AbiWriter for &Vec<T>
- // fn collection_admins(&self) -> Result<Vec<(address, uint256)>> {
- // let result = pallet_common::IsAdmin::<T>::iter_prefix((self.id,))
- // .map(|(admin, _)| pallet_common::eth::convert_cross_account_to_tuple::<T>(&admin))
- // .collect();
- // Ok(result)
- // }
+ /// Get collection administrators
+ ///
+ /// @return Vector of tuples with admins address and his substrate mirror.
+ /// If address is canonical then substrate mirror is zero and vice versa.
+ fn collection_admins(&self) -> Result<Vec<(address, uint256)>> {
+ let result = crate::IsAdmin::<T>::iter_prefix((self.id,))
+ .map(|(admin, _)| crate::eth::convert_cross_account_to_tuple::<T>(&admin))
+ .collect();
+ Ok(result)
+ }
}
/// ### Note
pallets/evm-contract-helpers/src/stubs/ContractHelpers.rawdiffbeforeafterbothbinary blob — no preview
pallets/fungible/src/stubs/UniqueFungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/fungible/src/stubs/UniqueFungible.soldiffbeforeafterboth--- a/pallets/fungible/src/stubs/UniqueFungible.sol
+++ b/pallets/fungible/src/stubs/UniqueFungible.sol
@@ -18,7 +18,7 @@
}
/// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0x62e22290
+/// @dev the ERC-165 identifier for this interface is 0x3af103fb
contract Collection is Dummy, ERC165 {
/// Set collection property.
///
@@ -282,7 +282,7 @@
/// Get collection owner.
///
- /// @return Tuble with sponsor address and his substrate mirror.
+ /// @return Tuple with sponsor address and his substrate mirror.
/// If address is canonical then substrate mirror is zero and vice versa.
/// @dev EVM selector for this function is: 0xdf727d3b,
/// or in textual repr: collectionOwner()
@@ -303,6 +303,18 @@
newOwner;
dummy = 0;
}
+
+ /// Get collection administrators
+ ///
+ /// @return Vector of tuples with admins address and his substrate mirror.
+ /// If address is canonical then substrate mirror is zero and vice versa.
+ /// @dev EVM selector for this function is: 0x5813216b,
+ /// or in textual repr: collectionAdmins()
+ function collectionAdmins() public view returns (Tuple6[] memory) {
+ require(false, stub_error);
+ dummy;
+ return new Tuple6[](0);
+ }
}
/// @dev the ERC-165 identifier for this interface is 0x63034ac5
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
@@ -91,7 +91,7 @@
}
/// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0x62e22290
+/// @dev the ERC-165 identifier for this interface is 0x3af103fb
contract Collection is Dummy, ERC165 {
/// Set collection property.
///
@@ -355,7 +355,7 @@
/// Get collection owner.
///
- /// @return Tuble with sponsor address and his substrate mirror.
+ /// @return Tuple with sponsor address and his substrate mirror.
/// If address is canonical then substrate mirror is zero and vice versa.
/// @dev EVM selector for this function is: 0xdf727d3b,
/// or in textual repr: collectionOwner()
@@ -376,6 +376,18 @@
newOwner;
dummy = 0;
}
+
+ /// Get collection administrators
+ ///
+ /// @return Vector of tuples with admins address and his substrate mirror.
+ /// If address is canonical then substrate mirror is zero and vice versa.
+ /// @dev EVM selector for this function is: 0x5813216b,
+ /// or in textual repr: collectionAdmins()
+ function collectionAdmins() public view returns (Tuple17[] memory) {
+ require(false, stub_error);
+ dummy;
+ return new Tuple17[](0);
+ }
}
/// @dev anonymous struct
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
@@ -91,7 +91,7 @@
}
/// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0x62e22290
+/// @dev the ERC-165 identifier for this interface is 0x3af103fb
contract Collection is Dummy, ERC165 {
/// Set collection property.
///
@@ -355,7 +355,7 @@
/// Get collection owner.
///
- /// @return Tuble with sponsor address and his substrate mirror.
+ /// @return Tuple with sponsor address and his substrate mirror.
/// If address is canonical then substrate mirror is zero and vice versa.
/// @dev EVM selector for this function is: 0xdf727d3b,
/// or in textual repr: collectionOwner()
@@ -376,6 +376,18 @@
newOwner;
dummy = 0;
}
+
+ /// Get collection administrators
+ ///
+ /// @return Vector of tuples with admins address and his substrate mirror.
+ /// If address is canonical then substrate mirror is zero and vice versa.
+ /// @dev EVM selector for this function is: 0x5813216b,
+ /// or in textual repr: collectionAdmins()
+ function collectionAdmins() public view returns (Tuple17[] memory) {
+ require(false, stub_error);
+ dummy;
+ return new Tuple17[](0);
+ }
}
/// @dev anonymous struct
pallets/refungible/src/stubs/UniqueRefungibleToken.rawdiffbeforeafterbothbinary blob — no preview
pallets/unique/src/eth/stubs/CollectionHelpers.rawdiffbeforeafterbothbinary blob — no preview
tests/src/eth/api/UniqueFungible.soldiffbeforeafterboth1// SPDX-License-Identifier: OTHER2// This code is automatically generated34pragma solidity >=0.8.0 <0.9.0;56/// @dev common stubs holder7interface Dummy {89}1011interface ERC165 is Dummy {12 function supportsInterface(bytes4 interfaceID) external view returns (bool);13}1415/// @title A contract that allows you to work with collections.16/// @dev the ERC-165 identifier for this interface is 0x62e2229017interface Collection is Dummy, ERC165 {18 /// Set collection property.19 ///20 /// @param key Property key.21 /// @param value Propery value.22 /// @dev EVM selector for this function is: 0x2f073f66,23 /// or in textual repr: setCollectionProperty(string,bytes)24 function setCollectionProperty(string memory key, bytes memory value) external;2526 /// Delete collection property.27 ///28 /// @param key Property key.29 /// @dev EVM selector for this function is: 0x7b7debce,30 /// or in textual repr: deleteCollectionProperty(string)31 function deleteCollectionProperty(string memory key) external;3233 /// Get collection property.34 ///35 /// @dev Throws error if key not found.36 ///37 /// @param key Property key.38 /// @return bytes The property corresponding to the key.39 /// @dev EVM selector for this function is: 0xcf24fd6d,40 /// or in textual repr: collectionProperty(string)41 function collectionProperty(string memory key) external view returns (bytes memory);4243 /// Set the sponsor of the collection.44 ///45 /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.46 ///47 /// @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.48 /// @dev EVM selector for this function is: 0x7623402e,49 /// or in textual repr: setCollectionSponsor(address)50 function setCollectionSponsor(address sponsor) external;5152 /// Whether there is a pending sponsor.53 /// @dev EVM selector for this function is: 0x058ac185,54 /// or in textual repr: hasCollectionPendingSponsor()55 function hasCollectionPendingSponsor() external view returns (bool);5657 /// Collection sponsorship confirmation.58 ///59 /// @dev After setting the sponsor for the collection, it must be confirmed with this function.60 /// @dev EVM selector for this function is: 0x3c50e97a,61 /// or in textual repr: confirmCollectionSponsorship()62 function confirmCollectionSponsorship() external;6364 /// Remove collection sponsor.65 /// @dev EVM selector for this function is: 0x6e0326a3,66 /// or in textual repr: removeCollectionSponsor()67 function removeCollectionSponsor() external;6869 /// Get current sponsor.70 ///71 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.72 /// @dev EVM selector for this function is: 0x6ec0a9f1,73 /// or in textual repr: collectionSponsor()74 function collectionSponsor() external view returns (Tuple6 memory);7576 /// Set limits for the collection.77 /// @dev Throws error if limit not found.78 /// @param limit Name of the limit. Valid names:79 /// "accountTokenOwnershipLimit",80 /// "sponsoredDataSize",81 /// "sponsoredDataRateLimit",82 /// "tokenLimit",83 /// "sponsorTransferTimeout",84 /// "sponsorApproveTimeout"85 /// @param value Value of the limit.86 /// @dev EVM selector for this function is: 0x6a3841db,87 /// or in textual repr: setCollectionLimit(string,uint32)88 function setCollectionLimit(string memory limit, uint32 value) external;8990 /// Set limits for the collection.91 /// @dev Throws error if limit not found.92 /// @param limit Name of the limit. Valid names:93 /// "ownerCanTransfer",94 /// "ownerCanDestroy",95 /// "transfersEnabled"96 /// @param value Value of the limit.97 /// @dev EVM selector for this function is: 0x993b7fba,98 /// or in textual repr: setCollectionLimit(string,bool)99 function setCollectionLimit(string memory limit, bool value) external;100101 /// Get contract address.102 /// @dev EVM selector for this function is: 0xf6b4dfb4,103 /// or in textual repr: contractAddress()104 function contractAddress() external view returns (address);105106 /// Add collection admin.107 /// @param newAdmin Address of the added administrator.108 /// @dev EVM selector for this function is: 0x92e462c7,109 /// or in textual repr: addCollectionAdmin(address)110 function addCollectionAdmin(address newAdmin) external;111112 /// Remove collection admin.113 ///114 /// @param admin Address of the removed administrator.115 /// @dev EVM selector for this function is: 0xfafd7b42,116 /// or in textual repr: removeCollectionAdmin(address)117 function removeCollectionAdmin(address admin) external;118119 /// Toggle accessibility of collection nesting.120 ///121 /// @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'122 /// @dev EVM selector for this function is: 0x112d4586,123 /// or in textual repr: setCollectionNesting(bool)124 function setCollectionNesting(bool enable) external;125126 /// Toggle accessibility of collection nesting.127 ///128 /// @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'129 /// @param collections Addresses of collections that will be available for nesting.130 /// @dev EVM selector for this function is: 0x64872396,131 /// or in textual repr: setCollectionNesting(bool,address[])132 function setCollectionNesting(bool enable, address[] memory collections) external;133134 /// Set the collection access method.135 /// @param mode Access mode136 /// 0 for Normal137 /// 1 for AllowList138 /// @dev EVM selector for this function is: 0x41835d4c,139 /// or in textual repr: setCollectionAccess(uint8)140 function setCollectionAccess(uint8 mode) external;141142 /// Checks that user allowed to operate with collection.143 ///144 /// @param user User address to check.145 /// @dev EVM selector for this function is: 0xd63a8e11,146 /// or in textual repr: allowed(address)147 function allowed(address user) external view returns (bool);148149 /// Add the user to the allowed list.150 ///151 /// @param user Address of a trusted user.152 /// @dev EVM selector for this function is: 0x67844fe6,153 /// or in textual repr: addToCollectionAllowList(address)154 function addToCollectionAllowList(address user) external;155156 /// Remove the user from the allowed list.157 ///158 /// @param user Address of a removed user.159 /// @dev EVM selector for this function is: 0x85c51acb,160 /// or in textual repr: removeFromCollectionAllowList(address)161 function removeFromCollectionAllowList(address user) external;162163 /// Switch permission for minting.164 ///165 /// @param mode Enable if "true".166 /// @dev EVM selector for this function is: 0x00018e84,167 /// or in textual repr: setCollectionMintMode(bool)168 function setCollectionMintMode(bool mode) external;169170 /// Check that account is the owner or admin of the collection171 ///172 /// @param user account to verify173 /// @return "true" if account is the owner or admin174 /// @dev EVM selector for this function is: 0x9811b0c7,175 /// or in textual repr: isOwnerOrAdmin(address)176 function isOwnerOrAdmin(address user) external view returns (bool);177178 /// Returns collection type179 ///180 /// @return `Fungible` or `NFT` or `ReFungible`181 /// @dev EVM selector for this function is: 0xd34b55b8,182 /// or in textual repr: uniqueCollectionType()183 function uniqueCollectionType() external view returns (string memory);184185 /// Get collection owner.186 ///187 /// @return Tuble with sponsor address and his substrate mirror.188 /// If address is canonical then substrate mirror is zero and vice versa.189 /// @dev EVM selector for this function is: 0xdf727d3b,190 /// or in textual repr: collectionOwner()191 function collectionOwner() external view returns (Tuple6 memory);192193 /// Changes collection owner to another account194 ///195 /// @dev Owner can be changed only by current owner196 /// @param newOwner new owner account197 /// @dev EVM selector for this function is: 0x4f53e226,198 /// or in textual repr: changeCollectionOwner(address)199 function changeCollectionOwner(address newOwner) external;200}201202/// @dev the ERC-165 identifier for this interface is 0x63034ac5203interface ERC20UniqueExtensions is Dummy, ERC165 {204 /// Burn tokens from account205 /// @dev Function that burns an `amount` of the tokens of a given account,206 /// deducting from the sender's allowance for said account.207 /// @param from The account whose tokens will be burnt.208 /// @param amount The amount that will be burnt.209 /// @dev EVM selector for this function is: 0x79cc6790,210 /// or in textual repr: burnFrom(address,uint256)211 function burnFrom(address from, uint256 amount) external returns (bool);212213 /// Mint tokens for multiple accounts.214 /// @param amounts array of pairs of account address and amount215 /// @dev EVM selector for this function is: 0x1acf2d55,216 /// or in textual repr: mintBulk((address,uint256)[])217 function mintBulk(Tuple6[] memory amounts) external returns (bool);218}219220/// @dev anonymous struct221struct Tuple6 {222 address field_0;223 uint256 field_1;224}225226/// @dev the ERC-165 identifier for this interface is 0x40c10f19227interface ERC20Mintable is Dummy, ERC165 {228 /// Mint tokens for `to` account.229 /// @param to account that will receive minted tokens230 /// @param amount amount of tokens to mint231 /// @dev EVM selector for this function is: 0x40c10f19,232 /// or in textual repr: mint(address,uint256)233 function mint(address to, uint256 amount) external returns (bool);234}235236/// @dev inlined interface237interface ERC20Events {238 event Transfer(address indexed from, address indexed to, uint256 value);239 event Approval(address indexed owner, address indexed spender, uint256 value);240}241242/// @dev the ERC-165 identifier for this interface is 0x942e8b22243interface ERC20 is Dummy, ERC165, ERC20Events {244 /// @dev EVM selector for this function is: 0x06fdde03,245 /// or in textual repr: name()246 function name() external view returns (string memory);247248 /// @dev EVM selector for this function is: 0x95d89b41,249 /// or in textual repr: symbol()250 function symbol() external view returns (string memory);251252 /// @dev EVM selector for this function is: 0x18160ddd,253 /// or in textual repr: totalSupply()254 function totalSupply() external view returns (uint256);255256 /// @dev EVM selector for this function is: 0x313ce567,257 /// or in textual repr: decimals()258 function decimals() external view returns (uint8);259260 /// @dev EVM selector for this function is: 0x70a08231,261 /// or in textual repr: balanceOf(address)262 function balanceOf(address owner) external view returns (uint256);263264 /// @dev EVM selector for this function is: 0xa9059cbb,265 /// or in textual repr: transfer(address,uint256)266 function transfer(address to, uint256 amount) external returns (bool);267268 /// @dev EVM selector for this function is: 0x23b872dd,269 /// or in textual repr: transferFrom(address,address,uint256)270 function transferFrom(271 address from,272 address to,273 uint256 amount274 ) external returns (bool);275276 /// @dev EVM selector for this function is: 0x095ea7b3,277 /// or in textual repr: approve(address,uint256)278 function approve(address spender, uint256 amount) external returns (bool);279280 /// @dev EVM selector for this function is: 0xdd62ed3e,281 /// or in textual repr: allowance(address,address)282 function allowance(address owner, address spender) external view returns (uint256);283}284285interface UniqueFungible is Dummy, ERC165, ERC20, ERC20Mintable, ERC20UniqueExtensions, Collection {}1// SPDX-License-Identifier: OTHER2// This code is automatically generated34pragma solidity >=0.8.0 <0.9.0;56/// @dev common stubs holder7interface Dummy {89}1011interface ERC165 is Dummy {12 function supportsInterface(bytes4 interfaceID) external view returns (bool);13}1415/// @title A contract that allows you to work with collections.16/// @dev the ERC-165 identifier for this interface is 0x3af103fb17interface Collection is Dummy, ERC165 {18 /// Set collection property.19 ///20 /// @param key Property key.21 /// @param value Propery value.22 /// @dev EVM selector for this function is: 0x2f073f66,23 /// or in textual repr: setCollectionProperty(string,bytes)24 function setCollectionProperty(string memory key, bytes memory value) external;2526 /// Delete collection property.27 ///28 /// @param key Property key.29 /// @dev EVM selector for this function is: 0x7b7debce,30 /// or in textual repr: deleteCollectionProperty(string)31 function deleteCollectionProperty(string memory key) external;3233 /// Get collection property.34 ///35 /// @dev Throws error if key not found.36 ///37 /// @param key Property key.38 /// @return bytes The property corresponding to the key.39 /// @dev EVM selector for this function is: 0xcf24fd6d,40 /// or in textual repr: collectionProperty(string)41 function collectionProperty(string memory key) external view returns (bytes memory);4243 /// Set the sponsor of the collection.44 ///45 /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.46 ///47 /// @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.48 /// @dev EVM selector for this function is: 0x7623402e,49 /// or in textual repr: setCollectionSponsor(address)50 function setCollectionSponsor(address sponsor) external;5152 /// Whether there is a pending sponsor.53 /// @dev EVM selector for this function is: 0x058ac185,54 /// or in textual repr: hasCollectionPendingSponsor()55 function hasCollectionPendingSponsor() external view returns (bool);5657 /// Collection sponsorship confirmation.58 ///59 /// @dev After setting the sponsor for the collection, it must be confirmed with this function.60 /// @dev EVM selector for this function is: 0x3c50e97a,61 /// or in textual repr: confirmCollectionSponsorship()62 function confirmCollectionSponsorship() external;6364 /// Remove collection sponsor.65 /// @dev EVM selector for this function is: 0x6e0326a3,66 /// or in textual repr: removeCollectionSponsor()67 function removeCollectionSponsor() external;6869 /// Get current sponsor.70 ///71 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.72 /// @dev EVM selector for this function is: 0x6ec0a9f1,73 /// or in textual repr: collectionSponsor()74 function collectionSponsor() external view returns (Tuple6 memory);7576 /// Set limits for the collection.77 /// @dev Throws error if limit not found.78 /// @param limit Name of the limit. Valid names:79 /// "accountTokenOwnershipLimit",80 /// "sponsoredDataSize",81 /// "sponsoredDataRateLimit",82 /// "tokenLimit",83 /// "sponsorTransferTimeout",84 /// "sponsorApproveTimeout"85 /// @param value Value of the limit.86 /// @dev EVM selector for this function is: 0x6a3841db,87 /// or in textual repr: setCollectionLimit(string,uint32)88 function setCollectionLimit(string memory limit, uint32 value) external;8990 /// Set limits for the collection.91 /// @dev Throws error if limit not found.92 /// @param limit Name of the limit. Valid names:93 /// "ownerCanTransfer",94 /// "ownerCanDestroy",95 /// "transfersEnabled"96 /// @param value Value of the limit.97 /// @dev EVM selector for this function is: 0x993b7fba,98 /// or in textual repr: setCollectionLimit(string,bool)99 function setCollectionLimit(string memory limit, bool value) external;100101 /// Get contract address.102 /// @dev EVM selector for this function is: 0xf6b4dfb4,103 /// or in textual repr: contractAddress()104 function contractAddress() external view returns (address);105106 /// Add collection admin.107 /// @param newAdmin Address of the added administrator.108 /// @dev EVM selector for this function is: 0x92e462c7,109 /// or in textual repr: addCollectionAdmin(address)110 function addCollectionAdmin(address newAdmin) external;111112 /// Remove collection admin.113 ///114 /// @param admin Address of the removed administrator.115 /// @dev EVM selector for this function is: 0xfafd7b42,116 /// or in textual repr: removeCollectionAdmin(address)117 function removeCollectionAdmin(address admin) external;118119 /// Toggle accessibility of collection nesting.120 ///121 /// @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'122 /// @dev EVM selector for this function is: 0x112d4586,123 /// or in textual repr: setCollectionNesting(bool)124 function setCollectionNesting(bool enable) external;125126 /// Toggle accessibility of collection nesting.127 ///128 /// @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'129 /// @param collections Addresses of collections that will be available for nesting.130 /// @dev EVM selector for this function is: 0x64872396,131 /// or in textual repr: setCollectionNesting(bool,address[])132 function setCollectionNesting(bool enable, address[] memory collections) external;133134 /// Set the collection access method.135 /// @param mode Access mode136 /// 0 for Normal137 /// 1 for AllowList138 /// @dev EVM selector for this function is: 0x41835d4c,139 /// or in textual repr: setCollectionAccess(uint8)140 function setCollectionAccess(uint8 mode) external;141142 /// Checks that user allowed to operate with collection.143 ///144 /// @param user User address to check.145 /// @dev EVM selector for this function is: 0xd63a8e11,146 /// or in textual repr: allowed(address)147 function allowed(address user) external view returns (bool);148149 /// Add the user to the allowed list.150 ///151 /// @param user Address of a trusted user.152 /// @dev EVM selector for this function is: 0x67844fe6,153 /// or in textual repr: addToCollectionAllowList(address)154 function addToCollectionAllowList(address user) external;155156 /// Remove the user from the allowed list.157 ///158 /// @param user Address of a removed user.159 /// @dev EVM selector for this function is: 0x85c51acb,160 /// or in textual repr: removeFromCollectionAllowList(address)161 function removeFromCollectionAllowList(address user) external;162163 /// Switch permission for minting.164 ///165 /// @param mode Enable if "true".166 /// @dev EVM selector for this function is: 0x00018e84,167 /// or in textual repr: setCollectionMintMode(bool)168 function setCollectionMintMode(bool mode) external;169170 /// Check that account is the owner or admin of the collection171 ///172 /// @param user account to verify173 /// @return "true" if account is the owner or admin174 /// @dev EVM selector for this function is: 0x9811b0c7,175 /// or in textual repr: isOwnerOrAdmin(address)176 function isOwnerOrAdmin(address user) external view returns (bool);177178 /// Returns collection type179 ///180 /// @return `Fungible` or `NFT` or `ReFungible`181 /// @dev EVM selector for this function is: 0xd34b55b8,182 /// or in textual repr: uniqueCollectionType()183 function uniqueCollectionType() external view returns (string memory);184185 /// Get collection owner.186 ///187 /// @return Tuple with sponsor address and his substrate mirror.188 /// If address is canonical then substrate mirror is zero and vice versa.189 /// @dev EVM selector for this function is: 0xdf727d3b,190 /// or in textual repr: collectionOwner()191 function collectionOwner() external view returns (Tuple6 memory);192193 /// Changes collection owner to another account194 ///195 /// @dev Owner can be changed only by current owner196 /// @param newOwner new owner account197 /// @dev EVM selector for this function is: 0x4f53e226,198 /// or in textual repr: changeCollectionOwner(address)199 function changeCollectionOwner(address newOwner) external;200201 /// Get collection administrators202 ///203 /// @return Vector of tuples with admins address and his substrate mirror.204 /// If address is canonical then substrate mirror is zero and vice versa.205 /// @dev EVM selector for this function is: 0x5813216b,206 /// or in textual repr: collectionAdmins()207 function collectionAdmins() external view returns (Tuple6[] memory);208}209210/// @dev the ERC-165 identifier for this interface is 0x63034ac5211interface ERC20UniqueExtensions is Dummy, ERC165 {212 /// Burn tokens from account213 /// @dev Function that burns an `amount` of the tokens of a given account,214 /// deducting from the sender's allowance for said account.215 /// @param from The account whose tokens will be burnt.216 /// @param amount The amount that will be burnt.217 /// @dev EVM selector for this function is: 0x79cc6790,218 /// or in textual repr: burnFrom(address,uint256)219 function burnFrom(address from, uint256 amount) external returns (bool);220221 /// Mint tokens for multiple accounts.222 /// @param amounts array of pairs of account address and amount223 /// @dev EVM selector for this function is: 0x1acf2d55,224 /// or in textual repr: mintBulk((address,uint256)[])225 function mintBulk(Tuple6[] memory amounts) external returns (bool);226}227228/// @dev anonymous struct229struct Tuple6 {230 address field_0;231 uint256 field_1;232}233234/// @dev the ERC-165 identifier for this interface is 0x40c10f19235interface ERC20Mintable is Dummy, ERC165 {236 /// Mint tokens for `to` account.237 /// @param to account that will receive minted tokens238 /// @param amount amount of tokens to mint239 /// @dev EVM selector for this function is: 0x40c10f19,240 /// or in textual repr: mint(address,uint256)241 function mint(address to, uint256 amount) external returns (bool);242}243244/// @dev inlined interface245interface ERC20Events {246 event Transfer(address indexed from, address indexed to, uint256 value);247 event Approval(address indexed owner, address indexed spender, uint256 value);248}249250/// @dev the ERC-165 identifier for this interface is 0x942e8b22251interface ERC20 is Dummy, ERC165, ERC20Events {252 /// @dev EVM selector for this function is: 0x06fdde03,253 /// or in textual repr: name()254 function name() external view returns (string memory);255256 /// @dev EVM selector for this function is: 0x95d89b41,257 /// or in textual repr: symbol()258 function symbol() external view returns (string memory);259260 /// @dev EVM selector for this function is: 0x18160ddd,261 /// or in textual repr: totalSupply()262 function totalSupply() external view returns (uint256);263264 /// @dev EVM selector for this function is: 0x313ce567,265 /// or in textual repr: decimals()266 function decimals() external view returns (uint8);267268 /// @dev EVM selector for this function is: 0x70a08231,269 /// or in textual repr: balanceOf(address)270 function balanceOf(address owner) external view returns (uint256);271272 /// @dev EVM selector for this function is: 0xa9059cbb,273 /// or in textual repr: transfer(address,uint256)274 function transfer(address to, uint256 amount) external returns (bool);275276 /// @dev EVM selector for this function is: 0x23b872dd,277 /// or in textual repr: transferFrom(address,address,uint256)278 function transferFrom(279 address from,280 address to,281 uint256 amount282 ) external returns (bool);283284 /// @dev EVM selector for this function is: 0x095ea7b3,285 /// or in textual repr: approve(address,uint256)286 function approve(address spender, uint256 amount) external returns (bool);287288 /// @dev EVM selector for this function is: 0xdd62ed3e,289 /// or in textual repr: allowance(address,address)290 function allowance(address owner, address spender) external view returns (uint256);291}292293interface UniqueFungible is Dummy, ERC165, ERC20, ERC20Mintable, ERC20UniqueExtensions, Collection {}tests/src/eth/api/UniqueNFT.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueNFT.sol
+++ b/tests/src/eth/api/UniqueNFT.sol
@@ -62,7 +62,7 @@
}
/// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0x62e22290
+/// @dev the ERC-165 identifier for this interface is 0x3af103fb
interface Collection is Dummy, ERC165 {
/// Set collection property.
///
@@ -233,7 +233,7 @@
/// Get collection owner.
///
- /// @return Tuble with sponsor address and his substrate mirror.
+ /// @return Tuple with sponsor address and his substrate mirror.
/// If address is canonical then substrate mirror is zero and vice versa.
/// @dev EVM selector for this function is: 0xdf727d3b,
/// or in textual repr: collectionOwner()
@@ -246,6 +246,14 @@
/// @dev EVM selector for this function is: 0x4f53e226,
/// or in textual repr: changeCollectionOwner(address)
function changeCollectionOwner(address newOwner) external;
+
+ /// Get collection administrators
+ ///
+ /// @return Vector of tuples with admins address and his substrate mirror.
+ /// If address is canonical then substrate mirror is zero and vice versa.
+ /// @dev EVM selector for this function is: 0x5813216b,
+ /// or in textual repr: collectionAdmins()
+ function collectionAdmins() external view returns (Tuple17[] memory);
}
/// @dev anonymous struct
tests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueRefungible.sol
+++ b/tests/src/eth/api/UniqueRefungible.sol
@@ -62,7 +62,7 @@
}
/// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0x62e22290
+/// @dev the ERC-165 identifier for this interface is 0x3af103fb
interface Collection is Dummy, ERC165 {
/// Set collection property.
///
@@ -233,7 +233,7 @@
/// Get collection owner.
///
- /// @return Tuble with sponsor address and his substrate mirror.
+ /// @return Tuple with sponsor address and his substrate mirror.
/// If address is canonical then substrate mirror is zero and vice versa.
/// @dev EVM selector for this function is: 0xdf727d3b,
/// or in textual repr: collectionOwner()
@@ -246,6 +246,14 @@
/// @dev EVM selector for this function is: 0x4f53e226,
/// or in textual repr: changeCollectionOwner(address)
function changeCollectionOwner(address newOwner) external;
+
+ /// Get collection administrators
+ ///
+ /// @return Vector of tuples with admins address and his substrate mirror.
+ /// If address is canonical then substrate mirror is zero and vice versa.
+ /// @dev EVM selector for this function is: 0x5813216b,
+ /// or in textual repr: collectionAdmins()
+ function collectionAdmins() external view returns (Tuple17[] memory);
}
/// @dev anonymous struct
tests/src/eth/collectionAdmin.test.tsdiffbeforeafterboth--- a/tests/src/eth/collectionAdmin.test.ts
+++ b/tests/src/eth/collectionAdmin.test.ts
@@ -14,6 +14,7 @@
// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
import {IKeyringPair} from '@polkadot/types/types';
+import {IEthCrossAccountId} from '../util/playgrounds/types';
import {usingEthPlaygrounds, itEth, expect, EthUniqueHelper} from './util';
async function recordEthFee(helper: EthUniqueHelper, userAddress: string, call: () => Promise<any>) {
@@ -68,11 +69,31 @@
const newAdmin = helper.eth.createAccount();
const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
+
expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.false;
await collectionEvm.methods.addCollectionAdmin(newAdmin).send();
expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.true;
});
+
+ itEth.skip('Check adminlist', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+
+ const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
+ const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
+
+ const admin1 = helper.eth.createAccount();
+ const [admin2] = await helper.arrange.createAccounts([10n], donor);
+ await collectionEvm.methods.addCollectionAdmin(admin1).send();
+ await collectionEvm.methods.addCollectionAdminSubstrate(admin2.addressRaw).send();
+ const adminListRpc = await helper.collection.getAdmins(collectionId);
+ let adminListEth = await collectionEvm.methods.collectionAdmins().call();
+ adminListEth = adminListEth.map((element: IEthCrossAccountId) => {
+ return helper.address.convertCrossAccountFromEthCrossAcoount(element);
+ });
+ expect(adminListRpc).to.be.like(adminListEth);
+ });
+
itEth('(!negative tests!) Add admin by ADMIN is not allowed', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
tests/src/eth/fungibleAbi.jsondiffbeforeafterboth--- a/tests/src/eth/fungibleAbi.json
+++ b/tests/src/eth/fungibleAbi.json
@@ -126,6 +126,23 @@
},
{
"inputs": [],
+ "name": "collectionAdmins",
+ "outputs": [
+ {
+ "components": [
+ { "internalType": "address", "name": "field_0", "type": "address" },
+ { "internalType": "uint256", "name": "field_1", "type": "uint256" }
+ ],
+ "internalType": "struct Tuple6[]",
+ "name": "",
+ "type": "tuple[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
"name": "collectionOwner",
"outputs": [
{
tests/src/eth/nonFungibleAbi.jsondiffbeforeafterboth--- a/tests/src/eth/nonFungibleAbi.json
+++ b/tests/src/eth/nonFungibleAbi.json
@@ -156,6 +156,23 @@
},
{
"inputs": [],
+ "name": "collectionAdmins",
+ "outputs": [
+ {
+ "components": [
+ { "internalType": "address", "name": "field_0", "type": "address" },
+ { "internalType": "uint256", "name": "field_1", "type": "uint256" }
+ ],
+ "internalType": "struct Tuple17[]",
+ "name": "",
+ "type": "tuple[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
"name": "collectionOwner",
"outputs": [
{
tests/src/eth/reFungibleAbi.jsondiffbeforeafterboth--- a/tests/src/eth/reFungibleAbi.json
+++ b/tests/src/eth/reFungibleAbi.json
@@ -156,6 +156,23 @@
},
{
"inputs": [],
+ "name": "collectionAdmins",
+ "outputs": [
+ {
+ "components": [
+ { "internalType": "address", "name": "field_0", "type": "address" },
+ { "internalType": "uint256", "name": "field_1", "type": "uint256" }
+ ],
+ "internalType": "struct Tuple17[]",
+ "name": "",
+ "type": "tuple[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
"name": "collectionOwner",
"outputs": [
{
tests/src/util/playgrounds/types.tsdiffbeforeafterboth--- a/tests/src/util/playgrounds/types.ts
+++ b/tests/src/util/playgrounds/types.ts
@@ -70,6 +70,13 @@
ethereum?: TEthereumAccount;
}
+export interface IEthCrossAccountId {
+ 0: TEthereumAccount;
+ 1: TSubstrateAccount;
+ field_0: TEthereumAccount;
+ field_1: TSubstrateAccount;
+}
+
export interface ICollectionLimits {
accountTokenOwnershipLimit?: number | null;
sponsoredDataSize?: number | null;
tests/src/util/playgrounds/unique.tsdiffbeforeafterboth--- a/tests/src/util/playgrounds/unique.ts
+++ b/tests/src/util/playgrounds/unique.ts
@@ -7,9 +7,11 @@
import {ApiPromise, WsProvider, Keyring} from '@polkadot/api';
import {ApiInterfaceEvents, SignerOptions} from '@polkadot/api/types';
-import {encodeAddress, decodeAddress, keccakAsHex, evmToAddress, addressToEvm} from '@polkadot/util-crypto';
+import {encodeAddress, decodeAddress, keccakAsHex, evmToAddress, addressToEvm, base58Encode, blake2AsU8a} from '@polkadot/util-crypto';
import {IKeyringPair} from '@polkadot/types/types';
-import {IApiListeners, IBlock, IEvent, IChainProperties, ICollectionCreationOptions, ICollectionLimits, ICollectionPermissions, ICrossAccountId, ICrossAccountIdLower, ILogger, INestingPermissions, IProperty, IStakingInfo, ISchedulerOptions, ISubstrateBalance, IToken, ITokenPropertyPermission, ITransactionResult, IUniqueHelperLog, TApiAllowedListeners, TEthereumAccount, TSigner, TSubstrateAccount, IForeignAssetMetadata, TNetworks, MoonbeamAssetInfo, DemocracyStandardAccountVote, AcalaAssetMetadata} from './types';
+import {IApiListeners, IBlock, IEvent, IChainProperties, ICollectionCreationOptions, ICollectionLimits, ICollectionPermissions, ICrossAccountId, ICrossAccountIdLower, ILogger, INestingPermissions, IProperty, IStakingInfo, ISchedulerOptions, ISubstrateBalance, IToken, ITokenPropertyPermission, ITransactionResult, IUniqueHelperLog, TApiAllowedListeners, TEthereumAccount, TSigner, TSubstrateAccount, IForeignAssetMetadata, TNetworks, MoonbeamAssetInfo, DemocracyStandardAccountVote, AcalaAssetMetadata, IEthCrossAccountId} from './types';
+import {hexToU8a} from '@polkadot/util/hex';
+import {u8aConcat} from '@polkadot/util/u8a';
export class CrossAccountId implements ICrossAccountId {
Substrate?: TSubstrateAccount;
@@ -2309,6 +2311,73 @@
return siblingPrefix + encodedParaId + suffix;
}
+
+ /**
+ * Encode key to substrate address
+ * @param key key for encoding address
+ * @param ss58Format prefix for encoding to the address of the corresponding network
+ * @returns encoded substrate address
+ */
+ encodeSubstrateAddress (key: Uint8Array | string | bigint, ss58Format = 42): string {
+ const u8a :Uint8Array = typeof key === 'string'
+ ? hexToU8a(key)
+ : typeof key === 'bigint'
+ ? hexToU8a(key.toString(16))
+ : key;
+
+ if (ss58Format < 0 || ss58Format > 16383 || [46, 47].includes(ss58Format)) {
+ throw new Error(`ss58Format is not valid, received ${typeof ss58Format} "${ss58Format}"`);
+ }
+
+ const allowedDecodedLengths = [1, 2, 4, 8, 32, 33];
+ if (!allowedDecodedLengths.includes(u8a.length)) {
+ throw new Error(`key length is not valid, received ${u8a.length}, valid values are ${allowedDecodedLengths.join(', ')}`);
+ }
+
+ const u8aPrefix = ss58Format < 64
+ ? new Uint8Array([ss58Format])
+ : new Uint8Array([
+ ((ss58Format & 0xfc) >> 2) | 0x40,
+ (ss58Format >> 8) | ((ss58Format & 0x03) << 6),
+ ]);
+
+ const input = u8aConcat(u8aPrefix, u8a);
+
+ return base58Encode(u8aConcat(
+ input,
+ blake2AsU8a(input).subarray(0, [32, 33].includes(u8a.length) ? 2 : 1),
+ ));
+ }
+
+ /**
+ * Restore substrate address from bigint representation
+ * @param number decimal representation of substrate address
+ * @returns substrate address
+ */
+ restoreCrossAccountFromBigInt(number: bigint): TSubstrateAccount {
+ if (this.helper.api === null) {
+ throw 'Not connected';
+ }
+ const res = this.helper.api.registry.createType('AccountId', '0x' + number.toString(16).padStart(64, '0')).toJSON();
+ if (res === undefined || res === null) {
+ throw 'Restore address error';
+ }
+ return res.toString();
+ }
+
+ /**
+ * Convert etherium cross account id to substrate cross account id
+ * @param ethCrossAccount etherium cross account
+ * @returns substrate cross account id
+ */
+ convertCrossAccountFromEthCrossAcoount(ethCrossAccount: IEthCrossAccountId): ICrossAccountId {
+ if (ethCrossAccount.field_1 === '0') {
+ return {Ethereum: ethCrossAccount.field_0.toLocaleLowerCase()};
+ }
+
+ const ss58 = this.restoreCrossAccountFromBigInt(BigInt(ethCrossAccount.field_1));
+ return {Substrate: ss58};
+ }
}
class StakingGroup extends HelperGroup<UniqueHelper> {