--- a/pallets/refungible/src/stubs/UniqueRefungible.sol +++ b/pallets/refungible/src/stubs/UniqueRefungible.sol @@ -18,30 +18,45 @@ } /// @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(Tuple53[] memory permissions) public { require(false, stub_error); - key; - isMutable; - collectionAdmin; - tokenOwner; + permissions; dummy = 0; } + /// @notice Get permissions for token properties. + /// @dev EVM selector for this function is: 0xf23d7790, + /// or in textual repr: tokenPropertyPermissions() + function tokenPropertyPermissions() public view returns (Tuple53[] memory) { + require(false, stub_error); + dummy; + return new Tuple53[](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 +133,24 @@ bytes value; } +enum EthTokenPermissions { + Mutable, + TokenOwner, + CollectionAdmin +} + +/// @dev anonymous struct +struct Tuple53 { + string field_0; + Tuple51[] field_1; +} + +/// @dev anonymous struct +struct Tuple51 { + 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 { --- a/tests/src/eth/abi/reFungible.json +++ b/tests/src/eth/abi/reFungible.json @@ -679,12 +679,29 @@ }, { "inputs": [ - { "internalType": "string", "name": "key", "type": "string" }, - { "internalType": "bool", "name": "isMutable", "type": "bool" }, - { "internalType": "bool", "name": "collectionAdmin", "type": "bool" }, - { "internalType": "bool", "name": "tokenOwner", "type": "bool" } + { + "components": [ + { "internalType": "string", "name": "field_0", "type": "string" }, + { + "components": [ + { + "internalType": "enum EthTokenPermissions", + "name": "field_0", + "type": "uint8" + }, + { "internalType": "bool", "name": "field_1", "type": "bool" } + ], + "internalType": "struct Tuple51[]", + "name": "field_1", + "type": "tuple[]" + } + ], + "internalType": "struct Tuple53[]", + "name": "permissions", + "type": "tuple[]" + } ], - "name": "setTokenPropertyPermission", + "name": "setTokenPropertyPermissions", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -734,6 +751,35 @@ "type": "function" }, { + "inputs": [], + "name": "tokenPropertyPermissions", + "outputs": [ + { + "components": [ + { "internalType": "string", "name": "field_0", "type": "string" }, + { + "components": [ + { + "internalType": "enum EthTokenPermissions", + "name": "field_0", + "type": "uint8" + }, + { "internalType": "bool", "name": "field_1", "type": "bool" } + ], + "internalType": "struct Tuple51[]", + "name": "field_1", + "type": "tuple[]" + } + ], + "internalType": "struct Tuple53[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { "inputs": [ { "internalType": "uint256", "name": "tokenId", "type": "uint256" } ], --- a/tests/src/eth/api/UniqueRefungible.sol +++ b/tests/src/eth/api/UniqueRefungible.sol @@ -13,22 +13,29 @@ } /// @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(Tuple47[] memory permissions) external; + + /// @notice Get permissions for token properties. + /// @dev EVM selector for this function is: 0xf23d7790, + /// or in textual repr: tokenPropertyPermissions() + function tokenPropertyPermissions() external view returns (Tuple47[] memory); // /// @notice Set token property value. // /// @dev Throws error if `msg.sender` has no permission to edit the property. @@ -79,6 +86,24 @@ bytes value; } +enum EthTokenPermissions { + Mutable, + TokenOwner, + CollectionAdmin +} + +/// @dev anonymous struct +struct Tuple47 { + string field_0; + Tuple45[] field_1; +} + +/// @dev anonymous struct +struct Tuple45 { + 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 { --- a/tests/src/eth/events.test.ts +++ b/tests/src/eth/events.test.ts @@ -119,7 +119,7 @@ ethEvents.push(event); }); const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['PropertyPermissionSet']}]); - await collection.methods.setTokenPropertyPermission('testKey', true, true, true).send({from: owner}); + await collection.methods.setTokenPropertyPermissions([['testKey', [[0, true], [1, true], [2, true]]]]).send({from: owner}); await helper.wait.newBlocks(1); expect(ethEvents).to.be.like([ { @@ -374,7 +374,7 @@ const collectionHelper = helper.ethNativeContract.collectionHelpers(owner); const result = await collection.methods.mint(owner).send({from: owner}); const tokenId = result.events.Transfer.returnValues.tokenId; - await collection.methods.setTokenPropertyPermission('A', true, true, true).send({from: owner}); + await collection.methods.setTokenPropertyPermissions([['A', [[0, true], [1, true], [2, true]]]]).send({from: owner}); const ethEvents: any = []; --- a/tests/src/eth/tokenProperties.test.ts +++ b/tests/src/eth/tokenProperties.test.ts @@ -17,7 +17,7 @@ import {IKeyringPair} from '@polkadot/types/types'; import {Contract} from 'web3-eth-contract'; import {itEth, usingEthPlaygrounds, expect} from './util'; -import {ITokenPropertyPermission} from '../util/playgrounds/types'; +import {ITokenPropertyPermission, TCollectionMode} from '../util/playgrounds/types'; import {Pallets} from '../util'; import {UniqueNFTCollection, UniqueNFToken, UniqueRFTCollection} from '../util/playgrounds/unique'; @@ -32,28 +32,32 @@ }); }); - itEth('Can be reconfigured', async({helper}) => { + [ + {mode: 'nft'}, + {mode: 'rft'} + ].map(testCase => + itEth(`[${testCase.mode}] Set and get token property permissions`, async({helper}) => { const owner = await helper.eth.createAccountWithBalance(donor); - const caller = await helper.eth.createAccountWithBalance(donor); + const caller = await helper.ethCrossAccount.createAccountWithBalance(donor); + const mode: any = testCase.mode; for(const [mutable,collectionAdmin, tokenOwner] of cartesian([], [false, true], [false, true], [false, true])) { - const collection = await helper.nft.mintCollection(alice); - await collection.addAdmin(alice, {Ethereum: caller}); + const {collectionId, collectionAddress} = await helper.eth.createCollection(mode, owner, 'A', 'B', 'C'); + const collection = await helper.ethNativeContract.collection(collectionAddress, mode, owner); + await collection.methods.addCollectionAdminCross(caller).send({from: owner}); + + await collection.methods.setTokenPropertyPermissions([['testKey', [[0, mutable], [1, tokenOwner], [2, collectionAdmin]]]]).send({from: caller.eth}); - const address = helper.ethAddress.fromCollectionId(collection.collectionId); - const contract = helper.ethNativeContract.collection(address, 'nft', caller); - - await contract.methods.setTokenPropertyPermissions([['testKey', [[0, mutable], [1, tokenOwner], [2, collectionAdmin]]]]).send({from: caller}); - - expect(await collection.getPropertyPermissions()).to.be.deep.equal([{ + expect(await helper.nft.getPropertyPermissions(collectionId)).to.be.deep.equal([{ key: 'testKey', permission: {mutable, collectionAdmin, tokenOwner}, }]); - expect(await contract.methods.tokenPropertyPermissions().call({from: caller})).to.be.like([ + expect(await collection.methods.tokenPropertyPermissions().call({from: caller.eth})).to.be.like([ ['testKey', [['0', mutable], ['1', tokenOwner], ['2', collectionAdmin]]] ]); } - }); + }) + ); [ {