Expose txHash on submittable results (#4387)
* Expose txHash on submittable results * CHANGELOG * CHANGELOG
This commit is contained in:
@@ -2,9 +2,16 @@
|
|||||||
|
|
||||||
## master
|
## master
|
||||||
|
|
||||||
|
Contributed:
|
||||||
|
|
||||||
|
- Expose `storageDepositLimit` on contract options (Thanks to https://github.com/kwingram25)
|
||||||
|
|
||||||
Changes:
|
Changes:
|
||||||
|
|
||||||
|
- Expose `txHash` on submittable results, e.g. `tx.signAndSend(..., ({ txHash }) => ...)`
|
||||||
|
- Align casing for TS & exposed queries (adjusts for `ALLCAPS` entries)
|
||||||
- Split `types-augment` into `registry` & `lookup` variants (better control)
|
- Split `types-augment` into `registry` & `lookup` variants (better control)
|
||||||
|
- Additional tests for `Option` codec (explicit in expectations)
|
||||||
|
|
||||||
|
|
||||||
## 7.0.2 Dec 21, 2021
|
## 7.0.2 Dec 21, 2021
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ export interface SubmittableResultValue {
|
|||||||
events?: EventRecord[];
|
events?: EventRecord[];
|
||||||
internalError?: Error;
|
internalError?: Error;
|
||||||
status: ExtrinsicStatus;
|
status: ExtrinsicStatus;
|
||||||
|
txHash: Hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SubmittableExtrinsic<ApiType extends ApiTypes, R extends ISubmittableResult = ISubmittableResult> extends Extrinsic {
|
export interface SubmittableExtrinsic<ApiType extends ApiTypes, R extends ISubmittableResult = ISubmittableResult> extends Extrinsic {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright 2017-2021 @polkadot/api authors & contributors
|
// Copyright 2017-2021 @polkadot/api authors & contributors
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import type { DispatchError, DispatchInfo, EventRecord, ExtrinsicStatus } from '@polkadot/types/interfaces';
|
import type { DispatchError, DispatchInfo, EventRecord, ExtrinsicStatus, Hash } from '@polkadot/types/interfaces';
|
||||||
import type { AnyJson, ISubmittableResult } from '@polkadot/types/types';
|
import type { AnyJson, ISubmittableResult } from '@polkadot/types/types';
|
||||||
import type { SubmittableResultValue } from './types';
|
import type { SubmittableResultValue } from './types';
|
||||||
|
|
||||||
@@ -45,12 +45,15 @@ export class SubmittableResult implements ISubmittableResult {
|
|||||||
|
|
||||||
public readonly status: ExtrinsicStatus;
|
public readonly status: ExtrinsicStatus;
|
||||||
|
|
||||||
constructor ({ dispatchError, dispatchInfo, events, internalError, status }: SubmittableResultValue) {
|
public readonly txHash: Hash;
|
||||||
|
|
||||||
|
constructor ({ dispatchError, dispatchInfo, events, internalError, status, txHash }: SubmittableResultValue) {
|
||||||
this.dispatchError = dispatchError || extractError(events);
|
this.dispatchError = dispatchError || extractError(events);
|
||||||
this.dispatchInfo = dispatchInfo || extractInfo(events);
|
this.dispatchInfo = dispatchInfo || extractInfo(events);
|
||||||
this.events = events || [];
|
this.events = events || [];
|
||||||
this.internalError = internalError;
|
this.internalError = internalError;
|
||||||
this.status = status;
|
this.status = status;
|
||||||
|
this.txHash = txHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get isCompleted (): boolean {
|
public get isCompleted (): boolean {
|
||||||
|
|||||||
@@ -233,10 +233,11 @@ export function createClass <ApiType extends ApiTypes> ({ api, apiType, decorate
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
#observeStatus = (hash: Hash, status: ExtrinsicStatus): Observable<ISubmittableResult> => {
|
#observeStatus = (txHash: Hash, status: ExtrinsicStatus): Observable<ISubmittableResult> => {
|
||||||
if (!status.isFinalized && !status.isInBlock) {
|
if (!status.isFinalized && !status.isInBlock) {
|
||||||
return of(this.#transformResult(new SubmittableResult({
|
return of(this.#transformResult(new SubmittableResult({
|
||||||
status
|
status,
|
||||||
|
txHash
|
||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,14 +248,16 @@ export function createClass <ApiType extends ApiTypes> ({ api, apiType, decorate
|
|||||||
return api.derive.tx.events(blockHash).pipe(
|
return api.derive.tx.events(blockHash).pipe(
|
||||||
map(({ block, events }): ISubmittableResult =>
|
map(({ block, events }): ISubmittableResult =>
|
||||||
this.#transformResult(new SubmittableResult({
|
this.#transformResult(new SubmittableResult({
|
||||||
events: filterEvents(hash, block, events, status),
|
events: filterEvents(txHash, block, events, status),
|
||||||
status
|
status,
|
||||||
|
txHash
|
||||||
}))
|
}))
|
||||||
),
|
),
|
||||||
catchError((internalError: Error) =>
|
catchError((internalError: Error) =>
|
||||||
of(this.#transformResult(new SubmittableResult({
|
of(this.#transformResult(new SubmittableResult({
|
||||||
internalError,
|
internalError,
|
||||||
status
|
status,
|
||||||
|
txHash
|
||||||
})))
|
})))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -269,11 +272,11 @@ export function createClass <ApiType extends ApiTypes> ({ api, apiType, decorate
|
|||||||
};
|
};
|
||||||
|
|
||||||
#observeSubscribe = (updateId = -1): Observable<ISubmittableResult> => {
|
#observeSubscribe = (updateId = -1): Observable<ISubmittableResult> => {
|
||||||
const hash = this.hash;
|
const txHash = this.hash;
|
||||||
|
|
||||||
return api.rpc.author.submitAndWatchExtrinsic(this).pipe(
|
return api.rpc.author.submitAndWatchExtrinsic(this).pipe(
|
||||||
switchMap((status): Observable<ISubmittableResult> =>
|
switchMap((status): Observable<ISubmittableResult> =>
|
||||||
this.#observeStatus(hash, status)
|
this.#observeStatus(txHash, status)
|
||||||
),
|
),
|
||||||
tap((status): void => {
|
tap((status): void => {
|
||||||
this.#updateSigner(updateId, status);
|
this.#updateSigner(updateId, status);
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import type { EventRecord, ExtrinsicStatus, H256, SignedBlock } from '@polkadot/
|
|||||||
|
|
||||||
import { l } from './logging';
|
import { l } from './logging';
|
||||||
|
|
||||||
export function filterEvents (extHash: H256, { block: { extrinsics, header } }: SignedBlock, allEvents: EventRecord[], status: ExtrinsicStatus): EventRecord[] | undefined {
|
export function filterEvents (txHash: H256, { block: { extrinsics, header } }: SignedBlock, allEvents: EventRecord[], status: ExtrinsicStatus): EventRecord[] | undefined {
|
||||||
// extrinsics to hashes
|
// extrinsics to hashes
|
||||||
for (const [index, extrinsic] of extrinsics.entries()) {
|
for (const [index, x] of extrinsics.entries()) {
|
||||||
if (extrinsic.hash.eq(extHash)) {
|
if (x.hash.eq(txHash)) {
|
||||||
return allEvents.filter(({ phase }) =>
|
return allEvents.filter(({ phase }) =>
|
||||||
// only ApplyExtrinsic has the extrinsic index
|
// only ApplyExtrinsic has the extrinsic index
|
||||||
phase.isApplyExtrinsic && phase.asApplyExtrinsic.eqn(index)
|
phase.isApplyExtrinsic && phase.asApplyExtrinsic.eqn(index)
|
||||||
@@ -21,7 +21,7 @@ export function filterEvents (extHash: H256, { block: { extrinsics, header } }:
|
|||||||
if (status.isInBlock) {
|
if (status.isInBlock) {
|
||||||
const allHashes = extrinsics.map((x) => x.hash.toHex());
|
const allHashes = extrinsics.map((x) => x.hash.toHex());
|
||||||
|
|
||||||
l.warn(`block ${header.hash.toHex()}: Unable to find extrinsic ${extHash.toHex()} inside ${allHashes.join(', ')}`);
|
l.warn(`block ${header.hash.toHex()}: Unable to find extrinsic ${txHash.toHex()} inside ${allHashes.join(', ')}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import type { AnyJson, AnyNumber, AnyTuple, AnyU8a, Codec } from '@polkadot/type
|
|||||||
import type { HexString } from '@polkadot/util/types';
|
import type { HexString } from '@polkadot/util/types';
|
||||||
import type { ExtrinsicStatus } from '../interfaces/author';
|
import type { ExtrinsicStatus } from '../interfaces/author';
|
||||||
import type { EcdsaSignature, Ed25519Signature, Sr25519Signature } from '../interfaces/extrinsics';
|
import type { EcdsaSignature, Ed25519Signature, Sr25519Signature } from '../interfaces/extrinsics';
|
||||||
import type { Address, Balance, Call, H256, Index } from '../interfaces/runtime';
|
import type { Address, Balance, Call, H256, Hash, Index } from '../interfaces/runtime';
|
||||||
import type { DispatchError, DispatchInfo, EventRecord } from '../interfaces/system';
|
import type { DispatchError, DispatchInfo, EventRecord } from '../interfaces/system';
|
||||||
import type { ICompact, IKeyringPair, IMethod, IRuntimeVersion } from './interfaces';
|
import type { ICompact, IKeyringPair, IMethod, IRuntimeVersion } from './interfaces';
|
||||||
import type { Registry } from './registry';
|
import type { Registry } from './registry';
|
||||||
@@ -21,6 +21,7 @@ export interface ISubmittableResult {
|
|||||||
readonly isFinalized: boolean;
|
readonly isFinalized: boolean;
|
||||||
readonly isInBlock: boolean;
|
readonly isInBlock: boolean;
|
||||||
readonly isWarning: boolean;
|
readonly isWarning: boolean;
|
||||||
|
readonly txHash: Hash;
|
||||||
|
|
||||||
filterRecords (section: string, method: string): EventRecord[];
|
filterRecords (section: string, method: string): EventRecord[];
|
||||||
findRecord (section: string, method: string): EventRecord | undefined;
|
findRecord (section: string, method: string): EventRecord | undefined;
|
||||||
|
|||||||
Reference in New Issue
Block a user