git.delta.rocks / unique-network / refs/commits / 27a31c97aaab

difftreelog

Merge pull request #620 from UniqueNetwork/test/burnItemPlaygrounds

ut-akuznetsov2022-10-04parents: #e9e910f #55c7c97.patch.diff
in: master
Move burnItemTests to playgrounds

5 files changed

modifiedtests/src/app-promotion.test.tsdiffbeforeafterboth
--- a/tests/src/app-promotion.test.ts
+++ b/tests/src/app-promotion.test.ts
@@ -34,7 +34,10 @@
 let accounts: IKeyringPair[] = [];
 const LOCKING_PERIOD = 20n; // 20 blocks of relay
 const UNLOCKING_PERIOD = 10n; // 10 blocks of parachain
-const rewardAvailableInBlock = (stakedInBlock: bigint) => (stakedInBlock - stakedInBlock % LOCKING_PERIOD) + (LOCKING_PERIOD * 2n);
+const rewardAvailableInBlock = (stakedInBlock: bigint) => {
+  if (stakedInBlock % LOCKING_PERIOD === 0n) return stakedInBlock + 20n;
+  return (stakedInBlock - stakedInBlock % LOCKING_PERIOD) + (LOCKING_PERIOD * 2n);
+};
 
 describe('App promotion', () => {
   before(async function () {
modifiedtests/src/burnItem.test.tsdiffbeforeafterboth
before · tests/src/burnItem.test.ts
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync} from './substrate/substrate-api';18import {IKeyringPair} from '@polkadot/types/types';19import {20  createCollectionExpectSuccess,21  createItemExpectSuccess,22  getGenericResult,23  normalizeAccountId,24  addCollectionAdminExpectSuccess,25  getBalance,26  setCollectionLimitsExpectSuccess,27  isTokenExists,28  requirePallets,29  Pallets,30} from './util/helpers';3132import chai from 'chai';33import chaiAsPromised from 'chai-as-promised';34chai.use(chaiAsPromised);35const expect = chai.expect;3637let alice: IKeyringPair;38let bob: IKeyringPair;3940describe('integration test: ext. burnItem():', () => {41  before(async () => {42    await usingApi(async (api, privateKeyWrapper) => {43      alice = privateKeyWrapper('//Alice');44      bob = privateKeyWrapper('//Bob');45    });46  });4748  it('Burn item in NFT collection', async () => {49    const createMode = 'NFT';50    const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});51    const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);5253    await usingApi(async (api) => {54      const tx = api.tx.unique.burnItem(collectionId, tokenId, 1);55      const events = await submitTransactionAsync(alice, tx);56      const result = getGenericResult(events);5758      expect(result.success).to.be.true;59      // Get the item60      expect(await isTokenExists(api, collectionId, tokenId)).to.be.false;61    });62  });6364  it('Burn item in Fungible collection', async () => {65    const createMode = 'Fungible';66    const collectionId = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0}});67    await createItemExpectSuccess(alice, collectionId, createMode); // Helper creates 10 fungible tokens68    const tokenId = 0; // ignored6970    await usingApi(async (api) => {71      // Destroy 1 of 1072      const tx = api.tx.unique.burnItem(collectionId, tokenId, 1);73      const events = await submitTransactionAsync(alice, tx);74      const result = getGenericResult(events);7576      // Get alice balance77      const balance = await getBalance(api, collectionId, alice.address, 0);7879      // What to expect80      expect(result.success).to.be.true;81      expect(balance).to.be.equal(9n);82    });83  });8485  it('Burn item in ReFungible collection', async function() {86    await requirePallets(this, [Pallets.ReFungible]);8788    const createMode = 'ReFungible';89    const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});90    const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);9192    await usingApi(async (api) => {93      const tx = api.tx.unique.burnItem(collectionId, tokenId, 100);94      const events = await submitTransactionAsync(alice, tx);95      const result = getGenericResult(events);9697      // Get alice balance98      const balance = await getBalance(api, collectionId, alice.address, tokenId);99100      // What to expect101      expect(result.success).to.be.true;102      expect(balance).to.be.equal(0n);103    });104  });105106  it('Burn owned portion of item in ReFungible collection', async function() {107    await requirePallets(this, [Pallets.ReFungible]);108109    const createMode = 'ReFungible';110    const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});111    const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);112113    await usingApi(async (api) => {114      // Transfer 1/100 of the token to Bob115      const transfertx = api.tx.unique.transfer(normalizeAccountId(bob.address), collectionId, tokenId, 1);116      const events1 = await submitTransactionAsync(alice, transfertx);117      const result1 = getGenericResult(events1);118119      // Get balances120      const bobBalanceBefore = await getBalance(api, collectionId, bob.address, tokenId);121      const aliceBalanceBefore = await getBalance(api, collectionId, alice.address, tokenId);122123      // Bob burns his portion124      const tx = api.tx.unique.burnItem(collectionId, tokenId, 1);125      const events2 = await submitTransactionAsync(bob, tx);126      const result2 = getGenericResult(events2);127128      // Get balances129      const bobBalanceAfter = await getBalance(api, collectionId, bob.address, tokenId);130      const aliceBalanceAfter = await getBalance(api, collectionId, alice.address, tokenId);131      // console.log(balance);132133      // What to expect before burning134      expect(result1.success).to.be.true;135      expect(aliceBalanceBefore).to.be.equal(99n);136      expect(bobBalanceBefore).to.be.equal(1n);137138      // What to expect after burning139      expect(result2.success).to.be.true;140      expect(aliceBalanceAfter).to.be.equal(99n);141      expect(bobBalanceAfter).to.be.equal(0n);142    });143144  });145146});147148describe('integration test: ext. burnItem() with admin permissions:', () => {149  before(async () => {150    await usingApi(async (api, privateKeyWrapper) => {151      alice = privateKeyWrapper('//Alice');152      bob = privateKeyWrapper('//Bob');153    });154  });155156  it('Burn item in NFT collection', async () => {157    const createMode = 'NFT';158    const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});159    await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});160    const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);161    await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);162163    await usingApi(async (api) => {164      const tx = api.tx.unique.burnFrom(collectionId, {Substrate: alice.address}, tokenId, 1);165      const events = await submitTransactionAsync(bob, tx);166      const result = getGenericResult(events);167168      expect(result.success).to.be.true;169      // Get the item170      expect(await isTokenExists(api, collectionId, tokenId)).to.be.false;171    });172  });173174  // TODO: burnFrom175  it('Burn item in Fungible collection', async () => {176    const createMode = 'Fungible';177    const collectionId = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0}});178    await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});179    const tokenId = await createItemExpectSuccess(alice, collectionId, createMode); // Helper creates 10 fungible tokens180    await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);181182    await usingApi(async (api) => {183      // Destroy 1 of 10184      const tx = api.tx.unique.burnFrom(collectionId, normalizeAccountId(alice.address), tokenId, 1);185      const events = await submitTransactionAsync(bob, tx);186      const result = getGenericResult(events);187188      // Get alice balance189      const balance = await getBalance(api, collectionId, alice.address, 0);190191      // What to expect192      expect(result.success).to.be.true;193      expect(balance).to.be.equal(9n);194    });195  });196197  // TODO: burnFrom198  it('Burn item in ReFungible collection', async function() {199    await requirePallets(this, [Pallets.ReFungible]);200201    const createMode = 'ReFungible';202    const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});203    await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});204    const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);205    await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);206207    await usingApi(async (api) => {208      const tx = api.tx.unique.burnFrom(collectionId, normalizeAccountId(alice.address), tokenId, 100);209      const events = await submitTransactionAsync(bob, tx);210      const result = getGenericResult(events);211      // Get alice balance212      expect(result.success).to.be.true;213      // Get the item214      expect(await isTokenExists(api, collectionId, tokenId)).to.be.false;215    });216  });217});218219describe('Negative integration test: ext. burnItem():', () => {220  before(async () => {221    await usingApi(async (api, privateKeyWrapper) => {222      alice = privateKeyWrapper('//Alice');223      bob = privateKeyWrapper('//Bob');224    });225  });226227  it('Burn a token that was never created', async () => {228    const createMode = 'NFT';229    const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});230    const tokenId = 10;231232    await usingApi(async (api) => {233      const tx = api.tx.unique.burnItem(collectionId, tokenId, 1);234      const badTransaction = async function () {235        await submitTransactionExpectFailAsync(alice, tx);236      };237      await expect(badTransaction()).to.be.rejected;238    });239240  });241242  it('Burn a token using the address that does not own it', async () => {243    const createMode = 'NFT';244    const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});245    const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);246247    await usingApi(async (api) => {248      const tx = api.tx.unique.burnItem(collectionId, tokenId, 1);249      const badTransaction = async function () {250        await submitTransactionExpectFailAsync(bob, tx);251      };252      await expect(badTransaction()).to.be.rejected;253    });254255  });256257  it('Transfer a burned a token', async () => {258    const createMode = 'NFT';259    const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});260    const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);261262    await usingApi(async (api) => {263264      const burntx = api.tx.unique.burnItem(collectionId, tokenId, 1);265      const events1 = await submitTransactionAsync(alice, burntx);266      const result1 = getGenericResult(events1);267      expect(result1.success).to.be.true;268269      const tx = api.tx.unique.transfer(normalizeAccountId(bob.address), collectionId, tokenId, 1);270      const badTransaction = async function () {271        await submitTransactionExpectFailAsync(alice, tx);272      };273      await expect(badTransaction()).to.be.rejected;274    });275276  });277278  it('Burn more than owned in Fungible collection', async () => {279    const createMode = 'Fungible';280    const collectionId = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0}});281    // Helper creates 10 fungible tokens282    await createItemExpectSuccess(alice, collectionId, createMode);283    const tokenId = 0; // ignored284285    await usingApi(async (api) => {286      // Destroy 11 of 10287      const tx = api.tx.unique.burnItem(collectionId, tokenId, 11);288      const badTransaction = async function () {289        await submitTransactionExpectFailAsync(alice, tx);290      };291      await expect(badTransaction()).to.be.rejected;292293      // Get alice balance294      const balance = await getBalance(api, collectionId, alice.address, 0);295296      // What to expect297      expect(balance).to.be.equal(10n);298    });299300  });301302});
after · tests/src/burnItem.test.ts
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {IKeyringPair} from '@polkadot/types/types';18import {expect, itSub, Pallets, usingPlaygrounds} from './util/playgrounds';192021describe('integration test: ext. burnItem():', () => {22  let donor: IKeyringPair;23  let alice: IKeyringPair;24  let bob: IKeyringPair;2526  before(async () => {27    await usingPlaygrounds(async (helper, privateKey) => {28      donor = privateKey('//Alice');29      [alice, bob] = await helper.arrange.createAccounts([100n, 100n], donor);30    });31  });3233  itSub('Burn item in NFT collection', async ({helper}) => {34    const collection = await helper.nft.mintCollection(alice);35    const token = await collection.mintToken(alice);3637    await token.burn(alice);38    expect(await token.doesExist()).to.be.false;39  });4041  itSub('Burn item in Fungible collection', async ({helper}) => {42    const collection = await helper.ft.mintCollection(alice, {}, 10);43    await collection.mint(alice, 10n);4445    await collection.burnTokens(alice, 1n);46    expect(await collection.getBalance({Substrate: alice.address})).to.eq(9n);47  });4849  itSub.ifWithPallets('Burn item in ReFungible collection', [Pallets.ReFungible], async function({helper}) {50    const collection = await helper.rft.mintCollection(alice);51    const token = await collection.mintToken(alice, 100n);5253    await token.burn(alice, 90n);54    expect(await token.getBalance({Substrate: alice.address})).to.eq(10n);5556    await token.burn(alice, 10n);57    expect(await token.getBalance({Substrate: alice.address})).to.eq(0n);58  });5960  itSub.ifWithPallets('Burn owned portion of item in ReFungible collection', [Pallets.ReFungible], async function({helper}) {61    const collection = await helper.rft.mintCollection(alice);62    const token = await collection.mintToken(alice, 100n);6364    await token.transfer(alice, {Substrate: bob.address}, 1n);6566    expect(await token.getBalance({Substrate: alice.address})).to.eq(99n);67    expect(await token.getBalance({Substrate: bob.address})).to.eq(1n);6869    await token.burn(bob, 1n);7071    expect(await token.getBalance({Substrate: alice.address})).to.eq(99n);72    expect(await token.getBalance({Substrate: bob.address})).to.eq(0n);73  });74});7576describe('integration test: ext. burnItem() with admin permissions:', () => {77  let donor: IKeyringPair;78  let alice: IKeyringPair;79  let bob: IKeyringPair;8081  before(async () => {82    await usingPlaygrounds(async (helper, privateKey) => {83      donor = privateKey('//Alice');84      [alice, bob] = await helper.arrange.createAccounts([100n, 100n], donor);85    });86  });8788  itSub('Burn item in NFT collection', async ({helper}) => {89    const collection = await helper.nft.mintCollection(alice);90    await collection.setLimits(alice, {ownerCanTransfer: true});91    await collection.addAdmin(alice, {Substrate: bob.address});92    const token = await collection.mintToken(alice);9394    await token.burnFrom(bob, {Substrate: alice.address});95    expect(await token.doesExist()).to.be.false;96  });9798  itSub('Burn item in Fungible collection', async ({helper}) => {99    const collection = await helper.ft.mintCollection(alice, {}, 0);100    await collection.setLimits(alice, {ownerCanTransfer: true});101    await collection.addAdmin(alice, {Substrate: bob.address});102    await collection.mint(alice, 10n);103104    await collection.burnTokensFrom(bob, {Substrate: alice.address}, 1n);105    expect(await collection.getBalance({Substrate: alice.address})).to.eq(9n);106  });107108  itSub.ifWithPallets('Burn item in ReFungible collection', [Pallets.ReFungible], async function({helper}) {109    const collection = await helper.rft.mintCollection(alice);110    await collection.setLimits(alice, {ownerCanTransfer: true});111    await collection.addAdmin(alice, {Substrate: bob.address});112    const token = await collection.mintToken(alice, 100n);113114    await token.burnFrom(bob, {Substrate: alice.address}, 100n);115    expect(await token.doesExist()).to.be.false;116  });117});118119describe('Negative integration test: ext. burnItem():', () => {120  let donor: IKeyringPair;121  let alice: IKeyringPair;122  let bob: IKeyringPair;123124  before(async () => {125    await usingPlaygrounds(async (helper, privateKey) => {126      donor = privateKey('//Alice');127      [alice, bob] = await helper.arrange.createAccounts([100n, 100n], donor);128    });129  });130131  itSub('Burn a token that was never created', async ({helper}) => {132    const collection = await helper.nft.mintCollection(alice);133    await expect(collection.burnToken(alice, 10)).to.be.rejectedWith('common.TokenNotFound');134  });135136  itSub('Burn a token using the address that does not own it', async ({helper}) => {137    const collection = await helper.nft.mintCollection(alice);138    const token = await collection.mintToken(alice);139140    await expect(token.burn(bob)).to.be.rejectedWith('common.NoPermission');141  });142143  itSub('Transfer a burned token', async ({helper}) => {144    const collection = await helper.nft.mintCollection(alice);145    const token = await collection.mintToken(alice);146    await token.burn(alice);147148    await expect(token.transfer(alice, {Substrate: bob.address})).to.be.rejectedWith('common.TokenNotFound');149  });150151  itSub('Burn more than owned in Fungible collection', async ({helper}) => {152    const collection = await helper.ft.mintCollection(alice, {}, 0);153    await collection.mint(alice, 10n);154155    await expect(collection.burnTokens(alice, 11n)).to.be.rejectedWith('common.TokenValueTooLow');156    expect(await collection.getBalance({Substrate: alice.address})).to.eq(10n);157  });158});
modifiedtests/src/fungible.test.tsdiffbeforeafterboth
--- a/tests/src/fungible.test.ts
+++ b/tests/src/fungible.test.ts
@@ -101,10 +101,10 @@
     const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
     await collection.mint(alice, 500n);
 
-    expect(await collection.isTokenExists(0)).to.be.true;
+    expect(await collection.doesTokenExist(0)).to.be.true;
     expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(500n);
     expect(await collection.burnTokens(alice, 499n)).to.be.true;
-    expect(await collection.isTokenExists(0)).to.be.true;
+    expect(await collection.doesTokenExist(0)).to.be.true;
     expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);
   });
   
@@ -112,9 +112,9 @@
     const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
     await collection.mint(alice, 500n);
 
-    expect(await collection.isTokenExists(0)).to.be.true;
+    expect(await collection.doesTokenExist(0)).to.be.true;
     expect(await collection.burnTokens(alice, 500n)).to.be.true;
-    expect(await collection.isTokenExists(0)).to.be.true;
+    expect(await collection.doesTokenExist(0)).to.be.true;
 
     expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(0n);
     expect(await collection.getTotalPieces()).to.be.equal(0n);
modifiedtests/src/refungible.test.tsdiffbeforeafterboth
--- a/tests/src/refungible.test.ts
+++ b/tests/src/refungible.test.ts
@@ -122,10 +122,10 @@
   itSub('Burn some pieces', async ({helper}) => {
     const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
     const token = await collection.mintToken(alice, 100n);
-    expect(await collection.isTokenExists(token.tokenId)).to.be.true;
+    expect(await collection.doesTokenExist(token.tokenId)).to.be.true;
     expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
     expect(await token.burn(alice, 99n)).to.be.true;
-    expect(await collection.isTokenExists(token.tokenId)).to.be.true;
+    expect(await collection.doesTokenExist(token.tokenId)).to.be.true;
     expect(await token.getBalance({Substrate: alice.address})).to.be.equal(1n);
   });
 
@@ -133,18 +133,18 @@
     const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
     const token = await collection.mintToken(alice, 100n);
     
-    expect(await collection.isTokenExists(token.tokenId)).to.be.true;
+    expect(await collection.doesTokenExist(token.tokenId)).to.be.true;
     expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
 
     expect(await token.burn(alice, 100n)).to.be.true;
-    expect(await collection.isTokenExists(token.tokenId)).to.be.false;
+    expect(await collection.doesTokenExist(token.tokenId)).to.be.false;
   });
 
   itSub('Burn some pieces for multiple users', async ({helper}) => {
     const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
     const token = await collection.mintToken(alice, 100n);
 
-    expect(await collection.isTokenExists(token.tokenId)).to.be.true;
+    expect(await collection.doesTokenExist(token.tokenId)).to.be.true;
     
     expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
     expect(await token.transfer(alice, {Substrate: bob.address}, 60n)).to.be.true;
@@ -154,17 +154,17 @@
 
     expect(await token.burn(alice, 40n)).to.be.true;
 
-    expect(await collection.isTokenExists(token.tokenId)).to.be.true;
+    expect(await collection.doesTokenExist(token.tokenId)).to.be.true;
     expect(await token.getBalance({Substrate: alice.address})).to.be.equal(0n);
 
     expect(await token.burn(bob, 59n)).to.be.true;
 
     expect(await token.getBalance({Substrate: bob.address})).to.be.equal(1n);
-    expect(await collection.isTokenExists(token.tokenId)).to.be.true;
+    expect(await collection.doesTokenExist(token.tokenId)).to.be.true;
 
     expect(await token.burn(bob, 1n)).to.be.true;
 
-    expect(await collection.isTokenExists(token.tokenId)).to.be.false;
+    expect(await collection.doesTokenExist(token.tokenId)).to.be.false;
   });
 
   itSub('Set allowance for token', async ({helper}) => {
modifiedtests/src/util/playgrounds/unique.tsdiffbeforeafterboth
--- a/tests/src/util/playgrounds/unique.ts
+++ b/tests/src/util/playgrounds/unique.ts
@@ -1114,10 +1114,10 @@
    *
    * @param collectionId ID of collection
    * @param tokenId ID of token
-   * @example isTokenExists(10, 20);
+   * @example doesTokenExist(10, 20);
    * @returns true if the token exists, otherwise false
    */
-  async isTokenExists(collectionId: number, tokenId: number): Promise<boolean> {
+  async doesTokenExist(collectionId: number, tokenId: number): Promise<boolean> {
     return (await this.helper.callRpc('api.rpc.unique.tokenExists', [collectionId, tokenId])).toJSON();
   }
 }
@@ -2277,8 +2277,8 @@
     return await this.helper.collection.getLastTokenId(this.collectionId);
   }
 
-  async isTokenExists(tokenId: number) {
-    return await this.helper.collection.isTokenExists(this.collectionId, tokenId);
+  async doesTokenExist(tokenId: number) {
+    return await this.helper.collection.doesTokenExist(this.collectionId, tokenId);
   }
 
   async getAdmins() {
@@ -2607,6 +2607,10 @@
     return await this.collection.deleteTokenProperties(signer, this.tokenId, propertyKeys);
   }
 
+  async doesExist() {
+    return await this.collection.doesTokenExist(this.tokenId);
+  }
+
   nestingAccount() {
     return this.collection.helper.util.getTokenAccount(this);
   }