difftreelog
Tests: code-style fixes
in: master
14 files changed
tests/src/addCollectionAdmin.test.tsdiffbeforeafterboth--- a/tests/src/addCollectionAdmin.test.ts
+++ b/tests/src/addCollectionAdmin.test.ts
@@ -110,7 +110,7 @@
const [alice, ...accounts] = await helper.arrange.createAccounts([10n, 0n, 0n, 0n, 0n, 0n, 0n, 0n], donor);
const collection = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
- const chainAdminLimit = (helper.api!.consts.common.collectionAdminsLimit as any).toNumber();
+ const chainAdminLimit = (helper.getApi().consts.common.collectionAdminsLimit as any).toNumber();
expect(chainAdminLimit).to.be.equal(5);
for (let i = 0; i < chainAdminLimit; i++) {
tests/src/approve.test.tsdiffbeforeafterboth--- a/tests/src/approve.test.ts
+++ b/tests/src/approve.test.ts
@@ -60,7 +60,7 @@
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));
+ await helper.signTransaction(alice, helper.constructApiCall('api.tx.unique.approve', [{Substrate: bob.address}, collectionId, tokenId, 0]));
expect(await helper.nft.isTokenApproved(collectionId, tokenId, {Substrate: bob.address})).to.be.false;
});
@@ -275,7 +275,7 @@
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));
+ await helper.signTransaction(alice, helper.constructApiCall('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;
@@ -328,7 +328,7 @@
itSub('1 for NFT', 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));
+ const approveTx = async () => helper.signTransaction(bob, helper.constructApiCall('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;
});
tests/src/block-production.test.tsdiffbeforeafterboth--- a/tests/src/block-production.test.ts
+++ b/tests/src/block-production.test.ts
@@ -37,7 +37,7 @@
describe('Block Production smoke test', () => {
itSub('Node produces new blocks', async ({helper}) => {
- const blocks: number[] | undefined = await getBlocks(helper.api!);
+ const blocks: number[] | undefined = await getBlocks(helper.getApi());
expect(blocks[0]).to.be.lessThan(blocks[1]);
});
});
tests/src/createMultipleItemsEx.test.tsdiffbeforeafterboth--- a/tests/src/createMultipleItemsEx.test.ts
+++ b/tests/src/createMultipleItemsEx.test.ts
@@ -178,13 +178,12 @@
tokenPrefix: 'COL',
}, 0);
- const api = helper.api;
- await helper.signTransaction(alice, api?.tx.unique.createMultipleItemsEx(collection.collectionId, {
+ await helper.executeExtrinsic(alice, 'api.tx.unique.createMultipleItemsEx',[collection.collectionId, {
Fungible: new Map([
[JSON.stringify({Substrate: alice.address}), 50],
[JSON.stringify({Substrate: bob.address}), 100],
]),
- }));
+ }], true);
expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(50n);
expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(100n);
@@ -200,8 +199,7 @@
],
});
- const api = helper.api;
- await helper.signTransaction(alice, api?.tx.unique.createMultipleItemsEx(collection.collectionId, {
+ await helper.executeExtrinsic(alice, 'api.tx.unique.createMultipleItemsEx', [collection.collectionId, {
RefungibleMultipleOwners: {
users: new Map([
[JSON.stringify({Substrate: alice.address}), 1],
@@ -211,7 +209,7 @@
{key: 'k', value: 'v'},
],
},
- }));
+ }], true);
const tokenId = await collection.getLastTokenId();
expect(tokenId).to.be.equal(1);
expect(await collection.getTokenBalance(1, {Substrate: alice.address})).to.be.equal(1n);
@@ -228,9 +226,7 @@
],
});
- const api = helper.api;
-
- await helper.signTransaction(alice, api?.tx.unique.createMultipleItemsEx(collection.collectionId, {
+ await helper.executeExtrinsic(alice, 'api.tx.unique.createMultipleItemsEx', [collection.collectionId, {
RefungibleMultipleItems: [
{
user: {Substrate: alice.address}, pieces: 1,
@@ -245,7 +241,7 @@
],
},
],
- }));
+ }], true);
expect(await collection.getLastTokenId()).to.be.equal(2);
expect(await collection.getTokenBalance(1, {Substrate: alice.address})).to.be.equal(1n);
tests/src/creditFeesToTreasury.test.tsdiffbeforeafterboth--- a/tests/src/creditFeesToTreasury.test.ts
+++ b/tests/src/creditFeesToTreasury.test.ts
@@ -70,7 +70,7 @@
});
itSub('Sender balance decreased by fee+sent amount, Treasury balance increased by fee', async ({helper}) => {
- await skipInflationBlock(helper.api!);
+ await skipInflationBlock(helper.getApi());
await helper.wait.newBlocks(1);
const treasuryBalanceBefore = await helper.balance.getSubstrate(TREASURY);
@@ -89,7 +89,7 @@
});
itSub('Treasury balance increased by failed tx fee', async ({helper}) => {
- const api = helper.api!;
+ const api = helper.getApi();
await helper.wait.newBlocks(1);
const treasuryBalanceBefore = await helper.balance.getSubstrate(TREASURY);
@@ -107,7 +107,7 @@
});
itSub('NFT Transactions also send fees to Treasury', async ({helper}) => {
- await skipInflationBlock(helper.api!);
+ await skipInflationBlock(helper.getApi());
await helper.wait.newBlocks(1);
const treasuryBalanceBefore = await helper.balance.getSubstrate(TREASURY);
@@ -125,7 +125,7 @@
itSub('Fees are sane', async ({helper}) => {
const unique = helper.balance.getOneTokenNominal();
- await skipInflationBlock(helper.api!);
+ await skipInflationBlock(helper.getApi());
await helper.wait.newBlocks(1);
const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);
@@ -140,7 +140,7 @@
});
itSub('NFT Transfer fee is close to 0.1 Unique', async ({helper}) => {
- await skipInflationBlock(helper.api!);
+ await skipInflationBlock(helper.getApi());
await helper.wait.newBlocks(1);
const collection = await helper.nft.mintCollection(alice, {
tests/src/eth/createNFTCollection.test.tsdiffbeforeafterboth--- a/tests/src/eth/createNFTCollection.test.ts
+++ b/tests/src/eth/createNFTCollection.test.ts
@@ -152,7 +152,7 @@
before(async function() {
await usingEthPlaygrounds(async (helper, privateKey) => {
donor = privateKey('//Alice');
- nominal = helper.balance.getOneTokenNominal()
+ nominal = helper.balance.getOneTokenNominal();
});
});
tests/src/eth/proxy/nonFungibleProxy.test.tsdiffbeforeafterboth--- a/tests/src/eth/proxy/nonFungibleProxy.test.ts
+++ b/tests/src/eth/proxy/nonFungibleProxy.test.ts
@@ -138,23 +138,16 @@
});
//TODO: CORE-302 add eth methods
- itEth.skip('Can perform mintBulk()', async ({helper, privateKey}) => {
- const api = helper.getApi();
- const web3 = helper.getWeb3();
- const privateKeyWrapper = privateKey;
- /*
- const collection = await createCollectionExpectSuccess({
- mode: {type: 'NFT'},
- });
- const alice = privateKeyWrapper('//Alice');
+ itEth.skip('Can perform mintBulk()', async ({helper}) => {
+ const collection = await helper.nft.mintCollection(donor, {name: 'New', description: 'New collection', tokenPrefix: 'NEW'});
- const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
- const receiver = createEthAccount(web3);
+ const caller = await helper.eth.createAccountWithBalance(donor, 30n);
+ const receiver = helper.eth.createAccount();
- const address = collectionIdToAddress(collection);
- const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}), privateKeyWrapper);
- const changeAdminTx = api.tx.unique.addCollectionAdmin(collection, {Ethereum: contract.options.address});
- await submitTransactionAsync(alice, changeAdminTx);
+ const address = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const evmCollection = helper.ethNativeContract.collection(address, 'nft', caller);
+ const contract = await proxyWrap(helper, evmCollection, donor);
+ await collection.addAdmin(donor, {Ethereum: contract.options.address});
{
const nextTokenId = await contract.methods.nextTokenId().call();
@@ -167,7 +160,7 @@
[+nextTokenId + 2, 'Test URI 2'],
],
).send({from: caller});
- const events = normalizeEvents(result.events);
+ const events = helper.eth.normalizeEvents(result.events);
expect(events).to.be.deep.equal([
{
@@ -203,7 +196,6 @@
expect(await contract.methods.tokenURI(+nextTokenId + 1).call()).to.be.equal('Test URI 1');
expect(await contract.methods.tokenURI(+nextTokenId + 2).call()).to.be.equal('Test URI 2');
}
- */
});
itEth('Can perform burn()', async ({helper}) => {
tests/src/eth/util/playgrounds/unique.dev.tsdiffbeforeafterboth--- a/tests/src/eth/util/playgrounds/unique.dev.ts
+++ b/tests/src/eth/util/playgrounds/unique.dev.ts
@@ -285,8 +285,8 @@
await code();
// In dev mode, the transaction might not finish processing in time
await this.helper.wait.newBlocks(1);
- }
- return await this.helper.arrange.calculcateFee(address, code);
+ };
+ return await this.helper.arrange.calculcateFee(address, wrappedCode);
}
}
tests/src/inflation.test.tsdiffbeforeafterboth--- a/tests/src/inflation.test.ts
+++ b/tests/src/inflation.test.ts
@@ -40,9 +40,9 @@
const tx = helper.constructApiCall('api.tx.inflation.startInflation', [1]);
await expect(helper.executeExtrinsic(superuser, 'api.tx.sudo.sudo', [tx])).to.not.be.rejected;
- const blockInterval = (helper.api!.consts.inflation.inflationBlockInterval as any).toBigInt();
- const totalIssuanceStart = ((await helper.api!.query.inflation.startingYearTotalIssuance()) as any).toBigInt();
- const blockInflation = (await helper.api!.query.inflation.blockInflation() as any).toBigInt();
+ const blockInterval = (helper.getApi().consts.inflation.inflationBlockInterval as any).toBigInt();
+ const totalIssuanceStart = ((await helper.callRpc('api.query.inflation.startingYearTotalIssuance', [])) as any).toBigInt();
+ const blockInflation = (await helper.callRpc('api.query.inflation.blockInflation', []) as any).toBigInt();
const YEAR = 5259600n; // 6-second block. Blocks in one year
// const YEAR = 2629800n; // 12-second block. Blocks in one year
tests/src/nesting/properties.test.tsdiffbeforeafterboth--- a/tests/src/nesting/properties.test.ts
+++ b/tests/src/nesting/properties.test.ts
@@ -276,7 +276,7 @@
itSub('Reads access rights to properties of a collection', async ({helper}) => {
const collection = await helper.nft.mintCollection(alice);
- const propertyRights = (await helper.api!.query.common.collectionPropertyPermissions(collection.collectionId)).toJSON();
+ const propertyRights = (await helper.callRpc('api.query.common.collectionPropertyPermissions', [collection.collectionId])).toJSON();
expect(propertyRights).to.be.empty;
});
@@ -817,7 +817,7 @@
).to.be.fulfilled;
}
- const originalSpace = await getConsumedSpace(token.collection.helper.api, token.collectionId, token.tokenId, pieces == 1n ? 'NFT' : 'RFT');
+ const originalSpace = await getConsumedSpace(token.collection.helper.getApi(), token.collectionId, token.tokenId, pieces == 1n ? 'NFT' : 'RFT');
return originalSpace;
}
@@ -840,7 +840,7 @@
).to.be.rejectedWith(/common\.NoPermission/);
}
- const consumedSpace = await getConsumedSpace(token.collection.helper.api, token.collectionId, token.tokenId, pieces == 1n ? 'NFT' : 'RFT');
+ const consumedSpace = await getConsumedSpace(token.collection.helper.getApi(), token.collectionId, token.tokenId, pieces == 1n ? 'NFT' : 'RFT');
expect(consumedSpace).to.be.equal(originalSpace);
}
@@ -875,7 +875,7 @@
).to.be.rejectedWith(/common\.NoPermission/);
}
- const consumedSpace = await getConsumedSpace(token.collection.helper.api, token.collectionId, token.tokenId, pieces == 1n ? 'NFT' : 'RFT');
+ const consumedSpace = await getConsumedSpace(token.collection.helper.getApi(), token.collectionId, token.tokenId, pieces == 1n ? 'NFT' : 'RFT');
expect(consumedSpace).to.be.equal(originalSpace);
}
@@ -911,7 +911,7 @@
expect(await token.getProperties(['non-existent', 'now-existent'])).to.be.empty;
- const consumedSpace = await getConsumedSpace(token.collection.helper.api, token.collectionId, token.tokenId, pieces == 1n ? 'NFT' : 'RFT');
+ const consumedSpace = await getConsumedSpace(token.collection.helper.getApi(), token.collectionId, token.tokenId, pieces == 1n ? 'NFT' : 'RFT');
expect(consumedSpace).to.be.equal(originalSpace);
}
@@ -951,7 +951,7 @@
])).to.be.rejectedWith(/common\.NoSpaceForProperty/);
expect(await token.getProperties(['a_holy_book', 'young_years'])).to.be.empty;
- const consumedSpace = await getConsumedSpace(token.collection.helper.api, token.collectionId, token.tokenId, pieces == 1n ? 'NFT' : 'RFT');
+ const consumedSpace = await getConsumedSpace(token.collection.helper.getApi(), token.collectionId, token.tokenId, pieces == 1n ? 'NFT' : 'RFT');
expect(consumedSpace).to.be.equal(originalSpace);
}
tests/src/pallet-presence.test.tsdiffbeforeafterboth--- a/tests/src/pallet-presence.test.ts
+++ b/tests/src/pallet-presence.test.ts
@@ -59,7 +59,7 @@
describe('Pallet presence', () => {
before(async () => {
await usingPlaygrounds(async helper => {
- const chain = await helper.api!.rpc.system.chain();
+ const chain = await helper.callRpc('api.rpc.system.chain', []);
const refungible = 'refungible';
const scheduler = 'scheduler';
tests/src/tx-version-presence.test.tsdiffbeforeafterboth--- a/tests/src/tx-version-presence.test.ts
+++ b/tests/src/tx-version-presence.test.ts
@@ -22,7 +22,7 @@
describe('TxVersion is present', () => {
before(async () => {
await usingPlaygrounds(async helper => {
- metadata = await helper.api!.rpc.state.getMetadata();
+ metadata = await helper.callRpc('api.rpc.state.getMetadata', []);
});
});
tests/src/util/playgrounds/unique.dev.tsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// SPDX-License-Identifier: Apache-2.034import {mnemonicGenerate} from '@polkadot/util-crypto';5import {UniqueHelper} from './unique';6import {ApiPromise, WsProvider} from '@polkadot/api';7import * as defs from '../../interfaces/definitions';8import {IKeyringPair} from '@polkadot/types/types';9import {ICrossAccountId} from './types';101112export class SilentLogger {13 log(_msg: any, _level: any): void { }14 level = {15 ERROR: 'ERROR' as const,16 WARNING: 'WARNING' as const,17 INFO: 'INFO' as const,18 };19}2021export class SilentConsole {22 // TODO: Remove, this is temporary: Filter unneeded API output23 // (Jaco promised it will be removed in the next version)24 consoleErr: any;25 consoleLog: any;26 consoleWarn: any;2728 constructor() {29 this.consoleErr = console.error;30 this.consoleLog = console.log;31 this.consoleWarn = console.warn;32 }3334 enable() { 35 const outFn = (printer: any) => (...args: any[]) => {36 for (const arg of args) {37 if (typeof arg !== 'string')38 continue;39 if (arg.includes('1000:: Normal connection closure') || arg.includes('Not decorating unknown runtime apis:') || arg.includes('RPC methods not decorated:') || arg === 'Normal connection closure')40 return;41 }42 printer(...args);43 };44 45 console.error = outFn(this.consoleErr.bind(console));46 console.log = outFn(this.consoleLog.bind(console));47 console.warn = outFn(this.consoleWarn.bind(console));48 }4950 disable() {51 console.error = this.consoleErr;52 console.log = this.consoleLog;53 console.warn = this.consoleWarn;54 }55}565758export class DevUniqueHelper extends UniqueHelper {59 /**60 * Arrange methods for tests61 */62 arrange: ArrangeGroup;63 wait: WaitGroup;64 admin: AdminGroup;6566 constructor(logger: { log: (msg: any, level: any) => void, level: any }) {67 super(logger);68 this.arrange = new ArrangeGroup(this);69 this.wait = new WaitGroup(this);70 this.admin = new AdminGroup(this);71 }7273 async connect(wsEndpoint: string, _listeners?: any): Promise<void> {74 const wsProvider = new WsProvider(wsEndpoint);75 this.api = new ApiPromise({76 provider: wsProvider,77 signedExtensions: {78 ContractHelpers: {79 extrinsic: {},80 payload: {},81 },82 FakeTransactionFinalizer: {83 extrinsic: {},84 payload: {},85 },86 },87 rpc: {88 unique: defs.unique.rpc,89 appPromotion: defs.appPromotion.rpc,90 rmrk: defs.rmrk.rpc,91 eth: {92 feeHistory: {93 description: 'Dummy',94 params: [],95 type: 'u8',96 },97 maxPriorityFeePerGas: {98 description: 'Dummy',99 params: [],100 type: 'u8',101 },102 },103 },104 });105 await this.api.isReadyOrError;106 this.network = await UniqueHelper.detectNetwork(this.api);107 }108}109110class ArrangeGroup {111 helper: UniqueHelper;112113 constructor(helper: UniqueHelper) {114 this.helper = helper;115 }116117 /**118 * Generates accounts with the specified UNQ token balance 119 * @param balances balances for generated accounts. Each balance will be multiplied by the token nominal.120 * @param donor donor account for balances121 * @returns array of newly created accounts122 * @example const [acc1, acc2, acc3] = await createAccounts([0n, 10n, 20n], donor); 123 */124 createAccounts = async (balances: bigint[], donor: IKeyringPair): Promise<IKeyringPair[]> => {125 let nonce = await this.helper.chain.getNonce(donor.address);126 const wait = new WaitGroup(this.helper);127 const ss58Format = this.helper.chain.getChainProperties().ss58Format;128 const tokenNominal = this.helper.balance.getOneTokenNominal();129 const transactions = [];130 const accounts: IKeyringPair[] = [];131 for (const balance of balances) {132 const recipient = this.helper.util.fromSeed(mnemonicGenerate(), ss58Format);133 accounts.push(recipient);134 if (balance !== 0n) {135 const tx = this.helper.constructApiCall('api.tx.balances.transfer', [{Id: recipient.address}, balance * tokenNominal]);136 transactions.push(this.helper.signTransaction(donor, tx, {nonce}, 'account generation'));137 nonce++;138 }139 }140141 await Promise.all(transactions).catch(_e => {});142 143 //#region TODO remove this region, when nonce problem will be solved144 const checkBalances = async () => {145 let isSuccess = true;146 for (let i = 0; i < balances.length; i++) {147 const balance = await this.helper.balance.getSubstrate(accounts[i].address);148 if (balance !== balances[i] * tokenNominal) {149 isSuccess = false;150 break;151 }152 }153 return isSuccess;154 };155156 let accountsCreated = false;157 // checkBalances retry up to 5 blocks158 for (let index = 0; index < 5; index++) {159 accountsCreated = await checkBalances();160 if(accountsCreated) break;161 await wait.newBlocks(1);162 }163164 if (!accountsCreated) throw Error('Accounts generation failed');165 //#endregion166167 return accounts;168 };169170 // TODO combine this method and createAccounts into one171 createCrowd = async (accountsToCreate: number, withBalance: bigint, donor: IKeyringPair): Promise<IKeyringPair[]> => { 172 const createAsManyAsCan = async () => {173 let transactions: any = [];174 const accounts: IKeyringPair[] = [];175 let nonce = await this.helper.chain.getNonce(donor.address);176 const tokenNominal = this.helper.balance.getOneTokenNominal();177 for (let i = 0; i < accountsToCreate; i++) {178 if (i === 500) { // if there are too many accounts to create179 await Promise.allSettled(transactions); // wait while first 500 (should be 100 for devnode) tx will be settled 180 transactions = []; //181 nonce = await this.helper.chain.getNonce(donor.address); // update nonce 182 }183 const recepient = this.helper.util.fromSeed(mnemonicGenerate());184 accounts.push(recepient);185 if (withBalance !== 0n) {186 const tx = this.helper.constructApiCall('api.tx.balances.transfer', [{Id: recepient.address}, withBalance * tokenNominal]);187 transactions.push(this.helper.signTransaction(donor, tx, {nonce}, 'account generation'));188 nonce++;189 }190 }191 192 const fullfilledAccounts = [];193 await Promise.allSettled(transactions);194 for (const account of accounts) {195 const accountBalance = await this.helper.balance.getSubstrate(account.address);196 if (accountBalance === withBalance * tokenNominal) {197 fullfilledAccounts.push(account);198 }199 }200 return fullfilledAccounts;201 };202203 204 const crowd: IKeyringPair[] = [];205 // do up to 5 retries206 for (let index = 0; index < 5 && accountsToCreate !== 0; index++) {207 const asManyAsCan = await createAsManyAsCan();208 crowd.push(...asManyAsCan);209 accountsToCreate -= asManyAsCan.length;210 }211212 if (accountsToCreate !== 0) throw Error(`Crowd generation failed: ${accountsToCreate} accounts left`);213214 return crowd;215 };216217 isDevNode = async () => {218 const block1 = await this.helper.api?.rpc.chain.getBlock(await this.helper.api?.rpc.chain.getBlockHash(1));219 const block2 = await this.helper.api?.rpc.chain.getBlock(await this.helper.api?.rpc.chain.getBlockHash(2));220 const findCreationDate = async (block: any) => {221 const humanBlock = block.toHuman();222 let date;223 humanBlock.block.extrinsics.forEach((ext: any) => {224 if(ext.method.section === 'timestamp') {225 date = Number(ext.method.args.now.replaceAll(',', ''));226 }227 });228 return date;229 };230 const block1date = await findCreationDate(block1);231 const block2date = await findCreationDate(block2);232 if(block2date! - block1date! < 9000) return true;233 };234 235 async calculcateFee(payer: ICrossAccountId, promise: () => Promise<any>): Promise<bigint> {236 const address = payer.Substrate ? payer.Substrate : await this.helper.address.ethToSubstrate(payer.Ethereum!);237 let balance = await this.helper.balance.getSubstrate(address); 238 239 await promise();240 241 balance -= await this.helper.balance.getSubstrate(address);242 243 return balance;244 }245}246247class WaitGroup {248 helper: UniqueHelper;249250 constructor(helper: UniqueHelper) {251 this.helper = helper;252 }253254 /**255 * Wait for specified bnumber of blocks256 * @param blocksCount number of blocks to wait257 * @returns 258 */259 async newBlocks(blocksCount = 1): Promise<void> {260 // eslint-disable-next-line no-async-promise-executor261 const promise = new Promise<void>(async (resolve) => {262 const unsubscribe = await this.helper.api!.rpc.chain.subscribeNewHeads(() => {263 if (blocksCount > 0) {264 blocksCount--;265 } else {266 unsubscribe();267 resolve();268 }269 });270 });271 return promise;272 }273274 async forParachainBlockNumber(blockNumber: bigint) {275 // eslint-disable-next-line no-async-promise-executor276 return new Promise<void>(async (resolve) => {277 const unsubscribe = await this.helper.api!.rpc.chain.subscribeNewHeads(async (data: any) => {278 if (data.number.toNumber() >= blockNumber) {279 unsubscribe();280 resolve();281 }282 });283 });284 }285 286 async forRelayBlockNumber(blockNumber: bigint) {287 // eslint-disable-next-line no-async-promise-executor288 return new Promise<void>(async (resolve) => {289 const unsubscribe = await this.helper.api!.query.parachainSystem.validationData(async (data: any) => {290 if (data.value.relayParentNumber.toNumber() >= blockNumber) {291 // @ts-ignore292 unsubscribe();293 resolve();294 }295 });296 });297 }298}299300class AdminGroup {301 helper: UniqueHelper;302303 constructor(helper: UniqueHelper) {304 this.helper = helper;305 }306307 async payoutStakers(signer: IKeyringPair, stakersToPayout: number) {308 const payoutResult = await this.helper.executeExtrinsic(signer, 'api.tx.appPromotion.payoutStakers', [stakersToPayout], true);309 return payoutResult.result.events.filter(e => e.event.method === 'StakingRecalculation').map(e => {310 return {311 staker: e.event.data[0].toString(),312 stake: e.event.data[1].toBigInt(),313 payout: e.event.data[2].toBigInt(),314 };315 });316 }317}1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// SPDX-License-Identifier: Apache-2.034import {mnemonicGenerate} from '@polkadot/util-crypto';5import {UniqueHelper} from './unique';6import {ApiPromise, WsProvider} from '@polkadot/api';7import * as defs from '../../interfaces/definitions';8import {IKeyringPair} from '@polkadot/types/types';9import {ICrossAccountId} from './types';101112export class SilentLogger {13 log(_msg: any, _level: any): void { }14 level = {15 ERROR: 'ERROR' as const,16 WARNING: 'WARNING' as const,17 INFO: 'INFO' as const,18 };19}2021export class SilentConsole {22 // TODO: Remove, this is temporary: Filter unneeded API output23 // (Jaco promised it will be removed in the next version)24 consoleErr: any;25 consoleLog: any;26 consoleWarn: any;2728 constructor() {29 this.consoleErr = console.error;30 this.consoleLog = console.log;31 this.consoleWarn = console.warn;32 }3334 enable() { 35 const outFn = (printer: any) => (...args: any[]) => {36 for (const arg of args) {37 if (typeof arg !== 'string')38 continue;39 if (arg.includes('1000:: Normal connection closure') || arg.includes('Not decorating unknown runtime apis:') || arg.includes('RPC methods not decorated:') || arg === 'Normal connection closure')40 return;41 }42 printer(...args);43 };44 45 console.error = outFn(this.consoleErr.bind(console));46 console.log = outFn(this.consoleLog.bind(console));47 console.warn = outFn(this.consoleWarn.bind(console));48 }4950 disable() {51 console.error = this.consoleErr;52 console.log = this.consoleLog;53 console.warn = this.consoleWarn;54 }55}565758export class DevUniqueHelper extends UniqueHelper {59 /**60 * Arrange methods for tests61 */62 arrange: ArrangeGroup;63 wait: WaitGroup;64 admin: AdminGroup;6566 constructor(logger: { log: (msg: any, level: any) => void, level: any }) {67 super(logger);68 this.arrange = new ArrangeGroup(this);69 this.wait = new WaitGroup(this);70 this.admin = new AdminGroup(this);71 }7273 async connect(wsEndpoint: string, _listeners?: any): Promise<void> {74 const wsProvider = new WsProvider(wsEndpoint);75 this.api = new ApiPromise({76 provider: wsProvider,77 signedExtensions: {78 ContractHelpers: {79 extrinsic: {},80 payload: {},81 },82 FakeTransactionFinalizer: {83 extrinsic: {},84 payload: {},85 },86 },87 rpc: {88 unique: defs.unique.rpc,89 appPromotion: defs.appPromotion.rpc,90 rmrk: defs.rmrk.rpc,91 eth: {92 feeHistory: {93 description: 'Dummy',94 params: [],95 type: 'u8',96 },97 maxPriorityFeePerGas: {98 description: 'Dummy',99 params: [],100 type: 'u8',101 },102 },103 },104 });105 await this.api.isReadyOrError;106 this.network = await UniqueHelper.detectNetwork(this.api);107 }108}109110class ArrangeGroup {111 helper: UniqueHelper;112113 constructor(helper: UniqueHelper) {114 this.helper = helper;115 }116117 /**118 * Generates accounts with the specified UNQ token balance 119 * @param balances balances for generated accounts. Each balance will be multiplied by the token nominal.120 * @param donor donor account for balances121 * @returns array of newly created accounts122 * @example const [acc1, acc2, acc3] = await createAccounts([0n, 10n, 20n], donor); 123 */124 createAccounts = async (balances: bigint[], donor: IKeyringPair): Promise<IKeyringPair[]> => {125 let nonce = await this.helper.chain.getNonce(donor.address);126 const wait = new WaitGroup(this.helper);127 const ss58Format = this.helper.chain.getChainProperties().ss58Format;128 const tokenNominal = this.helper.balance.getOneTokenNominal();129 const transactions = [];130 const accounts: IKeyringPair[] = [];131 for (const balance of balances) {132 const recipient = this.helper.util.fromSeed(mnemonicGenerate(), ss58Format);133 accounts.push(recipient);134 if (balance !== 0n) {135 const tx = this.helper.constructApiCall('api.tx.balances.transfer', [{Id: recipient.address}, balance * tokenNominal]);136 transactions.push(this.helper.signTransaction(donor, tx, {nonce}, 'account generation'));137 nonce++;138 }139 }140141 await Promise.all(transactions).catch(_e => {});142 143 //#region TODO remove this region, when nonce problem will be solved144 const checkBalances = async () => {145 let isSuccess = true;146 for (let i = 0; i < balances.length; i++) {147 const balance = await this.helper.balance.getSubstrate(accounts[i].address);148 if (balance !== balances[i] * tokenNominal) {149 isSuccess = false;150 break;151 }152 }153 return isSuccess;154 };155156 let accountsCreated = false;157 // checkBalances retry up to 5 blocks158 for (let index = 0; index < 5; index++) {159 accountsCreated = await checkBalances();160 if(accountsCreated) break;161 await wait.newBlocks(1);162 }163164 if (!accountsCreated) throw Error('Accounts generation failed');165 //#endregion166167 return accounts;168 };169170 // TODO combine this method and createAccounts into one171 createCrowd = async (accountsToCreate: number, withBalance: bigint, donor: IKeyringPair): Promise<IKeyringPair[]> => { 172 const createAsManyAsCan = async () => {173 let transactions: any = [];174 const accounts: IKeyringPair[] = [];175 let nonce = await this.helper.chain.getNonce(donor.address);176 const tokenNominal = this.helper.balance.getOneTokenNominal();177 for (let i = 0; i < accountsToCreate; i++) {178 if (i === 500) { // if there are too many accounts to create179 await Promise.allSettled(transactions); // wait while first 500 (should be 100 for devnode) tx will be settled 180 transactions = []; //181 nonce = await this.helper.chain.getNonce(donor.address); // update nonce 182 }183 const recepient = this.helper.util.fromSeed(mnemonicGenerate());184 accounts.push(recepient);185 if (withBalance !== 0n) {186 const tx = this.helper.constructApiCall('api.tx.balances.transfer', [{Id: recepient.address}, withBalance * tokenNominal]);187 transactions.push(this.helper.signTransaction(donor, tx, {nonce}, 'account generation'));188 nonce++;189 }190 }191 192 const fullfilledAccounts = [];193 await Promise.allSettled(transactions);194 for (const account of accounts) {195 const accountBalance = await this.helper.balance.getSubstrate(account.address);196 if (accountBalance === withBalance * tokenNominal) {197 fullfilledAccounts.push(account);198 }199 }200 return fullfilledAccounts;201 };202203 204 const crowd: IKeyringPair[] = [];205 // do up to 5 retries206 for (let index = 0; index < 5 && accountsToCreate !== 0; index++) {207 const asManyAsCan = await createAsManyAsCan();208 crowd.push(...asManyAsCan);209 accountsToCreate -= asManyAsCan.length;210 }211212 if (accountsToCreate !== 0) throw Error(`Crowd generation failed: ${accountsToCreate} accounts left`);213214 return crowd;215 };216217 isDevNode = async () => {218 const block1 = await this.helper.callRpc('api.rpc.chain.getBlock', [await this.helper.callRpc('api.rpc.chain.getBlockHash', [1])]);219 const block2 = await this.helper.callRpc('api.rpc.chain.getBlock', [await this.helper.callRpc('api.rpc.chain.getBlockHash', [2])]);220 const findCreationDate = async (block: any) => {221 const humanBlock = block.toHuman();222 let date;223 humanBlock.block.extrinsics.forEach((ext: any) => {224 if(ext.method.section === 'timestamp') {225 date = Number(ext.method.args.now.replaceAll(',', ''));226 }227 });228 return date;229 };230 const block1date = await findCreationDate(block1);231 const block2date = await findCreationDate(block2);232 if(block2date! - block1date! < 9000) return true;233 };234 235 async calculcateFee(payer: ICrossAccountId, promise: () => Promise<any>): Promise<bigint> {236 const address = payer.Substrate ? payer.Substrate : await this.helper.address.ethToSubstrate(payer.Ethereum!);237 let balance = await this.helper.balance.getSubstrate(address); 238 239 await promise();240 241 balance -= await this.helper.balance.getSubstrate(address);242 243 return balance;244 }245}246247class WaitGroup {248 helper: UniqueHelper;249250 constructor(helper: UniqueHelper) {251 this.helper = helper;252 }253254 /**255 * Wait for specified bnumber of blocks256 * @param blocksCount number of blocks to wait257 * @returns 258 */259 async newBlocks(blocksCount = 1): Promise<void> {260 // eslint-disable-next-line no-async-promise-executor261 const promise = new Promise<void>(async (resolve) => {262 const unsubscribe = await this.helper.getApi().rpc.chain.subscribeNewHeads(() => {263 if (blocksCount > 0) {264 blocksCount--;265 } else {266 unsubscribe();267 resolve();268 }269 });270 });271 return promise;272 }273274 async forParachainBlockNumber(blockNumber: bigint) {275 // eslint-disable-next-line no-async-promise-executor276 return new Promise<void>(async (resolve) => {277 const unsubscribe = await this.helper.getApi().rpc.chain.subscribeNewHeads(async (data: any) => {278 if (data.number.toNumber() >= blockNumber) {279 unsubscribe();280 resolve();281 }282 });283 });284 }285 286 async forRelayBlockNumber(blockNumber: bigint) {287 // eslint-disable-next-line no-async-promise-executor288 return new Promise<void>(async (resolve) => {289 const unsubscribe = await this.helper.getApi().query.parachainSystem.validationData(async (data: any) => {290 if (data.value.relayParentNumber.toNumber() >= blockNumber) {291 // @ts-ignore292 unsubscribe();293 resolve();294 }295 });296 });297 }298}299300class AdminGroup {301 helper: UniqueHelper;302303 constructor(helper: UniqueHelper) {304 this.helper = helper;305 }306307 async payoutStakers(signer: IKeyringPair, stakersToPayout: number) {308 const payoutResult = await this.helper.executeExtrinsic(signer, 'api.tx.appPromotion.payoutStakers', [stakersToPayout], true);309 return payoutResult.result.events.filter(e => e.event.method === 'StakingRecalculation').map(e => {310 return {311 staker: e.event.data[0].toString(),312 stake: e.event.data[1].toBigInt(),313 payout: e.event.data[2].toBigInt(),314 };315 });316 }317}tests/src/util/playgrounds/unique.tsdiffbeforeafterboth--- a/tests/src/util/playgrounds/unique.ts
+++ b/tests/src/util/playgrounds/unique.ts
@@ -1991,7 +1991,7 @@
* @returns ss58Format, token decimals, and token symbol
*/
getChainProperties(): IChainProperties {
- const properties = (this.helper.api as any).registry.getChainProperties().toJSON();
+ const properties = (this.helper.getApi() as any).registry.getChainProperties().toJSON();
return {
ss58Format: properties.ss58Format.toJSON(),
tokenDecimals: properties.tokenDecimals.toJSON(),
@@ -2034,7 +2034,7 @@
* @returns number, account's nonce
*/
async getNonce(address: TSubstrateAccount): Promise<number> {
- return (await (this.helper.api as any).query.system.account(address)).nonce.toNumber();
+ return (await this.helper.callRpc('api.query.system.account', [address])).nonce.toNumber();
}
}