difftreelog
feat set/get tokenPropertyPermissions for NFT
in: master
7 files changed
pallets/common/src/eth.rsdiffbeforeafterboth--- a/pallets/common/src/eth.rs
+++ b/pallets/common/src/eth.rs
@@ -162,3 +162,12 @@
CollectionAdmin,
TokenOwner,
}
+
+#[derive(AbiCoder, Copy, Clone, Default, Debug)]
+#[repr(u8)]
+pub enum EthTokenPermissions {
+ #[default]
+ Mutable,
+ TokenOwner,
+ CollectionAdmin,
+}
pallets/nonfungible/src/erc.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -38,7 +38,7 @@
use pallet_common::{
CollectionHandle, CollectionPropertyPermissions, CommonCollectionOperations,
erc::{CommonEvmHandler, PrecompileResult, CollectionCall, static_property::key},
- eth::EthCrossAccount,
+ eth::{EthCrossAccount, EthTokenPermissions},
};
use pallet_evm::{account::CrossAccountId, PrecompileHandle};
use pallet_evm_coder_substrate::call;
@@ -60,6 +60,7 @@
/// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.
/// @param tokenOwner Permission to mutate property by token owner if property is mutable.
#[weight(<SelfWeightOf<T>>::set_token_property_permissions(1))]
+ #[solidity(hide)]
fn set_token_property_permission(
&mut self,
caller: caller,
@@ -69,10 +70,10 @@
token_owner: bool,
) -> Result<()> {
let caller = T::CrossAccountId::from_eth(caller);
- <Pallet<T>>::set_property_permission(
+ <Pallet<T>>::set_property_permissions(
self,
&caller,
- PropertyKeyPermission {
+ [PropertyKeyPermission {
key: <Vec<u8>>::from(key)
.try_into()
.map_err(|_| "too long key")?,
@@ -81,11 +82,81 @@
collection_admin,
token_owner,
},
- },
+ }]
+ .into(),
)
.map_err(dispatch_to_evm::<T>)
}
+ /// @notice Set permissions for token property.
+ /// @dev Throws error if `msg.sender` is not admin or owner of the collection.
+ /// @param permissions Permissions for keys.
+ fn set_token_property_permissions(
+ &mut self,
+ caller: caller,
+ permissions: Vec<(string, Vec<(EthTokenPermissions, bool)>)>,
+ ) -> Result<()> {
+ let caller = T::CrossAccountId::from_eth(caller);
+ const PERMISSIONS_FIELDS_COUNT: usize = 3;
+
+ let mut perms = <Vec<_>>::new();
+
+ for (key, pp) in permissions {
+ if pp.len() > PERMISSIONS_FIELDS_COUNT {
+ return Err(alloc::format!(
+ "Actual number of fields {} for {}, which exceeds the maximum value of {}",
+ pp.len(),
+ stringify!(EthTokenPermissions),
+ PERMISSIONS_FIELDS_COUNT
+ )
+ .as_str()
+ .into());
+ }
+
+ let mut token_permission = PropertyPermission {
+ mutable: false,
+ collection_admin: false,
+ token_owner: false,
+ };
+
+ for (perm, value) in pp {
+ match perm {
+ EthTokenPermissions::Mutable => token_permission.mutable = value,
+ EthTokenPermissions::TokenOwner => token_permission.token_owner = value,
+ EthTokenPermissions::CollectionAdmin => {
+ token_permission.collection_admin = value
+ }
+ }
+ }
+
+ perms.push(PropertyKeyPermission {
+ key: <Vec<u8>>::from(key)
+ .try_into()
+ .map_err(|_| "too long key")?,
+ permission: token_permission,
+ });
+ }
+
+ <Pallet<T>>::set_property_permissions(self, &caller, perms).map_err(dispatch_to_evm::<T>)
+ }
+
+ fn token_property_permissions(
+ &self,
+ ) -> Result<Vec<(string, Vec<(EthTokenPermissions, bool)>)>> {
+ let mut res = <Vec<_>>::new();
+ for (key, pp) in <Pallet<T>>::token_property_permission(self.id) {
+ let key = string::from_utf8(key.into_inner()).unwrap();
+ let pp = [
+ (EthTokenPermissions::Mutable, pp.mutable),
+ (EthTokenPermissions::TokenOwner, pp.token_owner),
+ (EthTokenPermissions::CollectionAdmin, pp.collection_admin),
+ ]
+ .into();
+ res.push((key, pp));
+ }
+ Ok(res)
+ }
+
/// @notice Set token property value.
/// @dev Throws error if `msg.sender` has no permission to edit the property.
/// @param tokenId ID of the token.
pallets/nonfungible/src/lib.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/lib.rs
+++ b/pallets/nonfungible/src/lib.rs
@@ -103,7 +103,7 @@
AccessMode, CollectionId, CollectionFlags, CustomDataLimit, TokenId, CreateCollectionData,
CreateNftExData, mapping::TokenAddressMapping, budget::Budget, Property, PropertyPermission,
PropertyKey, PropertyValue, PropertyKeyPermission, Properties, PropertyScope, TrySetProperty,
- TokenChild, AuxPropertyValue,
+ TokenChild, AuxPropertyValue, PropertiesPermissionMap,
};
use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};
use pallet_common::{
@@ -827,12 +827,16 @@
/// Set property permissions for the collection.
///
/// Sender should be the owner or admin of the collection.
- pub fn set_property_permission(
+ pub fn set_property_permissions(
collection: &CollectionHandle<T>,
sender: &T::CrossAccountId,
- permission: PropertyKeyPermission,
+ permission: Vec<PropertyKeyPermission>,
) -> DispatchResult {
- <PalletCommon<T>>::set_property_permission(collection, sender, permission)
+ <PalletCommon<T>>::set_token_property_permissions(collection, sender, permission)
+ }
+
+ pub fn token_property_permission(collection_id: CollectionId) -> PropertiesPermissionMap {
+ <PalletCommon<T>>::property_permissions(collection_id)
}
pub fn check_token_immediate_ownership(
pallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth--- a/pallets/nonfungible/src/stubs/UniqueNFT.sol
+++ b/pallets/nonfungible/src/stubs/UniqueNFT.sol
@@ -18,30 +18,44 @@
}
/// @title A contract that allows to set and delete token properties and change token property permissions.
-/// @dev the ERC-165 identifier for this interface is 0x91a97a68
+/// @dev the ERC-165 identifier for this interface is 0xde0695c2
contract TokenProperties is Dummy, ERC165 {
+ // /// @notice Set permissions for token property.
+ // /// @dev Throws error if `msg.sender` is not admin or owner of the collection.
+ // /// @param key Property key.
+ // /// @param isMutable Permission to mutate property.
+ // /// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.
+ // /// @param tokenOwner Permission to mutate property by token owner if property is mutable.
+ // /// @dev EVM selector for this function is: 0x222d97fa,
+ // /// or in textual repr: setTokenPropertyPermission(string,bool,bool,bool)
+ // function setTokenPropertyPermission(string memory key, bool isMutable, bool collectionAdmin, bool tokenOwner) public {
+ // require(false, stub_error);
+ // key;
+ // isMutable;
+ // collectionAdmin;
+ // tokenOwner;
+ // dummy = 0;
+ // }
+
/// @notice Set permissions for token property.
/// @dev Throws error if `msg.sender` is not admin or owner of the collection.
- /// @param key Property key.
- /// @param isMutable Permission to mutate property.
- /// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.
- /// @param tokenOwner Permission to mutate property by token owner if property is mutable.
- /// @dev EVM selector for this function is: 0x222d97fa,
- /// or in textual repr: setTokenPropertyPermission(string,bool,bool,bool)
- function setTokenPropertyPermission(
- string memory key,
- bool isMutable,
- bool collectionAdmin,
- bool tokenOwner
- ) public {
+ /// @param permissions Permissions for keys.
+ /// @dev EVM selector for this function is: 0xbd92983a,
+ /// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[])
+ function setTokenPropertyPermissions(Tuple48[] memory permissions) public {
require(false, stub_error);
- key;
- isMutable;
- collectionAdmin;
- tokenOwner;
+ permissions;
dummy = 0;
}
+ /// @dev EVM selector for this function is: 0xf23d7790,
+ /// or in textual repr: tokenPropertyPermissions()
+ function tokenPropertyPermissions() public view returns (Tuple48[] memory) {
+ require(false, stub_error);
+ dummy;
+ return new Tuple48[](0);
+ }
+
// /// @notice Set token property value.
// /// @dev Throws error if `msg.sender` has no permission to edit the property.
// /// @param tokenId ID of the token.
@@ -118,6 +132,24 @@
bytes value;
}
+enum EthTokenPermissions {
+ Mutable,
+ TokenOwner,
+ CollectionAdmin
+}
+
+/// @dev anonymous struct
+struct Tuple48 {
+ string field_0;
+ Tuple46[] field_1;
+}
+
+/// @dev anonymous struct
+struct Tuple46 {
+ EthTokenPermissions field_0;
+ bool field_1;
+}
+
/// @title A contract that allows you to work with collections.
/// @dev the ERC-165 identifier for this interface is 0xb5e1747f
contract Collection is Dummy, ERC165 {
tests/src/eth/abi/nonFungible.jsondiffbeforeafterboth1[2 {3 "anonymous": false,4 "inputs": [5 {6 "indexed": true,7 "internalType": "address",8 "name": "owner",9 "type": "address"10 },11 {12 "indexed": true,13 "internalType": "address",14 "name": "approved",15 "type": "address"16 },17 {18 "indexed": true,19 "internalType": "uint256",20 "name": "tokenId",21 "type": "uint256"22 }23 ],24 "name": "Approval",25 "type": "event"26 },27 {28 "anonymous": false,29 "inputs": [30 {31 "indexed": true,32 "internalType": "address",33 "name": "owner",34 "type": "address"35 },36 {37 "indexed": true,38 "internalType": "address",39 "name": "operator",40 "type": "address"41 },42 {43 "indexed": false,44 "internalType": "bool",45 "name": "approved",46 "type": "bool"47 }48 ],49 "name": "ApprovalForAll",50 "type": "event"51 },52 {53 "anonymous": false,54 "inputs": [],55 "name": "MintingFinished",56 "type": "event"57 },58 {59 "anonymous": false,60 "inputs": [61 {62 "indexed": true,63 "internalType": "address",64 "name": "from",65 "type": "address"66 },67 {68 "indexed": true,69 "internalType": "address",70 "name": "to",71 "type": "address"72 },73 {74 "indexed": true,75 "internalType": "uint256",76 "name": "tokenId",77 "type": "uint256"78 }79 ],80 "name": "Transfer",81 "type": "event"82 },83 {84 "inputs": [85 {86 "components": [87 { "internalType": "address", "name": "eth", "type": "address" },88 { "internalType": "uint256", "name": "sub", "type": "uint256" }89 ],90 "internalType": "struct EthCrossAccount",91 "name": "newAdmin",92 "type": "tuple"93 }94 ],95 "name": "addCollectionAdminCross",96 "outputs": [],97 "stateMutability": "nonpayable",98 "type": "function"99 },100 {101 "inputs": [102 {103 "components": [104 { "internalType": "address", "name": "eth", "type": "address" },105 { "internalType": "uint256", "name": "sub", "type": "uint256" }106 ],107 "internalType": "struct EthCrossAccount",108 "name": "user",109 "type": "tuple"110 }111 ],112 "name": "addToCollectionAllowListCross",113 "outputs": [],114 "stateMutability": "nonpayable",115 "type": "function"116 },117 {118 "inputs": [119 {120 "components": [121 { "internalType": "address", "name": "eth", "type": "address" },122 { "internalType": "uint256", "name": "sub", "type": "uint256" }123 ],124 "internalType": "struct EthCrossAccount",125 "name": "user",126 "type": "tuple"127 }128 ],129 "name": "allowlistedCross",130 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],131 "stateMutability": "view",132 "type": "function"133 },134 {135 "inputs": [136 { "internalType": "address", "name": "approved", "type": "address" },137 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }138 ],139 "name": "approve",140 "outputs": [],141 "stateMutability": "nonpayable",142 "type": "function"143 },144 {145 "inputs": [146 {147 "components": [148 { "internalType": "address", "name": "eth", "type": "address" },149 { "internalType": "uint256", "name": "sub", "type": "uint256" }150 ],151 "internalType": "struct EthCrossAccount",152 "name": "approved",153 "type": "tuple"154 },155 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }156 ],157 "name": "approveCross",158 "outputs": [],159 "stateMutability": "nonpayable",160 "type": "function"161 },162 {163 "inputs": [164 { "internalType": "address", "name": "owner", "type": "address" }165 ],166 "name": "balanceOf",167 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],168 "stateMutability": "view",169 "type": "function"170 },171 {172 "inputs": [173 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }174 ],175 "name": "burn",176 "outputs": [],177 "stateMutability": "nonpayable",178 "type": "function"179 },180 {181 "inputs": [182 {183 "components": [184 { "internalType": "address", "name": "eth", "type": "address" },185 { "internalType": "uint256", "name": "sub", "type": "uint256" }186 ],187 "internalType": "struct EthCrossAccount",188 "name": "from",189 "type": "tuple"190 },191 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }192 ],193 "name": "burnFromCross",194 "outputs": [],195 "stateMutability": "nonpayable",196 "type": "function"197 },198 {199 "inputs": [200 {201 "components": [202 { "internalType": "address", "name": "eth", "type": "address" },203 { "internalType": "uint256", "name": "sub", "type": "uint256" }204 ],205 "internalType": "struct EthCrossAccount",206 "name": "newOwner",207 "type": "tuple"208 }209 ],210 "name": "changeCollectionOwnerCross",211 "outputs": [],212 "stateMutability": "nonpayable",213 "type": "function"214 },215 {216 "inputs": [],217 "name": "collectionAdmins",218 "outputs": [219 {220 "components": [221 { "internalType": "address", "name": "eth", "type": "address" },222 { "internalType": "uint256", "name": "sub", "type": "uint256" }223 ],224 "internalType": "struct EthCrossAccount[]",225 "name": "",226 "type": "tuple[]"227 }228 ],229 "stateMutability": "view",230 "type": "function"231 },232 {233 "inputs": [],234 "name": "collectionHelperAddress",235 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],236 "stateMutability": "view",237 "type": "function"238 },239 {240 "inputs": [],241 "name": "collectionNestingPermissions",242 "outputs": [243 {244 "components": [245 {246 "internalType": "enum CollectionPermissions",247 "name": "field_0",248 "type": "uint8"249 },250 { "internalType": "bool", "name": "field_1", "type": "bool" }251 ],252 "internalType": "struct Tuple37[]",253 "name": "",254 "type": "tuple[]"255 }256 ],257 "stateMutability": "view",258 "type": "function"259 },260 {261 "inputs": [],262 "name": "collectionNestingRestrictedCollectionIds",263 "outputs": [264 {265 "components": [266 { "internalType": "bool", "name": "field_0", "type": "bool" },267 {268 "internalType": "uint256[]",269 "name": "field_1",270 "type": "uint256[]"271 }272 ],273 "internalType": "struct Tuple34",274 "name": "",275 "type": "tuple"276 }277 ],278 "stateMutability": "view",279 "type": "function"280 },281 {282 "inputs": [],283 "name": "collectionOwner",284 "outputs": [285 {286 "components": [287 { "internalType": "address", "name": "eth", "type": "address" },288 { "internalType": "uint256", "name": "sub", "type": "uint256" }289 ],290 "internalType": "struct EthCrossAccount",291 "name": "",292 "type": "tuple"293 }294 ],295 "stateMutability": "view",296 "type": "function"297 },298 {299 "inputs": [300 { "internalType": "string[]", "name": "keys", "type": "string[]" }301 ],302 "name": "collectionProperties",303 "outputs": [304 {305 "components": [306 { "internalType": "string", "name": "key", "type": "string" },307 { "internalType": "bytes", "name": "value", "type": "bytes" }308 ],309 "internalType": "struct Property[]",310 "name": "",311 "type": "tuple[]"312 }313 ],314 "stateMutability": "view",315 "type": "function"316 },317 {318 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],319 "name": "collectionProperty",320 "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],321 "stateMutability": "view",322 "type": "function"323 },324 {325 "inputs": [],326 "name": "collectionSponsor",327 "outputs": [328 {329 "components": [330 { "internalType": "address", "name": "field_0", "type": "address" },331 { "internalType": "uint256", "name": "field_1", "type": "uint256" }332 ],333 "internalType": "struct Tuple30",334 "name": "",335 "type": "tuple"336 }337 ],338 "stateMutability": "view",339 "type": "function"340 },341 {342 "inputs": [],343 "name": "confirmCollectionSponsorship",344 "outputs": [],345 "stateMutability": "nonpayable",346 "type": "function"347 },348 {349 "inputs": [],350 "name": "contractAddress",351 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],352 "stateMutability": "view",353 "type": "function"354 },355 {356 "inputs": [357 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }358 ],359 "name": "crossOwnerOf",360 "outputs": [361 {362 "components": [363 { "internalType": "address", "name": "eth", "type": "address" },364 { "internalType": "uint256", "name": "sub", "type": "uint256" }365 ],366 "internalType": "struct EthCrossAccount",367 "name": "",368 "type": "tuple"369 }370 ],371 "stateMutability": "view",372 "type": "function"373 },374 {375 "inputs": [376 { "internalType": "string[]", "name": "keys", "type": "string[]" }377 ],378 "name": "deleteCollectionProperties",379 "outputs": [],380 "stateMutability": "nonpayable",381 "type": "function"382 },383 {384 "inputs": [385 { "internalType": "uint256", "name": "tokenId", "type": "uint256" },386 { "internalType": "string[]", "name": "keys", "type": "string[]" }387 ],388 "name": "deleteProperties",389 "outputs": [],390 "stateMutability": "nonpayable",391 "type": "function"392 },393 {394 "inputs": [],395 "name": "description",396 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],397 "stateMutability": "view",398 "type": "function"399 },400 {401 "inputs": [],402 "name": "finishMinting",403 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],404 "stateMutability": "nonpayable",405 "type": "function"406 },407 {408 "inputs": [409 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }410 ],411 "name": "getApproved",412 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],413 "stateMutability": "view",414 "type": "function"415 },416 {417 "inputs": [],418 "name": "hasCollectionPendingSponsor",419 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],420 "stateMutability": "view",421 "type": "function"422 },423 {424 "inputs": [425 { "internalType": "address", "name": "owner", "type": "address" },426 { "internalType": "address", "name": "operator", "type": "address" }427 ],428 "name": "isApprovedForAll",429 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],430 "stateMutability": "view",431 "type": "function"432 },433 {434 "inputs": [435 {436 "components": [437 { "internalType": "address", "name": "eth", "type": "address" },438 { "internalType": "uint256", "name": "sub", "type": "uint256" }439 ],440 "internalType": "struct EthCrossAccount",441 "name": "user",442 "type": "tuple"443 }444 ],445 "name": "isOwnerOrAdminCross",446 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],447 "stateMutability": "view",448 "type": "function"449 },450 {451 "inputs": [{ "internalType": "address", "name": "to", "type": "address" }],452 "name": "mint",453 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],454 "stateMutability": "nonpayable",455 "type": "function"456 },457 {458 "inputs": [459 { "internalType": "address", "name": "to", "type": "address" },460 { "internalType": "string", "name": "tokenUri", "type": "string" }461 ],462 "name": "mintWithTokenURI",463 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],464 "stateMutability": "nonpayable",465 "type": "function"466 },467 {468 "inputs": [],469 "name": "mintingFinished",470 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],471 "stateMutability": "view",472 "type": "function"473 },474 {475 "inputs": [],476 "name": "name",477 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],478 "stateMutability": "view",479 "type": "function"480 },481 {482 "inputs": [],483 "name": "nextTokenId",484 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],485 "stateMutability": "view",486 "type": "function"487 },488 {489 "inputs": [490 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }491 ],492 "name": "ownerOf",493 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],494 "stateMutability": "view",495 "type": "function"496 },497 {498 "inputs": [499 { "internalType": "uint256", "name": "tokenId", "type": "uint256" },500 { "internalType": "string[]", "name": "keys", "type": "string[]" }501 ],502 "name": "properties",503 "outputs": [504 {505 "components": [506 { "internalType": "string", "name": "key", "type": "string" },507 { "internalType": "bytes", "name": "value", "type": "bytes" }508 ],509 "internalType": "struct Property[]",510 "name": "",511 "type": "tuple[]"512 }513 ],514 "stateMutability": "view",515 "type": "function"516 },517 {518 "inputs": [519 { "internalType": "uint256", "name": "tokenId", "type": "uint256" },520 { "internalType": "string", "name": "key", "type": "string" }521 ],522 "name": "property",523 "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],524 "stateMutability": "view",525 "type": "function"526 },527 {528 "inputs": [529 {530 "components": [531 { "internalType": "address", "name": "eth", "type": "address" },532 { "internalType": "uint256", "name": "sub", "type": "uint256" }533 ],534 "internalType": "struct EthCrossAccount",535 "name": "admin",536 "type": "tuple"537 }538 ],539 "name": "removeCollectionAdminCross",540 "outputs": [],541 "stateMutability": "nonpayable",542 "type": "function"543 },544 {545 "inputs": [],546 "name": "removeCollectionSponsor",547 "outputs": [],548 "stateMutability": "nonpayable",549 "type": "function"550 },551 {552 "inputs": [553 {554 "components": [555 { "internalType": "address", "name": "eth", "type": "address" },556 { "internalType": "uint256", "name": "sub", "type": "uint256" }557 ],558 "internalType": "struct EthCrossAccount",559 "name": "user",560 "type": "tuple"561 }562 ],563 "name": "removeFromCollectionAllowListCross",564 "outputs": [],565 "stateMutability": "nonpayable",566 "type": "function"567 },568 {569 "inputs": [570 { "internalType": "address", "name": "from", "type": "address" },571 { "internalType": "address", "name": "to", "type": "address" },572 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }573 ],574 "name": "safeTransferFrom",575 "outputs": [],576 "stateMutability": "nonpayable",577 "type": "function"578 },579 {580 "inputs": [581 { "internalType": "address", "name": "from", "type": "address" },582 { "internalType": "address", "name": "to", "type": "address" },583 { "internalType": "uint256", "name": "tokenId", "type": "uint256" },584 { "internalType": "bytes", "name": "data", "type": "bytes" }585 ],586 "name": "safeTransferFrom",587 "outputs": [],588 "stateMutability": "nonpayable",589 "type": "function"590 },591 {592 "inputs": [593 { "internalType": "address", "name": "operator", "type": "address" },594 { "internalType": "bool", "name": "approved", "type": "bool" }595 ],596 "name": "setApprovalForAll",597 "outputs": [],598 "stateMutability": "nonpayable",599 "type": "function"600 },601 {602 "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],603 "name": "setCollectionAccess",604 "outputs": [],605 "stateMutability": "nonpayable",606 "type": "function"607 },608 {609 "inputs": [610 { "internalType": "string", "name": "limit", "type": "string" },611 { "internalType": "uint256", "name": "value", "type": "uint256" }612 ],613 "name": "setCollectionLimit",614 "outputs": [],615 "stateMutability": "nonpayable",616 "type": "function"617 },618 {619 "inputs": [{ "internalType": "bool", "name": "mode", "type": "bool" }],620 "name": "setCollectionMintMode",621 "outputs": [],622 "stateMutability": "nonpayable",623 "type": "function"624 },625 {626 "inputs": [{ "internalType": "bool", "name": "enable", "type": "bool" }],627 "name": "setCollectionNesting",628 "outputs": [],629 "stateMutability": "nonpayable",630 "type": "function"631 },632 {633 "inputs": [634 { "internalType": "bool", "name": "enable", "type": "bool" },635 {636 "internalType": "address[]",637 "name": "collections",638 "type": "address[]"639 }640 ],641 "name": "setCollectionNesting",642 "outputs": [],643 "stateMutability": "nonpayable",644 "type": "function"645 },646 {647 "inputs": [648 {649 "components": [650 { "internalType": "string", "name": "key", "type": "string" },651 { "internalType": "bytes", "name": "value", "type": "bytes" }652 ],653 "internalType": "struct Property[]",654 "name": "properties",655 "type": "tuple[]"656 }657 ],658 "name": "setCollectionProperties",659 "outputs": [],660 "stateMutability": "nonpayable",661 "type": "function"662 },663 {664 "inputs": [665 {666 "components": [667 { "internalType": "address", "name": "eth", "type": "address" },668 { "internalType": "uint256", "name": "sub", "type": "uint256" }669 ],670 "internalType": "struct EthCrossAccount",671 "name": "sponsor",672 "type": "tuple"673 }674 ],675 "name": "setCollectionSponsorCross",676 "outputs": [],677 "stateMutability": "nonpayable",678 "type": "function"679 },680 {681 "inputs": [682 { "internalType": "uint256", "name": "tokenId", "type": "uint256" },683 {684 "components": [685 { "internalType": "string", "name": "key", "type": "string" },686 { "internalType": "bytes", "name": "value", "type": "bytes" }687 ],688 "internalType": "struct Property[]",689 "name": "properties",690 "type": "tuple[]"691 }692 ],693 "name": "setProperties",694 "outputs": [],695 "stateMutability": "nonpayable",696 "type": "function"697 },698 {699 "inputs": [700 { "internalType": "string", "name": "key", "type": "string" },701 { "internalType": "bool", "name": "isMutable", "type": "bool" },702 { "internalType": "bool", "name": "collectionAdmin", "type": "bool" },703 { "internalType": "bool", "name": "tokenOwner", "type": "bool" }704 ],705 "name": "setTokenPropertyPermission",706 "outputs": [],707 "stateMutability": "nonpayable",708 "type": "function"709 },710 {711 "inputs": [712 { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }713 ],714 "name": "supportsInterface",715 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],716 "stateMutability": "view",717 "type": "function"718 },719 {720 "inputs": [],721 "name": "symbol",722 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],723 "stateMutability": "view",724 "type": "function"725 },726 {727 "inputs": [728 { "internalType": "uint256", "name": "index", "type": "uint256" }729 ],730 "name": "tokenByIndex",731 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],732 "stateMutability": "view",733 "type": "function"734 },735 {736 "inputs": [737 { "internalType": "address", "name": "owner", "type": "address" },738 { "internalType": "uint256", "name": "index", "type": "uint256" }739 ],740 "name": "tokenOfOwnerByIndex",741 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],742 "stateMutability": "view",743 "type": "function"744 },745 {746 "inputs": [747 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }748 ],749 "name": "tokenURI",750 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],751 "stateMutability": "view",752 "type": "function"753 },754 {755 "inputs": [],756 "name": "totalSupply",757 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],758 "stateMutability": "view",759 "type": "function"760 },761 {762 "inputs": [763 { "internalType": "address", "name": "to", "type": "address" },764 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }765 ],766 "name": "transfer",767 "outputs": [],768 "stateMutability": "nonpayable",769 "type": "function"770 },771 {772 "inputs": [773 {774 "components": [775 { "internalType": "address", "name": "eth", "type": "address" },776 { "internalType": "uint256", "name": "sub", "type": "uint256" }777 ],778 "internalType": "struct EthCrossAccount",779 "name": "to",780 "type": "tuple"781 },782 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }783 ],784 "name": "transferCross",785 "outputs": [],786 "stateMutability": "nonpayable",787 "type": "function"788 },789 {790 "inputs": [791 { "internalType": "address", "name": "from", "type": "address" },792 { "internalType": "address", "name": "to", "type": "address" },793 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }794 ],795 "name": "transferFrom",796 "outputs": [],797 "stateMutability": "nonpayable",798 "type": "function"799 },800 {801 "inputs": [802 {803 "components": [804 { "internalType": "address", "name": "eth", "type": "address" },805 { "internalType": "uint256", "name": "sub", "type": "uint256" }806 ],807 "internalType": "struct EthCrossAccount",808 "name": "from",809 "type": "tuple"810 },811 {812 "components": [813 { "internalType": "address", "name": "eth", "type": "address" },814 { "internalType": "uint256", "name": "sub", "type": "uint256" }815 ],816 "internalType": "struct EthCrossAccount",817 "name": "to",818 "type": "tuple"819 },820 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }821 ],822 "name": "transferFromCross",823 "outputs": [],824 "stateMutability": "nonpayable",825 "type": "function"826 },827 {828 "inputs": [],829 "name": "uniqueCollectionType",830 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],831 "stateMutability": "view",832 "type": "function"833 }834]1[2 {3 "anonymous": false,4 "inputs": [5 {6 "indexed": true,7 "internalType": "address",8 "name": "owner",9 "type": "address"10 },11 {12 "indexed": true,13 "internalType": "address",14 "name": "approved",15 "type": "address"16 },17 {18 "indexed": true,19 "internalType": "uint256",20 "name": "tokenId",21 "type": "uint256"22 }23 ],24 "name": "Approval",25 "type": "event"26 },27 {28 "anonymous": false,29 "inputs": [30 {31 "indexed": true,32 "internalType": "address",33 "name": "owner",34 "type": "address"35 },36 {37 "indexed": true,38 "internalType": "address",39 "name": "operator",40 "type": "address"41 },42 {43 "indexed": false,44 "internalType": "bool",45 "name": "approved",46 "type": "bool"47 }48 ],49 "name": "ApprovalForAll",50 "type": "event"51 },52 {53 "anonymous": false,54 "inputs": [],55 "name": "MintingFinished",56 "type": "event"57 },58 {59 "anonymous": false,60 "inputs": [61 {62 "indexed": true,63 "internalType": "address",64 "name": "from",65 "type": "address"66 },67 {68 "indexed": true,69 "internalType": "address",70 "name": "to",71 "type": "address"72 },73 {74 "indexed": true,75 "internalType": "uint256",76 "name": "tokenId",77 "type": "uint256"78 }79 ],80 "name": "Transfer",81 "type": "event"82 },83 {84 "inputs": [85 {86 "components": [87 { "internalType": "address", "name": "eth", "type": "address" },88 { "internalType": "uint256", "name": "sub", "type": "uint256" }89 ],90 "internalType": "struct EthCrossAccount",91 "name": "newAdmin",92 "type": "tuple"93 }94 ],95 "name": "addCollectionAdminCross",96 "outputs": [],97 "stateMutability": "nonpayable",98 "type": "function"99 },100 {101 "inputs": [102 {103 "components": [104 { "internalType": "address", "name": "eth", "type": "address" },105 { "internalType": "uint256", "name": "sub", "type": "uint256" }106 ],107 "internalType": "struct EthCrossAccount",108 "name": "user",109 "type": "tuple"110 }111 ],112 "name": "addToCollectionAllowListCross",113 "outputs": [],114 "stateMutability": "nonpayable",115 "type": "function"116 },117 {118 "inputs": [119 {120 "components": [121 { "internalType": "address", "name": "eth", "type": "address" },122 { "internalType": "uint256", "name": "sub", "type": "uint256" }123 ],124 "internalType": "struct EthCrossAccount",125 "name": "user",126 "type": "tuple"127 }128 ],129 "name": "allowlistedCross",130 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],131 "stateMutability": "view",132 "type": "function"133 },134 {135 "inputs": [136 { "internalType": "address", "name": "approved", "type": "address" },137 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }138 ],139 "name": "approve",140 "outputs": [],141 "stateMutability": "nonpayable",142 "type": "function"143 },144 {145 "inputs": [146 {147 "components": [148 { "internalType": "address", "name": "eth", "type": "address" },149 { "internalType": "uint256", "name": "sub", "type": "uint256" }150 ],151 "internalType": "struct EthCrossAccount",152 "name": "approved",153 "type": "tuple"154 },155 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }156 ],157 "name": "approveCross",158 "outputs": [],159 "stateMutability": "nonpayable",160 "type": "function"161 },162 {163 "inputs": [164 { "internalType": "address", "name": "owner", "type": "address" }165 ],166 "name": "balanceOf",167 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],168 "stateMutability": "view",169 "type": "function"170 },171 {172 "inputs": [173 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }174 ],175 "name": "burn",176 "outputs": [],177 "stateMutability": "nonpayable",178 "type": "function"179 },180 {181 "inputs": [182 {183 "components": [184 { "internalType": "address", "name": "eth", "type": "address" },185 { "internalType": "uint256", "name": "sub", "type": "uint256" }186 ],187 "internalType": "struct EthCrossAccount",188 "name": "from",189 "type": "tuple"190 },191 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }192 ],193 "name": "burnFromCross",194 "outputs": [],195 "stateMutability": "nonpayable",196 "type": "function"197 },198 {199 "inputs": [200 {201 "components": [202 { "internalType": "address", "name": "eth", "type": "address" },203 { "internalType": "uint256", "name": "sub", "type": "uint256" }204 ],205 "internalType": "struct EthCrossAccount",206 "name": "newOwner",207 "type": "tuple"208 }209 ],210 "name": "changeCollectionOwnerCross",211 "outputs": [],212 "stateMutability": "nonpayable",213 "type": "function"214 },215 {216 "inputs": [],217 "name": "collectionAdmins",218 "outputs": [219 {220 "components": [221 { "internalType": "address", "name": "eth", "type": "address" },222 { "internalType": "uint256", "name": "sub", "type": "uint256" }223 ],224 "internalType": "struct EthCrossAccount[]",225 "name": "",226 "type": "tuple[]"227 }228 ],229 "stateMutability": "view",230 "type": "function"231 },232 {233 "inputs": [],234 "name": "collectionHelperAddress",235 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],236 "stateMutability": "view",237 "type": "function"238 },239 {240 "inputs": [],241 "name": "collectionNestingPermissions",242 "outputs": [243 {244 "components": [245 {246 "internalType": "enum CollectionPermissions",247 "name": "field_0",248 "type": "uint8"249 },250 { "internalType": "bool", "name": "field_1", "type": "bool" }251 ],252 "internalType": "struct Tuple37[]",253 "name": "",254 "type": "tuple[]"255 }256 ],257 "stateMutability": "view",258 "type": "function"259 },260 {261 "inputs": [],262 "name": "collectionNestingRestrictedCollectionIds",263 "outputs": [264 {265 "components": [266 { "internalType": "bool", "name": "field_0", "type": "bool" },267 {268 "internalType": "uint256[]",269 "name": "field_1",270 "type": "uint256[]"271 }272 ],273 "internalType": "struct Tuple34",274 "name": "",275 "type": "tuple"276 }277 ],278 "stateMutability": "view",279 "type": "function"280 },281 {282 "inputs": [],283 "name": "collectionOwner",284 "outputs": [285 {286 "components": [287 { "internalType": "address", "name": "eth", "type": "address" },288 { "internalType": "uint256", "name": "sub", "type": "uint256" }289 ],290 "internalType": "struct EthCrossAccount",291 "name": "",292 "type": "tuple"293 }294 ],295 "stateMutability": "view",296 "type": "function"297 },298 {299 "inputs": [300 { "internalType": "string[]", "name": "keys", "type": "string[]" }301 ],302 "name": "collectionProperties",303 "outputs": [304 {305 "components": [306 { "internalType": "string", "name": "key", "type": "string" },307 { "internalType": "bytes", "name": "value", "type": "bytes" }308 ],309 "internalType": "struct Property[]",310 "name": "",311 "type": "tuple[]"312 }313 ],314 "stateMutability": "view",315 "type": "function"316 },317 {318 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],319 "name": "collectionProperty",320 "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],321 "stateMutability": "view",322 "type": "function"323 },324 {325 "inputs": [],326 "name": "collectionSponsor",327 "outputs": [328 {329 "components": [330 { "internalType": "address", "name": "field_0", "type": "address" },331 { "internalType": "uint256", "name": "field_1", "type": "uint256" }332 ],333 "internalType": "struct Tuple30",334 "name": "",335 "type": "tuple"336 }337 ],338 "stateMutability": "view",339 "type": "function"340 },341 {342 "inputs": [],343 "name": "confirmCollectionSponsorship",344 "outputs": [],345 "stateMutability": "nonpayable",346 "type": "function"347 },348 {349 "inputs": [],350 "name": "contractAddress",351 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],352 "stateMutability": "view",353 "type": "function"354 },355 {356 "inputs": [357 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }358 ],359 "name": "crossOwnerOf",360 "outputs": [361 {362 "components": [363 { "internalType": "address", "name": "eth", "type": "address" },364 { "internalType": "uint256", "name": "sub", "type": "uint256" }365 ],366 "internalType": "struct EthCrossAccount",367 "name": "",368 "type": "tuple"369 }370 ],371 "stateMutability": "view",372 "type": "function"373 },374 {375 "inputs": [376 { "internalType": "string[]", "name": "keys", "type": "string[]" }377 ],378 "name": "deleteCollectionProperties",379 "outputs": [],380 "stateMutability": "nonpayable",381 "type": "function"382 },383 {384 "inputs": [385 { "internalType": "uint256", "name": "tokenId", "type": "uint256" },386 { "internalType": "string[]", "name": "keys", "type": "string[]" }387 ],388 "name": "deleteProperties",389 "outputs": [],390 "stateMutability": "nonpayable",391 "type": "function"392 },393 {394 "inputs": [],395 "name": "description",396 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],397 "stateMutability": "view",398 "type": "function"399 },400 {401 "inputs": [],402 "name": "finishMinting",403 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],404 "stateMutability": "nonpayable",405 "type": "function"406 },407 {408 "inputs": [409 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }410 ],411 "name": "getApproved",412 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],413 "stateMutability": "view",414 "type": "function"415 },416 {417 "inputs": [],418 "name": "hasCollectionPendingSponsor",419 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],420 "stateMutability": "view",421 "type": "function"422 },423 {424 "inputs": [425 { "internalType": "address", "name": "owner", "type": "address" },426 { "internalType": "address", "name": "operator", "type": "address" }427 ],428 "name": "isApprovedForAll",429 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],430 "stateMutability": "view",431 "type": "function"432 },433 {434 "inputs": [435 {436 "components": [437 { "internalType": "address", "name": "eth", "type": "address" },438 { "internalType": "uint256", "name": "sub", "type": "uint256" }439 ],440 "internalType": "struct EthCrossAccount",441 "name": "user",442 "type": "tuple"443 }444 ],445 "name": "isOwnerOrAdminCross",446 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],447 "stateMutability": "view",448 "type": "function"449 },450 {451 "inputs": [{ "internalType": "address", "name": "to", "type": "address" }],452 "name": "mint",453 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],454 "stateMutability": "nonpayable",455 "type": "function"456 },457 {458 "inputs": [459 { "internalType": "address", "name": "to", "type": "address" },460 { "internalType": "string", "name": "tokenUri", "type": "string" }461 ],462 "name": "mintWithTokenURI",463 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],464 "stateMutability": "nonpayable",465 "type": "function"466 },467 {468 "inputs": [],469 "name": "mintingFinished",470 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],471 "stateMutability": "view",472 "type": "function"473 },474 {475 "inputs": [],476 "name": "name",477 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],478 "stateMutability": "view",479 "type": "function"480 },481 {482 "inputs": [],483 "name": "nextTokenId",484 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],485 "stateMutability": "view",486 "type": "function"487 },488 {489 "inputs": [490 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }491 ],492 "name": "ownerOf",493 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],494 "stateMutability": "view",495 "type": "function"496 },497 {498 "inputs": [499 { "internalType": "uint256", "name": "tokenId", "type": "uint256" },500 { "internalType": "string[]", "name": "keys", "type": "string[]" }501 ],502 "name": "properties",503 "outputs": [504 {505 "components": [506 { "internalType": "string", "name": "key", "type": "string" },507 { "internalType": "bytes", "name": "value", "type": "bytes" }508 ],509 "internalType": "struct Property[]",510 "name": "",511 "type": "tuple[]"512 }513 ],514 "stateMutability": "view",515 "type": "function"516 },517 {518 "inputs": [519 { "internalType": "uint256", "name": "tokenId", "type": "uint256" },520 { "internalType": "string", "name": "key", "type": "string" }521 ],522 "name": "property",523 "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],524 "stateMutability": "view",525 "type": "function"526 },527 {528 "inputs": [529 {530 "components": [531 { "internalType": "address", "name": "eth", "type": "address" },532 { "internalType": "uint256", "name": "sub", "type": "uint256" }533 ],534 "internalType": "struct EthCrossAccount",535 "name": "admin",536 "type": "tuple"537 }538 ],539 "name": "removeCollectionAdminCross",540 "outputs": [],541 "stateMutability": "nonpayable",542 "type": "function"543 },544 {545 "inputs": [],546 "name": "removeCollectionSponsor",547 "outputs": [],548 "stateMutability": "nonpayable",549 "type": "function"550 },551 {552 "inputs": [553 {554 "components": [555 { "internalType": "address", "name": "eth", "type": "address" },556 { "internalType": "uint256", "name": "sub", "type": "uint256" }557 ],558 "internalType": "struct EthCrossAccount",559 "name": "user",560 "type": "tuple"561 }562 ],563 "name": "removeFromCollectionAllowListCross",564 "outputs": [],565 "stateMutability": "nonpayable",566 "type": "function"567 },568 {569 "inputs": [570 { "internalType": "address", "name": "from", "type": "address" },571 { "internalType": "address", "name": "to", "type": "address" },572 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }573 ],574 "name": "safeTransferFrom",575 "outputs": [],576 "stateMutability": "nonpayable",577 "type": "function"578 },579 {580 "inputs": [581 { "internalType": "address", "name": "from", "type": "address" },582 { "internalType": "address", "name": "to", "type": "address" },583 { "internalType": "uint256", "name": "tokenId", "type": "uint256" },584 { "internalType": "bytes", "name": "data", "type": "bytes" }585 ],586 "name": "safeTransferFrom",587 "outputs": [],588 "stateMutability": "nonpayable",589 "type": "function"590 },591 {592 "inputs": [593 { "internalType": "address", "name": "operator", "type": "address" },594 { "internalType": "bool", "name": "approved", "type": "bool" }595 ],596 "name": "setApprovalForAll",597 "outputs": [],598 "stateMutability": "nonpayable",599 "type": "function"600 },601 {602 "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],603 "name": "setCollectionAccess",604 "outputs": [],605 "stateMutability": "nonpayable",606 "type": "function"607 },608 {609 "inputs": [610 { "internalType": "string", "name": "limit", "type": "string" },611 { "internalType": "uint256", "name": "value", "type": "uint256" }612 ],613 "name": "setCollectionLimit",614 "outputs": [],615 "stateMutability": "nonpayable",616 "type": "function"617 },618 {619 "inputs": [{ "internalType": "bool", "name": "mode", "type": "bool" }],620 "name": "setCollectionMintMode",621 "outputs": [],622 "stateMutability": "nonpayable",623 "type": "function"624 },625 {626 "inputs": [{ "internalType": "bool", "name": "enable", "type": "bool" }],627 "name": "setCollectionNesting",628 "outputs": [],629 "stateMutability": "nonpayable",630 "type": "function"631 },632 {633 "inputs": [634 { "internalType": "bool", "name": "enable", "type": "bool" },635 {636 "internalType": "address[]",637 "name": "collections",638 "type": "address[]"639 }640 ],641 "name": "setCollectionNesting",642 "outputs": [],643 "stateMutability": "nonpayable",644 "type": "function"645 },646 {647 "inputs": [648 {649 "components": [650 { "internalType": "string", "name": "key", "type": "string" },651 { "internalType": "bytes", "name": "value", "type": "bytes" }652 ],653 "internalType": "struct Property[]",654 "name": "properties",655 "type": "tuple[]"656 }657 ],658 "name": "setCollectionProperties",659 "outputs": [],660 "stateMutability": "nonpayable",661 "type": "function"662 },663 {664 "inputs": [665 {666 "components": [667 { "internalType": "address", "name": "eth", "type": "address" },668 { "internalType": "uint256", "name": "sub", "type": "uint256" }669 ],670 "internalType": "struct EthCrossAccount",671 "name": "sponsor",672 "type": "tuple"673 }674 ],675 "name": "setCollectionSponsorCross",676 "outputs": [],677 "stateMutability": "nonpayable",678 "type": "function"679 },680 {681 "inputs": [682 { "internalType": "uint256", "name": "tokenId", "type": "uint256" },683 {684 "components": [685 { "internalType": "string", "name": "key", "type": "string" },686 { "internalType": "bytes", "name": "value", "type": "bytes" }687 ],688 "internalType": "struct Property[]",689 "name": "properties",690 "type": "tuple[]"691 }692 ],693 "name": "setProperties",694 "outputs": [],695 "stateMutability": "nonpayable",696 "type": "function"697 },698 {699 "inputs": [700 {701 "components": [702 { "internalType": "string", "name": "field_0", "type": "string" },703 {704 "components": [705 {706 "internalType": "enum EthTokenPermissions",707 "name": "field_0",708 "type": "uint8"709 },710 { "internalType": "bool", "name": "field_1", "type": "bool" }711 ],712 "internalType": "struct Tuple46[]",713 "name": "field_1",714 "type": "tuple[]"715 }716 ],717 "internalType": "struct Tuple48[]",718 "name": "permissions",719 "type": "tuple[]"720 }721 ],722 "name": "setTokenPropertyPermissions",723 "outputs": [],724 "stateMutability": "nonpayable",725 "type": "function"726 },727 {728 "inputs": [729 { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }730 ],731 "name": "supportsInterface",732 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],733 "stateMutability": "view",734 "type": "function"735 },736 {737 "inputs": [],738 "name": "symbol",739 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],740 "stateMutability": "view",741 "type": "function"742 },743 {744 "inputs": [745 { "internalType": "uint256", "name": "index", "type": "uint256" }746 ],747 "name": "tokenByIndex",748 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],749 "stateMutability": "view",750 "type": "function"751 },752 {753 "inputs": [754 { "internalType": "address", "name": "owner", "type": "address" },755 { "internalType": "uint256", "name": "index", "type": "uint256" }756 ],757 "name": "tokenOfOwnerByIndex",758 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],759 "stateMutability": "view",760 "type": "function"761 },762 {763 "inputs": [],764 "name": "tokenPropertyPermissions",765 "outputs": [766 {767 "components": [768 { "internalType": "string", "name": "field_0", "type": "string" },769 {770 "components": [771 {772 "internalType": "enum EthTokenPermissions",773 "name": "field_0",774 "type": "uint8"775 },776 { "internalType": "bool", "name": "field_1", "type": "bool" }777 ],778 "internalType": "struct Tuple46[]",779 "name": "field_1",780 "type": "tuple[]"781 }782 ],783 "internalType": "struct Tuple48[]",784 "name": "",785 "type": "tuple[]"786 }787 ],788 "stateMutability": "view",789 "type": "function"790 },791 {792 "inputs": [793 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }794 ],795 "name": "tokenURI",796 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],797 "stateMutability": "view",798 "type": "function"799 },800 {801 "inputs": [],802 "name": "totalSupply",803 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],804 "stateMutability": "view",805 "type": "function"806 },807 {808 "inputs": [809 { "internalType": "address", "name": "to", "type": "address" },810 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }811 ],812 "name": "transfer",813 "outputs": [],814 "stateMutability": "nonpayable",815 "type": "function"816 },817 {818 "inputs": [819 {820 "components": [821 { "internalType": "address", "name": "eth", "type": "address" },822 { "internalType": "uint256", "name": "sub", "type": "uint256" }823 ],824 "internalType": "struct EthCrossAccount",825 "name": "to",826 "type": "tuple"827 },828 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }829 ],830 "name": "transferCross",831 "outputs": [],832 "stateMutability": "nonpayable",833 "type": "function"834 },835 {836 "inputs": [837 { "internalType": "address", "name": "from", "type": "address" },838 { "internalType": "address", "name": "to", "type": "address" },839 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }840 ],841 "name": "transferFrom",842 "outputs": [],843 "stateMutability": "nonpayable",844 "type": "function"845 },846 {847 "inputs": [848 {849 "components": [850 { "internalType": "address", "name": "eth", "type": "address" },851 { "internalType": "uint256", "name": "sub", "type": "uint256" }852 ],853 "internalType": "struct EthCrossAccount",854 "name": "from",855 "type": "tuple"856 },857 {858 "components": [859 { "internalType": "address", "name": "eth", "type": "address" },860 { "internalType": "uint256", "name": "sub", "type": "uint256" }861 ],862 "internalType": "struct EthCrossAccount",863 "name": "to",864 "type": "tuple"865 },866 { "internalType": "uint256", "name": "tokenId", "type": "uint256" }867 ],868 "name": "transferFromCross",869 "outputs": [],870 "stateMutability": "nonpayable",871 "type": "function"872 },873 {874 "inputs": [],875 "name": "uniqueCollectionType",876 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],877 "stateMutability": "view",878 "type": "function"879 }880]tests/src/eth/api/UniqueNFT.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueNFT.sol
+++ b/tests/src/eth/api/UniqueNFT.sol
@@ -13,22 +13,28 @@
}
/// @title A contract that allows to set and delete token properties and change token property permissions.
-/// @dev the ERC-165 identifier for this interface is 0x91a97a68
+/// @dev the ERC-165 identifier for this interface is 0xde0695c2
interface TokenProperties is Dummy, ERC165 {
+ // /// @notice Set permissions for token property.
+ // /// @dev Throws error if `msg.sender` is not admin or owner of the collection.
+ // /// @param key Property key.
+ // /// @param isMutable Permission to mutate property.
+ // /// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.
+ // /// @param tokenOwner Permission to mutate property by token owner if property is mutable.
+ // /// @dev EVM selector for this function is: 0x222d97fa,
+ // /// or in textual repr: setTokenPropertyPermission(string,bool,bool,bool)
+ // function setTokenPropertyPermission(string memory key, bool isMutable, bool collectionAdmin, bool tokenOwner) external;
+
/// @notice Set permissions for token property.
/// @dev Throws error if `msg.sender` is not admin or owner of the collection.
- /// @param key Property key.
- /// @param isMutable Permission to mutate property.
- /// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.
- /// @param tokenOwner Permission to mutate property by token owner if property is mutable.
- /// @dev EVM selector for this function is: 0x222d97fa,
- /// or in textual repr: setTokenPropertyPermission(string,bool,bool,bool)
- function setTokenPropertyPermission(
- string memory key,
- bool isMutable,
- bool collectionAdmin,
- bool tokenOwner
- ) external;
+ /// @param permissions Permissions for keys.
+ /// @dev EVM selector for this function is: 0xbd92983a,
+ /// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[])
+ function setTokenPropertyPermissions(Tuple43[] memory permissions) external;
+
+ /// @dev EVM selector for this function is: 0xf23d7790,
+ /// or in textual repr: tokenPropertyPermissions()
+ function tokenPropertyPermissions() external view returns (Tuple43[] memory);
// /// @notice Set token property value.
// /// @dev Throws error if `msg.sender` has no permission to edit the property.
@@ -79,6 +85,24 @@
bytes value;
}
+enum EthTokenPermissions {
+ Mutable,
+ TokenOwner,
+ CollectionAdmin
+}
+
+/// @dev anonymous struct
+struct Tuple43 {
+ string field_0;
+ Tuple41[] field_1;
+}
+
+/// @dev anonymous struct
+struct Tuple41 {
+ EthTokenPermissions field_0;
+ bool field_1;
+}
+
/// @title A contract that allows you to work with collections.
/// @dev the ERC-165 identifier for this interface is 0xb5e1747f
interface Collection is Dummy, ERC165 {
tests/src/eth/tokenProperties.test.tsdiffbeforeafterboth--- a/tests/src/eth/tokenProperties.test.ts
+++ b/tests/src/eth/tokenProperties.test.ts
@@ -32,7 +32,7 @@
});
});
- itEth('Can be reconfigured', async({helper}) => {
+ itEth.only('Can be reconfigured', async({helper}) => {
const caller = await helper.eth.createAccountWithBalance(donor);
for(const [mutable,collectionAdmin, tokenOwner] of cartesian([], [false, true], [false, true], [false, true])) {
const collection = await helper.nft.mintCollection(alice);
@@ -41,12 +41,16 @@
const address = helper.ethAddress.fromCollectionId(collection.collectionId);
const contract = helper.ethNativeContract.collection(address, 'nft', caller);
- await contract.methods.setTokenPropertyPermission('testKey', mutable, collectionAdmin, tokenOwner).send({from: caller});
+ await contract.methods.setTokenPropertyPermissions([['testKey', [[0, mutable], [1, tokenOwner], [2, collectionAdmin]]]]).send({from: caller});
expect(await collection.getPropertyPermissions()).to.be.deep.equal([{
key: 'testKey',
permission: {mutable, collectionAdmin, tokenOwner},
}]);
+
+ expect(await contract.methods.tokenPropertyPermissions().call({from: caller})).to.be.like([
+ ['testKey', [['0', mutable], ['1', tokenOwner], ['2', collectionAdmin]]]
+ ]);
}
});