difftreelog
tests(eth): NFT, RFT, FT tests refactored for playgrounds
in: master
6 files changed
tests/package.jsondiffbeforeafterboth--- a/tests/package.json
+++ b/tests/package.json
@@ -87,8 +87,11 @@
"testLimits": "mocha --timeout 9999999 -r ts-node/register ./**/limits.test.ts",
"testEthCreateNFTCollection": "mocha --timeout 9999999 -r ts-node/register ./**/eth/createNFTCollection.test.ts",
"testEthCreateRFTCollection": "mocha --timeout 9999999 -r ts-node/register ./**/eth/createRFTCollection.test.ts",
+ "testEthNFT": "mocha --timeout 9999999 -r ts-node/register ./**/eth/nonFungible.test.ts",
"testRFT": "mocha --timeout 9999999 -r ts-node/register ./**/refungible.test.ts",
+ "testEthRFT": "mocha --timeout 9999999 -r ts-node/register ./**/eth/reFungible.test.ts ./**/eth/reFungibleToken.test.ts",
"testFT": "mocha --timeout 9999999 -r ts-node/register ./**/fungible.test.ts",
+ "testEthFT": "mocha --timeout 9999999 -r ts-node/register ./**/eth/fungible.test.ts",
"testRPC": "mocha --timeout 9999999 -r ts-node/register ./**/rpc.test.ts",
"testPromotion": "mocha --timeout 9999999 -r ts-node/register ./**/app-promotion.test.ts",
"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.tsdiffbeforeafterboth--- a/tests/src/eth/fungible.test.ts
+++ b/tests/src/eth/fungible.test.ts
@@ -14,204 +14,132 @@
// You should have received a copy of the GNU General Public License
// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-import {approveExpectSuccess, createCollection, createCollectionExpectSuccess, createFungibleItemExpectSuccess, transferExpectSuccess, transferFromExpectSuccess, UNIQUE} from '../util/helpers';
-import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, evmCollection, GAS_ARGS, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, transferBalanceToEth} from './util/helpers';
-import fungibleAbi from './fungibleAbi.json';
-import {expect} from 'chai';
-import {submitTransactionAsync} from '../substrate/substrate-api';
+import {expect, itEth, usingEthPlaygrounds} from './util/playgrounds';
+import {IKeyringPair} from '@polkadot/types/types';
describe('Fungible: Information getting', () => {
- itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- name: 'token name',
- mode: {type: 'Fungible', decimalPoints: 0},
+ let donor: IKeyringPair;
+ let alice: IKeyringPair;
+
+ before(async function() {
+ await usingEthPlaygrounds(async (helper, privateKey) => {
+ donor = privateKey('//Alice');
+ [alice] = await helper.arrange.createAccounts([20n], donor);
});
- const alice = privateKeyWrapper('//Alice');
+ });
- const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+ itEth('totalSupply', async ({helper}) => {
+ const caller = await helper.eth.createAccountWithBalance(donor);
+ const collection = await helper.ft.mintCollection(alice);
+ await collection.mint(alice, 200n);
- await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Substrate: alice.address});
-
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS});
+ const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'ft', caller);
const totalSupply = await contract.methods.totalSupply().call();
-
expect(totalSupply).to.equal('200');
});
- itWeb3('balanceOf', async ({api, web3, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- name: 'token name',
- mode: {type: 'Fungible', decimalPoints: 0},
- });
- const alice = privateKeyWrapper('//Alice');
+ itEth('balanceOf', async ({helper}) => {
+ const caller = await helper.eth.createAccountWithBalance(donor);
+ const collection = await helper.ft.mintCollection(alice);
+ await collection.mint(alice, 200n, {Ethereum: caller});
- const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
-
- await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: caller});
-
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS});
+ const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'ft', caller);
const balance = await contract.methods.balanceOf(caller).call();
-
expect(balance).to.equal('200');
});
});
describe('Fungible: Plain calls', () => {
- itWeb3('Can perform mint()', async ({web3, api, privateKeyWrapper}) => {
- const alice = privateKeyWrapper('//Alice');
- const collection = await createCollection(api, alice, {
- name: 'token name',
- mode: {type: 'Fungible', decimalPoints: 0},
+ let donor: IKeyringPair;
+ let alice: IKeyringPair;
+
+ before(async function() {
+ await usingEthPlaygrounds(async (helper, privateKey) => {
+ donor = privateKey('//Alice');
+ [alice] = await helper.arrange.createAccounts([20n], donor);
});
+ });
- const receiver = createEthAccount(web3);
+ itEth('Can perform mint()', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const receiver = helper.eth.createAccount();
+ const collection = await helper.ft.mintCollection(alice);
+ await collection.addAdmin(alice, {Ethereum: owner});
- const collectionIdAddress = collectionIdToAddress(collection.collectionId);
- const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const changeAdminTx = api.tx.unique.addCollectionAdmin(collection.collectionId, {Ethereum: owner});
- await submitTransactionAsync(alice, changeAdminTx);
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);
- const collectionContract = evmCollection(web3, owner, collectionIdAddress, {type: 'Fungible', decimalPoints: 0});
- const result = await collectionContract.methods.mint(receiver, 100).send();
- const events = normalizeEvents(result.events);
+ const result = await contract.methods.mint(receiver, 100).send();
- expect(events).to.be.deep.equal([
- {
- address: collectionIdAddress,
- event: 'Transfer',
- args: {
- from: '0x0000000000000000000000000000000000000000',
- to: receiver,
- value: '100',
- },
- },
- ]);
+ const event = result.events.Transfer;
+ expect(event.address).to.equal(collectionAddress);
+ expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');
+ expect(event.returnValues.to).to.equal(receiver);
+ expect(event.returnValues.value).to.equal('100');
});
-
- itWeb3('Can perform mintBulk()', async ({web3, api, privateKeyWrapper}) => {
- const alice = privateKeyWrapper('//Alice');
- const collection = await createCollection(api, alice, {
- name: 'token name',
- mode: {type: 'Fungible', decimalPoints: 0},
- });
- const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const receiver1 = createEthAccount(web3);
- const receiver2 = createEthAccount(web3);
- const receiver3 = createEthAccount(web3);
-
- const collectionIdAddress = collectionIdToAddress(collection.collectionId);
- const changeAdminTx = api.tx.unique.addCollectionAdmin(collection.collectionId, {Ethereum: owner});
- await submitTransactionAsync(alice, changeAdminTx);
+ itEth('Can perform mintBulk()', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const bulkSize = 3;
+ const receivers = [...new Array(bulkSize)].map(() => helper.eth.createAccount());
+ const collection = await helper.ft.mintCollection(alice);
+ await collection.addAdmin(alice, {Ethereum: owner});
- const collectionContract = evmCollection(web3, owner, collectionIdAddress, {type: 'Fungible', decimalPoints: 0});
- const result = await collectionContract.methods.mintBulk([
- [receiver1, 10],
- [receiver2, 20],
- [receiver3, 30],
- ]).send();
- const events = normalizeEvents(result.events);
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);
- expect(events).to.be.deep.contain({
- address:collectionIdAddress,
- event: 'Transfer',
- args: {
- from: '0x0000000000000000000000000000000000000000',
- to: receiver1,
- value: '10',
- },
- });
-
- expect(events).to.be.deep.contain({
- address:collectionIdAddress,
- event: 'Transfer',
- args: {
- from: '0x0000000000000000000000000000000000000000',
- to: receiver2,
- value: '20',
- },
- });
-
- expect(events).to.be.deep.contain({
- address:collectionIdAddress,
- event: 'Transfer',
- args: {
- from: '0x0000000000000000000000000000000000000000',
- to: receiver3,
- value: '30',
- },
- });
+ const result = await contract.methods.mintBulk(Array.from({length: bulkSize}, (_, i) => (
+ [receivers[i], (i + 1) * 10]
+ ))).send();
+ const events = result.events.Transfer.sort((a: any, b: any) => +a.returnValues.value - b.returnValues.value);
+ for (let i = 0; i < bulkSize; i++) {
+ const event = events[i];
+ expect(event.address).to.equal(collectionAddress);
+ expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');
+ expect(event.returnValues.to).to.equal(receivers[i]);
+ expect(event.returnValues.value).to.equal(String(10 * (i + 1)));
+ }
});
- itWeb3('Can perform burn()', async ({web3, api, privateKeyWrapper}) => {
- const alice = privateKeyWrapper('//Alice');
- const collection = await createCollection(api, alice, {
- name: 'token name',
- mode: {type: 'Fungible', decimalPoints: 0},
- });
-
- const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const changeAdminTx = api.tx.unique.addCollectionAdmin(collection.collectionId, {Ethereum: owner});
- await submitTransactionAsync(alice, changeAdminTx);
- const receiver = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+ itEth('Can perform burn()', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const receiver = await helper.eth.createAccountWithBalance(donor);
+ const collection = await helper.ft.mintCollection(alice);
+ await collection.addAdmin(alice, {Ethereum: owner});
- const collectionIdAddress = collectionIdToAddress(collection.collectionId);
- const collectionContract = evmCollection(web3, owner, collectionIdAddress, {type: 'Fungible', decimalPoints: 0});
- await collectionContract.methods.mint(receiver, 100).send();
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);
+ await contract.methods.mint(receiver, 100).send();
- const result = await collectionContract.methods.burnFrom(receiver, 49).send({from: receiver});
+ const result = await contract.methods.burnFrom(receiver, 49).send({from: receiver});
- const events = normalizeEvents(result.events);
-
- expect(events).to.be.deep.equal([
- {
- address: collectionIdAddress,
- event: 'Transfer',
- args: {
- from: receiver,
- to: '0x0000000000000000000000000000000000000000',
- value: '49',
- },
- },
- ]);
+ const event = result.events.Transfer;
+ expect(event.address).to.equal(collectionAddress);
+ expect(event.returnValues.from).to.equal(receiver);
+ expect(event.returnValues.to).to.equal('0x0000000000000000000000000000000000000000');
+ expect(event.returnValues.value).to.equal('49');
- const balance = await collectionContract.methods.balanceOf(receiver).call();
+ const balance = await contract.methods.balanceOf(receiver).call();
expect(balance).to.equal('51');
});
- itWeb3('Can perform approve()', async ({web3, api, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- name: 'token name',
- mode: {type: 'Fungible', decimalPoints: 0},
- });
- const alice = privateKeyWrapper('//Alice');
+ itEth('Can perform approve()', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const spender = helper.eth.createAccount();
+ const collection = await helper.ft.mintCollection(alice);
+ await collection.mint(alice, 200n, {Ethereum: owner});
- const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
-
- await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});
-
- const spender = createEthAccount(web3);
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: owner, ...GAS_ARGS});
-
{
const result = await contract.methods.approve(spender, 100).send({from: owner});
- const events = normalizeEvents(result.events);
- expect(events).to.be.deep.equal([
- {
- address,
- event: 'Approval',
- args: {
- owner,
- spender,
- value: '100',
- },
- },
- ]);
+ const event = result.events.Approval;
+ expect(event.address).to.be.equal(collectionAddress);
+ expect(event.returnValues.owner).to.be.equal(owner);
+ expect(event.returnValues.spender).to.be.equal(spender);
+ expect(event.returnValues.value).to.be.equal('100');
}
{
@@ -220,51 +148,32 @@
}
});
- itWeb3('Can perform transferFrom()', async ({web3, api, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- name: 'token name',
- mode: {type: 'Fungible', decimalPoints: 0},
- });
- const alice = privateKeyWrapper('//Alice');
-
- const owner = createEthAccount(web3);
- await transferBalanceToEth(api, alice, owner);
-
- await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});
-
- const spender = createEthAccount(web3);
- await transferBalanceToEth(api, alice, spender);
-
- const receiver = createEthAccount(web3);
+ itEth('Can perform transferFrom()', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const spender = await helper.eth.createAccountWithBalance(donor);
+ const receiver = helper.eth.createAccount();
+ const collection = await helper.ft.mintCollection(alice);
+ await collection.mint(alice, 200n, {Ethereum: owner});
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: owner, ...GAS_ARGS});
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);
await contract.methods.approve(spender, 100).send();
{
const result = await contract.methods.transferFrom(owner, receiver, 49).send({from: spender});
- const events = normalizeEvents(result.events);
- expect(events).to.be.deep.equal([
- {
- address,
- event: 'Transfer',
- args: {
- from: owner,
- to: receiver,
- value: '49',
- },
- },
- {
- address,
- event: 'Approval',
- args: {
- owner,
- spender,
- value: '51',
- },
- },
- ]);
+
+ let event = result.events.Transfer;
+ expect(event.address).to.be.equal(collectionAddress);
+ expect(event.returnValues.from).to.be.equal(owner);
+ expect(event.returnValues.to).to.be.equal(receiver);
+ expect(event.returnValues.value).to.be.equal('49');
+
+ event = result.events.Approval;
+ expect(event.address).to.be.equal(collectionAddress);
+ expect(event.returnValues.owner).to.be.equal(owner);
+ expect(event.returnValues.spender).to.be.equal(spender);
+ expect(event.returnValues.value).to.be.equal('51');
}
{
@@ -278,38 +187,23 @@
}
});
- itWeb3('Can perform transfer()', async ({web3, api, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- name: 'token name',
- mode: {type: 'Fungible', decimalPoints: 0},
- });
- const alice = privateKeyWrapper('//Alice');
-
- const owner = createEthAccount(web3);
- await transferBalanceToEth(api, alice, owner);
-
- await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});
-
- const receiver = createEthAccount(web3);
- await transferBalanceToEth(api, alice, receiver);
+ itEth('Can perform transfer()', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const receiver = await helper.eth.createAccountWithBalance(donor);
+ const collection = await helper.ft.mintCollection(alice);
+ await collection.mint(alice, 200n, {Ethereum: owner});
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: owner, ...GAS_ARGS});
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);
{
const result = await contract.methods.transfer(receiver, 50).send({from: owner});
- const events = normalizeEvents(result.events);
- expect(events).to.be.deep.equal([
- {
- address,
- event: 'Transfer',
- args: {
- from: owner,
- to: receiver,
- value: '50',
- },
- },
- ]);
+
+ const event = result.events.Transfer;
+ expect(event.address).to.be.equal(collectionAddress);
+ expect(event.returnValues.from).to.be.equal(owner);
+ expect(event.returnValues.to).to.be.equal(receiver);
+ expect(event.returnValues.value).to.be.equal('50');
}
{
@@ -325,162 +219,141 @@
});
describe('Fungible: Fees', () => {
- itWeb3('approve() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- mode: {type: 'Fungible', decimalPoints: 0},
+ let donor: IKeyringPair;
+ let alice: IKeyringPair;
+
+ before(async function() {
+ await usingEthPlaygrounds(async (helper, privateKey) => {
+ donor = privateKey('//Alice');
+ [alice] = await helper.arrange.createAccounts([20n], donor);
});
- const alice = privateKeyWrapper('//Alice');
+ });
+
+ itEth('approve() call fee is less than 0.2UNQ', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const spender = helper.eth.createAccount();
+ const collection = await helper.ft.mintCollection(alice);
+ await collection.mint(alice, 200n, {Ethereum: owner});
- const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const spender = createEthAccount(web3);
-
- await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: owner, ...GAS_ARGS});
-
- const cost = await recordEthFee(api, owner, () => contract.methods.approve(spender, 100).send({from: owner}));
- expect(cost < BigInt(0.2 * Number(UNIQUE)));
+ const cost = await helper.eth.recordCallFee(owner, () => contract.methods.approve(spender, 100).send({from: owner}));
+ expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));
});
- itWeb3('transferFrom() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- mode: {type: 'Fungible', decimalPoints: 0},
- });
- const alice = privateKeyWrapper('//Alice');
-
- const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const spender = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
-
- await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});
+ itEth('transferFrom() call fee is less than 0.2UNQ', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const spender = await helper.eth.createAccountWithBalance(donor);
+ const collection = await helper.ft.mintCollection(alice);
+ await collection.mint(alice, 200n, {Ethereum: owner});
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: owner, ...GAS_ARGS});
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);
await contract.methods.approve(spender, 100).send({from: owner});
- const cost = await recordEthFee(api, spender, () => contract.methods.transferFrom(owner, spender, 100).send({from: spender}));
- expect(cost < BigInt(0.2 * Number(UNIQUE)));
+ const cost = await helper.eth.recordCallFee(spender, () => contract.methods.transferFrom(owner, spender, 100).send({from: spender}));
+ expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));
});
-
- itWeb3('transfer() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- mode: {type: 'Fungible', decimalPoints: 0},
- });
- const alice = privateKeyWrapper('//Alice');
- const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const receiver = createEthAccount(web3);
-
- await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});
+ itEth('transfer() call fee is less than 0.2UNQ', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const receiver = helper.eth.createAccount();
+ const collection = await helper.ft.mintCollection(alice);
+ await collection.mint(alice, 200n, {Ethereum: owner});
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: owner, ...GAS_ARGS});
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);
- const cost = await recordEthFee(api, owner, () => contract.methods.transfer(receiver, 100).send({from: owner}));
- expect(cost < BigInt(0.2 * Number(UNIQUE)));
+ const cost = await helper.eth.recordCallFee(owner, () => contract.methods.transfer(receiver, 100).send({from: owner}));
+ expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));
});
});
describe('Fungible: Substrate calls', () => {
- itWeb3('Events emitted for approve()', async ({web3, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- mode: {type: 'Fungible', decimalPoints: 0},
+ let donor: IKeyringPair;
+ let alice: IKeyringPair;
+
+ before(async function() {
+ await usingEthPlaygrounds(async (helper, privateKey) => {
+ donor = privateKey('//Alice');
+ [alice] = await helper.arrange.createAccounts([20n], donor);
});
- const alice = privateKeyWrapper('//Alice');
+ });
- const receiver = createEthAccount(web3);
+ itEth('Events emitted for approve()', async ({helper}) => {
+ const receiver = helper.eth.createAccount();
+ const collection = await helper.ft.mintCollection(alice);
+ await collection.mint(alice, 200n);
- await createFungibleItemExpectSuccess(alice, collection, {Value: 200n});
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'ft');
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(fungibleAbi as any, address);
-
- const events = await recordEvents(contract, async () => {
- await approveExpectSuccess(collection, 0, alice, {Ethereum: receiver}, 100);
+ const events: any = [];
+ contract.events.allEvents((_: any, event: any) => {
+ events.push(event);
});
+ await collection.approveTokens(alice, {Ethereum: receiver}, 100n);
- expect(events).to.be.deep.equal([
- {
- address,
- event: 'Approval',
- args: {
- owner: subToEth(alice.address),
- spender: receiver,
- value: '100',
- },
- },
- ]);
+ const event = events[0];
+ expect(event.event).to.be.equal('Approval');
+ expect(event.address).to.be.equal(collectionAddress);
+ expect(event.returnValues.owner).to.be.equal(helper.address.substrateToEth(alice.address));
+ expect(event.returnValues.spender).to.be.equal(receiver);
+ expect(event.returnValues.value).to.be.equal('100');
});
- itWeb3('Events emitted for transferFrom()', async ({web3, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- mode: {type: 'Fungible', decimalPoints: 0},
- });
- const alice = privateKeyWrapper('//Alice');
- const bob = privateKeyWrapper('//Bob');
+ itEth('Events emitted for transferFrom()', async ({helper}) => {
+ const [bob] = await helper.arrange.createAccounts([10n], donor);
+ const receiver = helper.eth.createAccount();
+ const collection = await helper.ft.mintCollection(alice);
+ await collection.mint(alice, 200n);
+ await collection.approveTokens(alice, {Substrate: bob.address}, 100n);
- const receiver = createEthAccount(web3);
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'ft');
- await createFungibleItemExpectSuccess(alice, collection, {Value: 200n});
- await approveExpectSuccess(collection, 0, alice, bob.address, 100);
+ const events: any = [];
+ contract.events.allEvents((_: any, event: any) => {
+ events.push(event);
+ });
+ await collection.transferFrom(bob, {Substrate: alice.address}, {Ethereum: receiver}, 51n);
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(fungibleAbi as any, address);
+ let event = events[0];
+ expect(event.event).to.be.equal('Transfer');
+ expect(event.address).to.be.equal(collectionAddress);
+ expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));
+ expect(event.returnValues.to).to.be.equal(receiver);
+ expect(event.returnValues.value).to.be.equal('51');
- const events = await recordEvents(contract, async () => {
- await transferFromExpectSuccess(collection, 0, bob, alice, {Ethereum: receiver}, 51, 'Fungible');
- });
-
- expect(events).to.be.deep.equal([
- {
- address,
- event: 'Transfer',
- args: {
- from: subToEth(alice.address),
- to: receiver,
- value: '51',
- },
- },
- {
- address,
- event: 'Approval',
- args: {
- owner: subToEth(alice.address),
- spender: subToEth(bob.address),
- value: '49',
- },
- },
- ]);
+ event = events[1];
+ expect(event.event).to.be.equal('Approval');
+ expect(event.address).to.be.equal(collectionAddress);
+ expect(event.returnValues.owner).to.be.equal(helper.address.substrateToEth(alice.address));
+ expect(event.returnValues.spender).to.be.equal(helper.address.substrateToEth(bob.address));
+ expect(event.returnValues.value).to.be.equal('49');
});
- itWeb3('Events emitted for transfer()', async ({web3, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- mode: {type: 'Fungible', decimalPoints: 0},
- });
- const alice = privateKeyWrapper('//Alice');
+ itEth('Events emitted for transfer()', async ({helper}) => {
+ const receiver = helper.eth.createAccount();
+ const collection = await helper.ft.mintCollection(alice);
+ await collection.mint(alice, 200n);
- const receiver = createEthAccount(web3);
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'ft');
- await createFungibleItemExpectSuccess(alice, collection, {Value: 200n});
-
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(fungibleAbi as any, address);
-
- const events = await recordEvents(contract, async () => {
- await transferExpectSuccess(collection, 0, alice, {Ethereum:receiver}, 51, 'Fungible');
+ const events: any = [];
+ contract.events.allEvents((_: any, event: any) => {
+ events.push(event);
});
+ await collection.transfer(alice, {Ethereum:receiver}, 51n);
- expect(events).to.be.deep.equal([
- {
- address,
- event: 'Transfer',
- args: {
- from: subToEth(alice.address),
- to: receiver,
- value: '51',
- },
- },
- ]);
+ const event = events[0];
+ expect(event.event).to.be.equal('Transfer');
+ expect(event.address).to.be.equal(collectionAddress);
+ expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));
+ expect(event.returnValues.to).to.be.equal(receiver);
+ expect(event.returnValues.value).to.be.equal('51');
});
});
tests/src/eth/nonFungible.test.tsdiffbeforeafterboth--- a/tests/src/eth/nonFungible.test.ts
+++ b/tests/src/eth/nonFungible.test.ts
@@ -14,72 +14,78 @@
// You should have received a copy of the GNU General Public License
// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-import {approveExpectSuccess, burnItemExpectSuccess, createCollectionExpectSuccess, createItemExpectSuccess, transferExpectSuccess, transferFromExpectSuccess, UNIQUE} from '../util/helpers';
-import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, evmCollection, evmCollectionHelpers, GAS_ARGS, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, transferBalanceToEth} from './util/helpers';
-import nonFungibleAbi from './nonFungibleAbi.json';
-import {expect} from 'chai';
-import {submitTransactionAsync} from '../substrate/substrate-api';
+import {itEth, usingEthPlaygrounds, expect, EthUniqueHelper} from './util/playgrounds';
+import {IKeyringPair} from '@polkadot/types/types';
+import {Contract} from 'web3-eth-contract';
describe('NFT: Information getting', () => {
- itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- mode: {type: 'NFT'},
+ let donor: IKeyringPair;
+ let alice: IKeyringPair;
+
+ before(async function() {
+ await usingEthPlaygrounds(async (helper, privateKey) => {
+ donor = privateKey('//Alice');
+ [alice] = await helper.arrange.createAccounts([10n], donor);
});
- const alice = privateKeyWrapper('//Alice');
- const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+ });
+
+ itEth('totalSupply', async ({helper}) => {
+ const collection = await helper.nft.mintCollection(alice, {});
+ await collection.mintToken(alice);
- await createItemExpectSuccess(alice, collection, 'NFT', {Substrate: alice.address});
+ const caller = await helper.eth.createAccountWithBalance(donor);
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});
+ const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);
const totalSupply = await contract.methods.totalSupply().call();
expect(totalSupply).to.equal('1');
});
- itWeb3('balanceOf', async ({api, web3, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- mode: {type: 'NFT'},
- });
- const alice = privateKeyWrapper('//Alice');
+ itEth('balanceOf', async ({helper}) => {
+ const collection = await helper.nft.mintCollection(alice, {});
+ const caller = await helper.eth.createAccountWithBalance(donor);
- const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum:caller});
- await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});
- await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});
+ await collection.mintToken(alice, {Ethereum: caller});
+ await collection.mintToken(alice, {Ethereum: caller});
+ await collection.mintToken(alice, {Ethereum: caller});
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});
+ const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);
const balance = await contract.methods.balanceOf(caller).call();
expect(balance).to.equal('3');
});
- itWeb3('ownerOf', async ({api, web3, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- mode: {type: 'NFT'},
- });
- const alice = privateKeyWrapper('//Alice');
+ itEth('ownerOf', async ({helper}) => {
+ const collection = await helper.nft.mintCollection(alice, {});
+ const caller = await helper.eth.createAccountWithBalance(donor);
- const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});
+ const token = await collection.mintToken(alice, {Ethereum: caller});
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});
- const owner = await contract.methods.ownerOf(tokenId).call();
+ const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);
+
+ const owner = await contract.methods.ownerOf(token.tokenId).call();
expect(owner).to.equal(caller);
});
});
describe('Check ERC721 token URI for NFT', () => {
- itWeb3('Empty tokenURI', async ({web3, api, privateKeyWrapper}) => {
- const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const helper = evmCollectionHelpers(web3, owner);
- let result = await helper.methods.createERC721MetadataCompatibleCollection('Mint collection', '1', '1', '').send();
- const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
- const receiver = createEthAccount(web3);
- const contract = evmCollection(web3, owner, collectionIdAddress);
+ let donor: IKeyringPair;
+
+ before(async function() {
+ await usingEthPlaygrounds(async (_helper, privateKey) => {
+ donor = privateKey('//Alice');
+ });
+ });
+
+ async function setup(helper: EthUniqueHelper, tokenPrefix: string, propertyKey?: string, propertyValue?: string): Promise<{contract: Contract, nextTokenId: string}> {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const receiver = helper.eth.createAccount();
+
+ const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);
+ let result = await collectionHelper.methods.createERC721MetadataCompatibleCollection('Mint collection', 'a', 'b', tokenPrefix).send();
+ const collectionAddress = helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
const nextTokenId = await contract.methods.nextTokenId().call();
expect(nextTokenId).to.be.equal('1');
@@ -88,162 +94,73 @@
nextTokenId,
).send();
- const events = normalizeEvents(result.events);
- const address = collectionIdToAddress(collectionId);
+ if (propertyKey && propertyValue) {
+ // Set URL or suffix
+ await contract.methods.setProperty(nextTokenId, propertyKey, Buffer.from(propertyValue)).send();
+ }
- expect(events).to.be.deep.equal([
- {
- address,
- event: 'Transfer',
- args: {
- from: '0x0000000000000000000000000000000000000000',
- to: receiver,
- tokenId: nextTokenId,
- },
- },
- ]);
+ const event = result.events.Transfer;
+ expect(event.address).to.be.equal(collectionAddress);
+ expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');
+ expect(event.returnValues.to).to.be.equal(receiver);
+ expect(event.returnValues.tokenId).to.be.equal(nextTokenId);
+ return {contract, nextTokenId};
+ }
+
+ itEth('Empty tokenURI', async ({helper}) => {
+ const {contract, nextTokenId} = await setup(helper, '');
expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('');
});
- itWeb3('TokenURI from url', async ({web3, api, privateKeyWrapper}) => {
- const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const helper = evmCollectionHelpers(web3, owner);
- let result = await helper.methods.createERC721MetadataCompatibleCollection('Mint collection', '1', '1', 'BaseURI_').send();
- const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
- const receiver = createEthAccount(web3);
- const contract = evmCollection(web3, owner, collectionIdAddress);
-
- const nextTokenId = await contract.methods.nextTokenId().call();
- expect(nextTokenId).to.be.equal('1');
- result = await contract.methods.mint(
- receiver,
- nextTokenId,
- ).send();
-
- // Set URL
- await contract.methods.setProperty(nextTokenId, 'url', Buffer.from('Token URI')).send();
-
- const events = normalizeEvents(result.events);
- const address = collectionIdToAddress(collectionId);
-
- expect(events).to.be.deep.equal([
- {
- address,
- event: 'Transfer',
- args: {
- from: '0x0000000000000000000000000000000000000000',
- to: receiver,
- tokenId: nextTokenId,
- },
- },
- ]);
-
+ itEth('TokenURI from url', async ({helper}) => {
+ const {contract, nextTokenId} = await setup(helper, 'BaseURI_', 'url', 'Token URI');
expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Token URI');
});
- itWeb3('TokenURI from baseURI + tokenId', async ({web3, api, privateKeyWrapper}) => {
- const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const helper = evmCollectionHelpers(web3, owner);
- let result = await helper.methods.createERC721MetadataCompatibleCollection('Mint collection', '1', '1', 'BaseURI_').send();
- const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
- const receiver = createEthAccount(web3);
- const contract = evmCollection(web3, owner, collectionIdAddress);
-
- const nextTokenId = await contract.methods.nextTokenId().call();
- expect(nextTokenId).to.be.equal('1');
- result = await contract.methods.mint(
- receiver,
- nextTokenId,
- ).send();
-
- const events = normalizeEvents(result.events);
- const address = collectionIdToAddress(collectionId);
-
- expect(events).to.be.deep.equal([
- {
- address,
- event: 'Transfer',
- args: {
- from: '0x0000000000000000000000000000000000000000',
- to: receiver,
- tokenId: nextTokenId,
- },
- },
- ]);
-
+ itEth('TokenURI from baseURI + tokenId', async ({helper}) => {
+ const {contract, nextTokenId} = await setup(helper, 'BaseURI_');
expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('BaseURI_' + nextTokenId);
});
- itWeb3('TokenURI from baseURI + suffix', async ({web3, api, privateKeyWrapper}) => {
- const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const helper = evmCollectionHelpers(web3, owner);
- let result = await helper.methods.createERC721MetadataCompatibleCollection('Mint collection', '1', '1', 'BaseURI_').send();
- const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
- const receiver = createEthAccount(web3);
- const contract = evmCollection(web3, owner, collectionIdAddress);
-
- const nextTokenId = await contract.methods.nextTokenId().call();
- expect(nextTokenId).to.be.equal('1');
- result = await contract.methods.mint(
- receiver,
- nextTokenId,
- ).send();
-
- // Set suffix
+ itEth('TokenURI from baseURI + suffix', async ({helper}) => {
const suffix = '/some/suffix';
- await contract.methods.setProperty(nextTokenId, 'suffix', Buffer.from(suffix)).send();
-
- const events = normalizeEvents(result.events);
- const address = collectionIdToAddress(collectionId);
-
- expect(events).to.be.deep.equal([
- {
- address,
- event: 'Transfer',
- args: {
- from: '0x0000000000000000000000000000000000000000',
- to: receiver,
- tokenId: nextTokenId,
- },
- },
- ]);
-
+ const {contract, nextTokenId} = await setup(helper, 'BaseURI_', 'suffix', suffix);
expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('BaseURI_' + suffix);
});
});
describe('NFT: Plain calls', () => {
- itWeb3('Can perform mint()', async ({web3, api, privateKeyWrapper}) => {
- const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const helper = evmCollectionHelpers(web3, owner);
- let result = await helper.methods.createNonfungibleCollection('Mint collection', '6', '6').send();
- const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
- const receiver = createEthAccount(web3);
- const contract = evmCollection(web3, owner, collectionIdAddress);
+ let donor: IKeyringPair;
+ let alice: IKeyringPair;
+
+ before(async function() {
+ await usingEthPlaygrounds(async (helper, privateKey) => {
+ donor = privateKey('//Alice');
+ [alice] = await helper.arrange.createAccounts([10n], donor);
+ });
+ });
+
+ itEth('Can perform mint()', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const receiver = helper.eth.createAccount();
+
+ const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'Minty', '6', '6');
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
const nextTokenId = await contract.methods.nextTokenId().call();
expect(nextTokenId).to.be.equal('1');
- result = await contract.methods.mintWithTokenURI(
+ const result = await contract.methods.mintWithTokenURI(
receiver,
nextTokenId,
'Test URI',
).send();
- const events = normalizeEvents(result.events);
- const address = collectionIdToAddress(collectionId);
-
- expect(events).to.be.deep.equal([
- {
- address,
- event: 'Transfer',
- args: {
- from: '0x0000000000000000000000000000000000000000',
- to: receiver,
- tokenId: nextTokenId,
- },
- },
- ]);
+ const event = result.events.Transfer;
+ expect(event.address).to.be.equal(collectionAddress);
+ expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');
+ expect(event.returnValues.to).to.be.equal(receiver);
+ expect(event.returnValues.tokenId).to.be.equal(nextTokenId);
expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');
@@ -254,7 +171,8 @@
});
//TODO: CORE-302 add eth methods
- itWeb3.skip('Can perform mintBulk()', async ({web3, api, privateKeyWrapper}) => {
+ /* todo:playgrounds skipped test!
+ itWeb3.skip('Can perform mintBulk()', async ({helper}) => {
const collection = await createCollectionExpectSuccess({
mode: {type: 'NFT'},
});
@@ -316,107 +234,70 @@
expect(await contract.methods.tokenURI(+nextTokenId + 2).call()).to.be.equal('Test URI 2');
}
});
-
- itWeb3('Can perform burn()', async ({web3, api, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- mode: {type: 'NFT'},
- });
- const alice = privateKeyWrapper('//Alice');
+ */
- const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+ itEth('Can perform burn()', async ({helper}) => {
+ const caller = await helper.eth.createAccountWithBalance(donor);
- const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
+ const collection = await helper.nft.mintCollection(alice, {});
+ const {tokenId} = await collection.mintToken(alice, {Ethereum: caller});
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', caller);
{
- const result = await contract.methods.burn(tokenId).send({from: owner});
- const events = normalizeEvents(result.events);
-
- expect(events).to.be.deep.equal([
- {
- address,
- event: 'Transfer',
- args: {
- from: owner,
- to: '0x0000000000000000000000000000000000000000',
- tokenId: tokenId.toString(),
- },
- },
- ]);
+ const result = await contract.methods.burn(tokenId).send({from: caller});
+
+ const event = result.events.Transfer;
+ expect(event.address).to.be.equal(collectionAddress);
+ expect(event.returnValues.from).to.be.equal(caller);
+ expect(event.returnValues.to).to.be.equal('0x0000000000000000000000000000000000000000');
+ expect(event.returnValues.tokenId).to.be.equal(`${tokenId}`);
}
});
- itWeb3('Can perform approve()', async ({web3, api, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- mode: {type: 'NFT'},
- });
- const alice = privateKeyWrapper('//Alice');
-
- const owner = createEthAccount(web3);
- await transferBalanceToEth(api, alice, owner);
-
- const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
+ itEth('Can perform approve()', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const spender = helper.eth.createAccount();
- const spender = createEthAccount(web3);
+ const collection = await helper.nft.mintCollection(alice, {});
+ const {tokenId} = await collection.mintToken(alice, {Ethereum: owner});
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(nonFungibleAbi as any, address);
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
{
- const result = await contract.methods.approve(spender, tokenId).send({from: owner, ...GAS_ARGS});
- const events = normalizeEvents(result.events);
+ const result = await contract.methods.approve(spender, tokenId).send({from: owner});
- expect(events).to.be.deep.equal([
- {
- address,
- event: 'Approval',
- args: {
- owner,
- approved: spender,
- tokenId: tokenId.toString(),
- },
- },
- ]);
+ const event = result.events.Approval;
+ expect(event.address).to.be.equal(collectionAddress);
+ expect(event.returnValues.owner).to.be.equal(owner);
+ expect(event.returnValues.approved).to.be.equal(spender);
+ expect(event.returnValues.tokenId).to.be.equal(`${tokenId}`);
}
});
- itWeb3('Can perform transferFrom()', async ({web3, api, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- mode: {type: 'NFT'},
- });
- const alice = privateKeyWrapper('//Alice');
-
- const owner = createEthAccount(web3);
- await transferBalanceToEth(api, alice, owner);
+ itEth('Can perform transferFrom()', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const spender = await helper.eth.createAccountWithBalance(donor);
+ const receiver = helper.eth.createAccount();
- const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
-
- const spender = createEthAccount(web3);
- await transferBalanceToEth(api, alice, spender);
-
- const receiver = createEthAccount(web3);
+ const collection = await helper.nft.mintCollection(alice, {});
+ const {tokenId} = await collection.mintToken(alice, {Ethereum: owner});
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
await contract.methods.approve(spender, tokenId).send({from: owner});
{
const result = await contract.methods.transferFrom(owner, receiver, tokenId).send({from: spender});
- const events = normalizeEvents(result.events);
- expect(events).to.be.deep.equal([
- {
- address,
- event: 'Transfer',
- args: {
- from: owner,
- to: receiver,
- tokenId: tokenId.toString(),
- },
- },
- ]);
+
+ const event = result.events.Transfer;
+ expect(event.address).to.be.equal(collectionAddress);
+ expect(event.returnValues.from).to.be.equal(owner);
+ expect(event.returnValues.to).to.be.equal(receiver);
+ expect(event.returnValues.tokenId).to.be.equal(`${tokenId}`);
}
{
@@ -430,37 +311,24 @@
}
});
- itWeb3('Can perform transfer()', async ({web3, api, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- mode: {type: 'NFT'},
- });
- const alice = privateKeyWrapper('//Alice');
-
- const owner = createEthAccount(web3);
- await transferBalanceToEth(api, alice, owner);
-
- const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
+ itEth('Can perform transfer()', async ({helper}) => {
+ const collection = await helper.nft.mintCollection(alice, {});
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const receiver = helper.eth.createAccount();
- const receiver = createEthAccount(web3);
- await transferBalanceToEth(api, alice, receiver);
+ const {tokenId} = await collection.mintToken(alice, {Ethereum: owner});
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
{
const result = await contract.methods.transfer(receiver, tokenId).send({from: owner});
- const events = normalizeEvents(result.events);
- expect(events).to.be.deep.equal([
- {
- address,
- event: 'Transfer',
- args: {
- from: owner,
- to: receiver,
- tokenId: tokenId.toString(),
- },
- },
- ]);
+
+ const event = result.events.Transfer;
+ expect(event.address).to.be.equal(collectionAddress);
+ expect(event.returnValues.from).to.be.equal(owner);
+ expect(event.returnValues.to).to.be.equal(receiver);
+ expect(event.returnValues.tokenId).to.be.equal(`${tokenId}`);
}
{
@@ -476,237 +344,209 @@
});
describe('NFT: Fees', () => {
- itWeb3('approve() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- mode: {type: 'NFT'},
+ let donor: IKeyringPair;
+ let alice: IKeyringPair;
+
+ before(async function() {
+ await usingEthPlaygrounds(async (helper, privateKey) => {
+ donor = privateKey('//Alice');
+ [alice] = await helper.arrange.createAccounts([10n], donor);
});
- const alice = privateKeyWrapper('//Alice');
+ });
+
+ itEth('approve() call fee is less than 0.2UNQ', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const spender = helper.eth.createAccount();
- const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const spender = createEthAccount(web3);
+ const collection = await helper.nft.mintCollection(alice, {});
+ const {tokenId} = await collection.mintToken(alice, {Ethereum: owner});
- const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
+ const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', owner);
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});
-
- const cost = await recordEthFee(api, owner, () => contract.methods.approve(spender, tokenId).send({from: owner}));
- expect(cost < BigInt(0.2 * Number(UNIQUE)));
+ const cost = await helper.eth.recordCallFee(owner, () => contract.methods.approve(spender, tokenId).send({from: owner}));
+ expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));
});
- itWeb3('transferFrom() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- mode: {type: 'NFT'},
- });
- const alice = privateKeyWrapper('//Alice');
-
- const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const spender = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+ itEth('transferFrom() call fee is less than 0.2UNQ', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const spender = await helper.eth.createAccountWithBalance(donor);
- const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
+ const collection = await helper.nft.mintCollection(alice, {});
+ const {tokenId} = await collection.mintToken(alice, {Ethereum: owner});
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});
+ const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', owner);
await contract.methods.approve(spender, tokenId).send({from: owner});
- const cost = await recordEthFee(api, spender, () => contract.methods.transferFrom(owner, spender, tokenId).send({from: spender}));
- expect(cost < BigInt(0.2 * Number(UNIQUE)));
+ const cost = await helper.eth.recordCallFee(spender, () => contract.methods.transferFrom(owner, spender, tokenId).send({from: spender}));
+ expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));
});
- itWeb3('transfer() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- mode: {type: 'NFT'},
- });
- const alice = privateKeyWrapper('//Alice');
+ itEth('transfer() call fee is less than 0.2UNQ', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const receiver = helper.eth.createAccount();
- const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const receiver = createEthAccount(web3);
+ const collection = await helper.nft.mintCollection(alice, {});
+ const {tokenId} = await collection.mintToken(alice, {Ethereum: owner});
- const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
+ const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', owner);
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});
-
- const cost = await recordEthFee(api, owner, () => contract.methods.transfer(receiver, tokenId).send({from: owner}));
- expect(cost < BigInt(0.2 * Number(UNIQUE)));
+ const cost = await helper.eth.recordCallFee(owner, () => contract.methods.transfer(receiver, tokenId).send({from: owner}));
+ expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));
});
});
describe('NFT: Substrate calls', () => {
- itWeb3('Events emitted for mint()', async ({web3, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- mode: {type: 'NFT'},
+ let donor: IKeyringPair;
+ let alice: IKeyringPair;
+
+ before(async function() {
+ await usingEthPlaygrounds(async (helper, privateKey) => {
+ donor = privateKey('//Alice');
+ [alice] = await helper.arrange.createAccounts([20n], donor);
});
- const alice = privateKeyWrapper('//Alice');
+ });
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(nonFungibleAbi as any, address);
+ itEth('Events emitted for mint()', async ({helper}) => {
+ const collection = await helper.nft.mintCollection(alice, {});
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');
- let tokenId: number;
- const events = await recordEvents(contract, async () => {
- tokenId = await createItemExpectSuccess(alice, collection, 'NFT');
+ const events: any = [];
+ contract.events.allEvents((_: any, event: any) => {
+ events.push(event);
});
+ const {tokenId} = await collection.mintToken(alice);
- expect(events).to.be.deep.equal([
- {
- address,
- event: 'Transfer',
- args: {
- from: '0x0000000000000000000000000000000000000000',
- to: subToEth(alice.address),
- tokenId: tokenId!.toString(),
- },
- },
- ]);
+ const event = events[0];
+ expect(event.event).to.be.equal('Transfer');
+ expect(event.address).to.be.equal(collectionAddress);
+ expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');
+ expect(event.returnValues.to).to.be.equal(helper.address.substrateToEth(alice.address));
+ expect(event.returnValues.tokenId).to.be.equal(tokenId.toString());
});
- itWeb3('Events emitted for burn()', async ({web3, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- mode: {type: 'NFT'},
+ itEth('Events emitted for burn()', async ({helper}) => {
+ const collection = await helper.nft.mintCollection(alice, {});
+ const token = await collection.mintToken(alice);
+
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');
+
+ const events: any = [];
+ contract.events.allEvents((_: any, event: any) => {
+ events.push(event);
});
- const alice = privateKeyWrapper('//Alice');
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(nonFungibleAbi as any, address);
+ await token.burn(alice);
- const tokenId = await createItemExpectSuccess(alice, collection, 'NFT');
- const events = await recordEvents(contract, async () => {
- await burnItemExpectSuccess(alice, collection, tokenId);
- });
-
- expect(events).to.be.deep.equal([
- {
- address,
- event: 'Transfer',
- args: {
- from: subToEth(alice.address),
- to: '0x0000000000000000000000000000000000000000',
- tokenId: tokenId.toString(),
- },
- },
- ]);
+ const event = events[0];
+ expect(event.event).to.be.equal('Transfer');
+ expect(event.address).to.be.equal(collectionAddress);
+ expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));
+ expect(event.returnValues.to).to.be.equal('0x0000000000000000000000000000000000000000');
+ expect(event.returnValues.tokenId).to.be.equal(token.tokenId.toString());
});
- itWeb3('Events emitted for approve()', async ({web3, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- mode: {type: 'NFT'},
- });
- const alice = privateKeyWrapper('//Alice');
+ itEth('Events emitted for approve()', async ({helper}) => {
+ const receiver = helper.eth.createAccount();
- const receiver = createEthAccount(web3);
-
- const tokenId = await createItemExpectSuccess(alice, collection, 'NFT');
-
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(nonFungibleAbi as any, address);
+ const collection = await helper.nft.mintCollection(alice, {});
+ const token = await collection.mintToken(alice);
- const events = await recordEvents(contract, async () => {
- await approveExpectSuccess(collection, tokenId, alice, {Ethereum: receiver}, 1);
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');
+
+ const events: any = [];
+ contract.events.allEvents((_: any, event: any) => {
+ events.push(event);
});
- expect(events).to.be.deep.equal([
- {
- address,
- event: 'Approval',
- args: {
- owner: subToEth(alice.address),
- approved: receiver,
- tokenId: tokenId.toString(),
- },
- },
- ]);
+ await token.approve(alice, {Ethereum: receiver});
+
+ const event = events[0];
+ expect(event.event).to.be.equal('Approval');
+ expect(event.address).to.be.equal(collectionAddress);
+ expect(event.returnValues.owner).to.be.equal(helper.address.substrateToEth(alice.address));
+ expect(event.returnValues.approved).to.be.equal(receiver);
+ expect(event.returnValues.tokenId).to.be.equal(token.tokenId.toString());
});
- itWeb3('Events emitted for transferFrom()', async ({web3, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- mode: {type: 'NFT'},
- });
- const alice = privateKeyWrapper('//Alice');
- const bob = privateKeyWrapper('//Bob');
+ itEth('Events emitted for transferFrom()', async ({helper}) => {
+ const [bob] = await helper.arrange.createAccounts([10n], donor);
+ const receiver = helper.eth.createAccount();
- const receiver = createEthAccount(web3);
-
- const tokenId = await createItemExpectSuccess(alice, collection, 'NFT');
- await approveExpectSuccess(collection, tokenId, alice, bob.address, 1);
-
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(nonFungibleAbi as any, address);
+ const collection = await helper.nft.mintCollection(alice, {});
+ const token = await collection.mintToken(alice);
+ await token.approve(alice, {Substrate: bob.address});
- const events = await recordEvents(contract, async () => {
- await transferFromExpectSuccess(collection, tokenId, bob, alice, {Ethereum: receiver}, 1, 'NFT');
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');
+
+ const events: any = [];
+ contract.events.allEvents((_: any, event: any) => {
+ events.push(event);
});
- expect(events).to.be.deep.equal([
- {
- address,
- event: 'Transfer',
- args: {
- from: subToEth(alice.address),
- to: receiver,
- tokenId: tokenId.toString(),
- },
- },
- ]);
+ await token.transferFrom(bob, {Substrate: alice.address}, {Ethereum: receiver});
+
+ const event = events[0];
+ expect(event.address).to.be.equal(collectionAddress);
+ expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));
+ expect(event.returnValues.to).to.be.equal(receiver);
+ expect(event.returnValues.tokenId).to.be.equal(`${token.tokenId}`);
});
- itWeb3('Events emitted for transfer()', async ({web3, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- mode: {type: 'NFT'},
- });
- const alice = privateKeyWrapper('//Alice');
+ itEth('Events emitted for transfer()', async ({helper}) => {
+ const receiver = helper.eth.createAccount();
- const receiver = createEthAccount(web3);
+ const collection = await helper.nft.mintCollection(alice, {});
+ const token = await collection.mintToken(alice);
- const tokenId = await createItemExpectSuccess(alice, collection, 'NFT');
-
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(nonFungibleAbi as any, address);
-
- const events = await recordEvents(contract, async () => {
- await transferExpectSuccess(collection, tokenId, alice, {Ethereum: receiver}, 1, 'NFT');
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');
+
+ const events: any = [];
+ contract.events.allEvents((_: any, event: any) => {
+ events.push(event);
});
- expect(events).to.be.deep.equal([
- {
- address,
- event: 'Transfer',
- args: {
- from: subToEth(alice.address),
- to: receiver,
- tokenId: tokenId.toString(),
- },
- },
- ]);
+ await token.transfer(alice, {Ethereum: receiver});
+
+ const event = events[0];
+ expect(event.address).to.be.equal(collectionAddress);
+ expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));
+ expect(event.returnValues.to).to.be.equal(receiver);
+ expect(event.returnValues.tokenId).to.be.equal(`${token.tokenId}`);
});
});
describe('Common metadata', () => {
- itWeb3('Returns collection name', async ({api, web3, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- name: 'token name',
- mode: {type: 'NFT'},
+ let donor: IKeyringPair;
+ let alice: IKeyringPair;
+
+ before(async function() {
+ await usingEthPlaygrounds(async (helper, privateKey) => {
+ donor = privateKey('//Alice');
+ [alice] = await helper.arrange.createAccounts([20n], donor);
});
- const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+ });
+
+ itEth('Returns collection name', async ({helper}) => {
+ const caller = await helper.eth.createAccountWithBalance(donor);
+ const collection = await helper.nft.mintCollection(alice, {name: 'oh River', tokenPrefix: 'CHANGE'});
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});
+ const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);
const name = await contract.methods.name().call();
-
- expect(name).to.equal('token name');
+ expect(name).to.equal('oh River');
});
- itWeb3('Returns symbol name', async ({api, web3, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- tokenPrefix: 'TOK',
- mode: {type: 'NFT'},
- });
- const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+ itEth('Returns symbol name', async ({helper}) => {
+ const caller = await helper.eth.createAccountWithBalance(donor);
+ const collection = await helper.nft.mintCollection(alice, {name: 'oh River', tokenPrefix: 'CHANGE'});
- const address = collectionIdToAddress(collection);
- const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});
+ const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);
const symbol = await contract.methods.symbol().call();
-
- expect(symbol).to.equal('TOK');
+ expect(symbol).to.equal('CHANGE');
});
});
\ No newline at end of file
tests/src/eth/reFungible.test.tsdiffbeforeafterboth--- a/tests/src/eth/reFungible.test.ts
+++ b/tests/src/eth/reFungible.test.ts
@@ -14,33 +14,35 @@
// You should have received a copy of the GNU General Public License
// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-import {createCollectionExpectSuccess, UNIQUE, requirePallets, Pallets} from '../util/helpers';
-import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, evmCollection, evmCollectionHelpers, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, tokenIdToAddress, uniqueRefungibleToken} from './util/helpers';
-import {expect} from 'chai';
+import {Pallets, requirePalletsOrSkip} from '../util/playgrounds';
+import {expect, itEth, usingEthPlaygrounds} from './util/playgrounds';
+import {IKeyringPair} from '@polkadot/types/types';
describe('Refungible: Information getting', () => {
+ let donor: IKeyringPair;
+
before(async function() {
- await requirePallets(this, [Pallets.ReFungible]);
+ await usingEthPlaygrounds(async (helper, privateKey) => {
+ requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);
+
+ donor = privateKey('//Alice');
+ });
});
- itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {
- const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const helper = evmCollectionHelpers(web3, caller);
- const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
- const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
- const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
+ itEth('totalSupply', async ({helper}) => {
+ const caller = await helper.eth.createAccountWithBalance(donor);
+ const {collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'TotalSupply', '6', '6');
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
const nextTokenId = await contract.methods.nextTokenId().call();
await contract.methods.mint(caller, nextTokenId).send();
const totalSupply = await contract.methods.totalSupply().call();
expect(totalSupply).to.equal('1');
});
- itWeb3('balanceOf', async ({api, web3, privateKeyWrapper}) => {
- const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const helper = evmCollectionHelpers(web3, caller);
- const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
- const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
- const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
+ itEth('balanceOf', async ({helper}) => {
+ const caller = await helper.eth.createAccountWithBalance(donor);
+ const {collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'BalanceOf', '6', '6');
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
{
const nextTokenId = await contract.methods.nextTokenId().call();
@@ -56,38 +58,30 @@
}
const balance = await contract.methods.balanceOf(caller).call();
-
expect(balance).to.equal('3');
});
- itWeb3('ownerOf', async ({api, web3, privateKeyWrapper}) => {
- const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const helper = evmCollectionHelpers(web3, caller);
- const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
- const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
- const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
+ itEth('ownerOf', async ({helper}) => {
+ const caller = await helper.eth.createAccountWithBalance(donor);
+ const {collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'OwnerOf', '6', '6');
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
const tokenId = await contract.methods.nextTokenId().call();
await contract.methods.mint(caller, tokenId).send();
const owner = await contract.methods.ownerOf(tokenId).call();
-
expect(owner).to.equal(caller);
});
- itWeb3('ownerOf after burn', async ({api, web3, privateKeyWrapper}) => {
- const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const receiver = createEthAccount(web3);
- const helper = evmCollectionHelpers(web3, caller);
- const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
- const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
- const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
+ itEth('ownerOf after burn', async ({helper}) => {
+ const caller = await helper.eth.createAccountWithBalance(donor);
+ const receiver = helper.eth.createAccount();
+ const {collectionId, collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'OwnerOf-AfterBurn', '6', '6');
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
const tokenId = await contract.methods.nextTokenId().call();
await contract.methods.mint(caller, tokenId).send();
-
- const tokenAddress = tokenIdToAddress(collectionId, tokenId);
- const tokenContract = uniqueRefungibleToken(web3, tokenAddress, caller);
+ const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);
await tokenContract.methods.repartition(2).send();
await tokenContract.methods.transfer(receiver, 1).send();
@@ -95,80 +89,67 @@
await tokenContract.methods.burnFrom(caller, 1).send();
const owner = await contract.methods.ownerOf(tokenId).call();
-
expect(owner).to.equal(receiver);
});
- itWeb3('ownerOf for partial ownership', async ({api, web3, privateKeyWrapper}) => {
- const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const receiver = createEthAccount(web3);
- const helper = evmCollectionHelpers(web3, caller);
- const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
- const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
- const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
+ itEth('ownerOf for partial ownership', async ({helper}) => {
+ const caller = await helper.eth.createAccountWithBalance(donor);
+ const receiver = helper.eth.createAccount();
+ const {collectionId, collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'Partial-OwnerOf', '6', '6');
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
const tokenId = await contract.methods.nextTokenId().call();
await contract.methods.mint(caller, tokenId).send();
-
- const tokenAddress = tokenIdToAddress(collectionId, tokenId);
- const tokenContract = uniqueRefungibleToken(web3, tokenAddress, caller);
+ const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);
await tokenContract.methods.repartition(2).send();
await tokenContract.methods.transfer(receiver, 1).send();
const owner = await contract.methods.ownerOf(tokenId).call();
-
expect(owner).to.equal('0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF');
});
});
describe('Refungible: Plain calls', () => {
+ let donor: IKeyringPair;
+
before(async function() {
- await requirePallets(this, [Pallets.ReFungible]);
+ await usingEthPlaygrounds(async (helper, privateKey) => {
+ requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);
+
+ donor = privateKey('//Alice');
+ });
});
- itWeb3('Can perform mint()', async ({web3, api, privateKeyWrapper}) => {
- const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const helper = evmCollectionHelpers(web3, owner);
- let result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
- const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
- const receiver = createEthAccount(web3);
- const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});
+ itEth('Can perform mint()', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const receiver = helper.eth.createAccount();
+ const {collectionAddress} = await helper.eth.createRefungibleCollection(owner, 'Minty', '6', '6');
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);
+
const nextTokenId = await contract.methods.nextTokenId().call();
-
expect(nextTokenId).to.be.equal('1');
- result = await contract.methods.mintWithTokenURI(
+ const result = await contract.methods.mintWithTokenURI(
receiver,
nextTokenId,
'Test URI',
).send();
- const events = normalizeEvents(result.events);
-
- expect(events).to.include.deep.members([
- {
- address: collectionIdAddress,
- event: 'Transfer',
- args: {
- from: '0x0000000000000000000000000000000000000000',
- to: receiver,
- tokenId: nextTokenId,
- },
- },
- ]);
+ const event = result.events.Transfer;
+ expect(event.address).to.equal(collectionAddress);
+ expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');
+ expect(event.returnValues.to).to.equal(receiver);
+ expect(event.returnValues.tokenId).to.equal(nextTokenId);
expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');
});
- itWeb3('Can perform mintBulk()', async ({web3, api, privateKeyWrapper}) => {
- const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const helper = evmCollectionHelpers(web3, caller);
- const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
- const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
- const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
+ itEth('Can perform mintBulk()', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const receiver = helper.eth.createAccount();
+ const {collectionAddress} = await helper.eth.createRefungibleCollection(owner, 'MintBulky', '6', '6');
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);
- const receiver = createEthAccount(web3);
-
{
const nextTokenId = await contract.methods.nextTokenId().call();
expect(nextTokenId).to.be.equal('1');
@@ -180,37 +161,15 @@
[+nextTokenId + 2, 'Test URI 2'],
],
).send();
- const events = normalizeEvents(result.events);
- expect(events).to.include.deep.members([
- {
- address: collectionIdAddress,
- event: 'Transfer',
- args: {
- from: '0x0000000000000000000000000000000000000000',
- to: receiver,
- tokenId: nextTokenId,
- },
- },
- {
- address: collectionIdAddress,
- event: 'Transfer',
- args: {
- from: '0x0000000000000000000000000000000000000000',
- to: receiver,
- tokenId: String(+nextTokenId + 1),
- },
- },
- {
- address: collectionIdAddress,
- event: 'Transfer',
- args: {
- from: '0x0000000000000000000000000000000000000000',
- to: receiver,
- tokenId: String(+nextTokenId + 2),
- },
- },
- ]);
+ const events = result.events.Transfer;
+ for (let i = 0; i < 2; i++) {
+ const event = events[i];
+ expect(event.address).to.equal(collectionAddress);
+ expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');
+ expect(event.returnValues.to).to.equal(receiver);
+ expect(event.returnValues.tokenId).to.equal(String(+nextTokenId + i));
+ }
expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI 0');
expect(await contract.methods.tokenURI(+nextTokenId + 1).call()).to.be.equal('Test URI 1');
@@ -218,76 +177,54 @@
}
});
- itWeb3('Can perform burn()', async ({web3, api, privateKeyWrapper}) => {
- const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const helper = evmCollectionHelpers(web3, caller);
- const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
- const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
- const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
+ itEth('Can perform burn()', async ({helper}) => {
+ const caller = await helper.eth.createAccountWithBalance(donor);
+ const {collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'Burny', '6', '6');
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
const tokenId = await contract.methods.nextTokenId().call();
await contract.methods.mint(caller, tokenId).send();
{
const result = await contract.methods.burn(tokenId).send();
- const events = normalizeEvents(result.events);
- expect(events).to.include.deep.members([
- {
- address: collectionIdAddress,
- event: 'Transfer',
- args: {
- from: caller,
- to: '0x0000000000000000000000000000000000000000',
- tokenId: tokenId.toString(),
- },
- },
- ]);
+ const event = result.events.Transfer;
+ expect(event.address).to.equal(collectionAddress);
+ expect(event.returnValues.from).to.equal(caller);
+ expect(event.returnValues.to).to.equal('0x0000000000000000000000000000000000000000');
+ expect(event.returnValues.tokenId).to.equal(tokenId.toString());
}
});
- itWeb3('Can perform transferFrom()', async ({web3, api, privateKeyWrapper}) => {
- const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const helper = evmCollectionHelpers(web3, caller);
- const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
- const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
- const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
-
- const receiver = createEthAccount(web3);
+ itEth('Can perform transferFrom()', async ({helper}) => {
+ const caller = await helper.eth.createAccountWithBalance(donor);
+ const receiver = helper.eth.createAccount();
+ const {collectionId, collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'TransferFromy', '6', '6');
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
const tokenId = await contract.methods.nextTokenId().call();
+ const tokenAddress = helper.ethAddress.fromTokenId(collectionId, tokenId);
await contract.methods.mint(caller, tokenId).send();
- const address = tokenIdToAddress(collectionId, tokenId);
- const tokenContract = uniqueRefungibleToken(web3, address, caller);
+ const tokenContract = helper.ethNativeContract.rftToken(tokenAddress, caller);
await tokenContract.methods.repartition(15).send();
{
- const erc20Events = await recordEvents(tokenContract, async () => {
- const result = await contract.methods.transferFrom(caller, receiver, tokenId).send();
- const events = normalizeEvents(result.events);
- expect(events).to.include.deep.members([
- {
- address: collectionIdAddress,
- event: 'Transfer',
- args: {
- from: caller,
- to: receiver,
- tokenId: tokenId.toString(),
- },
- },
- ]);
+ const tokenEvents: any = [];
+ tokenContract.events.allEvents((_: any, event: any) => {
+ tokenEvents.push(event);
});
+ const result = await contract.methods.transferFrom(caller, receiver, tokenId).send();
+
+ let event = result.events.Transfer;
+ expect(event.address).to.equal(collectionAddress);
+ expect(event.returnValues.from).to.equal(caller);
+ expect(event.returnValues.to).to.equal(receiver);
+ expect(event.returnValues.tokenId).to.equal(tokenId.toString());
- expect(erc20Events).to.include.deep.members([
- {
- address,
- event: 'Transfer',
- args: {
- from: caller,
- to: receiver,
- value: '15',
- },
- },
- ]);
+ event = tokenEvents[0];
+ expect(event.address).to.equal(tokenAddress);
+ expect(event.returnValues.from).to.equal(caller);
+ expect(event.returnValues.to).to.equal(receiver);
+ expect(event.returnValues.value).to.equal('15');
}
{
@@ -301,32 +238,23 @@
}
});
- itWeb3('Can perform transfer()', async ({web3, api, privateKeyWrapper}) => {
- const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const helper = evmCollectionHelpers(web3, caller);
- const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
- const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
- const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
-
- const receiver = createEthAccount(web3);
+ itEth('Can perform transfer()', async ({helper}) => {
+ const caller = await helper.eth.createAccountWithBalance(donor);
+ const receiver = helper.eth.createAccount();
+ const {collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'Transferry', '6', '6');
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
const tokenId = await contract.methods.nextTokenId().call();
await contract.methods.mint(caller, tokenId).send();
{
const result = await contract.methods.transfer(receiver, tokenId).send();
- const events = normalizeEvents(result.events);
- expect(events).to.include.deep.members([
- {
- address: collectionIdAddress,
- event: 'Transfer',
- args: {
- from: caller,
- to: receiver,
- tokenId: tokenId.toString(),
- },
- },
- ]);
+
+ const event = result.events.Transfer;
+ expect(event.address).to.equal(collectionAddress);
+ expect(event.returnValues.from).to.equal(caller);
+ expect(event.returnValues.to).to.equal(receiver);
+ expect(event.returnValues.tokenId).to.equal(tokenId.toString());
}
{
@@ -340,141 +268,127 @@
}
});
- itWeb3('transfer event on transfer from partial ownership to full ownership', async ({api, web3, privateKeyWrapper}) => {
- const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const receiver = createEthAccount(web3);
- const helper = evmCollectionHelpers(web3, caller);
- const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
- const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
- const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
+ itEth('transfer event on transfer from partial ownership to full ownership', async ({helper}) => {
+ const caller = await helper.eth.createAccountWithBalance(donor);
+ const receiver = helper.eth.createAccount();
+ const {collectionId, collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'Transferry-Partial-to-Full', '6', '6');
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
const tokenId = await contract.methods.nextTokenId().call();
await contract.methods.mint(caller, tokenId).send();
- const tokenAddress = tokenIdToAddress(collectionId, tokenId);
- const tokenContract = uniqueRefungibleToken(web3, tokenAddress, caller);
+ const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);
await tokenContract.methods.repartition(2).send();
await tokenContract.methods.transfer(receiver, 1).send();
- const events = await recordEvents(contract, async () =>
- await tokenContract.methods.transfer(receiver, 1).send());
- expect(events).to.deep.equal([
- {
- address: collectionIdAddress,
- event: 'Transfer',
- args: {
- from: '0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF',
- to: receiver,
- tokenId: tokenId.toString(),
- },
- },
- ]);
+ const events: any = [];
+ contract.events.allEvents((_: any, event: any) => {
+ events.push(event);
+ });
+ await tokenContract.methods.transfer(receiver, 1).send();
+
+ const event = events[0];
+ expect(event.address).to.equal(collectionAddress);
+ expect(event.returnValues.from).to.equal('0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF');
+ expect(event.returnValues.to).to.equal(receiver);
+ expect(event.returnValues.tokenId).to.equal(tokenId.toString());
});
- itWeb3('transfer event on transfer from full ownership to partial ownership', async ({api, web3, privateKeyWrapper}) => {
- const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const receiver = createEthAccount(web3);
- const helper = evmCollectionHelpers(web3, caller);
- const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
- const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);
- const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
+ itEth('transfer event on transfer from full ownership to partial ownership', async ({helper}) => {
+ const caller = await helper.eth.createAccountWithBalance(donor);
+ const receiver = helper.eth.createAccount();
+ const {collectionId, collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'Transferry-Full-to-Partial', '6', '6');
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
const tokenId = await contract.methods.nextTokenId().call();
await contract.methods.mint(caller, tokenId).send();
- const tokenAddress = tokenIdToAddress(collectionId, tokenId);
- const tokenContract = uniqueRefungibleToken(web3, tokenAddress, caller);
+ const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);
await tokenContract.methods.repartition(2).send();
- const events = await recordEvents(contract, async () =>
- await tokenContract.methods.transfer(receiver, 1).send());
+ const events: any = [];
+ contract.events.allEvents((_: any, event: any) => {
+ events.push(event);
+ });
+ await tokenContract.methods.transfer(receiver, 1).send();
- expect(events).to.deep.equal([
- {
- address: collectionIdAddress,
- event: 'Transfer',
- args: {
- from: caller,
- to: '0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF',
- tokenId: tokenId.toString(),
- },
- },
- ]);
+ const event = events[0];
+ expect(event.address).to.equal(collectionAddress);
+ expect(event.returnValues.from).to.equal(caller);
+ expect(event.returnValues.to).to.equal('0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF');
+ expect(event.returnValues.tokenId).to.equal(tokenId.toString());
});
});
describe('RFT: Fees', () => {
+ let donor: IKeyringPair;
+
before(async function() {
- await requirePallets(this, [Pallets.ReFungible]);
+ await usingEthPlaygrounds(async (helper, privateKey) => {
+ requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);
+
+ donor = privateKey('//Alice');
+ });
});
- itWeb3('transferFrom() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {
- const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const helper = evmCollectionHelpers(web3, caller);
- const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
- const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
- const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
-
- const receiver = createEthAccount(web3);
+ itEth('transferFrom() call fee is less than 0.2UNQ', async ({helper}) => {
+ const caller = await helper.eth.createAccountWithBalance(donor);
+ const receiver = helper.eth.createAccount();
+ const {collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'Feeful-Transfer-From', '6', '6');
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
const tokenId = await contract.methods.nextTokenId().call();
await contract.methods.mint(caller, tokenId).send();
- const cost = await recordEthFee(api, caller, () => contract.methods.transferFrom(caller, receiver, tokenId).send());
- expect(cost < BigInt(0.2 * Number(UNIQUE)));
+ const cost = await helper.eth.recordCallFee(caller, () => contract.methods.transferFrom(caller, receiver, tokenId).send());
+ expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));
expect(cost > 0n);
});
- itWeb3('transfer() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {
- const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const helper = evmCollectionHelpers(web3, caller);
- const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();
- const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);
- const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});
-
- const receiver = createEthAccount(web3);
+ itEth('transfer() call fee is less than 0.2UNQ', async ({helper}) => {
+ const caller = await helper.eth.createAccountWithBalance(donor);
+ const receiver = helper.eth.createAccount();
+ const {collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'Feeful-Transfer', '6', '6');
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
const tokenId = await contract.methods.nextTokenId().call();
await contract.methods.mint(caller, tokenId).send();
- const cost = await recordEthFee(api, caller, () => contract.methods.transfer(receiver, tokenId).send());
- expect(cost < BigInt(0.2 * Number(UNIQUE)));
+ const cost = await helper.eth.recordCallFee(caller, () => contract.methods.transfer(receiver, tokenId).send());
+ expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));
expect(cost > 0n);
});
});
describe('Common metadata', () => {
+ let donor: IKeyringPair;
+ let alice: IKeyringPair;
+
before(async function() {
- await requirePallets(this, [Pallets.ReFungible]);
- });
+ await usingEthPlaygrounds(async (helper, privateKey) => {
+ requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);
- itWeb3('Returns collection name', async ({api, web3, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- name: 'token name',
- mode: {type: 'ReFungible'},
+ donor = privateKey('//Alice');
+ [alice] = await helper.arrange.createAccounts([20n], donor);
});
- const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+ });
- const address = collectionIdToAddress(collection);
- const contract = evmCollection(web3, caller, address, {type: 'ReFungible'});
+ itEth('Returns collection name', async ({helper}) => {
+ const caller = helper.eth.createAccount();
+ const collection = await helper.rft.mintCollection(alice, {name: 'Leviathan', tokenPrefix: '11'});
+
+ const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'rft', caller);
const name = await contract.methods.name().call();
-
- expect(name).to.equal('token name');
+ expect(name).to.equal('Leviathan');
});
- itWeb3('Returns symbol name', async ({api, web3, privateKeyWrapper}) => {
- const collection = await createCollectionExpectSuccess({
- tokenPrefix: 'TOK',
- mode: {type: 'ReFungible'},
- });
- const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
-
- const address = collectionIdToAddress(collection);
- const contract = evmCollection(web3, caller, address, {type: 'ReFungible'});
+ itEth('Returns symbol name', async ({helper}) => {
+ const caller = await helper.eth.createAccountWithBalance(donor);
+ const {collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'Leviathan', '', '12');
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
const symbol = await contract.methods.symbol().call();
-
- expect(symbol).to.equal('TOK');
+ expect(symbol).to.equal('12');
});
});
tests/src/eth/reFungibleToken.test.tsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {approve, createCollection, createRefungibleToken, transfer, transferFrom, UNIQUE, requirePallets, Pallets} from '../util/helpers';18import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, createRFTCollection, evmCollection, evmCollectionHelpers, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, tokenIdToAddress, transferBalanceToEth, uniqueRefungible, uniqueRefungibleToken} from './util/helpers';1920import chai from 'chai';21import chaiAsPromised from 'chai-as-promised';22chai.use(chaiAsPromised);23const expect = chai.expect;2425describe('Refungible token: Information getting', () => {26 before(async function() {27 await requirePallets(this, [Pallets.ReFungible]);28 });2930 itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {31 const alice = privateKeyWrapper('//Alice');3233 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;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();4243 expect(totalSupply).to.equal('200');44 });4546 itWeb3('balanceOf', async ({api, web3, privateKeyWrapper}) => {47 const alice = privateKeyWrapper('//Alice');4849 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;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();5859 expect(balance).to.equal('200');60 });6162 itWeb3('decimals', async ({api, web3, privateKeyWrapper}) => {63 const alice = privateKeyWrapper('//Alice');6465 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;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();7475 expect(decimals).to.equal('0');76 });77});7879// FIXME: Need erc721 for ReFubgible.80describe('Check ERC721 token URI for ReFungible', () => {81 before(async function() {82 await requirePallets(this, [Pallets.ReFungible]);83 });8485 itWeb3('Empty tokenURI', async ({web3, api, privateKeyWrapper}) => {86 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);87 const helper = evmCollectionHelpers(web3, owner);88 let result = await helper.methods.createERC721MetadataCompatibleCollection('Mint collection', '1', '1', '').send();89 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);90 const receiver = createEthAccount(web3);91 const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});9293 const nextTokenId = await contract.methods.nextTokenId().call();94 expect(nextTokenId).to.be.equal('1');95 result = await contract.methods.mint(96 receiver,97 nextTokenId,98 ).send();99100 const events = normalizeEvents(result.events);101 const address = collectionIdToAddress(collectionId);102103 expect(events).to.be.deep.equal([104 {105 address,106 event: 'Transfer',107 args: {108 from: '0x0000000000000000000000000000000000000000',109 to: receiver,110 tokenId: nextTokenId,111 },112 },113 ]);114115 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('');116 });117118 itWeb3('TokenURI from url', async ({web3, api, privateKeyWrapper}) => {119 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);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');152 });153154 itWeb3('TokenURI from baseURI + tokenId', async ({web3, api, privateKeyWrapper}) => {155 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);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);185 });186187 itWeb3('TokenURI from baseURI + suffix', async ({web3, api, privateKeyWrapper}) => {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';204 await contract.methods.setProperty(nextTokenId, 'suffix', Buffer.from(suffix)).send();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);222 });223});224225describe('Refungible: Plain calls', () => {226 before(async function() {227 await requirePallets(this, [Pallets.ReFungible]);228 });229230 itWeb3('Can perform approve()', async ({web3, api, privateKeyWrapper}) => {231 const alice = privateKeyWrapper('//Alice');232233 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;234235 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 {246 const result = await contract.methods.approve(spender, 100).send({from: owner});247 const events = normalizeEvents(result.events);248249 expect(events).to.be.deep.equal([250 {251 address,252 event: 'Approval',253 args: {254 owner,255 spender,256 value: '100',257 },258 },259 ]);260 }261262 {263 const allowance = await contract.methods.allowance(owner, spender).call();264 expect(+allowance).to.equal(100);265 }266 });267268 itWeb3('Can perform transferFrom()', async ({web3, api, privateKeyWrapper}) => {269 const alice = privateKeyWrapper('//Alice');270271 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;272273 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();287288 {289 const result = await contract.methods.transferFrom(owner, receiver, 49).send({from: spender});290 const events = normalizeEvents(result.events);291 expect(events).to.include.deep.members([292 {293 address,294 event: 'Transfer',295 args: {296 from: owner,297 to: receiver,298 value: '49',299 },300 },301 {302 address,303 event: 'Approval',304 args: {305 owner,306 spender,307 value: '51',308 },309 },310 ]);311 }312313 {314 const balance = await contract.methods.balanceOf(receiver).call();315 expect(+balance).to.equal(49);316 }317318 {319 const balance = await contract.methods.balanceOf(owner).call();320 expect(+balance).to.equal(151);321 }322 });323324 itWeb3('Can perform transfer()', async ({web3, api, privateKeyWrapper}) => {325 const alice = privateKeyWrapper('//Alice');326327 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;328329 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 {341 const result = await contract.methods.transfer(receiver, 50).send({from: owner});342 const events = normalizeEvents(result.events);343 expect(events).to.include.deep.members([344 {345 address,346 event: 'Transfer',347 args: {348 from: owner,349 to: receiver,350 value: '50',351 },352 },353 ]);354 }355356 {357 const balance = await contract.methods.balanceOf(owner).call();358 expect(+balance).to.equal(150);359 }360361 {362 const balance = await contract.methods.balanceOf(receiver).call();363 expect(+balance).to.equal(50);364 }365 });366367 itWeb3('Can perform repartition()', async ({web3, api, privateKeyWrapper}) => {368 const alice = privateKeyWrapper('//Alice');369370 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;371372 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});384 expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(200);385 await contract.methods.transfer(receiver, 110).send({from: owner});386 expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(90);387 expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(110);388389 await expect(contract.methods.repartition(80).send({from: owner})).to.eventually.be.rejected;390391 await contract.methods.transfer(receiver, 90).send({from: owner});392 expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(0);393 expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(200);394395 await contract.methods.repartition(150).send({from: receiver});396 await expect(contract.methods.transfer(owner, 160).send({from: receiver})).to.eventually.be.rejected;397 expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(150);398 });399400 itWeb3('Can repartition with increased amount', async ({web3, api, privateKeyWrapper}) => {401 const alice = privateKeyWrapper('//Alice');402403 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;404405 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();414 const events = normalizeEvents(result.events);415416 expect(events).to.deep.equal([417 {418 address,419 event: 'Transfer',420 args: {421 from: '0x0000000000000000000000000000000000000000',422 to: owner,423 value: '100',424 },425 },426 ]);427 });428429 itWeb3('Can repartition with decreased amount', async ({web3, api, privateKeyWrapper}) => {430 const alice = privateKeyWrapper('//Alice');431432 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;433434 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();443 const events = normalizeEvents(result.events);444 expect(events).to.deep.equal([445 {446 address,447 event: 'Transfer',448 args: {449 from: owner,450 to: '0x0000000000000000000000000000000000000000',451 value: '50',452 },453 },454 ]);455 });456457 itWeb3('Receiving Transfer event on burning into full ownership', async ({web3, api, privateKeyWrapper}) => {458 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);459 const receiver = await createEthAccountWithBalance(api, web3, privateKeyWrapper);460 const helper = evmCollectionHelpers(web3, caller);461 const result = await helper.methods.createRFTCollection('Mint collection', '6', '6').send();462 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);463 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});464465 const tokenId = await contract.methods.nextTokenId().call();466 await contract.methods.mint(caller, tokenId).send();467468 const address = tokenIdToAddress(collectionId, tokenId);469470 const tokenContract = uniqueRefungibleToken(web3, address, caller);471 await tokenContract.methods.repartition(2).send();472 await tokenContract.methods.transfer(receiver, 1).send();473474 const events = await recordEvents(contract, async () =>475 await tokenContract.methods.burnFrom(caller, 1).send());476 expect(events).to.deep.equal([477 {478 address: collectionIdAddress,479 event: 'Transfer',480 args: {481 from: '0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF',482 to: receiver,483 tokenId,484 },485 },486 ]);487 });488});489490describe('Refungible: Fees', () => {491 before(async function() {492 await requirePallets(this, [Pallets.ReFungible]);493 });494495 itWeb3('approve() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {496 const alice = privateKeyWrapper('//Alice');497498 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;499500 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);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)));510 });511512 itWeb3('transferFrom() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {513 const alice = privateKeyWrapper('//Alice');514515 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;516517 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});526527 const cost = await recordEthFee(api, spender, () => contract.methods.transferFrom(owner, spender, 100).send({from: spender}));528 expect(cost < BigInt(0.2 * Number(UNIQUE)));529 });530531 itWeb3('transfer() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {532 const alice = privateKeyWrapper('//Alice');533534 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;535536 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);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)));546 });547});548549describe('Refungible: Substrate calls', () => {550 before(async function() {551 await requirePallets(this, [Pallets.ReFungible]);552 });553554 itWeb3('Events emitted for approve()', async ({web3, api, privateKeyWrapper}) => {555 const alice = privateKeyWrapper('//Alice');556557 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;558559 const receiver = createEthAccount(web3);560561 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;562563 const address = tokenIdToAddress(collectionId, tokenId);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;568 });569570 expect(events).to.be.deep.equal([571 {572 address,573 event: 'Approval',574 args: {575 owner: subToEth(alice.address),576 spender: receiver,577 value: '100',578 },579 },580 ]);581 });582583 itWeb3('Events emitted for transferFrom()', async ({web3, api, privateKeyWrapper}) => {584 const alice = privateKeyWrapper('//Alice');585586 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;587 const bob = privateKeyWrapper('//Bob');588589 const receiver = createEthAccount(web3);590591 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;592 expect(await approve(api, collectionId, tokenId, alice, bob.address, 100n)).to.be.true;593594 const address = tokenIdToAddress(collectionId, tokenId);595 const contract = uniqueRefungibleToken(web3, address);596597 const events = await recordEvents(contract, async () => {598 expect(await transferFrom(api, collectionId, tokenId, bob, alice, {Ethereum: receiver}, 51n)).to.be.true;599 });600601 expect(events).to.be.deep.equal([602 {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),617 value: '49',618 },619 },620 ]);621 });622623 itWeb3('Events emitted for transfer()', async ({web3, api, privateKeyWrapper}) => {624 const alice = privateKeyWrapper('//Alice');625626 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;627628 const receiver = createEthAccount(web3);629630 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;631632 const address = tokenIdToAddress(collectionId, tokenId);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;637 });638639 expect(events).to.be.deep.equal([640 {641 address,642 event: 'Transfer',643 args: {644 from: subToEth(alice.address),645 to: receiver,646 value: '51',647 },648 },649 ]);650 });651});652653describe('ERC 1633 implementation', () => {654 before(async function() {655 await requirePallets(this, [Pallets.ReFungible]);656 });657658 itWeb3('Default parent token address and id', async ({api, web3, privateKeyWrapper}) => {659 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);660661 const {collectionIdAddress, collectionId} = await createRFTCollection(api, web3, owner);662 const refungibleContract = uniqueRefungible(web3, collectionIdAddress, owner);663 const refungibleTokenId = await refungibleContract.methods.nextTokenId().call();664 await refungibleContract.methods.mint(owner, refungibleTokenId).send();665666 const rftTokenAddress = tokenIdToAddress(collectionId, refungibleTokenId);667 const refungibleTokenContract = uniqueRefungibleToken(web3, rftTokenAddress, owner);668669 const tokenAddress = await refungibleTokenContract.methods.parentToken().call();670 const tokenId = await refungibleTokenContract.methods.parentTokenId().call();671 expect(tokenAddress).to.be.equal(collectionIdAddress);672 expect(tokenId).to.be.equal(refungibleTokenId);673 });674});1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {Pallets, requirePalletsOrSkip} from '../util/playgrounds';18import {EthUniqueHelper, expect, itEth, usingEthPlaygrounds} from './util/playgrounds';19import {IKeyringPair} from '@polkadot/types/types';20import {Contract} from 'web3-eth-contract';2122describe('Refungible token: Information getting', () => {23 let donor: IKeyringPair;24 let alice: IKeyringPair;2526 before(async function() {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 });33 });3435 itEth('totalSupply', async ({helper}) => {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});3940 const contract = helper.ethNativeContract.rftTokenById(collection.collectionId, tokenId, caller);41 const totalSupply = await contract.methods.totalSupply().call();42 expect(totalSupply).to.equal('200');43 });4445 itEth('balanceOf', async ({helper}) => {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});4950 const contract = helper.ethNativeContract.rftTokenById(collection.collectionId, tokenId, caller);51 const balance = await contract.methods.balanceOf(caller).call();52 expect(balance).to.equal('200');53 });5455 itEth('decimals', async ({helper}) => {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});5960 const contract = helper.ethNativeContract.rftTokenById(collection.collectionId, tokenId, caller);61 const decimals = await contract.methods.decimals().call();62 expect(decimals).to.equal('0');63 });64});6566// FIXME: Need erc721 for ReFubgible.67describe('Check ERC721 token URI for ReFungible', () => {68 let donor: IKeyringPair;6970 before(async function() {71 await usingEthPlaygrounds(async (helper, privateKey) => {72 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);7374 donor = privateKey('//Alice');75 });76 });7778 async function setup(helper: EthUniqueHelper, tokenPrefix: string, propertyKey?: string, propertyValue?: string): Promise<{contract: Contract, nextTokenId: string}> {79 const owner = await helper.eth.createAccountWithBalance(donor);80 const receiver = helper.eth.createAccount();8182 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 87 const nextTokenId = await contract.methods.nextTokenId().call();88 expect(nextTokenId).to.be.equal('1');89 result = await contract.methods.mint(90 receiver,91 nextTokenId,92 ).send();9394 if (propertyKey && propertyValue) {95 // Set URL or suffix96 await contract.methods.setProperty(nextTokenId, propertyKey, Buffer.from(propertyValue)).send();97 }9899 const event = result.events.Transfer;100 expect(event.address).to.be.equal(collectionAddress);101 expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');102 expect(event.returnValues.to).to.be.equal(receiver);103 expect(event.returnValues.tokenId).to.be.equal(nextTokenId);104105 return {contract, nextTokenId};106 }107108 itEth('Empty tokenURI', async ({helper}) => {109 const {contract, nextTokenId} = await setup(helper, '');110 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('');111 });112113 itEth('TokenURI from url', async ({helper}) => {114 const {contract, nextTokenId} = await setup(helper, 'BaseURI_', 'url', 'Token URI');115 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Token URI');116 });117118 itEth('TokenURI from baseURI + tokenId', async ({helper}) => {119 const {contract, nextTokenId} = await setup(helper, 'BaseURI_');120 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('BaseURI_' + nextTokenId);121 });122123 itEth('TokenURI from baseURI + suffix', async ({helper}) => {124 const suffix = '/some/suffix';125 const {contract, nextTokenId} = await setup(helper, 'BaseURI_', 'suffix', suffix);126 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('BaseURI_' + suffix);127 });128});129130describe('Refungible: Plain calls', () => {131 let donor: IKeyringPair;132 let alice: IKeyringPair;133134 before(async function() {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 });141 });142143 itEth('Can perform approve()', async ({helper}) => {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});148149 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);150 const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);151152 {153 const result = await contract.methods.approve(spender, 100).send({from: owner});154 const event = result.events.Approval;155 expect(event.address).to.be.equal(tokenAddress);156 expect(event.returnValues.owner).to.be.equal(owner);157 expect(event.returnValues.spender).to.be.equal(spender);158 expect(event.returnValues.value).to.be.equal('100');159 }160161 {162 const allowance = await contract.methods.allowance(owner, spender).call();163 expect(+allowance).to.equal(100);164 }165 });166167 itEth('Can perform transferFrom()', async ({helper}) => {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});173174 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);175 const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);176177 await contract.methods.approve(spender, 100).send();178179 {180 const result = await contract.methods.transferFrom(owner, receiver, 49).send({from: spender});181 let event = result.events.Transfer;182 expect(event.address).to.be.equal(tokenAddress);183 expect(event.returnValues.from).to.be.equal(owner);184 expect(event.returnValues.to).to.be.equal(receiver);185 expect(event.returnValues.value).to.be.equal('49');186187 event = result.events.Approval;188 expect(event.address).to.be.equal(tokenAddress);189 expect(event.returnValues.owner).to.be.equal(owner);190 expect(event.returnValues.spender).to.be.equal(spender);191 expect(event.returnValues.value).to.be.equal('51');192 }193194 {195 const balance = await contract.methods.balanceOf(receiver).call();196 expect(+balance).to.equal(49);197 }198199 {200 const balance = await contract.methods.balanceOf(owner).call();201 expect(+balance).to.equal(151);202 }203 });204205 itEth('Can perform transfer()', async ({helper}) => {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});210211 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);212 const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);213214 {215 const result = await contract.methods.transfer(receiver, 50).send({from: owner});216 const event = result.events.Transfer;217 expect(event.address).to.be.equal(tokenAddress);218 expect(event.returnValues.from).to.be.equal(owner);219 expect(event.returnValues.to).to.be.equal(receiver);220 expect(event.returnValues.value).to.be.equal('50');221 }222223 {224 const balance = await contract.methods.balanceOf(owner).call();225 expect(+balance).to.equal(150);226 }227228 {229 const balance = await contract.methods.balanceOf(receiver).call();230 expect(+balance).to.equal(50);231 }232 });233234 itEth('Can perform repartition()', async ({helper}) => {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});239240 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);241 const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);242243 await contract.methods.repartition(200).send({from: owner});244 expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(200);245 await contract.methods.transfer(receiver, 110).send({from: owner});246 expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(90);247 expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(110);248249 await expect(contract.methods.repartition(80).send({from: owner})).to.eventually.be.rejected; // Transaction is reverted250251 await contract.methods.transfer(receiver, 90).send({from: owner});252 expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(0);253 expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(200);254255 await contract.methods.repartition(150).send({from: receiver});256 await expect(contract.methods.transfer(owner, 160).send({from: receiver})).to.eventually.be.rejected; // Transaction is reverted257 expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(150);258 });259260 itEth('Can repartition with increased amount', async ({helper}) => {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});264265 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);266 const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);267268 const result = await contract.methods.repartition(200).send();269270 const event = result.events.Transfer;271 expect(event.address).to.be.equal(tokenAddress);272 expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');273 expect(event.returnValues.to).to.be.equal(owner);274 expect(event.returnValues.value).to.be.equal('100');275 });276277 itEth('Can repartition with decreased amount', async ({helper}) => {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});281282 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);283 const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);284285 const result = await contract.methods.repartition(50).send();286 const event = result.events.Transfer;287 expect(event.address).to.be.equal(tokenAddress);288 expect(event.returnValues.from).to.be.equal(owner);289 expect(event.returnValues.to).to.be.equal('0x0000000000000000000000000000000000000000');290 expect(event.returnValues.value).to.be.equal('50');291 });292293 itEth('Receiving Transfer event on burning into full ownership', async ({helper}) => {294 const caller = await helper.eth.createAccountWithBalance(donor);295 const receiver = await helper.eth.createAccountWithBalance(donor);296 const {collectionId, collectionAddress} = await helper.eth.createRefungibleCollection(caller, 'Devastation', '6', '6');297 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);298299 const tokenId = await contract.methods.nextTokenId().call();300 await contract.methods.mint(caller, tokenId).send();301 const tokenAddress = helper.ethAddress.fromTokenId(collectionId, tokenId);302 const tokenContract = helper.ethNativeContract.rftToken(tokenAddress, caller);303304 await tokenContract.methods.repartition(2).send();305 await tokenContract.methods.transfer(receiver, 1).send();306307 const events: any = [];308 contract.events.allEvents((_: any, event: any) => {309 events.push(event);310 });311 await tokenContract.methods.burnFrom(caller, 1).send();312313 const event = events[0];314 expect(event.address).to.be.equal(collectionAddress);315 expect(event.returnValues.from).to.be.equal('0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF');316 expect(event.returnValues.to).to.be.equal(receiver);317 expect(event.returnValues.tokenId).to.be.equal(tokenId);318 });319});320321describe('Refungible: Fees', () => {322 let donor: IKeyringPair;323 let alice: IKeyringPair;324325 before(async function() {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 });332 });333334 itEth('approve() call fee is less than 0.2UNQ', async ({helper}) => {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});339340 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);341 const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);342343 const cost = await helper.eth.recordCallFee(owner, () => contract.methods.approve(spender, 100).send({from: owner}));344 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));345 });346347 itEth('transferFrom() call fee is less than 0.2UNQ', async ({helper}) => {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});352353 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);354 const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);355356 await contract.methods.approve(spender, 100).send({from: owner});357358 const cost = await helper.eth.recordCallFee(spender, () => contract.methods.transferFrom(owner, spender, 100).send({from: spender}));359 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));360 });361362 itEth('transfer() call fee is less than 0.2UNQ', async ({helper}) => {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});367368 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);369 const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);370371 const cost = await helper.eth.recordCallFee(owner, () => contract.methods.transfer(receiver, 100).send({from: owner}));372 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));373 });374});375376describe('Refungible: Substrate calls', () => {377 let donor: IKeyringPair;378 let alice: IKeyringPair;379380 before(async function() {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 });387 });388389 itEth('Events emitted for approve()', async ({helper}) => {390 const receiver = helper.eth.createAccount();391 const collection = await helper.rft.mintCollection(alice);392 const token = await collection.mintToken(alice, 200n);393394 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, token.tokenId);395 const contract = helper.ethNativeContract.rftToken(tokenAddress);396397 const events: any = [];398 contract.events.allEvents((_: any, event: any) => {399 events.push(event);400 });401 expect(await token.approve(alice, {Ethereum: receiver}, 100n)).to.be.true;402403 const event = events[0];404 expect(event.event).to.be.equal('Approval');405 expect(event.address).to.be.equal(tokenAddress);406 expect(event.returnValues.owner).to.be.equal(helper.address.substrateToEth(alice.address));407 expect(event.returnValues.spender).to.be.equal(receiver);408 expect(event.returnValues.value).to.be.equal('100');409 });410411 itEth('Events emitted for transferFrom()', async ({helper}) => {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);417418 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, token.tokenId);419 const contract = helper.ethNativeContract.rftToken(tokenAddress);420421 const events: any = [];422 contract.events.allEvents((_: any, event: any) => {423 events.push(event);424 });425426 expect(await token.transferFrom(bob, {Substrate: alice.address}, {Ethereum: receiver}, 51n)).to.be.true;427428 let event = events[0];429 expect(event.event).to.be.equal('Transfer');430 expect(event.address).to.be.equal(tokenAddress);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');434435 event = events[1];436 expect(event.event).to.be.equal('Approval');437 expect(event.address).to.be.equal(tokenAddress);438 expect(event.returnValues.owner).to.be.equal(helper.address.substrateToEth(alice.address));439 expect(event.returnValues.spender).to.be.equal(helper.address.substrateToEth(bob.address));440 expect(event.returnValues.value).to.be.equal('49');441 });442443 itEth('Events emitted for transfer()', async ({helper}) => {444 const receiver = helper.eth.createAccount();445 const collection = await helper.rft.mintCollection(alice);446 const token = await collection.mintToken(alice, 200n);447448 const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, token.tokenId);449 const contract = helper.ethNativeContract.rftToken(tokenAddress);450451 const events: any = [];452 contract.events.allEvents((_: any, event: any) => {453 events.push(event);454 });455456 expect(await token.transfer(alice, {Ethereum: receiver}, 51n)).to.be.true;457458 const event = events[0];459 expect(event.event).to.be.equal('Transfer');460 expect(event.address).to.be.equal(tokenAddress);461 expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));462 expect(event.returnValues.to).to.be.equal(receiver);463 expect(event.returnValues.value).to.be.equal('51');464 });465});466467describe('ERC 1633 implementation', () => {468 let donor: IKeyringPair;469470 before(async function() {471 await usingEthPlaygrounds(async (helper, privateKey) => {472 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);473474 donor = privateKey('//Alice');475 });476 });477478 itEth('Default parent token address and id', async ({helper}) => {479 const owner = await helper.eth.createAccountWithBalance(donor);480481 const {collectionId, collectionAddress} = await helper.eth.createRefungibleCollection(owner, 'Sands', '', 'GRAIN');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);488489 expect(await tokenContract.methods.parentToken().call()).to.be.equal(collectionAddress);490 expect(await tokenContract.methods.parentTokenId().call()).to.be.equal(tokenId);491 });492});tests/src/eth/util/playgrounds/unique.dev.tsdiffbeforeafterboth--- a/tests/src/eth/util/playgrounds/unique.dev.ts
+++ b/tests/src/eth/util/playgrounds/unique.dev.ts
@@ -116,13 +116,17 @@
return new web3.eth.Contract(abi as any, address, {gas: this.helper.eth.DEFAULT_GAS, ...(caller ? {from: caller} : {})});
}
- rftTokenByAddress(address: string, caller?: string): Contract {
+ collectionById(collectionId: number, mode: 'nft' | 'rft' | 'ft', caller?: string): Contract {
+ return this.collection(this.helper.ethAddress.fromCollectionId(collectionId), mode, caller);
+ }
+
+ rftToken(address: string, caller?: string): Contract {
const web3 = this.helper.getWeb3();
return new web3.eth.Contract(refungibleTokenAbi as any, address, {gas: this.helper.eth.DEFAULT_GAS, ...(caller ? {from: caller} : {})});
}
- rftToken(collectionId: number, tokenId: number, caller?: string): Contract {
- return this.rftTokenByAddress(this.helper.ethAddress.fromTokenId(collectionId, tokenId), caller);
+ rftTokenById(collectionId: number, tokenId: number, caller?: string): Contract {
+ return this.rftToken(this.helper.ethAddress.fromTokenId(collectionId, tokenId), caller);
}
}
@@ -171,6 +175,17 @@
return {collectionId, collectionAddress};
}
+ async createRefungibleCollection(signer: string, name: string, description: string, tokenPrefix: string): Promise<{collectionId: number, collectionAddress: string}> {
+ const collectionHelper = this.helper.ethNativeContract.collectionHelpers(signer);
+
+ const result = await collectionHelper.methods.createRFTCollection(name, description, tokenPrefix).send();
+
+ const collectionAddress = this.helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);
+ const collectionId = this.helper.ethAddress.extractCollectionId(collectionAddress);
+
+ return {collectionId, collectionAddress};
+ }
+
async deployCollectorContract(signer: string): Promise<Contract> {
return await this.helper.ethContract.deployByCode(signer, 'Collector', `
// SPDX-License-Identifier: UNLICENSED
@@ -215,6 +230,16 @@
}
`);
}
+
+ async recordCallFee(user: string, call: () => Promise<any>): Promise<bigint> {
+ const before = await this.helper.balance.getEthereum(user);
+ await call();
+ // In dev mode, the transaction might not finish processing in time
+ await this.helper.wait.newBlocks(1);
+ const after = await this.helper.balance.getEthereum(user);
+
+ return before - after;
+ }
}
class EthAddressGroup extends EthGroupBase {