From 2c20e7a00712957c6eadd2e6fe9e914befca4079 Mon Sep 17 00:00:00 2001 From: Joe Caputo Date: Fri, 25 Oct 2024 14:44:42 -0400 Subject: [PATCH] feat: add webhook support for retireMsa, revokeDelegation (#664) # Problem `retireMsa` and `revokeDelegation` extrinsic submissions were not properly linked to the webhook processing, hence no webhook notifications were sent. This PR adds the hooks in to the webhook processing so that notifications may be sent when these operations complete. Closes #617 --- ...otifier.service.helper.createWebhookRsp.ts | 4 +- .../transaction_notifier/notifier.service.ts | 23 ++++++++ .../src/publisher/ipfs.publisher.spec.ts | 31 ----------- .../src/blockchain-rpc-query.service.ts | 53 +++++++++++++++++++ 4 files changed, 79 insertions(+), 32 deletions(-) delete mode 100644 apps/content-publishing-worker/src/publisher/ipfs.publisher.spec.ts diff --git a/apps/account-worker/src/transaction_notifier/notifier.service.helper.createWebhookRsp.ts b/apps/account-worker/src/transaction_notifier/notifier.service.helper.createWebhookRsp.ts index feb0fdb7..cd1a2302 100644 --- a/apps/account-worker/src/transaction_notifier/notifier.service.helper.createWebhookRsp.ts +++ b/apps/account-worker/src/transaction_notifier/notifier.service.helper.createWebhookRsp.ts @@ -53,10 +53,12 @@ export function createWebhookRsp(txStatus: ITxStatus, msaId: string): T; +export function createWebhookRsp(txStatus: ITxStatus, msaId: string): T; export function createWebhookRsp( { type: transactionType, providerId, referenceId }: ITxStatus, msaId: string, - options: TxWebhookOpts, + options?: TxWebhookOpts, ): TxWebhookRsp { const response = { transactionType, diff --git a/apps/account-worker/src/transaction_notifier/notifier.service.ts b/apps/account-worker/src/transaction_notifier/notifier.service.ts index 370cb045..fece70e2 100644 --- a/apps/account-worker/src/transaction_notifier/notifier.service.ts +++ b/apps/account-worker/src/transaction_notifier/notifier.service.ts @@ -160,6 +160,7 @@ export class TxnNotifierService ); } break; + case TransactionType.SIWF_SIGNUP: { const siwfTxnValues = await this.blockchainService.handleSIWFTxnResult(extrinsicEvents); @@ -175,6 +176,7 @@ export class TxnNotifierService ); } break; + case TransactionType.ADD_KEY: { const publicKeyValues = this.blockchainService.handlePublishKeyTxResult(successEvent); @@ -187,6 +189,7 @@ export class TxnNotifierService this.logger.log(`Keys: Added the key ${response.newPublicKey} for msaId ${response.msaId}.`); } break; + case TransactionType.ADD_PUBLIC_KEY_AGREEMENT: { const itemizedPageUpdated = @@ -200,6 +203,26 @@ export class TxnNotifierService this.logger.log(`Keys: Added the graph key msaId ${response.msaId} and schemaId ${response.schemaId}.`); } break; + + case TransactionType.RETIRE_MSA: + { + const msaRetired = this.blockchainService.handleRetireMsaTxResult(successEvent); + const response = createWebhookRsp(txStatus, msaRetired.msaId); + webhookResponse = response; + } + break; + + case TransactionType.REVOKE_DELEGATION: + { + const delegationRevoked = this.blockchainService.handleRevokeDelegationTxResult(successEvent); + const response = createWebhookRsp( + { ...txStatus, providerId: delegationRevoked.providerId }, + delegationRevoked.msaId, + ); + webhookResponse = response; + } + break; + default: this.logger.error(`Unknown transaction type on job.data: ${txStatus.type}`); break; diff --git a/apps/content-publishing-worker/src/publisher/ipfs.publisher.spec.ts b/apps/content-publishing-worker/src/publisher/ipfs.publisher.spec.ts deleted file mode 100644 index 3715e067..00000000 --- a/apps/content-publishing-worker/src/publisher/ipfs.publisher.spec.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* eslint-disable unused-imports/no-unused-vars */ -// test file for ipfs publisher -import { describe, it, beforeEach } from '@jest/globals'; -import { IPFSPublisher } from './ipfs.publisher'; - -describe('IPFSPublisher', () => { - let ipfsPublisher: IPFSPublisher; - - beforeEach(async () => {}); - - describe('publish', () => { - it.skip('should return capacity used per epoch', async () => { - const messages = [ - { - schemaId: 1, - data: { - cid: 'QmRgJZmR6Z6yB5k9aLXjzJ6jG8L6tq4v4J9zQfDz7p3J9v', - payloadLength: 100, - }, - }, - { - schemaId: 1, - data: { - cid: 'QmRgJZmR6Z6yB5k9aLXjzJ6jG8L6tq4v4J9zQfDz7p3J9v', - payloadLength: 100, - }, - }, - ]; - }); - }); -}); diff --git a/libs/blockchain/src/blockchain-rpc-query.service.ts b/libs/blockchain/src/blockchain-rpc-query.service.ts index af555350..6f5fc3c5 100644 --- a/libs/blockchain/src/blockchain-rpc-query.service.ts +++ b/libs/blockchain/src/blockchain-rpc-query.service.ts @@ -63,6 +63,17 @@ interface ItemizedPageUpdated { debugMsg: string; } +interface MsaRetired { + msaId: string; + debugMsg: string; +} + +interface DelegationRevoked { + msaId: string; + providerId: string; + debugMsg: string; +} + export interface ICapacityInfo { providerId: string; currentBlockNumber: number; @@ -398,6 +409,28 @@ export class BlockchainRpcQueryService extends PolkadotApiService { return this.api.tx.msa.revokeDelegationByDelegator(providerId); } + /** + * Handles the DelegationRevoked transaction result events and extracts the MSA ID and Provider ID from the event data. + * @param {Event} event - The DelegationRevoked event + * @returns {DelegationRevoked} The revoked delegation information + */ + public handleRevokeDelegationTxResult(event: Event): DelegationRevoked { + // Grab the event data + if (event && this.api.events.msa.DelegationRevoked.is(event)) { + const providerId = event.data.providerId.toString(); + const msaId = event.data.delegatorId.toString(); + + return { + msaId, + providerId, + debugMsg: `Delegation revoked for msaId: ${msaId}, providerId: ${providerId}`, + }; + } + + this.logger.error(`Expected DelegationRevoked event but found ${event}`); + return {} as DelegationRevoked; + } + public createAddPublicKeyToMsaPayload(payload: KeysRequestPayloadDto): any { const msaIdU64 = this.api.createType('u64', payload.msaId); @@ -572,6 +605,26 @@ export class BlockchainRpcQueryService extends PolkadotApiService { return this.api.tx.msa.retireMsa(); } + /** + * Handles the MsaRetired transaction result events and extracts the retired MSA ID from the event data. + * @param {Event} event - The MsaRetired event + * @returns {MsaRetired} The MSA ID that was retired + */ + public handleRetireMsaTxResult(event: Event): MsaRetired { + // Grab the event data + if (event && this.api.events.msa.MsaRetired.is(event)) { + const msaId = event.data.msaId.toString(); + + return { + msaId, + debugMsg: `MSA retired for msaId: ${msaId}`, + }; + } + + this.logger.error(`Expected MsaRetired event but found ${event}`); + return {} as MsaRetired; + } + public upsertPage( msaId: AnyNumber, schemaId: AnyNumber,