From 3066a1972ccdb78f68faf3e8c8bd9d81481e048a Mon Sep 17 00:00:00 2001 From: jpgundrum Date: Wed, 26 Jun 2024 11:52:49 -0500 Subject: [PATCH] fix: block events and error handling --- packages/sdk/src/modules/base/index.ts | 85 +++++++++++++++----------- packages/sdk/src/modules/did/index.ts | 4 +- packages/sdk/src/types/common.ts | 3 +- 3 files changed, 52 insertions(+), 40 deletions(-) diff --git a/packages/sdk/src/modules/base/index.ts b/packages/sdk/src/modules/base/index.ts index 91688ca..bc8183e 100644 --- a/packages/sdk/src/modules/base/index.ts +++ b/packages/sdk/src/modules/base/index.ts @@ -14,10 +14,20 @@ import { AnyTuple } from '@polkadot/types-codec/types'; import { truncatedString } from '../../utils'; type TErrorData = { - Module?: { - index?: string; - error?: string; - }; + dispatchError: { + Module?: { + index?: string; + error?: string; + }; + } + dispatchInfo: { + weight?: { + refTime?: string, + proofSize?: string + }, + class?: string, + paysFee?: string + } }; export class Base { @@ -90,17 +100,15 @@ export class Base { protected async _transactionError( method: string, - eventData: PeaqEventData[] - ): Promise<{ documentation: string[]; name: string } | null> { + eventData: PeaqEventData + ): Promise<{ documentation: string[]; name: string, section: string } | null> { const failedEvent = method === 'ExtrinsicFailed'; const api = this._getApi(); if (failedEvent) { - const error = eventData.find((item) => - item.lookupName.includes('DispatchError') - ); + const error = eventData; const errorData = error?.data?.toHuman?.() as TErrorData | undefined; - const errorIdx = errorData?.Module?.error; - const moduleIdx = errorData?.Module?.index; + const errorIdx = errorData?.dispatchError.Module?.error; + const moduleIdx = errorData?.dispatchError.Module?.index; if (errorIdx && moduleIdx) { try { const decode = api.registry.findMetaError({ @@ -110,11 +118,13 @@ export class Base { return { documentation: decode.docs, name: decode.name, + section: decode.section }; } catch (error) { return { documentation: ['Unknown error'], name: 'UnknownError', + section: 'UnknownSection' }; } } @@ -122,6 +132,7 @@ export class Base { return { documentation: ['Unknown error'], name: 'UnknownError', + section: 'UnknownSection' }; } return null; @@ -133,7 +144,7 @@ export class Base { const api = this._getApi(); let subscribed = false; - try { + try { // Sign the transaction await extrinsics.signAsync(address, { nonce }); } catch (error: any) { @@ -169,6 +180,9 @@ export class Base { const executionBlockStopNr = inclusionBlockNr.addn(10); let executionBlockNr = executionBlockStartNr; + // save instance of current block hash for peaqEvent + const _inclusionBlockHash = inclusionBlockHash; + // Subscribe to new blocks const unsubscribeNewHeads = await api.rpc.chain.subscribeNewHeads( async (lastHeader) => { @@ -194,10 +208,6 @@ export class Base { const extinsics: GenericExtrinsic[] = ( await api.rpc.chain.getBlock(blockHeader.hash) ).block.extrinsics; - const apiAt = await api.at(blockHeader.hash); - const events: any = await apiAt.query?.['system']?.[ - 'events' - ]; executionBlockNr.iaddn(1); @@ -213,30 +223,31 @@ export class Base { unsubscribeNewHeads(); } - const eventsTriggeredByTx: any = [] - .map((eventRecord : any) => { - const { event, phase } = eventRecord; - const types = event.typeDef; - const eventData: PeaqEventData[] = event.data.map((d: any, i: any) => { - return { - lookupName: types[i].lookupName!, - data: d - }; - }); + const events = await result.events; + const peaqEvents = events.map(({ event, phase }) => { + const { data, method, section } = event; + const eventData: PeaqEventData = { lookupName: method, data: data }; return { - event, - phase, - section: event.section, - method: event.method, - metaDocumentation: event.meta.docs.toString(), - eventData, - error: { - documentation: [], - name: "" - } + event: event, + phase: phase, + section: section, + method: method, + eventData: [eventData], + blockHash: _inclusionBlockHash } as PeaqEvent; }); - resolve(eventsTriggeredByTx); + // check for any failed extrinsics + const extrinsicFailedEvents = peaqEvents.filter(peaqEvent => peaqEvent.method === "ExtrinsicFailed"); + if (extrinsicFailedEvents.length > 0) { + const eventData = extrinsicFailedEvents[0].eventData[0]; + const errorResp = await this._transactionError(extrinsicFailedEvents[0].method, eventData); + reject( + new Error( + `${errorResp?.name} for ${errorResp?.section}.` + ) + ); + } + resolve(peaqEvents); unsub(); } } diff --git a/packages/sdk/src/modules/did/index.ts b/packages/sdk/src/modules/did/index.ts index 4bff021..809abfc 100644 --- a/packages/sdk/src/modules/did/index.ts +++ b/packages/sdk/src/modules/did/index.ts @@ -92,7 +92,7 @@ export class Did extends Base { ); const nonce = await this._getNonce(keyPair.address); - await this._newSignTx({nonce, address: keyPair, extrinsics: attributeExtrinsic}); + const eventData = await this._newSignTx({nonce, address: keyPair, extrinsics: attributeExtrinsic}); // await attributeExtrinsic.signAsync(keyPair, { nonce }); const unsubscribe = await attributeExtrinsic.send((result) => { statusCallback && @@ -100,7 +100,7 @@ export class Did extends Base { }); return { - hash: attributeExtrinsic.hash as unknown as CodecHash, + hash: eventData[0]?.blockHash as unknown as CodecHash, unsubscribe, }; } catch (error) { diff --git a/packages/sdk/src/types/common.ts b/packages/sdk/src/types/common.ts index 01c42f9..aa07827 100644 --- a/packages/sdk/src/types/common.ts +++ b/packages/sdk/src/types/common.ts @@ -116,7 +116,8 @@ export interface PeaqEvent{ section: string; method: string; eventData: PeaqEventData[]; - error: { + blockHash?: string, + error?: { documentation: string[]; name: string } | null