git.delta.rocks / unique-network / refs/commits / 05841c0bc519

difftreelog

Merge pull request #639 from UniqueNetwork/feature/playgrounds-nested-ops

ut-akuznetsov2022-10-06parents: #a693ced #09b9e64.patch.diff
in: master
Feature/playgrounds nested ops

5 files changed

modifiedtests/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();
   }
 };
modifiedtests/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
modifiedtests/src/util/playgrounds/types.tsdiffbeforeafterboth
--- a/tests/src/util/playgrounds/types.ts
+++ b/tests/src/util/playgrounds/types.ts
@@ -14,6 +14,7 @@
 export interface ITransactionResult {
   status: 'Fail' | 'Success';
   result: {
+      dispatchError: any,
       events: {
         phase: any, // {ApplyExtrinsic: number} | 'Initialization',
         event: IEvent;
@@ -47,6 +48,7 @@
   call: string;
   params: any[];
   moduleError?: string;
+  dispatchError?: any;
   events?: any;
 }
 
@@ -162,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';
modifiedtests/src/util/playgrounds/unique.dev.tsdiffbeforeafterboth
--- a/tests/src/util/playgrounds/unique.dev.ts
+++ b/tests/src/util/playgrounds/unique.dev.ts
@@ -8,7 +8,6 @@
 import {IKeyringPair} from '@polkadot/types/types';
 import {ICrossAccountId} from './types';
 
-
 export class SilentLogger {
   log(_msg: any, _level: any): void { }
   level = {
@@ -63,8 +62,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 +109,9 @@
 }
 
 class ArrangeGroup {
-  helper: UniqueHelper;
+  helper: DevUniqueHelper;
 
-  constructor(helper: UniqueHelper) {
+  constructor(helper: DevUniqueHelper) {
     this.helper = helper;
   }
 
@@ -245,14 +246,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 
    */
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';
1313
14export class CrossAccountId implements ICrossAccountId {14export class CrossAccountId implements ICrossAccountId {
15 Substrate?: TSubstrateAccount;15 Substrate?: TSubstrateAccount;
318 forcedNetwork: TUniqueNetworks | null;318 forcedNetwork: TUniqueNetworks | null;
319 network: TUniqueNetworks | null;319 network: TUniqueNetworks | null;
320 chainLog: IUniqueHelperLog[];320 chainLog: IUniqueHelperLog[];
321 children: ChainHelperBase[];
321322
322 constructor(logger?: ILogger) {323 constructor(logger?: ILogger) {
323 this.util = UniqueUtil;324 this.util = UniqueUtil;
328 this.forcedNetwork = null;329 this.forcedNetwork = null;
329 this.network = null;330 this.network = null;
330 this.chainLog = [];331 this.chainLog = [];
332 this.children = [];
331 }333 }
332334
333 getApi(): ApiPromise {335 getApi(): ApiPromise {
351 }353 }
352354
353 async disconnect() {355 async disconnect() {
356 for (const child of this.children) {
357 child.clearApi();
358 }
359
354 if (this.api === null) return;360 if (this.api === null) return;
355 await this.api.disconnect();361 await this.api.disconnect();
356 this.api = null;362 this.clearApi();
357 this.network = null;
358 }363 }
364
365 clearApi() {
366 this.api = null;
367 this.network = null;
368 }
359369
360 static async detectNetwork(api: ApiPromise): Promise<TUniqueNetworks> {370 static async detectNetwork(api: ApiPromise): Promise<TUniqueNetworks> {
361 const spec = (await api.query.system.lastRuntimeUpgrade()).toJSON() as any;371 const spec = (await api.query.system.lastRuntimeUpgrade()).toJSON() as any;
479489
480 constructApiCall(apiCall: string, params: any[]) {490 constructApiCall(apiCall: string, params: any[]) {
481 if(!apiCall.startsWith('api.')) throw Error(`Invalid api call: ${apiCall}`);491 if(!apiCall.startsWith('api.')) throw Error(`Invalid api call: ${apiCall}`);
482 let call = this.api as any;492 let call = this.getApi() as any;
483 for(const part of apiCall.slice(4).split('.')) {493 for(const part of apiCall.slice(4).split('.')) {
484 call = call[part];494 call = call[part];
485 }495 }
514 params,524 params,
515 } as IUniqueHelperLog;525 } as IUniqueHelperLog;
516526
517 if(result.status !== this.transactionStatus.SUCCESS && result.moduleError) log.moduleError = result.moduleError;527 if(result.status !== this.transactionStatus.SUCCESS) {
528 if (result.moduleError) log.moduleError = result.moduleError;
529 else if (result.result.dispatchError) log.dispatchError = result.result.dispatchError;
530 }
518 if(events.length > 0) log.events = events;531 if(events.length > 0) log.events = events;
519532
520 this.chainLog.push(log);533 this.chainLog.push(log);
521534
522 if(expectSuccess && result.status !== this.transactionStatus.SUCCESS) throw Error(`${result.moduleError}`);535 if(expectSuccess && result.status !== this.transactionStatus.SUCCESS) {
536 if (result.moduleError) throw Error(`${result.moduleError}`);
537 else if (result.result.dispatchError) throw Error(JSON.stringify(result.result.dispatchError));
538 }
523 return result;539 return result;
524 }540 }
525541
2242 }2258 }
2243}2259}
2260
2261class SchedulerGroup extends HelperGroup {
2262 constructor(helper: UniqueHelper) {
2263 super(helper);
2264 }
2265
2266 async cancelScheduled(signer: TSigner, scheduledId: string) {
2267 return this.helper.executeExtrinsic(
2268 signer,
2269 'api.tx.scheduler.cancelNamed',
2270 [scheduledId],
2271 true,
2272 );
2273 }
2274
2275 async changePriority(signer: TSigner, scheduledId: string, priority: number) {
2276 return this.helper.executeExtrinsic(
2277 signer,
2278 'api.tx.scheduler.changeNamedPriority',
2279 [scheduledId, priority],
2280 true,
2281 );
2282 }
2283
2284 scheduleAt<T extends UniqueHelper>(
2285 scheduledId: string,
2286 executionBlockNumber: number,
2287 options: ISchedulerOptions = {},
2288 ) {
2289 return this.schedule<T>('scheduleNamed', scheduledId, executionBlockNumber, options);
2290 }
2291
2292 scheduleAfter<T extends UniqueHelper>(
2293 scheduledId: string,
2294 blocksBeforeExecution: number,
2295 options: ISchedulerOptions = {},
2296 ) {
2297 return this.schedule<T>('scheduleNamedAfter', scheduledId, blocksBeforeExecution, options);
2298 }
2299
2300 schedule<T extends UniqueHelper>(
2301 scheduleFn: 'scheduleNamed' | 'scheduleNamedAfter',
2302 scheduledId: string,
2303 blocksNum: number,
2304 options: ISchedulerOptions = {},
2305 ) {
2306 // eslint-disable-next-line @typescript-eslint/naming-convention
2307 const ScheduledHelperType = ScheduledUniqueHelper(this.helper.helperBase);
2308 return this.helper.clone(ScheduledHelperType, {
2309 scheduleFn,
2310 scheduledId,
2311 blocksNum,
2312 options,
2313 }) as T;
2314 }
2315}
2316
2317export type UniqueHelperConstructor = new(...args: any[]) => UniqueHelper;
22442318
2245export class UniqueHelper extends ChainHelperBase {2319export class UniqueHelper extends ChainHelperBase {
2320 helperBase: any;
2321
2246 chain: ChainGroup;2322 chain: ChainGroup;
2247 balance: BalanceGroup;2323 balance: BalanceGroup;
2251 rft: RFTGroup;2327 rft: RFTGroup;
2252 ft: FTGroup;2328 ft: FTGroup;
2253 staking: StakingGroup;2329 staking: StakingGroup;
2330 scheduler: SchedulerGroup;
22542331
2255 constructor(logger?: ILogger) {2332 constructor(logger?: ILogger, options: {[key: string]: any} = {}) {
2256 super(logger);2333 super(logger);
2334
2335 this.helperBase = options.helperBase ?? UniqueHelper;
2336
2257 this.chain = new ChainGroup(this);2337 this.chain = new ChainGroup(this);
2258 this.balance = new BalanceGroup(this);2338 this.balance = new BalanceGroup(this);
2262 this.rft = new RFTGroup(this);2342 this.rft = new RFTGroup(this);
2263 this.ft = new FTGroup(this);2343 this.ft = new FTGroup(this);
2264 this.staking = new StakingGroup(this);2344 this.staking = new StakingGroup(this);
2345 this.scheduler = new SchedulerGroup(this);
2265 }2346 }
2347
2348 clone(helperCls: UniqueHelperConstructor, options: {[key: string]: any} = {}) {
2349 Object.setPrototypeOf(helperCls.prototype, this);
2350 const newHelper = new helperCls(this.logger, options);
2351
2352 newHelper.api = this.api;
2353 newHelper.network = this.network;
2354 newHelper.forceNetwork = this.forceNetwork;
2355
2356 this.children.push(newHelper);
2357
2358 return newHelper;
2359 }
2360
2361 getSudo<T extends UniqueHelper>() {
2362 // eslint-disable-next-line @typescript-eslint/naming-convention
2363 const SudoHelperType = SudoUniqueHelper(this.helperBase);
2364 return this.clone(SudoHelperType) as T;
2365 }
2266}2366}
22672367
2368// eslint-disable-next-line @typescript-eslint/naming-convention
2369function ScheduledUniqueHelper<T extends UniqueHelperConstructor>(Base: T) {
2370 return class extends Base {
2371 scheduleFn: 'scheduleNamed' | 'scheduleNamedAfter';
2372 scheduledId: string;
2373 blocksNum: number;
2374 options: ISchedulerOptions;
2375
2376 constructor(...args: any[]) {
2377 const logger = args[0] as ILogger;
2378 const options = args[1] as {
2379 scheduleFn: 'scheduleNamed' | 'scheduleNamedAfter',
2380 scheduledId: string,
2381 blocksNum: number,
2382 options: ISchedulerOptions
2383 };
2384
2385 super(logger);
2386
2387 this.scheduleFn = options.scheduleFn;
2388 this.scheduledId = options.scheduledId;
2389 this.blocksNum = options.blocksNum;
2390 this.options = options.options;
2391 }
2392
2393 executeExtrinsic(sender: IKeyringPair, scheduledExtrinsic: string, scheduledParams: any[], expectSuccess?: boolean): Promise<ITransactionResult> {
2394 const scheduledTx = this.constructApiCall(scheduledExtrinsic, scheduledParams);
2395 const extrinsic = 'api.tx.scheduler.' + this.scheduleFn;
2396
2397 return super.executeExtrinsic(
2398 sender,
2399 extrinsic,
2400 [
2401 this.scheduledId,
2402 this.blocksNum,
2403 this.options.periodic ? [this.options.periodic.period, this.options.periodic.repetitions] : null,
2404 this.options.priority ?? null,
2405 {Value: scheduledTx},
2406 ],
2407 expectSuccess,
2408 );
2409 }
2410 };
2411}
2412
2413// eslint-disable-next-line @typescript-eslint/naming-convention
2414function SudoUniqueHelper<T extends UniqueHelperConstructor>(Base: T) {
2415 return class extends Base {
2416 constructor(...args: any[]) {
2417 super(...args);
2418 }
2419
2420 executeExtrinsic (
2421 sender: IKeyringPair,
2422 extrinsic: string,
2423 params: any[],
2424 expectSuccess?: boolean,
2425 ): Promise<ITransactionResult> {
2426 const call = this.constructApiCall(extrinsic, params);
2427
2428 return super.executeExtrinsic(
2429 sender,
2430 'api.tx.sudo.sudo',
2431 [call],
2432 expectSuccess,
2433 );
2434 }
2435 };
2436}
22682437
2269export class UniqueBaseCollection {2438export class UniqueBaseCollection {
2270 helper: UniqueHelper;2439 helper: UniqueHelper;
2367 return await this.helper.collection.burn(signer, this.collectionId);2536 return await this.helper.collection.burn(signer, this.collectionId);
2368 }2537 }
2538
2539 scheduleAt<T extends UniqueHelper>(
2540 scheduledId: string,
2541 executionBlockNumber: number,
2542 options: ISchedulerOptions = {},
2543 ) {
2544 const scheduledHelper = this.helper.scheduler.scheduleAt<T>(scheduledId, executionBlockNumber, options);
2545 return new UniqueBaseCollection(this.collectionId, scheduledHelper);
2546 }
2547
2548 scheduleAfter<T extends UniqueHelper>(
2549 scheduledId: string,
2550 blocksBeforeExecution: number,
2551 options: ISchedulerOptions = {},
2552 ) {
2553 const scheduledHelper = this.helper.scheduler.scheduleAfter<T>(scheduledId, blocksBeforeExecution, options);
2554 return new UniqueBaseCollection(this.collectionId, scheduledHelper);
2555 }
2556
2557 getSudo<T extends UniqueHelper>() {
2558 return new UniqueBaseCollection(this.collectionId, this.helper.getSudo<T>());
2559 }
2369}2560}
23702561
23712562
2454 return await this.helper.nft.unnestToken(signer, {collectionId: this.collectionId, tokenId}, fromTokenObj, toAddressObj);2645 return await this.helper.nft.unnestToken(signer, {collectionId: this.collectionId, tokenId}, fromTokenObj, toAddressObj);
2455 }2646 }
2647
2648 scheduleAt<T extends UniqueHelper>(
2649 scheduledId: string,
2650 executionBlockNumber: number,
2651 options: ISchedulerOptions = {},
2652 ) {
2653 const scheduledHelper = this.helper.scheduler.scheduleAt<T>(scheduledId, executionBlockNumber, options);
2654 return new UniqueNFTCollection(this.collectionId, scheduledHelper);
2655 }
2656
2657 scheduleAfter<T extends UniqueHelper>(
2658 scheduledId: string,
2659 blocksBeforeExecution: number,
2660 options: ISchedulerOptions = {},
2661 ) {
2662 const scheduledHelper = this.helper.scheduler.scheduleAfter<T>(scheduledId, blocksBeforeExecution, options);
2663 return new UniqueNFTCollection(this.collectionId, scheduledHelper);
2664 }
2665
2666 getSudo<T extends UniqueHelper>() {
2667 return new UniqueNFTCollection(this.collectionId, this.helper.getSudo<T>());
2668 }
2456}2669}
24572670
24582671
2537 return await this.helper.rft.setTokenPropertyPermissions(signer, this.collectionId, permissions);2750 return await this.helper.rft.setTokenPropertyPermissions(signer, this.collectionId, permissions);
2538 }2751 }
2752
2753 scheduleAt<T extends UniqueHelper>(
2754 scheduledId: string,
2755 executionBlockNumber: number,
2756 options: ISchedulerOptions = {},
2757 ) {
2758 const scheduledHelper = this.helper.scheduler.scheduleAt<T>(scheduledId, executionBlockNumber, options);
2759 return new UniqueRFTCollection(this.collectionId, scheduledHelper);
2760 }
2761
2762 scheduleAfter<T extends UniqueHelper>(
2763 scheduledId: string,
2764 blocksBeforeExecution: number,
2765 options: ISchedulerOptions = {},
2766 ) {
2767 const scheduledHelper = this.helper.scheduler.scheduleAfter<T>(scheduledId, blocksBeforeExecution, options);
2768 return new UniqueRFTCollection(this.collectionId, scheduledHelper);
2769 }
2770
2771 getSudo<T extends UniqueHelper>() {
2772 return new UniqueRFTCollection(this.collectionId, this.helper.getSudo<T>());
2773 }
2539}2774}
25402775
25412776
2584 return await this.helper.ft.approveTokens(signer, this.collectionId, toAddressObj, amount);2819 return await this.helper.ft.approveTokens(signer, this.collectionId, toAddressObj, amount);
2585 }2820 }
2821
2822 scheduleAt<T extends UniqueHelper>(
2823 scheduledId: string,
2824 executionBlockNumber: number,
2825 options: ISchedulerOptions = {},
2826 ) {
2827 const scheduledHelper = this.helper.scheduler.scheduleAt<T>(scheduledId, executionBlockNumber, options);
2828 return new UniqueFTCollection(this.collectionId, scheduledHelper);
2829 }
2830
2831 scheduleAfter<T extends UniqueHelper>(
2832 scheduledId: string,
2833 blocksBeforeExecution: number,
2834 options: ISchedulerOptions = {},
2835 ) {
2836 const scheduledHelper = this.helper.scheduler.scheduleAfter<T>(scheduledId, blocksBeforeExecution, options);
2837 return new UniqueFTCollection(this.collectionId, scheduledHelper);
2838 }
2839
2840 getSudo<T extends UniqueHelper>() {
2841 return new UniqueFTCollection(this.collectionId, this.helper.getSudo<T>());
2842 }
2586}2843}
25872844
25882845
2621 return this.collection.helper.util.getTokenAccount(this);2878 return this.collection.helper.util.getTokenAccount(this);
2622 }2879 }
2880
2881 scheduleAt<T extends UniqueHelper>(
2882 scheduledId: string,
2883 executionBlockNumber: number,
2884 options: ISchedulerOptions = {},
2885 ) {
2886 const scheduledCollection = this.collection.scheduleAt<T>(scheduledId, executionBlockNumber, options);
2887 return new UniqueBaseToken(this.tokenId, scheduledCollection);
2888 }
2889
2890 scheduleAfter<T extends UniqueHelper>(
2891 scheduledId: string,
2892 blocksBeforeExecution: number,
2893 options: ISchedulerOptions = {},
2894 ) {
2895 const scheduledCollection = this.collection.scheduleAfter<T>(scheduledId, blocksBeforeExecution, options);
2896 return new UniqueBaseToken(this.tokenId, scheduledCollection);
2897 }
2898
2899 getSudo<T extends UniqueHelper>() {
2900 return new UniqueBaseToken(this.tokenId, this.collection.getSudo<T>());
2901 }
2623}2902}
26242903
26252904
2679 return await this.collection.burnTokenFrom(signer, this.tokenId, fromAddressObj);2958 return await this.collection.burnTokenFrom(signer, this.tokenId, fromAddressObj);
2680 }2959 }
2960
2961 scheduleAt<T extends UniqueHelper>(
2962 scheduledId: string,
2963 executionBlockNumber: number,
2964 options: ISchedulerOptions = {},
2965 ) {
2966 const scheduledCollection = this.collection.scheduleAt<T>(scheduledId, executionBlockNumber, options);
2967 return new UniqueNFToken(this.tokenId, scheduledCollection);
2968 }
2969
2970 scheduleAfter<T extends UniqueHelper>(
2971 scheduledId: string,
2972 blocksBeforeExecution: number,
2973 options: ISchedulerOptions = {},
2974 ) {
2975 const scheduledCollection = this.collection.scheduleAfter<T>(scheduledId, blocksBeforeExecution, options);
2976 return new UniqueNFToken(this.tokenId, scheduledCollection);
2977 }
2978
2979 getSudo<T extends UniqueHelper>() {
2980 return new UniqueNFToken(this.tokenId, this.collection.getSudo<T>());
2981 }
2681}2982}
26822983
2683export class UniqueRFToken extends UniqueBaseToken {2984export class UniqueRFToken extends UniqueBaseToken {
2732 return await this.collection.burnTokenFrom(signer, this.tokenId, fromAddressObj, amount);3033 return await this.collection.burnTokenFrom(signer, this.tokenId, fromAddressObj, amount);
2733 }3034 }
3035
3036 scheduleAt<T extends UniqueHelper>(
3037 scheduledId: string,
3038 executionBlockNumber: number,
3039 options: ISchedulerOptions = {},
3040 ) {
3041 const scheduledCollection = this.collection.scheduleAt<T>(scheduledId, executionBlockNumber, options);
3042 return new UniqueRFToken(this.tokenId, scheduledCollection);
3043 }
3044
3045 scheduleAfter<T extends UniqueHelper>(
3046 scheduledId: string,
3047 blocksBeforeExecution: number,
3048 options: ISchedulerOptions = {},
3049 ) {
3050 const scheduledCollection = this.collection.scheduleAfter<T>(scheduledId, blocksBeforeExecution, options);
3051 return new UniqueRFToken(this.tokenId, scheduledCollection);
3052 }
3053
3054 getSudo<T extends UniqueHelper>() {
3055 return new UniqueRFToken(this.tokenId, this.collection.getSudo<T>());
3056 }
2734}3057}
27353058