import { EventEmitter } from 'events'; import { SubmittableExtrinsic } from '@polkadot/api/types'; import { ISubmittableResult, Signer as PolkadotSigner } from '@polkadot/types/types'; import BigNumber from 'bignumber.js'; import { Context, Identity, MultiSigProposal, PolymeshError } from '../internal'; import { GenericPolymeshTransaction, MortalityProcedureOpt, MultiSig, MultiSigProcedureOpt, PayingAccountFees, TransactionPayload, TransactionStatus, UnsubCallback } from '../types'; import { BaseTransactionSpec, MaybeResolverFunction, TransactionConstructionData } from '../types/internal'; /** * Wrapper class for a Polymesh Transaction */ export declare abstract class PolymeshTransactionBase { /** * @hidden */ static toTransactionSpec(transaction: PolymeshTransactionBase): BaseTransactionSpec; /** * current status of the transaction */ status: TransactionStatus; /** * stores errors thrown while running the transaction (status: `Failed`, `Aborted`) */ error?: PolymeshError | undefined; /** * stores the transaction receipt (if successful) */ receipt?: ISubmittableResult | undefined; /** * transaction hash (status: `Running`, `Succeeded`, `Failed`) */ txHash?: string | undefined; /** * transaction index within its block (status: `Succeeded`, `Failed`) */ txIndex?: BigNumber | undefined; /** * hash of the block where this transaction resides (status: `Succeeded`, `Failed`) */ blockHash?: string | undefined; /** * number of the block where this transaction resides (status: `Succeeded`, `Failed`) */ blockNumber?: BigNumber | undefined; /** * This will be set if the signingAddress is a MultiSig signer, otherwise `null` * * When set it indicates the transaction will be wrapped as a proposal for the MultiSig, * meaning `.runAsProposal` should be used instead of `.run` */ multiSig: null | MultiSig; /** * @hidden * * Identity that will pay for this transaction's fees. This value overrides any subsidy, * and is seen as having infinite allowance (but still constrained by its current balance) */ protected paidForBy?: Identity | undefined; /** * @hidden * * function that transforms the transaction's return value before returning it after it is run */ protected resolver: MaybeResolverFunction; /** * @hidden * * internal event emitter to handle status changes */ protected emitter: EventEmitter<[never]>; /** * @hidden * * Account that will sign the transaction */ protected signingAddress: string; /** * @hidden * * Mortality of the transactions */ protected mortality: MortalityProcedureOpt; /** * @hidden * * MultiSig proposal options */ protected multiSigOpts: MultiSigProcedureOpt; /** * @hidden * * object that performs the payload signing logic */ protected signer?: PolkadotSigner | undefined; /** * @hidden * * function that transforms the return value to another type. Useful when using the same * Procedure for different endpoints which are supposed to return different values */ protected transformer?: undefined | ((result: ReturnValue) => Promise | TransformedReturnValue); /** * @hidden * * Optional validation function that runs before the transaction. Receives an object indicating whether it's running as a proposal. */ protected preRunValidation?: ((args: { asProposal: boolean; }) => Promise) | undefined; protected context: Context; /** * @hidden * whether the queue has run or not (prevents re-running) */ private hasRun; /** * @hidden * the result that was returned from this transaction after being successfully ran */ private _result; /** * @hidden */ constructor(transactionSpec: BaseTransactionSpec & TransactionConstructionData, context: Context); /** * Run the transaction as a multiSig proposal */ runAsProposal(): Promise; /** * Run the transaction, update its status and return a result if applicable. * Certain transactions create Entities on the blockchain, and those Entities are returned * for convenience. For example, when running a transaction that creates an Asset, the Asset itself * is returned */ run(): Promise; /** * @hidden */ private handleRunError; /** * @hidden */ private markAsRan; /** * @hidden * * Execute the underlying transaction, updating the status where applicable and * throwing any pertinent errors */ private internalRun; /** * @hidden * * Sign and submit the transaction, then poll for its finalization. Used when the * node connection does not support subscriptions */ private runViaPolling; /** * Subscribe to status changes * * @param listener - callback function that will be called whenever the status changes * * @returns unsubscribe function */ onStatusChange(listener: (transaction: GenericPolymeshTransaction) => void): UnsubCallback; /** * Retrieve a breakdown of the fees required to run this transaction, as well as the Account responsible for paying them * * @param asProposal - When `true` (default), treats the transaction as a MultiSig proposal if the signing account is a MultiSig signer. * When `false`, treats the transaction as a direct transaction from the signing account, ignoring the MultiSig. * * @note these values might be inaccurate if the transaction is run at a later time. This can be due to a governance vote or other * chain related factors (like modifications to a specific subsidizer relationship or a chain upgrade) */ getTotalFees(asProposal?: boolean): Promise; /** * Subscribe to the results of this transaction being processed by the indexing service (and as such, available to the middleware) * * @param listener - callback function that will be called whenever the middleware is updated with the latest data. * If there is an error (timeout or middleware offline) it will be passed to this callback * * @note this event will be fired even if the queue fails * @returns unsubscribe function * @throws if the middleware wasn't enabled when instantiating the SDK client */ onProcessedByMiddleware(listener: (err?: PolymeshError) => void): UnsubCallback; /** * @hidden */ private setIsRunningStatus; /** * Get the latest processed block from the database * * @note uses the middleware */ private getLatestBlockFromMiddleware; /** * Poll the middleware every 2 seconds to see if it has already processed the * block that reflects the changes brought on by this transaction being run. If so, * emit the corresponding event. After 5 retries (or if the middleware can't be reached), * the event is emitted with an error * * @note uses the middleware */ private emitWhenMiddlewareIsSynced; /** * @hidden */ protected updateStatus(status: TransactionStatus): void; /** * Return whether the transaction can be subsidized. If the result is false * AND the caller is being subsidized by a third party, the transaction can't be executed and trying * to do so will result in an error * * @note this depends on the type of transaction itself (e.g. `staking.bond` can't be subsidized, but `asset.createAsset` can) */ abstract supportsSubsidy(): void; /** * @hidden * * Asserts whether the transaction can be subsidized. * * @throws if transaction cannot be subsidized */ protected abstract assertTransactionSupportsSubsidy(): void; /** * @hidden * * Compose a Transaction Object with arguments that can be signed */ protected abstract composeTx(): SubmittableExtrinsic<'promise', ISubmittableResult>; /** * @hidden * * Return whether the transaction ignores any existing subsidizer relationships * and is always paid by the caller */ protected ignoresSubsidy(): boolean; /** * Return this transaction's protocol fees. These are extra fees charged for * specific operations on the chain. Not to be confused with network fees (which * depend on the complexity of the operation), protocol fees are set by governance and/or * chain upgrades */ abstract getProtocolFees(): Promise; /** * @hidden */ protected handleExtrinsicSuccess(resolve: (value: ISubmittableResult | PromiseLike) => void, _reject: (reason?: unknown) => void, receipt: ISubmittableResult): void; /** * @hidden * * Check if balances and allowances (both third party and signing Account) * are sufficient to cover this transaction's fees */ private assertFeesCovered; /** * returns the transaction result - this is the same value as the Promise run returns * @note it is generally preferable to `await` the `Promise` returned by { @link base/PolymeshTransactionBase!PolymeshTransactionBase.run | transaction.run() } instead of reading this property * * @throws if the { @link base/PolymeshTransactionBase!PolymeshTransactionBase.isSuccess | transaction.isSuccess } property is false — be sure to check that before accessing! */ get result(): TransformedReturnValue; /** * Returns a representation intended for offline signers. * * @param metadata - Additional information attached to the payload, such as IDs or memos about the transaction * @param asProposal - When `true` (default), treats the transaction as a MultiSig proposal if the signing account is a MultiSig signer. * When `false`, treats the transaction as a direct transaction from the signing account, ignoring the MultiSig. * * @note Usually `.run()` should be preferred due to is simplicity. * * @note When using this method, details like account nonces, and transaction mortality require extra consideration. Generating a payload for offline sign implies asynchronicity. If using this API, be sure each procedure is created with the correct nonce, accounting for in flight transactions, and the lifetime is sufficient. * */ toSignablePayload(metadata?: Record, asProposal?: boolean): Promise; /** * returns true if transaction has completed successfully */ get isSuccess(): boolean; /** * @hidden * * Retrieve the Account that would pay fees for the transaction if it was run at this moment, as well as the total amount that can be * charged to it (allowance) in case of a subsidy * * @param asProposal - When `true` (default), uses MultiSig payer if the signing account is a MultiSig signer. * When `false`, uses the signing account directly, ignoring the MultiSig. * * @note the paying Account might change if, before running the transaction, the caller Account enters (or leaves) * a subsidizer relationship. A governance vote or chain upgrade could also cause the value to change between the time * this method is called and the time the transaction is run */ private getPayingAccount; /** * Wrap a transaction with a multiSig proposal if the signer is a multiSig signer */ protected wrapProposalIfNeeded(tx: SubmittableExtrinsic<'promise', ISubmittableResult>): SubmittableExtrinsic<'promise', ISubmittableResult>; /** * @hidden * * Compose a transaction for fee calculation or payload generation, conditionally wrapping as a proposal * * @param asProposal - When `true` (default), wraps the transaction as a proposal if the signing account is a MultiSig signer. * When `false`, returns the unwrapped transaction. */ protected composeTxForFees(asProposal: boolean): SubmittableExtrinsic<'promise', ISubmittableResult>; /** * @hidden * * Get the base transaction without any proposal wrapping */ protected abstract getBaseTransaction(): SubmittableExtrinsic<'promise', ISubmittableResult>; } //# sourceMappingURL=PolymeshTransactionBase.d.ts.map