1234567891011121314151617import {itEth, usingEthPlaygrounds, expect} from './util';18import {IKeyringPair} from '@polkadot/types/types';19import {ITokenPropertyPermission} from '../util/playgrounds/types';2021describe('EVM token properties', () => {22 let donor: IKeyringPair;23 let alice: IKeyringPair;2425 before(async function() {26 await usingEthPlaygrounds(async (helper, privateKey) => {27 donor = await privateKey({filename: __filename});28 [alice] = await helper.arrange.createAccounts([100n], donor);29 });30 });3132 itEth('Can be reconfigured', async({helper}) => {33 const caller = await helper.eth.createAccountWithBalance(donor);34 for(const [mutable,collectionAdmin, tokenOwner] of cartesian([], [false, true], [false, true], [false, true])) {35 const collection = await helper.nft.mintCollection(alice);36 await collection.addAdmin(alice, {Ethereum: caller});37 38 const address = helper.ethAddress.fromCollectionId(collection.collectionId);39 const contract = helper.ethNativeContract.collection(address, 'nft', caller);40 41 await contract.methods.setTokenPropertyPermission('testKey', mutable, collectionAdmin, tokenOwner).send({from: caller});42 43 expect(await collection.getPropertyPermissions()).to.be.deep.equal([{44 key: 'testKey',45 permission: {mutable, collectionAdmin, tokenOwner},46 }]);47 }48 });4950 itEth('Can be set', async({helper}) => {51 const caller = await helper.eth.createAccountWithBalance(donor);52 const collection = await helper.nft.mintCollection(alice, {53 tokenPropertyPermissions: [{54 key: 'testKey',55 permission: {56 collectionAdmin: true,57 },58 }],59 });60 const token = await collection.mintToken(alice);6162 await collection.addAdmin(alice, {Ethereum: caller});6364 const address = helper.ethAddress.fromCollectionId(collection.collectionId);65 const contract = helper.ethNativeContract.collection(address, 'nft', caller);6667 await contract.methods.setProperty(token.tokenId, 'testKey', Buffer.from('testValue')).send({from: caller});6869 const [{value}] = await token.getProperties(['testKey']);70 expect(value).to.equal('testValue');71 });72 73 itEth('Can be multiple set for NFT ', async({helper}) => {74 const caller = await helper.eth.createAccountWithBalance(donor);75 76 const properties = Array(5).fill(0).map((_, i) => { return {field_0: `key_${i}`, field_1: Buffer.from(`value_${i}`)}; });77 const permissions: ITokenPropertyPermission[] = properties.map(p => { return {key: p.field_0, permission: {tokenOwner: true,78 collectionAdmin: true,79 mutable: true}}; });80 81 const collection = await helper.nft.mintCollection(alice, {82 tokenPrefix: 'ethp',83 tokenPropertyPermissions: permissions,84 });85 86 const token = await collection.mintToken(alice);87 88 const valuesBefore = await token.getProperties(properties.map(p => p.field_0));89 expect(valuesBefore).to.be.deep.equal([]);90 91 await collection.addAdmin(alice, {Ethereum: caller});9293 const address = helper.ethAddress.fromCollectionId(collection.collectionId);94 const contract = helper.ethNativeContract.collection(address, 'nft', caller);9596 await contract.methods.setProperties(token.tokenId, properties).send({from: caller});9798 const values = await token.getProperties(properties.map(p => p.field_0));99 expect(values).to.be.deep.equal(properties.map(p => { return {key: p.field_0, value: p.field_1.toString()}; }));100 });101 102 itEth('Can be multiple set for RFT ', async({helper}) => {103 const caller = await helper.eth.createAccountWithBalance(donor);104 105 const properties = Array(5).fill(0).map((_, i) => { return {field_0: `key_${i}`, field_1: Buffer.from(`value_${i}`)}; });106 const permissions: ITokenPropertyPermission[] = properties.map(p => { return {key: p.field_0, permission: {tokenOwner: true,107 collectionAdmin: true,108 mutable: true}}; });109 110 const collection = await helper.rft.mintCollection(alice, {111 tokenPrefix: 'ethp',112 tokenPropertyPermissions: permissions,113 });114 115 const token = await collection.mintToken(alice);116 117 const valuesBefore = await token.getProperties(properties.map(p => p.field_0));118 expect(valuesBefore).to.be.deep.equal([]);119 120 await collection.addAdmin(alice, {Ethereum: caller});121122 const address = helper.ethAddress.fromCollectionId(collection.collectionId);123 const contract = helper.ethNativeContract.collection(address, 'rft', caller);124125 await contract.methods.setProperties(token.tokenId, properties).send({from: caller});126127 const values = await token.getProperties(properties.map(p => p.field_0));128 expect(values).to.be.deep.equal(properties.map(p => { return {key: p.field_0, value: p.field_1.toString()}; }));129 });130131 itEth('Can be deleted', async({helper}) => {132 const caller = await helper.eth.createAccountWithBalance(donor);133 const collection = await helper.nft.mintCollection(alice, {134 tokenPropertyPermissions: [{135 key: 'testKey',136 permission: {137 mutable: true,138 collectionAdmin: true,139 },140 }],141 });142 143 const token = await collection.mintToken(alice);144 await token.setProperties(alice, [{key: 'testKey', value: 'testValue'}]);145146 await collection.addAdmin(alice, {Ethereum: caller});147148 const address = helper.ethAddress.fromCollectionId(collection.collectionId);149 const contract = helper.ethNativeContract.collection(address, 'nft', caller);150151 await contract.methods.deleteProperty(token.tokenId, 'testKey').send({from: caller});152153 const result = await token.getProperties(['testKey']);154 expect(result.length).to.equal(0);155 });156157 itEth('Can be read', async({helper}) => {158 const caller = helper.eth.createAccount();159 const collection = await helper.nft.mintCollection(alice, {160 tokenPropertyPermissions: [{161 key: 'testKey',162 permission: {163 collectionAdmin: true,164 },165 }],166 });167 168 const token = await collection.mintToken(alice);169 await token.setProperties(alice, [{key: 'testKey', value: 'testValue'}]);170171 const address = helper.ethAddress.fromCollectionId(collection.collectionId);172 const contract = helper.ethNativeContract.collection(address, 'nft', caller);173174 const value = await contract.methods.property(token.tokenId, 'testKey').call();175 expect(value).to.equal(helper.getWeb3().utils.toHex('testValue'));176 });177});178179180type ElementOf<A> = A extends readonly (infer T)[] ? T : never;181function* cartesian<T extends Array<Array<any>>, R extends Array<any>>(internalRest: [...R], ...args: [...T]): Generator<[...R, ...{[K in keyof T]: ElementOf<T[K]>}]> {182 if(args.length === 0) {183 yield internalRest as any;184 return;185 }186 for(const value of args[0]) {187 yield* cartesian([...internalRest, value], ...args.slice(1)) as any;188 }189}