git.delta.rocks / unique-network / refs/commits / afa958b4c036

difftreelog

source

tests/src/transfer.test.ts17.8 KiBsourcehistory
1// 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 {ApiPromise} from '@polkadot/api';18import {IKeyringPair} from '@polkadot/types/types';19import {expect} from 'chai';20import {alicesPublicKey, bobsPublicKey} from './accounts';21import getBalance from './substrate/get-balance';22import {default as usingApi, submitTransactionAsync} from './substrate/substrate-api';23import {24  burnItemExpectSuccess, createCollectionExpectSuccess, createItemExpectSuccess,25  destroyCollectionExpectSuccess,26  findUnusedAddress,27  getCreateCollectionResult,28  getCreateItemResult,29  transferExpectFailure,30  transferExpectSuccess,31  addCollectionAdminExpectSuccess,32  getCreatedCollectionCount,33  toSubstrateAddress,34  getTokenOwner,35  normalizeAccountId,36  getBalance as getTokenBalance,37  transferFromExpectSuccess,38  transferFromExpectFail,39} from './util/helpers';40import {41  subToEth,42  itWeb3, 43} from './eth/util/helpers';4445let alice: IKeyringPair;46let bob: IKeyringPair;47let charlie: IKeyringPair;4849describe('Integration Test Transfer(recipient, collection_id, item_id, value)', () => {50  it('Balance transfers and check balance', async () => {51    await usingApi(async (api, privateKeyWrapper) => {52      const [alicesBalanceBefore, bobsBalanceBefore] = await getBalance(api, [alicesPublicKey, bobsPublicKey]);5354      const alicePrivateKey = privateKeyWrapper('//Alice');5556      const transfer = api.tx.balances.transfer(bobsPublicKey, 1n);57      const events = await submitTransactionAsync(alicePrivateKey, transfer);58      const result = getCreateItemResult(events);59      // tslint:disable-next-line:no-unused-expression60      expect(result.success).to.be.true;6162      const [alicesBalanceAfter, bobsBalanceAfter] = await getBalance(api, [alicesPublicKey, bobsPublicKey]);6364      // tslint:disable-next-line:no-unused-expression65      expect(alicesBalanceAfter < alicesBalanceBefore).to.be.true;66      // tslint:disable-next-line:no-unused-expression67      expect(bobsBalanceAfter > bobsBalanceBefore).to.be.true;68    });69  });7071  it('Inability to pay fees error message is correct', async () => {72    await usingApi(async (api) => {73      // Find unused address74      const pk = await findUnusedAddress(api);7576      const badTransfer = api.tx.balances.transfer(bobsPublicKey, 1n);77      // const events = await submitTransactionAsync(pk, badTransfer);78      const badTransaction = async () => {79        const events = await submitTransactionAsync(pk, badTransfer);80        const result = getCreateCollectionResult(events);81        // tslint:disable-next-line:no-unused-expression82        expect(result.success).to.be.false;83      };84      await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees , e.g. account balance too low');85    });86  });8788  it('User can transfer owned token', async () => {89    await usingApi(async (api, privateKeyWrapper) => {90      const alice = privateKeyWrapper('//Alice');91      const bob = privateKeyWrapper('//Bob');92      // nft93      const nftCollectionId = await createCollectionExpectSuccess();94      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');95      await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 1, 'NFT');96      // fungible97      const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});98      const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');99      await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob, 1, 'Fungible');100      // reFungible101      const reFungibleCollectionId = await102      createCollectionExpectSuccess({mode: {type: 'ReFungible'}});103      const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');104      await transferExpectSuccess(105        reFungibleCollectionId,106        newReFungibleTokenId,107        alice,108        bob,109        100,110        'ReFungible',111      );112    });113  });114115  it('Collection admin can transfer owned token', async () => {116    await usingApi(async (api, privateKeyWrapper) => {117      const alice = privateKeyWrapper('//Alice');118      const bob = privateKeyWrapper('//Bob');119      // nft120      const nftCollectionId = await createCollectionExpectSuccess();121      await addCollectionAdminExpectSuccess(alice, nftCollectionId, bob.address);122      const newNftTokenId = await createItemExpectSuccess(bob, nftCollectionId, 'NFT', bob.address);123      await transferExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, 1, 'NFT');124      // fungible125      const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});126      await addCollectionAdminExpectSuccess(alice, fungibleCollectionId, bob.address);127      const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible', bob.address);128      await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, 1, 'Fungible');129      // reFungible130      const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});131      await addCollectionAdminExpectSuccess(alice, reFungibleCollectionId, bob.address);132      const newReFungibleTokenId = await createItemExpectSuccess(bob, reFungibleCollectionId, 'ReFungible', bob.address);133      await transferExpectSuccess(134        reFungibleCollectionId,135        newReFungibleTokenId,136        bob,137        alice,138        100,139        'ReFungible',140      );141    });142  });143});144145describe('Negative Integration Test Transfer(recipient, collection_id, item_id, value)', () => {146  before(async () => {147    await usingApi(async (api, privateKeyWrapper) => {148      alice = privateKeyWrapper('//Alice');149      bob = privateKeyWrapper('//Bob');150      charlie = privateKeyWrapper('//Charlie');151    });152  });153  it('Transfer with not existed collection_id', async () => {154    await usingApi(async (api) => {155      // nft156      const nftCollectionCount = await getCreatedCollectionCount(api);157      await transferExpectFailure(nftCollectionCount + 1, 1, alice, bob, 1);158      // fungible159      const fungibleCollectionCount = await getCreatedCollectionCount(api);160      await transferExpectFailure(fungibleCollectionCount + 1, 0, alice, bob, 1);161      // reFungible162      const reFungibleCollectionCount = await getCreatedCollectionCount(api);163      await transferExpectFailure(reFungibleCollectionCount + 1, 1, alice, bob, 1);164    });165  });166  it('Transfer with deleted collection_id', async () => {167    // nft168    const nftCollectionId = await createCollectionExpectSuccess();169    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');170    await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId);171    await destroyCollectionExpectSuccess(nftCollectionId);172    await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);173    // fungible174    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});175    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');176    await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);177    await destroyCollectionExpectSuccess(fungibleCollectionId);178    await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);179    // reFungible180    const reFungibleCollectionId = await181    createCollectionExpectSuccess({mode: {type: 'ReFungible'}});182    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');183    await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);184    await destroyCollectionExpectSuccess(reFungibleCollectionId);185    await transferExpectFailure(186      reFungibleCollectionId,187      newReFungibleTokenId,188      alice,189      bob,190      1,191    );192  });193  it('Transfer with not existed item_id', async () => {194    // nft195    const nftCollectionId = await createCollectionExpectSuccess();196    await transferExpectFailure(nftCollectionId, 2, alice, bob, 1);197    // fungible198    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});199    await transferExpectFailure(fungibleCollectionId, 2, alice, bob, 1);200    // reFungible201    const reFungibleCollectionId = await202    createCollectionExpectSuccess({mode: {type: 'ReFungible'}});203    await transferExpectFailure(204      reFungibleCollectionId,205      2,206      alice,207      bob,208      1,209    );210  });211  it('Transfer with deleted item_id', async () => {212    // nft213    const nftCollectionId = await createCollectionExpectSuccess();214    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');215    await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId, 1);216    await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);217    // fungible218    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});219    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');220    await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);221    await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);222    // reFungible223    const reFungibleCollectionId = await224    createCollectionExpectSuccess({mode: {type: 'ReFungible'}});225    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');226    await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);227    await transferExpectFailure(228      reFungibleCollectionId,229      newReFungibleTokenId,230      alice,231      bob,232      1,233    );234  });235  it('Transfer with recipient that is not owner', async () => {236    // nft237    const nftCollectionId = await createCollectionExpectSuccess();238    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');239    await transferExpectFailure(nftCollectionId, newNftTokenId, charlie, bob, 1);240    // fungible241    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});242    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');243    await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, charlie, bob, 1);244    // reFungible245    const reFungibleCollectionId = await246    createCollectionExpectSuccess({mode: {type: 'ReFungible'}});247    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');248    await transferExpectFailure(249      reFungibleCollectionId,250      newReFungibleTokenId,251      charlie,252      bob,253      1,254    );255  });256});257258describe('Zero value transfer(From)', () => {259  before(async () => {260    await usingApi(async (api, privateKeyWrapper) => {261      alice = privateKeyWrapper('//Alice');262      bob = privateKeyWrapper('//Bob');263    });264  });265266  it('NFT', async () => {267    await usingApi(async (api: ApiPromise) => {268      const nftCollectionId = await createCollectionExpectSuccess();269      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');270271      const transferTx = api.tx.unique.transfer(normalizeAccountId(bob), nftCollectionId, newNftTokenId, 0);272      await submitTransactionAsync(alice, transferTx);273      const address = normalizeAccountId(await getTokenOwner(api, nftCollectionId, newNftTokenId));274275      expect(toSubstrateAddress(address)).to.be.equal(alice.address);276    });277  });278279  it('RFT', async () => {280    await usingApi(async (api: ApiPromise) => {281      const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});282      const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');283      const balanceBeforeAlice = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(alice), newReFungibleTokenId);284      const balanceBeforeBob = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(bob), newReFungibleTokenId);285286      const transferTx = api.tx.unique.transfer(normalizeAccountId(bob), reFungibleCollectionId, newReFungibleTokenId, 0);287      await submitTransactionAsync(alice, transferTx);288289      const balanceAfterAlice = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(alice), newReFungibleTokenId);290      const balanceAfterBob = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(bob), newReFungibleTokenId);291292      expect((balanceBeforeAlice)).to.be.equal(balanceAfterAlice);293      expect((balanceBeforeBob)).to.be.equal(balanceAfterBob);294    });295  });296297  it('Fungible', async () => {298    await usingApi(async (api: ApiPromise) => {299      const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});300      const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');301      const balanceBeforeAlice = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(alice), newFungibleTokenId);302      const balanceBeforeBob = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(bob), newFungibleTokenId);303304      const transferTx = api.tx.unique.transfer(normalizeAccountId(bob), fungibleCollectionId, newFungibleTokenId, 0);305      await submitTransactionAsync(alice, transferTx);306307      const balanceAfterAlice = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(alice), newFungibleTokenId);308      const balanceAfterBob = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(bob), newFungibleTokenId);309310      expect((balanceBeforeAlice)).to.be.equal(balanceAfterAlice);311      expect((balanceBeforeBob)).to.be.equal(balanceAfterBob);312    });313  });314});315316describe('Transfers to self (potentially over substrate-evm boundary)', () => {317  itWeb3('Transfers to self. In case of same frontend', async ({api, privateKeyWrapper}) => {318    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});319    const alice = privateKeyWrapper('//Alice');320    const aliceProxy = subToEth(alice.address);321    const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});322    await transferExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, 10, 'Fungible');323    const balanceAliceBefore = await getTokenBalance(api, collectionId, {Ethereum: aliceProxy}, tokenId);324    await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, {Ethereum: aliceProxy}, 10, 'Fungible');325    const balanceAliceAfter = await getTokenBalance(api, collectionId, {Ethereum: aliceProxy}, tokenId);326    expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);327  });328329  itWeb3('Transfers to self. In case of substrate-evm boundary', async ({api, privateKeyWrapper}) => {330    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});331    const alice = privateKeyWrapper('//Alice');332    const aliceProxy = subToEth(alice.address);333    const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});334    const balanceAliceBefore = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);335    await transferExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy} , 10, 'Fungible');336    await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, alice, 10, 'Fungible');337    const balanceAliceAfter = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);338    expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);339  });340341  itWeb3('Transfers to self. In case of inside substrate-evm', async ({api, privateKeyWrapper}) => {342    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});343    const alice = privateKeyWrapper('//Alice');344    const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});345    const balanceAliceBefore = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);346    await transferExpectSuccess(collectionId, tokenId, alice, alice , 10, 'Fungible');347    await transferFromExpectSuccess(collectionId, tokenId, alice, alice, alice, 10, 'Fungible');348    const balanceAliceAfter = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);349    expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);350  });351352  itWeb3('Transfers to self. In case of inside substrate-evm when not enought "Fungibles"', async ({api, privateKeyWrapper}) => {353    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});354    const alice = privateKeyWrapper('//Alice');355    const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});356    const balanceAliceBefore = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);357    await transferExpectFailure(collectionId, tokenId, alice, alice , 11);358    await transferFromExpectFail(collectionId, tokenId, alice, alice, alice, 11);359    const balanceAliceAfter = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);360    expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);361  });362});