difftreelog
Merge pull request #612 from UniqueNetwork/tests/eth-tokens
in: master
Tests (Eth): NFT, RFT & FT tests refactored for Playgrounds
6 files changed
tests/package.jsondiffbeforeafterboth87 "testLimits": "mocha --timeout 9999999 -r ts-node/register ./**/limits.test.ts",87 "testLimits": "mocha --timeout 9999999 -r ts-node/register ./**/limits.test.ts",88 "testEthCreateNFTCollection": "mocha --timeout 9999999 -r ts-node/register ./**/eth/createNFTCollection.test.ts",88 "testEthCreateNFTCollection": "mocha --timeout 9999999 -r ts-node/register ./**/eth/createNFTCollection.test.ts",89 "testEthCreateRFTCollection": "mocha --timeout 9999999 -r ts-node/register ./**/eth/createRFTCollection.test.ts",89 "testEthCreateRFTCollection": "mocha --timeout 9999999 -r ts-node/register ./**/eth/createRFTCollection.test.ts",90 "testEthNFT": "mocha --timeout 9999999 -r ts-node/register ./**/eth/nonFungible.test.ts",90 "testRFT": "mocha --timeout 9999999 -r ts-node/register ./**/refungible.test.ts",91 "testRFT": "mocha --timeout 9999999 -r ts-node/register ./**/refungible.test.ts",92 "testEthRFT": "mocha --timeout 9999999 -r ts-node/register ./**/eth/reFungible.test.ts ./**/eth/reFungibleToken.test.ts",91 "testFT": "mocha --timeout 9999999 -r ts-node/register ./**/fungible.test.ts",93 "testFT": "mocha --timeout 9999999 -r ts-node/register ./**/fungible.test.ts",94 "testEthFT": "mocha --timeout 9999999 -r ts-node/register ./**/eth/fungible.test.ts",92 "testRPC": "mocha --timeout 9999999 -r ts-node/register ./**/rpc.test.ts",95 "testRPC": "mocha --timeout 9999999 -r ts-node/register ./**/rpc.test.ts",93 "testPromotion": "mocha --timeout 9999999 -r ts-node/register ./**/app-promotion.test.ts",96 "testPromotion": "mocha --timeout 9999999 -r ts-node/register ./**/app-promotion.test.ts",94 "polkadot-types-fetch-metadata": "curl -H 'Content-Type: application/json' -d '{\"id\":\"1\", \"jsonrpc\":\"2.0\", \"method\": \"state_getMetadata\", \"params\":[]}' http://localhost:9933 > src/interfaces/metadata.json",97 "polkadot-types-fetch-metadata": "curl -H 'Content-Type: application/json' -d '{\"id\":\"1\", \"jsonrpc\":\"2.0\", \"method\": \"state_getMetadata\", \"params\":[]}' http://localhost:9933 > src/interfaces/metadata.json",tests/src/eth/fungible.test.tsdiffbeforeafterboth14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.161617import {approveExpectSuccess, createCollection, createCollectionExpectSuccess, createFungibleItemExpectSuccess, transferExpectSuccess, transferFromExpectSuccess, UNIQUE} from '../util/helpers';17import {expect, itEth, usingEthPlaygrounds} from './util/playgrounds';18import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, evmCollection, GAS_ARGS, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, transferBalanceToEth} from './util/helpers';18import {IKeyringPair} from '@polkadot/types/types';19import fungibleAbi from './fungibleAbi.json';20import {expect} from 'chai';21import {submitTransactionAsync} from '../substrate/substrate-api';221923describe('Fungible: Information getting', () => {20describe('Fungible: Information getting', () => {24 itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {21 let donor: IKeyringPair;22 let alice: IKeyringPair;2325 const collection = await createCollectionExpectSuccess({24 before(async function() {25 await usingEthPlaygrounds(async (helper, privateKey) => {26 name: 'token name',26 donor = privateKey('//Alice');27 mode: {type: 'Fungible', decimalPoints: 0},27 [alice] = await helper.arrange.createAccounts([20n], donor);28 });28 });29 const alice = privateKeyWrapper('//Alice');29 });303031 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);31 itEth('totalSupply', async ({helper}) => {32 const caller = await helper.eth.createAccountWithBalance(donor);33 const collection = await helper.ft.mintCollection(alice);34 await collection.mint(alice, 200n);323533 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Substrate: alice.address});36 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'ft', caller);3435 const address = collectionIdToAddress(collection);36 const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS});37 const totalSupply = await contract.methods.totalSupply().call();37 const totalSupply = await contract.methods.totalSupply().call();3839 expect(totalSupply).to.equal('200');38 expect(totalSupply).to.equal('200');40 });39 });414042 itWeb3('balanceOf', async ({api, web3, privateKeyWrapper}) => {41 itEth('balanceOf', async ({helper}) => {43 const collection = await createCollectionExpectSuccess({42 const caller = await helper.eth.createAccountWithBalance(donor);44 name: 'token name',43 const collection = await helper.ft.mintCollection(alice);45 mode: {type: 'Fungible', decimalPoints: 0},44 await collection.mint(alice, 200n, {Ethereum: caller});46 });47 const alice = privateKeyWrapper('//Alice');484549 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);46 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'ft', caller);5051 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: caller});5253 const address = collectionIdToAddress(collection);54 const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS});55 const balance = await contract.methods.balanceOf(caller).call();47 const balance = await contract.methods.balanceOf(caller).call();5657 expect(balance).to.equal('200');48 expect(balance).to.equal('200');58 });49 });59});50});605161describe('Fungible: Plain calls', () => {52describe('Fungible: Plain calls', () => {62 itWeb3('Can perform mint()', async ({web3, api, privateKeyWrapper}) => {53 let donor: IKeyringPair;54 let alice: IKeyringPair;5556 before(async function() {57 await usingEthPlaygrounds(async (helper, privateKey) => {63 const alice = privateKeyWrapper('//Alice');58 donor = privateKey('//Alice');64 const collection = await createCollection(api, alice, {59 [alice] = await helper.arrange.createAccounts([20n], donor);65 name: 'token name',66 mode: {type: 'Fungible', decimalPoints: 0},67 });60 });61 });686269 const receiver = createEthAccount(web3);63 itEth('Can perform mint()', async ({helper}) => {64 const owner = await helper.eth.createAccountWithBalance(donor);65 const receiver = helper.eth.createAccount();66 const collection = await helper.ft.mintCollection(alice);67 await collection.addAdmin(alice, {Ethereum: owner});706871 const collectionIdAddress = collectionIdToAddress(collection.collectionId);69 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);72 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);70 const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);73 const changeAdminTx = api.tx.unique.addCollectionAdmin(collection.collectionId, {Ethereum: owner});74 await submitTransactionAsync(alice, changeAdminTx);757176 const collectionContract = evmCollection(web3, owner, collectionIdAddress, {type: 'Fungible', decimalPoints: 0});72 const result = await contract.methods.mint(receiver, 100).send();77 const result = await collectionContract.methods.mint(receiver, 100).send();78 const events = normalizeEvents(result.events);79 73 80 expect(events).to.be.deep.equal([74 const event = result.events.Transfer;81 {82 address: collectionIdAddress,75 expect(event.address).to.equal(collectionAddress);83 event: 'Transfer',76 expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');84 args: {85 from: '0x0000000000000000000000000000000000000000',86 to: receiver,77 expect(event.returnValues.to).to.equal(receiver);87 value: '100',78 expect(event.returnValues.value).to.equal('100');88 },89 },90 ]);91 });79 });928093 itWeb3('Can perform mintBulk()', async ({web3, api, privateKeyWrapper}) => {81 itEth('Can perform mintBulk()', async ({helper}) => {94 const alice = privateKeyWrapper('//Alice');82 const owner = await helper.eth.createAccountWithBalance(donor);95 const collection = await createCollection(api, alice, {83 const bulkSize = 3;96 name: 'token name',84 const receivers = [...new Array(bulkSize)].map(() => helper.eth.createAccount());97 mode: {type: 'Fungible', decimalPoints: 0},85 const collection = await helper.ft.mintCollection(alice);98 });86 await collection.addAdmin(alice, {Ethereum: owner});9987100 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);88 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);101 const receiver1 = createEthAccount(web3);89 const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);102 const receiver2 = createEthAccount(web3);103 const receiver3 = createEthAccount(web3);10490105 const collectionIdAddress = collectionIdToAddress(collection.collectionId);91 const result = await contract.methods.mintBulk(Array.from({length: bulkSize}, (_, i) => (106 const changeAdminTx = api.tx.unique.addCollectionAdmin(collection.collectionId, {Ethereum: owner});107 await submitTransactionAsync(alice, changeAdminTx);108109 const collectionContract = evmCollection(web3, owner, collectionIdAddress, {type: 'Fungible', decimalPoints: 0});110 const result = await collectionContract.methods.mintBulk([111 [receiver1, 10],92 [receivers[i], (i + 1) * 10]112 [receiver2, 20],113 [receiver3, 30],114 ]).send();93 ))).send();115 const events = normalizeEvents(result.events);94 const events = result.events.Transfer.sort((a: any, b: any) => +a.returnValues.value - b.returnValues.value);116117 expect(events).to.be.deep.contain({118 address:collectionIdAddress,119 event: 'Transfer',120 args: {121 from: '0x0000000000000000000000000000000000000000',122 to: receiver1,95 for (let i = 0; i < bulkSize; i++) {123 value: '10',124 },96 const event = events[i];125 });126 97 expect(event.address).to.equal(collectionAddress);127 expect(events).to.be.deep.contain({128 address:collectionIdAddress,98 expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');129 event: 'Transfer',130 args: {131 from: '0x0000000000000000000000000000000000000000',132 to: receiver2,133 value: '20',134 },135 });136 99 expect(event.returnValues.to).to.equal(receivers[i]);137 expect(events).to.be.deep.contain({138 address:collectionIdAddress,100 expect(event.returnValues.value).to.equal(String(10 * (i + 1)));139 event: 'Transfer',140 args: {141 from: '0x0000000000000000000000000000000000000000',142 to: receiver3,143 value: '30',144 },101 }145 });146 });102 });147103148 itWeb3('Can perform burn()', async ({web3, api, privateKeyWrapper}) => {104 itEth('Can perform burn()', async ({helper}) => {149 const alice = privateKeyWrapper('//Alice');105 const owner = await helper.eth.createAccountWithBalance(donor);150 const collection = await createCollection(api, alice, {106 const receiver = await helper.eth.createAccountWithBalance(donor);151 name: 'token name',107 const collection = await helper.ft.mintCollection(alice);152 mode: {type: 'Fungible', decimalPoints: 0},108 await collection.addAdmin(alice, {Ethereum: owner});153 });154109155 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);110 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);156 const changeAdminTx = api.tx.unique.addCollectionAdmin(collection.collectionId, {Ethereum: owner});111 const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);157 await submitTransactionAsync(alice, changeAdminTx);112 await contract.methods.mint(receiver, 100).send();158 const receiver = await createEthAccountWithBalance(api, web3, privateKeyWrapper);159113160 const collectionIdAddress = collectionIdToAddress(collection.collectionId);114 const result = await contract.methods.burnFrom(receiver, 49).send({from: receiver});161 const collectionContract = evmCollection(web3, owner, collectionIdAddress, {type: 'Fungible', decimalPoints: 0});162 await collectionContract.methods.mint(receiver, 100).send();163164 const result = await collectionContract.methods.burnFrom(receiver, 49).send({from: receiver});165 115 166 const events = normalizeEvents(result.events);116 const event = result.events.Transfer;117 expect(event.address).to.equal(collectionAddress);118 expect(event.returnValues.from).to.equal(receiver);119 expect(event.returnValues.to).to.equal('0x0000000000000000000000000000000000000000');120 expect(event.returnValues.value).to.equal('49');167121168 expect(events).to.be.deep.equal([122 const balance = await contract.methods.balanceOf(receiver).call();169 {170 address: collectionIdAddress,171 event: 'Transfer',172 args: {173 from: receiver,174 to: '0x0000000000000000000000000000000000000000',175 value: '49',176 },177 },178 ]);179180 const balance = await collectionContract.methods.balanceOf(receiver).call();181 expect(balance).to.equal('51');123 expect(balance).to.equal('51');182 });124 });183125184 itWeb3('Can perform approve()', async ({web3, api, privateKeyWrapper}) => {126 itEth('Can perform approve()', async ({helper}) => {185 const collection = await createCollectionExpectSuccess({127 const owner = await helper.eth.createAccountWithBalance(donor);186 name: 'token name',128 const spender = helper.eth.createAccount();187 mode: {type: 'Fungible', decimalPoints: 0},129 const collection = await helper.ft.mintCollection(alice);188 });189 const alice = privateKeyWrapper('//Alice');130 await collection.mint(alice, 200n, {Ethereum: owner});190131191 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);132 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);133 const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);192134193 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});194195 const spender = createEthAccount(web3);196197 const address = collectionIdToAddress(collection);198 const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: owner, ...GAS_ARGS});199200 {135 {201 const result = await contract.methods.approve(spender, 100).send({from: owner});136 const result = await contract.methods.approve(spender, 100).send({from: owner});202 const events = normalizeEvents(result.events);203137204 expect(events).to.be.deep.equal([138 const event = result.events.Approval;205 {206 address,139 expect(event.address).to.be.equal(collectionAddress);207 event: 'Approval',140 expect(event.returnValues.owner).to.be.equal(owner);208 args: {209 owner,210 spender,141 expect(event.returnValues.spender).to.be.equal(spender);211 value: '100',142 expect(event.returnValues.value).to.be.equal('100');212 },213 },214 ]);215 }143 }216144217 {145 {220 }148 }221 });149 });222150223 itWeb3('Can perform transferFrom()', async ({web3, api, privateKeyWrapper}) => {151 itEth('Can perform transferFrom()', async ({helper}) => {224 const collection = await createCollectionExpectSuccess({152 const owner = await helper.eth.createAccountWithBalance(donor);225 name: 'token name',153 const spender = await helper.eth.createAccountWithBalance(donor);226 mode: {type: 'Fungible', decimalPoints: 0},154 const receiver = helper.eth.createAccount();227 });155 const collection = await helper.ft.mintCollection(alice);228 const alice = privateKeyWrapper('//Alice');156 await collection.mint(alice, 200n, {Ethereum: owner});229157230 const owner = createEthAccount(web3);158 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);231 await transferBalanceToEth(api, alice, owner);159 const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);232160233 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});234235 const spender = createEthAccount(web3);236 await transferBalanceToEth(api, alice, spender);237238 const receiver = createEthAccount(web3);239240 const address = collectionIdToAddress(collection);241 const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: owner, ...GAS_ARGS});242243 await contract.methods.approve(spender, 100).send();161 await contract.methods.approve(spender, 100).send();244162245 {163 {246 const result = await contract.methods.transferFrom(owner, receiver, 49).send({from: spender});164 const result = await contract.methods.transferFrom(owner, receiver, 49).send({from: spender});247 const events = normalizeEvents(result.events);165 166 let event = result.events.Transfer;248 expect(events).to.be.deep.equal([167 expect(event.address).to.be.equal(collectionAddress);249 {168 expect(event.returnValues.from).to.be.equal(owner);250 address,251 event: 'Transfer',252 args: {253 from: owner,254 to: receiver,169 expect(event.returnValues.to).to.be.equal(receiver);255 value: '49',170 expect(event.returnValues.value).to.be.equal('49');256 },171257 },172 event = result.events.Approval;258 {173 expect(event.address).to.be.equal(collectionAddress);259 address,260 event: 'Approval',174 expect(event.returnValues.owner).to.be.equal(owner);261 args: {262 owner,263 spender,175 expect(event.returnValues.spender).to.be.equal(spender);264 value: '51',176 expect(event.returnValues.value).to.be.equal('51');265 },266 },267 ]);268 }177 }269178270 {179 {278 }187 }279 });188 });280189281 itWeb3('Can perform transfer()', async ({web3, api, privateKeyWrapper}) => {190 itEth('Can perform transfer()', async ({helper}) => {282 const collection = await createCollectionExpectSuccess({191 const owner = await helper.eth.createAccountWithBalance(donor);283 name: 'token name',192 const receiver = await helper.eth.createAccountWithBalance(donor);284 mode: {type: 'Fungible', decimalPoints: 0},193 const collection = await helper.ft.mintCollection(alice);285 });286 const alice = privateKeyWrapper('//Alice');194 await collection.mint(alice, 200n, {Ethereum: owner});287195288 const owner = createEthAccount(web3);196 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);289 await transferBalanceToEth(api, alice, owner);197 const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);290198291 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});292293 const receiver = createEthAccount(web3);294 await transferBalanceToEth(api, alice, receiver);295296 const address = collectionIdToAddress(collection);297 const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: owner, ...GAS_ARGS});298299 {199 {300 const result = await contract.methods.transfer(receiver, 50).send({from: owner});200 const result = await contract.methods.transfer(receiver, 50).send({from: owner});301 const events = normalizeEvents(result.events);201 202 const event = result.events.Transfer;302 expect(events).to.be.deep.equal([203 expect(event.address).to.be.equal(collectionAddress);303 {204 expect(event.returnValues.from).to.be.equal(owner);304 address,305 event: 'Transfer',306 args: {307 from: owner,308 to: receiver,205 expect(event.returnValues.to).to.be.equal(receiver);309 value: '50',206 expect(event.returnValues.value).to.be.equal('50');310 },311 },312 ]);313 }207 }314208315 {209 {325});219});326220327describe('Fungible: Fees', () => {221describe('Fungible: Fees', () => {328 itWeb3('approve() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {222 let donor: IKeyringPair;223 let alice: IKeyringPair;224225 before(async function() {226 await usingEthPlaygrounds(async (helper, privateKey) => {329 const collection = await createCollectionExpectSuccess({227 donor = privateKey('//Alice');330 mode: {type: 'Fungible', decimalPoints: 0},228 [alice] = await helper.arrange.createAccounts([20n], donor);331 });229 });332 const alice = privateKeyWrapper('//Alice');230 });231 232 itEth('approve() call fee is less than 0.2UNQ', async ({helper}) => {233 const owner = await helper.eth.createAccountWithBalance(donor);234 const spender = helper.eth.createAccount();235 const collection = await helper.ft.mintCollection(alice);236 await collection.mint(alice, 200n, {Ethereum: owner});333237334 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);238 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);335 const spender = createEthAccount(web3);239 const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);336240337 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});241 const cost = await helper.eth.recordCallFee(owner, () => contract.methods.approve(spender, 100).send({from: owner}));338339 const address = collectionIdToAddress(collection);340 const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: owner, ...GAS_ARGS});341342 const cost = await recordEthFee(api, owner, () => contract.methods.approve(spender, 100).send({from: owner}));343 expect(cost < BigInt(0.2 * Number(UNIQUE)));242 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));344 });243 });345244346 itWeb3('transferFrom() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {245 itEth('transferFrom() call fee is less than 0.2UNQ', async ({helper}) => {347 const collection = await createCollectionExpectSuccess({246 const owner = await helper.eth.createAccountWithBalance(donor);348 mode: {type: 'Fungible', decimalPoints: 0},247 const spender = await helper.eth.createAccountWithBalance(donor);349 });248 const collection = await helper.ft.mintCollection(alice);350 const alice = privateKeyWrapper('//Alice');249 await collection.mint(alice, 200n, {Ethereum: owner});351250352 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);251 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);353 const spender = await createEthAccountWithBalance(api, web3, privateKeyWrapper);252 const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);354253355 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});356357 const address = collectionIdToAddress(collection);358 const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: owner, ...GAS_ARGS});359360 await contract.methods.approve(spender, 100).send({from: owner});254 await contract.methods.approve(spender, 100).send({from: owner});361255362 const cost = await recordEthFee(api, spender, () => contract.methods.transferFrom(owner, spender, 100).send({from: spender}));256 const cost = await helper.eth.recordCallFee(spender, () => contract.methods.transferFrom(owner, spender, 100).send({from: spender}));363 expect(cost < BigInt(0.2 * Number(UNIQUE)));257 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));364 });258 });365259366 itWeb3('transfer() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {260 itEth('transfer() call fee is less than 0.2UNQ', async ({helper}) => {367 const collection = await createCollectionExpectSuccess({261 const owner = await helper.eth.createAccountWithBalance(donor);368 mode: {type: 'Fungible', decimalPoints: 0},262 const receiver = helper.eth.createAccount();369 });263 const collection = await helper.ft.mintCollection(alice);370 const alice = privateKeyWrapper('//Alice');264 await collection.mint(alice, 200n, {Ethereum: owner});371265372 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);266 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);373 const receiver = createEthAccount(web3);267 const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);374268375 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});269 const cost = await helper.eth.recordCallFee(owner, () => contract.methods.transfer(receiver, 100).send({from: owner}));376377 const address = collectionIdToAddress(collection);378 const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: owner, ...GAS_ARGS});379380 const cost = await recordEthFee(api, owner, () => contract.methods.transfer(receiver, 100).send({from: owner}));381 expect(cost < BigInt(0.2 * Number(UNIQUE)));270 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));382 });271 });383});272});384273385describe('Fungible: Substrate calls', () => {274describe('Fungible: Substrate calls', () => {386 itWeb3('Events emitted for approve()', async ({web3, privateKeyWrapper}) => {275 let donor: IKeyringPair;276 let alice: IKeyringPair;277278 before(async function() {279 await usingEthPlaygrounds(async (helper, privateKey) => {387 const collection = await createCollectionExpectSuccess({280 donor = privateKey('//Alice');388 mode: {type: 'Fungible', decimalPoints: 0},281 [alice] = await helper.arrange.createAccounts([20n], donor);389 });282 });390 const alice = privateKeyWrapper('//Alice');283 });391284392 const receiver = createEthAccount(web3);285 itEth('Events emitted for approve()', async ({helper}) => {286 const receiver = helper.eth.createAccount();287 const collection = await helper.ft.mintCollection(alice);288 await collection.mint(alice, 200n);393289394 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n});290 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);291 const contract = helper.ethNativeContract.collection(collectionAddress, 'ft');395292396 const address = collectionIdToAddress(collection);293 const events: any = [];397 const contract = new web3.eth.Contract(fungibleAbi as any, address);294 contract.events.allEvents((_: any, event: any) => {398399 const events = await recordEvents(contract, async () => {400 await approveExpectSuccess(collection, 0, alice, {Ethereum: receiver}, 100);295 events.push(event);401 });296 });297 await collection.approveTokens(alice, {Ethereum: receiver}, 100n);402298403 expect(events).to.be.deep.equal([299 const event = events[0];404 {405 address,406 event: 'Approval',300 expect(event.event).to.be.equal('Approval');407 args: {301 expect(event.address).to.be.equal(collectionAddress);408 owner: subToEth(alice.address),302 expect(event.returnValues.owner).to.be.equal(helper.address.substrateToEth(alice.address));409 spender: receiver,303 expect(event.returnValues.spender).to.be.equal(receiver);410 value: '100',304 expect(event.returnValues.value).to.be.equal('100');411 },412 },413 ]);414 });305 });415306416 itWeb3('Events emitted for transferFrom()', async ({web3, privateKeyWrapper}) => {307 itEth('Events emitted for transferFrom()', async ({helper}) => {417 const collection = await createCollectionExpectSuccess({308 const [bob] = await helper.arrange.createAccounts([10n], donor);418 mode: {type: 'Fungible', decimalPoints: 0},309 const receiver = helper.eth.createAccount();419 });310 const collection = await helper.ft.mintCollection(alice);420 const alice = privateKeyWrapper('//Alice');311 await collection.mint(alice, 200n);421 const bob = privateKeyWrapper('//Bob');312 await collection.approveTokens(alice, {Substrate: bob.address}, 100n);422313423 const receiver = createEthAccount(web3);314 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);315 const contract = helper.ethNativeContract.collection(collectionAddress, 'ft');424316425 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n});317 const events: any = [];426 await approveExpectSuccess(collection, 0, alice, bob.address, 100);427428 const address = collectionIdToAddress(collection);429 const contract = new web3.eth.Contract(fungibleAbi as any, address);318 contract.events.allEvents((_: any, event: any) => {430431 const events = await recordEvents(contract, async () => {432 await transferFromExpectSuccess(collection, 0, bob, alice, {Ethereum: receiver}, 51, 'Fungible');319 events.push(event);433 });320 });321 await collection.transferFrom(bob, {Substrate: alice.address}, {Ethereum: receiver}, 51n);434322435 expect(events).to.be.deep.equal([323 let event = events[0];436 {437 address,438 event: 'Transfer',324 expect(event.event).to.be.equal('Transfer');439 args: {325 expect(event.address).to.be.equal(collectionAddress);440 from: subToEth(alice.address),441 to: receiver,442 value: '51',326 expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));443 },444 },445 {446 address,447 event: 'Approval',448 args: {449 owner: subToEth(alice.address),450 spender: subToEth(bob.address),327 expect(event.returnValues.to).to.be.equal(receiver);451 value: '49',328 expect(event.returnValues.value).to.be.equal('51');452 },453 },454 ]);455 });456329457 itWeb3('Events emitted for transfer()', async ({web3, privateKeyWrapper}) => {330 event = events[1];458 const collection = await createCollectionExpectSuccess({331 expect(event.event).to.be.equal('Approval');332 expect(event.address).to.be.equal(collectionAddress);459 mode: {type: 'Fungible', decimalPoints: 0},333 expect(event.returnValues.owner).to.be.equal(helper.address.substrateToEth(alice.address));460 });334 expect(event.returnValues.spender).to.be.equal(helper.address.substrateToEth(bob.address));461 const alice = privateKeyWrapper('//Alice');335 expect(event.returnValues.value).to.be.equal('49');462463 const receiver = createEthAccount(web3);336 });464337465 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n});338 itEth('Events emitted for transfer()', async ({helper}) => {339 const receiver = helper.eth.createAccount();340 const collection = await helper.ft.mintCollection(alice);341 await collection.mint(alice, 200n);466342467 const address = collectionIdToAddress(collection);343 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);468 const contract = new web3.eth.Contract(fungibleAbi as any, address);344 const contract = helper.ethNativeContract.collection(collectionAddress, 'ft');469345470 const events = await recordEvents(contract, async () => {346 const events: any = [];347 contract.events.allEvents((_: any, event: any) => {471 await transferExpectSuccess(collection, 0, alice, {Ethereum:receiver}, 51, 'Fungible');348 events.push(event);472 });349 });350 await collection.transfer(alice, {Ethereum:receiver}, 51n);473351474 expect(events).to.be.deep.equal([352 const event = events[0];475 {476 address,477 event: 'Transfer',353 expect(event.event).to.be.equal('Transfer');478 args: {354 expect(event.address).to.be.equal(collectionAddress);479 from: subToEth(alice.address),355 expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));480 to: receiver,356 expect(event.returnValues.to).to.be.equal(receiver);481 value: '51',357 expect(event.returnValues.value).to.be.equal('51');482 },483 },484 ]);485 });358 });486});359});487360tests/src/eth/nonFungible.test.tsdiffbeforeafterboth14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.161617import {approveExpectSuccess, burnItemExpectSuccess, createCollectionExpectSuccess, createItemExpectSuccess, transferExpectSuccess, transferFromExpectSuccess, UNIQUE} from '../util/helpers';17import {itEth, usingEthPlaygrounds, expect, EthUniqueHelper} from './util/playgrounds';18import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, evmCollection, evmCollectionHelpers, GAS_ARGS, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, transferBalanceToEth} from './util/helpers';18import {IKeyringPair} from '@polkadot/types/types';19import nonFungibleAbi from './nonFungibleAbi.json';19import {Contract} from 'web3-eth-contract';20import {expect} from 'chai';21import {submitTransactionAsync} from '../substrate/substrate-api';222023describe('NFT: Information getting', () => {21describe('NFT: Information getting', () => {24 itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {22 let donor: IKeyringPair;23 let alice: IKeyringPair;2425 before(async function() {26 await usingEthPlaygrounds(async (helper, privateKey) => {25 const collection = await createCollectionExpectSuccess({27 donor = privateKey('//Alice');26 mode: {type: 'NFT'},28 [alice] = await helper.arrange.createAccounts([10n], donor);27 });29 });28 const alice = privateKeyWrapper('//Alice');30 });31 32 itEth('totalSupply', async ({helper}) => {29 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);33 const collection = await helper.nft.mintCollection(alice, {});34 await collection.mintToken(alice);303531 await createItemExpectSuccess(alice, collection, 'NFT', {Substrate: alice.address});36 const caller = await helper.eth.createAccountWithBalance(donor);323733 const address = collectionIdToAddress(collection);38 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);34 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});35 const totalSupply = await contract.methods.totalSupply().call();39 const totalSupply = await contract.methods.totalSupply().call();364037 expect(totalSupply).to.equal('1');41 expect(totalSupply).to.equal('1');38 });42 });394340 itWeb3('balanceOf', async ({api, web3, privateKeyWrapper}) => {44 itEth('balanceOf', async ({helper}) => {41 const collection = await createCollectionExpectSuccess({45 const collection = await helper.nft.mintCollection(alice, {});42 mode: {type: 'NFT'},43 });44 const alice = privateKeyWrapper('//Alice');46 const caller = await helper.eth.createAccountWithBalance(donor);454746 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);48 await collection.mintToken(alice, {Ethereum: caller});47 await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum:caller});48 await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});49 await collection.mintToken(alice, {Ethereum: caller});49 await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});50 await collection.mintToken(alice, {Ethereum: caller});505151 const address = collectionIdToAddress(collection);52 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);52 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});53 const balance = await contract.methods.balanceOf(caller).call();53 const balance = await contract.methods.balanceOf(caller).call();545455 expect(balance).to.equal('3');55 expect(balance).to.equal('3');56 });56 });575758 itWeb3('ownerOf', async ({api, web3, privateKeyWrapper}) => {58 itEth('ownerOf', async ({helper}) => {59 const collection = await createCollectionExpectSuccess({59 const collection = await helper.nft.mintCollection(alice, {});60 mode: {type: 'NFT'},61 });62 const alice = privateKeyWrapper('//Alice');60 const caller = await helper.eth.createAccountWithBalance(donor);636164 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);62 const token = await collection.mintToken(alice, {Ethereum: caller});65 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});666367 const address = collectionIdToAddress(collection);64 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);68 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});69 const owner = await contract.methods.ownerOf(tokenId).call();706566 const owner = await contract.methods.ownerOf(token.tokenId).call();6771 expect(owner).to.equal(caller);68 expect(owner).to.equal(caller);72 });69 });73});70});747175describe('Check ERC721 token URI for NFT', () => {72describe('Check ERC721 token URI for NFT', () => {76 itWeb3('Empty tokenURI', async ({web3, api, privateKeyWrapper}) => {73 let donor: IKeyringPair;7475 before(async function() {76 await usingEthPlaygrounds(async (_helper, privateKey) => {77 donor = privateKey('//Alice');78 });79 });8081 async function setup(helper: EthUniqueHelper, tokenPrefix: string, propertyKey?: string, propertyValue?: string): Promise<{contract: Contract, nextTokenId: string}> {77 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);82 const owner = await helper.eth.createAccountWithBalance(donor);83 const receiver = helper.eth.createAccount();8478 const helper = evmCollectionHelpers(web3, owner);85 const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);79 let result = await helper.methods.createERC721MetadataCompatibleCollection('Mint collection', '1', '1', '').send();86 let result = await collectionHelper.methods.createERC721MetadataCompatibleCollection('Mint collection', 'a', 'b', tokenPrefix).send();80 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);87 const collectionAddress = helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);81 const receiver = createEthAccount(web3);88 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);82 const contract = evmCollection(web3, owner, collectionIdAddress);83 89 84 const nextTokenId = await contract.methods.nextTokenId().call();90 const nextTokenId = await contract.methods.nextTokenId().call();85 expect(nextTokenId).to.be.equal('1');91 expect(nextTokenId).to.be.equal('1');88 nextTokenId,94 nextTokenId,89 ).send();95 ).send();909691 const events = normalizeEvents(result.events);97 if (propertyKey && propertyValue) {92 const address = collectionIdToAddress(collectionId);98 // Set URL or suffix99 await contract.methods.setProperty(nextTokenId, propertyKey, Buffer.from(propertyValue)).send();100 }9310194 expect(events).to.be.deep.equal([102 const event = result.events.Transfer;103 expect(event.address).to.be.equal(collectionAddress);95 {104 expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');96 address,97 event: 'Transfer',98 args: {99 from: '0x0000000000000000000000000000000000000000',100 to: receiver,105 expect(event.returnValues.to).to.be.equal(receiver);101 tokenId: nextTokenId,106 expect(event.returnValues.tokenId).to.be.equal(nextTokenId);102 },103 },104 ]);105107108 return {contract, nextTokenId};109 }110111 itEth('Empty tokenURI', async ({helper}) => {112 const {contract, nextTokenId} = await setup(helper, '');106 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('');113 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('');107 });114 });108115109 itWeb3('TokenURI from url', async ({web3, api, privateKeyWrapper}) => {116 itEth('TokenURI from url', async ({helper}) => {110 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);117 const {contract, nextTokenId} = await setup(helper, 'BaseURI_', 'url', 'Token URI');111 const helper = evmCollectionHelpers(web3, owner);112 let result = await helper.methods.createERC721MetadataCompatibleCollection('Mint collection', '1', '1', 'BaseURI_').send();113 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);114 const receiver = createEthAccount(web3);115 const contract = evmCollection(web3, owner, collectionIdAddress);116 117 const nextTokenId = await contract.methods.nextTokenId().call();118 expect(nextTokenId).to.be.equal('1');119 result = await contract.methods.mint(120 receiver,121 nextTokenId,122 ).send();123 124 // Set URL125 await contract.methods.setProperty(nextTokenId, 'url', Buffer.from('Token URI')).send();126 127 const events = normalizeEvents(result.events);128 const address = collectionIdToAddress(collectionId);129130 expect(events).to.be.deep.equal([131 {132 address,133 event: 'Transfer',134 args: {135 from: '0x0000000000000000000000000000000000000000',136 to: receiver,137 tokenId: nextTokenId,138 },139 },140 ]);141142 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Token URI');118 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Token URI');143 });119 });144120145 itWeb3('TokenURI from baseURI + tokenId', async ({web3, api, privateKeyWrapper}) => {121 itEth('TokenURI from baseURI + tokenId', async ({helper}) => {146 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);122 const {contract, nextTokenId} = await setup(helper, 'BaseURI_');147 const helper = evmCollectionHelpers(web3, owner);148 let result = await helper.methods.createERC721MetadataCompatibleCollection('Mint collection', '1', '1', 'BaseURI_').send();149 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);150 const receiver = createEthAccount(web3);151 const contract = evmCollection(web3, owner, collectionIdAddress);152 153 const nextTokenId = await contract.methods.nextTokenId().call();154 expect(nextTokenId).to.be.equal('1');155 result = await contract.methods.mint(156 receiver,157 nextTokenId,158 ).send();159 160 const events = normalizeEvents(result.events);161 const address = collectionIdToAddress(collectionId);162163 expect(events).to.be.deep.equal([164 {165 address,166 event: 'Transfer',167 args: {168 from: '0x0000000000000000000000000000000000000000',169 to: receiver,170 tokenId: nextTokenId,171 },172 },173 ]);174175 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('BaseURI_' + nextTokenId);123 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('BaseURI_' + nextTokenId);176 });124 });177125178 itWeb3('TokenURI from baseURI + suffix', async ({web3, api, privateKeyWrapper}) => {126 itEth('TokenURI from baseURI + suffix', async ({helper}) => {179 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);180 const helper = evmCollectionHelpers(web3, owner);181 let result = await helper.methods.createERC721MetadataCompatibleCollection('Mint collection', '1', '1', 'BaseURI_').send();182 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);183 const receiver = createEthAccount(web3);184 const contract = evmCollection(web3, owner, collectionIdAddress);185 186 const nextTokenId = await contract.methods.nextTokenId().call();187 expect(nextTokenId).to.be.equal('1');188 result = await contract.methods.mint(189 receiver,190 nextTokenId,191 ).send();192 193 // Set suffix194 const suffix = '/some/suffix';127 const suffix = '/some/suffix';195 await contract.methods.setProperty(nextTokenId, 'suffix', Buffer.from(suffix)).send();128 const {contract, nextTokenId} = await setup(helper, 'BaseURI_', 'suffix', suffix);196197 const events = normalizeEvents(result.events);198 const address = collectionIdToAddress(collectionId);199200 expect(events).to.be.deep.equal([201 {202 address,203 event: 'Transfer',204 args: {205 from: '0x0000000000000000000000000000000000000000',206 to: receiver,207 tokenId: nextTokenId,208 },209 },210 ]);211212 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('BaseURI_' + suffix);129 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('BaseURI_' + suffix);213 });130 });214});131});215132216describe('NFT: Plain calls', () => {133describe('NFT: Plain calls', () => {217 itWeb3('Can perform mint()', async ({web3, api, privateKeyWrapper}) => {134 let donor: IKeyringPair;135 let alice: IKeyringPair;136137 before(async function() {138 await usingEthPlaygrounds(async (helper, privateKey) => {218 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);139 donor = privateKey('//Alice');219 const helper = evmCollectionHelpers(web3, owner);140 [alice] = await helper.arrange.createAccounts([10n], donor);220 let result = await helper.methods.createNonfungibleCollection('Mint collection', '6', '6').send();141 });142 });143144 itEth('Can perform mint()', async ({helper}) => {221 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);145 const owner = await helper.eth.createAccountWithBalance(donor);222 const receiver = createEthAccount(web3);146 const receiver = helper.eth.createAccount();147223 const contract = evmCollection(web3, owner, collectionIdAddress);148 const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'Minty', '6', '6');149 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);224 const nextTokenId = await contract.methods.nextTokenId().call();150 const nextTokenId = await contract.methods.nextTokenId().call();225151226 expect(nextTokenId).to.be.equal('1');152 expect(nextTokenId).to.be.equal('1');227 result = await contract.methods.mintWithTokenURI(153 const result = await contract.methods.mintWithTokenURI(228 receiver,154 receiver,229 nextTokenId,155 nextTokenId,230 'Test URI',156 'Test URI',231 ).send();157 ).send();232158233 const events = normalizeEvents(result.events);159 const event = result.events.Transfer;160 expect(event.address).to.be.equal(collectionAddress);234 const address = collectionIdToAddress(collectionId);161 expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');162 expect(event.returnValues.to).to.be.equal(receiver);163 expect(event.returnValues.tokenId).to.be.equal(nextTokenId);235164236 expect(events).to.be.deep.equal([237 {238 address,239 event: 'Transfer',240 args: {241 from: '0x0000000000000000000000000000000000000000',242 to: receiver,243 tokenId: nextTokenId,244 },245 },246 ]);247248 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');165 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');249166250 // TODO: this wont work right now, need release 919000 first167 // TODO: this wont work right now, need release 919000 first254 });171 });255172256 //TODO: CORE-302 add eth methods173 //TODO: CORE-302 add eth methods257 itWeb3.skip('Can perform mintBulk()', async ({web3, api, privateKeyWrapper}) => {174 /* todo:playgrounds skipped test!175 itWeb3.skip('Can perform mintBulk()', async ({helper}) => {258 const collection = await createCollectionExpectSuccess({176 const collection = await createCollectionExpectSuccess({259 mode: {type: 'NFT'},177 mode: {type: 'NFT'},260 });178 });316 expect(await contract.methods.tokenURI(+nextTokenId + 2).call()).to.be.equal('Test URI 2');234 expect(await contract.methods.tokenURI(+nextTokenId + 2).call()).to.be.equal('Test URI 2');317 }235 }318 });236 });237 */319238320 itWeb3('Can perform burn()', async ({web3, api, privateKeyWrapper}) => {239 itEth('Can perform burn()', async ({helper}) => {321 const collection = await createCollectionExpectSuccess({240 const caller = await helper.eth.createAccountWithBalance(donor);322 mode: {type: 'NFT'},323 });324 const alice = privateKeyWrapper('//Alice');325241326 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);242 const collection = await helper.nft.mintCollection(alice, {});243 const {tokenId} = await collection.mintToken(alice, {Ethereum: caller});327244328 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});245 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);246 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', caller);329247330 const address = collectionIdToAddress(collection);331 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});332333 {248 {334 const result = await contract.methods.burn(tokenId).send({from: owner});249 const result = await contract.methods.burn(tokenId).send({from: caller});335 const events = normalizeEvents(result.events);250 336251 const event = result.events.Transfer;337 expect(events).to.be.deep.equal([252 expect(event.address).to.be.equal(collectionAddress);338 {253 expect(event.returnValues.from).to.be.equal(caller);339 address,340 event: 'Transfer',341 args: {342 from: owner,343 to: '0x0000000000000000000000000000000000000000',254 expect(event.returnValues.to).to.be.equal('0x0000000000000000000000000000000000000000');344 tokenId: tokenId.toString(),255 expect(event.returnValues.tokenId).to.be.equal(`${tokenId}`);345 },346 },347 ]);348 }256 }349 });257 });350258351 itWeb3('Can perform approve()', async ({web3, api, privateKeyWrapper}) => {259 itEth('Can perform approve()', async ({helper}) => {352 const collection = await createCollectionExpectSuccess({260 const owner = await helper.eth.createAccountWithBalance(donor);353 mode: {type: 'NFT'},354 });355 const alice = privateKeyWrapper('//Alice');261 const spender = helper.eth.createAccount();356262357 const owner = createEthAccount(web3);263 const collection = await helper.nft.mintCollection(alice, {});358 await transferBalanceToEth(api, alice, owner);264 const {tokenId} = await collection.mintToken(alice, {Ethereum: owner});359265360 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});266 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);267 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);361268362 const spender = createEthAccount(web3);363364 const address = collectionIdToAddress(collection);365 const contract = new web3.eth.Contract(nonFungibleAbi as any, address);366367 {269 {368 const result = await contract.methods.approve(spender, tokenId).send({from: owner, ...GAS_ARGS});270 const result = await contract.methods.approve(spender, tokenId).send({from: owner});369 const events = normalizeEvents(result.events);370271371 expect(events).to.be.deep.equal([272 const event = result.events.Approval;372 {373 address,273 expect(event.address).to.be.equal(collectionAddress);374 event: 'Approval',274 expect(event.returnValues.owner).to.be.equal(owner);375 args: {376 owner,377 approved: spender,275 expect(event.returnValues.approved).to.be.equal(spender);378 tokenId: tokenId.toString(),276 expect(event.returnValues.tokenId).to.be.equal(`${tokenId}`);379 },380 },381 ]);382 }277 }383 });278 });384279385 itWeb3('Can perform transferFrom()', async ({web3, api, privateKeyWrapper}) => {280 itEth('Can perform transferFrom()', async ({helper}) => {386 const collection = await createCollectionExpectSuccess({281 const owner = await helper.eth.createAccountWithBalance(donor);387 mode: {type: 'NFT'},282 const spender = await helper.eth.createAccountWithBalance(donor);388 });389 const alice = privateKeyWrapper('//Alice');283 const receiver = helper.eth.createAccount();390284391 const owner = createEthAccount(web3);285 const collection = await helper.nft.mintCollection(alice, {});392 await transferBalanceToEth(api, alice, owner);286 const {tokenId} = await collection.mintToken(alice, {Ethereum: owner});393287394 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});288 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);289 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);395290396 const spender = createEthAccount(web3);397 await transferBalanceToEth(api, alice, spender);398399 const receiver = createEthAccount(web3);400401 const address = collectionIdToAddress(collection);402 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});403404 await contract.methods.approve(spender, tokenId).send({from: owner});291 await contract.methods.approve(spender, tokenId).send({from: owner});405292406 {293 {407 const result = await contract.methods.transferFrom(owner, receiver, tokenId).send({from: spender});294 const result = await contract.methods.transferFrom(owner, receiver, tokenId).send({from: spender});295408 const events = normalizeEvents(result.events);296 const event = result.events.Transfer;409 expect(events).to.be.deep.equal([297 expect(event.address).to.be.equal(collectionAddress);410 {298 expect(event.returnValues.from).to.be.equal(owner);411 address,412 event: 'Transfer',413 args: {414 from: owner,415 to: receiver,299 expect(event.returnValues.to).to.be.equal(receiver);416 tokenId: tokenId.toString(),300 expect(event.returnValues.tokenId).to.be.equal(`${tokenId}`);417 },418 },419 ]);420 }301 }421302422 {303 {430 }311 }431 });312 });432313433 itWeb3('Can perform transfer()', async ({web3, api, privateKeyWrapper}) => {314 itEth('Can perform transfer()', async ({helper}) => {434 const collection = await createCollectionExpectSuccess({315 const collection = await helper.nft.mintCollection(alice, {});435 mode: {type: 'NFT'},316 const owner = await helper.eth.createAccountWithBalance(donor);436 });437 const alice = privateKeyWrapper('//Alice');317 const receiver = helper.eth.createAccount();438318439 const owner = createEthAccount(web3);319 const {tokenId} = await collection.mintToken(alice, {Ethereum: owner});440 await transferBalanceToEth(api, alice, owner);441320442 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});321 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);322 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);443323444 const receiver = createEthAccount(web3);445 await transferBalanceToEth(api, alice, receiver);446447 const address = collectionIdToAddress(collection);448 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});449450 {324 {451 const result = await contract.methods.transfer(receiver, tokenId).send({from: owner});325 const result = await contract.methods.transfer(receiver, tokenId).send({from: owner});326452 const events = normalizeEvents(result.events);327 const event = result.events.Transfer;453 expect(events).to.be.deep.equal([328 expect(event.address).to.be.equal(collectionAddress);454 {329 expect(event.returnValues.from).to.be.equal(owner);455 address,456 event: 'Transfer',457 args: {458 from: owner,459 to: receiver,330 expect(event.returnValues.to).to.be.equal(receiver);460 tokenId: tokenId.toString(),331 expect(event.returnValues.tokenId).to.be.equal(`${tokenId}`);461 },462 },463 ]);464 }332 }465333466 {334 {476});344});477345478describe('NFT: Fees', () => {346describe('NFT: Fees', () => {479 itWeb3('approve() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {347 let donor: IKeyringPair;348 let alice: IKeyringPair;349350 before(async function() {351 await usingEthPlaygrounds(async (helper, privateKey) => {480 const collection = await createCollectionExpectSuccess({352 donor = privateKey('//Alice');481 mode: {type: 'NFT'},353 [alice] = await helper.arrange.createAccounts([10n], donor);482 });354 });483 const alice = privateKeyWrapper('//Alice');355 });356 357 itEth('approve() call fee is less than 0.2UNQ', async ({helper}) => {358 const owner = await helper.eth.createAccountWithBalance(donor);359 const spender = helper.eth.createAccount();484360485 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);361 const collection = await helper.nft.mintCollection(alice, {});486 const spender = createEthAccount(web3);362 const {tokenId} = await collection.mintToken(alice, {Ethereum: owner});487363488 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});364 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', owner);489365490 const address = collectionIdToAddress(collection);366 const cost = await helper.eth.recordCallFee(owner, () => contract.methods.approve(spender, tokenId).send({from: owner}));491 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});492493 const cost = await recordEthFee(api, owner, () => contract.methods.approve(spender, tokenId).send({from: owner}));494 expect(cost < BigInt(0.2 * Number(UNIQUE)));367 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));495 });368 });496369497 itWeb3('transferFrom() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {370 itEth('transferFrom() call fee is less than 0.2UNQ', async ({helper}) => {498 const collection = await createCollectionExpectSuccess({371 const owner = await helper.eth.createAccountWithBalance(donor);499 mode: {type: 'NFT'},500 });501 const alice = privateKeyWrapper('//Alice');372 const spender = await helper.eth.createAccountWithBalance(donor);502373503 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);374 const collection = await helper.nft.mintCollection(alice, {});504 const spender = await createEthAccountWithBalance(api, web3, privateKeyWrapper);375 const {tokenId} = await collection.mintToken(alice, {Ethereum: owner});505376506 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});377 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', owner);507378508 const address = collectionIdToAddress(collection);509 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});510511 await contract.methods.approve(spender, tokenId).send({from: owner});379 await contract.methods.approve(spender, tokenId).send({from: owner});512380513 const cost = await recordEthFee(api, spender, () => contract.methods.transferFrom(owner, spender, tokenId).send({from: spender}));381 const cost = await helper.eth.recordCallFee(spender, () => contract.methods.transferFrom(owner, spender, tokenId).send({from: spender}));514 expect(cost < BigInt(0.2 * Number(UNIQUE)));382 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));515 });383 });516384517 itWeb3('transfer() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {385 itEth('transfer() call fee is less than 0.2UNQ', async ({helper}) => {518 const collection = await createCollectionExpectSuccess({386 const owner = await helper.eth.createAccountWithBalance(donor);519 mode: {type: 'NFT'},520 });521 const alice = privateKeyWrapper('//Alice');387 const receiver = helper.eth.createAccount();522388523 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);389 const collection = await helper.nft.mintCollection(alice, {});524 const receiver = createEthAccount(web3);390 const {tokenId} = await collection.mintToken(alice, {Ethereum: owner});525391526 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});392 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', owner);527393528 const address = collectionIdToAddress(collection);394 const cost = await helper.eth.recordCallFee(owner, () => contract.methods.transfer(receiver, tokenId).send({from: owner}));529 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});530531 const cost = await recordEthFee(api, owner, () => contract.methods.transfer(receiver, tokenId).send({from: owner}));532 expect(cost < BigInt(0.2 * Number(UNIQUE)));395 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));533 });396 });534});397});535398536describe('NFT: Substrate calls', () => {399describe('NFT: Substrate calls', () => {537 itWeb3('Events emitted for mint()', async ({web3, privateKeyWrapper}) => {400 let donor: IKeyringPair;538 const collection = await createCollectionExpectSuccess({539 mode: {type: 'NFT'},540 });541 const alice = privateKeyWrapper('//Alice');401 let alice: IKeyringPair;542402543 const address = collectionIdToAddress(collection);403 before(async function() {544 const contract = new web3.eth.Contract(nonFungibleAbi as any, address);404 await usingEthPlaygrounds(async (helper, privateKey) => {545546 let tokenId: number;547 const events = await recordEvents(contract, async () => {405 donor = privateKey('//Alice');548 tokenId = await createItemExpectSuccess(alice, collection, 'NFT');406 [alice] = await helper.arrange.createAccounts([20n], donor);549 });407 });550551 expect(events).to.be.deep.equal([552 {553 address,554 event: 'Transfer',555 args: {556 from: '0x0000000000000000000000000000000000000000',557 to: subToEth(alice.address),558 tokenId: tokenId!.toString(),559 },560 },561 ]);562 });408 });563409564 itWeb3('Events emitted for burn()', async ({web3, privateKeyWrapper}) => {410 itEth('Events emitted for mint()', async ({helper}) => {565 const collection = await createCollectionExpectSuccess({411 const collection = await helper.nft.mintCollection(alice, {});566 mode: {type: 'NFT'},412 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);567 });568 const alice = privateKeyWrapper('//Alice');413 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');569414570 const address = collectionIdToAddress(collection);415 const events: any = [];571 const contract = new web3.eth.Contract(nonFungibleAbi as any, address);416 contract.events.allEvents((_: any, event: any) => {572573 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT');574 const events = await recordEvents(contract, async () => {575 await burnItemExpectSuccess(alice, collection, tokenId);417 events.push(event);576 });418 });419 const {tokenId} = await collection.mintToken(alice);577420578 expect(events).to.be.deep.equal([421 const event = events[0];579 {580 address,581 event: 'Transfer',422 expect(event.event).to.be.equal('Transfer');582 args: {423 expect(event.address).to.be.equal(collectionAddress);583 from: subToEth(alice.address),584 to: '0x0000000000000000000000000000000000000000',424 expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');585 tokenId: tokenId.toString(),425 expect(event.returnValues.to).to.be.equal(helper.address.substrateToEth(alice.address));586 },587 },588 ]);426 expect(event.returnValues.tokenId).to.be.equal(tokenId.toString());589 });427 });590428591 itWeb3('Events emitted for approve()', async ({web3, privateKeyWrapper}) => {429 itEth('Events emitted for burn()', async ({helper}) => {592 const collection = await createCollectionExpectSuccess({430 const collection = await helper.nft.mintCollection(alice, {});593 mode: {type: 'NFT'},431 const token = await collection.mintToken(alice);432433 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);434 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');435 436 const events: any = [];437 contract.events.allEvents((_: any, event: any) => {438 events.push(event);594 });439 });595 const alice = privateKeyWrapper('//Alice');596440597 const receiver = createEthAccount(web3);441 await token.burn(alice);598442599 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT');443 const event = events[0];444 expect(event.event).to.be.equal('Transfer');445 expect(event.address).to.be.equal(collectionAddress);446 expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));447 expect(event.returnValues.to).to.be.equal('0x0000000000000000000000000000000000000000');448 expect(event.returnValues.tokenId).to.be.equal(token.tokenId.toString());449 });600450601 const address = collectionIdToAddress(collection);451 itEth('Events emitted for approve()', async ({helper}) => {602 const contract = new web3.eth.Contract(nonFungibleAbi as any, address);452 const receiver = helper.eth.createAccount();603453604 const events = await recordEvents(contract, async () => {454 const collection = await helper.nft.mintCollection(alice, {});605 await approveExpectSuccess(collection, tokenId, alice, {Ethereum: receiver}, 1);455 const token = await collection.mintToken(alice);606 });607456608 expect(events).to.be.deep.equal([457 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);609 {458 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');610 address,611 event: 'Approval',612 args: {613 owner: subToEth(alice.address),614 approved: receiver,459 615 tokenId: tokenId.toString(),460 const events: any = [];616 },617 },618 ]);619 });461 contract.events.allEvents((_: any, event: any) => {620621 itWeb3('Events emitted for transferFrom()', async ({web3, privateKeyWrapper}) => {622 const collection = await createCollectionExpectSuccess({462 events.push(event);623 mode: {type: 'NFT'},624 });463 });625 const alice = privateKeyWrapper('//Alice');626 const bob = privateKeyWrapper('//Bob');627464628 const receiver = createEthAccount(web3);465 await token.approve(alice, {Ethereum: receiver});629466630 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT');467 const event = events[0];468 expect(event.event).to.be.equal('Approval');631 await approveExpectSuccess(collection, tokenId, alice, bob.address, 1);469 expect(event.address).to.be.equal(collectionAddress);470 expect(event.returnValues.owner).to.be.equal(helper.address.substrateToEth(alice.address));471 expect(event.returnValues.approved).to.be.equal(receiver);472 expect(event.returnValues.tokenId).to.be.equal(token.tokenId.toString());473 });632474633 const address = collectionIdToAddress(collection);475 itEth('Events emitted for transferFrom()', async ({helper}) => {476 const [bob] = await helper.arrange.createAccounts([10n], donor);634 const contract = new web3.eth.Contract(nonFungibleAbi as any, address);477 const receiver = helper.eth.createAccount();635478636 const events = await recordEvents(contract, async () => {479 const collection = await helper.nft.mintCollection(alice, {});480 const token = await collection.mintToken(alice);481 await token.approve(alice, {Substrate: bob.address});482637 await transferFromExpectSuccess(collection, tokenId, bob, alice, {Ethereum: receiver}, 1, 'NFT');483 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);484 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');485 486 const events: any = [];487 contract.events.allEvents((_: any, event: any) => {488 events.push(event);638 });489 });639490640 expect(events).to.be.deep.equal([491 await token.transferFrom(bob, {Substrate: alice.address}, {Ethereum: receiver});641 {642 address,643 event: 'Transfer',492 644 args: {493 const event = events[0];645 from: subToEth(alice.address),494 expect(event.address).to.be.equal(collectionAddress);495 expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));646 to: receiver,496 expect(event.returnValues.to).to.be.equal(receiver);647 tokenId: tokenId.toString(),497 expect(event.returnValues.tokenId).to.be.equal(`${token.tokenId}`);648 },649 },650 ]);651 });498 });652499653 itWeb3('Events emitted for transfer()', async ({web3, privateKeyWrapper}) => {500 itEth('Events emitted for transfer()', async ({helper}) => {654 const collection = await createCollectionExpectSuccess({501 const receiver = helper.eth.createAccount();655 mode: {type: 'NFT'},656 });657 const alice = privateKeyWrapper('//Alice');658502659 const receiver = createEthAccount(web3);503 const collection = await helper.nft.mintCollection(alice, {});504 const token = await collection.mintToken(alice);660505661 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT');506 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);662663 const address = collectionIdToAddress(collection);507 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');664 const contract = new web3.eth.Contract(nonFungibleAbi as any, address);508 665509 const events: any = [];666 const events = await recordEvents(contract, async () => {510 contract.events.allEvents((_: any, event: any) => {667 await transferExpectSuccess(collection, tokenId, alice, {Ethereum: receiver}, 1, 'NFT');511 events.push(event);668 });512 });669513670 expect(events).to.be.deep.equal([514 await token.transfer(alice, {Ethereum: receiver});671 {515 672 address,516 const event = events[0];673 event: 'Transfer',517 expect(event.address).to.be.equal(collectionAddress);674 args: {518 expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));675 from: subToEth(alice.address),676 to: receiver,519 expect(event.returnValues.to).to.be.equal(receiver);677 tokenId: tokenId.toString(),520 expect(event.returnValues.tokenId).to.be.equal(`${token.tokenId}`);678 },679 },680 ]);681 });521 });682});522});683523684describe('Common metadata', () => {524describe('Common metadata', () => {685 itWeb3('Returns collection name', async ({api, web3, privateKeyWrapper}) => {525 let donor: IKeyringPair;526 let alice: IKeyringPair;527528 before(async function() {686 const collection = await createCollectionExpectSuccess({529 await usingEthPlaygrounds(async (helper, privateKey) => {687 name: 'token name',530 donor = privateKey('//Alice');688 mode: {type: 'NFT'},531 [alice] = await helper.arrange.createAccounts([20n], donor);689 });532 });690 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);533 });691534692 const address = collectionIdToAddress(collection);535 itEth('Returns collection name', async ({helper}) => {693 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});536 const caller = await helper.eth.createAccountWithBalance(donor);694 const name = await contract.methods.name().call();537 const collection = await helper.nft.mintCollection(alice, {name: 'oh River', tokenPrefix: 'CHANGE'});695538696 expect(name).to.equal('token name');539 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);540 const name = await contract.methods.name().call();541 expect(name).to.equal('oh River');697 });542 });698543699 itWeb3('Returns symbol name', async ({api, web3, privateKeyWrapper}) => {544 itEth('Returns symbol name', async ({helper}) => {700 const collection = await createCollectionExpectSuccess({545 const caller = await helper.eth.createAccountWithBalance(donor);701 tokenPrefix: 'TOK',702 mode: {type: 'NFT'},703 });704 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);546 const collection = await helper.nft.mintCollection(alice, {name: 'oh River', tokenPrefix: 'CHANGE'});705547706 const address = collectionIdToAddress(collection);548 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);707 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});708 const symbol = await contract.methods.symbol().call();549 const symbol = await contract.methods.symbol().call();709710 expect(symbol).to.equal('TOK');550 expect(symbol).to.equal('CHANGE');711 });551 });712});552});tests/src/eth/reFungible.test.tsdiffbeforeafterboth14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.161617import {createCollectionExpectSuccess, UNIQUE, requirePallets, Pallets} from '../util/helpers';17import {Pallets, requirePalletsOrSkip} from '../util/playgrounds';18import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, evmCollection, evmCollectionHelpers, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, tokenIdToAddress, uniqueRefungibleToken} from './util/helpers';18import {expect, itEth, usingEthPlaygrounds} from './util/playgrounds';19import {expect} from 'chai';19import {IKeyringPair} from '@polkadot/types/types';202021describe('Refungible: Information getting', () => {21describe('Refungible: Information getting', () => {22 let donor: IKeyringPair;2322 before(async function() {24 before(async function() {23 await requirePallets(this, [Pallets.ReFungible]);25 await usingEthPlaygrounds(async (helper, privateKey) => {26 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);2728 donor = privateKey('//Alice');29 });24 });30 });253126 itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {32 itEth('totalSupply', async ({helper}) => {27 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);33 const caller = await helper.eth.createAccountWithBalance(donor);28 const helper = evmCollectionHelpers(web3, caller);29 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();34 const {collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'TotalSupply', '6', '6');30 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);35 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);31 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});32 const nextTokenId = await contract.methods.nextTokenId().call();36 const nextTokenId = await contract.methods.nextTokenId().call();33 await contract.methods.mint(caller, nextTokenId).send();37 await contract.methods.mint(caller, nextTokenId).send();34 const totalSupply = await contract.methods.totalSupply().call();38 const totalSupply = await contract.methods.totalSupply().call();35 expect(totalSupply).to.equal('1');39 expect(totalSupply).to.equal('1');36 });40 });374138 itWeb3('balanceOf', async ({api, web3, privateKeyWrapper}) => {42 itEth('balanceOf', async ({helper}) => {39 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);43 const caller = await helper.eth.createAccountWithBalance(donor);40 const helper = evmCollectionHelpers(web3, caller);41 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();44 const {collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'BalanceOf', '6', '6');42 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);45 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);43 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});444645 {47 {46 const nextTokenId = await contract.methods.nextTokenId().call();48 const nextTokenId = await contract.methods.nextTokenId().call();56 }58 }575958 const balance = await contract.methods.balanceOf(caller).call();60 const balance = await contract.methods.balanceOf(caller).call();5960 expect(balance).to.equal('3');61 expect(balance).to.equal('3');61 });62 });626363 itWeb3('ownerOf', async ({api, web3, privateKeyWrapper}) => {64 itEth('ownerOf', async ({helper}) => {64 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);65 const caller = await helper.eth.createAccountWithBalance(donor);65 const helper = evmCollectionHelpers(web3, caller);66 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();66 const {collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'OwnerOf', '6', '6');67 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);67 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);68 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});696870 const tokenId = await contract.methods.nextTokenId().call();69 const tokenId = await contract.methods.nextTokenId().call();71 await contract.methods.mint(caller, tokenId).send();70 await contract.methods.mint(caller, tokenId).send();727173 const owner = await contract.methods.ownerOf(tokenId).call();72 const owner = await contract.methods.ownerOf(tokenId).call();7475 expect(owner).to.equal(caller);73 expect(owner).to.equal(caller);76 });74 });777578 itWeb3('ownerOf after burn', async ({api, web3, privateKeyWrapper}) => {76 itEth('ownerOf after burn', async ({helper}) => {79 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);77 const caller = await helper.eth.createAccountWithBalance(donor);80 const receiver = createEthAccount(web3);78 const receiver = helper.eth.createAccount();81 const helper = evmCollectionHelpers(web3, caller);79 const {collectionId, collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'OwnerOf-AfterBurn', '6', '6');82 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();83 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);80 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);84 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});858186 const tokenId = await contract.methods.nextTokenId().call();82 const tokenId = await contract.methods.nextTokenId().call();87 await contract.methods.mint(caller, tokenId).send();83 await contract.methods.mint(caller, tokenId).send();84 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);888589 const tokenAddress = tokenIdToAddress(collectionId, tokenId);90 const tokenContract = uniqueRefungibleToken(web3, tokenAddress, caller);9192 await tokenContract.methods.repartition(2).send();86 await tokenContract.methods.repartition(2).send();93 await tokenContract.methods.transfer(receiver, 1).send();87 await tokenContract.methods.transfer(receiver, 1).send();948895 await tokenContract.methods.burnFrom(caller, 1).send();89 await tokenContract.methods.burnFrom(caller, 1).send();969097 const owner = await contract.methods.ownerOf(tokenId).call();91 const owner = await contract.methods.ownerOf(tokenId).call();9899 expect(owner).to.equal(receiver);92 expect(owner).to.equal(receiver);100 });93 });10194102 itWeb3('ownerOf for partial ownership', async ({api, web3, privateKeyWrapper}) => {95 itEth('ownerOf for partial ownership', async ({helper}) => {103 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);96 const caller = await helper.eth.createAccountWithBalance(donor);104 const receiver = createEthAccount(web3);97 const receiver = helper.eth.createAccount();105 const helper = evmCollectionHelpers(web3, caller);98 const {collectionId, collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'Partial-OwnerOf', '6', '6');106 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();107 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);99 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);108 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});109100110 const tokenId = await contract.methods.nextTokenId().call();101 const tokenId = await contract.methods.nextTokenId().call();111 await contract.methods.mint(caller, tokenId).send();102 await contract.methods.mint(caller, tokenId).send();103 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);112104113 const tokenAddress = tokenIdToAddress(collectionId, tokenId);114 const tokenContract = uniqueRefungibleToken(web3, tokenAddress, caller);115116 await tokenContract.methods.repartition(2).send();105 await tokenContract.methods.repartition(2).send();117 await tokenContract.methods.transfer(receiver, 1).send();106 await tokenContract.methods.transfer(receiver, 1).send();118107119 const owner = await contract.methods.ownerOf(tokenId).call();108 const owner = await contract.methods.ownerOf(tokenId).call();120121 expect(owner).to.equal('0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF');109 expect(owner).to.equal('0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF');122 });110 });123});111});124112125describe('Refungible: Plain calls', () => {113describe('Refungible: Plain calls', () => {114 let donor: IKeyringPair;115126 before(async function() {116 before(async function() {127 await requirePallets(this, [Pallets.ReFungible]);117 await usingEthPlaygrounds(async (helper, privateKey) => {118 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);119120 donor = privateKey('//Alice');121 });128 });122 });129123130 itWeb3('Can perform mint()', async ({web3, api, privateKeyWrapper}) => {124 itEth('Can perform mint()', async ({helper}) => {131 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);125 const owner = await helper.eth.createAccountWithBalance(donor);132 const helper = evmCollectionHelpers(web3, owner);126 const receiver = helper.eth.createAccount();133 let result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();127 const {collectionAddress} = await helper.eth.createRefungibleCollection(owner, 'Minty', '6', '6');134 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);128 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);135 const receiver = createEthAccount(web3);136 const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});129 137 const nextTokenId = await contract.methods.nextTokenId().call();130 const nextTokenId = await contract.methods.nextTokenId().call();138139 expect(nextTokenId).to.be.equal('1');131 expect(nextTokenId).to.be.equal('1');140 result = await contract.methods.mintWithTokenURI(132 const result = await contract.methods.mintWithTokenURI(141 receiver,133 receiver,142 nextTokenId,134 nextTokenId,143 'Test URI',135 'Test URI',144 ).send();136 ).send();145137146 const events = normalizeEvents(result.events);138 const event = result.events.Transfer;139 expect(event.address).to.equal(collectionAddress);140 expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');141 expect(event.returnValues.to).to.equal(receiver);142 expect(event.returnValues.tokenId).to.equal(nextTokenId);147143148 expect(events).to.include.deep.members([149 {150 address: collectionIdAddress,151 event: 'Transfer',152 args: {153 from: '0x0000000000000000000000000000000000000000',154 to: receiver,155 tokenId: nextTokenId,156 },157 },158 ]);159160 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');144 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');161 });145 });162146163 itWeb3('Can perform mintBulk()', async ({web3, api, privateKeyWrapper}) => {147 itEth('Can perform mintBulk()', async ({helper}) => {164 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);148 const owner = await helper.eth.createAccountWithBalance(donor);165 const helper = evmCollectionHelpers(web3, caller);149 const receiver = helper.eth.createAccount();166 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();150 const {collectionAddress} = await helper.eth.createRefungibleCollection(owner, 'MintBulky', '6', '6');167 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);151 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);168 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});169152170 const receiver = createEthAccount(web3);171172 {153 {173 const nextTokenId = await contract.methods.nextTokenId().call();154 const nextTokenId = await contract.methods.nextTokenId().call();174 expect(nextTokenId).to.be.equal('1');155 expect(nextTokenId).to.be.equal('1');180 [+nextTokenId + 2, 'Test URI 2'],161 [+nextTokenId + 2, 'Test URI 2'],181 ],162 ],182 ).send();163 ).send();183 const events = normalizeEvents(result.events);184164185 expect(events).to.include.deep.members([165 const events = result.events.Transfer;186 {187 address: collectionIdAddress,188 event: 'Transfer',189 args: {166 for (let i = 0; i < 2; i++) {190 from: '0x0000000000000000000000000000000000000000',191 to: receiver,192 tokenId: nextTokenId,193 },194 },195 {196 address: collectionIdAddress,167 const event = events[i];197 event: 'Transfer',198 args: {199 from: '0x0000000000000000000000000000000000000000',168 expect(event.address).to.equal(collectionAddress);200 to: receiver,201 tokenId: String(+nextTokenId + 1),202 },169 expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');203 },204 {205 address: collectionIdAddress,206 event: 'Transfer',207 args: {208 from: '0x0000000000000000000000000000000000000000',209 to: receiver,170 expect(event.returnValues.to).to.equal(receiver);210 tokenId: String(+nextTokenId + 2),171 expect(event.returnValues.tokenId).to.equal(String(+nextTokenId + i));211 },172 }212 },213 ]);214173215 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI 0');174 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI 0');216 expect(await contract.methods.tokenURI(+nextTokenId + 1).call()).to.be.equal('Test URI 1');175 expect(await contract.methods.tokenURI(+nextTokenId + 1).call()).to.be.equal('Test URI 1');217 expect(await contract.methods.tokenURI(+nextTokenId + 2).call()).to.be.equal('Test URI 2');176 expect(await contract.methods.tokenURI(+nextTokenId + 2).call()).to.be.equal('Test URI 2');218 }177 }219 });178 });220179221 itWeb3('Can perform burn()', async ({web3, api, privateKeyWrapper}) => {180 itEth('Can perform burn()', async ({helper}) => {222 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);181 const caller = await helper.eth.createAccountWithBalance(donor);223 const helper = evmCollectionHelpers(web3, caller);224 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();182 const {collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'Burny', '6', '6');225 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);183 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);226 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});227184228 const tokenId = await contract.methods.nextTokenId().call();185 const tokenId = await contract.methods.nextTokenId().call();229 await contract.methods.mint(caller, tokenId).send();186 await contract.methods.mint(caller, tokenId).send();230 {187 {231 const result = await contract.methods.burn(tokenId).send();188 const result = await contract.methods.burn(tokenId).send();232 const events = normalizeEvents(result.events);189 const event = result.events.Transfer;233 expect(events).to.include.deep.members([190 expect(event.address).to.equal(collectionAddress);234 {191 expect(event.returnValues.from).to.equal(caller);235 address: collectionIdAddress,236 event: 'Transfer',237 args: {238 from: caller,239 to: '0x0000000000000000000000000000000000000000',192 expect(event.returnValues.to).to.equal('0x0000000000000000000000000000000000000000');240 tokenId: tokenId.toString(),193 expect(event.returnValues.tokenId).to.equal(tokenId.toString());241 },242 },243 ]);244 }194 }245 });195 });246196247 itWeb3('Can perform transferFrom()', async ({web3, api, privateKeyWrapper}) => {197 itEth('Can perform transferFrom()', async ({helper}) => {248 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);198 const caller = await helper.eth.createAccountWithBalance(donor);249 const helper = evmCollectionHelpers(web3, caller);199 const receiver = helper.eth.createAccount();250 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();200 const {collectionId, collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'TransferFromy', '6', '6');251 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);201 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);252 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});253202254 const receiver = createEthAccount(web3);255256 const tokenId = await contract.methods.nextTokenId().call();203 const tokenId = await contract.methods.nextTokenId().call();204 const tokenAddress = helper.ethAddress.fromTokenId(collectionId, tokenId);257 await contract.methods.mint(caller, tokenId).send();205 await contract.methods.mint(caller, tokenId).send();258206259 const address = tokenIdToAddress(collectionId, tokenId);207 const tokenContract = helper.ethNativeContract.rftToken(tokenAddress, caller);260 const tokenContract = uniqueRefungibleToken(web3, address, caller);261 await tokenContract.methods.repartition(15).send();208 await tokenContract.methods.repartition(15).send();262209263 {210 {264 const erc20Events = await recordEvents(tokenContract, async () => {211 const tokenEvents: any = [];265 const result = await contract.methods.transferFrom(caller, receiver, tokenId).send();266 const events = normalizeEvents(result.events);212 tokenContract.events.allEvents((_: any, event: any) => {267 expect(events).to.include.deep.members([268 {269 address: collectionIdAddress,270 event: 'Transfer',271 args: {272 from: caller,213 tokenEvents.push(event);273 to: receiver,274 tokenId: tokenId.toString(),275 },276 },277 ]);278 });214 });215 const result = await contract.methods.transferFrom(caller, receiver, tokenId).send();279216280 expect(erc20Events).to.include.deep.members([217 let event = result.events.Transfer;218 expect(event.address).to.equal(collectionAddress);281 {219 expect(event.returnValues.from).to.equal(caller);282 address,220 expect(event.returnValues.to).to.equal(receiver);283 event: 'Transfer',221 expect(event.returnValues.tokenId).to.equal(tokenId.toString());222284 args: {223 event = tokenEvents[0];285 from: caller,224 expect(event.address).to.equal(tokenAddress);225 expect(event.returnValues.from).to.equal(caller);286 to: receiver,226 expect(event.returnValues.to).to.equal(receiver);287 value: '15',227 expect(event.returnValues.value).to.equal('15');288 },289 },290 ]);291 }228 }292229293 {230 {301 }238 }302 });239 });303240304 itWeb3('Can perform transfer()', async ({web3, api, privateKeyWrapper}) => {241 itEth('Can perform transfer()', async ({helper}) => {305 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);242 const caller = await helper.eth.createAccountWithBalance(donor);306 const helper = evmCollectionHelpers(web3, caller);243 const receiver = helper.eth.createAccount();307 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();244 const {collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'Transferry', '6', '6');308 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);245 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);309 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});310246311 const receiver = createEthAccount(web3);312313 const tokenId = await contract.methods.nextTokenId().call();247 const tokenId = await contract.methods.nextTokenId().call();314 await contract.methods.mint(caller, tokenId).send();248 await contract.methods.mint(caller, tokenId).send();315249316 {250 {317 const result = await contract.methods.transfer(receiver, tokenId).send();251 const result = await contract.methods.transfer(receiver, tokenId).send();318 const events = normalizeEvents(result.events);252 253 const event = result.events.Transfer;319 expect(events).to.include.deep.members([254 expect(event.address).to.equal(collectionAddress);320 {255 expect(event.returnValues.from).to.equal(caller);321 address: collectionIdAddress,322 event: 'Transfer',323 args: {324 from: caller,325 to: receiver,256 expect(event.returnValues.to).to.equal(receiver);326 tokenId: tokenId.toString(),257 expect(event.returnValues.tokenId).to.equal(tokenId.toString());327 },328 },329 ]);330 }258 }331259332 {260 {340 }268 }341 });269 });342270343 itWeb3('transfer event on transfer from partial ownership to full ownership', async ({api, web3, privateKeyWrapper}) => {271 itEth('transfer event on transfer from partial ownership to full ownership', async ({helper}) => {344 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);272 const caller = await helper.eth.createAccountWithBalance(donor);345 const receiver = createEthAccount(web3);273 const receiver = helper.eth.createAccount();346 const helper = evmCollectionHelpers(web3, caller);274 const {collectionId, collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'Transferry-Partial-to-Full', '6', '6');347 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();348 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);275 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);349 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});350276351 const tokenId = await contract.methods.nextTokenId().call();277 const tokenId = await contract.methods.nextTokenId().call();352 await contract.methods.mint(caller, tokenId).send();278 await contract.methods.mint(caller, tokenId).send();353279354 const tokenAddress = tokenIdToAddress(collectionId, tokenId);280 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);355 const tokenContract = uniqueRefungibleToken(web3, tokenAddress, caller);356281357 await tokenContract.methods.repartition(2).send();282 await tokenContract.methods.repartition(2).send();358 await tokenContract.methods.transfer(receiver, 1).send();283 await tokenContract.methods.transfer(receiver, 1).send();359284360 const events = await recordEvents(contract, async () =>285 const events: any = [];286 contract.events.allEvents((_: any, event: any) => {361 await tokenContract.methods.transfer(receiver, 1).send());287 events.push(event);362 expect(events).to.deep.equal([288 });289 await tokenContract.methods.transfer(receiver, 1).send();290363 {291 const event = events[0];364 address: collectionIdAddress,365 event: 'Transfer',292 expect(event.address).to.equal(collectionAddress);366 args: {293 expect(event.returnValues.from).to.equal('0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF');367 from: '0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF',368 to: receiver,294 expect(event.returnValues.to).to.equal(receiver);369 tokenId: tokenId.toString(),295 expect(event.returnValues.tokenId).to.equal(tokenId.toString());370 },371 },372 ]);373 });296 });374297375 itWeb3('transfer event on transfer from full ownership to partial ownership', async ({api, web3, privateKeyWrapper}) => {298 itEth('transfer event on transfer from full ownership to partial ownership', async ({helper}) => {376 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);299 const caller = await helper.eth.createAccountWithBalance(donor);377 const receiver = createEthAccount(web3);300 const receiver = helper.eth.createAccount();378 const helper = evmCollectionHelpers(web3, caller);301 const {collectionId, collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'Transferry-Full-to-Partial', '6', '6');379 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();380 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);302 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);381 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});382303383 const tokenId = await contract.methods.nextTokenId().call();304 const tokenId = await contract.methods.nextTokenId().call();384 await contract.methods.mint(caller, tokenId).send();305 await contract.methods.mint(caller, tokenId).send();385306386 const tokenAddress = tokenIdToAddress(collectionId, tokenId);307 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);387 const tokenContract = uniqueRefungibleToken(web3, tokenAddress, caller);388308389 await tokenContract.methods.repartition(2).send();309 await tokenContract.methods.repartition(2).send();390310391 const events = await recordEvents(contract, async () =>311 const events: any = [];312 contract.events.allEvents((_: any, event: any) => {392 await tokenContract.methods.transfer(receiver, 1).send());313 events.push(event);314 });315 await tokenContract.methods.transfer(receiver, 1).send();393316394 expect(events).to.deep.equal([317 const event = events[0];395 {396 address: collectionIdAddress,318 expect(event.address).to.equal(collectionAddress);397 event: 'Transfer',319 expect(event.returnValues.from).to.equal(caller);398 args: {399 from: caller,400 to: '0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF',320 expect(event.returnValues.to).to.equal('0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF');401 tokenId: tokenId.toString(),321 expect(event.returnValues.tokenId).to.equal(tokenId.toString());402 },403 },404 ]);405 });322 });406});323});407324408describe('RFT: Fees', () => {325describe('RFT: Fees', () => {326 let donor: IKeyringPair;327409 before(async function() {328 before(async function() {410 await requirePallets(this, [Pallets.ReFungible]);329 await usingEthPlaygrounds(async (helper, privateKey) => {330 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);331332 donor = privateKey('//Alice');333 });411 });334 });412335413 itWeb3('transferFrom() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {336 itEth('transferFrom() call fee is less than 0.2UNQ', async ({helper}) => {414 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);337 const caller = await helper.eth.createAccountWithBalance(donor);415 const helper = evmCollectionHelpers(web3, caller);338 const receiver = helper.eth.createAccount();416 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();339 const {collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'Feeful-Transfer-From', '6', '6');417 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);340 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);418 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});419341420 const receiver = createEthAccount(web3);421422 const tokenId = await contract.methods.nextTokenId().call();342 const tokenId = await contract.methods.nextTokenId().call();423 await contract.methods.mint(caller, tokenId).send();343 await contract.methods.mint(caller, tokenId).send();424344425 const cost = await recordEthFee(api, caller, () => contract.methods.transferFrom(caller, receiver, tokenId).send());345 const cost = await helper.eth.recordCallFee(caller, () => contract.methods.transferFrom(caller, receiver, tokenId).send());426 expect(cost < BigInt(0.2 * Number(UNIQUE)));346 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));427 expect(cost > 0n);347 expect(cost > 0n);428 });348 });429349430 itWeb3('transfer() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {350 itEth('transfer() call fee is less than 0.2UNQ', async ({helper}) => {431 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);351 const caller = await helper.eth.createAccountWithBalance(donor);432 const helper = evmCollectionHelpers(web3, caller);352 const receiver = helper.eth.createAccount();433 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();353 const {collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'Feeful-Transfer', '6', '6');434 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);354 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);435 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});436355437 const receiver = createEthAccount(web3);438439 const tokenId = await contract.methods.nextTokenId().call();356 const tokenId = await contract.methods.nextTokenId().call();440 await contract.methods.mint(caller, tokenId).send();357 await contract.methods.mint(caller, tokenId).send();441358442 const cost = await recordEthFee(api, caller, () => contract.methods.transfer(receiver, tokenId).send());359 const cost = await helper.eth.recordCallFee(caller, () => contract.methods.transfer(receiver, tokenId).send());443 expect(cost < BigInt(0.2 * Number(UNIQUE)));360 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));444 expect(cost > 0n);361 expect(cost > 0n);445 });362 });446});363});447364448describe('Common metadata', () => {365describe('Common metadata', () => {366 let donor: IKeyringPair;367 let alice: IKeyringPair;368449 before(async function() {369 before(async function() {450 await requirePallets(this, [Pallets.ReFungible]);370 await usingEthPlaygrounds(async (helper, privateKey) => {451 });371 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);452372453 itWeb3('Returns collection name', async ({api, web3, privateKeyWrapper}) => {373 donor = privateKey('//Alice');454 const collection = await createCollectionExpectSuccess({374 [alice] = await helper.arrange.createAccounts([20n], donor);455 name: 'token name',456 mode: {type: 'ReFungible'},457 });375 });458 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);376 });459377460 const address = collectionIdToAddress(collection);378 itEth('Returns collection name', async ({helper}) => {379 const caller = helper.eth.createAccount();461 const contract = evmCollection(web3, caller, address, {type: 'ReFungible'});380 const collection = await helper.rft.mintCollection(alice, {name: 'Leviathan', tokenPrefix: '11'});381 382 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'rft', caller);462 const name = await contract.methods.name().call();383 const name = await contract.methods.name().call();463464 expect(name).to.equal('token name');384 expect(name).to.equal('Leviathan');465 });385 });466386467 itWeb3('Returns symbol name', async ({api, web3, privateKeyWrapper}) => {387 itEth('Returns symbol name', async ({helper}) => {468 const collection = await createCollectionExpectSuccess({388 const caller = await helper.eth.createAccountWithBalance(donor);469 tokenPrefix: 'TOK',470 mode: {type: 'ReFungible'},471 });472 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);389 const {collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'Leviathan', '', '12');473474 const address = collectionIdToAddress(collection);475 const contract = evmCollection(web3, caller, address, {type: 'ReFungible'});390 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);476 const symbol = await contract.methods.symbol().call();391 const symbol = await contract.methods.symbol().call();477478 expect(symbol).to.equal('TOK');392 expect(symbol).to.equal('12');479 });393 });480});394});481395tests/src/eth/reFungibleToken.test.tsdiffbeforeafterboth14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.161617import {approve, createCollection, createRefungibleToken, transfer, transferFrom, UNIQUE, requirePallets, Pallets} from '../util/helpers';17import {Pallets, requirePalletsOrSkip} from '../util/playgrounds';18import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, createRFTCollection, evmCollection, evmCollectionHelpers, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, tokenIdToAddress, transferBalanceToEth, uniqueRefungible, uniqueRefungibleToken} from './util/helpers';18import {EthUniqueHelper, expect, itEth, usingEthPlaygrounds} from './util/playgrounds';19import {IKeyringPair} from '@polkadot/types/types';20import {Contract} from 'web3-eth-contract';192120import chai from 'chai';21import chaiAsPromised from 'chai-as-promised';22chai.use(chaiAsPromised);23const expect = chai.expect;2425describe('Refungible token: Information getting', () => {22describe('Refungible token: Information getting', () => {23 let donor: IKeyringPair;24 let alice: IKeyringPair;2526 before(async function() {26 before(async function() {27 await requirePallets(this, [Pallets.ReFungible]);27 await usingEthPlaygrounds(async (helper, privateKey) => {28 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);2930 donor = privateKey('//Alice');31 [alice] = await helper.arrange.createAccounts([20n], donor);32 });28 });33 });293430 itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {35 itEth('totalSupply', async ({helper}) => {31 const alice = privateKeyWrapper('//Alice');36 const caller = await helper.eth.createAccountWithBalance(donor);37 const collection = await helper.rft.mintCollection(alice, {tokenPrefix: 'MUON'});38 const {tokenId} = await collection.mintToken(alice, 200n, {Ethereum: caller});323933 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;40 const contract = helper.ethNativeContract.rftTokenById(collection.collectionId, tokenId, caller);3435 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);3637 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;3839 const address = tokenIdToAddress(collectionId, tokenId);40 const contract = uniqueRefungibleToken(web3, address, caller);41 const totalSupply = await contract.methods.totalSupply().call();41 const totalSupply = await contract.methods.totalSupply().call();4243 expect(totalSupply).to.equal('200');42 expect(totalSupply).to.equal('200');44 });43 });454446 itWeb3('balanceOf', async ({api, web3, privateKeyWrapper}) => {45 itEth('balanceOf', async ({helper}) => {47 const alice = privateKeyWrapper('//Alice');46 const caller = await helper.eth.createAccountWithBalance(donor);47 const collection = await helper.rft.mintCollection(alice, {tokenPrefix: 'MUON'});48 const {tokenId} = await collection.mintToken(alice, 200n, {Ethereum: caller});484949 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;50 const contract = helper.ethNativeContract.rftTokenById(collection.collectionId, tokenId, caller);5051 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);5253 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;5455 const address = tokenIdToAddress(collectionId, tokenId);56 const contract = uniqueRefungibleToken(web3, address, caller);57 const balance = await contract.methods.balanceOf(caller).call();51 const balance = await contract.methods.balanceOf(caller).call();5859 expect(balance).to.equal('200');52 expect(balance).to.equal('200');60 });53 });615462 itWeb3('decimals', async ({api, web3, privateKeyWrapper}) => {55 itEth('decimals', async ({helper}) => {63 const alice = privateKeyWrapper('//Alice');56 const caller = await helper.eth.createAccountWithBalance(donor);57 const collection = await helper.rft.mintCollection(alice, {tokenPrefix: 'MUON'});58 const {tokenId} = await collection.mintToken(alice, 200n, {Ethereum: caller});645965 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;60 const contract = helper.ethNativeContract.rftTokenById(collection.collectionId, tokenId, caller);6667 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);6869 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;7071 const address = tokenIdToAddress(collectionId, tokenId);72 const contract = uniqueRefungibleToken(web3, address, caller);73 const decimals = await contract.methods.decimals().call();61 const decimals = await contract.methods.decimals().call();7475 expect(decimals).to.equal('0');62 expect(decimals).to.equal('0');76 });63 });77});64});786579// FIXME: Need erc721 for ReFubgible.66// FIXME: Need erc721 for ReFubgible.80describe('Check ERC721 token URI for ReFungible', () => {67describe('Check ERC721 token URI for ReFungible', () => {68 let donor: IKeyringPair;6981 before(async function() {70 before(async function() {82 await requirePallets(this, [Pallets.ReFungible]);71 await usingEthPlaygrounds(async (helper, privateKey) => {72 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);7374 donor = privateKey('//Alice');75 });83 });76 });847785 itWeb3('Empty tokenURI', async ({web3, api, privateKeyWrapper}) => {78 async function setup(helper: EthUniqueHelper, tokenPrefix: string, propertyKey?: string, propertyValue?: string): Promise<{contract: Contract, nextTokenId: string}> {86 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);87 const helper = evmCollectionHelpers(web3, owner);79 const owner = await helper.eth.createAccountWithBalance(donor);88 let result = await helper.methods.createERC721MetadataCompatibleCollection('Mint collection', '1', '1', '').send();89 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);80 const receiver = helper.eth.createAccount();90 const receiver = createEthAccount(web3);91 const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});928182 const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);83 let result = await collectionHelper.methods.createERC721MetadataCompatibleCollection('Mint collection', 'a', 'b', tokenPrefix).send();84 const collectionAddress = helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);85 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);86 93 const nextTokenId = await contract.methods.nextTokenId().call();87 const nextTokenId = await contract.methods.nextTokenId().call();94 expect(nextTokenId).to.be.equal('1');88 expect(nextTokenId).to.be.equal('1');95 result = await contract.methods.mint(89 result = await contract.methods.mint(96 receiver,90 receiver,97 nextTokenId,91 nextTokenId,98 ).send();92 ).send();9993100 const events = normalizeEvents(result.events);94 if (propertyKey && propertyValue) {101 const address = collectionIdToAddress(collectionId);95 // Set URL or suffix96 await contract.methods.setProperty(nextTokenId, propertyKey, Buffer.from(propertyValue)).send();97 }10298103 expect(events).to.be.deep.equal([99 const event = result.events.Transfer;100 expect(event.address).to.be.equal(collectionAddress);104 {101 expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');105 address,106 event: 'Transfer',107 args: {108 from: '0x0000000000000000000000000000000000000000',109 to: receiver,102 expect(event.returnValues.to).to.be.equal(receiver);110 tokenId: nextTokenId,103 expect(event.returnValues.tokenId).to.be.equal(nextTokenId);111 },112 },113 ]);114104105 return {contract, nextTokenId};106 }107108 itEth('Empty tokenURI', async ({helper}) => {109 const {contract, nextTokenId} = await setup(helper, '');115 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('');110 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('');116 });111 });117112118 itWeb3('TokenURI from url', async ({web3, api, privateKeyWrapper}) => {113 itEth('TokenURI from url', async ({helper}) => {119 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);114 const {contract, nextTokenId} = await setup(helper, 'BaseURI_', 'url', 'Token URI');120 const helper = evmCollectionHelpers(web3, owner);121 let result = await helper.methods.createERC721MetadataCompatibleCollection('Mint collection', '1', '1', 'BaseURI_').send();122 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);123 const receiver = createEthAccount(web3);124 const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});125126 const nextTokenId = await contract.methods.nextTokenId().call();127 expect(nextTokenId).to.be.equal('1');128 result = await contract.methods.mint(129 receiver,130 nextTokenId,131 ).send();132133 // Set URL134 await contract.methods.setProperty(nextTokenId, 'url', Buffer.from('Token URI')).send();135136 const events = normalizeEvents(result.events);137 const address = collectionIdToAddress(collectionId);138139 expect(events).to.be.deep.equal([140 {141 address,142 event: 'Transfer',143 args: {144 from: '0x0000000000000000000000000000000000000000',145 to: receiver,146 tokenId: nextTokenId,147 },148 },149 ]);150151 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Token URI');115 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Token URI');152 });116 });153117154 itWeb3('TokenURI from baseURI + tokenId', async ({web3, api, privateKeyWrapper}) => {118 itEth('TokenURI from baseURI + tokenId', async ({helper}) => {155 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);119 const {contract, nextTokenId} = await setup(helper, 'BaseURI_');156 const helper = evmCollectionHelpers(web3, owner);157 let result = await helper.methods.createERC721MetadataCompatibleCollection('Mint collection', '1', '1', 'BaseURI_').send();158 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);159 const receiver = createEthAccount(web3);160 const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});161162 const nextTokenId = await contract.methods.nextTokenId().call();163 expect(nextTokenId).to.be.equal('1');164 result = await contract.methods.mint(165 receiver,166 nextTokenId,167 ).send();168169 const events = normalizeEvents(result.events);170 const address = collectionIdToAddress(collectionId);171172 expect(events).to.be.deep.equal([173 {174 address,175 event: 'Transfer',176 args: {177 from: '0x0000000000000000000000000000000000000000',178 to: receiver,179 tokenId: nextTokenId,180 },181 },182 ]);183184 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('BaseURI_' + nextTokenId);120 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('BaseURI_' + nextTokenId);185 });121 });186122187 itWeb3('TokenURI from baseURI + suffix', async ({web3, api, privateKeyWrapper}) => {123 itEth('TokenURI from baseURI + suffix', async ({helper}) => {188 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);189 const helper = evmCollectionHelpers(web3, owner);190 let result = await helper.methods.createERC721MetadataCompatibleCollection('Mint collection', '1', '1', 'BaseURI_').send();191 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);192 const receiver = createEthAccount(web3);193 const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});194195 const nextTokenId = await contract.methods.nextTokenId().call();196 expect(nextTokenId).to.be.equal('1');197 result = await contract.methods.mint(198 receiver,199 nextTokenId,200 ).send();201202 // Set suffix203 const suffix = '/some/suffix';124 const suffix = '/some/suffix';204 await contract.methods.setProperty(nextTokenId, 'suffix', Buffer.from(suffix)).send();125 const {contract, nextTokenId} = await setup(helper, 'BaseURI_', 'suffix', suffix);205206 const events = normalizeEvents(result.events);207 const address = collectionIdToAddress(collectionId);208209 expect(events).to.be.deep.equal([210 {211 address,212 event: 'Transfer',213 args: {214 from: '0x0000000000000000000000000000000000000000',215 to: receiver,216 tokenId: nextTokenId,217 },218 },219 ]);220221 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('BaseURI_' + suffix);126 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('BaseURI_' + suffix);222 });127 });223});128});224129225describe('Refungible: Plain calls', () => {130describe('Refungible: Plain calls', () => {131 let donor: IKeyringPair;132 let alice: IKeyringPair;133226 before(async function() {134 before(async function() {227 await requirePallets(this, [Pallets.ReFungible]);135 await usingEthPlaygrounds(async (helper, privateKey) => {136 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);137138 donor = privateKey('//Alice');139 [alice] = await helper.arrange.createAccounts([50n], donor);140 });228 });141 });229142230 itWeb3('Can perform approve()', async ({web3, api, privateKeyWrapper}) => {143 itEth('Can perform approve()', async ({helper}) => {231 const alice = privateKeyWrapper('//Alice');144 const owner = await helper.eth.createAccountWithBalance(donor);145 const spender = helper.eth.createAccount();146 const collection = await helper.rft.mintCollection(alice);147 const {tokenId} = await collection.mintToken(alice, 200n, {Ethereum: owner});232148233 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;149 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);150 const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);234151235 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);236237 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;238239 const address = tokenIdToAddress(collectionId, tokenId);240241 const spender = createEthAccount(web3);242243 const contract = uniqueRefungibleToken(web3, address, owner);244245 {152 {246 const result = await contract.methods.approve(spender, 100).send({from: owner});153 const result = await contract.methods.approve(spender, 100).send({from: owner});247 const events = normalizeEvents(result.events);154 const event = result.events.Approval;248249 expect(events).to.be.deep.equal([155 expect(event.address).to.be.equal(tokenAddress);250 {156 expect(event.returnValues.owner).to.be.equal(owner);251 address,252 event: 'Approval',253 args: {254 owner,255 spender,157 expect(event.returnValues.spender).to.be.equal(spender);256 value: '100',158 expect(event.returnValues.value).to.be.equal('100');257 },258 },259 ]);260 }159 }261160262 {161 {265 }164 }266 });165 });267166268 itWeb3('Can perform transferFrom()', async ({web3, api, privateKeyWrapper}) => {167 itEth('Can perform transferFrom()', async ({helper}) => {269 const alice = privateKeyWrapper('//Alice');168 const owner = await helper.eth.createAccountWithBalance(donor);169 const spender = await helper.eth.createAccountWithBalance(donor);170 const receiver = helper.eth.createAccount();171 const collection = await helper.rft.mintCollection(alice);172 const {tokenId} = await collection.mintToken(alice, 200n, {Ethereum: owner});270173271 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;174 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);175 const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);272176273 const owner = createEthAccount(web3);274 await transferBalanceToEth(api, alice, owner);275276 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;277278 const spender = createEthAccount(web3);279 await transferBalanceToEth(api, alice, spender);280281 const receiver = createEthAccount(web3);282283 const address = tokenIdToAddress(collectionId, tokenId);284 const contract = uniqueRefungibleToken(web3, address, owner);285286 await contract.methods.approve(spender, 100).send();177 await contract.methods.approve(spender, 100).send();287178288 {179 {289 const result = await contract.methods.transferFrom(owner, receiver, 49).send({from: spender});180 const result = await contract.methods.transferFrom(owner, receiver, 49).send({from: spender});290 const events = normalizeEvents(result.events);181 let event = result.events.Transfer;291 expect(events).to.include.deep.members([182 expect(event.address).to.be.equal(tokenAddress);292 {183 expect(event.returnValues.from).to.be.equal(owner);293 address,294 event: 'Transfer',295 args: {296 from: owner,297 to: receiver,184 expect(event.returnValues.to).to.be.equal(receiver);298 value: '49',185 expect(event.returnValues.value).to.be.equal('49');299 },186300 },187 event = result.events.Approval;301 {188 expect(event.address).to.be.equal(tokenAddress);302 address,303 event: 'Approval',189 expect(event.returnValues.owner).to.be.equal(owner);304 args: {305 owner,306 spender,190 expect(event.returnValues.spender).to.be.equal(spender);307 value: '51',191 expect(event.returnValues.value).to.be.equal('51');308 },309 },310 ]);311 }192 }312193313 {194 {321 }202 }322 });203 });323204324 itWeb3('Can perform transfer()', async ({web3, api, privateKeyWrapper}) => {205 itEth('Can perform transfer()', async ({helper}) => {325 const alice = privateKeyWrapper('//Alice');206 const owner = await helper.eth.createAccountWithBalance(donor);207 const receiver = helper.eth.createAccount();208 const collection = await helper.rft.mintCollection(alice);209 const {tokenId} = await collection.mintToken(alice, 200n, {Ethereum: owner});326210327 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;211 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);212 const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);328213329 const owner = createEthAccount(web3);330 await transferBalanceToEth(api, alice, owner);331332 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;333334 const receiver = createEthAccount(web3);335 await transferBalanceToEth(api, alice, receiver);336337 const address = tokenIdToAddress(collectionId, tokenId);338 const contract = uniqueRefungibleToken(web3, address, owner);339340 {214 {341 const result = await contract.methods.transfer(receiver, 50).send({from: owner});215 const result = await contract.methods.transfer(receiver, 50).send({from: owner});342 const events = normalizeEvents(result.events);216 const event = result.events.Transfer;343 expect(events).to.include.deep.members([217 expect(event.address).to.be.equal(tokenAddress);344 {218 expect(event.returnValues.from).to.be.equal(owner);345 address,346 event: 'Transfer',347 args: {348 from: owner,349 to: receiver,219 expect(event.returnValues.to).to.be.equal(receiver);350 value: '50',220 expect(event.returnValues.value).to.be.equal('50');351 },352 },353 ]);354 }221 }355222356 {223 {364 }231 }365 });232 });366233367 itWeb3('Can perform repartition()', async ({web3, api, privateKeyWrapper}) => {234 itEth('Can perform repartition()', async ({helper}) => {368 const alice = privateKeyWrapper('//Alice');235 const owner = await helper.eth.createAccountWithBalance(donor);236 const receiver = await helper.eth.createAccountWithBalance(donor);237 const collection = await helper.rft.mintCollection(alice);238 const {tokenId} = await collection.mintToken(alice, 100n, {Ethereum: owner});369239370 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;240 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);241 const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);371242372 const owner = createEthAccount(web3);373 await transferBalanceToEth(api, alice, owner);374375 const receiver = createEthAccount(web3);376 await transferBalanceToEth(api, alice, receiver);377378 const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n, {Ethereum: owner})).itemId;379380 const address = tokenIdToAddress(collectionId, tokenId);381 const contract = uniqueRefungibleToken(web3, address, owner);382383 await contract.methods.repartition(200).send({from: owner});243 await contract.methods.repartition(200).send({from: owner});384 expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(200);244 expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(200);385 await contract.methods.transfer(receiver, 110).send({from: owner});245 await contract.methods.transfer(receiver, 110).send({from: owner});386 expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(90);246 expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(90);387 expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(110);247 expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(110);388248389 await expect(contract.methods.repartition(80).send({from: owner})).to.eventually.be.rejected;249 await expect(contract.methods.repartition(80).send({from: owner})).to.eventually.be.rejected; // Transaction is reverted390250391 await contract.methods.transfer(receiver, 90).send({from: owner});251 await contract.methods.transfer(receiver, 90).send({from: owner});392 expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(0);252 expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(0);393 expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(200);253 expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(200);394254395 await contract.methods.repartition(150).send({from: receiver});255 await contract.methods.repartition(150).send({from: receiver});396 await expect(contract.methods.transfer(owner, 160).send({from: receiver})).to.eventually.be.rejected;256 await expect(contract.methods.transfer(owner, 160).send({from: receiver})).to.eventually.be.rejected; // Transaction is reverted397 expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(150);257 expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(150);398 });258 });399259400 itWeb3('Can repartition with increased amount', async ({web3, api, privateKeyWrapper}) => {260 itEth('Can repartition with increased amount', async ({helper}) => {401 const alice = privateKeyWrapper('//Alice');261 const owner = await helper.eth.createAccountWithBalance(donor);262 const collection = await helper.rft.mintCollection(alice);263 const {tokenId} = await collection.mintToken(alice, 100n, {Ethereum: owner});402264403 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;265 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);266 const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);404267405 const owner = createEthAccount(web3);406 await transferBalanceToEth(api, alice, owner);407408 const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n, {Ethereum: owner})).itemId;409410 const address = tokenIdToAddress(collectionId, tokenId);411 const contract = uniqueRefungibleToken(web3, address, owner);412413 const result = await contract.methods.repartition(200).send();268 const result = await contract.methods.repartition(200).send();414 const events = normalizeEvents(result.events);415269416 expect(events).to.deep.equal([270 const event = result.events.Transfer;271 expect(event.address).to.be.equal(tokenAddress);417 {272 expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');418 address,419 event: 'Transfer',420 args: {421 from: '0x0000000000000000000000000000000000000000',422 to: owner,273 expect(event.returnValues.to).to.be.equal(owner);423 value: '100',274 expect(event.returnValues.value).to.be.equal('100');424 },425 },426 ]);427 });275 });428276429 itWeb3('Can repartition with decreased amount', async ({web3, api, privateKeyWrapper}) => {277 itEth('Can repartition with decreased amount', async ({helper}) => {430 const alice = privateKeyWrapper('//Alice');278 const owner = await helper.eth.createAccountWithBalance(donor);279 const collection = await helper.rft.mintCollection(alice);280 const {tokenId} = await collection.mintToken(alice, 100n, {Ethereum: owner});431281432 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;282 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);283 const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);433284434 const owner = createEthAccount(web3);435 await transferBalanceToEth(api, alice, owner);436437 const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n, {Ethereum: owner})).itemId;438439 const address = tokenIdToAddress(collectionId, tokenId);440 const contract = uniqueRefungibleToken(web3, address, owner);441442 const result = await contract.methods.repartition(50).send();285 const result = await contract.methods.repartition(50).send();443 const events = normalizeEvents(result.events);286 const event = result.events.Transfer;444 expect(events).to.deep.equal([287 expect(event.address).to.be.equal(tokenAddress);445 {288 expect(event.returnValues.from).to.be.equal(owner);446 address,447 event: 'Transfer',448 args: {449 from: owner,450 to: '0x0000000000000000000000000000000000000000',289 expect(event.returnValues.to).to.be.equal('0x0000000000000000000000000000000000000000');451 value: '50',290 expect(event.returnValues.value).to.be.equal('50');452 },453 },454 ]);455 });291 });456292457 itWeb3('Receiving Transfer event on burning into full ownership', async ({web3, api, privateKeyWrapper}) => {293 itEth('Receiving Transfer event on burning into full ownership', async ({helper}) => {458 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);294 const caller = await helper.eth.createAccountWithBalance(donor);459 const receiver = await createEthAccountWithBalance(api, web3, privateKeyWrapper);295 const receiver = await helper.eth.createAccountWithBalance(donor);460 const helper = evmCollectionHelpers(web3, caller);296 const {collectionId, collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'Devastation', '6', '6');461 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();462 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);297 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);463 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});464298465 const tokenId = await contract.methods.nextTokenId().call();299 const tokenId = await contract.methods.nextTokenId().call();466 await contract.methods.mint(caller, tokenId).send();300 await contract.methods.mint(caller, tokenId).send();301 const tokenAddress = helper.ethAddress.fromTokenId(collectionId, tokenId);302 const tokenContract = helper.ethNativeContract.rftToken(tokenAddress, caller);467303468 const address = tokenIdToAddress(collectionId, tokenId);469470 const tokenContract = uniqueRefungibleToken(web3, address, caller);471 await tokenContract.methods.repartition(2).send();304 await tokenContract.methods.repartition(2).send();472 await tokenContract.methods.transfer(receiver, 1).send();305 await tokenContract.methods.transfer(receiver, 1).send();473306474 const events = await recordEvents(contract, async () =>307 const events: any = [];308 contract.events.allEvents((_: any, event: any) => {475 await tokenContract.methods.burnFrom(caller, 1).send());309 events.push(event);476 expect(events).to.deep.equal([310 });311 await tokenContract.methods.burnFrom(caller, 1).send();312477 {313 const event = events[0];478 address: collectionIdAddress,479 event: 'Transfer',314 expect(event.address).to.be.equal(collectionAddress);480 args: {315 expect(event.returnValues.from).to.be.equal('0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF');481 from: '0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF',482 to: receiver,316 expect(event.returnValues.to).to.be.equal(receiver);483 tokenId,317 expect(event.returnValues.tokenId).to.be.equal(tokenId);484 },485 },486 ]);487 });318 });488});319});489320490describe('Refungible: Fees', () => {321describe('Refungible: Fees', () => {322 let donor: IKeyringPair;323 let alice: IKeyringPair;324491 before(async function() {325 before(async function() {492 await requirePallets(this, [Pallets.ReFungible]);326 await usingEthPlaygrounds(async (helper, privateKey) => {327 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);328329 donor = privateKey('//Alice');330 [alice] = await helper.arrange.createAccounts([50n], donor);331 });493 });332 });494333495 itWeb3('approve() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {334 itEth('approve() call fee is less than 0.2UNQ', async ({helper}) => {496 const alice = privateKeyWrapper('//Alice');335 const owner = await helper.eth.createAccountWithBalance(donor);336 const spender = helper.eth.createAccount();337 const collection = await helper.rft.mintCollection(alice);338 const {tokenId} = await collection.mintToken(alice, 100n, {Ethereum: owner});497339498 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;340 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);341 const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);499342500 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);343 const cost = await helper.eth.recordCallFee(owner, () => contract.methods.approve(spender, 100).send({from: owner}));501 const spender = createEthAccount(web3);502503 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;504505 const address = tokenIdToAddress(collectionId, tokenId);506 const contract = uniqueRefungibleToken(web3, address, owner);507508 const cost = await recordEthFee(api, owner, () => contract.methods.approve(spender, 100).send({from: owner}));509 expect(cost < BigInt(0.2 * Number(UNIQUE)));344 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));510 });345 });511346512 itWeb3('transferFrom() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {347 itEth('transferFrom() call fee is less than 0.2UNQ', async ({helper}) => {513 const alice = privateKeyWrapper('//Alice');348 const owner = await helper.eth.createAccountWithBalance(donor);349 const spender = await helper.eth.createAccountWithBalance(donor);350 const collection = await helper.rft.mintCollection(alice);351 const {tokenId} = await collection.mintToken(alice, 200n, {Ethereum: owner});514352515 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;353 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);354 const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);516355517 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);518 const spender = await createEthAccountWithBalance(api, web3, privateKeyWrapper);519520 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;521522 const address = tokenIdToAddress(collectionId, tokenId);523 const contract = uniqueRefungibleToken(web3, address, owner);524525 await contract.methods.approve(spender, 100).send({from: owner});356 await contract.methods.approve(spender, 100).send({from: owner});526357527 const cost = await recordEthFee(api, spender, () => contract.methods.transferFrom(owner, spender, 100).send({from: spender}));358 const cost = await helper.eth.recordCallFee(spender, () => contract.methods.transferFrom(owner, spender, 100).send({from: spender}));528 expect(cost < BigInt(0.2 * Number(UNIQUE)));359 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));529 });360 });530361531 itWeb3('transfer() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {362 itEth('transfer() call fee is less than 0.2UNQ', async ({helper}) => {532 const alice = privateKeyWrapper('//Alice');363 const owner = await helper.eth.createAccountWithBalance(donor);364 const receiver = helper.eth.createAccount();365 const collection = await helper.rft.mintCollection(alice);366 const {tokenId} = await collection.mintToken(alice, 200n, {Ethereum: owner});533367534 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;368 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);369 const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);535370536 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);371 const cost = await helper.eth.recordCallFee(owner, () => contract.methods.transfer(receiver, 100).send({from: owner}));537 const receiver = createEthAccount(web3);538539 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;540541 const address = tokenIdToAddress(collectionId, tokenId);542 const contract = uniqueRefungibleToken(web3, address, owner);543544 const cost = await recordEthFee(api, owner, () => contract.methods.transfer(receiver, 100).send({from: owner}));545 expect(cost < BigInt(0.2 * Number(UNIQUE)));372 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));546 });373 });547});374});548375549describe('Refungible: Substrate calls', () => {376describe('Refungible: Substrate calls', () => {377 let donor: IKeyringPair;378 let alice: IKeyringPair;379550 before(async function() {380 before(async function() {551 await requirePallets(this, [Pallets.ReFungible]);381 await usingEthPlaygrounds(async (helper, privateKey) => {382 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);383384 donor = privateKey('//Alice');385 [alice] = await helper.arrange.createAccounts([50n], donor);386 });552 });387 });553388554 itWeb3('Events emitted for approve()', async ({web3, api, privateKeyWrapper}) => {389 itEth('Events emitted for approve()', async ({helper}) => {555 const alice = privateKeyWrapper('//Alice');390 const receiver = helper.eth.createAccount();391 const collection = await helper.rft.mintCollection(alice);392 const token = await collection.mintToken(alice, 200n);556393557 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;394 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, token.tokenId);395 const contract = helper.ethNativeContract.rftToken(tokenAddress);558396559 const receiver = createEthAccount(web3);397 const events: any = [];560561 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;562563 const address = tokenIdToAddress(collectionId, tokenId);398 contract.events.allEvents((_: any, event: any) => {564 const contract = uniqueRefungibleToken(web3, address);565566 const events = await recordEvents(contract, async () => {567 expect(await approve(api, collectionId, tokenId, alice, {Ethereum: receiver}, 100n)).to.be.true;399 events.push(event);568 });400 });401 expect(await token.approve(alice, {Ethereum: receiver}, 100n)).to.be.true;569402570 expect(events).to.be.deep.equal([403 const event = events[0];571 {572 address,573 event: 'Approval',404 expect(event.event).to.be.equal('Approval');574 args: {405 expect(event.address).to.be.equal(tokenAddress);575 owner: subToEth(alice.address),406 expect(event.returnValues.owner).to.be.equal(helper.address.substrateToEth(alice.address));576 spender: receiver,407 expect(event.returnValues.spender).to.be.equal(receiver);577 value: '100',408 expect(event.returnValues.value).to.be.equal('100');578 },579 },580 ]);581 });409 });582410583 itWeb3('Events emitted for transferFrom()', async ({web3, api, privateKeyWrapper}) => {411 itEth('Events emitted for transferFrom()', async ({helper}) => {584 const alice = privateKeyWrapper('//Alice');412 const [bob] = await helper.arrange.createAccounts([10n], donor);413 const receiver = helper.eth.createAccount();414 const collection = await helper.rft.mintCollection(alice);415 const token = await collection.mintToken(alice, 200n);416 await token.approve(alice, {Substrate: bob.address}, 100n);585417586 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;418 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, token.tokenId);587 const bob = privateKeyWrapper('//Bob');419 const contract = helper.ethNativeContract.rftToken(tokenAddress);588420589 const receiver = createEthAccount(web3);421 const events: any = [];422 contract.events.allEvents((_: any, event: any) => {423 events.push(event);424 });590425591 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;426 expect(await token.transferFrom(bob, {Substrate: alice.address}, {Ethereum: receiver}, 51n)).to.be.true;592 expect(await approve(api, collectionId, tokenId, alice, bob.address, 100n)).to.be.true;593427594 const address = tokenIdToAddress(collectionId, tokenId);428 let event = events[0];429 expect(event.event).to.be.equal('Transfer');430 expect(event.address).to.be.equal(tokenAddress);595 const contract = uniqueRefungibleToken(web3, address);431 expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));432 expect(event.returnValues.to).to.be.equal(receiver);433 expect(event.returnValues.value).to.be.equal('51');596434597 const events = await recordEvents(contract, async () => {435 event = events[1];598 expect(await transferFrom(api, collectionId, tokenId, bob, alice, {Ethereum: receiver}, 51n)).to.be.true;436 expect(event.event).to.be.equal('Approval');599 });600601 expect(events).to.be.deep.equal([437 expect(event.address).to.be.equal(tokenAddress);602 {438 expect(event.returnValues.owner).to.be.equal(helper.address.substrateToEth(alice.address));603 address,604 event: 'Transfer',605 args: {606 from: subToEth(alice.address),607 to: receiver,608 value: '51',609 },610 },611 {612 address,613 event: 'Approval',614 args: {615 owner: subToEth(alice.address),616 spender: subToEth(bob.address),439 expect(event.returnValues.spender).to.be.equal(helper.address.substrateToEth(bob.address));617 value: '49',440 expect(event.returnValues.value).to.be.equal('49');618 },619 },620 ]);621 });441 });622442623 itWeb3('Events emitted for transfer()', async ({web3, api, privateKeyWrapper}) => {443 itEth('Events emitted for transfer()', async ({helper}) => {624 const alice = privateKeyWrapper('//Alice');444 const receiver = helper.eth.createAccount();445 const collection = await helper.rft.mintCollection(alice);446 const token = await collection.mintToken(alice, 200n);625447626 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;448 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, token.tokenId);449 const contract = helper.ethNativeContract.rftToken(tokenAddress);627450628 const receiver = createEthAccount(web3);451 const events: any = [];629630 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;631632 const address = tokenIdToAddress(collectionId, tokenId);452 contract.events.allEvents((_: any, event: any) => {633 const contract = uniqueRefungibleToken(web3, address);634635 const events = await recordEvents(contract, async () => {636 expect(await transfer(api, collectionId, tokenId, alice, {Ethereum: receiver}, 51n)).to.be.true;453 events.push(event);637 });454 });638455639 expect(events).to.be.deep.equal([456 expect(await token.transfer(alice, {Ethereum: receiver}, 51n)).to.be.true;640 {457641 address,458 const event = events[0];642 event: 'Transfer',459 expect(event.event).to.be.equal('Transfer');643 args: {460 expect(event.address).to.be.equal(tokenAddress);644 from: subToEth(alice.address),461 expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));645 to: receiver,462 expect(event.returnValues.to).to.be.equal(receiver);646 value: '51',463 expect(event.returnValues.value).to.be.equal('51');647 },648 },649 ]);650 });464 });651});465});652466653describe('ERC 1633 implementation', () => {467describe('ERC 1633 implementation', () => {468 let donor: IKeyringPair;469654 before(async function() {470 before(async function() {655 await requirePallets(this, [Pallets.ReFungible]);471 await usingEthPlaygrounds(async (helper, privateKey) => {656 });472 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);657473658 itWeb3('Default parent token address and id', async ({api, web3, privateKeyWrapper}) => {474 donor = privateKey('//Alice');475 });659 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);476 });660477661 const {collectionIdAddress, collectionId} = await createRFTCollection(api, web3, owner);478 itEth('Default parent token address and id', async ({helper}) => {662 const refungibleContract = uniqueRefungible(web3, collectionIdAddress, owner);663 const refungibleTokenId = await refungibleContract.methods.nextTokenId().call();479 const owner = await helper.eth.createAccountWithBalance(donor);664 await refungibleContract.methods.mint(owner, refungibleTokenId).send();665480666 const rftTokenAddress = tokenIdToAddress(collectionId, refungibleTokenId);481 const {collectionId, collectionAddress} = await helper.eth.createRefungibleCollection(owner, 'Sands', '', 'GRAIN');667 const refungibleTokenContract = uniqueRefungibleToken(web3, rftTokenAddress, owner);482 const collectionContract = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);483 484 const tokenId = await collectionContract.methods.nextTokenId().call();485 await collectionContract.methods.mint(owner, tokenId).send();486 const tokenAddress = helper.ethAddress.fromTokenId(collectionId, tokenId);487 const tokenContract = helper.ethNativeContract.rftToken(tokenAddress, owner);668488669 const tokenAddress = await refungibleTokenContract.methods.parentToken().call();489 expect(await tokenContract.methods.parentToken().call()).to.be.equal(collectionAddress);670 const tokenId = await refungibleTokenContract.methods.parentTokenId().call();490 expect(await tokenContract.methods.parentTokenId().call()).to.be.equal(tokenId);671 expect(tokenAddress).to.be.equal(collectionIdAddress);672 expect(tokenId).to.be.equal(refungibleTokenId);673 });491 });674});492});675493tests/src/eth/util/playgrounds/unique.dev.tsdiffbeforeafterboth117 return new web3.eth.Contract(abi as any, address, {gas: this.helper.eth.DEFAULT_GAS, ...(caller ? {from: caller} : {})});117 return new web3.eth.Contract(abi as any, address, {gas: this.helper.eth.DEFAULT_GAS, ...(caller ? {from: caller} : {})});118 }118 }119120 collectionById(collectionId: number, mode: 'nft' | 'rft' | 'ft', caller?: string): Contract {121 return this.collection(this.helper.ethAddress.fromCollectionId(collectionId), mode, caller);122 }119123120 rftTokenByAddress(address: string, caller?: string): Contract {124 rftToken(address: string, caller?: string): Contract {121 const web3 = this.helper.getWeb3();125 const web3 = this.helper.getWeb3();122 return new web3.eth.Contract(refungibleTokenAbi as any, address, {gas: this.helper.eth.DEFAULT_GAS, ...(caller ? {from: caller} : {})});126 return new web3.eth.Contract(refungibleTokenAbi as any, address, {gas: this.helper.eth.DEFAULT_GAS, ...(caller ? {from: caller} : {})});123 }127 }124128125 rftToken(collectionId: number, tokenId: number, caller?: string): Contract {129 rftTokenById(collectionId: number, tokenId: number, caller?: string): Contract {126 return this.rftTokenByAddress(this.helper.ethAddress.fromTokenId(collectionId, tokenId), caller);130 return this.rftToken(this.helper.ethAddress.fromTokenId(collectionId, tokenId), caller);127 }131 }128}132}129133176 return {collectionId, collectionAddress};180 return {collectionId, collectionAddress};177 }181 }182183 async createRefungibleCollection(signer: string, name: string, description: string, tokenPrefix: string): Promise<{collectionId: number, collectionAddress: string}> {184 const collectionHelper = this.helper.ethNativeContract.collectionHelpers(signer);185 186 const result = await collectionHelper.methods.createRFTCollection(name, description, tokenPrefix).send();187188 const collectionAddress = this.helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);189 const collectionId = this.helper.ethAddress.extractCollectionId(collectionAddress);190191 return {collectionId, collectionAddress};192 }178193179 async deployCollectorContract(signer: string): Promise<Contract> {194 async deployCollectorContract(signer: string): Promise<Contract> {180 return await this.helper.ethContract.deployByCode(signer, 'Collector', `195 return await this.helper.ethContract.deployByCode(signer, 'Collector', `221 `);236 `);222 }237 }238239 async recordCallFee(user: string, call: () => Promise<any>): Promise<bigint> {240 const before = await this.helper.balance.getEthereum(user);241 await call();242 // In dev mode, the transaction might not finish processing in time243 await this.helper.wait.newBlocks(1);244 const after = await this.helper.balance.getEthereum(user);245246 return before - after;247 }223} 248} 224 249 225class EthAddressGroup extends EthGroupBase {250class EthAddressGroup extends EthGroupBase {