difftreelog
feat add mint_bulk_cross
in: master
15 files changed
pallets/common/src/eth.rsdiffbeforeafterboth--- a/pallets/common/src/eth.rs
+++ b/pallets/common/src/eth.rs
@@ -631,3 +631,12 @@
}
}
}
+
+/// Token minting parameters
+#[derive(AbiCoder, Default, Debug)]
+pub struct MintTokenData {
+ /// Minted token owner
+ pub owner: CrossAddress,
+ /// Minted token properties
+ pub properties: Vec<Property>,
+}
pallets/nonfungible/src/erc.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -981,13 +981,41 @@
Ok(true)
}
+ /// @notice Function to mint a token.
+ /// @param data Array of pairs of token owner and token's properties for minted token
+ #[weight(<SelfWeightOf<T>>::create_multiple_items(data.len() as u32) + <SelfWeightOf<T>>::set_token_properties(data.len() as u32))]
+ fn mint_bulk_cross(&mut self, caller: Caller, data: Vec<eth::MintTokenData>) -> Result<bool> {
+ let caller = T::CrossAccountId::from_eth(caller);
+ let budget = self
+ .recorder
+ .weight_calls_budget(<StructureWeight<T>>::find_parent());
+
+ let mut create_nft_data = Vec::with_capacity(data.len());
+ for eth::MintTokenData { owner, properties } in data {
+ let owner = owner.into_sub_cross_account::<T>()?;
+ create_nft_data.push(CreateItemData::<T> {
+ properties: properties
+ .into_iter()
+ .map(|property| property.try_into())
+ .collect::<Result<Vec<_>>>()?
+ .try_into()
+ .map_err(|_| "too many properties")?,
+ owner,
+ });
+ }
+
+ <Pallet<T>>::create_multiple_items(self, &caller, create_nft_data, &budget)
+ .map_err(dispatch_to_evm::<T>)?;
+ Ok(true)
+ }
+
/// @notice Function to mint multiple tokens with the given tokenUris.
/// @dev `tokenIds` is array of pairs of token ID and token URI. Token IDs should be consecutive
/// numbers and first number should be obtained with `nextTokenId` method
/// @param to The new owner
/// @param tokens array of pairs of token ID and token URI for minted tokens
#[solidity(hide, rename_selector = "mintBulkWithTokenURI")]
- #[weight(<SelfWeightOf<T>>::create_multiple_items(tokens.len() as u32) + <SelfWeightOf<T>>::set_token_properties(tokens.len() as u32))]
+ #[weight(<SelfWeightOf<T>>::create_multiple_items(tokens.len() as u32) + <SelfWeightOf<T>>::set_token_properties(tokens.len() as u32))]
fn mint_bulk_with_token_uri(
&mut self,
caller: Caller,
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
@@ -800,7 +800,7 @@
}
/// @title Unique extensions for ERC721.
-/// @dev the ERC-165 identifier for this interface is 0x307b061a
+/// @dev the ERC-165 identifier for this interface is 0x9b397d16
contract ERC721UniqueExtensions is Dummy, ERC165 {
/// @notice A descriptive name for a collection of NFTs in this contract
/// @dev EVM selector for this function is: 0x06fdde03,
@@ -997,6 +997,17 @@
// return false;
// }
+ /// @notice Function to mint a token.
+ /// @param data Array of pairs of token owner and token's properties for minted token
+ /// @dev EVM selector for this function is: 0xab427b0c,
+ /// or in textual repr: mintBulkCross(((address,uint256),(string,bytes)[])[])
+ function mintBulkCross(MintTokenData[] memory data) public returns (bool) {
+ require(false, stub_error);
+ data;
+ dummy = 0;
+ return false;
+ }
+
// /// @notice Function to mint multiple tokens with the given tokenUris.
// /// @dev `tokenIds` is array of pairs of token ID and token URI. Token IDs should be consecutive
// /// numbers and first number should be obtained with `nextTokenId` method
@@ -1044,6 +1055,11 @@
string uri;
}
+struct MintTokenData {
+ CrossAddress owner;
+ Property[] properties;
+}
+
/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
/// @dev See https://eips.ethereum.org/EIPS/eip-721
/// @dev the ERC-165 identifier for this interface is 0x780e9d63
pallets/refungible/src/erc.rsdiffbeforeafterboth--- a/pallets/refungible/src/erc.rs
+++ b/pallets/refungible/src/erc.rs
@@ -1021,6 +1021,43 @@
Ok(true)
}
+ /// @notice Function to mint a token.
+ /// @param tokenProperties Properties of minted token
+ #[weight(<SelfWeightOf<T>>::create_multiple_items(token_properties.len() as u32) + <SelfWeightOf<T>>::set_token_properties(token_properties.len() as u32))]
+ fn mint_bulk_cross(
+ &mut self,
+ caller: Caller,
+ token_properties: Vec<eth::MintTokenData>,
+ ) -> Result<bool> {
+ let caller = T::CrossAccountId::from_eth(caller);
+ let budget = self
+ .recorder
+ .weight_calls_budget(<StructureWeight<T>>::find_parent());
+
+ let mut create_rft_data = Vec::with_capacity(token_properties.len());
+ for eth::MintTokenData { owner, properties } in token_properties {
+ let owner = owner.into_sub_cross_account::<T>()?;
+ let users: BoundedBTreeMap<_, _, _> = [(owner, 1)]
+ .into_iter()
+ .collect::<BTreeMap<_, _>>()
+ .try_into()
+ .map_err(|_| "too many users")?;
+ create_rft_data.push(CreateItemData::<T> {
+ properties: properties
+ .into_iter()
+ .map(|property| property.try_into())
+ .collect::<Result<Vec<_>>>()?
+ .try_into()
+ .map_err(|_| "too many properties")?,
+ users,
+ });
+ }
+
+ <Pallet<T>>::create_multiple_items(self, &caller, create_rft_data, &budget)
+ .map_err(dispatch_to_evm::<T>)?;
+ Ok(true)
+ }
+
/// @notice Function to mint multiple tokens with the given tokenUris.
/// @dev `tokenIds` is array of pairs of token ID and token URI. Token IDs should be consecutive
/// numbers and first number should be obtained with `nextTokenId` method
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
@@ -800,7 +800,7 @@
}
/// @title Unique extensions for ERC721.
-/// @dev the ERC-165 identifier for this interface is 0x95c0f66c
+/// @dev the ERC-165 identifier for this interface is 0x3e828d60
contract ERC721UniqueExtensions is Dummy, ERC165 {
/// @notice A descriptive name for a collection of NFTs in this contract
/// @dev EVM selector for this function is: 0x06fdde03,
@@ -986,6 +986,17 @@
// return false;
// }
+ /// @notice Function to mint a token.
+ /// @param tokenProperties Properties of minted token
+ /// @dev EVM selector for this function is: 0xab427b0c,
+ /// or in textual repr: mintBulkCross(((address,uint256),(string,bytes)[])[])
+ function mintBulkCross(MintTokenData[] memory tokenProperties) public returns (bool) {
+ require(false, stub_error);
+ tokenProperties;
+ dummy = 0;
+ return false;
+ }
+
// /// @notice Function to mint multiple tokens with the given tokenUris.
// /// @dev `tokenIds` is array of pairs of token ID and token URI. Token IDs should be consecutive
// /// numbers and first number should be obtained with `nextTokenId` method
@@ -1045,6 +1056,11 @@
string uri;
}
+struct MintTokenData {
+ CrossAddress owner;
+ Property[] properties;
+}
+
/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
/// @dev See https://eips.ethereum.org/EIPS/eip-721
/// @dev the ERC-165 identifier for this interface is 0x780e9d63
pallets/unique/src/eth/stubs/CollectionHelpers.rawdiffbeforeafterbothbinary blob — no preview
pallets/unique/src/eth/stubs/CollectionHelpers.soldiffbeforeafterboth1// SPDX-License-Identifier: OTHER2// This code is automatically generated34pragma solidity >=0.8.0 <0.9.0;56/// @dev common stubs holder7contract Dummy {8 uint8 dummy;9 string stub_error = "this contract is implemented in native";10}1112contract ERC165 is Dummy {13 function supportsInterface(bytes4 interfaceID) external view returns (bool) {14 require(false, stub_error);15 interfaceID;16 return true;17 }18}1920/// @dev inlined interface21contract CollectionHelpersEvents {22 event CollectionCreated(address indexed owner, address indexed collectionId);23 event CollectionDestroyed(address indexed collectionId);24 event CollectionChanged(address indexed collectionId);25}2627/// @title Contract, which allows users to operate with collections28/// @dev the ERC-165 identifier for this interface is 0x4135fff129contract CollectionHelpers is Dummy, ERC165, CollectionHelpersEvents {30 /// Create a collection31 /// @return address Address of the newly created collection32 /// @dev EVM selector for this function is: 0xa765ee5b,33 /// or in textual repr: createCollection(((address,uint256),string,string,string,uint8,uint8,(string,bytes)[],(string,(uint8,bool)[])[],(address,uint256)[],(bool,bool,address[]),(uint8,uint256)[],uint8))34 function createCollection(CreateCollectionData memory data) public payable returns (address) {35 require(false, stub_error);36 data;37 dummy = 0;38 return 0x0000000000000000000000000000000000000000;39 }4041 /// Create an NFT collection42 /// @param name Name of the collection43 /// @param description Informative description of the collection44 /// @param tokenPrefix Token prefix to represent the collection tokens in UI and user applications45 /// @return address Address of the newly created collection46 /// @dev EVM selector for this function is: 0x844af658,47 /// or in textual repr: createNFTCollection(string,string,string)48 function createNFTCollection(49 string memory name,50 string memory description,51 string memory tokenPrefix52 ) public payable returns (address) {53 require(false, stub_error);54 name;55 description;56 tokenPrefix;57 dummy = 0;58 return 0x0000000000000000000000000000000000000000;59 }6061 // /// Create an NFT collection62 // /// @param name Name of the collection63 // /// @param description Informative description of the collection64 // /// @param tokenPrefix Token prefix to represent the collection tokens in UI and user applications65 // /// @return address Address of the newly created collection66 // /// @dev EVM selector for this function is: 0xe34a6844,67 // /// or in textual repr: createNonfungibleCollection(string,string,string)68 // function createNonfungibleCollection(string memory name, string memory description, string memory tokenPrefix) public payable returns (address) {69 // require(false, stub_error);70 // name;71 // description;72 // tokenPrefix;73 // dummy = 0;74 // return 0x0000000000000000000000000000000000000000;75 // }7677 /// @dev EVM selector for this function is: 0xab173450,78 /// or in textual repr: createRFTCollection(string,string,string)79 function createRFTCollection(80 string memory name,81 string memory description,82 string memory tokenPrefix83 ) public payable returns (address) {84 require(false, stub_error);85 name;86 description;87 tokenPrefix;88 dummy = 0;89 return 0x0000000000000000000000000000000000000000;90 }9192 /// @dev EVM selector for this function is: 0x7335b79f,93 /// or in textual repr: createFTCollection(string,uint8,string,string)94 function createFTCollection(95 string memory name,96 uint8 decimals,97 string memory description,98 string memory tokenPrefix99 ) public payable returns (address) {100 require(false, stub_error);101 name;102 decimals;103 description;104 tokenPrefix;105 dummy = 0;106 return 0x0000000000000000000000000000000000000000;107 }108109 /// @dev EVM selector for this function is: 0x85624258,110 /// or in textual repr: makeCollectionERC721MetadataCompatible(address,string)111 function makeCollectionERC721MetadataCompatible(address collection, string memory baseUri) public {112 require(false, stub_error);113 collection;114 baseUri;115 dummy = 0;116 }117118 /// @dev EVM selector for this function is: 0x564e321f,119 /// or in textual repr: destroyCollection(address)120 function destroyCollection(address collectionAddress) public {121 require(false, stub_error);122 collectionAddress;123 dummy = 0;124 }125126 /// Check if a collection exists127 /// @param collectionAddress Address of the collection in question128 /// @return bool Does the collection exist?129 /// @dev EVM selector for this function is: 0xc3de1494,130 /// or in textual repr: isCollectionExist(address)131 function isCollectionExist(address collectionAddress) public view returns (bool) {132 require(false, stub_error);133 collectionAddress;134 dummy;135 return false;136 }137138 /// @dev EVM selector for this function is: 0xd23a7ab1,139 /// or in textual repr: collectionCreationFee()140 function collectionCreationFee() public view returns (uint256) {141 require(false, stub_error);142 dummy;143 return 0;144 }145146 /// Returns address of a collection.147 /// @param collectionId - CollectionId of the collection148 /// @return eth mirror address of the collection149 /// @dev EVM selector for this function is: 0x2e716683,150 /// or in textual repr: collectionAddress(uint32)151 function collectionAddress(uint32 collectionId) public view returns (address) {152 require(false, stub_error);153 collectionId;154 dummy;155 return 0x0000000000000000000000000000000000000000;156 }157158 /// Returns collectionId of a collection.159 /// @param collectionAddress - Eth address of the collection160 /// @return collectionId of the collection161 /// @dev EVM selector for this function is: 0xb5cb7498,162 /// or in textual repr: collectionId(address)163 function collectionId(address collectionAddress) public view returns (uint32) {164 require(false, stub_error);165 collectionAddress;166 dummy;167 return 0;168 }169}170171/// Collection properties172struct CreateCollectionData {173 /// Collection sponsor174 CrossAddress pending_sponsor;175 /// Collection name176 string name;177 /// Collection description178 string description;179 /// Token prefix180 string token_prefix;181 /// Token type (NFT, FT or RFT)182 CollectionMode mode;183 /// Fungible token precision184 uint8 decimals;185 /// Custom Properties186 Property[] properties;187 /// Permissions for token properties188 TokenPropertyPermission[] token_property_permissions;189 /// Collection admins190 CrossAddress[] admin_list;191 /// Nesting settings192 CollectionNestingAndPermission nesting_settings;193 /// Collection limits194 CollectionLimitValue[] limits;195 /// Extra collection flags196 CollectionFlags flags;197}198199/// Cross account struct200type CollectionFlags is uint8;201202library CollectionFlagsLib {203 /// Tokens in foreign collections can be transferred, but not burnt204 CollectionFlags constant foreignField = CollectionFlags.wrap(128);205 /// Supports ERC721Metadata206 CollectionFlags constant erc721metadataField = CollectionFlags.wrap(64);207 /// External collections can't be managed using `unique` api208 CollectionFlags constant externalField = CollectionFlags.wrap(1);209210 /// Reserved bits211 function reservedField(uint8 value) public pure returns (CollectionFlags) {212 require(value < 1 << 5, "out of bound value");213 return CollectionFlags.wrap(value << 1);214 }215}216217/// [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.218struct CollectionLimitValue {219 CollectionLimitField field;220 uint256 value;221}222223/// [`CollectionLimits`](up_data_structs::CollectionLimits) fields representation for EVM.224enum CollectionLimitField {225 /// How many tokens can a user have on one account.226 AccountTokenOwnership,227 /// How many bytes of data are available for sponsorship.228 SponsoredDataSize,229 /// In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]230 SponsoredDataRateLimit,231 /// How many tokens can be mined into this collection.232 TokenLimit,233 /// Timeouts for transfer sponsoring.234 SponsorTransferTimeout,235 /// Timeout for sponsoring an approval in passed blocks.236 SponsorApproveTimeout,237 /// Whether the collection owner of the collection can send tokens (which belong to other users).238 OwnerCanTransfer,239 /// Can the collection owner burn other people's tokens.240 OwnerCanDestroy,241 /// Is it possible to send tokens from this collection between users.242 TransferEnabled243}244245/// Nested collections and permissions246struct CollectionNestingAndPermission {247 /// Owner of token can nest tokens under it.248 bool token_owner;249 /// Admin of token collection can nest tokens under token.250 bool collection_admin;251 /// If set - only tokens from specified collections can be nested.252 address[] restricted;253}254255/// Cross account struct256struct CrossAddress {257 address eth;258 uint256 sub;259}260261/// Ethereum representation of Token Property Permissions.262struct TokenPropertyPermission {263 /// Token property key.264 string key;265 /// Token property permissions.266 PropertyPermission[] permissions;267}268269/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value.270struct PropertyPermission {271 /// TokenPermission field.272 TokenPermissionField code;273 /// TokenPermission value.274 bool value;275}276277/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.278enum TokenPermissionField {279 /// Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]280 Mutable,281 /// Change permission for the collection administrator. See [`up_data_structs::PropertyPermission::token_owner`]282 TokenOwner,283 /// Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]284 CollectionAdmin285}286287/// Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).288struct Property {289 string key;290 bytes value;291}292293/// Type of tokens in collection294enum CollectionMode {295 /// Fungible296 Fungible,297 /// Nonfungible298 Nonfungible,299 /// Refungible300 Refungible301}1// SPDX-License-Identifier: OTHER2// This code is automatically generated34pragma solidity >=0.8.0 <0.9.0;56/// @dev common stubs holder7contract Dummy {8 uint8 dummy;9 string stub_error = "this contract is implemented in native";10}1112contract ERC165 is Dummy {13 function supportsInterface(bytes4 interfaceID) external view returns (bool) {14 require(false, stub_error);15 interfaceID;16 return true;17 }18}1920/// @dev inlined interface21contract CollectionHelpersEvents {22 event CollectionCreated(address indexed owner, address indexed collectionId);23 event CollectionDestroyed(address indexed collectionId);24 event CollectionChanged(address indexed collectionId);25}2627/// @title Contract, which allows users to operate with collections28/// @dev the ERC-165 identifier for this interface is 0x94e5af0d29contract CollectionHelpers is Dummy, ERC165, CollectionHelpersEvents {30 /// Create a collection31 /// @return address Address of the newly created collection32 /// @dev EVM selector for this function is: 0x72b5bea7,33 /// or in textual repr: createCollection((string,string,string,uint8,uint8,(string,bytes)[],(string,(uint8,bool)[])[],(address,uint256)[],(bool,bool,address[]),(uint8,uint256)[],(address,uint256),uint8))34 function createCollection(CreateCollectionData memory data) public payable returns (address) {35 require(false, stub_error);36 data;37 dummy = 0;38 return 0x0000000000000000000000000000000000000000;39 }4041 /// Create an NFT collection42 /// @param name Name of the collection43 /// @param description Informative description of the collection44 /// @param tokenPrefix Token prefix to represent the collection tokens in UI and user applications45 /// @return address Address of the newly created collection46 /// @dev EVM selector for this function is: 0x844af658,47 /// or in textual repr: createNFTCollection(string,string,string)48 function createNFTCollection(49 string memory name,50 string memory description,51 string memory tokenPrefix52 ) public payable returns (address) {53 require(false, stub_error);54 name;55 description;56 tokenPrefix;57 dummy = 0;58 return 0x0000000000000000000000000000000000000000;59 }6061 // /// Create an NFT collection62 // /// @param name Name of the collection63 // /// @param description Informative description of the collection64 // /// @param tokenPrefix Token prefix to represent the collection tokens in UI and user applications65 // /// @return address Address of the newly created collection66 // /// @dev EVM selector for this function is: 0xe34a6844,67 // /// or in textual repr: createNonfungibleCollection(string,string,string)68 // function createNonfungibleCollection(string memory name, string memory description, string memory tokenPrefix) public payable returns (address) {69 // require(false, stub_error);70 // name;71 // description;72 // tokenPrefix;73 // dummy = 0;74 // return 0x0000000000000000000000000000000000000000;75 // }7677 /// @dev EVM selector for this function is: 0xab173450,78 /// or in textual repr: createRFTCollection(string,string,string)79 function createRFTCollection(80 string memory name,81 string memory description,82 string memory tokenPrefix83 ) public payable returns (address) {84 require(false, stub_error);85 name;86 description;87 tokenPrefix;88 dummy = 0;89 return 0x0000000000000000000000000000000000000000;90 }9192 /// @dev EVM selector for this function is: 0x7335b79f,93 /// or in textual repr: createFTCollection(string,uint8,string,string)94 function createFTCollection(95 string memory name,96 uint8 decimals,97 string memory description,98 string memory tokenPrefix99 ) public payable returns (address) {100 require(false, stub_error);101 name;102 decimals;103 description;104 tokenPrefix;105 dummy = 0;106 return 0x0000000000000000000000000000000000000000;107 }108109 /// @dev EVM selector for this function is: 0x85624258,110 /// or in textual repr: makeCollectionERC721MetadataCompatible(address,string)111 function makeCollectionERC721MetadataCompatible(address collection, string memory baseUri) public {112 require(false, stub_error);113 collection;114 baseUri;115 dummy = 0;116 }117118 /// @dev EVM selector for this function is: 0x564e321f,119 /// or in textual repr: destroyCollection(address)120 function destroyCollection(address collectionAddress) public {121 require(false, stub_error);122 collectionAddress;123 dummy = 0;124 }125126 /// Check if a collection exists127 /// @param collectionAddress Address of the collection in question128 /// @return bool Does the collection exist?129 /// @dev EVM selector for this function is: 0xc3de1494,130 /// or in textual repr: isCollectionExist(address)131 function isCollectionExist(address collectionAddress) public view returns (bool) {132 require(false, stub_error);133 collectionAddress;134 dummy;135 return false;136 }137138 /// @dev EVM selector for this function is: 0xd23a7ab1,139 /// or in textual repr: collectionCreationFee()140 function collectionCreationFee() public view returns (uint256) {141 require(false, stub_error);142 dummy;143 return 0;144 }145146 /// Returns address of a collection.147 /// @param collectionId - CollectionId of the collection148 /// @return eth mirror address of the collection149 /// @dev EVM selector for this function is: 0x2e716683,150 /// or in textual repr: collectionAddress(uint32)151 function collectionAddress(uint32 collectionId) public view returns (address) {152 require(false, stub_error);153 collectionId;154 dummy;155 return 0x0000000000000000000000000000000000000000;156 }157158 /// Returns collectionId of a collection.159 /// @param collectionAddress - Eth address of the collection160 /// @return collectionId of the collection161 /// @dev EVM selector for this function is: 0xb5cb7498,162 /// or in textual repr: collectionId(address)163 function collectionId(address collectionAddress) public view returns (uint32) {164 require(false, stub_error);165 collectionAddress;166 dummy;167 return 0;168 }169}170171/// Collection properties172struct CreateCollectionData {173 /// Collection name174 string name;175 /// Collection description176 string description;177 /// Token prefix178 string token_prefix;179 /// Token type (NFT, FT or RFT)180 CollectionMode mode;181 /// Fungible token precision182 uint8 decimals;183 /// Custom Properties184 Property[] properties;185 /// Permissions for token properties186 TokenPropertyPermission[] token_property_permissions;187 /// Collection admins188 CrossAddress[] admin_list;189 /// Nesting settings190 CollectionNestingAndPermission nesting_settings;191 /// Collection limits192 CollectionLimitValue[] limits;193 /// Collection sponsor194 CrossAddress pending_sponsor;195 /// Extra collection flags196 CollectionFlags flags;197}198199type CollectionFlags is uint8;200201library CollectionFlagsLib {202 /// Tokens in foreign collections can be transferred, but not burnt203 CollectionFlags constant foreignField = CollectionFlags.wrap(128);204 /// Supports ERC721Metadata205 CollectionFlags constant erc721metadataField = CollectionFlags.wrap(64);206 /// External collections can't be managed using `unique` api207 CollectionFlags constant externalField = CollectionFlags.wrap(1);208209 /// Reserved flags210 function reservedField(uint8 value) public pure returns (CollectionFlags) {211 require(value < 1 << 5, "out of bound value");212 return CollectionFlags.wrap(value << 1);213 }214}215216/// Cross account struct217struct CrossAddress {218 address eth;219 uint256 sub;220}221222/// [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.223struct CollectionLimitValue {224 CollectionLimitField field;225 uint256 value;226}227228/// [`CollectionLimits`](up_data_structs::CollectionLimits) fields representation for EVM.229enum CollectionLimitField {230 /// How many tokens can a user have on one account.231 AccountTokenOwnership,232 /// How many bytes of data are available for sponsorship.233 SponsoredDataSize,234 /// In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]235 SponsoredDataRateLimit,236 /// How many tokens can be mined into this collection.237 TokenLimit,238 /// Timeouts for transfer sponsoring.239 SponsorTransferTimeout,240 /// Timeout for sponsoring an approval in passed blocks.241 SponsorApproveTimeout,242 /// Whether the collection owner of the collection can send tokens (which belong to other users).243 OwnerCanTransfer,244 /// Can the collection owner burn other people's tokens.245 OwnerCanDestroy,246 /// Is it possible to send tokens from this collection between users.247 TransferEnabled248}249250/// Nested collections and permissions251struct CollectionNestingAndPermission {252 /// Owner of token can nest tokens under it.253 bool token_owner;254 /// Admin of token collection can nest tokens under token.255 bool collection_admin;256 /// If set - only tokens from specified collections can be nested.257 address[] restricted;258}259260/// Ethereum representation of Token Property Permissions.261struct TokenPropertyPermission {262 /// Token property key.263 string key;264 /// Token property permissions.265 PropertyPermission[] permissions;266}267268/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value.269struct PropertyPermission {270 /// TokenPermission field.271 TokenPermissionField code;272 /// TokenPermission value.273 bool value;274}275276/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.277enum TokenPermissionField {278 /// Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]279 Mutable,280 /// Change permission for the collection administrator. See [`up_data_structs::PropertyPermission::token_owner`]281 TokenOwner,282 /// Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]283 CollectionAdmin284}285286/// Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).287struct Property {288 string key;289 bytes value;290}291292/// Type of tokens in collection293enum CollectionMode {294 /// Nonfungible295 Nonfungible,296 /// Fungible297 Fungible,298 /// Refungible299 Refungible300}runtime/common/ethereum/sponsoring/refungible.rsdiffbeforeafterboth--- a/runtime/common/ethereum/sponsoring/refungible.rs
+++ b/runtime/common/ethereum/sponsoring/refungible.rs
@@ -242,6 +242,7 @@
BurnFrom { .. }
| BurnFromCross { .. }
| MintBulk { .. }
+ | MintBulkCross { .. }
| MintBulkWithTokenUri { .. } => None,
MintCross { .. } => withdraw_create_item::<T>(
tests/src/eth/abi/nonFungible.jsondiffbeforeafterboth--- a/tests/src/eth/abi/nonFungible.json
+++ b/tests/src/eth/abi/nonFungible.json
@@ -469,6 +469,39 @@
"inputs": [
{
"components": [
+ {
+ "components": [
+ { "internalType": "address", "name": "eth", "type": "address" },
+ { "internalType": "uint256", "name": "sub", "type": "uint256" }
+ ],
+ "internalType": "struct CrossAddress",
+ "name": "owner",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ { "internalType": "string", "name": "key", "type": "string" },
+ { "internalType": "bytes", "name": "value", "type": "bytes" }
+ ],
+ "internalType": "struct Property[]",
+ "name": "properties",
+ "type": "tuple[]"
+ }
+ ],
+ "internalType": "struct MintTokenData[]",
+ "name": "data",
+ "type": "tuple[]"
+ }
+ ],
+ "name": "mintBulkCross",
+ "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
{ "internalType": "address", "name": "eth", "type": "address" },
{ "internalType": "uint256", "name": "sub", "type": "uint256" }
],
tests/src/eth/abi/reFungible.jsondiffbeforeafterboth--- a/tests/src/eth/abi/reFungible.json
+++ b/tests/src/eth/abi/reFungible.json
@@ -451,6 +451,39 @@
"inputs": [
{
"components": [
+ {
+ "components": [
+ { "internalType": "address", "name": "eth", "type": "address" },
+ { "internalType": "uint256", "name": "sub", "type": "uint256" }
+ ],
+ "internalType": "struct CrossAddress",
+ "name": "owner",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ { "internalType": "string", "name": "key", "type": "string" },
+ { "internalType": "bytes", "name": "value", "type": "bytes" }
+ ],
+ "internalType": "struct Property[]",
+ "name": "properties",
+ "type": "tuple[]"
+ }
+ ],
+ "internalType": "struct MintTokenData[]",
+ "name": "tokenProperties",
+ "type": "tuple[]"
+ }
+ ],
+ "name": "mintBulkCross",
+ "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
{ "internalType": "address", "name": "eth", "type": "address" },
{ "internalType": "uint256", "name": "sub", "type": "uint256" }
],
tests/src/eth/api/CollectionHelpers.soldiffbeforeafterboth--- a/tests/src/eth/api/CollectionHelpers.sol
+++ b/tests/src/eth/api/CollectionHelpers.sol
@@ -20,12 +20,12 @@
}
/// @title Contract, which allows users to operate with collections
-/// @dev the ERC-165 identifier for this interface is 0x4135fff1
+/// @dev the ERC-165 identifier for this interface is 0x94e5af0d
interface CollectionHelpers is Dummy, ERC165, CollectionHelpersEvents {
/// Create a collection
/// @return address Address of the newly created collection
- /// @dev EVM selector for this function is: 0xa765ee5b,
- /// or in textual repr: createCollection(((address,uint256),string,string,string,uint8,uint8,(string,bytes)[],(string,(uint8,bool)[])[],(address,uint256)[],(bool,bool,address[]),(uint8,uint256)[],uint8))
+ /// @dev EVM selector for this function is: 0x72b5bea7,
+ /// or in textual repr: createCollection((string,string,string,uint8,uint8,(string,bytes)[],(string,(uint8,bool)[])[],(address,uint256)[],(bool,bool,address[]),(uint8,uint256)[],(address,uint256),uint8))
function createCollection(CreateCollectionData memory data) external payable returns (address);
/// Create an NFT collection
@@ -103,8 +103,6 @@
/// Collection properties
struct CreateCollectionData {
- /// Collection sponsor
- CrossAddress pending_sponsor;
/// Collection name
string name;
/// Collection description
@@ -125,11 +123,12 @@
CollectionNestingAndPermission nesting_settings;
/// Collection limits
CollectionLimitValue[] limits;
+ /// Collection sponsor
+ CrossAddress pending_sponsor;
/// Extra collection flags
CollectionFlags flags;
}
-/// Cross account struct
type CollectionFlags is uint8;
library CollectionFlagsLib {
@@ -140,13 +139,19 @@
/// External collections can't be managed using `unique` api
CollectionFlags constant externalField = CollectionFlags.wrap(1);
- /// Reserved bits
+ /// Reserved flags
function reservedField(uint8 value) public pure returns (CollectionFlags) {
require(value < 1 << 5, "out of bound value");
return CollectionFlags.wrap(value << 1);
}
}
+/// Cross account struct
+struct CrossAddress {
+ address eth;
+ uint256 sub;
+}
+
/// [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
struct CollectionLimitValue {
CollectionLimitField field;
@@ -183,12 +188,6 @@
bool collection_admin;
/// If set - only tokens from specified collections can be nested.
address[] restricted;
-}
-
-/// Cross account struct
-struct CrossAddress {
- address eth;
- uint256 sub;
}
/// Ethereum representation of Token Property Permissions.
@@ -225,10 +224,10 @@
/// Type of tokens in collection
enum CollectionMode {
- /// Fungible
- Fungible,
/// Nonfungible
Nonfungible,
+ /// Fungible
+ Fungible,
/// Refungible
Refungible
}
tests/src/eth/api/UniqueNFT.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueNFT.sol
+++ b/tests/src/eth/api/UniqueNFT.sol
@@ -551,7 +551,7 @@
}
/// @title Unique extensions for ERC721.
-/// @dev the ERC-165 identifier for this interface is 0x307b061a
+/// @dev the ERC-165 identifier for this interface is 0x9b397d16
interface ERC721UniqueExtensions is Dummy, ERC165 {
/// @notice A descriptive name for a collection of NFTs in this contract
/// @dev EVM selector for this function is: 0x06fdde03,
@@ -674,6 +674,12 @@
// /// or in textual repr: mintBulk(address,uint256[])
// function mintBulk(address to, uint256[] memory tokenIds) external returns (bool);
+ /// @notice Function to mint a token.
+ /// @param data Array of pairs of token owner and token's properties for minted token
+ /// @dev EVM selector for this function is: 0xab427b0c,
+ /// or in textual repr: mintBulkCross(((address,uint256),(string,bytes)[])[])
+ function mintBulkCross(MintTokenData[] memory data) external returns (bool);
+
// /// @notice Function to mint multiple tokens with the given tokenUris.
// /// @dev `tokenIds` is array of pairs of token ID and token URI. Token IDs should be consecutive
// /// numbers and first number should be obtained with `nextTokenId` method
@@ -705,6 +711,11 @@
string uri;
}
+struct MintTokenData {
+ CrossAddress owner;
+ Property[] properties;
+}
+
/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
/// @dev See https://eips.ethereum.org/EIPS/eip-721
/// @dev the ERC-165 identifier for this interface is 0x780e9d63
tests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueRefungible.sol
+++ b/tests/src/eth/api/UniqueRefungible.sol
@@ -551,7 +551,7 @@
}
/// @title Unique extensions for ERC721.
-/// @dev the ERC-165 identifier for this interface is 0x95c0f66c
+/// @dev the ERC-165 identifier for this interface is 0x3e828d60
interface ERC721UniqueExtensions is Dummy, ERC165 {
/// @notice A descriptive name for a collection of NFTs in this contract
/// @dev EVM selector for this function is: 0x06fdde03,
@@ -668,6 +668,12 @@
// /// or in textual repr: mintBulk(address,uint256[])
// function mintBulk(address to, uint256[] memory tokenIds) external returns (bool);
+ /// @notice Function to mint a token.
+ /// @param tokenProperties Properties of minted token
+ /// @dev EVM selector for this function is: 0xab427b0c,
+ /// or in textual repr: mintBulkCross(((address,uint256),(string,bytes)[])[])
+ function mintBulkCross(MintTokenData[] memory tokenProperties) external returns (bool);
+
// /// @notice Function to mint multiple tokens with the given tokenUris.
// /// @dev `tokenIds` is array of pairs of token ID and token URI. Token IDs should be consecutive
// /// numbers and first number should be obtained with `nextTokenId` method
@@ -706,6 +712,11 @@
string uri;
}
+struct MintTokenData {
+ CrossAddress owner;
+ Property[] properties;
+}
+
/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
/// @dev See https://eips.ethereum.org/EIPS/eip-721
/// @dev the ERC-165 identifier for this interface is 0x780e9d63