difftreelog
tests(nesting): revert majority of last commit + refactor token and collection naming convention
in: master
6 files changed
tests/src/fungible.test.tsdiffbeforeafterboth15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.161617import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';18import {itSub, usingPlaygrounds, expect, U128_MAX} from './util/playgrounds';18import {itSub, usingPlaygrounds, expect} from './util/playgrounds';1920const U128_MAX = (1n << 128n) - 1n;192120describe('integration test: Fungible functionality:', () => {22describe('integration test: Fungible functionality:', () => {21 let alice: IKeyringPair;23 let alice: IKeyringPair;tests/src/nesting/graphs.test.tsdiffbeforeafterboth161617import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';18import {expect, itSub, usingPlaygrounds} from '../util/playgrounds';18import {expect, itSub, usingPlaygrounds} from '../util/playgrounds';19import {ITokenNonfungible} from '../util/playgrounds/types';20import {UniqueHelper} from '../util/playgrounds/unique';19import {UniqueHelper, UniqueNFToken} from '../util/playgrounds/unique';212022/**21/**23 * ```dot22 * ```dot26 * 8 -> 525 * 8 -> 527 * ```26 * ```28 */27 */29async function buildComplexObjectGraph(helper: UniqueHelper, sender: IKeyringPair): Promise<ITokenNonfungible[]> {28async function buildComplexObjectGraph(helper: UniqueHelper, sender: IKeyringPair): Promise<UniqueNFToken[]> {30 const collection = await helper.nft.mintCollection(sender, {permissions: {nesting: {tokenOwner: true}}});29 const collection = await helper.nft.mintCollection(sender, {permissions: {nesting: {tokenOwner: true}}});31 const tokens = await collection.mintMultipleTokens(sender, Array(8).fill({owner: {Substrate: sender.address}}));30 const tokens = await collection.mintMultipleTokens(sender, Array(8).fill({owner: {Substrate: sender.address}}));3231tests/src/nesting/properties.test.tsdiffbeforeafterboth161617import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';18import {itSub, Pallets, requirePalletsOrSkip, usingPlaygrounds, expect} from '../util/playgrounds';18import {itSub, Pallets, requirePalletsOrSkip, usingPlaygrounds, expect} from '../util/playgrounds';19import {ICollectionBase, ICollectionNFT, ITokenNonfungible, ICollectionRFT, ITokenRefungible} from '../util/playgrounds/types';19import {UniqueHelper, UniqueBaseCollection, UniqueNFTCollection, UniqueNFToken, UniqueRFTCollection, UniqueRFToken} from '../util/playgrounds/unique';20import {UniqueHelper} from '../util/playgrounds/unique';212022// ---------- COLLECTION PROPERTIES21// ---------- COLLECTION PROPERTIES232237 expect(await collection.getProperties()).to.be.empty;36 expect(await collection.getProperties()).to.be.empty;38 });37 });393840 async function testSetsPropertiesForCollection(collection: ICollectionBase) {39 async function testSetsPropertiesForCollection(collection: UniqueBaseCollection) {41 // As owner40 // As owner42 await expect(collection.setProperties(alice, [{key: 'electron', value: 'come bond'}])).to.be.fulfilled;41 await expect(collection.setProperties(alice, [{key: 'electron', value: 'come bond'}])).to.be.fulfilled;434261 await testSetsPropertiesForCollection(await helper.rft.mintCollection(alice));60 await testSetsPropertiesForCollection(await helper.rft.mintCollection(alice));62 });61 });636264 async function testCheckValidNames(collection: ICollectionBase) {63 async function testCheckValidNames(collection: UniqueBaseCollection) {65 // alpha symbols64 // alpha symbols66 await expect(collection.setProperties(alice, [{key: 'answer'}])).to.be.fulfilled;65 await expect(collection.setProperties(alice, [{key: 'answer'}])).to.be.fulfilled;676695 await testCheckValidNames(await helper.rft.mintCollection(alice));94 await testCheckValidNames(await helper.rft.mintCollection(alice));96 });95 });979698 async function testChangesProperties(collection: ICollectionBase) {97 async function testChangesProperties(collection: UniqueBaseCollection) {99 await expect(collection.setProperties(alice, [{key: 'electron', value: 'come bond'}, {key: 'black_hole', value: ''}])).to.be.fulfilled;98 await expect(collection.setProperties(alice, [{key: 'electron', value: 'come bond'}, {key: 'black_hole', value: ''}])).to.be.fulfilled;10099101 // Mutate the properties100 // Mutate the properties116 await testChangesProperties(await helper.rft.mintCollection(alice));115 await testChangesProperties(await helper.rft.mintCollection(alice));117 });116 });118117119 async function testDeleteProperties(collection: ICollectionBase) {118 async function testDeleteProperties(collection: UniqueBaseCollection) {120 await expect(collection.setProperties(alice, [{key: 'electron', value: 'come bond'}, {key: 'black_hole', value: 'LIGO'}])).to.be.fulfilled;119 await expect(collection.setProperties(alice, [{key: 'electron', value: 'come bond'}, {key: 'black_hole', value: 'LIGO'}])).to.be.fulfilled;121120122 await expect(collection.deleteProperties(alice, ['electron'])).to.be.fulfilled;121 await expect(collection.deleteProperties(alice, ['electron'])).to.be.fulfilled;147 });146 });148 });147 });149 148 150 async function testFailsSetPropertiesIfNotOwnerOrAdmin(collection: ICollectionBase) { 149 async function testFailsSetPropertiesIfNotOwnerOrAdmin(collection: UniqueBaseCollection) { 151 await expect(collection.setProperties(bob, [{key: 'electron', value: 'come bond'}, {key: 'black_hole', value: 'LIGO'}]))150 await expect(collection.setProperties(bob, [{key: 'electron', value: 'come bond'}, {key: 'black_hole', value: 'LIGO'}]))152 .to.be.rejectedWith(/common\.NoPermission/);151 .to.be.rejectedWith(/common\.NoPermission/);153152162 await testFailsSetPropertiesIfNotOwnerOrAdmin(await helper.rft.mintCollection(alice));161 await testFailsSetPropertiesIfNotOwnerOrAdmin(await helper.rft.mintCollection(alice));163 });162 });164 163 165 async function testFailsSetPropertiesThatExeedLimits(collection: ICollectionBase) {164 async function testFailsSetPropertiesThatExeedLimits(collection: UniqueBaseCollection) {166 const spaceLimit = (await (collection.helper!.api! as any).query.common.collectionProperties(collection.collectionId)).spaceLimit.toNumber();165 const spaceLimit = (await (collection.helper!.api! as any).query.common.collectionProperties(collection.collectionId)).spaceLimit.toNumber();167 166 168 // Mute the general tx parsing error, too many bytes to process167 // Mute the general tx parsing error, too many bytes to process191 await testFailsSetPropertiesThatExeedLimits(await helper.rft.mintCollection(alice));190 await testFailsSetPropertiesThatExeedLimits(await helper.rft.mintCollection(alice));192 });191 });193 192 194 async function testFailsSetMorePropertiesThanAllowed(collection: ICollectionBase) {193 async function testFailsSetMorePropertiesThanAllowed(collection: UniqueBaseCollection) {195 const propertiesToBeSet = [];194 const propertiesToBeSet = [];196 for (let i = 0; i < 65; i++) {195 for (let i = 0; i < 65; i++) {197 propertiesToBeSet.push({196 propertiesToBeSet.push({214 await testFailsSetMorePropertiesThanAllowed(await helper.rft.mintCollection(alice));213 await testFailsSetMorePropertiesThanAllowed(await helper.rft.mintCollection(alice));215 });214 });216 215 217 async function testFailsSetPropertiesWithInvalidNames(collection: ICollectionBase) {216 async function testFailsSetPropertiesWithInvalidNames(collection: UniqueBaseCollection) {218 const invalidProperties = [217 const invalidProperties = [219 [{key: 'electron', value: 'negative'}, {key: 'string theory', value: 'understandable'}],218 [{key: 'electron', value: 'negative'}, {key: 'string theory', value: 'understandable'}],220 [{key: 'Mr/Sandman', value: 'Bring me a gene'}],219 [{key: 'Mr/Sandman', value: 'Bring me a gene'}],281 expect(propertyRights).to.be.empty;280 expect(propertyRights).to.be.empty;282 });281 });283 282 284 async function testSetsAccessRightsToProperties(collection: ICollectionNFT | ICollectionRFT) { 283 async function testSetsAccessRightsToProperties(collection: UniqueNFTCollection | UniqueRFTCollection) { 285 await expect(collection.setTokenPropertyPermissions(alice, [{key: 'skullduggery', permission: {mutable: true}}]))284 await expect(collection.setTokenPropertyPermissions(alice, [{key: 'skullduggery', permission: {mutable: true}}]))286 .to.be.fulfilled;285 .to.be.fulfilled;287286305 await testSetsAccessRightsToProperties(await helper.rft.mintCollection(alice));304 await testSetsAccessRightsToProperties(await helper.rft.mintCollection(alice));306 });305 });307 306 308 async function testChangesAccessRightsToProperty(collection: ICollectionNFT | ICollectionRFT) {307 async function testChangesAccessRightsToProperty(collection: UniqueNFTCollection | UniqueRFTCollection) {309 await expect(collection.setTokenPropertyPermissions(alice, [{key: 'skullduggery', permission: {mutable: true, collectionAdmin: true}}]))308 await expect(collection.setTokenPropertyPermissions(alice, [{key: 'skullduggery', permission: {mutable: true, collectionAdmin: true}}]))310 .to.be.fulfilled;309 .to.be.fulfilled;311310338 });337 });339 });338 });340339341 async function testPreventsFromSettingAccessRightsNotAdminOrOwner(collection: ICollectionNFT | ICollectionRFT) {340 async function testPreventsFromSettingAccessRightsNotAdminOrOwner(collection: UniqueNFTCollection | UniqueRFTCollection) {342 await expect(collection.setTokenPropertyPermissions(bob, [{key: 'skullduggery', permission: {mutable: true, tokenOwner: true}}]))341 await expect(collection.setTokenPropertyPermissions(bob, [{key: 'skullduggery', permission: {mutable: true, tokenOwner: true}}]))343 .to.be.rejectedWith(/common\.NoPermission/);342 .to.be.rejectedWith(/common\.NoPermission/);344343354 await testPreventsFromSettingAccessRightsNotAdminOrOwner(await helper.rft.mintCollection(alice));353 await testPreventsFromSettingAccessRightsNotAdminOrOwner(await helper.rft.mintCollection(alice));355 });354 });356355357 async function testPreventFromAddingTooManyPossibleProperties(collection: ICollectionNFT | ICollectionRFT) { 356 async function testPreventFromAddingTooManyPossibleProperties(collection: UniqueNFTCollection | UniqueRFTCollection) { 358 const constitution = [];357 const constitution = [];359 for (let i = 0; i < 65; i++) {358 for (let i = 0; i < 65; i++) {360 constitution.push({359 constitution.push({378 await testPreventFromAddingTooManyPossibleProperties(await helper.rft.mintCollection(alice));377 await testPreventFromAddingTooManyPossibleProperties(await helper.rft.mintCollection(alice));379 });378 });380379381 async function testPreventAccessRightsModifiedIfConstant(collection: ICollectionNFT | ICollectionRFT) {380 async function testPreventAccessRightsModifiedIfConstant(collection: UniqueNFTCollection | UniqueRFTCollection) {382 await expect(collection.setTokenPropertyPermissions(alice, [{key: 'skullduggery', permission: {mutable: false, tokenOwner: true}}]))381 await expect(collection.setTokenPropertyPermissions(alice, [{key: 'skullduggery', permission: {mutable: false, tokenOwner: true}}]))383 .to.be.fulfilled;382 .to.be.fulfilled;384383399 await testPreventAccessRightsModifiedIfConstant(await helper.rft.mintCollection(alice));398 await testPreventAccessRightsModifiedIfConstant(await helper.rft.mintCollection(alice));400 });399 });401400402 async function testPreventsAddingPropertiesWithInvalidNames(collection: ICollectionNFT | ICollectionRFT) {401 async function testPreventsAddingPropertiesWithInvalidNames(collection: UniqueNFTCollection | UniqueRFTCollection) {403 const invalidProperties = [402 const invalidProperties = [404 [{key: 'skullduggery', permission: {tokenOwner: true}}, {key: 'im possible', permission: {collectionAdmin: true}}],403 [{key: 'skullduggery', permission: {tokenOwner: true}}, {key: 'im possible', permission: {collectionAdmin: true}}],405 [{key: 'G#4', permission: {tokenOwner: true}}],404 [{key: 'G#4', permission: {tokenOwner: true}}],469 ];468 ];470 });469 });471 470 472 async function testReadsYetEmptyProperties(token: ITokenNonfungible | ITokenRefungible) {471 async function testReadsYetEmptyProperties(token: UniqueNFToken | UniqueRFToken) {473 const properties = await token.getProperties();472 const properties = await token.getProperties();474 expect(properties).to.be.empty;473 expect(properties).to.be.empty;475474489 await testReadsYetEmptyProperties(token);488 await testReadsYetEmptyProperties(token);490 });489 });491490492 async function testAssignPropertiesAccordingToPermissions(token: ITokenNonfungible | ITokenRefungible, pieces: bigint) {491 async function testAssignPropertiesAccordingToPermissions(token: UniqueNFToken | UniqueRFToken, pieces: bigint) {493 await token.collection.addAdmin(alice, {Substrate: bob.address});492 await token.collection.addAdmin(alice, {Substrate: bob.address});494 await token.transfer(alice, {Substrate: charlie.address}, pieces);493 await token.transfer(alice, {Substrate: charlie.address}, pieces);495494535 await testAssignPropertiesAccordingToPermissions(token, 100n);534 await testAssignPropertiesAccordingToPermissions(token, 100n);536 });535 });537536538 async function testChangesPropertiesAccordingPermission(token: ITokenNonfungible | ITokenRefungible, pieces: bigint) {537 async function testChangesPropertiesAccordingPermission(token: UniqueNFToken | UniqueRFToken, pieces: bigint) {539 await token.collection.addAdmin(alice, {Substrate: bob.address});538 await token.collection.addAdmin(alice, {Substrate: bob.address});540 await token.transfer(alice, {Substrate: charlie.address}, pieces);539 await token.transfer(alice, {Substrate: charlie.address}, pieces);541540588 await testChangesPropertiesAccordingPermission(token, 100n);587 await testChangesPropertiesAccordingPermission(token, 100n);589 });588 });590589591 async function testDeletePropertiesAccordingPermission(token: ITokenNonfungible | ITokenRefungible, pieces: bigint) {590 async function testDeletePropertiesAccordingPermission(token: UniqueNFToken | UniqueRFToken, pieces: bigint) {592 await token.collection.addAdmin(alice, {Substrate: bob.address});591 await token.collection.addAdmin(alice, {Substrate: bob.address});593 await token.transfer(alice, {Substrate: charlie.address}, pieces);592 await token.transfer(alice, {Substrate: charlie.address}, pieces);594593799 return (await (mode == 'NFT' ? api.query.nonfungible : api.query.refungible).tokenProperties(collectionId, tokenId)).toJSON().consumedSpace;798 return (await (mode == 'NFT' ? api.query.nonfungible : api.query.refungible).tokenProperties(collectionId, tokenId)).toJSON().consumedSpace;800 }799 }801800802 async function prepare(token: ITokenNonfungible | ITokenRefungible, pieces: bigint): Promise<number> {801 async function prepare(token: UniqueNFToken | UniqueRFToken, pieces: bigint): Promise<number> {803 await token.collection.addAdmin(alice, {Substrate: bob.address});802 await token.collection.addAdmin(alice, {Substrate: bob.address});804 await token.transfer(alice, {Substrate: charlie.address}, pieces);803 await token.transfer(alice, {Substrate: charlie.address}, pieces);805804823 return originalSpace;822 return originalSpace;824 }823 }825824826 async function testForbidsChangingDeletingPropertiesUserOutsideOfPermissions(token: ITokenNonfungible | ITokenRefungible, pieces: bigint) {825 async function testForbidsChangingDeletingPropertiesUserOutsideOfPermissions(token: UniqueNFToken | UniqueRFToken, pieces: bigint) {827 const originalSpace = await prepare(token, pieces);826 const originalSpace = await prepare(token, pieces);828827829 let i = 0;828 let i = 0;858 await testForbidsChangingDeletingPropertiesUserOutsideOfPermissions(token, 100n);857 await testForbidsChangingDeletingPropertiesUserOutsideOfPermissions(token, 100n);859 });858 });860859861 async function testForbidsChangingDeletingPropertiesIfPropertyImmutable(token: ITokenNonfungible | ITokenRefungible, pieces: bigint) {860 async function testForbidsChangingDeletingPropertiesIfPropertyImmutable(token: UniqueNFToken | UniqueRFToken, pieces: bigint) {862 const originalSpace = await prepare(token, pieces);861 const originalSpace = await prepare(token, pieces);863862864 let i = 0;863 let i = 0;893 await testForbidsChangingDeletingPropertiesIfPropertyImmutable(token, 100n);892 await testForbidsChangingDeletingPropertiesIfPropertyImmutable(token, 100n);894 });893 });895894896 async function testForbidsAddingPropertiesIfPropertyNotDeclared(token: ITokenNonfungible | ITokenRefungible, pieces: bigint) {895 async function testForbidsAddingPropertiesIfPropertyNotDeclared(token: UniqueNFToken | UniqueRFToken, pieces: bigint) {897 const originalSpace = await prepare(token, pieces);896 const originalSpace = await prepare(token, pieces);898897899 await expect(898 await expect(929 await testForbidsAddingPropertiesIfPropertyNotDeclared(token, 100n);928 await testForbidsAddingPropertiesIfPropertyNotDeclared(token, 100n);930 });929 });931930932 async function testForbidsAddingTooManyProperties(token: ITokenNonfungible | ITokenRefungible, pieces: bigint) {931 async function testForbidsAddingTooManyProperties(token: UniqueNFToken | UniqueRFToken, pieces: bigint) {933 const originalSpace = await prepare(token, pieces);932 const originalSpace = await prepare(token, pieces);934933935 await expect(934 await expect(984 });983 });985 });984 });986985987 async function prepare(helper: UniqueHelper): Promise<ITokenRefungible> {986 async function prepare(helper: UniqueHelper): Promise<UniqueRFToken> {988 const collection = await helper.rft.mintCollection(alice);987 const collection = await helper.rft.mintCollection(alice);989 const token = await collection.mintToken(alice, 100n);988 const token = await collection.mintToken(alice, 100n);990 989 tests/src/util/playgrounds/index.tsdiffbeforeafterboth12chai.use(chaiAsPromised);12chai.use(chaiAsPromised);13export const expect = chai.expect;13export const expect = chai.expect;1415export const U128_MAX = (1n << 128n) - 1n;1617const MICROUNIQUE = 1_000_000_000_000n;18const MILLIUNIQUE = 1_000n * MICROUNIQUE;19const CENTIUNIQUE = 10n * MILLIUNIQUE;20export const UNIQUE = 100n * CENTIUNIQUE;211422export const usingPlaygrounds = async (code: (helper: DevUniqueHelper, privateKey: (seed: string) => IKeyringPair) => Promise<void>, url: string = config.substrateUrl) => {15export const usingPlaygrounds = async (code: (helper: DevUniqueHelper, privateKey: (seed: string) => IKeyringPair) => Promise<void>, url: string = config.substrateUrl) => {23 const silentConsole = new SilentConsole();16 const silentConsole = new SilentConsole();tests/src/util/playgrounds/types.tsdiffbeforeafterboth2// SPDX-License-Identifier: Apache-2.02// SPDX-License-Identifier: Apache-2.0334import {IKeyringPair} from '@polkadot/types/types';4import {IKeyringPair} from '@polkadot/types/types';5import {UniqueHelper} from './unique';657export interface IEvent {6export interface IEvent {8 section: string;7 section: string;107 }106 }108}107}109108110export interface ITokenAddress {109export interface IToken {111 collectionId: number;110 collectionId: number;112 tokenId: number;111 tokenId: number;113}112}169export type TUniqueNetworks = 'opal' | 'quartz' | 'unique';168export type TUniqueNetworks = 'opal' | 'quartz' | 'unique';170export type TSigner = IKeyringPair; // | 'string'169export type TSigner = IKeyringPair; // | 'string'171172export interface ICollectionBase {173 helper: UniqueHelper;174 collectionId: number;175 getData: () => Promise<{176 id: number;177 name: string;178 description: string;179 tokensCount: number;180 admins: ICrossAccountId[];181 normalizedOwner: TSubstrateAccount;182 raw: any183 } | null>;184 getLastTokenId: () => Promise<number>;185 isTokenExists: (tokenId: number) => Promise<boolean>;186 getAdmins: () => Promise<ICrossAccountId[]>;187 getAllowList: () => Promise<ICrossAccountId[]>;188 getEffectiveLimits: () => Promise<ICollectionLimits>;189 getProperties: (propertyKeys?: string[]) => Promise<IProperty[]>;190 getTokenNextSponsored: (tokenId: number, addressObj: ICrossAccountId) => Promise<number | null>;191 setSponsor: (signer: TSigner, sponsorAddress: TSubstrateAccount) => Promise<boolean>;192 confirmSponsorship: (signer: TSigner) => Promise<boolean>;193 removeSponsor: (signer: TSigner) => Promise<boolean>;194 setLimits: (signer: TSigner, limits: ICollectionLimits) => Promise<boolean>;195 changeOwner: (signer: TSigner, ownerAddress: TSubstrateAccount) => Promise<boolean>;196 addAdmin: (signer: TSigner, adminAddressObj: ICrossAccountId) => Promise<boolean>;197 addToAllowList: (signer: TSigner, addressObj: ICrossAccountId) => Promise<boolean>;198 removeFromAllowList: (signer: TSigner, addressObj: ICrossAccountId) => Promise<boolean>;199 removeAdmin: (signer: TSigner, adminAddressObj: ICrossAccountId) => Promise<boolean>;200 setProperties: (signer: TSigner, properties: IProperty[]) => Promise<boolean>;201 deleteProperties: (signer: TSigner, propertyKeys: string[]) => Promise<boolean>;202 setPermissions: (signer: TSigner, permissions: ICollectionPermissions) => Promise<boolean>;203 enableNesting: (signer: TSigner, permissions: INestingPermissions) => Promise<boolean>;204 disableNesting: (signer: TSigner) => Promise<boolean>;205 burn: (signer: TSigner) => Promise<boolean>;206}207208export interface ICollectionNFT extends ICollectionBase {209 getTokenObject: (tokenId: number) => ITokenNonfungible; // todo:playgrounds210 getTokensByAddress: (addressObj: ICrossAccountId) => Promise<number[]>;211 getToken: (tokenId: number, blockHashAt?: string) => Promise<{212 properties: IProperty[];213 owner: ICrossAccountId;214 normalizedOwner: ICrossAccountId;215 }| null>;216 getTokenOwner: (tokenId: number, blockHashAt?: string) => Promise<ICrossAccountId>;217 getTokenTopmostOwner: (tokenId: number, blockHashAt?: string) => Promise<ICrossAccountId | null>;218 getTokenChildren: (tokenId: number, blockHashAt?: string) => Promise<ITokenAddress[]>; // todo:playgrounds219 getPropertyPermissions: (propertyKeys?: string[]) => Promise<ITokenPropertyPermission[]>;220 getTokenProperties: (tokenId: number, propertyKeys?: string[]) => Promise<IProperty[]>;221 transferToken: (signer: TSigner, tokenId: number, addressObj: ICrossAccountId) => Promise<boolean>;222 transferTokenFrom: (signer: TSigner, tokenId: number, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId) => Promise<boolean>;223 approveToken: (signer: TSigner, tokenId: number, toAddressObj: ICrossAccountId) => Promise<boolean>;224 isTokenApproved: (tokenId: number, toAddressObj: ICrossAccountId) => Promise<boolean>;225 mintToken: (signer: TSigner, owner: ICrossAccountId, properties?: IProperty[]) => Promise<ITokenNonfungible>;// todo:playgrounds226 mintMultipleTokens: (signer: TSigner, tokens: {owner: ICrossAccountId, properties?: IProperty[]}[]) => Promise<ITokenNonfungible[]>;// todo:playgrounds227 burnToken: (signer: TSigner, tokenId: number) => Promise<{228 success: boolean,229 token: number | null230 }>;231 burnTokenFrom: (signer: TSigner, tokenId: number, fromAddressObj: ICrossAccountId) => Promise<boolean>;232 setTokenProperties: (signer: TSigner, tokenId: number, properties: IProperty[]) => Promise<boolean>;233 deleteTokenProperties: (signer: TSigner, tokenId: number, propertyKeys: string[]) => Promise<boolean>;234 setTokenPropertyPermissions: (signer: TSigner, permissions: ITokenPropertyPermission[]) => Promise<boolean>;235 nestToken: (signer: TSigner, tokenId: number, toTokenObj: ITokenAddress) => Promise<boolean>;236 unnestToken: (signer: TSigner, tokenId: number, fromTokenObj: ITokenAddress, toAddressObj: ICrossAccountId) => Promise<boolean>;237}238239export interface ICollectionRFT extends ICollectionBase {240 getTokenObject: (tokenId: number) => ITokenRefungible;241 getToken: (tokenId: number, blockHashAt?: string) => Promise<{242 properties: IProperty[];243 owner: ICrossAccountId;244 normalizedOwner: ICrossAccountId;245 }| null>;246 getTokensByAddress: (addressObj: ICrossAccountId) => Promise<number[]>;247 getTop10TokenOwners: (tokenId: number) => Promise<ICrossAccountId[]>;248 getTokenBalance: (tokenId: number, addressObj: ICrossAccountId) => Promise<bigint>;249 getTokenTotalPieces: (tokenId: number) => Promise<bigint>;250 getTokenApprovedPieces: (tokenId: number, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId) => Promise<bigint>;251 getPropertyPermissions: (propertyKeys?: string[] | null) => Promise<ITokenPropertyPermission[]>;252 getTokenProperties: (tokenId: number, propertyKeys?: string[]) => Promise<IProperty[]>;253 transferToken: (signer: TSigner, tokenId: number, addressObj: ICrossAccountId, amount: bigint) => Promise<boolean>;254 transferTokenFrom: (signer: TSigner, tokenId: number, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId, amount: bigint) => Promise<boolean>;255 approveToken: (signer: TSigner, tokenId: number, toAddressObj: ICrossAccountId, amount: bigint) => Promise<boolean>;256 repartitionToken: (signer: TSigner, tokenId: number, amount: bigint) => Promise<boolean>;257 mintToken: (signer: TSigner, pieces: bigint, owner: ICrossAccountId, properties?: IProperty[]) => Promise<ITokenRefungible>;258 mintMultipleTokens: (signer: TSigner, tokens: {pieces: bigint, owner: ICrossAccountId, properties?: IProperty[]}[]) => Promise<ITokenRefungible[]>; // todo:playgrounds259 burnToken: (signer: TSigner, tokenId: number, amount: bigint) => Promise<{260 success: boolean,261 token: number | null262 }>;263 burnTokenFrom: (signer: TSigner, tokenId: number, fromAddressObj: ICrossAccountId, amount: bigint) => Promise<boolean>;264 setTokenProperties: (signer: TSigner, tokenId: number, properties: IProperty[]) => Promise<boolean>;265 deleteTokenProperties: (signer: TSigner, tokenId: number, propertyKeys: string[]) => Promise<boolean>;266 setTokenPropertyPermissions: (signer: TSigner, permissions: ITokenPropertyPermission[]) => Promise<boolean>;267}268269export interface ICollectionFT extends ICollectionBase {270 getBalance: (addressObj: ICrossAccountId) => Promise<bigint>;271 getTotalPieces: () => Promise<bigint>;272 getApprovedTokens: (fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId) => Promise<bigint>;273 getTop10Owners: () => Promise<ICrossAccountId[]>;274 mint: (signer: TSigner, amount: bigint, owner: ICrossAccountId) => Promise<boolean>;275 mintWithOneOwner: (signer: TSigner, tokens: {value: bigint}[], owner: ICrossAccountId) => Promise<boolean>;276 transfer: (signer: TSigner, toAddressObj: ICrossAccountId, amount: bigint) => Promise<boolean>;277 transferFrom: (signer: TSigner, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId, amount: bigint) => Promise<boolean>;278 burnTokens: (signer: TSigner, amount: bigint) => Promise<boolean>;279 burnTokensFrom: (signer: TSigner, fromAddressObj: ICrossAccountId, amount: bigint) => Promise<boolean>;280 approveTokens: (signer: TSigner, toAddressObj: ICrossAccountId, amount: bigint) => Promise<boolean>;281}282283export interface ITokenBase extends ITokenAddress {284 collection: ICollectionNFT | ICollectionRFT;285 getNextSponsored: (addressObj: ICrossAccountId) => Promise<number|null>;286 getProperties: (propertyKeys?: string[]) => Promise<IProperty[]>;287 setProperties: (signer: TSigner, properties: IProperty[]) => Promise<boolean>;288 deleteProperties: (signer: TSigner, propertyKeys: string[]) => Promise<boolean>;289 nestingAccount: () => ICrossAccountId;290 nestingAccountInLowerCase: () => ICrossAccountId;291}292293export interface ITokenNonfungible extends ITokenBase {294 collection: ICollectionNFT;295 getData: (blockHashAt?: string) => Promise<{296 properties: IProperty[];297 owner: ICrossAccountId;298 normalizedOwner: ICrossAccountId;299 }| null>;300 getOwner: (blockHashAt?: string) => Promise<ICrossAccountId>;301 getTopmostOwner: (blockHashAt?: string) => Promise<ICrossAccountId | null>;302 getChildren: (blockHashAt?: string) => Promise<ITokenAddress[]>; // todo:playgrounds303 nest: (signer: TSigner, toTokenObj: ITokenAddress) => Promise<boolean>;304 unnest: (signer: TSigner, fromTokenObj: ITokenAddress, toAddressObj: ICrossAccountId) => Promise<boolean>;305 transfer: (signer: TSigner, addressObj: ICrossAccountId) => Promise<boolean>;306 transferFrom: (signer: TSigner, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId) => Promise<boolean>;307 approve: (signer: TSigner, toAddressObj: ICrossAccountId) => Promise<boolean>;308 isApproved: (toAddressObj: ICrossAccountId) => Promise<boolean>;309 burn: (signer: TSigner) => Promise<{310 success: boolean,311 token: number | null312 }>;313 burnFrom: (signer: TSigner, fromAddressObj: ICrossAccountId) => Promise<boolean>;314}315316export interface ITokenRefungible extends ITokenBase {317 collection: ICollectionRFT;318 getData: (blockHashAt?: string) => Promise<{319 properties: IProperty[];320 owner: ICrossAccountId;321 normalizedOwner: ICrossAccountId;322 }| null>;323 getTop10Owners: () => Promise<ICrossAccountId[]>;324 getBalance: (addressObj: ICrossAccountId) => Promise<bigint>;325 getTotalPieces: () => Promise<bigint>;326 getApprovedPieces: (fromAddressObj: ICrossAccountId, toAccountObj: ICrossAccountId) => Promise<bigint>;327 transfer: (signer: TSigner, addressObj: ICrossAccountId, amount: bigint) => Promise<boolean>;328 transferFrom: (signer: TSigner, fromAddressObj: ICrossAccountId, toAddressObj: ICrossAccountId, amount: bigint) => Promise<boolean>;329 approve: (signer: TSigner, toAddressObj: ICrossAccountId, amount: bigint) => Promise<boolean>;330 repartition: (signer: TSigner, amount: bigint) => Promise<boolean>;331 burn: (signer: TSigner, amount: bigint) => Promise<{332 success: boolean,333 token: number | null334 }>;335 burnFrom: (signer: TSigner, fromAddressObj: ICrossAccountId, amount: bigint) => Promise<boolean>;336}337170tests/src/util/playgrounds/unique.tsdiffbeforeafterboth9import {ApiInterfaceEvents, SignerOptions} from '@polkadot/api/types';9import {ApiInterfaceEvents, SignerOptions} from '@polkadot/api/types';10import {encodeAddress, decodeAddress, keccakAsHex, evmToAddress, addressToEvm} from '@polkadot/util-crypto';10import {encodeAddress, decodeAddress, keccakAsHex, evmToAddress, addressToEvm} from '@polkadot/util-crypto';11import {IKeyringPair} from '@polkadot/types/types';11import {IKeyringPair} from '@polkadot/types/types';12import {IApiListeners, IBlock, IEvent, IChainProperties, ICollectionCreationOptions, ICollectionLimits, ICollectionPermissions, ICrossAccountId, ICrossAccountIdLower, ILogger, INestingPermissions, IProperty, IStakingInfo, ISubstrateBalance, ITokenAddress, ITokenPropertyPermission, ITransactionResult, IUniqueHelperLog, TApiAllowedListeners, TEthereumAccount, TSigner, TSubstrateAccount, TUniqueNetworks, ICollectionBase, ICollectionNFT, ICollectionRFT, ITokenBase, ITokenNonfungible, ITokenRefungible, ICollectionFT} from './types';12import {IApiListeners, IBlock, IEvent, IChainProperties, ICollectionCreationOptions, ICollectionLimits, ICollectionPermissions, ICrossAccountId, ICrossAccountIdLower, ILogger, INestingPermissions, IProperty, IStakingInfo, ISubstrateBalance, IToken, ITokenPropertyPermission, ITransactionResult, IUniqueHelperLog, TApiAllowedListeners, TEthereumAccount, TSigner, TSubstrateAccount, TUniqueNetworks} from './types';131314export const crossAccountIdFromLower = (lowerAddress: ICrossAccountIdLower): ICrossAccountId => {14export const crossAccountIdFromLower = (lowerAddress: ICrossAccountIdLower): ICrossAccountId => {15 const address = {} as ICrossAccountId;15 const address = {} as ICrossAccountId;55 RPC: 'rpc',55 RPC: 'rpc',56 };56 };575758 static getTokenAccount(token: ITokenAddress): ICrossAccountId {58 static getTokenAccount(token: IToken): ICrossAccountId {59 return {Ethereum: this.getTokenAddress(token)};59 return {Ethereum: this.getTokenAddress(token)};60 }60 }616162 static getTokenAccountInLowerCase(token: ITokenAddress): ICrossAccountId {62 static getTokenAccountInLowerCase(token: IToken): ICrossAccountId {63 return {Ethereum: this.getTokenAddress(token).toLowerCase()};63 return {Ethereum: this.getTokenAddress(token).toLowerCase()};64 }64 }656566 static getTokenAddress(token: ITokenAddress): string {66 static getTokenAddress(token: IToken): string {67 return nesting.tokenIdToAddress(token.collectionId, token.tokenId);67 return nesting.tokenIdToAddress(token.collectionId, token.tokenId);68 }68 }69691218 * @example mintCollection(aliceKeyring, {name: 'New', description: "New collection", tokenPrefix: "NEW"}, "NFT")1218 * @example mintCollection(aliceKeyring, {name: 'New', description: "New collection", tokenPrefix: "NEW"}, "NFT")1219 * @returns object of the created collection1219 * @returns object of the created collection1220 */1220 */1221 async mintCollection(signer: TSigner, collectionOptions: ICollectionCreationOptions, mode: 'NFT' | 'RFT'): Promise<UniqueCollectionBase> {1221 async mintCollection(signer: TSigner, collectionOptions: ICollectionCreationOptions, mode: 'NFT' | 'RFT'): Promise<UniqueBaseCollection> {1222 collectionOptions = JSON.parse(JSON.stringify(collectionOptions)) as ICollectionCreationOptions; // Clone object1222 collectionOptions = JSON.parse(JSON.stringify(collectionOptions)) as ICollectionCreationOptions; // Clone object1223 collectionOptions.mode = (mode === 'NFT') ? {nft: null} : {refungible: null};1223 collectionOptions.mode = (mode === 'NFT') ? {nft: null} : {refungible: null};1224 for (const key of ['name', 'description', 'tokenPrefix']) {1224 for (const key of ['name', 'description', 'tokenPrefix']) {1260 * @example getTokenObject(10, 5);1260 * @example getTokenObject(10, 5);1261 * @returns instance of UniqueNFTToken1261 * @returns instance of UniqueNFTToken1262 */1262 */1263 getTokenObject(collectionId: number, tokenId: number): UniqueNFTToken {1263 getTokenObject(collectionId: number, tokenId: number): UniqueNFToken {1264 return new UniqueNFTToken(tokenId, this.getCollectionObject(collectionId));1264 return new UniqueNFToken(tokenId, this.getCollectionObject(collectionId));1265 }1265 }126612661267 /**1267 /**1352 * @example getTokenChildren(10, 5);1352 * @example getTokenChildren(10, 5);1353 * @returns tokens whose depth of nesting is <= 51353 * @returns tokens whose depth of nesting is <= 51354 */1354 */1355 async getTokenChildren(collectionId: number, tokenId: number, blockHashAt?: string): Promise<ITokenAddress[]> {1355 async getTokenChildren(collectionId: number, tokenId: number, blockHashAt?: string): Promise<IToken[]> {1356 let children;1356 let children;1357 if(typeof blockHashAt === 'undefined') {1357 if(typeof blockHashAt === 'undefined') {1358 children = await this.helper.callRpc('api.rpc.unique.tokenChildren', [collectionId, tokenId]);1358 children = await this.helper.callRpc('api.rpc.unique.tokenChildren', [collectionId, tokenId]);1373 * @example nestToken(aliceKeyring, {collectionId: 10, tokenId: 5}, {collectionId: 10, tokenId: 4});1373 * @example nestToken(aliceKeyring, {collectionId: 10, tokenId: 5}, {collectionId: 10, tokenId: 4});1374 * @returns ```true``` if extrinsic success, otherwise ```false```1374 * @returns ```true``` if extrinsic success, otherwise ```false```1375 */1375 */1376 async nestToken(signer: TSigner, tokenObj: ITokenAddress, rootTokenObj: ITokenAddress): Promise<boolean> {1376 async nestToken(signer: TSigner, tokenObj: IToken, rootTokenObj: IToken): Promise<boolean> {1377 const rootTokenAddress = this.helper.util.getTokenAccount(rootTokenObj);1377 const rootTokenAddress = this.helper.util.getTokenAccount(rootTokenObj);1378 const result = await this.transferToken(signer, tokenObj.collectionId, tokenObj.tokenId, rootTokenAddress);1378 const result = await this.transferToken(signer, tokenObj.collectionId, tokenObj.tokenId, rootTokenAddress);1379 if(!result) {1379 if(!result) {1391 * @example unnestToken(aliceKeyring, {collectionId: 10, tokenId: 5}, {collectionId: 10, tokenId: 4}, {Substrate: "5DyN4Y92vZCjv38fg..."});1391 * @example unnestToken(aliceKeyring, {collectionId: 10, tokenId: 5}, {collectionId: 10, tokenId: 4}, {Substrate: "5DyN4Y92vZCjv38fg..."});1392 * @returns ```true``` if extrinsic success, otherwise ```false```1392 * @returns ```true``` if extrinsic success, otherwise ```false```1393 */1393 */1394 async unnestToken(signer: TSigner, tokenObj: ITokenAddress, rootTokenObj: ITokenAddress, toAddressObj: ICrossAccountId): Promise<boolean> {1394 async unnestToken(signer: TSigner, tokenObj: IToken, rootTokenObj: IToken, toAddressObj: ICrossAccountId): Promise<boolean> {1395 const rootTokenAddress = this.helper.util.getTokenAccount(rootTokenObj);1395 const rootTokenAddress = this.helper.util.getTokenAccount(rootTokenObj);1396 const result = await this.transferTokenFrom(signer, tokenObj.collectionId, tokenObj.tokenId, rootTokenAddress, toAddressObj);1396 const result = await this.transferTokenFrom(signer, tokenObj.collectionId, tokenObj.tokenId, rootTokenAddress, toAddressObj);1397 if(!result) {1397 if(!result) {1422 * @param data token data1422 * @param data token data1423 * @returns created token object1423 * @returns created token object1424 */1424 */1425 async mintToken(signer: TSigner, data: { collectionId: number; owner: ICrossAccountId | string; properties?: IProperty[]; }): Promise<UniqueNFTToken> {1425 async mintToken(signer: TSigner, data: { collectionId: number; owner: ICrossAccountId | string; properties?: IProperty[]; }): Promise<UniqueNFToken> {1426 const creationResult = await this.helper.executeExtrinsic(1426 const creationResult = await this.helper.executeExtrinsic(1427 signer,1427 signer,1428 'api.tx.unique.createItem', [data.collectionId, (typeof data.owner === 'string') ? {Substrate: data.owner} : data.owner, {1428 'api.tx.unique.createItem', [data.collectionId, (typeof data.owner === 'string') ? {Substrate: data.owner} : data.owner, {1453 * }]);1453 * }]);1454 * @returns ```true``` if extrinsic success, otherwise ```false```1454 * @returns ```true``` if extrinsic success, otherwise ```false```1455 */1455 */1456 async mintMultipleTokens(signer: TSigner, collectionId: number, tokens: {owner: ICrossAccountId, properties?: IProperty[]}[]): Promise<UniqueNFTToken[]> {1456 async mintMultipleTokens(signer: TSigner, collectionId: number, tokens: {owner: ICrossAccountId, properties?: IProperty[]}[]): Promise<UniqueNFToken[]> {1457 const creationResult = await this.helper.executeExtrinsic(1457 const creationResult = await this.helper.executeExtrinsic(1458 signer,1458 signer,1459 'api.tx.unique.createMultipleItemsEx', [collectionId, {NFT: tokens}],1459 'api.tx.unique.createMultipleItemsEx', [collectionId, {NFT: tokens}],1460 true,1460 true,1461 );1461 );1462 const collection = this.getCollectionObject(collectionId);1462 const collection = this.getCollectionObject(collectionId);1463 return this.helper.util.extractTokensFromCreationResult(creationResult).tokens.map((x: ITokenAddress) => collection.getTokenObject(x.tokenId));1463 return this.helper.util.extractTokensFromCreationResult(creationResult).tokens.map((x: IToken) => collection.getTokenObject(x.tokenId));1464 }1464 }146514651466 /**1466 /**1481 * }]);1481 * }]);1482 * @returns array of newly created tokens1482 * @returns array of newly created tokens1483 */1483 */1484 async mintMultipleTokensWithOneOwner(signer: TSigner, collectionId: number, owner: ICrossAccountId, tokens: {properties?: IProperty[]}[]): Promise<UniqueNFTToken[]> {1484 async mintMultipleTokensWithOneOwner(signer: TSigner, collectionId: number, owner: ICrossAccountId, tokens: {properties?: IProperty[]}[]): Promise<UniqueNFToken[]> {1485 const rawTokens = [];1485 const rawTokens = [];1486 for (const token of tokens) {1486 for (const token of tokens) {1487 const raw = {NFT: {properties: token.properties}};1487 const raw = {NFT: {properties: token.properties}};1493 true,1493 true,1494 );1494 );1495 const collection = this.getCollectionObject(collectionId);1495 const collection = this.getCollectionObject(collectionId);1496 return this.helper.util.extractTokensFromCreationResult(creationResult).tokens.map((x: ITokenAddress) => collection.getTokenObject(x.tokenId));1496 return this.helper.util.extractTokensFromCreationResult(creationResult).tokens.map((x: IToken) => collection.getTokenObject(x.tokenId));1497 }1497 }149814981499 /**1499 /**1530 * @example getTokenObject(10, 5);1530 * @example getTokenObject(10, 5);1531 * @returns instance of UniqueNFTToken1531 * @returns instance of UniqueNFTToken1532 */1532 */1533 getTokenObject(collectionId: number, tokenId: number): UniqueRFTToken {1533 getTokenObject(collectionId: number, tokenId: number): UniqueRFToken {1534 return new UniqueRFTToken(tokenId, this.getCollectionObject(collectionId));1534 return new UniqueRFToken(tokenId, this.getCollectionObject(collectionId));1535 }1535 }153615361537 /**1537 /**1609 * @example mintToken(aliceKeyring, {collectionId: 10, owner: {Substrate: '5GHoZe9c73RYbVzq...'}, pieces: 10000n});1609 * @example mintToken(aliceKeyring, {collectionId: 10, owner: {Substrate: '5GHoZe9c73RYbVzq...'}, pieces: 10000n});1610 * @returns created token object1610 * @returns created token object1611 */1611 */1612 async mintToken(signer: TSigner, data: { collectionId: number; owner: ICrossAccountId | string; pieces: bigint; properties?: IProperty[]; }): Promise<UniqueRFTToken> {1612 async mintToken(signer: TSigner, data: { collectionId: number; owner: ICrossAccountId | string; pieces: bigint; properties?: IProperty[]; }): Promise<UniqueRFToken> {1613 const creationResult = await this.helper.executeExtrinsic(1613 const creationResult = await this.helper.executeExtrinsic(1614 signer,1614 signer,1615 'api.tx.unique.createItem', [data.collectionId, (typeof data.owner === 'string') ? {Substrate: data.owner} : data.owner, {1615 'api.tx.unique.createItem', [data.collectionId, (typeof data.owner === 'string') ? {Substrate: data.owner} : data.owner, {1626 return this.getTokenObject(data.collectionId, createdTokens.tokens[0].tokenId);1626 return this.getTokenObject(data.collectionId, createdTokens.tokens[0].tokenId);1627 }1627 }162816281629 async mintMultipleTokens(signer: TSigner, collectionId: number, tokens: {owner: ICrossAccountId, pieces: bigint, properties?: IProperty[]}[]): Promise<UniqueRFTToken[]> {1629 async mintMultipleTokens(signer: TSigner, collectionId: number, tokens: {owner: ICrossAccountId, pieces: bigint, properties?: IProperty[]}[]): Promise<UniqueRFToken[]> {1630 throw Error('Not implemented');1630 throw Error('Not implemented');1631 const creationResult = await this.helper.executeExtrinsic(1631 const creationResult = await this.helper.executeExtrinsic(1632 signer,1632 signer,1633 'api.tx.unique.createMultipleItemsEx', [collectionId, {RefungibleMultipleOwners: tokens}],1633 'api.tx.unique.createMultipleItemsEx', [collectionId, {RefungibleMultipleOwners: tokens}],1634 true, // `Unable to mint RFT tokens for ${label}`,1634 true, // `Unable to mint RFT tokens for ${label}`,1635 );1635 );1636 const collection = this.getCollectionObject(collectionId);1636 const collection = this.getCollectionObject(collectionId);1637 return this.helper.util.extractTokensFromCreationResult(creationResult).tokens.map((x: ITokenAddress) => collection.getTokenObject(x.tokenId));1637 return this.helper.util.extractTokensFromCreationResult(creationResult).tokens.map((x: IToken) => collection.getTokenObject(x.tokenId));1638 }1638 }163916391640 /**1640 /**1646 * @example mintMultipleTokensWithOneOwner(aliceKeyring, 10, {Substrate: "5GHoZe9c73RYbVzq..."}, [{pieces: 100000n, properties: [{key: "gender", value: "male"}]}]);1646 * @example mintMultipleTokensWithOneOwner(aliceKeyring, 10, {Substrate: "5GHoZe9c73RYbVzq..."}, [{pieces: 100000n, properties: [{key: "gender", value: "male"}]}]);1647 * @returns array of newly created RFT tokens1647 * @returns array of newly created RFT tokens1648 */1648 */1649 async mintMultipleTokensWithOneOwner(signer: TSigner, collectionId: number, owner: ICrossAccountId, tokens: {pieces: bigint, properties?: IProperty[]}[]): Promise<UniqueRFTToken[]> {1649 async mintMultipleTokensWithOneOwner(signer: TSigner, collectionId: number, owner: ICrossAccountId, tokens: {pieces: bigint, properties?: IProperty[]}[]): Promise<UniqueRFToken[]> {1650 const rawTokens = [];1650 const rawTokens = [];1651 for (const token of tokens) {1651 for (const token of tokens) {1652 const raw = {ReFungible: {pieces: token.pieces, properties: token.properties}};1652 const raw = {ReFungible: {pieces: token.pieces, properties: token.properties}};1658 true,1658 true,1659 );1659 );1660 const collection = this.getCollectionObject(collectionId);1660 const collection = this.getCollectionObject(collectionId);1661 return this.helper.util.extractTokensFromCreationResult(creationResult).tokens.map((x: ITokenAddress) => collection.getTokenObject(x.tokenId));1661 return this.helper.util.extractTokensFromCreationResult(creationResult).tokens.map((x: IToken) => collection.getTokenObject(x.tokenId));1662 }1662 }166316631664 /**1664 /**19841984198519851986class BalanceGroup extends HelperGroup {1986class BalanceGroup extends HelperGroup {1987 /**1987 /**1988 * Representation of the native token in the smallest unit1988 * Representation of the native token in the smallest unit - one OPAL (OPL), QUARTZ (QTZ), or UNIQUE (UNQ).1989 * @example getOneTokenNominal()1989 * @example getOneTokenNominal()1990 * @returns ```BigInt``` representation of the native token in the smallest unit, e.g. ```1_000_000_000_000_000_000n``` for QTZ.1990 * @returns ```BigInt``` representation of the native token in the smallest unit, e.g. ```1_000_000_000_000_000_000n``` for QTZ.1991 */1991 */1992 getOneTokenNominal(): bigint {1992 getOneTokenNominal(): bigint {1993 const chainProperties = this.helper.chain.getChainProperties();1993 const chainProperties = this.helper.chain.getChainProperties();1994 return 10n ** BigInt((chainProperties.tokenDecimals || [18])[0]);1994 return 10n ** BigInt((chainProperties.tokenDecimals || [18])[0]);2223}2223}22242224222522252226class UniqueCollectionBase implements ICollectionBase {2226export class UniqueBaseCollection {2227 helper: UniqueHelper;2227 helper: UniqueHelper;2228 collectionId: number;2228 collectionId: number;222922292326}2326}23272327232823282329class UniqueNFTCollection extends UniqueCollectionBase implements ICollectionNFT {2329export class UniqueNFTCollection extends UniqueBaseCollection {2330 getTokenObject(tokenId: number) {2330 getTokenObject(tokenId: number) {2331 return new UniqueNFTToken(tokenId, this);2331 return new UniqueNFToken(tokenId, this);2332 }2332 }233323332334 async getTokensByAddress(addressObj: ICrossAccountId) {2334 async getTokensByAddress(addressObj: ICrossAccountId) {2403 return await this.helper.nft.setTokenPropertyPermissions(signer, this.collectionId, permissions);2403 return await this.helper.nft.setTokenPropertyPermissions(signer, this.collectionId, permissions);2404 }2404 }240524052406 async nestToken(signer: TSigner, tokenId: number, toTokenObj: ITokenAddress) {2406 async nestToken(signer: TSigner, tokenId: number, toTokenObj: IToken) {2407 return await this.helper.nft.nestToken(signer, {collectionId: this.collectionId, tokenId}, toTokenObj);2407 return await this.helper.nft.nestToken(signer, {collectionId: this.collectionId, tokenId}, toTokenObj);2408 }2408 }240924092410 async unnestToken(signer: TSigner, tokenId: number, fromTokenObj: ITokenAddress, toAddressObj: ICrossAccountId) {2410 async unnestToken(signer: TSigner, tokenId: number, fromTokenObj: IToken, toAddressObj: ICrossAccountId) {2411 return await this.helper.nft.unnestToken(signer, {collectionId: this.collectionId, tokenId}, fromTokenObj, toAddressObj);2411 return await this.helper.nft.unnestToken(signer, {collectionId: this.collectionId, tokenId}, fromTokenObj, toAddressObj);2412 }2412 }2413}2413}24142414241524152416class UniqueRFTCollection extends UniqueCollectionBase implements ICollectionRFT {2416export class UniqueRFTCollection extends UniqueBaseCollection {2417 getTokenObject(tokenId: number) {2417 getTokenObject(tokenId: number) {2418 return new UniqueRFTToken(tokenId, this);2418 return new UniqueRFToken(tokenId, this);2419 }2419 }242024202421 async getToken(tokenId: number, blockHashAt?: string) {2421 async getToken(tokenId: number, blockHashAt?: string) {2496}2496}24972497249824982499class UniqueFTCollection extends UniqueCollectionBase implements ICollectionFT {2499export class UniqueFTCollection extends UniqueBaseCollection {2500 async getBalance(addressObj: ICrossAccountId) {2500 async getBalance(addressObj: ICrossAccountId) {2501 return await this.helper.ft.getBalance(this.collectionId, addressObj);2501 return await this.helper.ft.getBalance(this.collectionId, addressObj);2502 }2502 }2543}2543}25442544254525452546class UniqueTokenBase implements ITokenBase {2546export class UniqueBaseToken {2547 collection: UniqueNFTCollection | UniqueRFTCollection;2547 collection: UniqueNFTCollection | UniqueRFTCollection;2548 collectionId: number;2548 collectionId: number;2549 tokenId: number;2549 tokenId: number;2580}2580}25812581258225822583class UniqueNFTToken extends UniqueTokenBase implements ITokenNonfungible {2583export class UniqueNFToken extends UniqueBaseToken {2584 collection: UniqueNFTCollection;2584 collection: UniqueNFTCollection;258525852586 constructor(tokenId: number, collection: UniqueNFTCollection) {2586 constructor(tokenId: number, collection: UniqueNFTCollection) {2604 return await this.collection.getTokenChildren(this.tokenId, blockHashAt);2604 return await this.collection.getTokenChildren(this.tokenId, blockHashAt);2605 }2605 }260626062607 async nest(signer: TSigner, toTokenObj: ITokenAddress) {2607 async nest(signer: TSigner, toTokenObj: IToken) {2608 return await this.collection.nestToken(signer, this.tokenId, toTokenObj);2608 return await this.collection.nestToken(signer, this.tokenId, toTokenObj);2609 }2609 }261026102611 async unnest(signer: TSigner, fromTokenObj: ITokenAddress, toAddressObj: ICrossAccountId) {2611 async unnest(signer: TSigner, fromTokenObj: IToken, toAddressObj: ICrossAccountId) {2612 return await this.collection.unnestToken(signer, this.tokenId, fromTokenObj, toAddressObj);2612 return await this.collection.unnestToken(signer, this.tokenId, fromTokenObj, toAddressObj);2613 }2613 }261426142637 }2637 }2638}2638}263926392640class UniqueRFTToken extends UniqueTokenBase implements ITokenRefungible {2640export class UniqueRFToken extends UniqueBaseToken {2641 collection: UniqueRFTCollection;2641 collection: UniqueRFTCollection;264226422643 constructor(tokenId: number, collection: UniqueRFTCollection) {2643 constructor(tokenId: number, collection: UniqueRFTCollection) {