difftreelog
wip migrating confirmSponsorship
in: master
2 files changed
tests/package.jsondiffbeforeafterboth--- a/tests/package.json
+++ b/tests/package.json
@@ -44,6 +44,7 @@
"testAddCollectionAdmin": "mocha --timeout 9999999 -r ts-node/register ./**/addCollectionAdmin.test.ts",
"testSetSchemaVersion": "mocha --timeout 9999999 -r ts-node/register ./**/setSchemaVersion.test.ts",
"testSetCollectionLimits": "mocha --timeout 9999999 -r ts-node/register ./**/setCollectionLimits.test.ts",
+ "testChangeCollectionOwner": "mocha --timeout 9999999 -r ts-node/register ./**/change-collection-owner.test.ts",
"testSetCollectionSponsor": "mocha --timeout 9999999 -r ts-node/register ./**/setCollectionSponsor.test.ts",
"testConfirmSponsorship": "mocha --timeout 9999999 -r ts-node/register ./**/confirmSponsorship.test.ts",
"testRemoveCollectionAdmin": "mocha --timeout 9999999 -r ts-node/register ./**/removeCollectionAdmin.test.ts",
tests/src/confirmSponsorship.test.tsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import chai from 'chai';18import chaiAsPromised from 'chai-as-promised';19import {default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync} from './substrate/substrate-api';20import {21 createCollectionExpectSuccess,22 setCollectionSponsorExpectSuccess,23 destroyCollectionExpectSuccess,24 confirmSponsorshipExpectSuccess,25 confirmSponsorshipExpectFailure,26 createItemExpectSuccess,27 findUnusedAddress,28 getGenericResult,29 enableAllowListExpectSuccess,30 enablePublicMintingExpectSuccess,31 addToAllowListExpectSuccess,32 normalizeAccountId,33 addCollectionAdminExpectSuccess,34 getCreatedCollectionCount,35 UNIQUE,36 requirePallets,37 Pallets,38} from './util/helpers';39import {IKeyringPair} from '@polkadot/types/types';4041chai.use(chaiAsPromised);42const expect = chai.expect;4344let alice: IKeyringPair;45let bob: IKeyringPair;46let charlie: IKeyringPair;4748describe('integration test: ext. confirmSponsorship():', () => {4950 before(async () => {51 await usingApi(async (api, privateKeyWrapper) => {52 alice = privateKeyWrapper('//Alice');53 bob = privateKeyWrapper('//Bob');54 charlie = privateKeyWrapper('//Charlie');55 });56 });5758 it('Confirm collection sponsorship', async () => {59 const collectionId = await createCollectionExpectSuccess();60 await setCollectionSponsorExpectSuccess(collectionId, bob.address);61 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');62 });63 it('Add sponsor to a collection after the same sponsor was already added and confirmed', async () => {64 const collectionId = await createCollectionExpectSuccess();65 await setCollectionSponsorExpectSuccess(collectionId, bob.address);66 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');67 await setCollectionSponsorExpectSuccess(collectionId, bob.address);68 });69 it('Add new sponsor to a collection after another sponsor was already added and confirmed', async () => {70 const collectionId = await createCollectionExpectSuccess();71 await setCollectionSponsorExpectSuccess(collectionId, bob.address);72 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');73 await setCollectionSponsorExpectSuccess(collectionId, charlie.address);74 });7576 it('NFT: Transfer fees are paid by the sponsor after confirmation', async () => {77 const collectionId = await createCollectionExpectSuccess();78 await setCollectionSponsorExpectSuccess(collectionId, bob.address);79 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');8081 await usingApi(async (api, privateKeyWrapper) => {82 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();8384 // Find unused address85 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);8687 // Mint token for unused address88 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', zeroBalance.address);8990 // Transfer this tokens from unused address to Alice91 const zeroToAlice = api.tx.unique.transfer(normalizeAccountId(zeroBalance.address), collectionId, itemId, 0);92 const events = await submitTransactionAsync(zeroBalance, zeroToAlice);93 const result = getGenericResult(events);94 expect(result.success).to.be.true;9596 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();9798 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;99 });100101 });102103 it('Fungible: Transfer fees are paid by the sponsor after confirmation', async () => {104 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});105 await setCollectionSponsorExpectSuccess(collectionId, bob.address);106 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');107108 await usingApi(async (api, privateKeyWrapper) => {109 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();110111 // Find unused address112 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);113114 // Mint token for unused address115 const itemId = await createItemExpectSuccess(alice, collectionId, 'Fungible', zeroBalance.address);116117 // Transfer this tokens from unused address to Alice118 const zeroToAlice = api.tx.unique.transfer(normalizeAccountId(zeroBalance.address), collectionId, itemId, 1);119 const events1 = await submitTransactionAsync(zeroBalance, zeroToAlice);120 const result1 = getGenericResult(events1);121 expect(result1.success).to.be.true;122123 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();124125 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;126 });127 });128129 it('ReFungible: Transfer fees are paid by the sponsor after confirmation', async function() {130 await requirePallets(this, [Pallets.ReFungible]);131132 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});133 await setCollectionSponsorExpectSuccess(collectionId, bob.address);134 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');135136 await usingApi(async (api, privateKeyWrapper) => {137 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();138139 // Find unused address140 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);141142 // Mint token for unused address143 const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', zeroBalance.address);144145 // Transfer this tokens from unused address to Alice146 const zeroToAlice = api.tx.unique.transfer(normalizeAccountId(zeroBalance.address), collectionId, itemId, 1);147 const events1 = await submitTransactionAsync(zeroBalance, zeroToAlice);148 const result1 = getGenericResult(events1);149150 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();151152 expect(result1.success).to.be.true;153 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;154 });155 });156157 it('CreateItem fees are paid by the sponsor after confirmation', async () => {158 const collectionId = await createCollectionExpectSuccess();159 await setCollectionSponsorExpectSuccess(collectionId, bob.address);160 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');161162 // Enable collection allow list163 await enableAllowListExpectSuccess(alice, collectionId);164165 // Enable public minting166 await enablePublicMintingExpectSuccess(alice, collectionId);167168 // Create Item169 await usingApi(async (api, privateKeyWrapper) => {170 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();171172 // Find unused address173 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);174175 // Add zeroBalance address to allow list176 await addToAllowListExpectSuccess(alice, collectionId, zeroBalance.address);177178 // Mint token using unused address as signer179 await createItemExpectSuccess(zeroBalance, collectionId, 'NFT', zeroBalance.address);180181 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();182183 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;184 });185 });186187 it('NFT: Sponsoring of transfers is rate limited', async () => {188 const collectionId = await createCollectionExpectSuccess();189 await setCollectionSponsorExpectSuccess(collectionId, bob.address);190 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');191192 await usingApi(async (api, privateKeyWrapper) => {193 // Find unused address194 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);195196 // Mint token for alice197 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);198199 // Transfer this token from Alice to unused address and back200 // Alice to Zero gets sponsored201 const aliceToZero = api.tx.unique.transfer(normalizeAccountId(zeroBalance.address), collectionId, itemId, 0);202 const events1 = await submitTransactionAsync(alice, aliceToZero);203 const result1 = getGenericResult(events1);204205 // Second transfer should fail206 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();207 const zeroToAlice = api.tx.unique.transfer(normalizeAccountId(alice.address), collectionId, itemId, 0);208 const badTransaction = async function () {209 await submitTransactionExpectFailAsync(zeroBalance, zeroToAlice);210 };211 await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees');212 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();213214 // Try again after Zero gets some balance - now it should succeed215 const balancetx = api.tx.balances.transfer(zeroBalance.address, 1n * UNIQUE);216 await submitTransactionAsync(alice, balancetx);217 const events2 = await submitTransactionAsync(zeroBalance, zeroToAlice);218 const result2 = getGenericResult(events2);219220 expect(result1.success).to.be.true;221 expect(result2.success).to.be.true;222 expect(sponsorBalanceAfter).to.be.equal(sponsorBalanceBefore);223 });224 });225226 it('Fungible: Sponsoring is rate limited', async () => {227 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});228 await setCollectionSponsorExpectSuccess(collectionId, bob.address);229 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');230231 await usingApi(async (api, privateKeyWrapper) => {232 // Find unused address233 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);234235 // Mint token for unused address236 const itemId = await createItemExpectSuccess(alice, collectionId, 'Fungible', zeroBalance.address);237238 // Transfer this tokens in parts from unused address to Alice239 const zeroToAlice = api.tx.unique.transfer(normalizeAccountId(zeroBalance.address), collectionId, itemId, 1);240 const events1 = await submitTransactionAsync(zeroBalance, zeroToAlice);241 const result1 = getGenericResult(events1);242 expect(result1.success).to.be.true;243244 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();245 await expect(submitTransactionExpectFailAsync(zeroBalance, zeroToAlice)).to.be.rejected;246 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();247248 // Try again after Zero gets some balance - now it should succeed249 const balancetx = api.tx.balances.transfer(zeroBalance.address, 1n * UNIQUE);250 await submitTransactionAsync(alice, balancetx);251 const events2 = await submitTransactionAsync(zeroBalance, zeroToAlice);252 const result2 = getGenericResult(events2);253 expect(result2.success).to.be.true;254255 expect(sponsorBalanceAfter).to.be.equal(sponsorBalanceBefore);256 });257 });258259 it('ReFungible: Sponsoring is rate limited', async function() {260 await requirePallets(this, [Pallets.ReFungible]);261262 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});263 await setCollectionSponsorExpectSuccess(collectionId, bob.address);264 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');265266 await usingApi(async (api, privateKeyWrapper) => {267 // Find unused address268 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);269270 // Mint token for alice271 const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', zeroBalance.address);272273 const zeroToAlice = api.tx.unique.transfer(normalizeAccountId(alice.address), collectionId, itemId, 1);274275 // Zero to alice gets sponsored276 const events1 = await submitTransactionAsync(zeroBalance, zeroToAlice);277 const result1 = getGenericResult(events1);278 expect(result1.success).to.be.true;279280 // Second transfer should fail281 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();282 await expect(submitTransactionExpectFailAsync(zeroBalance, zeroToAlice)).to.be.rejectedWith('Inability to pay some fees');283 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();284 expect(sponsorBalanceAfter).to.be.equal(sponsorBalanceBefore);285286 // Try again after Zero gets some balance - now it should succeed287 const balancetx = api.tx.balances.transfer(zeroBalance.address, 1n * UNIQUE);288 await submitTransactionAsync(alice, balancetx);289 const events2 = await submitTransactionAsync(zeroBalance, zeroToAlice);290 const result2 = getGenericResult(events2);291 expect(result2.success).to.be.true;292 });293 });294295 it('NFT: Sponsoring of createItem is rate limited', async () => {296 const collectionId = await createCollectionExpectSuccess();297 await setCollectionSponsorExpectSuccess(collectionId, bob.address);298 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');299300 // Enable collection allow list301 await enableAllowListExpectSuccess(alice, collectionId);302303 // Enable public minting304 await enablePublicMintingExpectSuccess(alice, collectionId);305306 await usingApi(async (api, privateKeyWrapper) => {307 // Find unused address308 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);309310 // Add zeroBalance address to allow list311 await addToAllowListExpectSuccess(alice, collectionId, zeroBalance.address);312313 // Mint token using unused address as signer - gets sponsored314 await createItemExpectSuccess(zeroBalance, collectionId, 'NFT', zeroBalance.address);315316 // Second mint should fail317 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();318319 const badTransaction = async function () {320 await createItemExpectSuccess(zeroBalance, collectionId, 'NFT', zeroBalance.address);321 };322 await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees');323 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();324325 // Try again after Zero gets some balance - now it should succeed326 const balancetx = api.tx.balances.transfer(zeroBalance.address, 1n * UNIQUE);327 await submitTransactionAsync(alice, balancetx);328 await createItemExpectSuccess(zeroBalance, collectionId, 'NFT', zeroBalance.address);329330 expect(sponsorBalanceAfter).to.be.equal(sponsorBalanceBefore);331 });332 });333334});335336describe('(!negative test!) integration test: ext. confirmSponsorship():', () => {337 before(async () => {338 await usingApi(async (api, privateKeyWrapper) => {339 alice = privateKeyWrapper('//Alice');340 bob = privateKeyWrapper('//Bob');341 charlie = privateKeyWrapper('//Charlie');342 });343 });344345 it('(!negative test!) Confirm sponsorship for a collection that never existed', async () => {346 // Find the collection that never existed347 let collectionId = 0;348 await usingApi(async (api) => {349 collectionId = await getCreatedCollectionCount(api) + 1;350 });351352 await confirmSponsorshipExpectFailure(collectionId, '//Bob');353 });354355 it('(!negative test!) Confirm sponsorship using a non-sponsor address', async () => {356 const collectionId = await createCollectionExpectSuccess();357 await setCollectionSponsorExpectSuccess(collectionId, bob.address);358359 await usingApi(async (api) => {360 const transfer = api.tx.balances.transfer(charlie.address, 1e15);361 await submitTransactionAsync(alice, transfer);362 });363364 await confirmSponsorshipExpectFailure(collectionId, '//Charlie');365 });366367 it('(!negative test!) Confirm sponsorship using owner address', async () => {368 const collectionId = await createCollectionExpectSuccess();369 await setCollectionSponsorExpectSuccess(collectionId, bob.address);370 await confirmSponsorshipExpectFailure(collectionId, '//Alice');371 });372373 it('(!negative test!) Confirm sponsorship by collection admin', async () => {374 const collectionId = await createCollectionExpectSuccess();375 await setCollectionSponsorExpectSuccess(collectionId, bob.address);376 await addCollectionAdminExpectSuccess(alice, collectionId, charlie.address);377 await confirmSponsorshipExpectFailure(collectionId, '//Charlie');378 });379380 it('(!negative test!) Confirm sponsorship without sponsor being set with setCollectionSponsor', async () => {381 const collectionId = await createCollectionExpectSuccess();382 await confirmSponsorshipExpectFailure(collectionId, '//Bob');383 });384385 it('(!negative test!) Confirm sponsorship in a collection that was destroyed', async () => {386 const collectionId = await createCollectionExpectSuccess();387 await destroyCollectionExpectSuccess(collectionId);388 await confirmSponsorshipExpectFailure(collectionId, '//Bob');389 });390391 it('(!negative test!) Transfer fees are not paid by the sponsor if the transfer failed', async () => {392 const collectionId = await createCollectionExpectSuccess();393 await setCollectionSponsorExpectSuccess(collectionId, bob.address);394 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');395396 await usingApi(async (api, privateKeyWrapper) => {397 // Find unused address398 const ownerZeroBalance = await findUnusedAddress(api, privateKeyWrapper);399400 // Find another unused address401 const senderZeroBalance = await findUnusedAddress(api, privateKeyWrapper);402403 // Mint token for an unused address404 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', ownerZeroBalance.address);405406 const sponsorBalanceBeforeTx = (await api.query.system.account(bob.address)).data.free.toBigInt();407408 // Try to transfer this token from an unsponsored unused adress to Alice409 const zeroToAlice = api.tx.unique.transfer(normalizeAccountId(alice.address), collectionId, itemId, 0);410 await expect(submitTransactionExpectFailAsync(senderZeroBalance, zeroToAlice)).to.be.rejected;411412 const sponsorBalanceAfterTx = (await api.query.system.account(bob.address)).data.free.toBigInt();413414 expect(sponsorBalanceAfterTx).to.equal(sponsorBalanceBeforeTx);415 });416 });417});