1234567891011121314151617import {IKeyringPair} from '@polkadot/types/types';18import chai from 'chai';19import chaiAsPromised from 'chai-as-promised';20import { usingPlaygrounds } from './util/playgrounds';2122chai.use(chaiAsPromised);23const expect = chai.expect;2425let donor: IKeyringPair;2627before(async () => {28 await usingPlaygrounds(async (_, privateKeyWrapper) => {29 donor = privateKeyWrapper('//Alice');30 });31});3233let alice: IKeyringPair;34let bob: IKeyringPair;35let charlie: IKeyringPair;3637describe('Integration Test ext. Allow list tests', () => {3839 before(async () => {40 await usingPlaygrounds(async (helper) => {41 [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);42 });43 });4445 it('Owner can add address to allow list', async () => {46 await usingPlaygrounds(async (helper) => {47 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});48 await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address});49 const allowList = await helper.nft.getAllowList(collectionId);50 expect(allowList).to.be.deep.contains({Substrate: bob.address});51 });52 });5354 it('Admin can add address to allow list', async () => {55 await usingPlaygrounds(async (helper) => {56 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});57 await helper.nft.addAdmin(alice, collectionId, {Substrate: bob.address});5859 await helper.nft.addToAllowList(bob, collectionId, {Substrate: charlie.address});60 const allowList = await helper.nft.getAllowList(collectionId);61 expect(allowList).to.be.deep.contains({Substrate: charlie.address});62 });63 });6465 it('Non-privileged user cannot add address to allow list', async () => {66 await usingPlaygrounds(async (helper) => {67 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});68 const addToAllowListTx = async () => helper.nft.addToAllowList(bob, collectionId, {Substrate: charlie.address});69 expect(addToAllowListTx()).to.be.rejected;70 });71 });7273 it('Nobody can add address to allow list of non-existing collection', async () => {74 const collectionId = (1<<32) - 1;75 await usingPlaygrounds(async (helper) => {76 const addToAllowListTx = async () => helper.nft.addToAllowList(bob, collectionId, {Substrate: charlie.address});77 expect(addToAllowListTx()).to.be.rejected;78 });79 });8081 it('Nobody can add address to allow list of destroyed collection', async () => {82 await usingPlaygrounds(async (helper) => {83 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});84 await helper.collection.burn(alice, collectionId);85 const addToAllowListTx = async () => helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address});86 expect(addToAllowListTx()).to.be.rejected;87 });88 });8990 it('If address is already added to allow list, nothing happens', async () => {91 await usingPlaygrounds(async (helper) => {92 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});93 await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address});94 await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address});95 const allowList = await helper.nft.getAllowList(collectionId);96 expect(allowList).to.be.deep.contains({Substrate: bob.address});97 });98 });99100 it('Owner can remove address from allow list', async () => {101 await usingPlaygrounds(async (helper) => {102 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});103 await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address});104105 106 await helper.api?.tx.unique.removeFromAllowList(collectionId, {Substrate: bob.address}).signAndSend(alice);107108 const allowList = await helper.nft.getAllowList(collectionId);109110 expect(allowList).to.be.not.deep.contains({Substrate: bob.address});111 });112 });113114 it('Admin can remove address from allow list', async () => {115 await usingPlaygrounds(async (helper) => {116 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});117 await helper.nft.addAdmin(alice, collectionId, {Substrate: charlie.address});118 await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address});119 120 await helper.api?.tx.unique.removeFromAllowList(collectionId, {Substrate: bob.address}).signAndSend(charlie);121122 const allowList = await helper.nft.getAllowList(collectionId);123124 expect(allowList).to.be.not.deep.contains({Substrate: bob.address});125 });126 });127128 it('Non-privileged user cannot remove address from allow list', async () => {129 await usingPlaygrounds(async (helper) => {130 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});131 await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address});132 133 await helper.api?.tx.unique.removeFromAllowList(collectionId, {Substrate: charlie.address}).signAndSend(bob);134135 const allowList = await helper.nft.getAllowList(collectionId);136137 expect(allowList).to.be.deep.contains({Substrate: charlie.address});138 });139 });140141 it('Nobody can remove address from allow list of non-existing collection', async () => {142 const collectionId = (1<<32) - 1;143 await usingPlaygrounds(async (helper) => {144 145 await helper.api?.tx.unique.removeFromAllowList(collectionId, {Substrate: charlie.address}).signAndSend(bob);146147 const allowList = await helper.nft.getAllowList(collectionId);148149 expect(allowList).to.be.not.deep.contains({Substrate: charlie.address});150 });151 });152153 it('Nobody can remove address from allow list of deleted collection', async () => {154 await usingPlaygrounds(async (helper) => {155 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});156 await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address});157 await helper.collection.burn(alice, collectionId);158159 160 const removeTx = async () => helper.api?.tx.unique.removeFromAllowList(collectionId, {Substrate: bob.address}).signAndSend(alice);161162 expect(removeTx()).to.be.rejected;163 });164 });165166 it('If address is already removed from allow list, nothing happens', async () => {167 await usingPlaygrounds(async (helper) => {168 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});169 await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address});170171 172 await helper.api?.tx.unique.removeFromAllowList(collectionId, {Substrate: bob.address}).signAndSend(alice);173 const allowListBefore = await helper.nft.getAllowList(collectionId);174 expect(allowListBefore).to.be.not.deep.contains({Substrate: bob.address});175176 await helper.api?.tx.unique.removeFromAllowList(collectionId, {Substrate: bob.address}).signAndSend(alice);177178 const allowListAfter = await helper.nft.getAllowList(collectionId);179 expect(allowListAfter).to.be.not.deep.contains({Substrate: bob.address});180 });181 });182183 it('If Public Access mode is set to AllowList, tokens can’t be transferred from a non-allowlisted address with transfer or transferFrom. Test1', async () => {184 await usingPlaygrounds(async (helper) => {185 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});186 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});187 await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});188 await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address});189190 const transferResult = async () => helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address});191 expect(transferResult()).to.be.rejected;192 });193 });194195 it('If Public Access mode is set to AllowList, tokens can’t be transferred from a non-allowlisted address with transfer or transferFrom. Test2', async () => {196 await usingPlaygrounds(async (helper) => {197 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});198 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});199 await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});200 await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address});201 await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address});202 await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: charlie.address});203204 205 await helper.api?.tx.unique.removeFromAllowList(collectionId, {Substrate: alice.address}).signAndSend(alice);206207 const transferResult = async () => helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address});208 expect(transferResult()).to.be.rejected;209 });210 });211212 it('If Public Access mode is set to AllowList, tokens can’t be transferred to a non-allowlisted address with transfer or transferFrom. Test1', async () => {213 await usingPlaygrounds(async (helper) => {214 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});215 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});216 await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});217 await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address});218219 const transferResult = async () => helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address});220 expect(transferResult()).to.be.rejected;221 });222 });223224 it('If Public Access mode is set to AllowList, tokens can’t be transferred to a non-allowlisted address with transfer or transferFrom. Test2', async () => {225 await usingPlaygrounds(async (helper) => {226 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});227 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});228 await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});229 await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address});230 await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address});231232 await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: charlie.address});233234 235 await helper.api?.tx.unique.removeFromAllowList(collectionId, {Substrate: alice.address}).signAndSend(alice);236237 const transferResult = async () => helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address});238 expect(transferResult()).to.be.rejected;239 });240 });241242 it('If Public Access mode is set to AllowList, tokens can’t be destroyed by a non-allowlisted address (even if it owned them before enabling AllowList mode)', async () => {243 await usingPlaygrounds(async (helper) => {244 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});245 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});246 await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});247 const burnTx = async () => helper.nft.burnToken(bob, collectionId, tokenId);248 expect(burnTx()).to.be.rejected;249 });250 });251252 it('If Public Access mode is set to AllowList, token transfers can’t be Approved by a non-allowlisted address (see Approve method)', async () => {253 await usingPlaygrounds(async (helper) => {254 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});255 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});256 await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});257 const approveTx = async () => helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});258 await expect(approveTx()).to.be.rejected;259 });260 });261262 it('If Public Access mode is set to AllowList, tokens can be transferred to a allowlisted address with transfer.', async () => {263 await usingPlaygrounds(async (helper) => {264 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});265 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});266 await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});267 await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address});268 await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address});269 await helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address});270 const owner = await helper.nft.getTokenOwner(collectionId, tokenId);271 expect(owner.Substrate).to.be.equal(charlie.address);272 });273 });274275 it('If Public Access mode is set to AllowList, tokens can be transferred to a allowlisted address with transferFrom.', async () => {276 await usingPlaygrounds(async (helper) => {277 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});278 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});279 await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});280 await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address});281 await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address});282 await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: charlie.address});283284 await helper.nft.transferTokenFrom(alice, collectionId, tokenId, {Substrate: alice.address}, {Substrate: charlie.address});285 const owner = await helper.nft.getTokenOwner(collectionId, tokenId);286 expect(owner.Substrate).to.be.equal(charlie.address);287 });288 });289290 it('If Public Access mode is set to AllowList, tokens can be transferred from a allowlisted address with transfer', async () => {291 await usingPlaygrounds(async (helper) => {292 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});293 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});294 await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});295 await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address});296 await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address});297298 await helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address});299 const owner = await helper.nft.getTokenOwner(collectionId, tokenId);300 expect(owner.Substrate).to.be.equal(charlie.address);301 });302 });303304 it('If Public Access mode is set to AllowList, tokens can be transferred from a allowlisted address with transferFrom', async () => {305 await usingPlaygrounds(async (helper) => {306 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});307 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});308 await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});309 await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address});310 await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address});311 await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: charlie.address});312313 await helper.nft.transferTokenFrom(alice, collectionId, tokenId, {Substrate: alice.address}, {Substrate: charlie.address});314 const owner = await helper.nft.getTokenOwner(collectionId, tokenId);315 expect(owner.Substrate).to.be.equal(charlie.address);316 });317 });318319 it('If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens can be created by owner', async () => {320 await usingPlaygrounds(async (helper) => {321 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});322 await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList', mintMode: false});323 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});324 const token = await helper.nft.getToken(collectionId, tokenId);325 expect(token).to.be.not.null;326 });327 });328329 it('If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens can be created by admin', async () => {330 await usingPlaygrounds(async (helper) => {331 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});332 await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList', mintMode: false});333 await helper.collection.addAdmin(alice, collectionId, {Substrate: bob.address});334 const {tokenId} = await helper.nft.mintToken(bob, {collectionId: collectionId, owner: bob.address});335 const token = await helper.nft.getToken(collectionId, tokenId);336 expect(token).to.be.not.null;337 });338 });339340 it('If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens cannot be created by non-privileged and allow-listed address', async () => {341 await usingPlaygrounds(async (helper) => {342 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});343 await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList', mintMode: false});344 await helper.collection.addToAllowList(alice, collectionId, {Substrate: bob.address});345 const mintTokenTx = async () => helper.nft.mintToken(bob, {collectionId: collectionId, owner: bob.address});346 await expect(mintTokenTx()).to.be.rejected;347 });348 });349350 it('If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens cannot be created by non-privileged and non-allow listed address', async () => {351 await usingPlaygrounds(async (helper) => {352 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});353 await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList', mintMode: false});354 const mintTokenTx = async () => helper.nft.mintToken(bob, {collectionId: collectionId, owner: bob.address});355 await expect(mintTokenTx()).to.be.rejected;356 });357 });358359 it('If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens can be created by owner', async () => {360 await usingPlaygrounds(async (helper) => {361 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});362 await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList', mintMode: true});363 const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});364 const owner = await helper.nft.getTokenOwner(collectionId, tokenId);365 expect(owner.Substrate).to.be.equal(alice.address);366 });367 });368369 it('If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens can be created by admin', async () => {370 await usingPlaygrounds(async (helper) => {371 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});372 await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList', mintMode: true});373 await helper.nft.addAdmin(alice, collectionId, {Substrate: bob.address});374 const {tokenId} = await helper.nft.mintToken(bob, {collectionId: collectionId, owner: bob.address});375 const owner = await helper.nft.getTokenOwner(collectionId, tokenId);376 expect(owner.Substrate).to.be.equal(bob.address);377 });378 });379380 it('If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens cannot be created by non-privileged and non-allow listed address', async () => {381 await usingPlaygrounds(async (helper) => {382 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});383 await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList', mintMode: true});384 const mintTokenTx = async () => helper.nft.mintToken(bob, {collectionId: collectionId, owner: bob.address});385 await expect(mintTokenTx()).to.be.rejected;386 });387 });388389 it('If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens can be created by non-privileged and allow listed address', async () => {390 await usingPlaygrounds(async (helper) => {391 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});392 await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList', mintMode: true});393 await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address});394 const {tokenId} = await helper.nft.mintToken(bob, {collectionId: collectionId, owner: bob.address});395 const owner = await helper.nft.getTokenOwner(collectionId, tokenId);396 expect(owner.Substrate).to.be.equal(bob.address);397 });398 });399});