git.delta.rocks / unique-network / refs/commits / 17a52a581b90

difftreelog

feat add nested ops - scheduled and sudo

Daniel Shiposha2022-10-06parent: #4a02655.patch.diff
in: master

5 files changed

modifiedtests/src/eth/util/playgrounds/index.tsdiffbeforeafterboth
39 }39 }
40 finally {40 finally {
41 await helper.disconnect();41 await helper.disconnect();
42 await helper.disconnectWeb3();
43 silentConsole.disable();42 silentConsole.disable();
44 }43 }
45};44};
modifiedtests/src/eth/util/playgrounds/unique.dev.tsdiffbeforeafterboth
321 }321 }
322} 322}
323 323
324export type EthUniqueHelperConstructor = new (...args: any[]) => EthUniqueHelper;
324325
325export class EthUniqueHelper extends DevUniqueHelper {326export class EthUniqueHelper extends DevUniqueHelper {
326 web3: Web3 | null = null;327 web3: Web3 | null = null;
331 ethNativeContract: NativeContractGroup;332 ethNativeContract: NativeContractGroup;
332 ethContract: ContractGroup;333 ethContract: ContractGroup;
333334
334 constructor(logger: { log: (msg: any, level: any) => void, level: any }) {335 constructor(logger: { log: (msg: any, level: any) => void, level: any }, options: {[key: string]: any} = {}) {
336 options.helperBase = options.helperBase ?? EthUniqueHelper;
337
335 super(logger);338 super(logger, options);
336 this.eth = new EthGroup(this);339 this.eth = new EthGroup(this);
337 this.ethAddress = new EthAddressGroup(this);340 this.ethAddress = new EthAddressGroup(this);
338 this.ethNativeContract = new NativeContractGroup(this);341 this.ethNativeContract = new NativeContractGroup(this);
350 this.web3 = new Web3(this.web3Provider);353 this.web3 = new Web3(this.web3Provider);
351 }354 }
352355
353 async disconnectWeb3() {356 async disconnect() {
354 if(this.web3 === null) return;357 if(this.web3 === null) return;
355 this.web3Provider?.connection.close();358 this.web3Provider?.connection.close();
359
356 this.web3 = null;360 await super.disconnect();
357 }361 }
362
363 clearApi() {
364 this.web3 = null;
365 }
366
367 clone(helperCls: EthUniqueHelperConstructor, options?: { [key: string]: any; }): EthUniqueHelper {
368 const newHelper = super.clone(helperCls, options) as EthUniqueHelper;
369 newHelper.web3 = this.web3;
370 newHelper.web3Provider = this.web3Provider;
371
372 return newHelper;
373 }
358}374}
359 375
modifiedtests/src/util/playgrounds/types.tsdiffbeforeafterboth
164 amount: bigint,164 amount: bigint,
165}165}
166
167export interface ISchedulerOptions {
168 priority?: number,
169 periodic?: {
170 period: number,
171 repetitions: number,
172 },
173}
166174
167export type TSubstrateAccount = string;175export type TSubstrateAccount = string;
168export type TEthereumAccount = string;176export type TEthereumAccount = string;
modifiedtests/src/util/playgrounds/unique.dev.tsdiffbeforeafterboth
7import * as defs from '../../interfaces/definitions';7import * as defs from '../../interfaces/definitions';
8import {IKeyringPair} from '@polkadot/types/types';8import {IKeyringPair} from '@polkadot/types/types';
9import {ICrossAccountId} from './types';9import {ICrossAccountId} from './types';
10import type {EventRecord} from '@polkadot/types/interfaces';
11import {VoidFn} from '@polkadot/api/types';
12import {FrameSystemEventRecord} from '@polkadot/types/lookup';
1013
1114
12export class SilentLogger {15export class SilentLogger {
63 wait: WaitGroup;66 wait: WaitGroup;
64 admin: AdminGroup;67 admin: AdminGroup;
6568
66 constructor(logger: { log: (msg: any, level: any) => void, level: any }) {69 constructor(logger: { log: (msg: any, level: any) => void, level: any }, options: {[key: string]: any} = {}) {
70 options.helperBase = options.helperBase ?? DevUniqueHelper;
71
67 super(logger);72 super(logger, options);
68 this.arrange = new ArrangeGroup(this);73 this.arrange = new ArrangeGroup(this);
69 this.wait = new WaitGroup(this);74 this.wait = new WaitGroup(this);
70 this.admin = new AdminGroup(this);75 this.admin = new AdminGroup(this);
108}113}
109114
110class ArrangeGroup {115class ArrangeGroup {
111 helper: UniqueHelper;116 helper: DevUniqueHelper;
112117
113 constructor(helper: UniqueHelper) {118 constructor(helper: DevUniqueHelper) {
114 this.helper = helper;119 this.helper = helper;
115 }120 }
116121
245}250}
246251
247class WaitGroup {252class WaitGroup {
248 helper: UniqueHelper;253 helper: DevUniqueHelper;
249254
250 constructor(helper: UniqueHelper) {255 constructor(helper: DevUniqueHelper) {
251 this.helper = helper;256 this.helper = helper;
252 }257 }
253258
254 /**259 /**
255 * Wait for specified bnumber of blocks260 * Wait for specified number of blocks
256 * @param blocksCount number of blocks to wait261 * @param blocksCount number of blocks to wait
257 * @returns 262 * @returns
258 */263 */
259 async newBlocks(blocksCount = 1): Promise<void> {264 async newBlocks(blocksCount = 1): Promise<void> {
260 // eslint-disable-next-line no-async-promise-executor265 // eslint-disable-next-line no-async-promise-executor
261 const promise = new Promise<void>(async (resolve) => {266 const promise = new Promise<void>(async (resolve) => {
modifiedtests/src/util/playgrounds/unique.tsdiffbeforeafterboth
9import {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';
1314
14export 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[];
321323
322 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 }
332335
333 getApi(): ApiPromise {336 getApi(): ApiPromise {
351 }354 }
352355
353 async disconnect() {356 async disconnect() {
357 for (const child of this.children) {
358 child.clearApi();
359 }
360
354 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 }
365
366 clearApi() {
367 this.api = null;
368 this.network = null;
369 }
359370
360 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;
479490
480 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}
2261
2262class SchedulerGroup extends HelperGroup {
2263 constructor(helper: UniqueHelper) {
2264 super(helper);
2265 }
2266
2267 async cancelScheduled(signer: TSigner, scheduledId: string) {
2268 return this.helper.executeExtrinsic(
2269 signer,
2270 'api.tx.scheduler.cancelNamed',
2271 [scheduledId],
2272 true,
2273 );
2274 }
2275
2276 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 }
2284
2285 scheduleAt<T extends UniqueHelper>(
2286 scheduledId: string,
2287 executionBlockNumber: number,
2288 options: ISchedulerOptions = {},
2289 ) {
2290 return this.schedule<T>('scheduleNamed', scheduledId, executionBlockNumber, options);
2291 }
2292
2293 scheduleAfter<T extends UniqueHelper>(
2294 scheduledId: string,
2295 blocksBeforeExecution: number,
2296 options: ISchedulerOptions = {},
2297 ) {
2298 return this.schedule<T>('scheduleNamedAfter', scheduledId, blocksBeforeExecution, options);
2299 }
2300
2301 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-convention
2308 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}
2317
2318export type UniqueHelperConstructor = new(...args: any[]) => UniqueHelper;
22502319
2251export class UniqueHelper extends ChainHelperBase {2320export class UniqueHelper extends ChainHelperBase {
2321 helperBase: any;
2322
2252 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;
22602332
2261 constructor(logger?: ILogger) {2333 constructor(logger?: ILogger, options: {[key: string]: any} = {}) {
2262 super(logger);2334 super(logger);
2335
2336 this.helperBase = options.helperBase ?? UniqueHelper;
2337
2263 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 }
2348
2349 clone(helperCls: UniqueHelperConstructor, options: {[key: string]: any} = {}) {
2350 Object.setPrototypeOf(helperCls.prototype, this);
2351 const newHelper = new helperCls(this.logger, options);
2352
2353 newHelper.api = this.api;
2354 newHelper.network = this.network;
2355 newHelper.forceNetwork = this.forceNetwork;
2356
2357 this.children.push(newHelper);
2358
2359 return newHelper;
2360 }
2361
2362 getSudo<T extends UniqueHelper>() {
2363 // eslint-disable-next-line @typescript-eslint/naming-convention
2364 const SudoHelperType = SudoUniqueHelper(this.helperBase);
2365 return this.clone(SudoHelperType) as T;
2366 }
2272}2367}
22732368
2369// eslint-disable-next-line @typescript-eslint/naming-convention
2370function ScheduledUniqueHelper<T extends UniqueHelperConstructor>(Base: T) {
2371 return class extends Base {
2372 scheduleFn: 'scheduleNamed' | 'scheduleNamedAfter';
2373 scheduledId: string;
2374 blocksNum: number;
2375 options: ISchedulerOptions;
2376
2377 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: ISchedulerOptions
2384 };
2385
2386 super(logger);
2387
2388 this.scheduleFn = options.scheduleFn;
2389 this.scheduledId = options.scheduledId;
2390 this.blocksNum = options.blocksNum;
2391 this.options = options.options;
2392 }
2393
2394 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;
2397
2398 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}
2413
2414// eslint-disable-next-line @typescript-eslint/naming-convention
2415function SudoUniqueHelper<T extends UniqueHelperConstructor>(Base: T) {
2416 return class extends Base {
2417 constructor(...args: any[]) {
2418 super(...args);
2419 }
2420
2421 executeExtrinsic (
2422 sender: IKeyringPair,
2423 extrinsic: string,
2424 params: any[],
2425 expectSuccess?: boolean,
2426 ): Promise<ITransactionResult> {
2427 const call = this.constructApiCall(extrinsic, params);
2428
2429 return super.executeExtrinsic(
2430 sender,
2431 'api.tx.sudo.sudo',
2432 [call],
2433 expectSuccess,
2434 );
2435 }
2436 };
2437}
22742438
2275export 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 }
2539
2540 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 }
2548
2549 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 }
2557
2558 getSudo<T extends UniqueHelper>() {
2559 return new UniqueBaseCollection(this.collectionId, this.helper.getSudo<T>());
2560 }
2375}2561}
23762562
23772563
2460 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 }
2648
2649 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 }
2657
2658 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 }
2666
2667 getSudo<T extends UniqueHelper>() {
2668 return new UniqueNFTCollection(this.collectionId, this.helper.getSudo<T>());
2669 }
2462}2670}
24632671
24642672
2543 return await this.helper.rft.setTokenPropertyPermissions(signer, this.collectionId, permissions);2751 return await this.helper.rft.setTokenPropertyPermissions(signer, this.collectionId, permissions);
2544 }2752 }
2753
2754 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 }
2762
2763 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 }
2771
2772 getSudo<T extends UniqueHelper>() {
2773 return new UniqueRFTCollection(this.collectionId, this.helper.getSudo<T>());
2774 }
2545}2775}
25462776
25472777
2590 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 }
2822
2823 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 }
2831
2832 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 }
2840
2841 getSudo<T extends UniqueHelper>() {
2842 return new UniqueFTCollection(this.collectionId, this.helper.getSudo<T>());
2843 }
2592}2844}
25932845
25942846
2627 return this.collection.helper.util.getTokenAccount(this);2879 return this.collection.helper.util.getTokenAccount(this);
2628 }2880 }
2881
2882 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 }
2890
2891 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 }
2899
2900 getSudo<T extends UniqueHelper>() {
2901 return new UniqueBaseToken(this.tokenId, this.collection.getSudo<T>());
2902 }
2629}2903}
26302904
26312905
2685 return await this.collection.burnTokenFrom(signer, this.tokenId, fromAddressObj);2959 return await this.collection.burnTokenFrom(signer, this.tokenId, fromAddressObj);
2686 }2960 }
2961
2962 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 }
2970
2971 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 }
2979
2980 getSudo<T extends UniqueHelper>() {
2981 return new UniqueNFToken(this.tokenId, this.collection.getSudo<T>());
2982 }
2687}2983}
26882984
2689export 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 }
3036
3037 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 }
3045
3046 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 }
3054
3055 getSudo<T extends UniqueHelper>() {
3056 return new UniqueRFToken(this.tokenId, this.collection.getSudo<T>());
3057 }
2740}3058}
27413059