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

difftreelog

source

tests/src/transfer.test.ts16.7 KiBsourcehistory
1//2// This file is subject to the terms and conditions defined in3// file 'LICENSE', which is part of this source code package.4//56import {ApiPromise} from '@polkadot/api';7import {IKeyringPair} from '@polkadot/types/types';8import {expect} from 'chai';9import {alicesPublicKey, bobsPublicKey} from './accounts';10import getBalance from './substrate/get-balance';11import privateKey from './substrate/privateKey';12import {default as usingApi, submitTransactionAsync} from './substrate/substrate-api';13import {14  burnItemExpectSuccess, createCollectionExpectSuccess, createItemExpectSuccess,15  destroyCollectionExpectSuccess,16  findUnusedAddress,17  getCreateCollectionResult,18  getCreateItemResult,19  transferExpectFailure,20  transferExpectSuccess,21  addCollectionAdminExpectSuccess,22  getCreatedCollectionCount,23  toSubstrateAddress,24  getTokenOwner,25  normalizeAccountId,26  getBalance as getTokenBalance,27  transferFromExpectSuccess,28  transferFromExpectFail,29} from './util/helpers';30import {31  subToEth,32  itWeb3, 33} from './eth/util/helpers';3435let alice: IKeyringPair;36let bob: IKeyringPair;37let charlie: IKeyringPair;3839describe('Integration Test Transfer(recipient, collection_id, item_id, value)', () => {40  it('Balance transfers and check balance', async () => {41    await usingApi(async (api: ApiPromise) => {42      const [alicesBalanceBefore, bobsBalanceBefore] = await getBalance(api, [alicesPublicKey, bobsPublicKey]);4344      const alicePrivateKey = privateKey('//Alice');4546      const transfer = api.tx.balances.transfer(bobsPublicKey, 1n);47      const events = await submitTransactionAsync(alicePrivateKey, transfer);48      const result = getCreateItemResult(events);49      // tslint:disable-next-line:no-unused-expression50      expect(result.success).to.be.true;5152      const [alicesBalanceAfter, bobsBalanceAfter] = await getBalance(api, [alicesPublicKey, bobsPublicKey]);5354      // tslint:disable-next-line:no-unused-expression55      expect(alicesBalanceAfter < alicesBalanceBefore).to.be.true;56      // tslint:disable-next-line:no-unused-expression57      expect(bobsBalanceAfter > bobsBalanceBefore).to.be.true;58    });59  });6061  it('Inability to pay fees error message is correct', async () => {62    await usingApi(async (api) => {63      // Find unused address64      const pk = await findUnusedAddress(api);6566      const badTransfer = api.tx.balances.transfer(bobsPublicKey, 1n);67      // const events = await submitTransactionAsync(pk, badTransfer);68      const badTransaction = async () => {69        const events = await submitTransactionAsync(pk, badTransfer);70        const result = getCreateCollectionResult(events);71        // tslint:disable-next-line:no-unused-expression72        expect(result.success).to.be.false;73      };74      await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees , e.g. account balance too low');75    });76  });7778  it('User can transfer owned token', async () => {79    await usingApi(async () => {80      const alice = privateKey('//Alice');81      const bob = privateKey('//Bob');82      // nft83      const nftCollectionId = await createCollectionExpectSuccess();84      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');85      await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 1, 'NFT');86      // fungible87      const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});88      const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');89      await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob, 1, 'Fungible');90      // reFungible91      const reFungibleCollectionId = await92      createCollectionExpectSuccess({mode: {type: 'ReFungible'}});93      const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');94      await transferExpectSuccess(95        reFungibleCollectionId,96        newReFungibleTokenId,97        alice,98        bob,99        100,100        'ReFungible',101      );102    });103  });104105  it('Collection admin can transfer owned token', async () => {106    await usingApi(async () => {107      const alice = privateKey('//Alice');108      const bob = privateKey('//Bob');109      // nft110      const nftCollectionId = await createCollectionExpectSuccess();111      await addCollectionAdminExpectSuccess(alice, nftCollectionId, bob.address);112      const newNftTokenId = await createItemExpectSuccess(bob, nftCollectionId, 'NFT', bob.address);113      await transferExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, 1, 'NFT');114      // fungible115      const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});116      await addCollectionAdminExpectSuccess(alice, fungibleCollectionId, bob.address);117      const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible', bob.address);118      await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, 1, 'Fungible');119      // reFungible120      const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});121      await addCollectionAdminExpectSuccess(alice, reFungibleCollectionId, bob.address);122      const newReFungibleTokenId = await createItemExpectSuccess(bob, reFungibleCollectionId, 'ReFungible', bob.address);123      await transferExpectSuccess(124        reFungibleCollectionId,125        newReFungibleTokenId,126        bob,127        alice,128        100,129        'ReFungible',130      );131    });132  });133});134135describe('Negative Integration Test Transfer(recipient, collection_id, item_id, value)', () => {136  before(async () => {137    await usingApi(async () => {138      alice = privateKey('//Alice');139      bob = privateKey('//Bob');140      charlie = privateKey('//Charlie');141    });142  });143  it('Transfer with not existed collection_id', async () => {144    await usingApi(async (api) => {145      // nft146      const nftCollectionCount = await getCreatedCollectionCount(api);147      await transferExpectFailure(nftCollectionCount + 1, 1, alice, bob, 1);148      // fungible149      const fungibleCollectionCount = await getCreatedCollectionCount(api);150      await transferExpectFailure(fungibleCollectionCount + 1, 0, alice, bob, 1);151      // reFungible152      const reFungibleCollectionCount = await getCreatedCollectionCount(api);153      await transferExpectFailure(reFungibleCollectionCount + 1, 1, alice, bob, 1);154    });155  });156  it('Transfer with deleted collection_id', async () => {157    // nft158    const nftCollectionId = await createCollectionExpectSuccess();159    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');160    await destroyCollectionExpectSuccess(nftCollectionId);161    await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);162    // fungible163    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});164    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');165    await destroyCollectionExpectSuccess(fungibleCollectionId);166    await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);167    // reFungible168    const reFungibleCollectionId = await169    createCollectionExpectSuccess({mode: {type: 'ReFungible'}});170    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');171    await destroyCollectionExpectSuccess(reFungibleCollectionId);172    await transferExpectFailure(173      reFungibleCollectionId,174      newReFungibleTokenId,175      alice,176      bob,177      1,178    );179  });180  it('Transfer with not existed item_id', async () => {181    // nft182    const nftCollectionId = await createCollectionExpectSuccess();183    await transferExpectFailure(nftCollectionId, 2, alice, bob, 1);184    // fungible185    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});186    await transferExpectFailure(fungibleCollectionId, 2, alice, bob, 1);187    // reFungible188    const reFungibleCollectionId = await189    createCollectionExpectSuccess({mode: {type: 'ReFungible'}});190    await transferExpectFailure(191      reFungibleCollectionId,192      2,193      alice,194      bob,195      1,196    );197  });198  it('Transfer with deleted item_id', async () => {199    // nft200    const nftCollectionId = await createCollectionExpectSuccess();201    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');202    await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId, 1);203    await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);204    // fungible205    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});206    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');207    await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);208    await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);209    // reFungible210    const reFungibleCollectionId = await211    createCollectionExpectSuccess({mode: {type: 'ReFungible'}});212    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');213    await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);214    await transferExpectFailure(215      reFungibleCollectionId,216      newReFungibleTokenId,217      alice,218      bob,219      1,220    );221  });222  it('Transfer with recipient that is not owner', async () => {223    // nft224    const nftCollectionId = await createCollectionExpectSuccess();225    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');226    await transferExpectFailure(nftCollectionId, newNftTokenId, charlie, bob, 1);227    // fungible228    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});229    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');230    await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, charlie, bob, 1);231    // reFungible232    const reFungibleCollectionId = await233    createCollectionExpectSuccess({mode: {type: 'ReFungible'}});234    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');235    await transferExpectFailure(236      reFungibleCollectionId,237      newReFungibleTokenId,238      charlie,239      bob,240      1,241    );242  });243});244245describe('Zero value transfer(From)', () => {246  before(async () => {247    await usingApi(async () => {248      alice = privateKey('//Alice');249      bob = privateKey('//Bob');250    });251  });252253  it('NFT', async () => {254    await usingApi(async (api: ApiPromise) => {255      const nftCollectionId = await createCollectionExpectSuccess();256      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');257258      const transferTx = api.tx.unique.transfer(normalizeAccountId(bob), nftCollectionId, newNftTokenId, 0);259      await submitTransactionAsync(alice, transferTx);260      const address = normalizeAccountId(await getTokenOwner(api, nftCollectionId, newNftTokenId));261262      expect(toSubstrateAddress(address)).to.be.equal(alice.address);263    });264  });265266  it('RFT', async () => {267    await usingApi(async (api: ApiPromise) => {268      const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});269      const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');270      const balanceBeforeAlice = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(alice), newReFungibleTokenId);271      const balanceBeforeBob = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(bob), newReFungibleTokenId);272273      const transferTx = api.tx.unique.transfer(normalizeAccountId(bob), reFungibleCollectionId, newReFungibleTokenId, 0);274      await submitTransactionAsync(alice, transferTx);275276      const balanceAfterAlice = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(alice), newReFungibleTokenId);277      const balanceAfterBob = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(bob), newReFungibleTokenId);278279      expect((balanceBeforeAlice)).to.be.equal(balanceAfterAlice);280      expect((balanceBeforeBob)).to.be.equal(balanceAfterBob);281    });282  });283284  it('Fungible', async () => {285    await usingApi(async (api: ApiPromise) => {286      const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});287      const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');288      const balanceBeforeAlice = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(alice), newFungibleTokenId);289      const balanceBeforeBob = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(bob), newFungibleTokenId);290291      const transferTx = api.tx.unique.transfer(normalizeAccountId(bob), fungibleCollectionId, newFungibleTokenId, 0);292      await submitTransactionAsync(alice, transferTx);293294      const balanceAfterAlice = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(alice), newFungibleTokenId);295      const balanceAfterBob = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(bob), newFungibleTokenId);296297      expect((balanceBeforeAlice)).to.be.equal(balanceAfterAlice);298      expect((balanceBeforeBob)).to.be.equal(balanceAfterBob);299    });300  });301});302303describe('Transfers to self (potentially over substrate-evm boundary)', () => {304  itWeb3('Transfers to self. In case of same frontend', async ({api}) => {305    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});306    const alice = privateKey('//Alice');307    const aliceProxy = subToEth(alice.address);308    const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});309    await transferExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, 10, 'Fungible');310    const balanceAliceBefore = await getTokenBalance(api, collectionId, {Ethereum: aliceProxy}, tokenId);311    await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, {Ethereum: aliceProxy}, 10, 'Fungible');312    const balanceAliceAfter = await getTokenBalance(api, collectionId, {Ethereum: aliceProxy}, tokenId);313    expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);314  });315316  itWeb3('Transfers to self. In case of substrate-evm boundary', async ({api}) => {317    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});318    const alice = privateKey('//Alice');319    const aliceProxy = subToEth(alice.address);320    const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});321    const balanceAliceBefore = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);322    await transferExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy} , 10, 'Fungible');323    await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, alice, 10, 'Fungible');324    const balanceAliceAfter = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);325    expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);326  });327328  itWeb3('Transfers to self. In case of inside substrate-evm', async ({api}) => {329    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});330    const alice = privateKey('//Alice');331    const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});332    const balanceAliceBefore = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);333    await transferExpectSuccess(collectionId, tokenId, alice, alice , 10, 'Fungible');334    await transferFromExpectSuccess(collectionId, tokenId, alice, alice, alice, 10, 'Fungible');335    const balanceAliceAfter = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);336    expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);337  });338339  itWeb3('Transfers to self. In case of inside substrate-evm when not enought "Fungibles"', async ({api}) => {340    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});341    const alice = privateKey('//Alice');342    const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});343    const balanceAliceBefore = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);344    await transferExpectFailure(collectionId, tokenId, alice, alice , 11);345    await transferFromExpectFail(collectionId, tokenId, alice, alice, alice, 11);346    const balanceAliceAfter = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);347    expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);348  });349});