git.delta.rocks / unique-network / refs/commits / ba711a7b1711

difftreelog

added `collectionNestingPermissions` funtion in `Collection` interface

PraetorP2022-12-06parent: #5223dbe.patch.diff
in: master

13 files changed

modifiedpallets/common/src/erc.rsdiffbeforeafterboth
--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -26,7 +26,7 @@
 	weight,
 };
 use pallet_evm_coder_substrate::dispatch_to_evm;
-use sp_std::vec::Vec;
+use sp_std::{vec, vec::Vec};
 use up_data_structs::{
 	AccessMode, CollectionMode, CollectionPermissions, OwnerRestrictedSet, Property,
 	SponsoringRateLimit, SponsorshipState,
@@ -35,7 +35,9 @@
 
 use crate::{
 	Pallet, CollectionHandle, Config, CollectionProperties, SelfWeightOf,
-	eth::{EthCrossAccount, convert_cross_account_to_uint256},
+	eth::{
+		EthCrossAccount, convert_cross_account_to_uint256, CollectionPermissions as EvmPermissions,
+	},
 	weights::WeightInfo,
 };
 
@@ -508,6 +510,14 @@
 		))
 	}
 
+	/// Returns permissions for a collection
+	fn collection_nesting_permissions(&self) -> Result<Vec<(EvmPermissions, bool)>> {
+		let nesting = self.collection.permissions.nesting();
+		Ok(vec![
+			(EvmPermissions::CollectionAdmin, nesting.collection_admin),
+			(EvmPermissions::TokenOwner, nesting.token_owner),
+		])
+	}
 	/// Set the collection access method.
 	/// @param mode Access mode
 	/// 	0 for Normal
modifiedpallets/common/src/eth.rsdiffbeforeafterboth
--- a/pallets/common/src/eth.rs
+++ b/pallets/common/src/eth.rs
@@ -155,3 +155,10 @@
 		}
 	}
 }
+#[derive(Default, Debug, Clone, Copy, AbiCoder)]
+#[repr(u8)]
+pub enum CollectionPermissions {
+	#[default]
+	CollectionAdmin,
+	TokenOwner,
+}
modifiedpallets/fungible/src/stubs/UniqueFungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/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 0xeecfdb34
+/// @dev the ERC-165 identifier for this interface is 0xb5e1747f
 contract Collection is Dummy, ERC165 {
 	// /// Set collection property.
 	// ///
@@ -263,6 +263,15 @@
 		return Tuple21(false, new uint256[](0));
 	}
 
+	/// Returns permissions for a collection
+	/// @dev EVM selector for this function is: 0x5b2eaf4b,
+	///  or in textual repr: collectionNestingPermissions()
+	function collectionNestingPermissions() public view returns (Tuple24[] memory) {
+		require(false, stub_error);
+		dummy;
+		return new Tuple24[](0);
+	}
+
 	/// Set the collection access method.
 	/// @param mode Access mode
 	/// 	0 for Normal
@@ -434,6 +443,17 @@
 	uint256 sub;
 }
 
+enum CollectionPermissions {
+	CollectionAdmin,
+	TokenOwner
+}
+
+/// @dev anonymous struct
+struct Tuple24 {
+	CollectionPermissions field_0;
+	bool field_1;
+}
+
 /// @dev anonymous struct
 struct Tuple21 {
 	bool field_0;
modifiedpallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth
--- a/pallets/nonfungible/src/stubs/UniqueNFT.sol
+++ b/pallets/nonfungible/src/stubs/UniqueNFT.sol
@@ -119,7 +119,7 @@
 }
 
 /// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0xeecfdb34
+/// @dev the ERC-165 identifier for this interface is 0xb5e1747f
 contract Collection is Dummy, ERC165 {
 	// /// Set collection property.
 	// ///
@@ -364,6 +364,15 @@
 		return Tuple34(false, new uint256[](0));
 	}
 
+	/// Returns permissions for a collection
+	/// @dev EVM selector for this function is: 0x5b2eaf4b,
+	///  or in textual repr: collectionNestingPermissions()
+	function collectionNestingPermissions() public view returns (Tuple37[] memory) {
+		require(false, stub_error);
+		dummy;
+		return new Tuple37[](0);
+	}
+
 	/// Set the collection access method.
 	/// @param mode Access mode
 	/// 	0 for Normal
@@ -535,6 +544,17 @@
 	uint256 sub;
 }
 
+enum CollectionPermissions {
+	CollectionAdmin,
+	TokenOwner
+}
+
+/// @dev anonymous struct
+struct Tuple37 {
+	CollectionPermissions field_0;
+	bool field_1;
+}
+
 /// @dev anonymous struct
 struct Tuple34 {
 	bool field_0;
modifiedpallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth
--- a/pallets/refungible/src/stubs/UniqueRefungible.sol
+++ b/pallets/refungible/src/stubs/UniqueRefungible.sol
@@ -119,7 +119,7 @@
 }
 
 /// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0xeecfdb34
+/// @dev the ERC-165 identifier for this interface is 0xb5e1747f
 contract Collection is Dummy, ERC165 {
 	// /// Set collection property.
 	// ///
@@ -364,6 +364,15 @@
 		return Tuple33(false, new uint256[](0));
 	}
 
+	/// Returns permissions for a collection
+	/// @dev EVM selector for this function is: 0x5b2eaf4b,
+	///  or in textual repr: collectionNestingPermissions()
+	function collectionNestingPermissions() public view returns (Tuple36[] memory) {
+		require(false, stub_error);
+		dummy;
+		return new Tuple36[](0);
+	}
+
 	/// Set the collection access method.
 	/// @param mode Access mode
 	/// 	0 for Normal
@@ -535,6 +544,17 @@
 	uint256 sub;
 }
 
+enum CollectionPermissions {
+	CollectionAdmin,
+	TokenOwner
+}
+
+/// @dev anonymous struct
+struct Tuple36 {
+	CollectionPermissions field_0;
+	bool field_1;
+}
+
 /// @dev anonymous struct
 struct Tuple33 {
 	bool field_0;
modifiedtests/src/eth/abi/fungible.jsondiffbeforeafterboth
--- a/tests/src/eth/abi/fungible.json
+++ b/tests/src/eth/abi/fungible.json
@@ -208,6 +208,27 @@
   },
   {
     "inputs": [],
+    "name": "collectionNestingPermissions",
+    "outputs": [
+      {
+        "components": [
+          {
+            "internalType": "enum CollectionPermissions",
+            "name": "field_0",
+            "type": "uint8"
+          },
+          { "internalType": "bool", "name": "field_1", "type": "bool" }
+        ],
+        "internalType": "struct Tuple24[]",
+        "name": "",
+        "type": "tuple[]"
+      }
+    ],
+    "stateMutability": "view",
+    "type": "function"
+  },
+  {
+    "inputs": [],
     "name": "collectionNestingRestrictedCollectionIds",
     "outputs": [
       {
modifiedtests/src/eth/abi/nonFungible.jsondiffbeforeafterboth
before · tests/src/eth/abi/nonFungible.json
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": "collectionNestingRestrictedCollectionIds",242    "outputs": [243      {244        "components": [245          { "internalType": "bool", "name": "field_0", "type": "bool" },246          {247            "internalType": "uint256[]",248            "name": "field_1",249            "type": "uint256[]"250          }251        ],252        "internalType": "struct Tuple34",253        "name": "",254        "type": "tuple"255      }256    ],257    "stateMutability": "view",258    "type": "function"259  },260  {261    "inputs": [],262    "name": "collectionOwner",263    "outputs": [264      {265        "components": [266          { "internalType": "address", "name": "eth", "type": "address" },267          { "internalType": "uint256", "name": "sub", "type": "uint256" }268        ],269        "internalType": "struct EthCrossAccount",270        "name": "",271        "type": "tuple"272      }273    ],274    "stateMutability": "view",275    "type": "function"276  },277  {278    "inputs": [279      { "internalType": "string[]", "name": "keys", "type": "string[]" }280    ],281    "name": "collectionProperties",282    "outputs": [283      {284        "components": [285          { "internalType": "string", "name": "key", "type": "string" },286          { "internalType": "bytes", "name": "value", "type": "bytes" }287        ],288        "internalType": "struct Property[]",289        "name": "",290        "type": "tuple[]"291      }292    ],293    "stateMutability": "view",294    "type": "function"295  },296  {297    "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],298    "name": "collectionProperty",299    "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],300    "stateMutability": "view",301    "type": "function"302  },303  {304    "inputs": [],305    "name": "collectionSponsor",306    "outputs": [307      {308        "components": [309          { "internalType": "address", "name": "field_0", "type": "address" },310          { "internalType": "uint256", "name": "field_1", "type": "uint256" }311        ],312        "internalType": "struct Tuple30",313        "name": "",314        "type": "tuple"315      }316    ],317    "stateMutability": "view",318    "type": "function"319  },320  {321    "inputs": [],322    "name": "confirmCollectionSponsorship",323    "outputs": [],324    "stateMutability": "nonpayable",325    "type": "function"326  },327  {328    "inputs": [],329    "name": "contractAddress",330    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],331    "stateMutability": "view",332    "type": "function"333  },334  {335    "inputs": [336      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }337    ],338    "name": "crossOwnerOf",339    "outputs": [340      {341        "components": [342          { "internalType": "address", "name": "eth", "type": "address" },343          { "internalType": "uint256", "name": "sub", "type": "uint256" }344        ],345        "internalType": "struct EthCrossAccount",346        "name": "",347        "type": "tuple"348      }349    ],350    "stateMutability": "view",351    "type": "function"352  },353  {354    "inputs": [355      { "internalType": "string[]", "name": "keys", "type": "string[]" }356    ],357    "name": "deleteCollectionProperties",358    "outputs": [],359    "stateMutability": "nonpayable",360    "type": "function"361  },362  {363    "inputs": [364      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },365      { "internalType": "string[]", "name": "keys", "type": "string[]" }366    ],367    "name": "deleteProperties",368    "outputs": [],369    "stateMutability": "nonpayable",370    "type": "function"371  },372  {373    "inputs": [],374    "name": "description",375    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],376    "stateMutability": "view",377    "type": "function"378  },379  {380    "inputs": [],381    "name": "finishMinting",382    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],383    "stateMutability": "nonpayable",384    "type": "function"385  },386  {387    "inputs": [388      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }389    ],390    "name": "getApproved",391    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],392    "stateMutability": "view",393    "type": "function"394  },395  {396    "inputs": [],397    "name": "hasCollectionPendingSponsor",398    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],399    "stateMutability": "view",400    "type": "function"401  },402  {403    "inputs": [404      { "internalType": "address", "name": "owner", "type": "address" },405      { "internalType": "address", "name": "operator", "type": "address" }406    ],407    "name": "isApprovedForAll",408    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],409    "stateMutability": "view",410    "type": "function"411  },412  {413    "inputs": [414      {415        "components": [416          { "internalType": "address", "name": "eth", "type": "address" },417          { "internalType": "uint256", "name": "sub", "type": "uint256" }418        ],419        "internalType": "struct EthCrossAccount",420        "name": "user",421        "type": "tuple"422      }423    ],424    "name": "isOwnerOrAdminCross",425    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],426    "stateMutability": "view",427    "type": "function"428  },429  {430    "inputs": [{ "internalType": "address", "name": "to", "type": "address" }],431    "name": "mint",432    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],433    "stateMutability": "nonpayable",434    "type": "function"435  },436  {437    "inputs": [438      { "internalType": "address", "name": "to", "type": "address" },439      { "internalType": "string", "name": "tokenUri", "type": "string" }440    ],441    "name": "mintWithTokenURI",442    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],443    "stateMutability": "nonpayable",444    "type": "function"445  },446  {447    "inputs": [],448    "name": "mintingFinished",449    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],450    "stateMutability": "view",451    "type": "function"452  },453  {454    "inputs": [],455    "name": "name",456    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],457    "stateMutability": "view",458    "type": "function"459  },460  {461    "inputs": [],462    "name": "nextTokenId",463    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],464    "stateMutability": "view",465    "type": "function"466  },467  {468    "inputs": [469      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }470    ],471    "name": "ownerOf",472    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],473    "stateMutability": "view",474    "type": "function"475  },476  {477    "inputs": [478      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },479      { "internalType": "string[]", "name": "keys", "type": "string[]" }480    ],481    "name": "properties",482    "outputs": [483      {484        "components": [485          { "internalType": "string", "name": "key", "type": "string" },486          { "internalType": "bytes", "name": "value", "type": "bytes" }487        ],488        "internalType": "struct Property[]",489        "name": "",490        "type": "tuple[]"491      }492    ],493    "stateMutability": "view",494    "type": "function"495  },496  {497    "inputs": [498      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },499      { "internalType": "string", "name": "key", "type": "string" }500    ],501    "name": "property",502    "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],503    "stateMutability": "view",504    "type": "function"505  },506  {507    "inputs": [508      {509        "components": [510          { "internalType": "address", "name": "eth", "type": "address" },511          { "internalType": "uint256", "name": "sub", "type": "uint256" }512        ],513        "internalType": "struct EthCrossAccount",514        "name": "admin",515        "type": "tuple"516      }517    ],518    "name": "removeCollectionAdminCross",519    "outputs": [],520    "stateMutability": "nonpayable",521    "type": "function"522  },523  {524    "inputs": [],525    "name": "removeCollectionSponsor",526    "outputs": [],527    "stateMutability": "nonpayable",528    "type": "function"529  },530  {531    "inputs": [532      {533        "components": [534          { "internalType": "address", "name": "eth", "type": "address" },535          { "internalType": "uint256", "name": "sub", "type": "uint256" }536        ],537        "internalType": "struct EthCrossAccount",538        "name": "user",539        "type": "tuple"540      }541    ],542    "name": "removeFromCollectionAllowListCross",543    "outputs": [],544    "stateMutability": "nonpayable",545    "type": "function"546  },547  {548    "inputs": [549      { "internalType": "address", "name": "from", "type": "address" },550      { "internalType": "address", "name": "to", "type": "address" },551      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }552    ],553    "name": "safeTransferFrom",554    "outputs": [],555    "stateMutability": "nonpayable",556    "type": "function"557  },558  {559    "inputs": [560      { "internalType": "address", "name": "from", "type": "address" },561      { "internalType": "address", "name": "to", "type": "address" },562      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },563      { "internalType": "bytes", "name": "data", "type": "bytes" }564    ],565    "name": "safeTransferFrom",566    "outputs": [],567    "stateMutability": "nonpayable",568    "type": "function"569  },570  {571    "inputs": [572      { "internalType": "address", "name": "operator", "type": "address" },573      { "internalType": "bool", "name": "approved", "type": "bool" }574    ],575    "name": "setApprovalForAll",576    "outputs": [],577    "stateMutability": "nonpayable",578    "type": "function"579  },580  {581    "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],582    "name": "setCollectionAccess",583    "outputs": [],584    "stateMutability": "nonpayable",585    "type": "function"586  },587  {588    "inputs": [589      { "internalType": "string", "name": "limit", "type": "string" },590      { "internalType": "uint256", "name": "value", "type": "uint256" }591    ],592    "name": "setCollectionLimit",593    "outputs": [],594    "stateMutability": "nonpayable",595    "type": "function"596  },597  {598    "inputs": [{ "internalType": "bool", "name": "mode", "type": "bool" }],599    "name": "setCollectionMintMode",600    "outputs": [],601    "stateMutability": "nonpayable",602    "type": "function"603  },604  {605    "inputs": [{ "internalType": "bool", "name": "enable", "type": "bool" }],606    "name": "setCollectionNesting",607    "outputs": [],608    "stateMutability": "nonpayable",609    "type": "function"610  },611  {612    "inputs": [613      { "internalType": "bool", "name": "enable", "type": "bool" },614      {615        "internalType": "address[]",616        "name": "collections",617        "type": "address[]"618      }619    ],620    "name": "setCollectionNesting",621    "outputs": [],622    "stateMutability": "nonpayable",623    "type": "function"624  },625  {626    "inputs": [627      {628        "components": [629          { "internalType": "string", "name": "key", "type": "string" },630          { "internalType": "bytes", "name": "value", "type": "bytes" }631        ],632        "internalType": "struct Property[]",633        "name": "properties",634        "type": "tuple[]"635      }636    ],637    "name": "setCollectionProperties",638    "outputs": [],639    "stateMutability": "nonpayable",640    "type": "function"641  },642  {643    "inputs": [644      {645        "components": [646          { "internalType": "address", "name": "eth", "type": "address" },647          { "internalType": "uint256", "name": "sub", "type": "uint256" }648        ],649        "internalType": "struct EthCrossAccount",650        "name": "sponsor",651        "type": "tuple"652      }653    ],654    "name": "setCollectionSponsorCross",655    "outputs": [],656    "stateMutability": "nonpayable",657    "type": "function"658  },659  {660    "inputs": [661      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },662      {663        "components": [664          { "internalType": "string", "name": "key", "type": "string" },665          { "internalType": "bytes", "name": "value", "type": "bytes" }666        ],667        "internalType": "struct Property[]",668        "name": "properties",669        "type": "tuple[]"670      }671    ],672    "name": "setProperties",673    "outputs": [],674    "stateMutability": "nonpayable",675    "type": "function"676  },677  {678    "inputs": [679      { "internalType": "string", "name": "key", "type": "string" },680      { "internalType": "bool", "name": "isMutable", "type": "bool" },681      { "internalType": "bool", "name": "collectionAdmin", "type": "bool" },682      { "internalType": "bool", "name": "tokenOwner", "type": "bool" }683    ],684    "name": "setTokenPropertyPermission",685    "outputs": [],686    "stateMutability": "nonpayable",687    "type": "function"688  },689  {690    "inputs": [691      { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }692    ],693    "name": "supportsInterface",694    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],695    "stateMutability": "view",696    "type": "function"697  },698  {699    "inputs": [],700    "name": "symbol",701    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],702    "stateMutability": "view",703    "type": "function"704  },705  {706    "inputs": [707      { "internalType": "uint256", "name": "index", "type": "uint256" }708    ],709    "name": "tokenByIndex",710    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],711    "stateMutability": "view",712    "type": "function"713  },714  {715    "inputs": [716      { "internalType": "address", "name": "owner", "type": "address" },717      { "internalType": "uint256", "name": "index", "type": "uint256" }718    ],719    "name": "tokenOfOwnerByIndex",720    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],721    "stateMutability": "view",722    "type": "function"723  },724  {725    "inputs": [726      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }727    ],728    "name": "tokenURI",729    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],730    "stateMutability": "view",731    "type": "function"732  },733  {734    "inputs": [],735    "name": "totalSupply",736    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],737    "stateMutability": "view",738    "type": "function"739  },740  {741    "inputs": [742      { "internalType": "address", "name": "to", "type": "address" },743      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }744    ],745    "name": "transfer",746    "outputs": [],747    "stateMutability": "nonpayable",748    "type": "function"749  },750  {751    "inputs": [752      {753        "components": [754          { "internalType": "address", "name": "eth", "type": "address" },755          { "internalType": "uint256", "name": "sub", "type": "uint256" }756        ],757        "internalType": "struct EthCrossAccount",758        "name": "to",759        "type": "tuple"760      },761      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }762    ],763    "name": "transferCross",764    "outputs": [],765    "stateMutability": "nonpayable",766    "type": "function"767  },768  {769    "inputs": [770      { "internalType": "address", "name": "from", "type": "address" },771      { "internalType": "address", "name": "to", "type": "address" },772      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }773    ],774    "name": "transferFrom",775    "outputs": [],776    "stateMutability": "nonpayable",777    "type": "function"778  },779  {780    "inputs": [781      {782        "components": [783          { "internalType": "address", "name": "eth", "type": "address" },784          { "internalType": "uint256", "name": "sub", "type": "uint256" }785        ],786        "internalType": "struct EthCrossAccount",787        "name": "from",788        "type": "tuple"789      },790      {791        "components": [792          { "internalType": "address", "name": "eth", "type": "address" },793          { "internalType": "uint256", "name": "sub", "type": "uint256" }794        ],795        "internalType": "struct EthCrossAccount",796        "name": "to",797        "type": "tuple"798      },799      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }800    ],801    "name": "transferFromCross",802    "outputs": [],803    "stateMutability": "nonpayable",804    "type": "function"805  },806  {807    "inputs": [],808    "name": "uniqueCollectionType",809    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],810    "stateMutability": "view",811    "type": "function"812  }813]
after · tests/src/eth/abi/nonFungible.json
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      { "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]
modifiedtests/src/eth/abi/reFungible.jsondiffbeforeafterboth
--- a/tests/src/eth/abi/reFungible.json
+++ b/tests/src/eth/abi/reFungible.json
@@ -220,6 +220,27 @@
   },
   {
     "inputs": [],
+    "name": "collectionNestingPermissions",
+    "outputs": [
+      {
+        "components": [
+          {
+            "internalType": "enum CollectionPermissions",
+            "name": "field_0",
+            "type": "uint8"
+          },
+          { "internalType": "bool", "name": "field_1", "type": "bool" }
+        ],
+        "internalType": "struct Tuple36[]",
+        "name": "",
+        "type": "tuple[]"
+      }
+    ],
+    "stateMutability": "view",
+    "type": "function"
+  },
+  {
+    "inputs": [],
     "name": "collectionNestingRestrictedCollectionIds",
     "outputs": [
       {
modifiedtests/src/eth/api/UniqueFungible.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueFungible.sol
+++ b/tests/src/eth/api/UniqueFungible.sol
@@ -13,7 +13,7 @@
 }
 
 /// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0xeecfdb34
+/// @dev the ERC-165 identifier for this interface is 0xb5e1747f
 interface Collection is Dummy, ERC165 {
 	// /// Set collection property.
 	// ///
@@ -171,6 +171,11 @@
 	///  or in textual repr: collectionNestingRestrictedCollectionIds()
 	function collectionNestingRestrictedCollectionIds() external view returns (Tuple20 memory);
 
+	/// Returns permissions for a collection
+	/// @dev EVM selector for this function is: 0x5b2eaf4b,
+	///  or in textual repr: collectionNestingPermissions()
+	function collectionNestingPermissions() external view returns (Tuple23[] memory);
+
 	/// Set the collection access method.
 	/// @param mode Access mode
 	/// 	0 for Normal
@@ -284,6 +289,17 @@
 }
 
 /// @dev anonymous struct
+struct Tuple23 {
+	CollectionPermissions field_0;
+	bool field_1;
+}
+
+enum CollectionPermissions {
+	CollectionAdmin,
+	TokenOwner
+}
+
+/// @dev anonymous struct
 struct Tuple20 {
 	bool field_0;
 	uint256[] field_1;
modifiedtests/src/eth/api/UniqueNFT.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueNFT.sol
+++ b/tests/src/eth/api/UniqueNFT.sol
@@ -80,7 +80,7 @@
 }
 
 /// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0xeecfdb34
+/// @dev the ERC-165 identifier for this interface is 0xb5e1747f
 interface Collection is Dummy, ERC165 {
 	// /// Set collection property.
 	// ///
@@ -238,6 +238,11 @@
 	///  or in textual repr: collectionNestingRestrictedCollectionIds()
 	function collectionNestingRestrictedCollectionIds() external view returns (Tuple31 memory);
 
+	/// Returns permissions for a collection
+	/// @dev EVM selector for this function is: 0x5b2eaf4b,
+	///  or in textual repr: collectionNestingPermissions()
+	function collectionNestingPermissions() external view returns (Tuple34[] memory);
+
 	/// Set the collection access method.
 	/// @param mode Access mode
 	/// 	0 for Normal
@@ -351,6 +356,17 @@
 }
 
 /// @dev anonymous struct
+struct Tuple34 {
+	CollectionPermissions field_0;
+	bool field_1;
+}
+
+enum CollectionPermissions {
+	CollectionAdmin,
+	TokenOwner
+}
+
+/// @dev anonymous struct
 struct Tuple31 {
 	bool field_0;
 	uint256[] field_1;
modifiedtests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueRefungible.sol
+++ b/tests/src/eth/api/UniqueRefungible.sol
@@ -80,7 +80,7 @@
 }
 
 /// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0xeecfdb34
+/// @dev the ERC-165 identifier for this interface is 0xb5e1747f
 interface Collection is Dummy, ERC165 {
 	// /// Set collection property.
 	// ///
@@ -238,6 +238,11 @@
 	///  or in textual repr: collectionNestingRestrictedCollectionIds()
 	function collectionNestingRestrictedCollectionIds() external view returns (Tuple30 memory);
 
+	/// Returns permissions for a collection
+	/// @dev EVM selector for this function is: 0x5b2eaf4b,
+	///  or in textual repr: collectionNestingPermissions()
+	function collectionNestingPermissions() external view returns (Tuple33[] memory);
+
 	/// Set the collection access method.
 	/// @param mode Access mode
 	/// 	0 for Normal
@@ -351,6 +356,17 @@
 }
 
 /// @dev anonymous struct
+struct Tuple33 {
+	CollectionPermissions field_0;
+	bool field_1;
+}
+
+enum CollectionPermissions {
+	CollectionAdmin,
+	TokenOwner
+}
+
+/// @dev anonymous struct
 struct Tuple30 {
 	bool field_0;
 	uint256[] field_1;
modifiedtests/src/eth/nesting/nest.test.tsdiffbeforeafterboth
--- a/tests/src/eth/nesting/nest.test.ts
+++ b/tests/src/eth/nesting/nest.test.ts
@@ -52,7 +52,7 @@
       expect(await contract.methods.ownerOf(secondTokenId).call()).to.be.equal(owner);
     });
     
-    itEth('NFT: collectionNestingRestrictedCollectionIds()', async ({helper}) => {
+    itEth('NFT: collectionNestingRestrictedCollectionIds() & collectionNestingPermissions', async ({helper}) => {
       const owner = await helper.eth.createAccountWithBalance(donor);
       const {collectionId: unnestedCollsectionId, collectionAddress: unnsetedCollectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
       const unnestedContract = helper.ethNativeContract.collection(unnsetedCollectionAddress, 'nft', owner);
@@ -62,7 +62,9 @@
       expect(await contract.methods.collectionNestingRestrictedCollectionIds().call({from: owner})).to.be.like([true, []]);
       await contract.methods.setCollectionNesting(true, [unnsetedCollectionAddress]).send({from: owner});
       expect(await contract.methods.collectionNestingRestrictedCollectionIds().call({from: owner})).to.be.like([true, [unnestedCollsectionId.toString()]]);
-      
+      expect(await contract.methods.collectionNestingPermissions().call({from: owner})).to.be.like([['0', false], ['1', true]]);
+      await contract.methods.setCollectionNesting(false).send({from: owner});
+      expect(await contract.methods.collectionNestingPermissions().call({from: owner})).to.be.like([['0', false], ['1', false]]);
     });
     
     itEth('NFT: allows an Owner to nest/unnest their token (Restricted nesting)', async ({helper}) => {