difftreelog
Merge pull request #539 from UniqueNetwork/test/move-to-playgrounds
in: master
Test/move to playgrounds
3 files changed
tests/src/util/playgrounds/types.tsdiffbeforeafterboth--- /dev/null
+++ b/tests/src/util/playgrounds/types.ts
@@ -0,0 +1,130 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+import {IKeyringPair} from '@polkadot/types/types';
+
+export interface IChainEvent {
+ data: any;
+ method: string;
+ section: string;
+}
+
+export interface ITransactionResult {
+ status: 'Fail' | 'Success';
+ result: {
+ events: {
+ event: IChainEvent
+ }[];
+ },
+ moduleError?: string;
+}
+
+export interface ILogger {
+ log: (msg: any, level?: string) => void;
+ level: {
+ ERROR: 'ERROR';
+ WARNING: 'WARNING';
+ INFO: 'INFO';
+ [key: string]: string;
+ }
+}
+
+export interface IUniqueHelperLog {
+ executedAt: number;
+ executionTime: number;
+ type: 'extrinsic' | 'rpc';
+ status: 'Fail' | 'Success';
+ call: string;
+ params: any[];
+ moduleError?: string;
+ events?: any;
+}
+
+export interface IApiListeners {
+ connected?: (...args: any[]) => any;
+ disconnected?: (...args: any[]) => any;
+ error?: (...args: any[]) => any;
+ ready?: (...args: any[]) => any;
+ decorated?: (...args: any[]) => any;
+}
+
+export interface ICrossAccountId {
+ Substrate?: TSubstrateAccount;
+ Ethereum?: TEthereumAccount;
+}
+
+export interface ICrossAccountIdLower {
+ substrate?: TSubstrateAccount;
+ ethereum?: TEthereumAccount;
+}
+
+export interface ICollectionLimits {
+ accountTokenOwnershipLimit?: number | null;
+ sponsoredDataSize?: number | null;
+ sponsoredDataRateLimit?: {blocks: number} | {sponsoringDisabled: null} | null;
+ tokenLimit?: number | null;
+ sponsorTransferTimeout?: number | null;
+ sponsorApproveTimeout?: number | null;
+ ownerCanTransfer?: boolean | null;
+ ownerCanDestroy?: boolean | null;
+ transfersEnabled?: boolean | null;
+}
+
+export interface INestingPermissions {
+ tokenOwner?: boolean;
+ collectionAdmin?: boolean;
+ restricted?: number[] | null;
+}
+
+export interface ICollectionPermissions {
+ access?: 'Normal' | 'AllowList';
+ mintMode?: boolean;
+ nesting?: INestingPermissions;
+}
+
+export interface IProperty {
+ key: string;
+ value: string;
+}
+
+export interface ITokenPropertyPermission {
+ key: string;
+ permission: {
+ mutable: boolean;
+ tokenOwner: boolean;
+ collectionAdmin: boolean;
+ }
+}
+
+export interface IToken {
+ collectionId: number;
+ tokenId: number;
+}
+
+export interface ICollectionCreationOptions {
+ name: string | number[];
+ description: string | number[];
+ tokenPrefix: string | number[];
+ mode?: {
+ nft?: null;
+ refungible?: null;
+ fungible?: number;
+ }
+ permissions?: ICollectionPermissions;
+ properties?: IProperty[];
+ tokenPropertyPermissions?: ITokenPropertyPermission[];
+ limits?: ICollectionLimits;
+ pendingSponsor?: TSubstrateAccount;
+}
+
+export interface IChainProperties {
+ ss58Format: number;
+ tokenDecimals: number[];
+ tokenSymbol: string[]
+}
+
+export type TSubstrateAccount = string;
+export type TEthereumAccount = string;
+export type TApiAllowedListeners = 'connected' | 'disconnected' | 'error' | 'ready' | 'decorated';
+export type TUniqueNetworks = 'opal' | 'quartz' | 'unique';
+export type TSigner = IKeyringPair; // | 'string'
\ No newline at end of file
tests/src/util/playgrounds/unique.dev.tsdiffbeforeafterboth--- a/tests/src/util/playgrounds/unique.dev.ts
+++ b/tests/src/util/playgrounds/unique.dev.ts
@@ -3,9 +3,10 @@
import {mnemonicGenerate} from '@polkadot/util-crypto';
import {UniqueHelper} from './unique';
-import {IKeyringPair} from '@polkadot/types/types';
import {ApiPromise, WsProvider} from '@polkadot/api';
import * as defs from '../../interfaces/definitions';
+import {TSigner} from './types';
+import {IKeyringPair} from '@polkadot/types/types';
export class DevUniqueHelper extends UniqueHelper {
@@ -73,7 +74,7 @@
let nonce = await this.helper.chain.getNonce(donor.address);
const tokenNominal = this.helper.balance.getOneTokenNominal();
const transactions = [];
- const accounts = [];
+ const accounts: IKeyringPair[] = [];
for (const balance of balances) {
const recepient = this.helper.util.fromSeed(mnemonicGenerate());
accounts.push(recepient);
@@ -84,7 +85,52 @@
}
}
- await Promise.all(transactions);
+ await Promise.all(transactions).catch(e => {});
+
+ //#region TODO remove this region, when nonce problem will be solved
+ const checkBalances = async () => {
+ let isSuccess = true;
+ for (let i = 0; i < balances.length; i++) {
+ const balance = await this.helper.balance.getSubstrate(accounts[i].address);
+ if (balance !== balances[i] * tokenNominal) {
+ isSuccess = false;
+ break;
+ }
+ }
+ return isSuccess;
+ };
+
+ let accountsCreated = false;
+ // checkBalances retry up to 5 blocks
+ for (let index = 0; index < 5; index++) {
+ console.log(await this.helper.chain.getLatestBlockNumber());
+ accountsCreated = await checkBalances();
+ if(accountsCreated) break;
+ await this.waitNewBlocks(1);
+ }
+
+ if (!accountsCreated) throw Error('Accounts generation failed');
+ //#endregion
+
return accounts;
};
+
+ /**
+ * Wait for specified bnumber of blocks
+ * @param blocksCount number of blocks to wait
+ * @returns
+ */
+ async waitNewBlocks(blocksCount = 1): Promise<void> {
+ const promise = new Promise<void>(async (resolve) => {
+ const unsubscribe = await this.helper.api!.rpc.chain.subscribeNewHeads(() => {
+ if (blocksCount > 0) {
+ blocksCount--;
+ } else {
+ unsubscribe();
+ resolve();
+ }
+ });
+ });
+ return promise;
+ }
}
\ No newline at end of file
tests/src/util/playgrounds/unique.tsdiffbeforeafterboth778import {ApiPromise, WsProvider, Keyring} from '@polkadot/api';8import {ApiPromise, WsProvider, Keyring} from '@polkadot/api';9import {ApiInterfaceEvents} from '@polkadot/api/types';9import {ApiInterfaceEvents} from '@polkadot/api/types';10import {IKeyringPair} from '@polkadot/types/types';11import {encodeAddress, decodeAddress, keccakAsHex, evmToAddress, addressToEvm} from '@polkadot/util-crypto';10import {encodeAddress, decodeAddress, keccakAsHex, evmToAddress, addressToEvm} from '@polkadot/util-crypto';1211import {IKeyringPair} from '@polkadot/types/types';12import {IApiListeners, IChainEvent, IChainProperties, ICollectionCreationOptions, ICollectionLimits, ICollectionPermissions, ICrossAccountId, ICrossAccountIdLower, ILogger, INestingPermissions, IProperty, IToken, ITokenPropertyPermission, ITransactionResult, IUniqueHelperLog, TApiAllowedListeners, TEthereumAccount, TSigner, TSubstrateAccount, TUniqueNetworks} from './types';131314const crossAccountIdFromLower = (lowerAddress: ICrossAccountIdLower): ICrossAccountId => {14const crossAccountIdFromLower = (lowerAddress: ICrossAccountIdLower): ICrossAccountId => {15 const address = {} as ICrossAccountId;15 const address = {} as ICrossAccountId;45};45};464748interface IChainEvent {49 data: any;50 method: string;51 section: string;52}5354interface ITransactionResult {55 status: 'Fail' | 'Success';56 result: {57 events: {58 event: IChainEvent59 }[];60 },61 moduleError?: string;62}6364interface ILogger {65 log: (msg: any, level?: string) => void;66 level: {67 ERROR: 'ERROR';68 WARNING: 'WARNING';69 INFO: 'INFO';70 [key: string]: string;71 }72}7374interface IUniqueHelperLog {75 executedAt: number;76 executionTime: number;77 type: 'extrinsic' | 'rpc';78 status: 'Fail' | 'Success';79 call: string;80 params: any[];81 moduleError?: string;82 events?: any;83}8485interface IApiListeners {86 connected?: (...args: any[]) => any;87 disconnected?: (...args: any[]) => any;88 error?: (...args: any[]) => any;89 ready?: (...args: any[]) => any; 90 decorated?: (...args: any[]) => any;91}9293interface ICrossAccountId {94 Substrate?: TSubstrateAccount;95 Ethereum?: TEthereumAccount;96}9798interface ICrossAccountIdLower {99 substrate?: TSubstrateAccount;100 ethereum?: TEthereumAccount;101}102103interface ICollectionLimits {104 accountTokenOwnershipLimit?: number | null;105 sponsoredDataSize?: number | null;106 sponsoredDataRateLimit?: {blocks: number} | {sponsoringDisabled: null} | null;107 tokenLimit?: number | null;108 sponsorTransferTimeout?: number | null;109 sponsorApproveTimeout?: number | null;110 ownerCanTransfer?: boolean | null;111 ownerCanDestroy?: boolean | null;112 transfersEnabled?: boolean | null;113}114115interface INestingPermissions {116 tokenOwner?: boolean;117 collectionAdmin?: boolean;118 restricted?: number[] | null;119}120121interface ICollectionPermissions {122 access?: 'Normal' | 'AllowList';123 mintMode?: boolean;124 nesting?: INestingPermissions;125}126127interface IProperty {128 key: string;129 value: string;130}131132interface ITokenPropertyPermission {133 key: string;134 permission: {135 mutable: boolean;136 tokenOwner: boolean;137 collectionAdmin: boolean;138 }139}140141interface IToken {142 collectionId: number;143 tokenId: number;144}145146interface ICollectionCreationOptions {147 name: string | number[];148 description: string | number[];149 tokenPrefix: string | number[];150 mode?: {151 nft?: null;152 refungible?: null;153 fungible?: number;154 }155 permissions?: ICollectionPermissions;156 properties?: IProperty[];157 tokenPropertyPermissions?: ITokenPropertyPermission[];158 limits?: ICollectionLimits;159 pendingSponsor?: TSubstrateAccount;160}161162interface IChainProperties {163 ss58Format: number;164 tokenDecimals: number[];165 tokenSymbol: string[]166}167168type TSubstrateAccount = string;169type TEthereumAccount = string;170type TApiAllowedListeners = 'connected' | 'disconnected' | 'error' | 'ready' | 'decorated';171type TUniqueNetworks = 'opal' | 'quartz' | 'unique';172type TSigner = IKeyringPair; // | 'string'17346174class UniqueUtil {47class UniqueUtil {175 static transactionStatus = {48 static transactionStatus = {651 return normalized;524 return normalized;652 }525 }526527 /**528 * Get the normalized addresses added to the collection allow-list.529 * @param collectionId ID of collection530 * @example await getAllowList(1)531 * @returns array of allow-listed addresses532 */533 async getAllowList(collectionId: number): Promise<ICrossAccountId[]> {534 const normalized = [];535 const allowListed = (await this.helper.callRpc('api.rpc.unique.allowlist', [collectionId])).toHuman();536 for (const address of allowListed) {537 if (address.Substrate) normalized.push({Substrate: this.helper.address.normalizeSubstrate(address.Substrate)});538 else normalized.push(address);539 }540 return normalized;541 }653542654 /**543 /**655 * Get the effective limits of the collection instead of null for default values544 * Get the effective limits of the collection instead of null for default values794 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionAdminAdded', label);683 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionAdminAdded', label);795 }684 }685686 /**687 * Adds an address to allow list 688 * @param signer keyring of signer689 * @param collectionId ID of collection690 * @param addressObj address to add to the allow list691 * @param label extra label for log692 * @returns ```true``` if extrinsic success, otherwise ```false```693 */694 async addToAllowList(signer: TSigner, collectionId: number, addressObj: ICrossAccountId, label?: string): Promise<boolean> {695 if(typeof label === 'undefined') label = `collection #${collectionId}`;696 const result = await this.helper.executeExtrinsic(697 signer,698 'api.tx.unique.addToAllowList', [collectionId, addressObj],699 true, `Unable to add address to allow list for ${label}`,700 );701702 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'AllowListAddressAdded');703 }796704797 /**705 /**798 * Removes a collection administrator.706 * Removes a collection administrator.2119 return await this.helper.collection.getAdmins(this.collectionId);2027 return await this.helper.collection.getAdmins(this.collectionId);2120 }2028 }20292030 async getAllowList() {2031 return await this.helper.collection.getAllowList(this.collectionId);2032 }212120332122 async getEffectiveLimits() {2034 async getEffectiveLimits() {2123 return await this.helper.collection.getEffectiveLimits(this.collectionId);2035 return await this.helper.collection.getEffectiveLimits(this.collectionId);2143 return await this.helper.collection.addAdmin(signer, this.collectionId, adminAddressObj, label);2055 return await this.helper.collection.addAdmin(signer, this.collectionId, adminAddressObj, label);2144 }2056 }20572058 async addToAllowList(signer: TSigner, addressObj: ICrossAccountId, label?: string) {2059 return await this.helper.collection.addToAllowList(signer, this.collectionId, addressObj, label);2060 }214520612146 async removeAdmin(signer: TSigner, adminAddressObj: ICrossAccountId, label?: string) {2062 async removeAdmin(signer: TSigner, adminAddressObj: ICrossAccountId, label?: string) {2147 return await this.helper.collection.removeAdmin(signer, this.collectionId, adminAddressObj, label);2063 return await this.helper.collection.removeAdmin(signer, this.collectionId, adminAddressObj, label);