1234567891011121314151617import {Pallets, requirePalletsOrSkip} from '../util/playgrounds';18import {expect, itEth, usingEthPlaygrounds} from './util/playgrounds';19import {IKeyringPair} from '@polkadot/types/types';2021describe('Refungible: Information getting', () => {22 let donor: IKeyringPair;2324 before(async function() {25 await usingEthPlaygrounds(async (helper, privateKey) => {26 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);2728 donor = privateKey('//Alice');29 });30 });3132 itEth('totalSupply', async ({helper}) => {33 const caller = await helper.eth.createAccountWithBalance(donor);34 const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'TotalSupply', '6', '6');35 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);3637 await contract.methods.mint(caller).send();3839 const totalSupply = await contract.methods.totalSupply().call();40 expect(totalSupply).to.equal('1');41 });4243 itEth('balanceOf', async ({helper}) => {44 const caller = await helper.eth.createAccountWithBalance(donor);45 const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'BalanceOf', '6', '6');46 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);4748 await contract.methods.mint(caller).send();49 await contract.methods.mint(caller).send();50 await contract.methods.mint(caller).send();5152 const balance = await contract.methods.balanceOf(caller).call();53 expect(balance).to.equal('3');54 });5556 itEth('ownerOf', async ({helper}) => {57 const caller = await helper.eth.createAccountWithBalance(donor);58 const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'OwnerOf', '6', '6');59 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);6061 const result = await contract.methods.mint(caller).send();62 const tokenId = result.events.Transfer.returnValues.tokenId;6364 const owner = await contract.methods.ownerOf(tokenId).call();65 expect(owner).to.equal(caller);66 });6768 itEth('ownerOf after burn', async ({helper}) => {69 const caller = await helper.eth.createAccountWithBalance(donor);70 const receiver = helper.eth.createAccount();71 const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(caller, 'OwnerOf-AfterBurn', '6', '6');72 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);7374 const result = await contract.methods.mint(caller).send();75 const tokenId = result.events.Transfer.returnValues.tokenId;76 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);7778 await tokenContract.methods.repartition(2).send();79 await tokenContract.methods.transfer(receiver, 1).send();8081 await tokenContract.methods.burnFrom(caller, 1).send();8283 const owner = await contract.methods.ownerOf(tokenId).call();84 expect(owner).to.equal(receiver);85 });8687 itEth('ownerOf for partial ownership', async ({helper}) => {88 const caller = await helper.eth.createAccountWithBalance(donor);89 const receiver = helper.eth.createAccount();90 const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(caller, 'Partial-OwnerOf', '6', '6');91 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);9293 const result = await contract.methods.mint(caller).send();94 const tokenId = result.events.Transfer.returnValues.tokenId;95 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);9697 await tokenContract.methods.repartition(2).send();98 await tokenContract.methods.transfer(receiver, 1).send();99100 const owner = await contract.methods.ownerOf(tokenId).call();101 expect(owner).to.equal('0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF');102 });103});104105describe('Refungible: Plain calls', () => {106 let donor: IKeyringPair;107108 before(async function() {109 await usingEthPlaygrounds(async (helper, privateKey) => {110 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);111112 donor = privateKey('//Alice');113 });114 });115116 itEth('Can perform mint()', async ({helper}) => {117 const owner = await helper.eth.createAccountWithBalance(donor);118 const receiver = helper.eth.createAccount();119 const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner, 'Minty', '6', '6', '');120 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);121122 const result = await contract.methods.mintWithTokenURI(receiver, 'Test URI').send();123124 const event = result.events.Transfer;125 expect(event.address).to.equal(collectionAddress);126 expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');127 expect(event.returnValues.to).to.equal(receiver);128 const tokenId = event.returnValues.tokenId;129 expect(tokenId).to.be.equal('1');130131 expect(await contract.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');132 });133134 itEth('Can perform mintBulk()', async ({helper}) => {135 const owner = await helper.eth.createAccountWithBalance(donor);136 const receiver = helper.eth.createAccount();137 const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner, 'MintBulky', '6', '6', '');138 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);139140 {141 const nextTokenId = await contract.methods.nextTokenId().call();142 expect(nextTokenId).to.be.equal('1');143 const result = await contract.methods.mintBulkWithTokenURI(144 receiver,145 [146 [nextTokenId, 'Test URI 0'],147 [+nextTokenId + 1, 'Test URI 1'],148 [+nextTokenId + 2, 'Test URI 2'],149 ],150 ).send();151152 const events = result.events.Transfer;153 for (let i = 0; i < 2; i++) {154 const event = events[i];155 expect(event.address).to.equal(collectionAddress);156 expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');157 expect(event.returnValues.to).to.equal(receiver);158 expect(event.returnValues.tokenId).to.equal(String(+nextTokenId + i));159 }160161 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI 0');162 expect(await contract.methods.tokenURI(+nextTokenId + 1).call()).to.be.equal('Test URI 1');163 expect(await contract.methods.tokenURI(+nextTokenId + 2).call()).to.be.equal('Test URI 2');164 }165 });166167 itEth('Can perform burn()', async ({helper}) => {168 const caller = await helper.eth.createAccountWithBalance(donor);169 const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'Burny', '6', '6');170 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);171172 const result = await contract.methods.mint(caller).send();173 const tokenId = result.events.Transfer.returnValues.tokenId;174 {175 const result = await contract.methods.burn(tokenId).send();176 const event = result.events.Transfer;177 expect(event.address).to.equal(collectionAddress);178 expect(event.returnValues.from).to.equal(caller);179 expect(event.returnValues.to).to.equal('0x0000000000000000000000000000000000000000');180 expect(event.returnValues.tokenId).to.equal(tokenId.toString());181 }182 });183184 itEth('Can perform transferFrom()', async ({helper}) => {185 const caller = await helper.eth.createAccountWithBalance(donor);186 const receiver = helper.eth.createAccount();187 const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(caller, 'TransferFromy', '6', '6');188 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);189190 const result = await contract.methods.mint(caller).send();191 const tokenId = result.events.Transfer.returnValues.tokenId;192193 const tokenAddress = helper.ethAddress.fromTokenId(collectionId, tokenId);194195 const tokenContract = helper.ethNativeContract.rftToken(tokenAddress, caller);196 await tokenContract.methods.repartition(15).send();197198 {199 const tokenEvents: any = [];200 tokenContract.events.allEvents((_: any, event: any) => {201 tokenEvents.push(event);202 });203 const result = await contract.methods.transferFrom(caller, receiver, tokenId).send();204205 let event = result.events.Transfer;206 expect(event.address).to.equal(collectionAddress);207 expect(event.returnValues.from).to.equal(caller);208 expect(event.returnValues.to).to.equal(receiver);209 expect(event.returnValues.tokenId).to.equal(tokenId.toString());210211 event = tokenEvents[0];212 expect(event.address).to.equal(tokenAddress);213 expect(event.returnValues.from).to.equal(caller);214 expect(event.returnValues.to).to.equal(receiver);215 expect(event.returnValues.value).to.equal('15');216 }217218 {219 const balance = await contract.methods.balanceOf(receiver).call();220 expect(+balance).to.equal(1);221 }222223 {224 const balance = await contract.methods.balanceOf(caller).call();225 expect(+balance).to.equal(0);226 }227 });228229 itEth('Can perform transfer()', async ({helper}) => {230 const caller = await helper.eth.createAccountWithBalance(donor);231 const receiver = helper.eth.createAccount();232 const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'Transferry', '6', '6');233 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);234235 const result = await contract.methods.mint(caller).send();236 const tokenId = result.events.Transfer.returnValues.tokenId;237238 {239 const result = await contract.methods.transfer(receiver, tokenId).send();240241 const event = result.events.Transfer;242 expect(event.address).to.equal(collectionAddress);243 expect(event.returnValues.from).to.equal(caller);244 expect(event.returnValues.to).to.equal(receiver);245 expect(event.returnValues.tokenId).to.equal(tokenId.toString());246 }247248 {249 const balance = await contract.methods.balanceOf(caller).call();250 expect(+balance).to.equal(0);251 }252253 {254 const balance = await contract.methods.balanceOf(receiver).call();255 expect(+balance).to.equal(1);256 }257 });258259 itEth('transfer event on transfer from partial ownership to full ownership', async ({helper}) => {260 const caller = await helper.eth.createAccountWithBalance(donor);261 const receiver = helper.eth.createAccount();262 const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(caller, 'Transferry-Partial-to-Full', '6', '6');263 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);264265 const result = await contract.methods.mint(caller).send();266 const tokenId = result.events.Transfer.returnValues.tokenId;267268 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);269270 await tokenContract.methods.repartition(2).send();271 await tokenContract.methods.transfer(receiver, 1).send();272273 const events: any = [];274 contract.events.allEvents((_: any, event: any) => {275 events.push(event);276 });277 await tokenContract.methods.transfer(receiver, 1).send();278279 const event = events[0];280 expect(event.address).to.equal(collectionAddress);281 expect(event.returnValues.from).to.equal('0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF');282 expect(event.returnValues.to).to.equal(receiver);283 expect(event.returnValues.tokenId).to.equal(tokenId.toString());284 });285286 itEth('transfer event on transfer from full ownership to partial ownership', async ({helper}) => {287 const caller = await helper.eth.createAccountWithBalance(donor);288 const receiver = helper.eth.createAccount();289 const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(caller, 'Transferry-Full-to-Partial', '6', '6');290 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);291292 const result = await contract.methods.mint(caller).send();293 const tokenId = result.events.Transfer.returnValues.tokenId;294295 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);296297 await tokenContract.methods.repartition(2).send();298299 const events: any = [];300 contract.events.allEvents((_: any, event: any) => {301 events.push(event);302 });303 await tokenContract.methods.transfer(receiver, 1).send();304305 const event = events[0];306 expect(event.address).to.equal(collectionAddress);307 expect(event.returnValues.from).to.equal(caller);308 expect(event.returnValues.to).to.equal('0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF');309 expect(event.returnValues.tokenId).to.equal(tokenId.toString());310 });311});312313describe('RFT: Fees', () => {314 let donor: IKeyringPair;315316 before(async function() {317 await usingEthPlaygrounds(async (helper, privateKey) => {318 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);319320 donor = privateKey('//Alice');321 });322 });323324 itEth('transferFrom() call fee is less than 0.2UNQ', async ({helper}) => {325 const caller = await helper.eth.createAccountWithBalance(donor);326 const receiver = helper.eth.createAccount();327 const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'Feeful-Transfer-From', '6', '6');328 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);329330 const result = await contract.methods.mint(caller).send();331 const tokenId = result.events.Transfer.returnValues.tokenId;332333 const cost = await helper.eth.recordCallFee(caller, () => contract.methods.transferFrom(caller, receiver, tokenId).send());334 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));335 expect(cost > 0n);336 });337338 itEth('transfer() call fee is less than 0.2UNQ', async ({helper}) => {339 const caller = await helper.eth.createAccountWithBalance(donor);340 const receiver = helper.eth.createAccount();341 const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'Feeful-Transfer', '6', '6');342 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);343344 const result = await contract.methods.mint(caller).send();345 const tokenId = result.events.Transfer.returnValues.tokenId;346347 const cost = await helper.eth.recordCallFee(caller, () => contract.methods.transfer(receiver, tokenId).send());348 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));349 expect(cost > 0n);350 });351});352353describe('Common metadata', () => {354 let donor: IKeyringPair;355 let alice: IKeyringPair;356357 before(async function() {358 await usingEthPlaygrounds(async (helper, privateKey) => {359 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);360361 donor = privateKey('//Alice');362 [alice] = await helper.arrange.createAccounts([20n], donor);363 });364 });365366 itEth('Returns collection name', async ({helper}) => {367 const caller = helper.eth.createAccount();368 const tokenPropertyPermissions = [{369 key: 'URI',370 permission: {371 mutable: true,372 collectionAdmin: true,373 tokenOwner: false,374 },375 }];376 const collection = await helper.rft.mintCollection(377 alice,378 {379 name: 'Leviathan',380 tokenPrefix: '11',381 properties: [{key: 'ERC721Metadata', value: '1'}],382 tokenPropertyPermissions,383 },384 );385386 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'rft', caller);387 const name = await contract.methods.name().call();388 expect(name).to.equal('Leviathan');389 });390391 itEth('Returns symbol name', async ({helper}) => {392 const caller = await helper.eth.createAccountWithBalance(donor);393 const tokenPropertyPermissions = [{394 key: 'URI',395 permission: {396 mutable: true,397 collectionAdmin: true,398 tokenOwner: false,399 },400 }];401 const {collectionId} = await helper.rft.mintCollection(402 alice,403 {404 name: 'Leviathan',405 tokenPrefix: '12',406 properties: [{key: 'ERC721Metadata', value: '1'}],407 tokenPropertyPermissions,408 },409 );410411 const contract = helper.ethNativeContract.collectionById(collectionId, 'rft', caller);412 const symbol = await contract.methods.symbol().call();413 expect(symbol).to.equal('12');414 });415});