difftreelog
Merge pull request #567 from UniqueNetwork/test/playground-migration
in: master
Test/playground migration
5 files changed
tests/package.jsondiffbeforeafterboth--- a/tests/package.json
+++ b/tests/package.json
@@ -49,6 +49,7 @@
"testRemoveCollectionAdmin": "mocha --timeout 9999999 -r ts-node/register ./**/removeCollectionAdmin.test.ts",
"testRemoveCollectionSponsor": "mocha --timeout 9999999 -r ts-node/register ./**/removeCollectionSponsor.test.ts",
"testRemoveFromAllowList": "mocha --timeout 9999999 -r ts-node/register ./**/removeFromAllowList.test.ts",
+ "testAllowLists": "mocha --timeout 9999999 -r ts-node/register ./**/allowLists.test.ts",
"testConnection": "mocha --timeout 9999999 -r ts-node/register ./**/connection.test.ts",
"testContracts": "mocha --timeout 9999999 -r ts-node/register ./**/contracts.test.ts",
"testCreateItem": "mocha --timeout 9999999 -r ts-node/register ./**/createItem.test.ts",
tests/src/adminTransferAndBurn.test.tsdiffbeforeafterboth--- a/tests/src/adminTransferAndBurn.test.ts
+++ b/tests/src/adminTransferAndBurn.test.ts
@@ -17,56 +17,63 @@
import {IKeyringPair} from '@polkadot/types/types';
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
-import {default as usingApi} from './substrate/substrate-api';
-import {
- createCollectionExpectSuccess,
- createItemExpectSuccess,
- transferExpectFailure,
- transferFromExpectSuccess,
- burnItemExpectFailure,
- burnFromExpectSuccess,
- setCollectionLimitsExpectSuccess,
-} from './util/helpers';
+import {usingPlaygrounds} from './util/playgrounds';
chai.use(chaiAsPromised);
const expect = chai.expect;
+let donor: IKeyringPair;
+
+before(async () => {
+ await usingPlaygrounds(async (_, privateKey) => {
+ donor = privateKey('//Alice');
+ });
+});
+
describe('Integration Test: ownerCanTransfer allows admins to use only transferFrom/burnFrom:', () => {
let alice: IKeyringPair;
let bob: IKeyringPair;
let charlie: IKeyringPair;
before(async () => {
- await usingApi(async (api, privateKeyWrapper) => {
- alice = privateKeyWrapper('//Alice');
- bob = privateKeyWrapper('//Bob');
- charlie = privateKeyWrapper('//Charlie');
+ await usingPlaygrounds(async (helper) => {
+ [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
});
});
it('admin transfers other user\'s token', async () => {
- await usingApi(async () => {
- const collectionId = await createCollectionExpectSuccess();
- await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});
-
- const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', {Substrate: bob.address});
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'name', description: 'descr', tokenPrefix: 'COL'});
+ await helper.collection.setLimits(alice, collectionId, {ownerCanTransfer: true});
+ const limits = await helper.collection.getEffectiveLimits(collectionId);
+ expect(limits.ownerCanTransfer).to.be.true;
- await transferExpectFailure(collectionId, tokenId, alice, charlie);
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: bob.address});
+ const transferResult = async () => helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address});
+ await expect(transferResult()).to.be.rejected;
- await transferFromExpectSuccess(collectionId, tokenId, alice, bob, charlie, 1);
+ await helper.nft.transferTokenFrom(alice, collectionId, tokenId, {Substrate: bob.address}, {Substrate: charlie.address});
+ const newTokenOwner = await helper.nft.getTokenOwner(collectionId, tokenId);
+ expect(newTokenOwner.Substrate).to.be.equal(charlie.address);
});
});
it('admin burns other user\'s token', async () => {
- await usingApi(async () => {
- const collectionId = await createCollectionExpectSuccess();
- await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'name', description: 'descr', tokenPrefix: 'COL'});
+
+ await helper.collection.setLimits(alice, collectionId, {ownerCanTransfer: true});
+ const limits = await helper.collection.getEffectiveLimits(collectionId);
+ expect(limits.ownerCanTransfer).to.be.true;
- const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', {Substrate: bob.address});
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: bob.address});
+ const burnTxFailed = async () => helper.nft.burnToken(alice, collectionId, tokenId);
- await burnItemExpectFailure(alice, collectionId, tokenId);
+ await expect(burnTxFailed()).to.be.rejected;
- await burnFromExpectSuccess(alice, bob, collectionId, tokenId);
+ await helper.nft.burnToken(bob, collectionId, tokenId);
+ const token = await helper.nft.getToken(collectionId, tokenId);
+ expect(token).to.be.null;
});
});
});
tests/src/allowLists.test.tsdiffbeforeafterboth--- a/tests/src/allowLists.test.ts
+++ b/tests/src/allowLists.test.ts
@@ -17,31 +17,19 @@
import {IKeyringPair} from '@polkadot/types/types';
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
-import usingApi, {submitTransactionExpectFailAsync} from './substrate/substrate-api';
-import {
- addToAllowListExpectSuccess,
- createCollectionExpectSuccess,
- createItemExpectSuccess,
- destroyCollectionExpectSuccess,
- enableAllowListExpectSuccess,
- normalizeAccountId,
- addCollectionAdminExpectSuccess,
- addToAllowListExpectFail,
- removeFromAllowListExpectSuccess,
- removeFromAllowListExpectFailure,
- addToAllowListAgainExpectSuccess,
- transferExpectFailure,
- approveExpectSuccess,
- approveExpectFail,
- transferExpectSuccess,
- transferFromExpectSuccess,
- setMintPermissionExpectSuccess,
- createItemExpectFailure,
-} from './util/helpers';
+import {usingPlaygrounds} from './util/playgrounds';
chai.use(chaiAsPromised);
const expect = chai.expect;
+let donor: IKeyringPair;
+
+before(async () => {
+ await usingPlaygrounds(async (_, privateKey) => {
+ donor = privateKey('//Alice');
+ });
+});
+
let alice: IKeyringPair;
let bob: IKeyringPair;
let charlie: IKeyringPair;
@@ -49,266 +37,348 @@
describe('Integration Test ext. Allow list tests', () => {
before(async () => {
- await usingApi(async (api, privateKeyWrapper) => {
- alice = privateKeyWrapper('//Alice');
- bob = privateKeyWrapper('//Bob');
- charlie = privateKeyWrapper('//Charlie');
+ await usingPlaygrounds(async (helper) => {
+ [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);
});
});
it('Owner can add address to allow list', async () => {
- const collectionId = await createCollectionExpectSuccess();
- await addToAllowListExpectSuccess(alice, collectionId, bob.address);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address});
+ const allowList = await helper.nft.getAllowList(collectionId);
+ expect(allowList).to.be.deep.contains({Substrate: bob.address});
+ });
});
it('Admin can add address to allow list', async () => {
- const collectionId = await createCollectionExpectSuccess();
- await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
- await addToAllowListExpectSuccess(bob, collectionId, charlie.address);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ await helper.nft.addAdmin(alice, collectionId, {Substrate: bob.address});
+
+ await helper.nft.addToAllowList(bob, collectionId, {Substrate: charlie.address});
+ const allowList = await helper.nft.getAllowList(collectionId);
+ expect(allowList).to.be.deep.contains({Substrate: charlie.address});
+ });
});
it('Non-privileged user cannot add address to allow list', async () => {
- const collectionId = await createCollectionExpectSuccess();
- await addToAllowListExpectFail(bob, collectionId, charlie.address);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const addToAllowListTx = async () => helper.nft.addToAllowList(bob, collectionId, {Substrate: charlie.address});
+ await expect(addToAllowListTx()).to.be.rejected;
+ });
});
it('Nobody can add address to allow list of non-existing collection', async () => {
const collectionId = (1<<32) - 1;
- await addToAllowListExpectFail(alice, collectionId, bob.address);
+ await usingPlaygrounds(async (helper) => {
+ const addToAllowListTx = async () => helper.nft.addToAllowList(bob, collectionId, {Substrate: charlie.address});
+ await expect(addToAllowListTx()).to.be.rejected;
+ });
});
it('Nobody can add address to allow list of destroyed collection', async () => {
- const collectionId = await createCollectionExpectSuccess();
- await destroyCollectionExpectSuccess(collectionId, '//Alice');
- await addToAllowListExpectFail(alice, collectionId, bob.address);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ await helper.collection.burn(alice, collectionId);
+ const addToAllowListTx = async () => helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address});
+ await expect(addToAllowListTx()).to.be.rejected;
+ });
});
it('If address is already added to allow list, nothing happens', async () => {
- const collectionId = await createCollectionExpectSuccess();
- await addToAllowListExpectSuccess(alice, collectionId, bob.address);
- await addToAllowListAgainExpectSuccess(alice, collectionId, bob.address);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address});
+ await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address});
+ const allowList = await helper.nft.getAllowList(collectionId);
+ expect(allowList).to.be.deep.contains({Substrate: bob.address});
+ });
});
it('Owner can remove address from allow list', async () => {
- const collectionId = await createCollectionExpectSuccess();
- await addToAllowListExpectSuccess(alice, collectionId, bob.address);
- await removeFromAllowListExpectSuccess(alice, collectionId, normalizeAccountId(bob));
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address});
+
+ await helper.collection.removeFromAllowList(alice, collectionId, {Substrate: bob.address});
+
+ const allowList = await helper.nft.getAllowList(collectionId);
+
+ expect(allowList).to.be.not.deep.contains({Substrate: bob.address});
+ });
});
it('Admin can remove address from allow list', async () => {
- const collectionId = await createCollectionExpectSuccess();
- await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
- await addToAllowListExpectSuccess(alice, collectionId, charlie.address);
- await removeFromAllowListExpectSuccess(bob, collectionId, normalizeAccountId(charlie));
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ await helper.nft.addAdmin(alice, collectionId, {Substrate: charlie.address});
+ await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address});
+ await helper.collection.removeFromAllowList(charlie, collectionId, {Substrate: bob.address});
+
+ const allowList = await helper.nft.getAllowList(collectionId);
+
+ expect(allowList).to.be.not.deep.contains({Substrate: bob.address});
+ });
});
it('Non-privileged user cannot remove address from allow list', async () => {
- const collectionId = await createCollectionExpectSuccess();
- await addToAllowListExpectSuccess(alice, collectionId, charlie.address);
- await removeFromAllowListExpectFailure(bob, collectionId, normalizeAccountId(charlie));
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address});
+ const removeTx = async () => helper.collection.removeFromAllowList(bob, collectionId, {Substrate: charlie.address});
+ await expect(removeTx()).to.be.rejected;
+ const allowList = await helper.nft.getAllowList(collectionId);
+
+ expect(allowList).to.be.deep.contains({Substrate: charlie.address});
+ });
});
it('Nobody can remove address from allow list of non-existing collection', async () => {
const collectionId = (1<<32) - 1;
- await removeFromAllowListExpectFailure(alice, collectionId, normalizeAccountId(charlie));
+ await usingPlaygrounds(async (helper) => {
+ const removeTx = async () => helper.collection.removeFromAllowList(bob, collectionId, {Substrate: charlie.address});
+ await expect(removeTx()).to.be.rejected;
+ });
});
it('Nobody can remove address from allow list of deleted collection', async () => {
- const collectionId = await createCollectionExpectSuccess();
- await addToAllowListExpectSuccess(alice, collectionId, charlie.address);
- await destroyCollectionExpectSuccess(collectionId, '//Alice');
- await removeFromAllowListExpectFailure(alice, collectionId, normalizeAccountId(charlie));
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address});
+ await helper.collection.burn(alice, collectionId);
+ const removeTx = async () => helper.collection.removeFromAllowList(alice, collectionId, {Substrate: bob.address});
+
+ await expect(removeTx()).to.be.rejected;
+ });
});
it('If address is already removed from allow list, nothing happens', async () => {
- const collectionId = await createCollectionExpectSuccess();
- await addToAllowListExpectSuccess(alice, collectionId, charlie.address);
- await removeFromAllowListExpectSuccess(alice, collectionId, normalizeAccountId(charlie));
- await removeFromAllowListExpectSuccess(alice, collectionId, normalizeAccountId(charlie));
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address});
+ await helper.collection.removeFromAllowList(alice, collectionId, {Substrate: bob.address});
+ const allowListBefore = await helper.nft.getAllowList(collectionId);
+ expect(allowListBefore).to.be.not.deep.contains({Substrate: bob.address});
+
+ await helper.collection.removeFromAllowList(alice, collectionId, {Substrate: bob.address});
+
+ const allowListAfter = await helper.nft.getAllowList(collectionId);
+ expect(allowListAfter).to.be.not.deep.contains({Substrate: bob.address});
+ });
});
it('If Public Access mode is set to AllowList, tokens can’t be transferred from a non-allowlisted address with transfer or transferFrom. Test1', async () => {
- const collectionId = await createCollectionExpectSuccess();
- const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
- await enableAllowListExpectSuccess(alice, collectionId);
- await addToAllowListExpectSuccess(alice, collectionId, charlie.address);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});
+ await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});
+ await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address});
- await transferExpectFailure(
- collectionId,
- itemId,
- alice,
- charlie,
- 1,
- );
+ const transferResult = async () => helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address});
+ await expect(transferResult()).to.be.rejected;
+ });
});
it('If Public Access mode is set to AllowList, tokens can’t be transferred from a non-allowlisted address with transfer or transferFrom. Test2', async () => {
- const collectionId = await createCollectionExpectSuccess();
- const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
- await enableAllowListExpectSuccess(alice, collectionId);
- await addToAllowListExpectSuccess(alice, collectionId, alice.address);
- await addToAllowListExpectSuccess(alice, collectionId, charlie.address);
- await approveExpectSuccess(collectionId, itemId, alice, charlie.address);
- await removeFromAllowListExpectSuccess(alice, collectionId, normalizeAccountId(alice));
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});
+ await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});
+ await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address});
+ await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address});
+ await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: charlie.address});
+ await helper.collection.removeFromAllowList(alice, collectionId, {Substrate: alice.address});
- await transferExpectFailure(
- collectionId,
- itemId,
- alice,
- charlie,
- 1,
- );
+ const transferResult = async () => helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address});
+ await expect(transferResult()).to.be.rejected;
+ });
});
it('If Public Access mode is set to AllowList, tokens can’t be transferred to a non-allowlisted address with transfer or transferFrom. Test1', async () => {
- const collectionId = await createCollectionExpectSuccess();
- const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
- await enableAllowListExpectSuccess(alice, collectionId);
- await addToAllowListExpectSuccess(alice, collectionId, alice.address);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});
+ await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});
+ await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address});
- await transferExpectFailure(
- collectionId,
- itemId,
- alice,
- charlie,
- 1,
- );
+ const transferResult = async () => helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address});
+ await expect(transferResult()).to.be.rejected;
+ });
});
it('If Public Access mode is set to AllowList, tokens can’t be transferred to a non-allowlisted address with transfer or transferFrom. Test2', async () => {
- const collectionId = await createCollectionExpectSuccess();
- const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
- await enableAllowListExpectSuccess(alice, collectionId);
- await addToAllowListExpectSuccess(alice, collectionId, alice.address);
- await addToAllowListExpectSuccess(alice, collectionId, charlie.address);
- await approveExpectSuccess(collectionId, itemId, alice, charlie.address);
- await removeFromAllowListExpectSuccess(alice, collectionId, normalizeAccountId(alice));
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});
+ await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});
+ await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address});
+ await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address});
+
+ await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: charlie.address});
+ await helper.collection.removeFromAllowList(alice, collectionId, {Substrate: alice.address});
- await transferExpectFailure(
- collectionId,
- itemId,
- alice,
- charlie,
- 1,
- );
+ const transferResult = async () => helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address});
+ await expect(transferResult()).to.be.rejected;
+ });
});
it('If Public Access mode is set to AllowList, tokens can’t be destroyed by a non-allowlisted address (even if it owned them before enabling AllowList mode)', async () => {
- const collectionId = await createCollectionExpectSuccess();
- const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
- await enableAllowListExpectSuccess(alice, collectionId);
-
- await usingApi(async (api) => {
- const tx = api.tx.unique.burnItem(collectionId, itemId, /*normalizeAccountId(Alice.address),*/ 11);
- const badTransaction = async function () {
- await submitTransactionExpectFailAsync(alice, tx);
- };
- await expect(badTransaction()).to.be.rejected;
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});
+ await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});
+ const burnTx = async () => helper.nft.burnToken(bob, collectionId, tokenId);
+ await expect(burnTx()).to.be.rejected;
});
});
it('If Public Access mode is set to AllowList, token transfers can’t be Approved by a non-allowlisted address (see Approve method)', async () => {
- const collectionId = await createCollectionExpectSuccess();
- const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
- await enableAllowListExpectSuccess(alice, collectionId);
- await approveExpectFail(collectionId, itemId, alice, bob);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});
+ await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});
+ const approveTx = async () => helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});
+ await expect(approveTx()).to.be.rejected;
+ });
});
it('If Public Access mode is set to AllowList, tokens can be transferred to a allowlisted address with transfer.', async () => {
- const collectionId = await createCollectionExpectSuccess();
- const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
- await enableAllowListExpectSuccess(alice, collectionId);
- await addToAllowListExpectSuccess(alice, collectionId, alice.address);
- await addToAllowListExpectSuccess(alice, collectionId, charlie.address);
- await transferExpectSuccess(collectionId, itemId, alice, charlie, 1, 'NFT');
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});
+ await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});
+ await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address});
+ await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address});
+ await helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address});
+ const owner = await helper.nft.getTokenOwner(collectionId, tokenId);
+ expect(owner.Substrate).to.be.equal(charlie.address);
+ });
});
- it('If Public Access mode is set to AllowList, tokens can be transferred to a alowlisted address with transferFrom.', async () => {
- const collectionId = await createCollectionExpectSuccess();
- const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
- await enableAllowListExpectSuccess(alice, collectionId);
- await addToAllowListExpectSuccess(alice, collectionId, alice.address);
- await addToAllowListExpectSuccess(alice, collectionId, charlie.address);
- await approveExpectSuccess(collectionId, itemId, alice, charlie.address);
- await transferFromExpectSuccess(collectionId, itemId, alice, alice, charlie, 1, 'NFT');
+ it('If Public Access mode is set to AllowList, tokens can be transferred to a allowlisted address with transferFrom.', async () => {
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});
+ await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});
+ await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address});
+ await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address});
+ await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: charlie.address});
+
+ await helper.nft.transferTokenFrom(alice, collectionId, tokenId, {Substrate: alice.address}, {Substrate: charlie.address});
+ const owner = await helper.nft.getTokenOwner(collectionId, tokenId);
+ expect(owner.Substrate).to.be.equal(charlie.address);
+ });
});
it('If Public Access mode is set to AllowList, tokens can be transferred from a allowlisted address with transfer', async () => {
- const collectionId = await createCollectionExpectSuccess();
- const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
- await enableAllowListExpectSuccess(alice, collectionId);
- await addToAllowListExpectSuccess(alice, collectionId, alice.address);
- await addToAllowListExpectSuccess(alice, collectionId, charlie.address);
- await transferExpectSuccess(collectionId, itemId, alice, charlie, 1, 'NFT');
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});
+ await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});
+ await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address});
+ await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address});
+
+ await helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address});
+ const owner = await helper.nft.getTokenOwner(collectionId, tokenId);
+ expect(owner.Substrate).to.be.equal(charlie.address);
+ });
});
it('If Public Access mode is set to AllowList, tokens can be transferred from a allowlisted address with transferFrom', async () => {
- const collectionId = await createCollectionExpectSuccess();
- const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
- await enableAllowListExpectSuccess(alice, collectionId);
- await addToAllowListExpectSuccess(alice, collectionId, alice.address);
- await addToAllowListExpectSuccess(alice, collectionId, charlie.address);
- await approveExpectSuccess(collectionId, itemId, alice, charlie.address);
- await transferFromExpectSuccess(collectionId, itemId, alice, alice, charlie, 1, 'NFT');
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});
+ await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});
+ await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address});
+ await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address});
+ await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: charlie.address});
+
+ await helper.nft.transferTokenFrom(alice, collectionId, tokenId, {Substrate: alice.address}, {Substrate: charlie.address});
+ const owner = await helper.nft.getTokenOwner(collectionId, tokenId);
+ expect(owner.Substrate).to.be.equal(charlie.address);
+ });
});
it('If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens can be created by owner', async () => {
- const collectionId = await createCollectionExpectSuccess();
- await enableAllowListExpectSuccess(alice, collectionId);
- await setMintPermissionExpectSuccess(alice, collectionId, false);
- await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList', mintMode: false});
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});
+ const token = await helper.nft.getToken(collectionId, tokenId);
+ expect(token).to.be.not.null;
+ });
});
it('If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens can be created by admin', async () => {
- const collectionId = await createCollectionExpectSuccess();
- await enableAllowListExpectSuccess(alice, collectionId);
- await setMintPermissionExpectSuccess(alice, collectionId, false);
- await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
- await createItemExpectSuccess(bob, collectionId, 'NFT', bob.address);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList', mintMode: false});
+ await helper.collection.addAdmin(alice, collectionId, {Substrate: bob.address});
+ const {tokenId} = await helper.nft.mintToken(bob, {collectionId: collectionId, owner: bob.address});
+ const token = await helper.nft.getToken(collectionId, tokenId);
+ expect(token).to.be.not.null;
+ });
});
it('If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens cannot be created by non-privileged and allow-listed address', async () => {
- const collectionId = await createCollectionExpectSuccess();
- await enableAllowListExpectSuccess(alice, collectionId);
- await setMintPermissionExpectSuccess(alice, collectionId, false);
- await addToAllowListExpectSuccess(alice, collectionId, bob.address);
- await createItemExpectFailure(bob, collectionId, 'NFT', bob.address);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList', mintMode: false});
+ await helper.collection.addToAllowList(alice, collectionId, {Substrate: bob.address});
+ const mintTokenTx = async () => helper.nft.mintToken(bob, {collectionId: collectionId, owner: bob.address});
+ await expect(mintTokenTx()).to.be.rejected;
+ });
});
it('If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens cannot be created by non-privileged and non-allow listed address', async () => {
- const collectionId = await createCollectionExpectSuccess();
- await enableAllowListExpectSuccess(alice, collectionId);
- await setMintPermissionExpectSuccess(alice, collectionId, false);
- await createItemExpectFailure(bob, collectionId, 'NFT', bob.address);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList', mintMode: false});
+ const mintTokenTx = async () => helper.nft.mintToken(bob, {collectionId: collectionId, owner: bob.address});
+ await expect(mintTokenTx()).to.be.rejected;
+ });
});
it('If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens can be created by owner', async () => {
- const collectionId = await createCollectionExpectSuccess();
- await enableAllowListExpectSuccess(alice, collectionId);
- await setMintPermissionExpectSuccess(alice, collectionId, true);
- await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList', mintMode: true});
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});
+ const owner = await helper.nft.getTokenOwner(collectionId, tokenId);
+ expect(owner.Substrate).to.be.equal(alice.address);
+ });
});
it('If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens can be created by admin', async () => {
- const collectionId = await createCollectionExpectSuccess();
- await enableAllowListExpectSuccess(alice, collectionId);
- await setMintPermissionExpectSuccess(alice, collectionId, true);
- await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
- await createItemExpectSuccess(bob, collectionId, 'NFT', bob.address);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList', mintMode: true});
+ await helper.nft.addAdmin(alice, collectionId, {Substrate: bob.address});
+ const {tokenId} = await helper.nft.mintToken(bob, {collectionId: collectionId, owner: bob.address});
+ const owner = await helper.nft.getTokenOwner(collectionId, tokenId);
+ expect(owner.Substrate).to.be.equal(bob.address);
+ });
});
it('If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens cannot be created by non-privileged and non-allow listed address', async () => {
- const collectionId = await createCollectionExpectSuccess();
- await enableAllowListExpectSuccess(alice, collectionId);
- await setMintPermissionExpectSuccess(alice, collectionId, true);
- await createItemExpectFailure(bob, collectionId, 'NFT', bob.address);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList', mintMode: true});
+ const mintTokenTx = async () => helper.nft.mintToken(bob, {collectionId: collectionId, owner: bob.address});
+ await expect(mintTokenTx()).to.be.rejected;
+ });
});
it('If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens can be created by non-privileged and allow listed address', async () => {
- const collectionId = await createCollectionExpectSuccess();
- await enableAllowListExpectSuccess(alice, collectionId);
- await setMintPermissionExpectSuccess(alice, collectionId, true);
- await addToAllowListExpectSuccess(alice, collectionId, bob.address);
- await createItemExpectSuccess(bob, collectionId, 'NFT', bob.address);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList', mintMode: true});
+ await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address});
+ const {tokenId} = await helper.nft.mintToken(bob, {collectionId: collectionId, owner: bob.address});
+ const owner = await helper.nft.getTokenOwner(collectionId, tokenId);
+ expect(owner.Substrate).to.be.equal(bob.address);
+ });
});
});
tests/src/approve.test.tsdiffbeforeafterboth--- a/tests/src/approve.test.ts
+++ b/tests/src/approve.test.ts
@@ -15,28 +15,26 @@
// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
import {IKeyringPair} from '@polkadot/types/types';
-import {ApiPromise} from '@polkadot/api';
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
-import {default as usingApi} from './substrate/substrate-api';
import {
approveExpectFail,
approveExpectSuccess,
createCollectionExpectSuccess,
createItemExpectSuccess,
- destroyCollectionExpectSuccess,
- setCollectionLimitsExpectSuccess,
- transferExpectSuccess,
- addCollectionAdminExpectSuccess,
- adminApproveFromExpectFail,
- getCreatedCollectionCount,
- transferFromExpectSuccess,
- transferFromExpectFail,
- requirePallets,
- Pallets,
} from './util/helpers';
+import {usingPlaygrounds} from './util/playgrounds';
+
+let donor: IKeyringPair;
+
+before(async () => {
+ await usingPlaygrounds(async (_, privateKey) => {
+ donor = privateKey('//Alice');
+ });
+});
chai.use(chaiAsPromised);
+const expect = chai.expect;
describe('Integration Test approve(spender, collection_id, item_id, amount):', () => {
let alice: IKeyringPair;
@@ -44,63 +42,89 @@
let charlie: IKeyringPair;
before(async () => {
- await usingApi(async (api, privateKeyWrapper) => {
- alice = privateKeyWrapper('//Alice');
- bob = privateKeyWrapper('//Bob');
- charlie = privateKeyWrapper('//Charlie');
+ await usingPlaygrounds(async (helper) => {
+ [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);
});
});
it('[nft] Execute the extrinsic and check approvedList', async () => {
- const nftCollectionId = await createCollectionExpectSuccess();
- const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
- await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});
+ await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});
+ expect(await helper.nft.isTokenApproved(collectionId, tokenId, {Substrate: bob.address})).to.be.true;
+ });
});
it('[fungible] Execute the extrinsic and check approvedList', async () => {
- const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
- const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
- await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);
+ await helper.ft.mintTokens(alice, collectionId, alice.address, 10n);
+ const tokenId = await helper.ft.getLastTokenId(collectionId);
+ await helper.ft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});
+ const amount = await helper.ft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
+ expect(amount).to.be.equal(BigInt(1));
+ });
});
it('[refungible] Execute the extrinsic and check approvedList', async function() {
- await requirePallets(this, [Pallets.ReFungible]);
-
- const reFungibleCollectionId =
- await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
- const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
- await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: alice.address, pieces: 100n});
+ await helper.rft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});
+ const amount = await helper.rft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
+ expect(amount).to.be.equal(BigInt(1));
+ });
});
it('[nft] Remove approval by using 0 amount', async () => {
- const nftCollectionId = await createCollectionExpectSuccess();
- const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
- await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address, 1);
- await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address, 0);
+ await usingPlaygrounds(async (helper) => {
+ const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const collectionId = collection.collectionId;
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});
+ await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});
+ expect(await helper.nft.isTokenApproved(collectionId, tokenId, {Substrate: bob.address})).to.be.true;
+ await helper.signTransaction(alice, helper.api?.tx.unique.approve({Substrate: bob.address}, collectionId, tokenId, 0));
+ expect(await helper.nft.isTokenApproved(collectionId, tokenId, {Substrate: bob.address})).to.be.false;
+ });
});
it('[fungible] Remove approval by using 0 amount', async () => {
- const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
- const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
- await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 1);
- await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 0);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);
+ await helper.ft.mintTokens(alice, collectionId, alice.address, 10n);
+ const tokenId = await helper.ft.getLastTokenId(collectionId);
+ await helper.ft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});
+ const amountBefore = await helper.ft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
+ expect(amountBefore).to.be.equal(BigInt(1));
+
+ await helper.ft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address}, 0n);
+ const amountAfter = await helper.ft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
+ expect(amountAfter).to.be.equal(BigInt(0));
+ });
});
it('[refungible] Remove approval by using 0 amount', async function() {
- await requirePallets(this, [Pallets.ReFungible]);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: alice.address, pieces: 100n});
+ await helper.rft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});
+ const amountBefore = await helper.rft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
+ expect(amountBefore).to.be.equal(BigInt(1));
- const reFungibleCollectionId =
- await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
- const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
- await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address, 1);
- await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address, 0);
+ await helper.rft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address}, 0n);
+ const amountAfter = await helper.rft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
+ expect(amountAfter).to.be.equal(BigInt(0));
+ });
});
it('can`t be called by collection owner on non-owned item when OwnerCanTransfer == false', async () => {
- const collectionId = await createCollectionExpectSuccess();
- const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);
-
- await adminApproveFromExpectFail(collectionId, itemId, alice, bob.address, charlie.address);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: bob.address});
+ const approveTokenTx = async () => helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: charlie.address});
+ await expect(approveTokenTx()).to.be.rejected;
+ });
});
});
@@ -110,31 +134,39 @@
let charlie: IKeyringPair;
before(async () => {
- await usingApi(async (api, privateKeyWrapper) => {
- alice = privateKeyWrapper('//Alice');
- bob = privateKeyWrapper('//Bob');
- charlie = privateKeyWrapper('//Charlie');
+ await usingPlaygrounds(async (helper) => {
+ [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);
});
- });
+ });
it('NFT', async () => {
- const collectionId = await createCollectionExpectSuccess();
- const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);
- await approveExpectSuccess(collectionId, itemId, bob, charlie.address);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: bob.address});
+ await helper.nft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address});
+ expect(await helper.nft.isTokenApproved(collectionId, tokenId, {Substrate: charlie.address})).to.be.true;
+ });
});
it('Fungible up to an approved amount', async () => {
- const collectionId = await createCollectionExpectSuccess({mode:{type: 'Fungible', decimalPoints: 0}});
- const itemId = await createItemExpectSuccess(alice, collectionId, 'Fungible', bob.address);
- await approveExpectSuccess(collectionId, itemId, bob, charlie.address);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);
+ await helper.ft.mintTokens(alice, collectionId, bob.address, 10n);
+ const tokenId = await helper.ft.getLastTokenId(collectionId);
+ await helper.ft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address});
+ const amount = await helper.ft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: charlie.address}, {Substrate: bob.address});
+ expect(amount).to.be.equal(BigInt(1));
+ });
});
it('ReFungible up to an approved amount', async function() {
- await requirePallets(this, [Pallets.ReFungible]);
-
- const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});
- const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', bob.address);
- await approveExpectSuccess(collectionId, itemId, bob, charlie.address);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: bob.address, pieces: 100n});
+ await helper.rft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address}, 100n);
+ const amount = await helper.rft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: charlie.address}, {Substrate: bob.address});
+ expect(amount).to.be.equal(BigInt(100n));
+ });
});
});
@@ -144,34 +176,45 @@
let charlie: IKeyringPair;
before(async () => {
- await usingApi(async (api, privateKeyWrapper) => {
- alice = privateKeyWrapper('//Alice');
- bob = privateKeyWrapper('//Bob');
- charlie = privateKeyWrapper('//Charlie');
+ await usingPlaygrounds(async (helper) => {
+ [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);
});
- });
+ });
it('NFT', async () => {
- const collectionId = await createCollectionExpectSuccess();
- const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);
- await approveExpectSuccess(collectionId, itemId, bob, charlie.address);
- await transferFromExpectSuccess(collectionId, itemId, charlie, bob, alice, 1, 'NFT');
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: bob.address});
+ await helper.nft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address});
+ await helper.nft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
+ const owner = await helper.nft.getTokenOwner(collectionId, tokenId);
+ expect(owner.Substrate).to.be.equal(alice.address);
+ });
});
it('Fungible up to an approved amount', async () => {
- const collectionId = await createCollectionExpectSuccess({mode:{type: 'Fungible', decimalPoints: 0}});
- const itemId = await createItemExpectSuccess(alice, collectionId, 'Fungible', bob.address);
- await approveExpectSuccess(collectionId, itemId, bob, charlie.address);
- await transferFromExpectSuccess(collectionId, itemId, charlie, bob, alice, 1, 'Fungible');
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);
+ await helper.ft.mintTokens(alice, collectionId, bob.address, 10n);
+ const tokenId = await helper.ft.getLastTokenId(collectionId);
+ await helper.ft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address});
+ const before = await helper.ft.getBalance(collectionId, {Substrate: alice.address});
+ await helper.ft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address}, 1n);
+ const after = await helper.ft.getBalance(collectionId, {Substrate: alice.address});
+ expect(after - before).to.be.equal(BigInt(1));
+ });
});
it('ReFungible up to an approved amount', async function() {
- await requirePallets(this, [Pallets.ReFungible]);
-
- const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});
- const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', bob.address);
- await approveExpectSuccess(collectionId, itemId, bob, charlie.address);
- await transferFromExpectSuccess(collectionId, itemId, charlie, bob, alice, 1, 'ReFungible');
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: bob.address, pieces: 100n});
+ await helper.rft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address});
+ const before = await helper.rft.getTokenBalance(collectionId, tokenId, {Substrate: alice.address});
+ await helper.rft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address}, 1n);
+ const after = await helper.rft.getTokenBalance(collectionId, tokenId, {Substrate: alice.address});
+ expect(after - before).to.be.equal(BigInt(1));
+ });
});
});
@@ -181,37 +224,52 @@
let charlie: IKeyringPair;
before(async () => {
- await usingApi(async (api, privateKeyWrapper) => {
- alice = privateKeyWrapper('//Alice');
- bob = privateKeyWrapper('//Bob');
- charlie = privateKeyWrapper('//Charlie');
+ await usingPlaygrounds(async (helper) => {
+ [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);
});
- });
+ });
it('NFT', async () => {
- const collectionId = await createCollectionExpectSuccess();
- const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);
- await approveExpectSuccess(collectionId, itemId, bob, charlie.address);
- await transferFromExpectSuccess(collectionId, itemId, charlie, bob, alice, 1, 'NFT');
- await transferFromExpectFail(collectionId, itemId, charlie, bob, alice, 1);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: bob.address});
+ await helper.nft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address});
+ await helper.nft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
+ const owner = await helper.nft.getTokenOwner(collectionId, tokenId);
+ expect(owner.Substrate).to.be.equal(alice.address);
+ const transferTokenFromTx = async () => helper.nft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
+ await expect(transferTokenFromTx()).to.be.rejected;
+ });
});
it('Fungible up to an approved amount', async () => {
- const collectionId = await createCollectionExpectSuccess({mode:{type: 'Fungible', decimalPoints: 0}});
- const itemId = await createItemExpectSuccess(alice, collectionId, 'Fungible', bob.address);
- await approveExpectSuccess(collectionId, itemId, bob, charlie.address);
- await transferFromExpectSuccess(collectionId, itemId, charlie, bob, alice, 1, 'Fungible');
- await transferFromExpectFail(collectionId, itemId, charlie, bob, alice, 1);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);
+ await helper.ft.mintTokens(alice, collectionId, bob.address, 10n);
+ const tokenId = await helper.ft.getLastTokenId(collectionId);
+ await helper.ft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address});
+ const before = await helper.ft.getBalance(collectionId, {Substrate: alice.address});
+ await helper.ft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address}, 1n);
+ const after = await helper.ft.getBalance(collectionId, {Substrate: alice.address});
+ expect(after - before).to.be.equal(BigInt(1));
+
+ const transferTokenFromTx = async () => helper.ft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address}, 1n);
+ await expect(transferTokenFromTx()).to.be.rejected;
+ });
});
it('ReFungible up to an approved amount', async function() {
- await requirePallets(this, [Pallets.ReFungible]);
-
- const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});
- const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', bob.address);
- await approveExpectSuccess(collectionId, itemId, bob, charlie.address);
- await transferFromExpectSuccess(collectionId, itemId, charlie, bob, alice, 1, 'ReFungible');
- await transferFromExpectFail(collectionId, itemId, charlie, bob, alice, 1);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: bob.address, pieces: 100n});
+ await helper.rft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address}, 100n);
+ const before = await helper.rft.getTokenBalance(collectionId, tokenId, {Substrate: alice.address});
+ await helper.rft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address}, 100n);
+ const after = await helper.rft.getTokenBalance(collectionId, tokenId, {Substrate: alice.address});
+ expect(after - before).to.be.equal(BigInt(100));
+ const transferTokenFromTx = async () => helper.rft.transferTokenFrom(charlie, collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address}, 100n);
+ await expect(transferTokenFromTx()).to.be.rejected;
+ });
});
});
@@ -222,20 +280,28 @@
let dave: IKeyringPair;
before(async () => {
- await usingApi(async (api, privateKeyWrapper) => {
- alice = privateKeyWrapper('//Alice');
- bob = privateKeyWrapper('//Bob');
- charlie = privateKeyWrapper('//Charlie');
- dave = privateKeyWrapper('//Dave');
+ await usingPlaygrounds(async (helper) => {
+ [alice, bob, charlie, dave] = await helper.arrange.createAccounts([100n, 100n, 100n, 100n], donor);
});
- });
+ });
it('If a user B is approved to transfer 10 Fungible tokens from user A, they can transfer 2 tokens to user C, which will result in decreasing approval from 10 to 8. Then user B can transfer 8 tokens to user D.', async () => {
- const collectionId = await createCollectionExpectSuccess({mode:{type: 'Fungible', decimalPoints: 0}});
- const itemId = await createItemExpectSuccess(alice, collectionId, 'Fungible', alice.address);
- await approveExpectSuccess(collectionId, itemId, alice, bob.address, 10);
- await transferFromExpectSuccess(collectionId, itemId, bob, alice, charlie, 2, 'Fungible');
- await transferFromExpectSuccess(collectionId, itemId, bob, alice, dave, 8, 'Fungible');
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);
+ await helper.ft.mintTokens(alice, collectionId, alice.address, 10n);
+ const tokenId = await helper.ft.getLastTokenId(collectionId);
+ await helper.ft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address}, 10n);
+
+ const charlieBefore = await helper.ft.getBalance(collectionId, {Substrate: charlie.address});
+ await helper.ft.transferTokenFrom(bob, collectionId, tokenId, {Substrate: alice.address}, {Substrate: charlie.address}, 2n);
+ const charlieAfter = await helper.ft.getBalance(collectionId, {Substrate: charlie.address});
+ expect(charlieAfter - charlieBefore).to.be.equal(BigInt(2));
+
+ const daveBefore = await helper.ft.getBalance(collectionId, {Substrate: dave.address});
+ await helper.ft.transferTokenFrom(bob, collectionId, tokenId, {Substrate: alice.address}, {Substrate: dave.address}, 8n);
+ const daveAfter = await helper.ft.getBalance(collectionId, {Substrate: dave.address});
+ expect(daveAfter - daveBefore).to.be.equal(BigInt(8));
+ });
});
});
@@ -245,38 +311,57 @@
let charlie: IKeyringPair;
before(async () => {
- await usingApi(async (api, privateKeyWrapper) => {
- alice = privateKeyWrapper('//Alice');
- bob = privateKeyWrapper('//Bob');
- charlie = privateKeyWrapper('//Charlie');
+ await usingPlaygrounds(async (helper) => {
+ [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);
});
});
it('NFT', async () => {
- const collectionId = await createCollectionExpectSuccess();
- const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT');
- await approveExpectSuccess(collectionId, itemId, alice, bob.address, 1);
- await approveExpectSuccess(collectionId, itemId, alice, bob.address, 0);
- await transferFromExpectFail(collectionId, itemId, bob, bob, charlie, 1);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});
+ await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});
+ expect(await helper.nft.isTokenApproved(collectionId, tokenId, {Substrate: bob.address})).to.be.true;
+ await helper.signTransaction(alice, helper.api?.tx.unique.approve({Substrate: bob.address}, collectionId, tokenId, 0));
+ expect(await helper.nft.isTokenApproved(collectionId, tokenId, {Substrate: bob.address})).to.be.false;
+ const transferTokenFromTx = async () => helper.nft.transferTokenFrom(bob, collectionId, tokenId, {Substrate: bob.address}, {Substrate: bob.address});
+ await expect(transferTokenFromTx()).to.be.rejected;
+ });
});
it('Fungible', async () => {
- const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
- const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
- await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 1);
- await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 0);
- await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, bob, charlie, 1);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);
+ await helper.ft.mintTokens(alice, collectionId, alice.address, 10n);
+ const tokenId = await helper.ft.getLastTokenId(collectionId);
+ await helper.ft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});
+ const amountBefore = await helper.ft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
+ expect(amountBefore).to.be.equal(BigInt(1));
+
+ await helper.ft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address}, 0n);
+ const amountAfter = await helper.ft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
+ expect(amountAfter).to.be.equal(BigInt(0));
+
+ const transferTokenFromTx = async () => helper.ft.transferTokenFrom(bob, collectionId, tokenId, {Substrate: bob.address}, {Substrate: charlie.address}, 1n);
+ await expect(transferTokenFromTx()).to.be.rejected;
+ });
});
it('ReFungible', async function() {
- await requirePallets(this, [Pallets.ReFungible]);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: alice.address, pieces: 100n});
+ await helper.rft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address});
+ const amountBefore = await helper.rft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
+ expect(amountBefore).to.be.equal(BigInt(1));
- const reFungibleCollectionId =
- await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
- const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
- await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address, 1);
- await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address, 0);
- await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, bob, charlie, 1);
+ await helper.rft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address}, 0n);
+ const amountAfter = await helper.rft.getTokenApprovedPieces(collectionId, tokenId, {Substrate: bob.address}, {Substrate: alice.address});
+ expect(amountAfter).to.be.equal(BigInt(0));
+
+ const transferTokenFromTx = async () => helper.rft.transferTokenFrom(bob, collectionId, tokenId, {Substrate: bob.address}, {Substrate: charlie.address}, 100n);
+ await expect(transferTokenFromTx()).to.be.rejected;
+ });
});
});
@@ -286,31 +371,38 @@
let charlie: IKeyringPair;
before(async () => {
- await usingApi(async (api, privateKeyWrapper) => {
- alice = privateKeyWrapper('//Alice');
- bob = privateKeyWrapper('//Bob');
- charlie = privateKeyWrapper('//Charlie');
+ await usingPlaygrounds(async (helper) => {
+ [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);
});
});
it('1 for NFT', async () => {
- const collectionId = await createCollectionExpectSuccess();
- const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);
- await approveExpectFail(collectionId, itemId, bob, charlie, 2);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: bob.address});
+ const approveTx = async () => helper.signTransaction(bob, helper.api?.tx.unique.approve({Substrate: charlie.address}, collectionId, tokenId, 2));
+ await expect(approveTx()).to.be.rejected;
+ expect(await helper.nft.isTokenApproved(collectionId, tokenId, {Substrate: charlie.address})).to.be.false;
+ });
});
it('Fungible', async () => {
- const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
- const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
- await approveExpectFail(fungibleCollectionId, newFungibleTokenId, bob, charlie, 11);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);
+ await helper.ft.mintTokens(alice, collectionId, alice.address, 10n);
+ const tokenId = await helper.ft.getLastTokenId(collectionId);
+ const approveTx = async () => helper.ft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address}, 11n);
+ await expect(approveTx()).to.be.rejected;
+ });
});
it('ReFungible', async function() {
- await requirePallets(this, [Pallets.ReFungible]);
-
- const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
- const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
- await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, charlie, 101);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: alice.address, pieces: 100n});
+ const approveTx = async () => helper.rft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address}, 101n);
+ await expect(approveTx()).to.be.rejected;
+ });
});
});
@@ -321,41 +413,67 @@
let dave: IKeyringPair;
before(async () => {
- await usingApi(async (api, privateKeyWrapper) => {
- alice = privateKeyWrapper('//Alice');
- bob = privateKeyWrapper('//Bob');
- charlie = privateKeyWrapper('//Charlie');
- dave = privateKeyWrapper('//Dave');
+ await usingPlaygrounds(async (helper) => {
+ [alice, bob, charlie, dave] = await helper.arrange.createAccounts([100n, 100n, 100n, 100n], donor);
});
- });
+ });
it('NFT', async () => {
- const collectionId = await createCollectionExpectSuccess();
- await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});
- const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', charlie.address);
- await transferFromExpectSuccess(collectionId, itemId, alice, charlie, dave, 1, 'NFT');
- await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
- await transferFromExpectSuccess(collectionId, itemId, bob, dave, alice, 1, 'NFT');
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ await helper.collection.setLimits(alice, collectionId, {ownerCanTransfer: true});
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: charlie.address});
+
+ await helper.nft.transferTokenFrom(alice, collectionId, tokenId, {Substrate: charlie.address}, {Substrate: dave.address});
+ const owner1 = await helper.nft.getTokenOwner(collectionId, tokenId);
+ expect(owner1.Substrate).to.be.equal(dave.address);
+
+ await helper.collection.addAdmin(alice, collectionId, {Substrate: bob.address});
+ await helper.nft.transferTokenFrom(bob, collectionId, tokenId, {Substrate: dave.address}, {Substrate: alice.address});
+ const owner2 = await helper.nft.getTokenOwner(collectionId, tokenId);
+ expect(owner2.Substrate).to.be.equal(alice.address);
+ });
});
it('Fungible up to an approved amount', async () => {
- const collectionId = await createCollectionExpectSuccess({mode:{type: 'Fungible', decimalPoints: 0}});
- await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});
- const itemId = await createItemExpectSuccess(alice, collectionId, 'Fungible', charlie.address);
- await transferFromExpectSuccess(collectionId, itemId, alice, charlie, dave, 1, 'Fungible');
- await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
- await transferFromExpectSuccess(collectionId, itemId, bob, dave, alice, 1, 'Fungible');
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);
+ await helper.collection.setLimits(alice, collectionId, {ownerCanTransfer: true});
+ await helper.ft.mintTokens(alice, collectionId, charlie.address, 10n);
+ const tokenId = await helper.ft.getLastTokenId(collectionId);
+
+ const daveBalanceBefore = await helper.ft.getBalance(collectionId, {Substrate: dave.address});
+ await helper.ft.transferTokenFrom(alice, collectionId, tokenId, {Substrate: charlie.address}, {Substrate: dave.address}, 1n);
+ const daveBalanceAfter = await helper.ft.getBalance(collectionId, {Substrate: dave.address});
+ expect(daveBalanceAfter - daveBalanceBefore).to.be.equal(BigInt(1));
+
+ await helper.collection.addAdmin(alice ,collectionId, {Substrate: bob.address});
+
+ const aliceBalanceBefore = await helper.ft.getBalance(collectionId, {Substrate: alice.address});
+ await helper.ft.transferTokenFrom(bob, collectionId, tokenId, {Substrate: dave.address}, {Substrate: alice.address}, 1n);
+ const aliceBalanceAfter = await helper.ft.getBalance(collectionId, {Substrate: alice.address});
+ expect(aliceBalanceAfter - aliceBalanceBefore).to.be.equal(BigInt(1));
+ });
});
it('ReFungible up to an approved amount', async function() {
- await requirePallets(this, [Pallets.ReFungible]);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ await helper.collection.setLimits(alice, collectionId, {ownerCanTransfer: true});
+ const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: charlie.address, pieces: 100n});
+
+ const daveBefore = await helper.rft.getTokenBalance(collectionId, tokenId, {Substrate: dave.address});
+ await helper.rft.transferTokenFrom(alice, collectionId, tokenId, {Substrate: charlie.address}, {Substrate: dave.address}, 1n);
+ const daveAfter = await helper.rft.getTokenBalance(collectionId, tokenId, {Substrate: dave.address});
+ expect(daveAfter - daveBefore).to.be.equal(BigInt(1));
- const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});
- await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});
- const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', charlie.address);
- await transferFromExpectSuccess(collectionId, itemId, alice, charlie, dave, 1, 'ReFungible');
- await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
- await transferFromExpectSuccess(collectionId, itemId, bob, dave, alice, 1, 'ReFungible');
+ await helper.collection.addAdmin(alice, collectionId, {Substrate: bob.address});
+
+ const aliceBefore = await helper.rft.getTokenBalance(collectionId, tokenId, {Substrate: alice.address});
+ await helper.rft.transferTokenFrom(bob, collectionId, tokenId, {Substrate: dave.address}, {Substrate: alice.address}, 1n);
+ const aliceAfter = await helper.rft.getTokenBalance(collectionId, tokenId, {Substrate: alice.address});
+ expect(aliceAfter - aliceBefore).to.be.equal(BigInt(1));
+ });
});
});
@@ -366,13 +484,10 @@
let dave: IKeyringPair;
before(async () => {
- await usingApi(async (api, privateKeyWrapper) => {
- alice = privateKeyWrapper('//Alice');
- bob = privateKeyWrapper('//Bob');
- charlie = privateKeyWrapper('//Charlie');
- dave = privateKeyWrapper('//Dave');
+ await usingPlaygrounds(async (helper) => {
+ [alice, bob, charlie, dave] = await helper.arrange.createAccounts([100n, 100n, 100n, 100n], donor);
});
- });
+ });
it.skip('Owned 10, approval 1: 1, approval 2: 1, resulting approved value: 2. Fungible', async () => {
const collectionId = await createCollectionExpectSuccess({mode:{type: 'Fungible', decimalPoints: 0}});
@@ -417,19 +532,19 @@
let charlie: IKeyringPair;
before(async () => {
- await usingApi(async (api, privateKeyWrapper) => {
- alice = privateKeyWrapper('//Alice');
- bob = privateKeyWrapper('//Bob');
- charlie = privateKeyWrapper('//Charlie');
+ await usingPlaygrounds(async (helper) => {
+ [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);
});
});
it('can be called by collection admin on non-owned item', async () => {
- const collectionId = await createCollectionExpectSuccess();
- const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
-
- await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
- await adminApproveFromExpectFail(collectionId, itemId, bob, alice.address, charlie.address);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});
+ await helper.collection.addAdmin(alice, collectionId, {Substrate: bob.address});
+ const approveTx = async () => helper.nft.approveToken(bob, collectionId, tokenId, {Substrate: charlie.address});
+ await expect(approveTx()).to.be.rejected;
+ });
});
});
@@ -439,114 +554,139 @@
let charlie: IKeyringPair;
before(async () => {
- await usingApi(async (api, privateKeyWrapper) => {
- alice = privateKeyWrapper('//Alice');
- bob = privateKeyWrapper('//Bob');
- charlie = privateKeyWrapper('//Charlie');
+ await usingPlaygrounds(async (helper) => {
+ [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);
});
});
it('[nft] Approve for a collection that does not exist', async () => {
- await usingApi(async (api: ApiPromise) => {
- const nftCollectionCount = await getCreatedCollectionCount(api);
- await approveExpectFail(nftCollectionCount + 1, 1, alice, bob);
+ await usingPlaygrounds(async (helper) => {
+ const collectionId = 1 << 32 - 1;
+ const approveTx = async () => helper.nft.approveToken(bob, collectionId, 1, {Substrate: charlie.address});
+ await expect(approveTx()).to.be.rejected;
});
});
it('[fungible] Approve for a collection that does not exist', async () => {
- await usingApi(async (api: ApiPromise) => {
- const fungibleCollectionCount = await getCreatedCollectionCount(api);
- await approveExpectFail(fungibleCollectionCount + 1, 0, alice, bob);
+ await usingPlaygrounds(async (helper) => {
+ const collectionId = 1 << 32 - 1;
+ const approveTx = async () => helper.ft.approveToken(bob, collectionId, 1, {Substrate: charlie.address});
+ await expect(approveTx()).to.be.rejected;
});
});
it('[refungible] Approve for a collection that does not exist', async function() {
- await requirePallets(this, [Pallets.ReFungible]);
-
- await usingApi(async (api: ApiPromise) => {
- const reFungibleCollectionCount = await getCreatedCollectionCount(api);
- await approveExpectFail(reFungibleCollectionCount + 1, 1, alice, bob);
+ await usingPlaygrounds(async (helper) => {
+ const collectionId = 1 << 32 - 1;
+ const approveTx = async () => helper.rft.approveToken(bob, collectionId, 1, {Substrate: charlie.address});
+ await expect(approveTx()).to.be.rejected;
});
});
it('[nft] Approve for a collection that was destroyed', async () => {
- const nftCollectionId = await createCollectionExpectSuccess();
- await destroyCollectionExpectSuccess(nftCollectionId);
- await approveExpectFail(nftCollectionId, 1, alice, bob);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ await helper.nft.burn(alice, collectionId);
+ const approveTx = async () => helper.nft.approveToken(alice, collectionId, 1, {Substrate: bob.address});
+ await expect(approveTx()).to.be.rejected;
+ });
});
- it('Approve for a collection that was destroyed', async () => {
- const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
- await destroyCollectionExpectSuccess(fungibleCollectionId);
- await approveExpectFail(fungibleCollectionId, 0, alice, bob);
+ it('[fungible] Approve for a collection that was destroyed', async () => {
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ await helper.ft.burn(alice, collectionId);
+ const approveTx = async () => helper.ft.approveToken(alice, collectionId, 1, {Substrate: bob.address});
+ await expect(approveTx()).to.be.rejected;
+ });
});
it('[refungible] Approve for a collection that was destroyed', async function() {
- await requirePallets(this, [Pallets.ReFungible]);
-
- const reFungibleCollectionId =
- await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
- await destroyCollectionExpectSuccess(reFungibleCollectionId);
- await approveExpectFail(reFungibleCollectionId, 1, alice, bob);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ await helper.rft.burn(alice, collectionId);
+ const approveTx = async () => helper.rft.approveToken(alice, collectionId, 1, {Substrate: bob.address});
+ await expect(approveTx()).to.be.rejected;
+ });
});
it('[nft] Approve transfer of a token that does not exist', async () => {
- const nftCollectionId = await createCollectionExpectSuccess();
- await approveExpectFail(nftCollectionId, 2, alice, bob);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const approveTx = async () => helper.nft.approveToken(alice, collectionId, 2, {Substrate: bob.address});
+ await expect(approveTx()).to.be.rejected;
+ });
});
it('[refungible] Approve transfer of a token that does not exist', async function() {
- await requirePallets(this, [Pallets.ReFungible]);
-
- const reFungibleCollectionId =
- await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
- await approveExpectFail(reFungibleCollectionId, 2, alice, bob);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const approveTx = async () => helper.rft.approveToken(alice, collectionId, 2, {Substrate: bob.address});
+ await expect(approveTx()).to.be.rejected;
+ });
});
it('[nft] Approve using the address that does not own the approved token', async () => {
- const nftCollectionId = await createCollectionExpectSuccess();
- const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
- await approveExpectFail(nftCollectionId, newNftTokenId, bob, alice);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});
+ const approveTx = async () => helper.nft.approveToken(bob, collectionId, tokenId, {Substrate: alice.address});
+ await expect(approveTx()).to.be.rejected;
+ });
});
it('[fungible] Approve using the address that does not own the approved token', async () => {
- const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
- const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
- await approveExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ await helper.ft.mintTokens(alice, collectionId, alice.address, 10n);
+ const tokenId = await helper.ft.getLastTokenId(collectionId);
+ const approveTx = async () => helper.ft.approveToken(bob, collectionId, tokenId, {Substrate: alice.address});
+ await expect(approveTx()).to.be.rejected;
+ });
});
it('[refungible] Approve using the address that does not own the approved token', async function() {
- await requirePallets(this, [Pallets.ReFungible]);
-
- const reFungibleCollectionId =
- await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
- const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
- await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, alice);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: alice.address, pieces: 100n});
+ const approveTx = async () => helper.rft.approveToken(bob, collectionId, tokenId, {Substrate: alice.address});
+ await expect(approveTx()).to.be.rejected;
+ });
});
it('should fail if approved more ReFungibles than owned', async function() {
- await requirePallets(this, [Pallets.ReFungible]);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.rft.mintToken(alice, {collectionId: collectionId, owner: alice.address, pieces: 100n});
+ await helper.rft.transferToken(alice, collectionId, tokenId, {Substrate: bob.address}, 100n);
+ await helper.rft.approveToken(bob, collectionId, tokenId, {Substrate: alice.address}, 100n);
- const nftCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
- const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'ReFungible');
- await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 100, 'ReFungible');
- await approveExpectSuccess(nftCollectionId, newNftTokenId, bob, alice.address, 100);
- await approveExpectFail(nftCollectionId, newNftTokenId, bob, alice, 101);
+ const approveTx = async () => helper.rft.approveToken(bob, collectionId, tokenId, {Substrate: alice.address}, 101n);
+ await expect(approveTx()).to.be.rejected;
+ });
});
it('should fail if approved more Fungibles than owned', async () => {
- const nftCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
- const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'Fungible');
- await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 10, 'Fungible');
- await approveExpectSuccess(nftCollectionId, newNftTokenId, bob, alice.address, 10);
- await approveExpectFail(nftCollectionId, newNftTokenId, bob, alice, 11);
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ await helper.ft.mintTokens(alice, collectionId, alice.address, 10n);
+ const tokenId = await helper.ft.getLastTokenId(collectionId);
+
+ await helper.ft.transferToken(alice, collectionId, tokenId, {Substrate: bob.address}, 10n);
+ await helper.ft.approveToken(bob, collectionId, tokenId, {Substrate: alice.address}, 10n);
+ const approveTx = async () => helper.ft.approveToken(bob, collectionId, tokenId, {Substrate: alice.address}, 11n);
+ await expect(approveTx()).to.be.rejected;
+ });
});
it('fails when called by collection owner on non-owned item when OwnerCanTransfer == false', async () => {
- const collectionId = await createCollectionExpectSuccess();
- const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);
- await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: false});
+ await usingPlaygrounds(async (helper) => {
+ const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
+ const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: bob.address});
+ await helper.collection.setLimits(alice, collectionId, {ownerCanTransfer: false});
- await approveExpectFail(collectionId, itemId, alice, charlie);
+ const approveTx = async () => helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: charlie.address});
+ await expect(approveTx()).to.be.rejected;
+ });
});
});
tests/src/util/playgrounds/unique.tsdiffbeforeafterboth475 return (await this.helper.callRpc('api.rpc.unique.nextSponsored', [collectionId, addressObj, tokenId])).toJSON();475 return (await this.helper.callRpc('api.rpc.unique.nextSponsored', [collectionId, addressObj, tokenId])).toJSON();476 }476 }477477478 /**478 /**479 * Get the number of created collections.479 * Get the number of created collections.480 * 480 *481 * @returns number of created collections481 * @returns number of created collections482 */482 */483 async getTotalCount(): Promise<number> {483 async getTotalCount(): Promise<number> {484 return (await this.helper.callRpc('api.rpc.unique.collectionStats')).created.toNumber();484 return (await this.helper.callRpc('api.rpc.unique.collectionStats')).created.toNumber();485 }485 }486486487 /**487 /**488 * Get information about the collection with additional data, 488 * Get information about the collection with additional data,489 * including the number of tokens it contains, its administrators, 489 * including the number of tokens it contains, its administrators,490 * the normalized address of the collection's owner, and decoded name and description.490 * the normalized address of the collection's owner, and decoded name and description.491 * 491 *492 * @param collectionId ID of collection492 * @param collectionId ID of collection493 * @example await getData(2)493 * @example await getData(2)494 * @returns collection information object494 * @returns collection information object495 */495 */496 async getData(collectionId: number): Promise<{496 async getData(collectionId: number): Promise<{497 id: number;497 id: number;498 name: string;498 name: string;523 return collectionData;523 return collectionData;524 }524 }525525526 /**526 /**527 * Get the addresses of the collection's administrators, optionally normalized.527 * Get the addresses of the collection's administrators, optionally normalized.528 * 528 *529 * @param collectionId ID of collection529 * @param collectionId ID of collection530 * @param normalize whether to normalize the addresses to the default ss58 format530 * @param normalize whether to normalize the addresses to the default ss58 format531 * @example await getAdmins(1)531 * @example await getAdmins(1)532 * @returns array of administrators532 * @returns array of administrators533 */533 */534 async getAdmins(collectionId: number, normalize = false): Promise<ICrossAccountId[]> {534 async getAdmins(collectionId: number, normalize = false): Promise<ICrossAccountId[]> {535 const admins = (await this.helper.callRpc('api.rpc.unique.adminlist', [collectionId])).toHuman();535 const admins = (await this.helper.callRpc('api.rpc.unique.adminlist', [collectionId])).toHuman();536536561 : allowListed;561 : allowListed;562 }562 }563563564 /**564 /**565 * Get the effective limits of the collection instead of null for default values565 * Get the effective limits of the collection instead of null for default values566 * 566 *567 * @param collectionId ID of collection567 * @param collectionId ID of collection568 * @example await getEffectiveLimits(2)568 * @example await getEffectiveLimits(2)569 * @returns object of collection limits569 * @returns object of collection limits570 */570 */571 async getEffectiveLimits(collectionId: number): Promise<ICollectionLimits> {571 async getEffectiveLimits(collectionId: number): Promise<ICollectionLimits> {572 return (await this.helper.callRpc('api.rpc.unique.effectiveCollectionLimits', [collectionId])).toJSON();572 return (await this.helper.callRpc('api.rpc.unique.effectiveCollectionLimits', [collectionId])).toJSON();573 }573 }574574575 /**575 /**576 * Burns the collection if the signer has sufficient permissions and collection is empty.576 * Burns the collection if the signer has sufficient permissions and collection is empty.577 * 577 *578 * @param signer keyring of signer578 * @param signer keyring of signer579 * @param collectionId ID of collection579 * @param collectionId ID of collection580 * @example await helper.collection.burn(aliceKeyring, 3);580 * @example await helper.collection.burn(aliceKeyring, 3);581 * @returns ```true``` if extrinsic success, otherwise ```false```581 * @returns ```true``` if extrinsic success, otherwise ```false```582 */582 */583 async burn(signer: TSigner, collectionId: number): Promise<boolean> {583 async burn(signer: TSigner, collectionId: number): Promise<boolean> {584 const result = await this.helper.executeExtrinsic(584 const result = await this.helper.executeExtrinsic(585 signer,585 signer,590 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'CollectionDestroyed');590 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'CollectionDestroyed');591 }591 }592592593 /**593 /**594 * Sets the sponsor for the collection (Requires the Substrate address). Needs confirmation by the sponsor.594 * Sets the sponsor for the collection (Requires the Substrate address). Needs confirmation by the sponsor.595 * 595 *596 * @param signer keyring of signer596 * @param signer keyring of signer597 * @param collectionId ID of collection597 * @param collectionId ID of collection598 * @param sponsorAddress Sponsor substrate address598 * @param sponsorAddress Sponsor substrate address599 * @example setSponsor(aliceKeyring, 10, "5DyN4Y92vZCjv38fg...")599 * @example setSponsor(aliceKeyring, 10, "5DyN4Y92vZCjv38fg...")600 * @returns ```true``` if extrinsic success, otherwise ```false```600 * @returns ```true``` if extrinsic success, otherwise ```false```601 */601 */602 async setSponsor(signer: TSigner, collectionId: number, sponsorAddress: TSubstrateAccount): Promise<boolean> {602 async setSponsor(signer: TSigner, collectionId: number, sponsorAddress: TSubstrateAccount): Promise<boolean> {603 const result = await this.helper.executeExtrinsic(603 const result = await this.helper.executeExtrinsic(604 signer,604 signer,609 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionSponsorSet');609 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionSponsorSet');610 }610 }611611612 /**612 /**613 * Confirms consent to sponsor the collection on behalf of the signer.613 * Confirms consent to sponsor the collection on behalf of the signer.614 * 614 *615 * @param signer keyring of signer615 * @param signer keyring of signer616 * @param collectionId ID of collection616 * @param collectionId ID of collection617 * @example confirmSponsorship(aliceKeyring, 10)617 * @example confirmSponsorship(aliceKeyring, 10)618 * @returns ```true``` if extrinsic success, otherwise ```false```618 * @returns ```true``` if extrinsic success, otherwise ```false```619 */619 */620 async confirmSponsorship(signer: TSigner, collectionId: number): Promise<boolean> {620 async confirmSponsorship(signer: TSigner, collectionId: number): Promise<boolean> {621 const result = await this.helper.executeExtrinsic(621 const result = await this.helper.executeExtrinsic(622 signer,622 signer,627 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'SponsorshipConfirmed');627 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'SponsorshipConfirmed');628 }628 }629629630 /**630 /**631 * Removes the sponsor of a collection, regardless if it consented or not.631 * Removes the sponsor of a collection, regardless if it consented or not.632 * 632 *633 * @param signer keyring of signer633 * @param signer keyring of signer634 * @param collectionId ID of collection634 * @param collectionId ID of collection635 * @example removeSponsor(aliceKeyring, 10)635 * @example removeSponsor(aliceKeyring, 10)636 * @returns ```true``` if extrinsic success, otherwise ```false```636 * @returns ```true``` if extrinsic success, otherwise ```false```637 */637 */638 async removeSponsor(signer: TSigner, collectionId: number): Promise<boolean> {638 async removeSponsor(signer: TSigner, collectionId: number): Promise<boolean> {639 const result = await this.helper.executeExtrinsic(639 const result = await this.helper.executeExtrinsic(640 signer,640 signer,645 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionSponsorRemoved');645 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionSponsorRemoved');646 }646 }647647648 /**648 /**649 * Sets the limits of the collection. At least one limit must be specified for a correct call.649 * Sets the limits of the collection. At least one limit must be specified for a correct call.650 * 650 *651 * @param signer keyring of signer651 * @param signer keyring of signer652 * @param collectionId ID of collection652 * @param collectionId ID of collection653 * @param limits collection limits object653 * @param limits collection limits object654 * @example654 * @example655 * await setLimits(655 * await setLimits(656 * aliceKeyring,656 * aliceKeyring,657 * 10,657 * 10,658 * {658 * {659 * sponsorTransferTimeout: 0,659 * sponsorTransferTimeout: 0,660 * ownerCanDestroy: false660 * ownerCanDestroy: false661 * }661 * }662 * )662 * )663 * @returns ```true``` if extrinsic success, otherwise ```false```663 * @returns ```true``` if extrinsic success, otherwise ```false```664 */664 */665 async setLimits(signer: TSigner, collectionId: number, limits: ICollectionLimits): Promise<boolean> {665 async setLimits(signer: TSigner, collectionId: number, limits: ICollectionLimits): Promise<boolean> {666 const result = await this.helper.executeExtrinsic(666 const result = await this.helper.executeExtrinsic(667 signer,667 signer,672 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionLimitSet');672 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionLimitSet');673 }673 }674674675 /**675 /**676 * Changes the owner of the collection to the new Substrate address.676 * Changes the owner of the collection to the new Substrate address.677 * 677 *678 * @param signer keyring of signer678 * @param signer keyring of signer679 * @param collectionId ID of collection679 * @param collectionId ID of collection680 * @param ownerAddress substrate address of new owner680 * @param ownerAddress substrate address of new owner681 * @example changeOwner(aliceKeyring, 10, "5DyN4Y92vZCjv38fg...")681 * @example changeOwner(aliceKeyring, 10, "5DyN4Y92vZCjv38fg...")682 * @returns ```true``` if extrinsic success, otherwise ```false```682 * @returns ```true``` if extrinsic success, otherwise ```false```683 */683 */684 async changeOwner(signer: TSigner, collectionId: number, ownerAddress: TSubstrateAccount): Promise<boolean> {684 async changeOwner(signer: TSigner, collectionId: number, ownerAddress: TSubstrateAccount): Promise<boolean> {685 const result = await this.helper.executeExtrinsic(685 const result = await this.helper.executeExtrinsic(686 signer,686 signer,691 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionOwnedChanged');691 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionOwnedChanged');692 }692 }693693694 /**694 /**695 * Adds a collection administrator. 695 * Adds a collection administrator.696 * 696 *697 * @param signer keyring of signer697 * @param signer keyring of signer698 * @param collectionId ID of collection698 * @param collectionId ID of collection699 * @param adminAddressObj Administrator address (substrate or ethereum)699 * @param adminAddressObj Administrator address (substrate or ethereum)700 * @example addAdmin(aliceKeyring, 10, {Substrate: "5DyN4Y92vZCjv38fg..."})700 * @example addAdmin(aliceKeyring, 10, {Substrate: "5DyN4Y92vZCjv38fg..."})701 * @returns ```true``` if extrinsic success, otherwise ```false```701 * @returns ```true``` if extrinsic success, otherwise ```false```702 */702 */703 async addAdmin(signer: TSigner, collectionId: number, adminAddressObj: ICrossAccountId): Promise<boolean> {703 async addAdmin(signer: TSigner, collectionId: number, adminAddressObj: ICrossAccountId): Promise<boolean> {704 const result = await this.helper.executeExtrinsic(704 const result = await this.helper.executeExtrinsic(705 signer,705 signer,710 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionAdminAdded');710 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionAdminAdded');711 }711 }712712713 /**713 /**714 * Removes a collection administrator.714 * Removes a collection administrator.715 * 715 *716 * @param signer keyring of signer716 * @param signer keyring of signer717 * @param collectionId ID of collection717 * @param collectionId ID of collection718 * @param adminAddressObj Administrator address (substrate or ethereum)718 * @param adminAddressObj Administrator address (substrate or ethereum)719 * @example removeAdmin(aliceKeyring, 10, {Substrate: "5DyN4Y92vZCjv38fg..."})719 * @example removeAdmin(aliceKeyring, 10, {Substrate: "5DyN4Y92vZCjv38fg..."})720 * @returns ```true``` if extrinsic success, otherwise ```false```720 * @returns ```true``` if extrinsic success, otherwise ```false```721 */721 */722 async removeAdmin(signer: TSigner, collectionId: number, adminAddressObj: ICrossAccountId): Promise<boolean> {722 async removeAdmin(signer: TSigner, collectionId: number, adminAddressObj: ICrossAccountId): Promise<boolean> {723 const result = await this.helper.executeExtrinsic(723 const result = await this.helper.executeExtrinsic(724 signer,724 signer,729 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionAdminRemoved');729 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionAdminRemoved');730 }730 }731731732 /**732 /**733 * Adds an address to allow list 733 * Adds an address to allow list734 * @param signer keyring of signer734 * @param signer keyring of signer735 * @param collectionId ID of collection735 * @param collectionId ID of collection736 * @param addressObj address to add to the allow list736 * @param addressObj address to add to the allow list737 * @returns ```true``` if extrinsic success, otherwise ```false```737 * @returns ```true``` if extrinsic success, otherwise ```false```738 */738 */739 async addToAllowList(signer: TSigner, collectionId: number, addressObj: ICrossAccountId): Promise<boolean> {739 async addToAllowList(signer: TSigner, collectionId: number, addressObj: ICrossAccountId): Promise<boolean> {740 const result = await this.helper.executeExtrinsic(740 const result = await this.helper.executeExtrinsic(741 signer,741 signer,746 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'AllowListAddressAdded');746 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'AllowListAddressAdded');747 }747 }748748749 /**749 /**750 * Removes an address from allow list 750 * Removes an address from allow list751 * 751 *752 * @param signer keyring of signer752 * @param signer keyring of signer753 * @param collectionId ID of collection753 * @param collectionId ID of collection754 * @param addressObj address to remove from the allow list754 * @param addressObj address to remove from the allow list755 * @returns ```true``` if extrinsic success, otherwise ```false```755 * @returns ```true``` if extrinsic success, otherwise ```false```756 */756 */757 async removeFromAllowList(signer: TSigner, collectionId: number, addressObj: ICrossAccountId): Promise<boolean> {757 async removeFromAllowList(signer: TSigner, collectionId: number, addressObj: ICrossAccountId): Promise<boolean> {758 const result = await this.helper.executeExtrinsic(758 const result = await this.helper.executeExtrinsic(759 signer,759 signer,764 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'AllowListAddressRemoved');764 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'AllowListAddressRemoved');765 }765 }766766767 /**767 /**768 * Sets onchain permissions for selected collection.768 * Sets onchain permissions for selected collection.769 * 769 *770 * @param signer keyring of signer770 * @param signer keyring of signer771 * @param collectionId ID of collection771 * @param collectionId ID of collection772 * @param permissions collection permissions object772 * @param permissions collection permissions object773 * @example setPermissions(aliceKeyring, 10, {access:'AllowList', mintMode: true, nesting: {collectionAdmin: true, tokenOwner: true}});773 * @example setPermissions(aliceKeyring, 10, {access:'AllowList', mintMode: true, nesting: {collectionAdmin: true, tokenOwner: true}});774 * @returns ```true``` if extrinsic success, otherwise ```false```774 * @returns ```true``` if extrinsic success, otherwise ```false```775 */775 */776 async setPermissions(signer: TSigner, collectionId: number, permissions: ICollectionPermissions): Promise<boolean> {776 async setPermissions(signer: TSigner, collectionId: number, permissions: ICollectionPermissions): Promise<boolean> {777 const result = await this.helper.executeExtrinsic(777 const result = await this.helper.executeExtrinsic(778 signer,778 signer,783 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionPermissionSet');783 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionPermissionSet');784 }784 }785785786 /**786 /**787 * Enables nesting for selected collection. If `restricted` set, you can nest only tokens from specified collections.787 * Enables nesting for selected collection. If `restricted` set, you can nest only tokens from specified collections.788 * 788 *789 * @param signer keyring of signer789 * @param signer keyring of signer790 * @param collectionId ID of collection790 * @param collectionId ID of collection791 * @param permissions nesting permissions object791 * @param permissions nesting permissions object792 * @example enableNesting(aliceKeyring, 10, {collectionAdmin: true, tokenOwner: true});792 * @example enableNesting(aliceKeyring, 10, {collectionAdmin: true, tokenOwner: true});793 * @returns ```true``` if extrinsic success, otherwise ```false```793 * @returns ```true``` if extrinsic success, otherwise ```false```794 */794 */795 async enableNesting(signer: TSigner, collectionId: number, permissions: INestingPermissions): Promise<boolean> {795 async enableNesting(signer: TSigner, collectionId: number, permissions: INestingPermissions): Promise<boolean> {796 return await this.setPermissions(signer, collectionId, {nesting: permissions});796 return await this.setPermissions(signer, collectionId, {nesting: permissions});797 }797 }798798799 /**799 /**800 * Disables nesting for selected collection.800 * Disables nesting for selected collection.801 * 801 *802 * @param signer keyring of signer802 * @param signer keyring of signer803 * @param collectionId ID of collection803 * @param collectionId ID of collection804 * @example disableNesting(aliceKeyring, 10);804 * @example disableNesting(aliceKeyring, 10);805 * @returns ```true``` if extrinsic success, otherwise ```false```805 * @returns ```true``` if extrinsic success, otherwise ```false```806 */806 */807 async disableNesting(signer: TSigner, collectionId: number): Promise<boolean> {807 async disableNesting(signer: TSigner, collectionId: number): Promise<boolean> {808 return await this.setPermissions(signer, collectionId, {nesting: {tokenOwner: false, collectionAdmin: false}});808 return await this.setPermissions(signer, collectionId, {nesting: {tokenOwner: false, collectionAdmin: false}});809 }809 }810810811 /**811 /**812 * Sets onchain properties to the collection.812 * Sets onchain properties to the collection.813 * 813 *814 * @param signer keyring of signer814 * @param signer keyring of signer815 * @param collectionId ID of collection815 * @param collectionId ID of collection816 * @param properties array of property objects816 * @param properties array of property objects817 * @example setProperties(aliceKeyring, 10, [{key: "gender", value: "male"}]);817 * @example setProperties(aliceKeyring, 10, [{key: "gender", value: "male"}]);818 * @returns ```true``` if extrinsic success, otherwise ```false```818 * @returns ```true``` if extrinsic success, otherwise ```false```819 */819 */820 async setProperties(signer: TSigner, collectionId: number, properties: IProperty[]): Promise<boolean> {820 async setProperties(signer: TSigner, collectionId: number, properties: IProperty[]): Promise<boolean> {821 const result = await this.helper.executeExtrinsic(821 const result = await this.helper.executeExtrinsic(822 signer,822 signer,827 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'CollectionPropertySet');827 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'CollectionPropertySet');828 }828 }829829830 /**830 /**831 * Deletes onchain properties from the collection.831 * Deletes onchain properties from the collection.832 * 832 *833 * @param signer keyring of signer833 * @param signer keyring of signer834 * @param collectionId ID of collection834 * @param collectionId ID of collection835 * @param propertyKeys array of property keys to delete835 * @param propertyKeys array of property keys to delete836 * @example deleteProperties(aliceKeyring, 10, ["gender", "age"]);836 * @example deleteProperties(aliceKeyring, 10, ["gender", "age"]);837 * @returns ```true``` if extrinsic success, otherwise ```false```837 * @returns ```true``` if extrinsic success, otherwise ```false```838 */838 */839 async deleteProperties(signer: TSigner, collectionId: number, propertyKeys: string[]): Promise<boolean> {839 async deleteProperties(signer: TSigner, collectionId: number, propertyKeys: string[]): Promise<boolean> {840 const result = await this.helper.executeExtrinsic(840 const result = await this.helper.executeExtrinsic(841 signer,841 signer,846 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'CollectionPropertyDeleted');846 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'CollectionPropertyDeleted');847 }847 }848848849 /**849 /**850 * Changes the owner of the token.850 * Changes the owner of the token.851 * 851 *852 * @param signer keyring of signer852 * @param signer keyring of signer853 * @param collectionId ID of collection853 * @param collectionId ID of collection854 * @param tokenId ID of token854 * @param tokenId ID of token855 * @param addressObj address of a new owner855 * @param addressObj address of a new owner856 * @param amount amount of tokens to be transfered. For NFT must be set to 1n856 * @param amount amount of tokens to be transfered. For NFT must be set to 1n857 * @example transferToken(aliceKeyring, 10, 5, {Substrate: "5DyN4Y92vZCjv38fg..."})857 * @example transferToken(aliceKeyring, 10, 5, {Substrate: "5DyN4Y92vZCjv38fg..."})858 * @returns true if the token success, otherwise false858 * @returns true if the token success, otherwise false859 */859 */860 async transferToken(signer: TSigner, collectionId: number, tokenId: number, addressObj: ICrossAccountId, amount=1n): Promise<boolean> {860 async transferToken(signer: TSigner, collectionId: number, tokenId: number, addressObj: ICrossAccountId, amount=1n): Promise<boolean> {861 const result = await this.helper.executeExtrinsic(861 const result = await this.helper.executeExtrinsic(862 signer,862 signer,867 return this.helper.util.isTokenTransferSuccess(result.result.events, collectionId, tokenId, {Substrate: typeof signer === 'string' ? signer : signer.address}, addressObj, amount);867 return this.helper.util.isTokenTransferSuccess(result.result.events, collectionId, tokenId, {Substrate: typeof signer === 'string' ? signer : signer.address}, addressObj, amount);868 }868 }869869870 /**870 /**871 * 871 *872 * Change ownership of a token(s) on behalf of the owner. 872 * Change ownership of a token(s) on behalf of the owner.873 * 873 *874 * @param signer keyring of signer874 * @param signer keyring of signer875 * @param collectionId ID of collection875 * @param collectionId ID of collection876 * @param tokenId ID of token876 * @param tokenId ID of token877 * @param fromAddressObj address on behalf of which the token will be sent877 * @param fromAddressObj address on behalf of which the token will be sent878 * @param toAddressObj new token owner878 * @param toAddressObj new token owner879 * @param amount amount of tokens to be transfered. For NFT must be set to 1n879 * @param amount amount of tokens to be transfered. For NFT must be set to 1n880 * @example transferTokenFrom(aliceKeyring, 10, 5, {Substrate: "5DyN4Y92vZCjv38fg"}, {Ethereum: "0x9F0583DbB85..."})880 * @example transferTokenFrom(aliceKeyring, 10, 5, {Substrate: "5DyN4Y92vZCjv38fg"}, {Ethereum: "0x9F0583DbB85..."})881 * @returns true if the token success, otherwise false881 * @returns true if the token success, otherwise false882 */882 */883 async transferTokenFrom(signer: TSigner, collectionId: number, tokenId: number, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId, amount=1n): Promise<boolean> {883 async transferTokenFrom(signer: TSigner, collectionId: number, tokenId: number, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId, amount=1n): Promise<boolean> {884 const result = await this.helper.executeExtrinsic(884 const result = await this.helper.executeExtrinsic(885 signer,885 signer,889 return this.helper.util.isTokenTransferSuccess(result.result.events, collectionId, tokenId, fromAddressObj, toAddressObj, amount);889 return this.helper.util.isTokenTransferSuccess(result.result.events, collectionId, tokenId, fromAddressObj, toAddressObj, amount);890 }890 }891891892 /**892 /**893 * 893 *894 * Destroys a concrete instance of NFT/RFT or burns a specified amount of fungible tokens.894 * Destroys a concrete instance of NFT/RFT or burns a specified amount of fungible tokens.895 * 895 *896 * @param signer keyring of signer896 * @param signer keyring of signer897 * @param collectionId ID of collection897 * @param collectionId ID of collection898 * @param tokenId ID of token898 * @param tokenId ID of token899 * @param amount amount of tokens to be burned. For NFT must be set to 1n899 * @param amount amount of tokens to be burned. For NFT must be set to 1n900 * @example burnToken(aliceKeyring, 10, 5);900 * @example burnToken(aliceKeyring, 10, 5);901 * @returns ```true``` and burnt token number is extrinsic success. Otherwise ```false``` and ```null```901 * @returns ```true``` and burnt token number is extrinsic success. Otherwise ```false``` and ```null```902 */902 */903 async burnToken(signer: TSigner, collectionId: number, tokenId: number, amount=1n): Promise<{903 async burnToken(signer: TSigner, collectionId: number, tokenId: number, amount=1n): Promise<{904 success: boolean,904 success: boolean,905 token: number | null905 token: number | null914 return {success: burnedTokens.success, token: burnedTokens.tokens.length > 0 ? burnedTokens.tokens[0] : null};914 return {success: burnedTokens.success, token: burnedTokens.tokens.length > 0 ? burnedTokens.tokens[0] : null};915 }915 }916916917 /**917 /**918 * Destroys a concrete instance of NFT on behalf of the owner918 * Destroys a concrete instance of NFT on behalf of the owner919 * 919 *920 * @param signer keyring of signer920 * @param signer keyring of signer921 * @param collectionId ID of collection921 * @param collectionId ID of collection922 * @param fromAddressObj address on behalf of which the token will be burnt922 * @param fromAddressObj address on behalf of which the token will be burnt923 * @param tokenId ID of token923 * @param tokenId ID of token924 * @param amount amount of tokens to be burned. For NFT must be set to 1n924 * @param amount amount of tokens to be burned. For NFT must be set to 1n925 * @example burnTokenFrom(aliceKeyring, 10, {Substrate: "5DyN4Y92vZCjv38fg..."}, 5, {Ethereum: "0x9F0583DbB85..."})925 * @example burnTokenFrom(aliceKeyring, 10, {Substrate: "5DyN4Y92vZCjv38fg..."}, 5, {Ethereum: "0x9F0583DbB85..."})926 * @returns ```true``` if extrinsic success, otherwise ```false```926 * @returns ```true``` if extrinsic success, otherwise ```false```927 */927 */928 async burnTokenFrom(signer: TSigner, collectionId: number, fromAddressObj: ICrossAccountId, tokenId: number, amount=1n): Promise<boolean> {928 async burnTokenFrom(signer: TSigner, collectionId: number, fromAddressObj: ICrossAccountId, tokenId: number, amount=1n): Promise<boolean> {929 const burnResult = await this.helper.executeExtrinsic(929 const burnResult = await this.helper.executeExtrinsic(930 signer,930 signer,935 return burnedTokens.success && burnedTokens.tokens.length > 0;935 return burnedTokens.success && burnedTokens.tokens.length > 0;936 }936 }937937938 /**938 /**939 * Set, change, or remove approved address to transfer the ownership of the NFT.939 * Set, change, or remove approved address to transfer the ownership of the NFT.940 * 940 *941 * @param signer keyring of signer941 * @param signer keyring of signer942 * @param collectionId ID of collection942 * @param collectionId ID of collection943 * @param tokenId ID of token943 * @param tokenId ID of token944 * @param toAddressObj Substrate or Ethereum address which gets approved use of the signer's tokens944 * @param toAddressObj Substrate or Ethereum address which gets approved use of the signer's tokens945 * @param amount amount of token to be approved. For NFT must be set to 1n945 * @param amount amount of token to be approved. For NFT must be set to 1n946 * @returns ```true``` if extrinsic success, otherwise ```false```946 * @returns ```true``` if extrinsic success, otherwise ```false```947 */947 */948 async approveToken(signer: IKeyringPair, collectionId: number, tokenId: number, toAddressObj: ICrossAccountId, amount=1n) {948 async approveToken(signer: IKeyringPair, collectionId: number, tokenId: number, toAddressObj: ICrossAccountId, amount=1n) {949 const approveResult = await this.helper.executeExtrinsic(949 const approveResult = await this.helper.executeExtrinsic(950 signer, 950 signer,955 return this.helper.util.findCollectionInEvents(approveResult.result.events, collectionId, 'common', 'Approved');955 return this.helper.util.findCollectionInEvents(approveResult.result.events, collectionId, 'common', 'Approved');956 }956 }957957958 /**958 /**959 * Get the amount of token pieces approved to transfer or burn. Normally 0.959 * Get the amount of token pieces approved to transfer or burn. Normally 0.960 * 960 *961 * @param collectionId ID of collection961 * @param collectionId ID of collection962 * @param tokenId ID of token962 * @param tokenId ID of token963 * @param toAccountObj address which is approved to use token pieces963 * @param toAccountObj address which is approved to use token pieces964 * @param fromAccountObj address which may have allowed the use of its owned tokens964 * @param fromAccountObj address which may have allowed the use of its owned tokens965 * @example getTokenApprovedPieces(10, 5, {Substrate: "5DyN4Y92vZCjv38fg..."}, {Substrate: "5ERZNF88Mm7UGfPP3mdG..."})965 * @example getTokenApprovedPieces(10, 5, {Substrate: "5DyN4Y92vZCjv38fg..."}, {Substrate: "5ERZNF88Mm7UGfPP3mdG..."})966 * @returns number of approved to transfer pieces966 * @returns number of approved to transfer pieces967 */967 */968 async getTokenApprovedPieces(collectionId: number, tokenId: number, toAccountObj: ICrossAccountId, fromAccountObj: ICrossAccountId): Promise<bigint> {968 async getTokenApprovedPieces(collectionId: number, tokenId: number, toAccountObj: ICrossAccountId, fromAccountObj: ICrossAccountId): Promise<bigint> {969 return (await this.helper.callRpc('api.rpc.unique.allowance', [collectionId, fromAccountObj, toAccountObj, tokenId])).toBigInt();969 return (await this.helper.callRpc('api.rpc.unique.allowance', [collectionId, fromAccountObj, toAccountObj, tokenId])).toBigInt();970 }970 }971971972 /**972 /**973 * Get the last created token ID in a collection973 * Get the last created token ID in a collection974 * 974 *975 * @param collectionId ID of collection975 * @param collectionId ID of collection976 * @example getLastTokenId(10);976 * @example getLastTokenId(10);977 * @returns id of the last created token977 * @returns id of the last created token978 */978 */979 async getLastTokenId(collectionId: number): Promise<number> {979 async getLastTokenId(collectionId: number): Promise<number> {980 return (await this.helper.callRpc('api.rpc.unique.lastTokenId', [collectionId])).toNumber();980 return (await this.helper.callRpc('api.rpc.unique.lastTokenId', [collectionId])).toNumber();981 }981 }982982983 /**983 /**984 * Check if token exists984 * Check if token exists985 * 985 *986 * @param collectionId ID of collection986 * @param collectionId ID of collection987 * @param tokenId ID of token987 * @param tokenId ID of token988 * @example isTokenExists(10, 20);988 * @example isTokenExists(10, 20);989 * @returns true if the token exists, otherwise false989 * @returns true if the token exists, otherwise false990 */990 */991 async isTokenExists(collectionId: number, tokenId: number): Promise<boolean> {991 async isTokenExists(collectionId: number, tokenId: number): Promise<boolean> {992 return (await this.helper.callRpc('api.rpc.unique.tokenExists', [collectionId, tokenId])).toJSON();992 return (await this.helper.callRpc('api.rpc.unique.tokenExists', [collectionId, tokenId])).toJSON();993 }993 }994}994}995995996class NFTnRFT extends CollectionGroup {996class NFTnRFT extends CollectionGroup {997 /**997 /**998 * Get tokens owned by account998 * Get tokens owned by account999 * 999 *1000 * @param collectionId ID of collection1000 * @param collectionId ID of collection1001 * @param addressObj tokens owner1001 * @param addressObj tokens owner1002 * @example getTokensByAddress(10, {Substrate: "5DyN4Y92vZCjv38fg..."})1002 * @example getTokensByAddress(10, {Substrate: "5DyN4Y92vZCjv38fg..."})1003 * @returns array of token ids owned by account1003 * @returns array of token ids owned by account1004 */1004 */1005 async getTokensByAddress(collectionId: number, addressObj: ICrossAccountId): Promise<number[]> {1005 async getTokensByAddress(collectionId: number, addressObj: ICrossAccountId): Promise<number[]> {1006 return (await this.helper.callRpc('api.rpc.unique.accountTokens', [collectionId, addressObj])).toJSON();1006 return (await this.helper.callRpc('api.rpc.unique.accountTokens', [collectionId, addressObj])).toJSON();1007 }1007 }100810081009 /**1009 /**1010 * Get token data1010 * Get token data1011 * 1011 *1012 * @param collectionId ID of collection1012 * @param collectionId ID of collection1013 * @param tokenId ID of token1013 * @param tokenId ID of token1014 * @param propertyKeys optionally filter the token properties to only these keys1014 * @param propertyKeys optionally filter the token properties to only these keys1015 * @param blockHashAt optionally query the data at some block with this hash1015 * @param blockHashAt optionally query the data at some block with this hash1016 * @example getToken(10, 5);1016 * @example getToken(10, 5);1017 * @returns human readable token data 1017 * @returns human readable token data1018 */1018 */1019 async getToken(collectionId: number, tokenId: number, propertyKeys: string[] = [], blockHashAt?: string): Promise<{1019 async getToken(collectionId: number, tokenId: number, propertyKeys: string[] = [], blockHashAt?: string): Promise<{1020 properties: IProperty[];1020 properties: IProperty[];1021 owner: ICrossAccountId;1021 owner: ICrossAccountId;1043 return tokenData;1043 return tokenData;1044 }1044 }104510451046 /**1046 /**1047 * Set permissions to change token properties1047 * Set permissions to change token properties1048 * 1048 *1049 * @param signer keyring of signer1049 * @param signer keyring of signer1050 * @param collectionId ID of collection1050 * @param collectionId ID of collection1051 * @param permissions permissions to change a property by the collection owner or admin1051 * @param permissions permissions to change a property by the collection owner or admin1052 * @example setTokenPropertyPermissions(1052 * @example setTokenPropertyPermissions(1053 * aliceKeyring, 10, [{key: "gender", permission: {tokenOwner: true, mutable: true, collectionAdmin: true}}]1053 * aliceKeyring, 10, [{key: "gender", permission: {tokenOwner: true, mutable: true, collectionAdmin: true}}]1054 * )1054 * )1055 * @returns true if extrinsic success otherwise false1055 * @returns true if extrinsic success otherwise false1056 */1056 */1057 async setTokenPropertyPermissions(signer: TSigner, collectionId: number, permissions: ITokenPropertyPermission[]): Promise<boolean> {1057 async setTokenPropertyPermissions(signer: TSigner, collectionId: number, permissions: ITokenPropertyPermission[]): Promise<boolean> {1058 const result = await this.helper.executeExtrinsic(1058 const result = await this.helper.executeExtrinsic(1059 signer,1059 signer,1064 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'PropertyPermissionSet');1064 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'PropertyPermissionSet');1065 }1065 }106610661067 /**1067 /**1068 * Set token properties1068 * Set token properties1069 * 1069 *1070 * @param signer keyring of signer1070 * @param signer keyring of signer1071 * @param collectionId ID of collection1071 * @param collectionId ID of collection1072 * @param tokenId ID of token1072 * @param tokenId ID of token1073 * @param properties key-value pairs of metadata which to add to a token. Keys must be permitted in the collection1073 * @param properties key-value pairs of metadata which to add to a token. Keys must be permitted in the collection1074 * @example setTokenProperties(aliceKeyring, 10, 5, [{key: "gender", value: "female"}, {key: "age", value: "23"}])1074 * @example setTokenProperties(aliceKeyring, 10, 5, [{key: "gender", value: "female"}, {key: "age", value: "23"}])1075 * @returns ```true``` if extrinsic success, otherwise ```false```1075 * @returns ```true``` if extrinsic success, otherwise ```false```1076 */1076 */1077 async setTokenProperties(signer: TSigner, collectionId: number, tokenId: number, properties: IProperty[]): Promise<boolean> {1077 async setTokenProperties(signer: TSigner, collectionId: number, tokenId: number, properties: IProperty[]): Promise<boolean> {1078 const result = await this.helper.executeExtrinsic(1078 const result = await this.helper.executeExtrinsic(1079 signer,1079 signer,1084 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'TokenPropertySet');1084 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'TokenPropertySet');1085 }1085 }108610861087 /**1087 /**1088 * Delete the provided properties of a token1088 * Delete the provided properties of a token1089 * @param signer keyring of signer1089 * @param signer keyring of signer1090 * @param collectionId ID of collection1090 * @param collectionId ID of collection1091 * @param tokenId ID of token1091 * @param tokenId ID of token1092 * @param propertyKeys property keys to be deleted 1092 * @param propertyKeys property keys to be deleted1093 * @example deleteTokenProperties(aliceKeyring, 10, 5, ["gender", "age"])1093 * @example deleteTokenProperties(aliceKeyring, 10, 5, ["gender", "age"])1094 * @returns ```true``` if extrinsic success, otherwise ```false```1094 * @returns ```true``` if extrinsic success, otherwise ```false```1095 */1095 */1096 async deleteTokenProperties(signer: TSigner, collectionId: number, tokenId: number, propertyKeys: string[]): Promise<boolean> {1096 async deleteTokenProperties(signer: TSigner, collectionId: number, tokenId: number, propertyKeys: string[]): Promise<boolean> {1097 const result = await this.helper.executeExtrinsic(1097 const result = await this.helper.executeExtrinsic(1098 signer,1098 signer,1103 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'TokenPropertyDeleted');1103 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'TokenPropertyDeleted');1104 }1104 }110511051106 /**1106 /**1107 * Mint new collection1107 * Mint new collection1108 * 1108 *1109 * @param signer keyring of signer1109 * @param signer keyring of signer1110 * @param collectionOptions basic collection options and properties 1110 * @param collectionOptions basic collection options and properties1111 * @param mode NFT or RFT type of a collection1111 * @param mode NFT or RFT type of a collection1112 * @example mintCollection(aliceKeyring, {name: 'New', description: "New collection", tokenPrefix: "NEW"}, "NFT")1112 * @example mintCollection(aliceKeyring, {name: 'New', description: "New collection", tokenPrefix: "NEW"}, "NFT")1113 * @returns object of the created collection1113 * @returns object of the created collection1114 */1114 */1115 async mintCollection(signer: TSigner, collectionOptions: ICollectionCreationOptions, mode: 'NFT' | 'RFT'): Promise<UniqueCollectionBase> {1115 async mintCollection(signer: TSigner, collectionOptions: ICollectionCreationOptions, mode: 'NFT' | 'RFT'): Promise<UniqueCollectionBase> {1116 collectionOptions = JSON.parse(JSON.stringify(collectionOptions)) as ICollectionCreationOptions; // Clone object1116 collectionOptions = JSON.parse(JSON.stringify(collectionOptions)) as ICollectionCreationOptions; // Clone object1117 collectionOptions.mode = (mode === 'NFT') ? {nft: null} : {refungible: null};1117 collectionOptions.mode = (mode === 'NFT') ? {nft: null} : {refungible: null};1187 return (await this.getTokenApprovedPieces(collectionId, tokenId, toAccountObj, await this.getTokenOwner(collectionId, tokenId))) === 1n;1187 return (await this.getTokenApprovedPieces(collectionId, tokenId, toAccountObj, await this.getTokenOwner(collectionId, tokenId))) === 1n;1188 }1188 }118911891190 /**1190 /**1191 * Changes the owner of the token.1191 * Changes the owner of the token.1192 * 1192 *1193 * @param signer keyring of signer1193 * @param signer keyring of signer1194 * @param collectionId ID of collection1194 * @param collectionId ID of collection1195 * @param tokenId ID of token1195 * @param tokenId ID of token1196 * @param addressObj address of a new owner1196 * @param addressObj address of a new owner1197 * @example transferToken(aliceKeyring, 10, 5, {Substrate: "5DyN4Y92vZCjv38fg..."})1197 * @example transferToken(aliceKeyring, 10, 5, {Substrate: "5DyN4Y92vZCjv38fg..."})1198 * @returns ```true``` if extrinsic success, otherwise ```false```1198 * @returns ```true``` if extrinsic success, otherwise ```false```1199 */1199 */1200 async transferToken(signer: TSigner, collectionId: number, tokenId: number, addressObj: ICrossAccountId): Promise<boolean> {1200 async transferToken(signer: TSigner, collectionId: number, tokenId: number, addressObj: ICrossAccountId): Promise<boolean> {1201 return await super.transferToken(signer, collectionId, tokenId, addressObj, 1n);1201 return await super.transferToken(signer, collectionId, tokenId, addressObj, 1n);1202 }1202 }120312031204 /**1204 /**1205 * 1205 *1206 * Change ownership of a NFT on behalf of the owner. 1206 * Change ownership of a NFT on behalf of the owner.1207 * 1207 *1208 * @param signer keyring of signer1208 * @param signer keyring of signer1209 * @param collectionId ID of collection1209 * @param collectionId ID of collection1210 * @param tokenId ID of token1210 * @param tokenId ID of token1211 * @param fromAddressObj address on behalf of which the token will be sent1211 * @param fromAddressObj address on behalf of which the token will be sent1212 * @param toAddressObj new token owner1212 * @param toAddressObj new token owner1213 * @example transferTokenFrom(aliceKeyring, 10, 5, {Substrate: "5DyN4Y92vZCjv38fg..."}, {Ethereum: "0x9F0583DbB85..."})1213 * @example transferTokenFrom(aliceKeyring, 10, 5, {Substrate: "5DyN4Y92vZCjv38fg..."}, {Ethereum: "0x9F0583DbB85..."})1214 * @returns ```true``` if extrinsic success, otherwise ```false```1214 * @returns ```true``` if extrinsic success, otherwise ```false```1215 */1215 */1216 async transferTokenFrom(signer: TSigner, collectionId: number, tokenId: number, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId): Promise<boolean> {1216 async transferTokenFrom(signer: TSigner, collectionId: number, tokenId: number, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId): Promise<boolean> {1217 return await super.transferTokenFrom(signer, collectionId, tokenId, fromAddressObj, toAddressObj, 1n);1217 return await super.transferTokenFrom(signer, collectionId, tokenId, fromAddressObj, toAddressObj, 1n);1218 }1218 }121912191220 /**1220 /**1221 * Recursively find the address that owns the token1221 * Recursively find the address that owns the token1222 * @param collectionId ID of collection1222 * @param collectionId ID of collection1223 * @param tokenId ID of token1223 * @param tokenId ID of token1224 * @param blockHashAt 1224 * @param blockHashAt1225 * @example getTokenTopmostOwner(10, 5);1225 * @example getTokenTopmostOwner(10, 5);1226 * @returns address in CrossAccountId format, e.g. {Substrate: "5DyN4Y92vZCjv38fg..."}1226 * @returns address in CrossAccountId format, e.g. {Substrate: "5DyN4Y92vZCjv38fg..."}1227 */1227 */1228 async getTokenTopmostOwner(collectionId: number, tokenId: number, blockHashAt?: string): Promise<ICrossAccountId | null> {1228 async getTokenTopmostOwner(collectionId: number, tokenId: number, blockHashAt?: string): Promise<ICrossAccountId | null> {1229 let owner;1229 let owner;1230 if (typeof blockHashAt === 'undefined') {1230 if (typeof blockHashAt === 'undefined') {1240 return owner.Substrate ? {Substrate: this.helper.address.normalizeSubstrate(owner.Substrate)} : owner;1240 return owner.Substrate ? {Substrate: this.helper.address.normalizeSubstrate(owner.Substrate)} : owner;1241 }1241 }124212421243 /**1243 /**1244 * Get tokens nested in the provided token1244 * Get tokens nested in the provided token1245 * @param collectionId ID of collection1245 * @param collectionId ID of collection1246 * @param tokenId ID of token1246 * @param tokenId ID of token1247 * @param blockHashAt optionally query the data at the block with this hash1247 * @param blockHashAt optionally query the data at the block with this hash1248 * @example getTokenChildren(10, 5);1248 * @example getTokenChildren(10, 5);1249 * @returns tokens whose depth of nesting is <= 5 1249 * @returns tokens whose depth of nesting is <= 51250 */1250 */1251 async getTokenChildren(collectionId: number, tokenId: number, blockHashAt?: string): Promise<IToken[]> {1251 async getTokenChildren(collectionId: number, tokenId: number, blockHashAt?: string): Promise<IToken[]> {1252 let children;1252 let children;1253 if(typeof blockHashAt === 'undefined') {1253 if(typeof blockHashAt === 'undefined') {1278 return result;1278 return result;1279 }1279 }128012801281 /**1281 /**1282 * Remove token from nested state1282 * Remove token from nested state1283 * @param signer keyring of signer1283 * @param signer keyring of signer1284 * @param tokenObj token to unnest1284 * @param tokenObj token to unnest1285 * @param rootTokenObj parent of a token1285 * @param rootTokenObj parent of a token1286 * @param toAddressObj address of a new token owner 1286 * @param toAddressObj address of a new token owner1287 * @example unnestToken(aliceKeyring, {collectionId: 10, tokenId: 5}, {collectionId: 10, tokenId: 4}, {Substrate: "5DyN4Y92vZCjv38fg..."});1287 * @example unnestToken(aliceKeyring, {collectionId: 10, tokenId: 5}, {collectionId: 10, tokenId: 4}, {Substrate: "5DyN4Y92vZCjv38fg..."});1288 * @returns ```true``` if extrinsic success, otherwise ```false```1288 * @returns ```true``` if extrinsic success, otherwise ```false```1289 */1289 */1290 async unnestToken(signer: TSigner, tokenObj: IToken, rootTokenObj: IToken, toAddressObj: ICrossAccountId): Promise<boolean> {1290 async unnestToken(signer: TSigner, tokenObj: IToken, rootTokenObj: IToken, toAddressObj: ICrossAccountId): Promise<boolean> {1291 const rootTokenAddress = {Ethereum: this.helper.util.getNestingTokenAddress(rootTokenObj.collectionId, rootTokenObj.tokenId)};1291 const rootTokenAddress = {Ethereum: this.helper.util.getNestingTokenAddress(rootTokenObj.collectionId, rootTokenObj.tokenId)};1292 const result = await this.transferTokenFrom(signer, tokenObj.collectionId, tokenObj.tokenId, rootTokenAddress, toAddressObj);1292 const result = await this.transferTokenFrom(signer, tokenObj.collectionId, tokenObj.tokenId, rootTokenAddress, toAddressObj);1296 return result;1296 return result;1297 }1297 }129812981299 /**1299 /**1300 * Mint new collection1300 * Mint new collection1301 * @param signer keyring of signer1301 * @param signer keyring of signer1302 * @param collectionOptions Collection options1302 * @param collectionOptions Collection options1303 * @example 1303 * @example1304 * mintCollection(aliceKeyring, {1304 * mintCollection(aliceKeyring, {1305 * name: 'New',1305 * name: 'New',1306 * description: 'New collection',1306 * description: 'New collection',1307 * tokenPrefix: 'NEW',1307 * tokenPrefix: 'NEW',1308 * })1308 * })1309 * @returns object of the created collection1309 * @returns object of the created collection1310 */1310 */1311 async mintCollection(signer: TSigner, collectionOptions: ICollectionCreationOptions): Promise<UniqueNFTCollection> {1311 async mintCollection(signer: TSigner, collectionOptions: ICollectionCreationOptions): Promise<UniqueNFTCollection> {1312 return await super.mintCollection(signer, collectionOptions, 'NFT') as UniqueNFTCollection;1312 return await super.mintCollection(signer, collectionOptions, 'NFT') as UniqueNFTCollection;1313 }1313 }1334 return this.getTokenObject(data.collectionId, createdTokens.tokens[0].tokenId);1334 return this.getTokenObject(data.collectionId, createdTokens.tokens[0].tokenId);1335 }1335 }133613361337 /**1337 /**1338 * Mint multiple NFT tokens1338 * Mint multiple NFT tokens1339 * @param signer keyring of signer1339 * @param signer keyring of signer1340 * @param collectionId ID of collection1340 * @param collectionId ID of collection1341 * @param tokens array of tokens with owner and properties1341 * @param tokens array of tokens with owner and properties1342 * @example 1342 * @example1343 * mintMultipleTokens(aliceKeyring, 10, [{1343 * mintMultipleTokens(aliceKeyring, 10, [{1344 * owner: {Substrate: "5DyN4Y92vZCjv38fg..."},1344 * owner: {Substrate: "5DyN4Y92vZCjv38fg..."},1345 * properties: [{key: "gender", value: "male"},{key: "age", value: "45"}],1345 * properties: [{key: "gender", value: "male"},{key: "age", value: "45"}],1346 * },{1346 * },{1347 * owner: {Ethereum: "0x9F0583DbB855d..."},1347 * owner: {Ethereum: "0x9F0583DbB855d..."},1348 * properties: [{key: "gender", value: "female"},{key: "age", value: "22"}],1348 * properties: [{key: "gender", value: "female"},{key: "age", value: "22"}],1349 * }]);1349 * }]);1350 * @returns ```true``` if extrinsic success, otherwise ```false```1350 * @returns ```true``` if extrinsic success, otherwise ```false```1351 */1351 */1352 async mintMultipleTokens(signer: TSigner, collectionId: number, tokens: {owner: ICrossAccountId, properties?: IProperty[]}[]): Promise<UniqueNFTToken[]> {1352 async mintMultipleTokens(signer: TSigner, collectionId: number, tokens: {owner: ICrossAccountId, properties?: IProperty[]}[]): Promise<UniqueNFTToken[]> {1353 const creationResult = await this.helper.executeExtrinsic(1353 const creationResult = await this.helper.executeExtrinsic(1354 signer,1354 signer,1392 return this.helper.util.extractTokensFromCreationResult(creationResult).tokens.map((x: IToken) => collection.getTokenObject(x.tokenId));1392 return this.helper.util.extractTokensFromCreationResult(creationResult).tokens.map((x: IToken) => collection.getTokenObject(x.tokenId));1393 }1393 }13941395 /**1396 * Destroys a concrete instance of NFT.1397 * @param signer keyring of signer1398 * @param collectionId ID of collection1399 * @param tokenId ID of token1400 * @example burnToken(aliceKeyring, 10, 5);1401 * @returns ```true``` and burnt token number is extrinsic success. Otherwise ```false``` and ```null```1402 */1403 async burnToken(signer: IKeyringPair, collectionId: number, tokenId: number): Promise<{ success: boolean; token: number | null; }> {1404 return await super.burnToken(signer, collectionId, tokenId, 1n);1405 }140613941407 /**1395 /**1408 * Set, change, or remove approved address to transfer the ownership of the NFT.1396 * Set, change, or remove approved address to transfer the ownership of the NFT.1409 * 1397 *1410 * @param signer keyring of signer1398 * @param signer keyring of signer1411 * @param collectionId ID of collection1399 * @param collectionId ID of collection1412 * @param tokenId ID of token1400 * @param tokenId ID of token1413 * @param toAddressObj address to approve1401 * @param toAddressObj address to approve1414 * @example approveToken(aliceKeyring, 10, 5, {Substrate: "5DyN4Y92vZCjv38fg..."})1402 * @example approveToken(aliceKeyring, 10, 5, {Substrate: "5DyN4Y92vZCjv38fg..."})1415 * @returns ```true``` if extrinsic success, otherwise ```false```1403 * @returns ```true``` if extrinsic success, otherwise ```false```1416 */1404 */1417 async approveToken(signer: IKeyringPair, collectionId: number, tokenId: number, toAddressObj: ICrossAccountId) {1405 async approveToken(signer: IKeyringPair, collectionId: number, tokenId: number, toAddressObj: ICrossAccountId) {1418 return super.approveToken(signer, collectionId, tokenId, toAddressObj, 1n);1406 return super.approveToken(signer, collectionId, tokenId, toAddressObj, 1n);1419 }1407 }1442 return new UniqueRFTToken(tokenId, this.getCollectionObject(collectionId));1430 return new UniqueRFTToken(tokenId, this.getCollectionObject(collectionId));1443 }1431 }144414321445 /**1433 /**1446 * Get top 10 token owners with the largest number of pieces 1434 * Get top 10 token owners with the largest number of pieces1447 * @param collectionId ID of collection1435 * @param collectionId ID of collection1448 * @param tokenId ID of token1436 * @param tokenId ID of token1449 * @example getTokenTop10Owners(10, 5);1437 * @example getTokenTop10Owners(10, 5);1450 * @returns array of top 10 owners1438 * @returns array of top 10 owners1451 */1439 */1452 async getTokenTop10Owners(collectionId: number, tokenId: number): Promise<ICrossAccountId[]> {1440 async getTokenTop10Owners(collectionId: number, tokenId: number): Promise<ICrossAccountId[]> {1453 return (await this.helper.callRpc('api.rpc.unique.tokenOwners', [collectionId, tokenId])).toJSON().map(crossAccountIdFromLower);1441 return (await this.helper.callRpc('api.rpc.unique.tokenOwners', [collectionId, tokenId])).toJSON().map(crossAccountIdFromLower);1454 }1442 }1479 return await super.transferToken(signer, collectionId, tokenId, addressObj, amount);1467 return await super.transferToken(signer, collectionId, tokenId, addressObj, amount);1480 }1468 }148114691482 /**1470 /**1483 * Change ownership of some pieces of RFT on behalf of the owner. 1471 * Change ownership of some pieces of RFT on behalf of the owner.1484 * @param signer keyring of signer1472 * @param signer keyring of signer1485 * @param collectionId ID of collection1473 * @param collectionId ID of collection1486 * @param tokenId ID of token1474 * @param tokenId ID of token1487 * @param fromAddressObj address on behalf of which the token will be sent1475 * @param fromAddressObj address on behalf of which the token will be sent1488 * @param toAddressObj new token owner1476 * @param toAddressObj new token owner1489 * @param amount number of pieces to be transfered1477 * @param amount number of pieces to be transfered1490 * @example transferTokenFrom(aliceKeyring, 10, 5, {Substrate: "5DyN4Y92vZCjv38fg..."}, {Substrate: "5DfhbVfww7ThF8q6f3i..."}, 2000n)1478 * @example transferTokenFrom(aliceKeyring, 10, 5, {Substrate: "5DyN4Y92vZCjv38fg..."}, {Substrate: "5DfhbVfww7ThF8q6f3i..."}, 2000n)1491 * @returns ```true``` if extrinsic success, otherwise ```false```1479 * @returns ```true``` if extrinsic success, otherwise ```false```1492 */1480 */1493 async transferTokenFrom(signer: TSigner, collectionId: number, tokenId: number, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId, amount=1n): Promise<boolean> {1481 async transferTokenFrom(signer: TSigner, collectionId: number, tokenId: number, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId, amount=1n): Promise<boolean> {1494 return await super.transferTokenFrom(signer, collectionId, tokenId, fromAddressObj, toAddressObj, amount);1482 return await super.transferTokenFrom(signer, collectionId, tokenId, fromAddressObj, toAddressObj, amount);1495 }1483 }1582 return await super.burnToken(signer, collectionId, tokenId, amount);1570 return await super.burnToken(signer, collectionId, tokenId, amount);1583 }1571 }158415721585 /**1573 /**1586 * Set, change, or remove approved address to transfer the ownership of the RFT.1574 * Set, change, or remove approved address to transfer the ownership of the RFT.1587 * 1575 *1588 * @param signer keyring of signer1576 * @param signer keyring of signer1589 * @param collectionId ID of collection1577 * @param collectionId ID of collection1590 * @param tokenId ID of token1578 * @param tokenId ID of token1591 * @param toAddressObj address to approve1579 * @param toAddressObj address to approve1592 * @param amount number of pieces to be approved1580 * @param amount number of pieces to be approved1593 * @example approveToken(aliceKeyring, 10, 5, {Substrate: "5GHoZe9c73RYbVzq..."}, "", 10000n);1581 * @example approveToken(aliceKeyring, 10, 5, {Substrate: "5GHoZe9c73RYbVzq..."}, "", 10000n);1594 * @returns true if the token success, otherwise false1582 * @returns true if the token success, otherwise false1595 */1583 */1596 async approveToken(signer: IKeyringPair, collectionId: number, tokenId: number, toAddressObj: ICrossAccountId, amount=1n) {1584 async approveToken(signer: IKeyringPair, collectionId: number, tokenId: number, toAddressObj: ICrossAccountId, amount=1n) {1597 return super.approveToken(signer, collectionId, tokenId, toAddressObj, amount);1585 return super.approveToken(signer, collectionId, tokenId, toAddressObj, amount);1598 }1586 }1641 return new UniqueFTCollection(collectionId, this.helper);1629 return new UniqueFTCollection(collectionId, this.helper);1642 }1630 }164316311644 /**1632 /**1645 * Mint new fungible collection1633 * Mint new fungible collection1646 * @param signer keyring of signer1634 * @param signer keyring of signer1647 * @param collectionOptions Collection options1635 * @param collectionOptions Collection options1648 * @param decimalPoints number of token decimals 1636 * @param decimalPoints number of token decimals1649 * @example1637 * @example1650 * mintCollection(aliceKeyring, {1638 * mintCollection(aliceKeyring, {1651 * name: 'New',1639 * name: 'New',1652 * description: 'New collection',1640 * description: 'New collection',1653 * tokenPrefix: 'NEW',1641 * tokenPrefix: 'NEW',1654 * }, 18)1642 * }, 18)1655 * @returns newly created fungible collection1643 * @returns newly created fungible collection1656 */1644 */1657 async mintCollection(signer: TSigner, collectionOptions: ICollectionCreationOptions, decimalPoints = 0): Promise<UniqueFTCollection> {1645 async mintCollection(signer: TSigner, collectionOptions: ICollectionCreationOptions, decimalPoints = 0): Promise<UniqueFTCollection> {1658 collectionOptions = JSON.parse(JSON.stringify(collectionOptions)) as ICollectionCreationOptions; // Clone object1646 collectionOptions = JSON.parse(JSON.stringify(collectionOptions)) as ICollectionCreationOptions; // Clone object1659 if(collectionOptions.tokenPropertyPermissions) throw Error('Fungible collections has no tokenPropertyPermissions');1647 if(collectionOptions.tokenPropertyPermissions) throw Error('Fungible collections has no tokenPropertyPermissions');1669 return this.getCollectionObject(this.helper.util.extractCollectionIdFromCreationResult(creationResult));1657 return this.getCollectionObject(this.helper.util.extractCollectionIdFromCreationResult(creationResult));1670 }1658 }167116591672 /**1660 /**1673 * Mint tokens1661 * Mint tokens1674 * @param signer keyring of signer1662 * @param signer keyring of signer1675 * @param collectionId ID of collection1663 * @param collectionId ID of collection1676 * @param owner address owner of new tokens1664 * @param owner address owner of new tokens1677 * @param amount amount of tokens to be meanted1665 * @param amount amount of tokens to be meanted1678 * @example mintTokens(aliceKeyring, 10, {Substrate: "5GHoZe9c73RYbVzq"}, 1000n);1666 * @example mintTokens(aliceKeyring, 10, {Substrate: "5GHoZe9c73RYbVzq"}, 1000n);1679 * @returns ```true``` if extrinsic success, otherwise ```false``` 1667 * @returns ```true``` if extrinsic success, otherwise ```false```1680 */1668 */1681 async mintTokens(signer: TSigner, collectionId: number, amount: bigint, owner: ICrossAccountId | string): Promise<boolean> {1669 async mintTokens(signer: TSigner, collectionId: number, amount: bigint, owner: ICrossAccountId | string): Promise<boolean> {1682 const creationResult = await this.helper.executeExtrinsic(1670 const creationResult = await this.helper.executeExtrinsic(1683 signer,1671 signer,1691 return this.helper.util.findCollectionInEvents(creationResult.result.events, collectionId, 'common', 'ItemCreated');1679 return this.helper.util.findCollectionInEvents(creationResult.result.events, collectionId, 'common', 'ItemCreated');1692 }1680 }169316811694 /**1682 /**1695 * Mint multiple Fungible tokens with one owner1683 * Mint multiple Fungible tokens with one owner1696 * @param signer keyring of signer1684 * @param signer keyring of signer1697 * @param collectionId ID of collection1685 * @param collectionId ID of collection1698 * @param owner tokens owner1686 * @param owner tokens owner1699 * @param tokens array of tokens with properties and pieces1687 * @param tokens array of tokens with properties and pieces1700 * @returns ```true``` if extrinsic success, otherwise ```false``` 1688 * @returns ```true``` if extrinsic success, otherwise ```false```1701 */1689 */1702 async mintMultipleTokensWithOneOwner(signer: TSigner, collectionId: number, tokens: {value: bigint}[], owner: ICrossAccountId): Promise<boolean> {1690 async mintMultipleTokensWithOneOwner(signer: TSigner, collectionId: number, tokens: {value: bigint}[], owner: ICrossAccountId): Promise<boolean> {1703 const rawTokens = [];1691 const rawTokens = [];1704 for (const token of tokens) {1692 for (const token of tokens) {1713 return this.helper.util.findCollectionInEvents(creationResult.result.events, collectionId, 'common', 'ItemCreated');1701 return this.helper.util.findCollectionInEvents(creationResult.result.events, collectionId, 'common', 'ItemCreated');1714 }1702 }171517031716 /**1704 /**1717 * Get the top 10 owners with the largest balance for the Fungible collection 1705 * Get the top 10 owners with the largest balance for the Fungible collection1718 * @param collectionId ID of collection1706 * @param collectionId ID of collection1719 * @example getTop10Owners(10);1707 * @example getTop10Owners(10);1720 * @returns array of ```ICrossAccountId```1708 * @returns array of ```ICrossAccountId```1721 */1709 */1722 async getTop10Owners(collectionId: number): Promise<ICrossAccountId[]> {1710 async getTop10Owners(collectionId: number): Promise<ICrossAccountId[]> {1723 return (await this.helper.callRpc('api.rpc.unique.tokenOwners', [collectionId, 0])).toJSON().map(crossAccountIdFromLower);1711 return (await this.helper.callRpc('api.rpc.unique.tokenOwners', [collectionId, 0])).toJSON().map(crossAccountIdFromLower);1724 }1712 }1734 return (await this.helper.callRpc('api.rpc.unique.balance', [collectionId, addressObj, 0])).toBigInt();1722 return (await this.helper.callRpc('api.rpc.unique.balance', [collectionId, addressObj, 0])).toBigInt();1735 }1723 }173617241737 /**1725 /**1738 * Transfer tokens to address1726 * Transfer tokens to address1739 * @param signer keyring of signer1727 * @param signer keyring of signer1740 * @param collectionId ID of collection1728 * @param collectionId ID of collection1741 * @param toAddressObj address recipient1729 * @param toAddressObj address recipient1742 * @param amount amount of tokens to be sent1730 * @param amount amount of tokens to be sent1743 * @example transfer(aliceKeyring, 10, {Substrate: "5GHoZe9c73RYbVzq..."}, 1000n);1731 * @example transfer(aliceKeyring, 10, {Substrate: "5GHoZe9c73RYbVzq..."}, 1000n);1744 * @returns ```true``` if extrinsic success, otherwise ```false``` 1732 * @returns ```true``` if extrinsic success, otherwise ```false```1745 */1733 */1746 async transfer(signer: TSigner, collectionId: number, toAddressObj: ICrossAccountId, amount=1n) {1734 async transfer(signer: TSigner, collectionId: number, toAddressObj: ICrossAccountId, amount=1n) {1747 return await super.transferToken(signer, collectionId, 0, toAddressObj, amount);1735 return await super.transferToken(signer, collectionId, 0, toAddressObj, amount);1748 }1736 }174917371750 /**1738 /**1751 * Transfer some tokens on behalf of the owner.1739 * Transfer some tokens on behalf of the owner.1752 * @param signer keyring of signer1740 * @param signer keyring of signer1753 * @param collectionId ID of collection1741 * @param collectionId ID of collection1754 * @param fromAddressObj address on behalf of which tokens will be sent1742 * @param fromAddressObj address on behalf of which tokens will be sent1755 * @param toAddressObj address where token to be sent1743 * @param toAddressObj address where token to be sent1756 * @param amount number of tokens to be sent1744 * @param amount number of tokens to be sent1757 * @example transferFrom(aliceKeyring, 10, {Substrate: "5GHoZe9c73RYbVzq..."}, {Substrate: "5DfhbVfww7ThF8q6f3ij..."}, 10000n);1745 * @example transferFrom(aliceKeyring, 10, {Substrate: "5GHoZe9c73RYbVzq..."}, {Substrate: "5DfhbVfww7ThF8q6f3ij..."}, 10000n);1758 * @returns ```true``` if extrinsic success, otherwise ```false``` 1746 * @returns ```true``` if extrinsic success, otherwise ```false```1759 */1747 */1760 async transferFrom(signer: TSigner, collectionId: number, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId, amount=1n) {1748 async transferFrom(signer: TSigner, collectionId: number, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId, amount=1n) {1761 return await super.transferTokenFrom(signer, collectionId, 0, fromAddressObj, toAddressObj, amount);1749 return await super.transferTokenFrom(signer, collectionId, 0, fromAddressObj, toAddressObj, amount);1762 }1750 }176317511764 /**1752 /**1765 * Destroy some amount of tokens1753 * Destroy some amount of tokens1766 * @param signer keyring of signer1754 * @param signer keyring of signer1767 * @param collectionId ID of collection1755 * @param collectionId ID of collection1768 * @param amount amount of tokens to be destroyed1756 * @param amount amount of tokens to be destroyed1769 * @example burnTokens(aliceKeyring, 10, 1000n);1757 * @example burnTokens(aliceKeyring, 10, 1000n);1770 * @returns ```true``` if extrinsic success, otherwise ```false``` 1758 * @returns ```true``` if extrinsic success, otherwise ```false```1771 */1759 */1772 async burnTokens(signer: IKeyringPair, collectionId: number, amount=1n): Promise<boolean> {1760 async burnTokens(signer: IKeyringPair, collectionId: number, amount=1n): Promise<boolean> {1773 return (await super.burnToken(signer, collectionId, 0, amount)).success;1761 return (await super.burnToken(signer, collectionId, 0, amount)).success;1774 }1762 }177517631776 /**1764 /**1777 * Burn some tokens on behalf of the owner.1765 * Burn some tokens on behalf of the owner.1778 * @param signer keyring of signer1766 * @param signer keyring of signer1779 * @param collectionId ID of collection1767 * @param collectionId ID of collection1780 * @param fromAddressObj address on behalf of which tokens will be burnt1768 * @param fromAddressObj address on behalf of which tokens will be burnt1781 * @param amount amount of tokens to be burnt1769 * @param amount amount of tokens to be burnt1782 * @example burnTokensFrom(aliceKeyring, 10, {Substrate: "5GHoZe9c73RYbVzq..."}, 1000n);1770 * @example burnTokensFrom(aliceKeyring, 10, {Substrate: "5GHoZe9c73RYbVzq..."}, 1000n);1783 * @returns ```true``` if extrinsic success, otherwise ```false``` 1771 * @returns ```true``` if extrinsic success, otherwise ```false```1784 */1772 */1785 async burnTokensFrom(signer: IKeyringPair, collectionId: number, fromAddressObj: ICrossAccountId, amount=1n): Promise<boolean> {1773 async burnTokensFrom(signer: IKeyringPair, collectionId: number, fromAddressObj: ICrossAccountId, amount=1n): Promise<boolean> {1786 return await super.burnTokenFrom(signer, collectionId, fromAddressObj, 0, amount);1774 return await super.burnTokenFrom(signer, collectionId, fromAddressObj, 0, amount);1787 }1775 }178817761789 /**1777 /**1790 * Get total collection supply1778 * Get total collection supply1791 * @param collectionId 1779 * @param collectionId1792 * @returns 1780 * @returns1793 */1781 */1794 async getTotalPieces(collectionId: number): Promise<bigint> {1782 async getTotalPieces(collectionId: number): Promise<bigint> {1795 return (await this.helper.callRpc('api.rpc.unique.totalPieces', [collectionId, 0])).unwrap().toBigInt();1783 return (await this.helper.callRpc('api.rpc.unique.totalPieces', [collectionId, 0])).unwrap().toBigInt();1796 }1784 }179717851798 /**1786 /**1799 * Set, change, or remove approved address to transfer tokens.1787 * Set, change, or remove approved address to transfer tokens.1800 * 1788 *1801 * @param signer keyring of signer1789 * @param signer keyring of signer1802 * @param collectionId ID of collection1790 * @param collectionId ID of collection1803 * @param toAddressObj address to be approved1791 * @param toAddressObj address to be approved1804 * @param amount amount of tokens to be approved1792 * @param amount amount of tokens to be approved1805 * @example approveTokens(aliceKeyring, 10, {Substrate: "5GHoZe9c73RYbVzq..."}, 1000n)1793 * @example approveTokens(aliceKeyring, 10, {Substrate: "5GHoZe9c73RYbVzq..."}, 1000n)1806 * @returns ```true``` if extrinsic success, otherwise ```false``` 1794 * @returns ```true``` if extrinsic success, otherwise ```false```1807 */1795 */1808 async approveTokens(signer: IKeyringPair, collectionId: number, toAddressObj: ICrossAccountId, amount=1n) {1796 async approveTokens(signer: IKeyringPair, collectionId: number, toAddressObj: ICrossAccountId, amount=1n) {1809 return super.approveToken(signer, collectionId, 0, toAddressObj, amount);1797 return super.approveToken(signer, collectionId, 0, toAddressObj, amount);1810 }1798 }1898 return (await this.helper.callRpc('api.query.system.account', [address])).data.free.toBigInt();1886 return (await this.helper.callRpc('api.query.system.account', [address])).data.free.toBigInt();1899 }1887 }190018881901 /**1889 /**1902 * Get full substrate balance including free, miscFrozen, feeFrozen, and reserved1890 * Get full substrate balance including free, miscFrozen, feeFrozen, and reserved1903 * @param address substrate address1891 * @param address substrate address1904 * @returns 1892 * @returns1905 */1893 */1906 async getSubstrateFull(address: TSubstrateAccount): Promise<ISubstrateBalance> {1894 async getSubstrateFull(address: TSubstrateAccount): Promise<ISubstrateBalance> {1907 const accountInfo = (await this.helper.callRpc('api.query.system.account', [address])).data;1895 const accountInfo = (await this.helper.callRpc('api.query.system.account', [address])).data;1908 return {free: accountInfo.free.toBigInt(), miscFrozen: accountInfo.miscFrozen.toBigInt(), feeFrozen: accountInfo.feeFrozen.toBigInt(), reserved: accountInfo.reserved.toBigInt()};1896 return {free: accountInfo.free.toBigInt(), miscFrozen: accountInfo.miscFrozen.toBigInt(), feeFrozen: accountInfo.feeFrozen.toBigInt(), reserved: accountInfo.reserved.toBigInt()};