--- a/pallets/common/src/erc.rs +++ b/pallets/common/src/erc.rs @@ -493,6 +493,21 @@ >::update_permissions(&caller, self, permissions).map_err(dispatch_to_evm::) } + /// Returns nesting for a collection + #[solidity(rename_selector = "collectionNestingRestrictedCollectionIds")] + fn collection_nesting_restricted_ids(&self) -> Result<(bool, Vec)> { + let nesting = self.collection.permissions.nesting(); + + Ok(( + nesting.token_owner, + nesting + .restricted + .clone() + .map(|b| b.0.into_inner().iter().map(|id| id.0.into()).collect()) + .unwrap_or_default(), + )) + } + /// Set the collection access method. /// @param mode Access mode /// 0 for Normal --- 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 0xcc1d80ca +/// @dev the ERC-165 identifier for this interface is 0xeecfdb34 contract Collection is Dummy, ERC165 { // /// Set collection property. // /// @@ -254,6 +254,15 @@ dummy = 0; } + /// Returns nesting for a collection + /// @dev EVM selector for this function is: 0x22d25bfe, + /// or in textual repr: collectionNestingRestrictedCollectionIds() + function collectionNestingRestrictedCollectionIds() public view returns (Tuple21 memory) { + require(false, stub_error); + dummy; + return Tuple21(false, new uint256[](0)); + } + /// Set the collection access method. /// @param mode Access mode /// 0 for Normal @@ -425,6 +434,12 @@ uint256 sub; } +/// @dev anonymous struct +struct Tuple21 { + bool field_0; + uint256[] field_1; +} + /// @dev Property struct struct Property { string key; --- 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 0xcc1d80ca +/// @dev the ERC-165 identifier for this interface is 0xeecfdb34 contract Collection is Dummy, ERC165 { // /// Set collection property. // /// @@ -355,6 +355,15 @@ dummy = 0; } + /// Returns nesting for a collection + /// @dev EVM selector for this function is: 0x22d25bfe, + /// or in textual repr: collectionNestingRestrictedCollectionIds() + function collectionNestingRestrictedCollectionIds() public view returns (Tuple34 memory) { + require(false, stub_error); + dummy; + return Tuple34(false, new uint256[](0)); + } + /// Set the collection access method. /// @param mode Access mode /// 0 for Normal @@ -527,6 +536,12 @@ } /// @dev anonymous struct +struct Tuple34 { + bool field_0; + uint256[] field_1; +} + +/// @dev anonymous struct struct Tuple30 { address field_0; uint256 field_1; --- 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 0xcc1d80ca +/// @dev the ERC-165 identifier for this interface is 0xeecfdb34 contract Collection is Dummy, ERC165 { // /// Set collection property. // /// @@ -355,6 +355,15 @@ dummy = 0; } + /// Returns nesting for a collection + /// @dev EVM selector for this function is: 0x22d25bfe, + /// or in textual repr: collectionNestingRestrictedCollectionIds() + function collectionNestingRestrictedCollectionIds() public view returns (Tuple33 memory) { + require(false, stub_error); + dummy; + return Tuple33(false, new uint256[](0)); + } + /// Set the collection access method. /// @param mode Access mode /// 0 for Normal @@ -527,6 +536,12 @@ } /// @dev anonymous struct +struct Tuple33 { + bool field_0; + uint256[] field_1; +} + +/// @dev anonymous struct struct Tuple29 { address field_0; uint256 field_1; --- a/tests/src/eth/abi/fungible.json +++ b/tests/src/eth/abi/fungible.json @@ -208,6 +208,27 @@ }, { "inputs": [], + "name": "collectionNestingRestrictedCollectionIds", + "outputs": [ + { + "components": [ + { "internalType": "bool", "name": "field_0", "type": "bool" }, + { + "internalType": "uint256[]", + "name": "field_1", + "type": "uint256[]" + } + ], + "internalType": "struct Tuple21", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], "name": "collectionOwner", "outputs": [ { --- a/tests/src/eth/abi/nonFungible.json +++ b/tests/src/eth/abi/nonFungible.json @@ -238,6 +238,27 @@ }, { "inputs": [], + "name": "collectionNestingRestrictedCollectionIds", + "outputs": [ + { + "components": [ + { "internalType": "bool", "name": "field_0", "type": "bool" }, + { + "internalType": "uint256[]", + "name": "field_1", + "type": "uint256[]" + } + ], + "internalType": "struct Tuple34", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], "name": "collectionOwner", "outputs": [ { --- a/tests/src/eth/abi/reFungible.json +++ b/tests/src/eth/abi/reFungible.json @@ -220,6 +220,27 @@ }, { "inputs": [], + "name": "collectionNestingRestrictedCollectionIds", + "outputs": [ + { + "components": [ + { "internalType": "bool", "name": "field_0", "type": "bool" }, + { + "internalType": "uint256[]", + "name": "field_1", + "type": "uint256[]" + } + ], + "internalType": "struct Tuple33", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], "name": "collectionOwner", "outputs": [ { --- 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 0xcc1d80ca +/// @dev the ERC-165 identifier for this interface is 0xeecfdb34 interface Collection is Dummy, ERC165 { // /// Set collection property. // /// @@ -166,6 +166,11 @@ /// or in textual repr: setCollectionNesting(bool,address[]) function setCollectionNesting(bool enable, address[] memory collections) external; + /// Returns nesting for a collection + /// @dev EVM selector for this function is: 0x22d25bfe, + /// or in textual repr: collectionNestingRestrictedCollectionIds() + function collectionNestingRestrictedCollectionIds() external view returns (Tuple20 memory); + /// Set the collection access method. /// @param mode Access mode /// 0 for Normal @@ -278,6 +283,12 @@ uint256 sub; } +/// @dev anonymous struct +struct Tuple20 { + bool field_0; + uint256[] field_1; +} + /// @dev Property struct struct Property { string key; --- 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 0xcc1d80ca +/// @dev the ERC-165 identifier for this interface is 0xeecfdb34 interface Collection is Dummy, ERC165 { // /// Set collection property. // /// @@ -233,6 +233,11 @@ /// or in textual repr: setCollectionNesting(bool,address[]) function setCollectionNesting(bool enable, address[] memory collections) external; + /// Returns nesting for a collection + /// @dev EVM selector for this function is: 0x22d25bfe, + /// or in textual repr: collectionNestingRestrictedCollectionIds() + function collectionNestingRestrictedCollectionIds() external view returns (Tuple31 memory); + /// Set the collection access method. /// @param mode Access mode /// 0 for Normal @@ -346,6 +351,12 @@ } /// @dev anonymous struct +struct Tuple31 { + bool field_0; + uint256[] field_1; +} + +/// @dev anonymous struct struct Tuple27 { address field_0; uint256 field_1; --- 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 0xcc1d80ca +/// @dev the ERC-165 identifier for this interface is 0xeecfdb34 interface Collection is Dummy, ERC165 { // /// Set collection property. // /// @@ -233,6 +233,11 @@ /// or in textual repr: setCollectionNesting(bool,address[]) function setCollectionNesting(bool enable, address[] memory collections) external; + /// Returns nesting for a collection + /// @dev EVM selector for this function is: 0x22d25bfe, + /// or in textual repr: collectionNestingRestrictedCollectionIds() + function collectionNestingRestrictedCollectionIds() external view returns (Tuple30 memory); + /// Set the collection access method. /// @param mode Access mode /// 0 for Normal @@ -346,6 +351,12 @@ } /// @dev anonymous struct +struct Tuple30 { + bool field_0; + uint256[] field_1; +} + +/// @dev anonymous struct struct Tuple26 { address field_0; uint256 field_1; --- a/tests/src/eth/nesting/nest.test.ts +++ b/tests/src/eth/nesting/nest.test.ts @@ -51,7 +51,20 @@ await contract.methods.transferFrom(targetNftTokenAddress, owner, secondTokenId).send({from: owner}); expect(await contract.methods.ownerOf(secondTokenId).call()).to.be.equal(owner); }); - + + itEth('NFT: collectionNestingRestrictedCollectionIds()', 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); + expect(await unnestedContract.methods.collectionNestingRestrictedCollectionIds().call({from: owner})).to.be.like([false, []]); + + const {contract} = await createNestingCollection(helper, owner); + 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()]]); + + }); + itEth('NFT: allows an Owner to nest/unnest their token (Restricted nesting)', async ({helper}) => { const owner = await helper.eth.createAccountWithBalance(donor);