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 getCreatedCollectionCount,24} from './util/helpers';2526chai.use(chaiAsPromised);27const expect = chai.expect;2829describe('Integration Test createMultipleItems(collection_id, owner, items_data):', () => {30 it('Create 0x31, 0x32, 0x33 items in active NFT collection and verify tokens data in chain', async () => {31 await usingApi(async (api: ApiPromise) => {32 const collectionId = await createCollectionExpectSuccess();33 const itemsListIndexBefore = await getLastTokenId(api, collectionId);34 expect(itemsListIndexBefore).to.be.equal(0);35 const alice = privateKey('//Alice');36 const args = [{NFT: ['0x31', '0x31']}, {NFT: ['0x32', '0x32']}, {NFT: ['0x33', '0x33']}];37 const createMultipleItemsTx = api.tx.nft38 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);39 await submitTransactionAsync(alice, createMultipleItemsTx);40 const itemsListIndexAfter = await getLastTokenId(api, collectionId);41 expect(itemsListIndexAfter).to.be.equal(3);4243 expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));44 expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));45 expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));4647 expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);48 expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);49 expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);5051 expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);52 expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);53 expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);54 });55 });5657 it('Create 0x01, 0x02, 0x03 items in active Fungible collection and verify tokens data in chain', async () => {58 await usingApi(async (api: ApiPromise) => {59 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});60 const itemsListIndexBefore = await getLastTokenId(api, collectionId);61 expect(itemsListIndexBefore).to.be.equal(0);62 const alice = privateKey('//Alice');63 const args = [64 {Fungible: {value: 1}},65 {Fungible: {value: 2}},66 {Fungible: {value: 3}},67 ];68 const createMultipleItemsTx = api.tx.nft69 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);70 await submitTransactionAsync(alice, createMultipleItemsTx);71 const token1Data = await getBalance(api, collectionId, alice.address, 0);7273 expect(token1Data).to.be.equal(6n); 74 });75 });7677 it('Create 0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {78 await usingApi(async (api: ApiPromise) => {79 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});80 const itemsListIndexBefore = await getLastTokenId(api, collectionId);81 expect(itemsListIndexBefore).to.be.equal(0);82 const alice = privateKey('//Alice');83 const args = [84 {ReFungible: {const_data: [0x31], variable_data: [0x31], pieces: 1}},85 {ReFungible: {const_data: [0x32], variable_data: [0x32], pieces: 1}},86 {ReFungible: {const_data: [0x33], variable_data: [0x33], pieces: 1}},87 ];88 const createMultipleItemsTx = api.tx.nft89 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);90 await submitTransactionAsync(alice, createMultipleItemsTx);91 const itemsListIndexAfter = await getLastTokenId(api, collectionId);92 expect(itemsListIndexAfter).to.be.equal(3);9394 expect(await getBalance(api, collectionId, alice.address, 1)).to.be.equal(1n);95 expect(await getBalance(api, collectionId, alice.address, 2)).to.be.equal(1n);96 expect(await getBalance(api, collectionId, alice.address, 3)).to.be.equal(1n);9798 expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);99 expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);100 expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);101102 expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);103 expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);104 expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);105 });106 });107108 it('Can mint amount of items equals to collection limits', async () => {109 await usingApi(async (api) => {110 const alice = privateKey('//Alice');111112 const collectionId = await createCollectionExpectSuccess();113 await setCollectionLimitsExpectSuccess(alice, collectionId, {114 tokenLimit: 2,115 });116 const args = [117 {NFT: ['A', 'A']},118 {NFT: ['B', 'B']},119 ];120 const createMultipleItemsTx = api.tx.nft.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);121 const events = await submitTransactionAsync(alice, createMultipleItemsTx);122 const result = getGenericResult(events);123 expect(result.success).to.be.true;124 });125 });126});127128describe('Integration Test createMultipleItems(collection_id, owner, items_data) with collection admin permissions:', () => {129130 let alice: IKeyringPair;131 let bob: IKeyringPair;132133 before(async () => {134 await usingApi(async () => {135 alice = privateKey('//Alice');136 bob = privateKey('//Bob');137 });138 });139140 it('Create 0x31, 0x32, 0x33 items in active NFT collection and verify tokens data in chain', async () => {141 await usingApi(async (api: ApiPromise) => {142 const collectionId = await createCollectionExpectSuccess();143 const itemsListIndexBefore = await getLastTokenId(api, collectionId);144 expect(itemsListIndexBefore).to.be.equal(0);145 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);146 const args = [{NFT: ['0x31', '0x31']}, {NFT: ['0x32', '0x32']}, {NFT: ['0x33', '0x33']}];147 const createMultipleItemsTx = api.tx.nft148 .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);149 await submitTransactionAsync(bob, createMultipleItemsTx);150 const itemsListIndexAfter = await getLastTokenId(api, collectionId);151 expect(itemsListIndexAfter).to.be.equal(3);152153 expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(bob.address));154 expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(bob.address));155 expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(bob.address));156157 expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);158 expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);159 expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);160161 expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);162 expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);163 expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);164 });165 });166167 it('Create 0x01, 0x02, 0x03 items in active Fungible collection and verify tokens data in chain', async () => {168 await usingApi(async (api: ApiPromise) => {169 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});170 const itemsListIndexBefore = await getLastTokenId(api, collectionId);171 expect(itemsListIndexBefore).to.be.equal(0);172 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);173 const args = [174 {Fungible: {value: 1}},175 {Fungible: {value: 2}},176 {Fungible: {value: 3}},177 ];178 const createMultipleItemsTx = api.tx.nft179 .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);180 await submitTransactionAsync(bob, createMultipleItemsTx);181 const token1Data = await getBalance(api, collectionId, bob.address, 0);182183 expect(token1Data).to.be.equal(6n); 184 });185 });186187 it('Create 0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {188 await usingApi(async (api: ApiPromise) => {189 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});190 const itemsListIndexBefore = await getLastTokenId(api, collectionId);191 expect(itemsListIndexBefore).to.be.equal(0);192 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);193 const args = [194 {ReFungible: {const_data: [0x31], variable_data: [0x31], pieces: 1}},195 {ReFungible: {const_data: [0x32], variable_data: [0x32], pieces: 1}},196 {ReFungible: {const_data: [0x33], variable_data: [0x33], pieces: 1}},197 ];198 const createMultipleItemsTx = api.tx.nft199 .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);200 await submitTransactionAsync(bob, createMultipleItemsTx);201 const itemsListIndexAfter = await getLastTokenId(api, collectionId);202 expect(itemsListIndexAfter).to.be.equal(3);203204 expect(await getBalance(api, collectionId, bob.address, 1)).to.be.equal(1n);205 expect(await getBalance(api, collectionId, bob.address, 2)).to.be.equal(1n);206 expect(await getBalance(api, collectionId, bob.address, 3)).to.be.equal(1n);207208 expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);209 expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);210 expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);211212 expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);213 expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);214 expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);215 });216 });217});218219describe('Negative Integration Test createMultipleItems(collection_id, owner, items_data):', () => {220221 let alice: IKeyringPair;222 let bob: IKeyringPair;223224 before(async () => {225 await usingApi(async () => {226 alice = privateKey('//Alice');227 bob = privateKey('//Bob');228 });229 });230231 it('Regular user cannot create items in active NFT collection', async () => {232 await usingApi(async (api: ApiPromise) => {233 const collectionId = await createCollectionExpectSuccess();234 const itemsListIndexBefore = await getLastTokenId(api, collectionId);235 expect(itemsListIndexBefore).to.be.equal(0);236 const args = [{NFT: ['0x31', '0x31']}, {NFT: ['0x32', '0x32']}, {NFT: ['0x33', '0x33']}];237 const createMultipleItemsTx = api.tx.nft238 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);239 await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;240 });241 });242243 it('Regular user cannot create items in active Fungible collection', async () => {244 await usingApi(async (api: ApiPromise) => {245 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});246 const itemsListIndexBefore = await getLastTokenId(api, collectionId);247 expect(itemsListIndexBefore).to.be.equal(0);248 const args = [249 {Fungible: {value: 1}},250 {Fungible: {value: 2}},251 {Fungible: {value: 3}},252 ];253 const createMultipleItemsTx = api.tx.nft254 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);255 await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;256 });257 });258259 it('Regular user cannot create items in active ReFungible collection', async () => {260 await usingApi(async (api: ApiPromise) => {261 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});262 const itemsListIndexBefore = await getLastTokenId(api, collectionId);263 expect(itemsListIndexBefore).to.be.equal(0);264 const args = [265 {ReFungible: {const_data: [0x31], variable_data: [0x31], pieces: 1}},266 {ReFungible: {const_data: [0x32], variable_data: [0x32], pieces: 1}},267 {ReFungible: {const_data: [0x33], variable_data: [0x33], pieces: 1}},268 ];269 const createMultipleItemsTx = api.tx.nft270 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);271 await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;272 });273 });274275 it('Create token in not existing collection', async () => {276 await usingApi(async (api: ApiPromise) => {277 const collectionId = await getCreatedCollectionCount(api) + 1;278 const createMultipleItemsTx = api.tx.nft279 .createMultipleItems(collectionId, normalizeAccountId(alice.address), ['NFT', 'NFT', 'NFT']);280 await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;281 });282 });283284 it('Create NFT and Re-fungible tokens that has reached the maximum data limit', async () => {285 await usingApi(async (api: ApiPromise) => {286 287 const collectionId = await createCollectionExpectSuccess();288 const alice = privateKey('//Alice');289 const args = [290 {NFT: ['A'.repeat(2049), 'A'.repeat(2049)]},291 {NFT: ['B'.repeat(2049), 'B'.repeat(2049)]},292 {NFT: ['C'.repeat(2049), 'C'.repeat(2049)]},293 ];294 const createMultipleItemsTx = api.tx.nft295 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);296 await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;297298 299 const collectionIdReFungible =300 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});301 const argsReFungible = [302 {ReFungible: ['1'.repeat(2049), '1'.repeat(2049), 10]},303 {ReFungible: ['2'.repeat(2049), '2'.repeat(2049), 10]},304 {ReFungible: ['3'.repeat(2049), '3'.repeat(2049), 10]},305 ];306 const createMultipleItemsTxFungible = api.tx.nft307 .createMultipleItems(collectionIdReFungible, normalizeAccountId(alice.address), argsReFungible);308 await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTxFungible)).to.be.rejected;309 });310 });311312 it('Create tokens with different types', async () => {313 await usingApi(async (api: ApiPromise) => {314 const collectionId = await createCollectionExpectSuccess();315 const createMultipleItemsTx = api.tx.nft316 .createMultipleItems(collectionId, normalizeAccountId(alice.address), ['NFT', 'Fungible', 'ReFungible']);317 await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;318 319 await destroyCollectionExpectSuccess(collectionId);320 });321 });322323 it('Create tokens with different data limits <> maximum data limit', async () => {324 await usingApi(async (api: ApiPromise) => {325 const collectionId = await createCollectionExpectSuccess();326 const args = [327 {NFT: ['A', 'A']},328 {NFT: ['B', 'B'.repeat(2049)]},329 {NFT: ['C'.repeat(2049), 'C']},330 ];331 const createMultipleItemsTx = await api.tx.nft332 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);333 await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;334 });335 });336337 it('Fails when minting tokens exceeds collectionLimits amount', async () => {338 await usingApi(async (api) => {339340 const collectionId = await createCollectionExpectSuccess();341 await setCollectionLimitsExpectSuccess(alice, collectionId, {342 tokenLimit: 1,343 });344 const args = [345 {NFT: ['A', 'A']},346 {NFT: ['B', 'B']},347 ];348 const createMultipleItemsTx = api.tx.nft.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);349 await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;350 });351 });352});