difftreelog
feat add nested ops - scheduled and sudo
in: master
5 files changed
tests/src/eth/util/playgrounds/index.tsdiffbeforeafterboth--- a/tests/src/eth/util/playgrounds/index.ts
+++ b/tests/src/eth/util/playgrounds/index.ts
@@ -39,7 +39,6 @@
}
finally {
await helper.disconnect();
- await helper.disconnectWeb3();
silentConsole.disable();
}
};
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
@@ -321,6 +321,7 @@
}
}
+export type EthUniqueHelperConstructor = new (...args: any[]) => EthUniqueHelper;
export class EthUniqueHelper extends DevUniqueHelper {
web3: Web3 | null = null;
@@ -331,8 +332,10 @@
ethNativeContract: NativeContractGroup;
ethContract: ContractGroup;
- constructor(logger: { log: (msg: any, level: any) => void, level: any }) {
- super(logger);
+ constructor(logger: { log: (msg: any, level: any) => void, level: any }, options: {[key: string]: any} = {}) {
+ options.helperBase = options.helperBase ?? EthUniqueHelper;
+
+ super(logger, options);
this.eth = new EthGroup(this);
this.ethAddress = new EthAddressGroup(this);
this.ethNativeContract = new NativeContractGroup(this);
@@ -350,10 +353,23 @@
this.web3 = new Web3(this.web3Provider);
}
- async disconnectWeb3() {
+ async disconnect() {
if(this.web3 === null) return;
this.web3Provider?.connection.close();
+
+ await super.disconnect();
+ }
+
+ clearApi() {
this.web3 = null;
}
+
+ clone(helperCls: EthUniqueHelperConstructor, options?: { [key: string]: any; }): EthUniqueHelper {
+ const newHelper = super.clone(helperCls, options) as EthUniqueHelper;
+ newHelper.web3 = this.web3;
+ newHelper.web3Provider = this.web3Provider;
+
+ return newHelper;
+ }
}
\ No newline at end of file
tests/src/util/playgrounds/types.tsdiffbeforeafterboth--- a/tests/src/util/playgrounds/types.ts
+++ b/tests/src/util/playgrounds/types.ts
@@ -164,6 +164,14 @@
amount: bigint,
}
+export interface ISchedulerOptions {
+ priority?: number,
+ periodic?: {
+ period: number,
+ repetitions: number,
+ },
+}
+
export type TSubstrateAccount = string;
export type TEthereumAccount = string;
export type TApiAllowedListeners = 'connected' | 'disconnected' | 'error' | 'ready' | 'decorated';
tests/src/util/playgrounds/unique.dev.tsdiffbeforeafterboth--- a/tests/src/util/playgrounds/unique.dev.ts
+++ b/tests/src/util/playgrounds/unique.dev.ts
@@ -7,6 +7,9 @@
import * as defs from '../../interfaces/definitions';
import {IKeyringPair} from '@polkadot/types/types';
import {ICrossAccountId} from './types';
+import type {EventRecord} from '@polkadot/types/interfaces';
+import {VoidFn} from '@polkadot/api/types';
+import {FrameSystemEventRecord} from '@polkadot/types/lookup';
export class SilentLogger {
@@ -63,8 +66,10 @@
wait: WaitGroup;
admin: AdminGroup;
- constructor(logger: { log: (msg: any, level: any) => void, level: any }) {
- super(logger);
+ constructor(logger: { log: (msg: any, level: any) => void, level: any }, options: {[key: string]: any} = {}) {
+ options.helperBase = options.helperBase ?? DevUniqueHelper;
+
+ super(logger, options);
this.arrange = new ArrangeGroup(this);
this.wait = new WaitGroup(this);
this.admin = new AdminGroup(this);
@@ -108,9 +113,9 @@
}
class ArrangeGroup {
- helper: UniqueHelper;
+ helper: DevUniqueHelper;
- constructor(helper: UniqueHelper) {
+ constructor(helper: DevUniqueHelper) {
this.helper = helper;
}
@@ -245,14 +250,14 @@
}
class WaitGroup {
- helper: UniqueHelper;
+ helper: DevUniqueHelper;
- constructor(helper: UniqueHelper) {
+ constructor(helper: DevUniqueHelper) {
this.helper = helper;
}
/**
- * Wait for specified bnumber of blocks
+ * Wait for specified number of blocks
* @param blocksCount number of blocks to wait
* @returns
*/
tests/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, IToken, ITokenPropertyPermission, ITransactionResult, IUniqueHelperLog, TApiAllowedListeners, TEthereumAccount, TSigner, TSubstrateAccount, TUniqueNetworks} from './types';12import {IApiListeners, IBlock, IEvent, IChainProperties, ICollectionCreationOptions, ICollectionLimits, ICollectionPermissions, ICrossAccountId, ICrossAccountIdLower, ILogger, INestingPermissions, IProperty, IStakingInfo, ISchedulerOptions, ISubstrateBalance, IToken, ITokenPropertyPermission, ITransactionResult, IUniqueHelperLog, TApiAllowedListeners, TEthereumAccount, TSigner, TSubstrateAccount, TUniqueNetworks} from './types';13import {RuntimeDispatchInfo} from '@polkadot/types/interfaces';131414export class CrossAccountId implements ICrossAccountId {15export class CrossAccountId implements ICrossAccountId {15 Substrate?: TSubstrateAccount;16 Substrate?: TSubstrateAccount;318 forcedNetwork: TUniqueNetworks | null;319 forcedNetwork: TUniqueNetworks | null;319 network: TUniqueNetworks | null;320 network: TUniqueNetworks | null;320 chainLog: IUniqueHelperLog[];321 chainLog: IUniqueHelperLog[];322 children: ChainHelperBase[];321323322 constructor(logger?: ILogger) {324 constructor(logger?: ILogger) {323 this.util = UniqueUtil;325 this.util = UniqueUtil;328 this.forcedNetwork = null;330 this.forcedNetwork = null;329 this.network = null;331 this.network = null;330 this.chainLog = [];332 this.chainLog = [];333 this.children = [];331 }334 }332335333 getApi(): ApiPromise {336 getApi(): ApiPromise {351 }354 }352355353 async disconnect() {356 async disconnect() {357 for (const child of this.children) {358 child.clearApi();359 }360354 if (this.api === null) return;361 if (this.api === null) return;355 await this.api.disconnect();362 await this.api.disconnect();356 this.api = null;363 this.clearApi();357 this.network = null;358 }364 }365366 clearApi() {367 this.api = null;368 this.network = null;369 }359370360 static async detectNetwork(api: ApiPromise): Promise<TUniqueNetworks> {371 static async detectNetwork(api: ApiPromise): Promise<TUniqueNetworks> {361 const spec = (await api.query.system.lastRuntimeUpgrade()).toJSON() as any;372 const spec = (await api.query.system.lastRuntimeUpgrade()).toJSON() as any;479490480 constructApiCall(apiCall: string, params: any[]) {491 constructApiCall(apiCall: string, params: any[]) {481 if(!apiCall.startsWith('api.')) throw Error(`Invalid api call: ${apiCall}`);492 if(!apiCall.startsWith('api.')) throw Error(`Invalid api call: ${apiCall}`);482 let call = this.api as any;493 let call = this.getApi() as any;483 for(const part of apiCall.slice(4).split('.')) {494 for(const part of apiCall.slice(4).split('.')) {484 call = call[part];495 call = call[part];485 }496 }2248 }2259 }2249}2260}22612262class SchedulerGroup extends HelperGroup {2263 constructor(helper: UniqueHelper) {2264 super(helper);2265 }22662267 async cancelScheduled(signer: TSigner, scheduledId: string) {2268 return this.helper.executeExtrinsic(2269 signer,2270 'api.tx.scheduler.cancelNamed',2271 [scheduledId],2272 true,2273 );2274 }22752276 async changePriority(signer: TSigner, scheduledId: string, priority: number) {2277 return this.helper.executeExtrinsic(2278 signer,2279 'api.tx.scheduler.changeNamedPriority',2280 [scheduledId, priority],2281 true,2282 );2283 }22842285 scheduleAt<T extends UniqueHelper>(2286 scheduledId: string,2287 executionBlockNumber: number,2288 options: ISchedulerOptions = {},2289 ) {2290 return this.schedule<T>('scheduleNamed', scheduledId, executionBlockNumber, options);2291 }22922293 scheduleAfter<T extends UniqueHelper>(2294 scheduledId: string,2295 blocksBeforeExecution: number,2296 options: ISchedulerOptions = {},2297 ) {2298 return this.schedule<T>('scheduleNamedAfter', scheduledId, blocksBeforeExecution, options);2299 }23002301 schedule<T extends UniqueHelper>(2302 scheduleFn: 'scheduleNamed' | 'scheduleNamedAfter',2303 scheduledId: string,2304 blocksNum: number,2305 options: ISchedulerOptions = {},2306 ) {2307 // eslint-disable-next-line @typescript-eslint/naming-convention2308 const ScheduledHelperType = ScheduledUniqueHelper(this.helper.helperBase);2309 return this.helper.clone(ScheduledHelperType, {2310 scheduleFn,2311 scheduledId,2312 blocksNum,2313 options,2314 }) as T;2315 }2316}23172318export type UniqueHelperConstructor = new(...args: any[]) => UniqueHelper;225023192251export class UniqueHelper extends ChainHelperBase {2320export class UniqueHelper extends ChainHelperBase {2321 helperBase: any;23222252 chain: ChainGroup;2323 chain: ChainGroup;2253 balance: BalanceGroup;2324 balance: BalanceGroup;2257 rft: RFTGroup;2328 rft: RFTGroup;2258 ft: FTGroup;2329 ft: FTGroup;2259 staking: StakingGroup;2330 staking: StakingGroup;2331 scheduler: SchedulerGroup;226023322261 constructor(logger?: ILogger) {2333 constructor(logger?: ILogger, options: {[key: string]: any} = {}) {2262 super(logger);2334 super(logger);23352336 this.helperBase = options.helperBase ?? UniqueHelper;23372263 this.chain = new ChainGroup(this);2338 this.chain = new ChainGroup(this);2264 this.balance = new BalanceGroup(this);2339 this.balance = new BalanceGroup(this);2268 this.rft = new RFTGroup(this);2343 this.rft = new RFTGroup(this);2269 this.ft = new FTGroup(this);2344 this.ft = new FTGroup(this);2270 this.staking = new StakingGroup(this);2345 this.staking = new StakingGroup(this);2346 this.scheduler = new SchedulerGroup(this);2271 }2347 }23482349 clone(helperCls: UniqueHelperConstructor, options: {[key: string]: any} = {}) {2350 Object.setPrototypeOf(helperCls.prototype, this);2351 const newHelper = new helperCls(this.logger, options);23522353 newHelper.api = this.api;2354 newHelper.network = this.network;2355 newHelper.forceNetwork = this.forceNetwork;23562357 this.children.push(newHelper);23582359 return newHelper;2360 }23612362 getSudo<T extends UniqueHelper>() {2363 // eslint-disable-next-line @typescript-eslint/naming-convention2364 const SudoHelperType = SudoUniqueHelper(this.helperBase);2365 return this.clone(SudoHelperType) as T;2366 }2272}2367}227323682369// eslint-disable-next-line @typescript-eslint/naming-convention2370function ScheduledUniqueHelper<T extends UniqueHelperConstructor>(Base: T) {2371 return class extends Base {2372 scheduleFn: 'scheduleNamed' | 'scheduleNamedAfter';2373 scheduledId: string;2374 blocksNum: number;2375 options: ISchedulerOptions;23762377 constructor(...args: any[]) {2378 const logger = args[0] as ILogger;2379 const options = args[1] as {2380 scheduleFn: 'scheduleNamed' | 'scheduleNamedAfter',2381 scheduledId: string,2382 blocksNum: number,2383 options: ISchedulerOptions2384 };23852386 super(logger);23872388 this.scheduleFn = options.scheduleFn;2389 this.scheduledId = options.scheduledId;2390 this.blocksNum = options.blocksNum;2391 this.options = options.options;2392 }23932394 executeExtrinsic(sender: IKeyringPair, scheduledExtrinsic: string, scheduledParams: any[], expectSuccess?: boolean): Promise<ITransactionResult> {2395 const scheduledTx = this.constructApiCall(scheduledExtrinsic, scheduledParams);2396 const extrinsic = 'api.tx.scheduler.' + this.scheduleFn;23972398 return super.executeExtrinsic(2399 sender,2400 extrinsic,2401 [2402 this.scheduledId,2403 this.blocksNum,2404 this.options.periodic ? [this.options.periodic.period, this.options.periodic.repetitions] : null,2405 this.options.priority ?? null,2406 {Value: scheduledTx},2407 ],2408 expectSuccess,2409 );2410 }2411 };2412}24132414// eslint-disable-next-line @typescript-eslint/naming-convention2415function SudoUniqueHelper<T extends UniqueHelperConstructor>(Base: T) {2416 return class extends Base {2417 constructor(...args: any[]) {2418 super(...args);2419 }24202421 executeExtrinsic (2422 sender: IKeyringPair,2423 extrinsic: string,2424 params: any[],2425 expectSuccess?: boolean,2426 ): Promise<ITransactionResult> {2427 const call = this.constructApiCall(extrinsic, params);24282429 return super.executeExtrinsic(2430 sender,2431 'api.tx.sudo.sudo',2432 [call],2433 expectSuccess,2434 );2435 }2436 };2437}227424382275export class UniqueBaseCollection {2439export class UniqueBaseCollection {2276 helper: UniqueHelper;2440 helper: UniqueHelper;2373 return await this.helper.collection.burn(signer, this.collectionId);2537 return await this.helper.collection.burn(signer, this.collectionId);2374 }2538 }25392540 scheduleAt<T extends UniqueHelper>(2541 scheduledId: string,2542 executionBlockNumber: number,2543 options: ISchedulerOptions = {},2544 ) {2545 const scheduledHelper = this.helper.scheduler.scheduleAt<T>(scheduledId, executionBlockNumber, options);2546 return new UniqueBaseCollection(this.collectionId, scheduledHelper);2547 }25482549 scheduleAfter<T extends UniqueHelper>(2550 scheduledId: string,2551 blocksBeforeExecution: number,2552 options: ISchedulerOptions = {},2553 ) {2554 const scheduledHelper = this.helper.scheduler.scheduleAfter<T>(scheduledId, blocksBeforeExecution, options);2555 return new UniqueBaseCollection(this.collectionId, scheduledHelper);2556 }25572558 getSudo<T extends UniqueHelper>() {2559 return new UniqueBaseCollection(this.collectionId, this.helper.getSudo<T>());2560 }2375}2561}23762562237725632460 return await this.helper.nft.unnestToken(signer, {collectionId: this.collectionId, tokenId}, fromTokenObj, toAddressObj);2646 return await this.helper.nft.unnestToken(signer, {collectionId: this.collectionId, tokenId}, fromTokenObj, toAddressObj);2461 }2647 }26482649 scheduleAt<T extends UniqueHelper>(2650 scheduledId: string,2651 executionBlockNumber: number,2652 options: ISchedulerOptions = {},2653 ) {2654 const scheduledHelper = this.helper.scheduler.scheduleAt<T>(scheduledId, executionBlockNumber, options);2655 return new UniqueNFTCollection(this.collectionId, scheduledHelper);2656 }26572658 scheduleAfter<T extends UniqueHelper>(2659 scheduledId: string,2660 blocksBeforeExecution: number,2661 options: ISchedulerOptions = {},2662 ) {2663 const scheduledHelper = this.helper.scheduler.scheduleAfter<T>(scheduledId, blocksBeforeExecution, options);2664 return new UniqueNFTCollection(this.collectionId, scheduledHelper);2665 }26662667 getSudo<T extends UniqueHelper>() {2668 return new UniqueNFTCollection(this.collectionId, this.helper.getSudo<T>());2669 }2462}2670}24632671246426722543 return await this.helper.rft.setTokenPropertyPermissions(signer, this.collectionId, permissions);2751 return await this.helper.rft.setTokenPropertyPermissions(signer, this.collectionId, permissions);2544 }2752 }27532754 scheduleAt<T extends UniqueHelper>(2755 scheduledId: string,2756 executionBlockNumber: number,2757 options: ISchedulerOptions = {},2758 ) {2759 const scheduledHelper = this.helper.scheduler.scheduleAt<T>(scheduledId, executionBlockNumber, options);2760 return new UniqueRFTCollection(this.collectionId, scheduledHelper);2761 }27622763 scheduleAfter<T extends UniqueHelper>(2764 scheduledId: string,2765 blocksBeforeExecution: number,2766 options: ISchedulerOptions = {},2767 ) {2768 const scheduledHelper = this.helper.scheduler.scheduleAfter<T>(scheduledId, blocksBeforeExecution, options);2769 return new UniqueRFTCollection(this.collectionId, scheduledHelper);2770 }27712772 getSudo<T extends UniqueHelper>() {2773 return new UniqueRFTCollection(this.collectionId, this.helper.getSudo<T>());2774 }2545}2775}25462776254727772590 return await this.helper.ft.approveTokens(signer, this.collectionId, toAddressObj, amount);2820 return await this.helper.ft.approveTokens(signer, this.collectionId, toAddressObj, amount);2591 }2821 }28222823 scheduleAt<T extends UniqueHelper>(2824 scheduledId: string,2825 executionBlockNumber: number,2826 options: ISchedulerOptions = {},2827 ) {2828 const scheduledHelper = this.helper.scheduler.scheduleAt<T>(scheduledId, executionBlockNumber, options);2829 return new UniqueFTCollection(this.collectionId, scheduledHelper);2830 }28312832 scheduleAfter<T extends UniqueHelper>(2833 scheduledId: string,2834 blocksBeforeExecution: number,2835 options: ISchedulerOptions = {},2836 ) {2837 const scheduledHelper = this.helper.scheduler.scheduleAfter<T>(scheduledId, blocksBeforeExecution, options);2838 return new UniqueFTCollection(this.collectionId, scheduledHelper);2839 }28402841 getSudo<T extends UniqueHelper>() {2842 return new UniqueFTCollection(this.collectionId, this.helper.getSudo<T>());2843 }2592}2844}25932845259428462627 return this.collection.helper.util.getTokenAccount(this);2879 return this.collection.helper.util.getTokenAccount(this);2628 }2880 }28812882 scheduleAt<T extends UniqueHelper>(2883 scheduledId: string,2884 executionBlockNumber: number,2885 options: ISchedulerOptions = {},2886 ) {2887 const scheduledCollection = this.collection.scheduleAt<T>(scheduledId, executionBlockNumber, options);2888 return new UniqueBaseToken(this.tokenId, scheduledCollection);2889 }28902891 scheduleAfter<T extends UniqueHelper>(2892 scheduledId: string,2893 blocksBeforeExecution: number,2894 options: ISchedulerOptions = {},2895 ) {2896 const scheduledCollection = this.collection.scheduleAfter<T>(scheduledId, blocksBeforeExecution, options);2897 return new UniqueBaseToken(this.tokenId, scheduledCollection);2898 }28992900 getSudo<T extends UniqueHelper>() {2901 return new UniqueBaseToken(this.tokenId, this.collection.getSudo<T>());2902 }2629}2903}26302904263129052685 return await this.collection.burnTokenFrom(signer, this.tokenId, fromAddressObj);2959 return await this.collection.burnTokenFrom(signer, this.tokenId, fromAddressObj);2686 }2960 }29612962 scheduleAt<T extends UniqueHelper>(2963 scheduledId: string,2964 executionBlockNumber: number,2965 options: ISchedulerOptions = {},2966 ) {2967 const scheduledCollection = this.collection.scheduleAt<T>(scheduledId, executionBlockNumber, options);2968 return new UniqueNFToken(this.tokenId, scheduledCollection);2969 }29702971 scheduleAfter<T extends UniqueHelper>(2972 scheduledId: string,2973 blocksBeforeExecution: number,2974 options: ISchedulerOptions = {},2975 ) {2976 const scheduledCollection = this.collection.scheduleAfter<T>(scheduledId, blocksBeforeExecution, options);2977 return new UniqueNFToken(this.tokenId, scheduledCollection);2978 }29792980 getSudo<T extends UniqueHelper>() {2981 return new UniqueNFToken(this.tokenId, this.collection.getSudo<T>());2982 }2687}2983}268829842689export class UniqueRFToken extends UniqueBaseToken {2985export class UniqueRFToken extends UniqueBaseToken {2738 return await this.collection.burnTokenFrom(signer, this.tokenId, fromAddressObj, amount);3034 return await this.collection.burnTokenFrom(signer, this.tokenId, fromAddressObj, amount);2739 }3035 }30363037 scheduleAt<T extends UniqueHelper>(3038 scheduledId: string,3039 executionBlockNumber: number,3040 options: ISchedulerOptions = {},3041 ) {3042 const scheduledCollection = this.collection.scheduleAt<T>(scheduledId, executionBlockNumber, options);3043 return new UniqueRFToken(this.tokenId, scheduledCollection);3044 }30453046 scheduleAfter<T extends UniqueHelper>(3047 scheduledId: string,3048 blocksBeforeExecution: number,3049 options: ISchedulerOptions = {},3050 ) {3051 const scheduledCollection = this.collection.scheduleAfter<T>(scheduledId, blocksBeforeExecution, options);3052 return new UniqueRFToken(this.tokenId, scheduledCollection);3053 }30543055 getSudo<T extends UniqueHelper>() {3056 return new UniqueRFToken(this.tokenId, this.collection.getSudo<T>());3057 }2740}3058}27413059