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({filename: __filename});29 [alice, bob] = await helper.arrange.createAccounts([50n, 10n], donor);30 });31 });32 33 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({filename: __filename});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 });165 166 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 api = helper.getApi();197 const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-3-NFT', description: '', tokenPrefix: 'T'});198 const tokenAlice = await collection.mintToken(alice, {Substrate: alice.address});199 const tokenBob = await collection.mintToken(alice, {Substrate: bob.address});200 201 await helper.signTransaction(alice, api.tx.unique.transfer({Substrate: bob.address}, collection.collectionId, tokenAlice.tokenId, 0));202 203 await expect(helper.signTransaction(alice, api.tx.unique.transfer({Substrate: alice.address}, collection.collectionId, tokenBob.tokenId, 0))).to.be.rejectedWith('common.NoPermission');204 205 await expect(helper.signTransaction(alice, api.tx.unique.transfer({Substrate: alice.address}, collection.collectionId, 10, 0))).to.be.rejectedWith('common.TokenNotFound');206 expect(await tokenAlice.getOwner()).to.deep.eq({Substrate: alice.address});207 expect(await tokenBob.getOwner()).to.deep.eq({Substrate: bob.address});208 209 await tokenAlice.transfer(alice, {Substrate: bob.address});210 await tokenBob.transfer(alice, {Substrate: alice.address});211 expect(await tokenAlice.getOwner()).to.deep.eq({Substrate: bob.address});212 expect(await tokenBob.getOwner()).to.deep.eq({Substrate: alice.address});213 });214215 itSub('[nft] Transfer with deleted item_id', async ({helper}) => {216 const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-3-NFT', description: '', tokenPrefix: 'T'});217 const nft = await collection.mintToken(alice);218219 await nft.burn(alice);220221 await expect(nft.transfer(alice, {Substrate: bob.address}))222 .to.be.rejectedWith(/common\.TokenNotFound/);223 });224225 itSub('[fungible] Transfer with deleted item_id', async ({helper}) => {226 const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-3-FT', description: '', tokenPrefix: 'T'});227 await collection.mint(alice, 10n);228229 await collection.burnTokens(alice, 10n);230231 await expect(collection.transfer(alice, {Substrate: bob.address}))232 .to.be.rejectedWith(/common\.TokenValueTooLow/);233 });234235 itSub.ifWithPallets('[refungible] Transfer with deleted item_id', [Pallets.ReFungible], async ({helper}) => {236 const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-3-RFT', description: '', tokenPrefix: 'T'});237 const rft = await collection.mintToken(alice, 10n);238239 await rft.burn(alice, 10n);240241 await expect(rft.transfer(alice, {Substrate: bob.address}))242 .to.be.rejectedWith(/common\.TokenValueTooLow/);243 });244245 itSub('[nft] Transfer with recipient that is not owner', async ({helper}) => {246 const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-4-NFT', description: '', tokenPrefix: 'T'});247 const nft = await collection.mintToken(alice);248249 await expect(nft.transfer(bob, {Substrate: bob.address}))250 .to.be.rejectedWith(/common\.NoPermission/);251 expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});252 });253254 itSub('[fungible] Transfer with recipient that is not owner', async ({helper}) => {255 const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-4-FT', description: '', tokenPrefix: 'T'});256 await collection.mint(alice, 10n);257258 await expect(collection.transfer(bob, {Substrate: bob.address}, 9n))259 .to.be.rejectedWith(/common\.TokenValueTooLow/);260 expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(0n);261 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(10n);262 });263264 itSub.ifWithPallets('[refungible] Transfer with recipient that is not owner', [Pallets.ReFungible], async ({helper}) => {265 const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-1-RFT', description: '', tokenPrefix: 'T'});266 const rft = await collection.mintToken(alice, 10n);267268 await expect(rft.transfer(bob, {Substrate: bob.address}, 9n))269 .to.be.rejectedWith(/common\.TokenValueTooLow/);270 expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(0n);271 expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(10n);272 });273});274275describe('Transfers to self (potentially over substrate-evm boundary)', () => {276 let donor: IKeyringPair;277278 before(async function() {279 await usingEthPlaygrounds(async (_, privateKey) => {280 donor = await privateKey({filename: __filename});281 });282 });283 284 itEth('Transfers to self. In case of same frontend', async ({helper}) => {285 const [owner] = await helper.arrange.createAccounts([10n], donor);286 const collection = await helper.ft.mintCollection(owner, {});287 await collection.mint(owner, 100n);288289 const ownerProxy = helper.address.substrateToEth(owner.address);290291 292 await collection.transfer(owner, {Ethereum: ownerProxy}, 10n);293 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);294 expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);295296 297 await collection.transferFrom(owner, {Ethereum: ownerProxy}, {Ethereum: ownerProxy}, 5n);298 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);299 expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);300 });301302 itEth('Transfers to self. In case of substrate-evm boundary', async ({helper}) => {303 const [owner] = await helper.arrange.createAccounts([10n], donor);304 const collection = await helper.ft.mintCollection(owner, {});305 await collection.mint(owner, 100n);306307 const ownerProxy = helper.address.substrateToEth(owner.address);308309 310 await collection.transfer(owner, {Ethereum: ownerProxy}, 10n);311 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);312 expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);313314 315 await collection.transferFrom(owner, {Ethereum: ownerProxy}, {Substrate: owner.address}, 5n);316 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(95n);317 expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(5n);318 });319320 itEth('Transfers to self. In case of inside substrate-evm', async ({helper}) => {321 const [owner] = await helper.arrange.createAccounts([10n], donor);322 const collection = await helper.ft.mintCollection(owner, {});323 await collection.mint(owner, 100n);324325 326 await collection.transfer(owner, {Substrate: owner.address}, 10n);327 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(100n);328329 330 await collection.transferFrom(owner, {Substrate: owner.address}, {Substrate: owner.address}, 5n);331 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(100n);332 });333334 itEth('Transfers to self. In case of inside substrate-evm when not enought "Fungibles"', async ({helper}) => {335 const [owner] = await helper.arrange.createAccounts([10n], donor);336 const collection = await helper.ft.mintCollection(owner, {});337 await collection.mint(owner, 10n);338339 340 await expect(collection.transfer(owner, {Substrate: owner.address}, 11n))341 .to.be.rejectedWith(/common\.TokenValueTooLow/);342343 344 await expect(collection.transferFrom(owner, {Substrate: owner.address}, {Substrate: owner.address}, 12n))345 .to.be.rejectedWith(/common\.TokenValueTooLow/);346 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(10n);347 });348});