Add dryRun capability on Submittable (#2793)
* Add dryRun capability on Submittable * Ordering, add to interface * Dry run with signing * Revert paymentInfo changes
This commit is contained in:
@@ -3,10 +3,10 @@
|
||||
|
||||
/* eslint-disable no-dupe-class-members */
|
||||
|
||||
import { Address, Call, Extrinsic, ExtrinsicEra, ExtrinsicStatus, Hash, Header, Index, RuntimeDispatchInfo } from '@polkadot/types/interfaces';
|
||||
import { Address, ApplyExtrinsicResult, Call, Extrinsic, ExtrinsicEra, ExtrinsicStatus, Hash, Header, Index, RuntimeDispatchInfo } from '@polkadot/types/interfaces';
|
||||
import { Callback, Codec, Constructor, IKeyringPair, Registry, SignatureOptions, ISubmittableResult } from '@polkadot/types/types';
|
||||
import { ApiInterfaceRx, ApiTypes, SignerResult } from '../types';
|
||||
import { AddressOrPair, SignerOptions, SubmittableExtrinsic, SubmittablePaymentResult, SubmittableResultResult, SubmittableResultSubscription, SubmittableThis } from './types';
|
||||
import { AddressOrPair, SignerOptions, SubmittableExtrinsic, SubmittableDryRunResult, SubmittablePaymentResult, SubmittableResultResult, SubmittableResultSubscription, SubmittableThis } from './types';
|
||||
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { first, map, mapTo, mergeMap, switchMap, tap } from 'rxjs/operators';
|
||||
@@ -39,11 +39,22 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
|
||||
this.#ignoreStatusCb = apiType === 'rxjs';
|
||||
}
|
||||
|
||||
// adds a transform to the result, applied before result is returned
|
||||
withResultTransform (transform: (input: ISubmittableResult) => ISubmittableResult): this {
|
||||
this.#transformResult = transform;
|
||||
// dry run an extrinsic
|
||||
public dryRun (account: AddressOrPair, optionsOrHash?: Partial<SignerOptions> | Uint8Array | string): SubmittableDryRunResult<ApiType> {
|
||||
if (isString(optionsOrHash) || isU8a(optionsOrHash)) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
return decorateMethod(
|
||||
() => api.rpc.system.dryRun(this.toHex(), optionsOrHash)
|
||||
);
|
||||
}
|
||||
|
||||
return this;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-call
|
||||
return decorateMethod(
|
||||
(): Observable<ApplyExtrinsicResult> =>
|
||||
this.#observeSign(account, optionsOrHash).pipe(
|
||||
switchMap(() => api.rpc.system.dryRun(this.toHex()))
|
||||
)
|
||||
)();
|
||||
}
|
||||
|
||||
// calculate the payment info for this transaction (if signed and submitted)
|
||||
@@ -51,7 +62,7 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
|
||||
if (isString(optionsOrHash) || isU8a(optionsOrHash)) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
return decorateMethod(
|
||||
() => api.rpc.payment.queryInfo(this.toHex(), optionsOrHash)
|
||||
(): Observable<RuntimeDispatchInfo> => api.rpc.payment.queryInfo(this.toHex(), optionsOrHash)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -68,7 +79,6 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
|
||||
const eraOptions = this.#makeEraOptions(allOptions, signingInfo);
|
||||
const signOptions = this.#makeSignOptions(eraOptions, {});
|
||||
|
||||
// add a fake signature to the extrinsic
|
||||
this.signFake(address, signOptions);
|
||||
|
||||
return api.rpc.payment.queryInfo(this.toHex());
|
||||
@@ -77,6 +87,24 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
|
||||
)();
|
||||
}
|
||||
|
||||
// send with an immediate Hash result
|
||||
public send (): SubmittableResultResult<ApiType>;
|
||||
|
||||
// send with a status callback
|
||||
public send (statusCb: Callback<ISubmittableResult>): SubmittableResultSubscription<ApiType>;
|
||||
|
||||
// send implementation for both immediate Hash and statusCb variants
|
||||
public send (statusCb?: Callback<ISubmittableResult>): SubmittableResultResult<ApiType> | SubmittableResultSubscription<ApiType> {
|
||||
const isSubscription = api.hasSubscriptions && (this.#ignoreStatusCb || !!statusCb);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-call
|
||||
return decorateMethod(
|
||||
isSubscription
|
||||
? this.#observeSubscribe
|
||||
: this.#observeSend
|
||||
)(statusCb);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Sign a transaction, returning the this to allow chaining, i.e. .sign(...).send(). When options, e.g. nonce/blockHash are not specified, it will be inferred. To retrieve eg. nonce use `signAsync` (the preferred interface, this is provided for backwards compatibility)
|
||||
* @deprecated
|
||||
@@ -125,22 +153,11 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
|
||||
)(statusCb);
|
||||
}
|
||||
|
||||
// send with an immediate Hash result
|
||||
public send (): SubmittableResultResult<ApiType>;
|
||||
// adds a transform to the result, applied before result is returned
|
||||
withResultTransform (transform: (input: ISubmittableResult) => ISubmittableResult): this {
|
||||
this.#transformResult = transform;
|
||||
|
||||
// send with a status callback
|
||||
public send (statusCb: Callback<ISubmittableResult>): SubmittableResultSubscription<ApiType>;
|
||||
|
||||
// send implementation for both immediate Hash and statusCb variants
|
||||
public send (statusCb?: Callback<ISubmittableResult>): SubmittableResultResult<ApiType> | SubmittableResultSubscription<ApiType> {
|
||||
const isSubscription = api.hasSubscriptions && (this.#ignoreStatusCb || !!statusCb);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-call
|
||||
return decorateMethod(
|
||||
isSubscription
|
||||
? this.#observeSubscribe
|
||||
: this.#observeSend
|
||||
)(statusCb);
|
||||
return this;
|
||||
}
|
||||
|
||||
#makeEraOptions = (options: Partial<SignerOptions>, { header, mortalLength, nonce }: { header: Header | null; mortalLength: number; nonce: Index }): SignatureOptions => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2017-2020 @polkadot/api authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { AccountId, Address, DispatchError, DispatchInfo, Extrinsic, ExtrinsicStatus, EventRecord, Hash, RuntimeDispatchInfo } from '@polkadot/types/interfaces';
|
||||
import { AccountId, Address, ApplyExtrinsicResult, DispatchError, DispatchInfo, Extrinsic, ExtrinsicStatus, EventRecord, Hash, RuntimeDispatchInfo } from '@polkadot/types/interfaces';
|
||||
import { AnyNumber, Callback, Codec, IExtrinsicEra, IKeyringPair, Signer, ISubmittableResult } from '@polkadot/types/types';
|
||||
import { ApiTypes } from '../types';
|
||||
|
||||
@@ -14,6 +14,11 @@ export interface SubmittableResultValue {
|
||||
status: ExtrinsicStatus;
|
||||
}
|
||||
|
||||
export type SubmittableDryRunResult<ApiType extends ApiTypes> =
|
||||
ApiType extends 'rxjs'
|
||||
? Observable<ApplyExtrinsicResult>
|
||||
: Promise<ApplyExtrinsicResult>;
|
||||
|
||||
export type SubmittablePaymentResult<ApiType extends ApiTypes> =
|
||||
ApiType extends 'rxjs'
|
||||
? Observable<RuntimeDispatchInfo>
|
||||
@@ -45,24 +50,26 @@ export interface SignerOptions {
|
||||
export type AddressOrPair = IKeyringPair | string | AccountId | Address;
|
||||
|
||||
export interface SubmittableExtrinsic<ApiType extends ApiTypes, R extends ISubmittableResult = ISubmittableResult> extends Extrinsic {
|
||||
withResultTransform (transform: (input: ISubmittableResult) => ISubmittableResult): this;
|
||||
dryRun (account: AddressOrPair, options?: Partial<SignerOptions>): SubmittableDryRunResult<ApiType>;
|
||||
|
||||
paymentInfo (account: AddressOrPair, options?: Partial<SignerOptions>): SubmittablePaymentResult<ApiType>;
|
||||
|
||||
send(): SubmittableResultResult<ApiType>;
|
||||
send (): SubmittableResultResult<ApiType>;
|
||||
|
||||
send(statusCb: Callback<R>): SubmittableResultSubscription<ApiType, R>;
|
||||
send (statusCb: Callback<R>): SubmittableResultSubscription<ApiType, R>;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
sign(account: IKeyringPair, _options?: Partial<SignerOptions>): this;
|
||||
sign (account: IKeyringPair, _options?: Partial<SignerOptions>): this;
|
||||
|
||||
signAsync(account: AddressOrPair, _options?: Partial<SignerOptions>): SubmittableThis<ApiType, this>;
|
||||
signAsync (account: AddressOrPair, _options?: Partial<SignerOptions>): SubmittableThis<ApiType, this>;
|
||||
|
||||
signAndSend(account: AddressOrPair, options?: Partial<SignerOptions>): SubmittableResultResult<ApiType, R>;
|
||||
signAndSend (account: AddressOrPair, options?: Partial<SignerOptions>): SubmittableResultResult<ApiType, R>;
|
||||
|
||||
signAndSend(account: AddressOrPair, statusCb: Callback<R>): SubmittableResultSubscription<ApiType>;
|
||||
signAndSend (account: AddressOrPair, statusCb: Callback<R>): SubmittableResultSubscription<ApiType>;
|
||||
|
||||
signAndSend(account: AddressOrPair, options: Partial<SignerOptions>, statusCb?: Callback<R>): SubmittableResultSubscription<ApiType, R>;
|
||||
signAndSend (account: AddressOrPair, options: Partial<SignerOptions>, statusCb?: Callback<R>): SubmittableResultSubscription<ApiType, R>;
|
||||
|
||||
withResultTransform (transform: (input: ISubmittableResult) => ISubmittableResult): this;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user