1234567891011121314151617import {IKeyringPair} from '@polkadot/types/types';18import {itEth, usingEthPlaygrounds} from './eth/util';19import {itSub, Pallets, usingPlaygrounds, expect} from './util';2021describe('Integration Test Transfer(recipient, collection_id, item_id, value)', () => {22 let donor: IKeyringPair;23 let alice: IKeyringPair;24 let bob: IKeyringPair;2526 before(async () => {27 await usingPlaygrounds(async (helper, privateKey) => {28 donor = await privateKey({url: import.meta.url});29 [alice, bob] = await helper.arrange.createAccounts([50n, 10n], donor);30 });31 });3233 itSub('Balance transfers and check balance', async ({helper}) => {34 const alicesBalanceBefore = await helper.balance.getSubstrate(alice.address);35 const bobsBalanceBefore = await helper.balance.getSubstrate(bob.address);3637 expect(await helper.balance.transferToSubstrate(alice, bob.address, 1n)).to.be.true;3839 const alicesBalanceAfter = await helper.balance.getSubstrate(alice.address);40 const bobsBalanceAfter = await helper.balance.getSubstrate(bob.address);4142 expect(alicesBalanceAfter < alicesBalanceBefore).to.be.true;43 expect(bobsBalanceAfter > bobsBalanceBefore).to.be.true;44 });4546 itSub('Inability to pay fees error message is correct', async ({helper}) => {47 const [zero] = await helper.arrange.createAccounts([0n], donor);4849 50 51 await expect(helper.balance.transferToSubstrate(zero, donor.address, 1n))52 .to.be.rejectedWith('Inability to pay some fees , e.g. account balance too low');53 });5455 itSub('[nft] User can transfer owned token', async ({helper}) => {56 const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-1-NFT', description: '', tokenPrefix: 'T'});57 const nft = await collection.mintToken(alice);5859 await nft.transfer(alice, {Substrate: bob.address});60 expect(await nft.getOwner()).to.be.deep.equal({Substrate: bob.address});61 });6263 itSub('[fungible] User can transfer owned token', async ({helper}) => {64 const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-1-FT', description: '', tokenPrefix: 'T'});65 await collection.mint(alice, 10n);6667 await collection.transfer(alice, {Substrate: bob.address}, 9n);68 expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(9n);69 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);70 });7172 itSub.ifWithPallets('[refungible] User can transfer owned token', [Pallets.ReFungible], async ({helper}) => {73 const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-1-RFT', description: '', tokenPrefix: 'T'});74 const rft = await collection.mintToken(alice, 10n);7576 await rft.transfer(alice, {Substrate: bob.address}, 9n);77 expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(9n);78 expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(1n);79 });8081 itSub('[nft] Collection admin can transfer owned token', async ({helper}) => {82 const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-2-NFT', description: '', tokenPrefix: 'T'});83 await collection.addAdmin(alice, {Substrate: bob.address});8485 const nft = await collection.mintToken(bob, {Substrate: bob.address});86 await nft.transfer(bob, {Substrate: alice.address});8788 expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});89 });9091 itSub('[fungible] Collection admin can transfer owned token', async ({helper}) => {92 const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-2-FT', description: '', tokenPrefix: 'T'});93 await collection.addAdmin(alice, {Substrate: bob.address});9495 await collection.mint(bob, 10n, {Substrate: bob.address});96 await collection.transfer(bob, {Substrate: alice.address}, 1n);9798 expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(9n);99 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);100 });101102 itSub.ifWithPallets('[refungible] Collection admin can transfer owned token', [Pallets.ReFungible], async ({helper}) => {103 const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-2-RFT', description: '', tokenPrefix: 'T'});104 await collection.addAdmin(alice, {Substrate: bob.address});105106 const rft = await collection.mintToken(bob, 10n, {Substrate: bob.address});107 await rft.transfer(bob, {Substrate: alice.address}, 1n);108109 expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(9n);110 expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(1n);111 });112});113114describe('Negative Integration Test Transfer(recipient, collection_id, item_id, value)', () => {115 let alice: IKeyringPair;116 let bob: IKeyringPair;117118 before(async () => {119 await usingPlaygrounds(async (helper, privateKey) => {120 const donor = await privateKey({url: import.meta.url});121 [alice, bob] = await helper.arrange.createAccounts([50n, 10n], donor);122 });123 });124125126 itSub('[nft] Transfer with not existed collection_id', async ({helper}) => {127 const collectionId = (1 << 32) - 1;128 await expect(helper.nft.transferToken(alice, collectionId, 1, {Substrate: bob.address}))129 .to.be.rejectedWith(/common\.CollectionNotFound/);130 });131132 itSub('[fungible] Transfer with not existed collection_id', async ({helper}) => {133 const collectionId = (1 << 32) - 1;134 await expect(helper.ft.transfer(alice, collectionId, {Substrate: bob.address}))135 .to.be.rejectedWith(/common\.CollectionNotFound/);136 });137138 itSub.ifWithPallets('[refungible] Transfer with not existed collection_id', [Pallets.ReFungible], async ({helper}) => {139 const collectionId = (1 << 32) - 1;140 await expect(helper.rft.transferToken(alice, collectionId, 1, {Substrate: bob.address}))141 .to.be.rejectedWith(/common\.CollectionNotFound/);142 });143144 itSub('[nft] Transfer with deleted collection_id', async ({helper}) => {145 const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-1-NFT', description: '', tokenPrefix: 'T'});146 const nft = await collection.mintToken(alice);147148 await nft.burn(alice);149 await collection.burn(alice);150151 await expect(nft.transfer(alice, {Substrate: bob.address}))152 .to.be.rejectedWith(/common\.CollectionNotFound/);153 });154155 itSub('[fungible] Transfer with deleted collection_id', async ({helper}) => {156 const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-1-FT', description: '', tokenPrefix: 'T'});157 await collection.mint(alice, 10n);158159 await collection.burnTokens(alice, 10n);160 await collection.burn(alice);161162 await expect(collection.transfer(alice, {Substrate: bob.address}))163 .to.be.rejectedWith(/common\.CollectionNotFound/);164 });165166 itSub.ifWithPallets('[refungible] Transfer with deleted collection_id', [Pallets.ReFungible], async ({helper}) => {167 const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-1-RFT', description: '', tokenPrefix: 'T'});168 const rft = await collection.mintToken(alice, 10n);169170 await rft.burn(alice, 10n);171 await collection.burn(alice);172173 await expect(rft.transfer(alice, {Substrate: bob.address}))174 .to.be.rejectedWith(/common\.CollectionNotFound/);175 });176177 itSub('[nft] Transfer with not existed item_id', async ({helper}) => {178 const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-2-NFT', description: '', tokenPrefix: 'T'});179 await expect(collection.transferToken(alice, 1, {Substrate: bob.address}))180 .to.be.rejectedWith(/common\.TokenNotFound/);181 });182183 itSub('[fungible] Transfer with not existed item_id', async ({helper}) => {184 const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-2-FT', description: '', tokenPrefix: 'T'});185 await expect(collection.transfer(alice, {Substrate: bob.address}))186 .to.be.rejectedWith(/common\.TokenValueTooLow/);187 });188189 itSub.ifWithPallets('[refungible] Transfer with not existed item_id', [Pallets.ReFungible], async ({helper}) => {190 const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-2-RFT', description: '', tokenPrefix: 'T'});191 await expect(collection.transferToken(alice, 1, {Substrate: bob.address}))192 .to.be.rejectedWith(/common\.TokenValueTooLow/);193 });194195 itSub('Zero transfer NFT', async ({helper}) => {196 const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-3-NFT', description: '', tokenPrefix: 'T'});197 const tokenAlice = await collection.mintToken(alice, {Substrate: alice.address});198 const tokenBob = await collection.mintToken(alice, {Substrate: bob.address});199 200 await helper.executeExtrinsic(alice, 'api.tx.unique.transfer', [{Substrate: bob.address}, collection.collectionId, tokenAlice.tokenId, 0]);201 202 await expect(helper.executeExtrinsic(alice, 'api.tx.unique.transfer', [{Substrate: alice.address}, collection.collectionId, tokenBob.tokenId, 0])).to.be.rejectedWith('common.NoPermission');203 204 await expect(helper.executeExtrinsic(alice, 'api.tx.unique.transfer', [{Substrate: alice.address}, collection.collectionId, 10, 0])).to.be.rejectedWith('common.TokenNotFound');205 expect(await tokenAlice.getOwner()).to.deep.eq({Substrate: alice.address});206 expect(await tokenBob.getOwner()).to.deep.eq({Substrate: bob.address});207 208 await tokenAlice.transfer(alice, {Substrate: bob.address});209 await tokenBob.transfer(bob, {Substrate: alice.address});210 expect(await tokenAlice.getOwner()).to.deep.eq({Substrate: bob.address});211 expect(await tokenBob.getOwner()).to.deep.eq({Substrate: alice.address});212 });213214 itSub('[nft] Transfer with deleted item_id', async ({helper}) => {215 const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-3-NFT', description: '', tokenPrefix: 'T'});216 const nft = await collection.mintToken(alice);217218 await nft.burn(alice);219220 await expect(nft.transfer(alice, {Substrate: bob.address}))221 .to.be.rejectedWith(/common\.TokenNotFound/);222 });223224 itSub('[fungible] Transfer with deleted item_id', async ({helper}) => {225 const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-3-FT', description: '', tokenPrefix: 'T'});226 await collection.mint(alice, 10n);227228 await collection.burnTokens(alice, 10n);229230 await expect(collection.transfer(alice, {Substrate: bob.address}))231 .to.be.rejectedWith(/common\.TokenValueTooLow/);232 });233234 itSub.ifWithPallets('[refungible] Transfer with deleted item_id', [Pallets.ReFungible], async ({helper}) => {235 const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-3-RFT', description: '', tokenPrefix: 'T'});236 const rft = await collection.mintToken(alice, 10n);237238 await rft.burn(alice, 10n);239240 await expect(rft.transfer(alice, {Substrate: bob.address}))241 .to.be.rejectedWith(/common\.TokenValueTooLow/);242 });243244 itSub('[nft] Transfer with recipient that is not owner', async ({helper}) => {245 const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-4-NFT', description: '', tokenPrefix: 'T'});246 const nft = await collection.mintToken(alice);247248 await expect(nft.transfer(bob, {Substrate: bob.address}))249 .to.be.rejectedWith(/common\.NoPermission/);250 expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});251 });252253 itSub('[fungible] Transfer with recipient that is not owner', async ({helper}) => {254 const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-4-FT', description: '', tokenPrefix: 'T'});255 await collection.mint(alice, 10n);256257 await expect(collection.transfer(bob, {Substrate: bob.address}, 9n))258 .to.be.rejectedWith(/common\.TokenValueTooLow/);259 expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(0n);260 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(10n);261 });262263 itSub.ifWithPallets('[refungible] Transfer with recipient that is not owner', [Pallets.ReFungible], async ({helper}) => {264 const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-1-RFT', description: '', tokenPrefix: 'T'});265 const rft = await collection.mintToken(alice, 10n);266267 await expect(rft.transfer(bob, {Substrate: bob.address}, 9n))268 .to.be.rejectedWith(/common\.TokenValueTooLow/);269 expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(0n);270 expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(10n);271 });272});273274describe('Transfers to self (potentially over substrate-evm boundary)', () => {275 let donor: IKeyringPair;276277 before(async function() {278 await usingEthPlaygrounds(async (_, privateKey) => {279 donor = await privateKey({url: import.meta.url});280 });281 });282283 itEth('Transfers to self. In case of same frontend', async ({helper}) => {284 const [owner] = await helper.arrange.createAccounts([10n], donor);285 const collection = await helper.ft.mintCollection(owner, {});286 await collection.mint(owner, 100n);287288 const ownerProxy = helper.address.substrateToEth(owner.address);289290 291 await collection.transfer(owner, {Ethereum: ownerProxy}, 10n);292 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);293 expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);294295 296 await collection.transferFrom(owner, {Ethereum: ownerProxy}, {Ethereum: ownerProxy}, 5n);297 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);298 expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);299 });300301 itEth('Transfers to self. In case of substrate-evm boundary', async ({helper}) => {302 const [owner] = await helper.arrange.createAccounts([10n], donor);303 const collection = await helper.ft.mintCollection(owner, {});304 await collection.mint(owner, 100n);305306 const ownerProxy = helper.address.substrateToEth(owner.address);307308 309 await collection.transfer(owner, {Ethereum: ownerProxy}, 10n);310 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);311 expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);312313 314 await collection.transferFrom(owner, {Ethereum: ownerProxy}, {Substrate: owner.address}, 5n);315 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(95n);316 expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(5n);317 });318319 itEth('Transfers to self. In case of inside substrate-evm', async ({helper}) => {320 const [owner] = await helper.arrange.createAccounts([10n], donor);321 const collection = await helper.ft.mintCollection(owner, {});322 await collection.mint(owner, 100n);323324 325 await collection.transfer(owner, {Substrate: owner.address}, 10n);326 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(100n);327328 329 await collection.transferFrom(owner, {Substrate: owner.address}, {Substrate: owner.address}, 5n);330 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(100n);331 });332333 itEth('Transfers to self. In case of inside substrate-evm when not enought "Fungibles"', async ({helper}) => {334 const [owner] = await helper.arrange.createAccounts([10n], donor);335 const collection = await helper.ft.mintCollection(owner, {});336 await collection.mint(owner, 10n);337338 339 await expect(collection.transfer(owner, {Substrate: owner.address}, 11n))340 .to.be.rejectedWith(/common\.TokenValueTooLow/);341342 343 await expect(collection.transferFrom(owner, {Substrate: owner.address}, {Substrate: owner.address}, 12n))344 .to.be.rejectedWith(/common\.TokenValueTooLow/);345 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(10n);346 });347});