12345678910111213141516import {IKeyringPair} from '@polkadot/types/types';17import {expect} from 'chai';18import {IEthCrossAccountId} from '../util/playgrounds/types';19import {usingEthPlaygrounds, itEth} from './util';20import {EthUniqueHelper} from './util/playgrounds/unique.dev';2122async function recordEthFee(helper: EthUniqueHelper, userAddress: string, call: () => Promise<any>) {23 const before = await helper.balance.getSubstrate(helper.address.ethToSubstrate(userAddress));24 await call();25 await helper.wait.newBlocks(1);26 const after = await helper.balance.getSubstrate(helper.address.ethToSubstrate(userAddress));2728 expect(after < before).to.be.true;2930 return before - after;31}3233describe('Add collection admins', () => {34 let donor: IKeyringPair;3536 before(async function() {37 await usingEthPlaygrounds(async (_helper, privateKey) => {38 donor = await privateKey({filename: __filename});39 });40 });4142 itEth('Add admin by owner', async ({helper}) => {43 const owner = await helper.eth.createAccountWithBalance(donor);44 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');45 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);4647 const newAdmin = helper.eth.createAccount();4849 await collectionEvm.methods.addCollectionAdmin(newAdmin).send();50 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);51 expect(adminList[0].asEthereum.toString().toLocaleLowerCase())52 .to.be.eq(newAdmin.toLocaleLowerCase());53 });5455 itEth('Add cross account admin by owner', async ({helper, privateKey}) => {56 const owner = await helper.eth.createAccountWithBalance(donor);57 58 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');59 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);60 61 const newAdmin = await privateKey('//Bob');62 const newAdminCross = helper.ethCrossAccount.fromKeyringPair(newAdmin);63 await collectionEvm.methods.addCollectionAdminCross(newAdminCross).send();6465 const adminList = await helper.collection.getAdmins(collectionId);66 expect(adminList).to.be.like([{Substrate: newAdmin.address}]);67 });6869 itEth('Check adminlist', async ({helper, privateKey}) => {70 const owner = await helper.eth.createAccountWithBalance(donor);71 72 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');73 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);7475 const admin1 = helper.eth.createAccount();76 const admin2 = await privateKey('admin');77 const admin2Cross = helper.ethCrossAccount.fromKeyringPair(admin2);78 await collectionEvm.methods.addCollectionAdmin(admin1).send();79 await collectionEvm.methods.addCollectionAdminCross(admin2Cross).send();8081 const adminListRpc = await helper.collection.getAdmins(collectionId);82 let adminListEth = await collectionEvm.methods.collectionAdmins().call();83 adminListEth = adminListEth.map((element: IEthCrossAccountId) => {84 return helper.address.convertCrossAccountFromEthCrossAcoount(element);85 });86 expect(adminListRpc).to.be.like(adminListEth);87 });8889 itEth('Verify owner or admin', async ({helper}) => {90 const owner = await helper.eth.createAccountWithBalance(donor);91 const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');9293 const newAdmin = helper.eth.createAccount();94 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);95 96 expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.false;97 await collectionEvm.methods.addCollectionAdmin(newAdmin).send();98 expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.true;99 });100 101 itEth('(!negative tests!) Add admin by ADMIN is not allowed', async ({helper}) => {102 const owner = await helper.eth.createAccountWithBalance(donor);103 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');104105 const admin = await helper.eth.createAccountWithBalance(donor);106 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);107 await collectionEvm.methods.addCollectionAdmin(admin).send();108109 const user = helper.eth.createAccount();110 await expect(collectionEvm.methods.addCollectionAdmin(user).call({from: admin}))111 .to.be.rejectedWith('NoPermission');112113 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);114 expect(adminList.length).to.be.eq(1);115 expect(adminList[0].asEthereum.toString().toLocaleLowerCase())116 .to.be.eq(admin.toLocaleLowerCase());117 });118119 itEth('(!negative tests!) Add admin by USER is not allowed', async ({helper}) => {120 const owner = await helper.eth.createAccountWithBalance(donor);121 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');122123 const notAdmin = await helper.eth.createAccountWithBalance(donor);124 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);125126 const user = helper.eth.createAccount();127 await expect(collectionEvm.methods.addCollectionAdmin(user).call({from: notAdmin}))128 .to.be.rejectedWith('NoPermission');129130 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);131 expect(adminList.length).to.be.eq(0);132 });133134 itEth.skip('(!negative tests!) Add substrate admin by ADMIN is not allowed', async ({helper}) => {135 const owner = await helper.eth.createAccountWithBalance(donor);136 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');137138 const admin = await helper.eth.createAccountWithBalance(donor);139 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);140 await collectionEvm.methods.addCollectionAdmin(admin).send();141142 const [notAdmin] = await helper.arrange.createAccounts([10n], donor);143 await expect(collectionEvm.methods.addCollectionAdminSubstrate(notAdmin.addressRaw).call({from: admin}))144 .to.be.rejectedWith('NoPermission');145146 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);147 expect(adminList.length).to.be.eq(1);148 expect(adminList[0].asEthereum.toString().toLocaleLowerCase())149 .to.be.eq(admin.toLocaleLowerCase());150 });151152 itEth.skip('(!negative tests!) Add substrate admin by USER is not allowed', async ({helper}) => {153 const owner = await helper.eth.createAccountWithBalance(donor);154 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');155156 const notAdmin0 = await helper.eth.createAccountWithBalance(donor);157 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);158 const [notAdmin1] = await helper.arrange.createAccounts([10n], donor);159 await expect(collectionEvm.methods.addCollectionAdminSubstrate(notAdmin1.addressRaw).call({from: notAdmin0}))160 .to.be.rejectedWith('NoPermission');161162 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);163 expect(adminList.length).to.be.eq(0);164 });165});166167describe('Remove collection admins', () => {168 let donor: IKeyringPair;169170 before(async function() {171 await usingEthPlaygrounds(async (_helper, privateKey) => {172 donor = await privateKey({filename: __filename});173 });174 });175176 itEth('Remove admin by owner', async ({helper}) => {177 const owner = await helper.eth.createAccountWithBalance(donor);178 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');179180 const newAdmin = helper.eth.createAccount();181 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);182 await collectionEvm.methods.addCollectionAdmin(newAdmin).send();183184 {185 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);186 expect(adminList.length).to.be.eq(1);187 expect(adminList[0].asEthereum.toString().toLocaleLowerCase())188 .to.be.eq(newAdmin.toLocaleLowerCase());189 }190191 await collectionEvm.methods.removeCollectionAdmin(newAdmin).send();192 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);193 expect(adminList.length).to.be.eq(0);194 });195196 itEth.skip('Remove substrate admin by owner', async ({helper}) => {197 const owner = await helper.eth.createAccountWithBalance(donor);198 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');199200 const [newAdmin] = await helper.arrange.createAccounts([10n], donor);201 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);202 await collectionEvm.methods.addCollectionAdminSubstrate(newAdmin.addressRaw).send();203 {204 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);205 expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())206 .to.be.eq(newAdmin.address.toLocaleLowerCase());207 }208209 await collectionEvm.methods.removeCollectionAdminSubstrate(newAdmin.addressRaw).send();210 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);211 expect(adminList.length).to.be.eq(0);212 });213214 itEth('(!negative tests!) Remove admin by ADMIN is not allowed', async ({helper}) => {215 const owner = await helper.eth.createAccountWithBalance(donor);216 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');217218 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);219220 const admin0 = await helper.eth.createAccountWithBalance(donor);221 await collectionEvm.methods.addCollectionAdmin(admin0).send();222 const admin1 = await helper.eth.createAccountWithBalance(donor);223 await collectionEvm.methods.addCollectionAdmin(admin1).send();224225 await expect(collectionEvm.methods.removeCollectionAdmin(admin1).call({from: admin0}))226 .to.be.rejectedWith('NoPermission');227 {228 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);229 expect(adminList.length).to.be.eq(2);230 expect(adminList.toString().toLocaleLowerCase())231 .to.be.deep.contains(admin0.toLocaleLowerCase())232 .to.be.deep.contains(admin1.toLocaleLowerCase());233 }234 });235236 itEth('(!negative tests!) Remove admin by USER is not allowed', async ({helper}) => {237 const owner = await helper.eth.createAccountWithBalance(donor);238 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');239240 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);241242 const admin = await helper.eth.createAccountWithBalance(donor);243 await collectionEvm.methods.addCollectionAdmin(admin).send();244 const notAdmin = helper.eth.createAccount();245246 await expect(collectionEvm.methods.removeCollectionAdmin(admin).call({from: notAdmin}))247 .to.be.rejectedWith('NoPermission');248 {249 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);250 expect(adminList[0].asEthereum.toString().toLocaleLowerCase())251 .to.be.eq(admin.toLocaleLowerCase());252 expect(adminList.length).to.be.eq(1);253 }254 });255256 itEth.skip('(!negative tests!) Remove substrate admin by ADMIN is not allowed', async ({helper}) => {257 const owner = await helper.eth.createAccountWithBalance(donor);258 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');259260 const [adminSub] = await helper.arrange.createAccounts([10n], donor);261 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);262 await collectionEvm.methods.addCollectionAdminSubstrate(adminSub.addressRaw).send();263 const adminEth = await helper.eth.createAccountWithBalance(donor);264 await collectionEvm.methods.addCollectionAdmin(adminEth).send();265266 await expect(collectionEvm.methods.removeCollectionAdminSubstrate(adminSub.addressRaw).call({from: adminEth}))267 .to.be.rejectedWith('NoPermission');268269 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);270 expect(adminList.length).to.be.eq(2);271 expect(adminList.toString().toLocaleLowerCase())272 .to.be.deep.contains(adminSub.address.toLocaleLowerCase())273 .to.be.deep.contains(adminEth.toLocaleLowerCase());274 });275276 itEth.skip('(!negative tests!) Remove substrate admin by USER is not allowed', async ({helper}) => {277 const owner = await helper.eth.createAccountWithBalance(donor);278 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');279280 const [adminSub] = await helper.arrange.createAccounts([10n], donor);281 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);282 await collectionEvm.methods.addCollectionAdminSubstrate(adminSub.addressRaw).send();283 const notAdminEth = await helper.eth.createAccountWithBalance(donor);284285 await expect(collectionEvm.methods.removeCollectionAdminSubstrate(adminSub.addressRaw).call({from: notAdminEth}))286 .to.be.rejectedWith('NoPermission');287288 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);289 expect(adminList.length).to.be.eq(1);290 expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())291 .to.be.eq(adminSub.address.toLocaleLowerCase());292 });293});294295describe('Change owner tests', () => {296 let donor: IKeyringPair;297298 before(async function() {299 await usingEthPlaygrounds(async (_helper, privateKey) => {300 donor = await privateKey({filename: __filename});301 });302 });303304 itEth('Change owner', async ({helper}) => {305 const owner = await helper.eth.createAccountWithBalance(donor);306 const newOwner = await helper.eth.createAccountWithBalance(donor);307 const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');308 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);309310 await collectionEvm.methods.changeCollectionOwner(newOwner).send();311312 expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.false;313 expect(await collectionEvm.methods.isOwnerOrAdmin(newOwner).call()).to.be.true;314 });315316 itEth('change owner call fee', async ({helper}) => {317 const owner = await helper.eth.createAccountWithBalance(donor);318 const newOwner = await helper.eth.createAccountWithBalance(donor);319 const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');320 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);321 const cost = await recordEthFee(helper, owner, () => collectionEvm.methods.changeCollectionOwner(newOwner).send());322 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));323 expect(cost > 0);324 });325326 itEth('(!negative tests!) call setOwner by non owner', async ({helper}) => {327 const owner = await helper.eth.createAccountWithBalance(donor);328 const newOwner = await helper.eth.createAccountWithBalance(donor);329 const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');330 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);331332 await expect(collectionEvm.methods.changeCollectionOwner(newOwner).send({from: newOwner})).to.be.rejected;333 expect(await collectionEvm.methods.isOwnerOrAdmin(newOwner).call()).to.be.false;334 });335});336337describe('Change substrate owner tests', () => {338 let donor: IKeyringPair;339340 before(async function() {341 await usingEthPlaygrounds(async (_helper, privateKey) => {342 donor = await privateKey({filename: __filename});343 });344 });345346 itEth.skip('Change owner', async ({helper}) => {347 const owner = await helper.eth.createAccountWithBalance(donor);348 const [newOwner] = await helper.arrange.createAccounts([10n], donor);349 const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');350 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);351352 expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.true;353 expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.false;354355 await collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send();356357 expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.false;358 expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.true;359 });360361 itEth.skip('change owner call fee', async ({helper}) => {362 const owner = await helper.eth.createAccountWithBalance(donor);363 const [newOwner] = await helper.arrange.createAccounts([10n], donor);364 const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');365 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);366367 const cost = await recordEthFee(helper, owner, () => collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send());368 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));369 expect(cost > 0);370 });371372 itEth.skip('(!negative tests!) call setOwner by non owner', async ({helper}) => {373 const owner = await helper.eth.createAccountWithBalance(donor);374 const otherReceiver = await helper.eth.createAccountWithBalance(donor);375 const [newOwner] = await helper.arrange.createAccounts([10n], donor);376 const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');377 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);378379 await expect(collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send({from: otherReceiver})).to.be.rejected;380 expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.false;381 });382});