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

difftreelog

CORE-215 Add test Transfers to self. In case of inside substrate-evm Transfers to self. In case of inside substrate-evm when not enought "Fungibles"

Trubnikov Sergey2022-02-22parent: #e6f8932.patch.diff
in: master

1 file changed

modifiedtests/src/transfer.test.tsdiffbeforeafterboth
before · tests/src/transfer.test.ts
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} from './util/helpers';29import {30  subToEth,31  itWeb3, 32} from './eth/util/helpers';3334let alice: IKeyringPair;35let bob: IKeyringPair;36let charlie: IKeyringPair;3738describe('Integration Test Transfer(recipient, collection_id, item_id, value)', () => {39  it('Balance transfers and check balance', async () => {40    await usingApi(async (api: ApiPromise) => {41      const [alicesBalanceBefore, bobsBalanceBefore] = await getBalance(api, [alicesPublicKey, bobsPublicKey]);4243      const alicePrivateKey = privateKey('//Alice');4445      const transfer = api.tx.balances.transfer(bobsPublicKey, 1n);46      const events = await submitTransactionAsync(alicePrivateKey, transfer);47      const result = getCreateItemResult(events);48      // tslint:disable-next-line:no-unused-expression49      expect(result.success).to.be.true;5051      const [alicesBalanceAfter, bobsBalanceAfter] = await getBalance(api, [alicesPublicKey, bobsPublicKey]);5253      // tslint:disable-next-line:no-unused-expression54      expect(alicesBalanceAfter < alicesBalanceBefore).to.be.true;55      // tslint:disable-next-line:no-unused-expression56      expect(bobsBalanceAfter > bobsBalanceBefore).to.be.true;57    });58  });5960  it('Inability to pay fees error message is correct', async () => {61    await usingApi(async (api) => {62      // Find unused address63      const pk = await findUnusedAddress(api);6465      const badTransfer = api.tx.balances.transfer(bobsPublicKey, 1n);66      // const events = await submitTransactionAsync(pk, badTransfer);67      const badTransaction = async () => {68        const events = await submitTransactionAsync(pk, badTransfer);69        const result = getCreateCollectionResult(events);70        // tslint:disable-next-line:no-unused-expression71        expect(result.success).to.be.false;72      };73      await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees , e.g. account balance too low');74    });75  });7677  it('User can transfer owned token', async () => {78    await usingApi(async () => {79      const alice = privateKey('//Alice');80      const bob = privateKey('//Bob');81      // nft82      const nftCollectionId = await createCollectionExpectSuccess();83      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');84      await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 1, 'NFT');85      // fungible86      const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});87      const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');88      await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob, 1, 'Fungible');89      // reFungible90      const reFungibleCollectionId = await91      createCollectionExpectSuccess({mode: {type: 'ReFungible'}});92      const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');93      await transferExpectSuccess(94        reFungibleCollectionId,95        newReFungibleTokenId,96        alice,97        bob,98        100,99        'ReFungible',100      );101    });102  });103104  it('Collection admin can transfer owned token', async () => {105    await usingApi(async () => {106      const alice = privateKey('//Alice');107      const bob = privateKey('//Bob');108      // nft109      const nftCollectionId = await createCollectionExpectSuccess();110      await addCollectionAdminExpectSuccess(alice, nftCollectionId, bob.address);111      const newNftTokenId = await createItemExpectSuccess(bob, nftCollectionId, 'NFT', bob.address);112      await transferExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, 1, 'NFT');113      // fungible114      const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});115      await addCollectionAdminExpectSuccess(alice, fungibleCollectionId, bob.address);116      const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible', bob.address);117      await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, 1, 'Fungible');118      // reFungible119      const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});120      await addCollectionAdminExpectSuccess(alice, reFungibleCollectionId, bob.address);121      const newReFungibleTokenId = await createItemExpectSuccess(bob, reFungibleCollectionId, 'ReFungible', bob.address);122      await transferExpectSuccess(123        reFungibleCollectionId,124        newReFungibleTokenId,125        bob,126        alice,127        100,128        'ReFungible',129      );130    });131  });132});133134describe('Negative Integration Test Transfer(recipient, collection_id, item_id, value)', () => {135  before(async () => {136    await usingApi(async () => {137      alice = privateKey('//Alice');138      bob = privateKey('//Bob');139      charlie = privateKey('//Charlie');140    });141  });142  it('Transfer with not existed collection_id', async () => {143    await usingApi(async (api) => {144      // nft145      const nftCollectionCount = await getCreatedCollectionCount(api);146      await transferExpectFailure(nftCollectionCount + 1, 1, alice, bob, 1);147      // fungible148      const fungibleCollectionCount = await getCreatedCollectionCount(api);149      await transferExpectFailure(fungibleCollectionCount + 1, 0, alice, bob, 1);150      // reFungible151      const reFungibleCollectionCount = await getCreatedCollectionCount(api);152      await transferExpectFailure(reFungibleCollectionCount + 1, 1, alice, bob, 1);153    });154  });155  it('Transfer with deleted collection_id', async () => {156    // nft157    const nftCollectionId = await createCollectionExpectSuccess();158    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');159    await destroyCollectionExpectSuccess(nftCollectionId);160    await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);161    // fungible162    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});163    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');164    await destroyCollectionExpectSuccess(fungibleCollectionId);165    await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);166    // reFungible167    const reFungibleCollectionId = await168    createCollectionExpectSuccess({mode: {type: 'ReFungible'}});169    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');170    await destroyCollectionExpectSuccess(reFungibleCollectionId);171    await transferExpectFailure(172      reFungibleCollectionId,173      newReFungibleTokenId,174      alice,175      bob,176      1,177    );178  });179  it('Transfer with not existed item_id', async () => {180    // nft181    const nftCollectionId = await createCollectionExpectSuccess();182    await transferExpectFailure(nftCollectionId, 2, alice, bob, 1);183    // fungible184    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});185    await transferExpectFailure(fungibleCollectionId, 2, alice, bob, 1);186    // reFungible187    const reFungibleCollectionId = await188    createCollectionExpectSuccess({mode: {type: 'ReFungible'}});189    await transferExpectFailure(190      reFungibleCollectionId,191      2,192      alice,193      bob,194      1,195    );196  });197  it('Transfer with deleted item_id', async () => {198    // nft199    const nftCollectionId = await createCollectionExpectSuccess();200    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');201    await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId, 1);202    await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);203    // fungible204    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});205    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');206    await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);207    await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);208    // reFungible209    const reFungibleCollectionId = await210    createCollectionExpectSuccess({mode: {type: 'ReFungible'}});211    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');212    await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);213    await transferExpectFailure(214      reFungibleCollectionId,215      newReFungibleTokenId,216      alice,217      bob,218      1,219    );220  });221  it('Transfer with recipient that is not owner', async () => {222    // nft223    const nftCollectionId = await createCollectionExpectSuccess();224    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');225    await transferExpectFailure(nftCollectionId, newNftTokenId, charlie, bob, 1);226    // fungible227    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});228    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');229    await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, charlie, bob, 1);230    // reFungible231    const reFungibleCollectionId = await232    createCollectionExpectSuccess({mode: {type: 'ReFungible'}});233    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');234    await transferExpectFailure(235      reFungibleCollectionId,236      newReFungibleTokenId,237      charlie,238      bob,239      1,240    );241  });242});243244describe('Zero value transfer(From)', () => {245  before(async () => {246    await usingApi(async () => {247      alice = privateKey('//Alice');248      bob = privateKey('//Bob');249    });250  });251252  it('NFT', async () => {253    await usingApi(async (api: ApiPromise) => {254      const nftCollectionId = await createCollectionExpectSuccess();255      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');256257      const transferTx = api.tx.unique.transfer(normalizeAccountId(bob), nftCollectionId, newNftTokenId, 0);258      await submitTransactionAsync(alice, transferTx);259      const address = normalizeAccountId(await getTokenOwner(api, nftCollectionId, newNftTokenId));260261      expect(toSubstrateAddress(address)).to.be.equal(alice.address);262    });263  });264265  it('RFT', async () => {266    await usingApi(async (api: ApiPromise) => {267      const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});268      const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');269      const balanceBeforeAlice = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(alice), newReFungibleTokenId);270      const balanceBeforeBob = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(bob), newReFungibleTokenId);271272      const transferTx = api.tx.unique.transfer(normalizeAccountId(bob), reFungibleCollectionId, newReFungibleTokenId, 0);273      await submitTransactionAsync(alice, transferTx);274275      const balanceAfterAlice = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(alice), newReFungibleTokenId);276      const balanceAfterBob = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(bob), newReFungibleTokenId);277278      expect((balanceBeforeAlice)).to.be.equal(balanceAfterAlice);279      expect((balanceBeforeBob)).to.be.equal(balanceAfterBob);280    });281  });282283  it('Fungible', async () => {284    await usingApi(async (api: ApiPromise) => {285      const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});286      const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');287      const balanceBeforeAlice = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(alice), newFungibleTokenId);288      const balanceBeforeBob = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(bob), newFungibleTokenId);289290      const transferTx = api.tx.unique.transfer(normalizeAccountId(bob), fungibleCollectionId, newFungibleTokenId, 0);291      await submitTransactionAsync(alice, transferTx);292293      const balanceAfterAlice = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(alice), newFungibleTokenId);294      const balanceAfterBob = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(bob), newFungibleTokenId);295296      expect((balanceBeforeAlice)).to.be.equal(balanceAfterAlice);297      expect((balanceBeforeBob)).to.be.equal(balanceAfterBob);298    });299  });300});301302describe.only('Transfers to self (potentially over substrate-evm boundary)', () => {303  itWeb3('Transfers to self. In case of same frontend', async ({api}) => {304    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});305    const alice = privateKey('//Alice');306    const aliceProxy = subToEth(alice.address);307    const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});308    await transferExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, 10, 'ReFungible');309    const balanceAliceBefore = await getTokenBalance(api, collectionId, {Ethereum: aliceProxy}, tokenId);310    await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, {Ethereum: aliceProxy}, 10, 'ReFungible');311    const balanceAliceAfter = await getTokenBalance(api, collectionId, {Ethereum: aliceProxy}, tokenId);312    expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);313  });314315  itWeb3('Transfers to self. In case of substrate-evm boundary', async ({api}) => {316    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});317    const alice = privateKey('//Alice');318    const aliceProxy = subToEth(alice.address);319    const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});320    const balanceAliceBefore = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);321    await transferExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy} , 10, 'ReFungible');322    await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, alice, 10, 'ReFungible');323    const balanceAliceAfter = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);324    expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);325  });326});
after · tests/src/transfer.test.ts
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, 'ReFungible');310    const balanceAliceBefore = await getTokenBalance(api, collectionId, {Ethereum: aliceProxy}, tokenId);311    await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, {Ethereum: aliceProxy}, 10, 'ReFungible');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, 'ReFungible');323    await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, alice, 10, 'ReFungible');324    const balanceAliceAfter = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);325    expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);326  });327328  itWeb3.only('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, 'ReFungible');334    await transferFromExpectSuccess(collectionId, tokenId, alice, alice, alice, 10, 'ReFungible');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});