12345import {ApiPromise} from '@polkadot/api';6import {IKeyringPair} from '@polkadot/types/types';7import chai from 'chai';8import chaiAsPromised from 'chai-as-promised';9import privateKey from './substrate/privateKey';10import {default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync} from './substrate/substrate-api';11import {12 createCollectionExpectSuccess,13 destroyCollectionExpectSuccess,14 getGenericResult,15 normalizeAccountId,16 setCollectionLimitsExpectSuccess,17 addCollectionAdminExpectSuccess,18 getBalance,19 getTokenOwner,20 getLastTokenId,21 getVariableMetadata,22 getConstMetadata,23} from './util/helpers';2425chai.use(chaiAsPromised);26const expect = chai.expect;2728describe('Integration Test createMultipleItems(collection_id, owner, items_data):', () => {29 it('Create 0x31, 0x32, 0x33 items in active NFT collection and verify tokens data in chain', async () => {30 await usingApi(async (api: ApiPromise) => {31 const collectionId = await createCollectionExpectSuccess();32 const itemsListIndexBefore = await getLastTokenId(api, collectionId);33 expect(itemsListIndexBefore).to.be.equal(0);34 const alice = privateKey('//Alice');35 const args = [{NFT: ['0x31', '0x31']}, {NFT: ['0x32', '0x32']}, {NFT: ['0x33', '0x33']}];36 const createMultipleItemsTx = api.tx.nft37 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);38 await submitTransactionAsync(alice, createMultipleItemsTx);39 const itemsListIndexAfter = await getLastTokenId(api, collectionId);40 expect(itemsListIndexAfter).to.be.equal(3);4142 expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));43 expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));44 expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));4546 expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);47 expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);48 expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);4950 expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);51 expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);52 expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);53 });54 });5556 it('Create 0x01, 0x02, 0x03 items in active Fungible collection and verify tokens data in chain', async () => {57 await usingApi(async (api: ApiPromise) => {58 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});59 const itemsListIndexBefore = await getLastTokenId(api, collectionId);60 expect(itemsListIndexBefore).to.be.equal(0);61 const alice = privateKey('//Alice');62 const args = [63 {Fungible: {value: 1}},64 {Fungible: {value: 2}},65 {Fungible: {value: 3}},66 ];67 const createMultipleItemsTx = api.tx.nft68 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);69 await submitTransactionAsync(alice, createMultipleItemsTx);70 const token1Data = await getBalance(api, collectionId, alice.address, 0);7172 expect(token1Data).to.be.equal(6n); 73 });74 });7576 it('Create 0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {77 await usingApi(async (api: ApiPromise) => {78 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});79 const itemsListIndexBefore = await getLastTokenId(api, collectionId);80 expect(itemsListIndexBefore).to.be.equal(0);81 const alice = privateKey('//Alice');82 const args = [83 {ReFungible: {const_data: [0x31], variable_data: [0x31], pieces: 1}},84 {ReFungible: {const_data: [0x32], variable_data: [0x32], pieces: 1}},85 {ReFungible: {const_data: [0x33], variable_data: [0x33], pieces: 1}},86 ];87 const createMultipleItemsTx = api.tx.nft88 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);89 await submitTransactionAsync(alice, createMultipleItemsTx);90 const itemsListIndexAfter = await getLastTokenId(api, collectionId);91 expect(itemsListIndexAfter).to.be.equal(3);9293 expect(await getBalance(api, collectionId, alice.address, 1)).to.be.equal(1n);94 expect(await getBalance(api, collectionId, alice.address, 2)).to.be.equal(1n);95 expect(await getBalance(api, collectionId, alice.address, 3)).to.be.equal(1n);9697 expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);98 expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);99 expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);100101 expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);102 expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);103 expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);104 });105 });106107 it('Can mint amount of items equals to collection limits', async () => {108 await usingApi(async (api) => {109 const alice = privateKey('//Alice');110111 const collectionId = await createCollectionExpectSuccess();112 await setCollectionLimitsExpectSuccess(alice, collectionId, {113 tokenLimit: 2,114 });115 const args = [116 {NFT: ['A', 'A']},117 {NFT: ['B', 'B']},118 ];119 const createMultipleItemsTx = api.tx.nft.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);120 const events = await submitTransactionAsync(alice, createMultipleItemsTx);121 const result = getGenericResult(events);122 expect(result.success).to.be.true;123 });124 });125});126127describe('Integration Test createMultipleItems(collection_id, owner, items_data) with collection admin permissions:', () => {128129 let alice: IKeyringPair;130 let bob: IKeyringPair;131132 before(async () => {133 await usingApi(async () => {134 alice = privateKey('//Alice');135 bob = privateKey('//Bob');136 });137 });138139 it('Create 0x31, 0x32, 0x33 items in active NFT collection and verify tokens data in chain', async () => {140 await usingApi(async (api: ApiPromise) => {141 const collectionId = await createCollectionExpectSuccess();142 const itemsListIndexBefore = await getLastTokenId(api, collectionId);143 expect(itemsListIndexBefore).to.be.equal(0);144 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);145 const args = [{NFT: ['0x31', '0x31']}, {NFT: ['0x32', '0x32']}, {NFT: ['0x33', '0x33']}];146 const createMultipleItemsTx = api.tx.nft147 .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);148 await submitTransactionAsync(bob, createMultipleItemsTx);149 const itemsListIndexAfter = await getLastTokenId(api, collectionId);150 expect(itemsListIndexAfter).to.be.equal(3);151152 expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(bob.address));153 expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(bob.address));154 expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(bob.address));155156 expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);157 expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);158 expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);159160 expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);161 expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);162 expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);163 });164 });165166 it('Create 0x01, 0x02, 0x03 items in active Fungible collection and verify tokens data in chain', async () => {167 await usingApi(async (api: ApiPromise) => {168 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});169 const itemsListIndexBefore = await getLastTokenId(api, collectionId);170 expect(itemsListIndexBefore).to.be.equal(0);171 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);172 const args = [173 {Fungible: {value: 1}},174 {Fungible: {value: 2}},175 {Fungible: {value: 3}},176 ];177 const createMultipleItemsTx = api.tx.nft178 .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);179 await submitTransactionAsync(bob, createMultipleItemsTx);180 const token1Data = await getBalance(api, collectionId, bob.address, 0);181182 expect(token1Data).to.be.equal(6n); 183 });184 });185186 it('Create 0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {187 await usingApi(async (api: ApiPromise) => {188 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});189 const itemsListIndexBefore = await getLastTokenId(api, collectionId);190 expect(itemsListIndexBefore).to.be.equal(0);191 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);192 const args = [193 {ReFungible: {const_data: [0x31], variable_data: [0x31], pieces: 1}},194 {ReFungible: {const_data: [0x32], variable_data: [0x32], pieces: 1}},195 {ReFungible: {const_data: [0x33], variable_data: [0x33], pieces: 1}},196 ];197 const createMultipleItemsTx = api.tx.nft198 .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);199 await submitTransactionAsync(bob, createMultipleItemsTx);200 const itemsListIndexAfter = await getLastTokenId(api, collectionId);201 expect(itemsListIndexAfter).to.be.equal(3);202203 expect(await getBalance(api, collectionId, bob.address, 1)).to.be.equal(1n);204 expect(await getBalance(api, collectionId, bob.address, 2)).to.be.equal(1n);205 expect(await getBalance(api, collectionId, bob.address, 3)).to.be.equal(1n);206207 expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);208 expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);209 expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);210211 expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);212 expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);213 expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);214 });215 });216});217218describe('Negative Integration Test createMultipleItems(collection_id, owner, items_data):', () => {219220 let alice: IKeyringPair;221 let bob: IKeyringPair;222223 before(async () => {224 await usingApi(async () => {225 alice = privateKey('//Alice');226 bob = privateKey('//Bob');227 });228 });229230 it('Regular user cannot create items in active NFT collection', async () => {231 await usingApi(async (api: ApiPromise) => {232 const collectionId = await createCollectionExpectSuccess();233 const itemsListIndexBefore = await getLastTokenId(api, collectionId);234 expect(itemsListIndexBefore).to.be.equal(0);235 const args = [{NFT: ['0x31', '0x31']}, {NFT: ['0x32', '0x32']}, {NFT: ['0x33', '0x33']}];236 const createMultipleItemsTx = api.tx.nft237 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);238 await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;239 });240 });241242 it('Regular user cannot create items in active Fungible collection', async () => {243 await usingApi(async (api: ApiPromise) => {244 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});245 const itemsListIndexBefore = await getLastTokenId(api, collectionId);246 expect(itemsListIndexBefore).to.be.equal(0);247 const args = [248 {Fungible: {value: 1}},249 {Fungible: {value: 2}},250 {Fungible: {value: 3}},251 ];252 const createMultipleItemsTx = api.tx.nft253 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);254 await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;255 });256 });257258 it('Regular user cannot create items in active ReFungible collection', async () => {259 await usingApi(async (api: ApiPromise) => {260 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});261 const itemsListIndexBefore = await getLastTokenId(api, collectionId);262 expect(itemsListIndexBefore).to.be.equal(0);263 const args = [264 {ReFungible: {const_data: [0x31], variable_data: [0x31], pieces: 1}},265 {ReFungible: {const_data: [0x32], variable_data: [0x32], pieces: 1}},266 {ReFungible: {const_data: [0x33], variable_data: [0x33], pieces: 1}},267 ];268 const createMultipleItemsTx = api.tx.nft269 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);270 await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;271 });272 });273274 it('Create token in not existing collection', async () => {275 await usingApi(async (api: ApiPromise) => {276 const collectionId = (await api.query.common.createdCollectionCount()).toNumber() + 1;277 const createMultipleItemsTx = api.tx.nft278 .createMultipleItems(collectionId, normalizeAccountId(alice.address), ['NFT', 'NFT', 'NFT']);279 await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;280 });281 });282283 it('Create NFT and Re-fungible tokens that has reached the maximum data limit', async () => {284 await usingApi(async (api: ApiPromise) => {285 286 const collectionId = await createCollectionExpectSuccess();287 const alice = privateKey('//Alice');288 const args = [289 {NFT: ['A'.repeat(2049), 'A'.repeat(2049)]},290 {NFT: ['B'.repeat(2049), 'B'.repeat(2049)]},291 {NFT: ['C'.repeat(2049), 'C'.repeat(2049)]},292 ];293 const createMultipleItemsTx = api.tx.nft294 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);295 await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;296297 298 const collectionIdReFungible =299 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});300 const argsReFungible = [301 {ReFungible: ['1'.repeat(2049), '1'.repeat(2049), 10]},302 {ReFungible: ['2'.repeat(2049), '2'.repeat(2049), 10]},303 {ReFungible: ['3'.repeat(2049), '3'.repeat(2049), 10]},304 ];305 const createMultipleItemsTxFungible = api.tx.nft306 .createMultipleItems(collectionIdReFungible, normalizeAccountId(alice.address), argsReFungible);307 await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTxFungible)).to.be.rejected;308 });309 });310311 it('Create tokens with different types', async () => {312 await usingApi(async (api: ApiPromise) => {313 const collectionId = await createCollectionExpectSuccess();314 const createMultipleItemsTx = api.tx.nft315 .createMultipleItems(collectionId, normalizeAccountId(alice.address), ['NFT', 'Fungible', 'ReFungible']);316 await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;317 318 await destroyCollectionExpectSuccess(collectionId);319 });320 });321322 it('Create tokens with different data limits <> maximum data limit', async () => {323 await usingApi(async (api: ApiPromise) => {324 const collectionId = await createCollectionExpectSuccess();325 const args = [326 {NFT: ['A', 'A']},327 {NFT: ['B', 'B'.repeat(2049)]},328 {NFT: ['C'.repeat(2049), 'C']},329 ];330 const createMultipleItemsTx = await api.tx.nft331 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);332 await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;333 });334 });335336 it('Fails when minting tokens exceeds collectionLimits amount', async () => {337 await usingApi(async (api) => {338339 const collectionId = await createCollectionExpectSuccess();340 await setCollectionLimitsExpectSuccess(alice, collectionId, {341 tokenLimit: 1,342 });343 const args = [344 {NFT: ['A', 'A']},345 {NFT: ['B', 'B']},346 ];347 const createMultipleItemsTx = api.tx.nft.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);348 await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;349 });350 });351});