diff --git a/packages/cactus-plugin-satp-hermes/src/main/typescript/core/session-utils.ts b/packages/cactus-plugin-satp-hermes/src/main/typescript/core/session-utils.ts index 8cd18f9fec..37e60ec517 100644 --- a/packages/cactus-plugin-satp-hermes/src/main/typescript/core/session-utils.ts +++ b/packages/cactus-plugin-satp-hermes/src/main/typescript/core/session-utils.ts @@ -1057,3 +1057,26 @@ export function getMessageInSessionData( throw new Error("Message type not found"); } } + +export function collectSessionAttributes( + session: SATPSession, + sessionSide: "client" | "server", +) { + let data: SessionData; + if (sessionSide === "client") { + data = session.getClientSessionData?.() || {}; + } else { + data = session.getServerSessionData?.() || {}; + } + + return { + senderNetworkId: data.senderAsset?.networkId?.id, + receiverNetworkId: data.receiverAsset?.networkId?.id, + senderGatewayNetworkId: data.senderGatewayNetworkId, + receiverGatewayNetworkId: data.recipientGatewayNetworkId, + assetProfileId: data.assetProfileId, + sessionId: session.getSessionId?.(), + sourceLedgerAssetId: data.sourceLedgerAssetId, + recipientLedgerAssetId: data.recipientLedgerAssetId, + }; +} diff --git a/packages/cactus-plugin-satp-hermes/src/main/typescript/core/stage-handlers/stage0-handler.ts b/packages/cactus-plugin-satp-hermes/src/main/typescript/core/stage-handlers/stage0-handler.ts index 59eb51a166..a09108e52f 100644 --- a/packages/cactus-plugin-satp-hermes/src/main/typescript/core/stage-handlers/stage0-handler.ts +++ b/packages/cactus-plugin-satp-hermes/src/main/typescript/core/stage-handlers/stage0-handler.ts @@ -26,7 +26,11 @@ import { SenderGatewayNetworkIdError, SessionNotFoundError, } from "../errors/satp-handler-errors"; -import { saveMessageInSessionData, setError } from "../session-utils"; +import { + collectSessionAttributes, + saveMessageInSessionData, + setError, +} from "../session-utils"; import { MessageType } from "../../generated/proto/cacti/satp/v02/common/message_pb"; import { getMessageTypeName } from "../satp-utils"; import { MonitorService } from "../../services/monitoring/monitor"; @@ -78,10 +82,6 @@ export class Stage0SATPHandler implements SATPHandler { const fnTag = `${this.getHandlerIdentifier()}#${stepTag}`; const { span, context: ctx } = this.monitorService.startSpan(fnTag); return context.with(ctx, async () => { - const attributes: Record< - string, - undefined | string | number | boolean | string[] | number[] | boolean[] - > = {}; let session: SATPSession | undefined; try { this.Log.debug(`${fnTag}, New Session...`); @@ -123,26 +123,16 @@ export class Stage0SATPHandler implements SATPHandler { saveMessageInSessionData(session.getServerSessionData(), message); - attributes.senderNetworkId = - session?.getServerSessionData().senderAsset?.networkId?.id || - undefined; - attributes.receiverNetworkId = - session?.getServerSessionData().receiverAsset?.networkId?.id || - undefined; - attributes.senderGatewayNetworkId = - session?.getServerSessionData().senderGatewayNetworkId || undefined; - attributes.receiverGatewayNetworkId = - session?.getServerSessionData().recipientGatewayNetworkId || - undefined; - attributes.assetProfileId = - session?.getServerSessionData().assetProfileId || undefined; - attributes.sessionId = session?.getSessionId() || undefined; - attributes.sourceLedgerAssetId = - session?.getServerSessionData().sourceLedgerAssetId || undefined; - attributes.recipientLedgerAssetId = - session?.getServerSessionData().recipientLedgerAssetId || undefined; - attributes.satp_phase = 0; - attributes.operation = "newSession"; + const attributes: Record< + string, + | undefined + | string + | number + | boolean + | string[] + | number[] + | boolean[] + > = collectSessionAttributes(session, "server"); const startTimestamp = session.getServerSessionData().receivedTimestamps?.stage0 @@ -156,7 +146,11 @@ export class Stage0SATPHandler implements SATPHandler { await this.monitorService.recordHistogram( "operation_duration", duration, - attributes, + { ...attributes, satp_phase: 0, operation: "newSession" }, + ); + } else { + this.Log.warn( + `${fnTag}, Missing timestamps for operation duration calculation`, ); } @@ -187,7 +181,7 @@ export class Stage0SATPHandler implements SATPHandler { const fnTag = `${this.getHandlerIdentifier()}#${stepTag}`; const { span, context: ctx } = this.monitorService.startSpan(fnTag); return context.with(ctx, async () => { - const attributes: Record< + let attributes: Record< string, undefined | string | number | boolean | string[] | number[] | boolean[] > = {}; @@ -226,26 +220,7 @@ export class Stage0SATPHandler implements SATPHandler { saveMessageInSessionData(session.getServerSessionData(), message); - attributes.senderNetworkId = - session?.getServerSessionData().senderAsset?.networkId?.id || - undefined; - attributes.receiverNetworkId = - session?.getServerSessionData().receiverAsset?.networkId?.id || - undefined; - attributes.senderGatewayNetworkId = - session?.getServerSessionData().senderGatewayNetworkId || undefined; - attributes.receiverGatewayNetworkId = - session?.getServerSessionData().recipientGatewayNetworkId || - undefined; - attributes.assetProfileId = - session?.getServerSessionData().assetProfileId || undefined; - attributes.sessionId = session?.getSessionId() || undefined; - attributes.sourceLedgerAssetId = - session?.getServerSessionData().sourceLedgerAssetId || undefined; - attributes.recipientLedgerAssetId = - session?.getServerSessionData().recipientLedgerAssetId || undefined; - attributes.satp_phase = 0; - attributes.operation = "preSATPTransfer"; + attributes = collectSessionAttributes(session, "server"); const startTimestamp = session.getServerSessionData().receivedTimestamps?.stage0 @@ -259,7 +234,11 @@ export class Stage0SATPHandler implements SATPHandler { await this.monitorService.recordHistogram( "operation_duration", duration, - attributes, + { ...attributes, satp_phase: 0, operation: "preSATPTransfer" }, + ); + } else { + this.Log.warn( + `${fnTag}, Missing timestamps for operation duration calculation`, ); } diff --git a/packages/cactus-plugin-satp-hermes/src/main/typescript/core/stage-handlers/stage1-handler.ts b/packages/cactus-plugin-satp-hermes/src/main/typescript/core/stage-handlers/stage1-handler.ts index defb3a81f7..2c0e5d96e2 100644 --- a/packages/cactus-plugin-satp-hermes/src/main/typescript/core/stage-handlers/stage1-handler.ts +++ b/packages/cactus-plugin-satp-hermes/src/main/typescript/core/stage-handlers/stage1-handler.ts @@ -27,7 +27,11 @@ import { PreSATPTransferResponse } from "../../generated/proto/cacti/satp/v02/se import { stringify as safeStableStringify } from "safe-stable-stringify"; import { getMessageTypeName } from "../satp-utils"; import { MessageType } from "../../generated/proto/cacti/satp/v02/common/message_pb"; -import { saveMessageInSessionData, setError } from "../session-utils"; +import { + collectSessionAttributes, + saveMessageInSessionData, + setError, +} from "../session-utils"; import { BridgeManagerClientInterface } from "../../cross-chain-mechanisms/bridge/interfaces/bridge-manager-client-interface"; import { MonitorService } from "../../services/monitoring/monitor"; import { context, SpanStatusCode } from "@opentelemetry/api"; @@ -77,10 +81,6 @@ export class Stage1SATPHandler implements SATPHandler { const fnTag = `${this.getHandlerIdentifier()}#${stepTag}`; const { span, context: ctx } = this.monitorService.startSpan(fnTag); return context.with(ctx, async () => { - const attributes: Record< - string, - undefined | string | number | boolean | string[] | number[] | boolean[] - > = {}; let session: SATPSession | undefined; try { this.Log.debug(`${fnTag}, Transfer Proposal...`); @@ -124,33 +124,23 @@ export class Stage1SATPHandler implements SATPHandler { span.setAttribute("sessionId", session.getSessionId()); span.setAttribute( "senderNetworkId", - session?.getServerSessionData().senderAsset?.networkId?.id ?? "", + session.getServerSessionData().senderAsset?.networkId?.id ?? "", ); span.setAttribute( "receiverNetworkId", - session?.getServerSessionData().receiverAsset?.networkId?.id ?? "", + session.getServerSessionData().receiverAsset?.networkId?.id ?? "", ); - attributes.senderNetworkId = - session?.getServerSessionData().senderAsset?.networkId?.id || - undefined; - attributes.receiverNetworkId = - session?.getServerSessionData().receiverAsset?.networkId?.id || - undefined; - attributes.senderGatewayNetworkId = - session?.getServerSessionData().senderGatewayNetworkId || undefined; - attributes.receiverGatewayNetworkId = - session?.getServerSessionData().recipientGatewayNetworkId || - undefined; - attributes.assetProfileId = - session?.getServerSessionData().assetProfileId || undefined; - attributes.sessionId = session?.getSessionId() || undefined; - attributes.sourceLedgerAssetId = - session?.getServerSessionData().sourceLedgerAssetId || undefined; - attributes.recipientLedgerAssetId = - session?.getServerSessionData().recipientLedgerAssetId || undefined; - attributes.satp_phase = 1; - attributes.operation = "transferProposal"; + const attributes: Record< + string, + | undefined + | string + | number + | boolean + | string[] + | number[] + | boolean[] + > = collectSessionAttributes(session, "server"); const startTimestamp = session.getServerSessionData().receivedTimestamps?.stage1 @@ -164,7 +154,11 @@ export class Stage1SATPHandler implements SATPHandler { await this.monitorService.recordHistogram( "operation_duration", duration, - attributes, + { ...attributes, satp_phase: 1, operation: "transferProposal" }, + ); + } else { + this.Log.warn( + `${fnTag}, Missing timestamps for operation duration calculation`, ); } @@ -198,7 +192,7 @@ export class Stage1SATPHandler implements SATPHandler { const fnTag = `${this.getHandlerIdentifier()}#${stepTag}`; const { span, context: ctx } = this.monitorService.startSpan(fnTag); return context.with(ctx, async () => { - const attributes: Record< + let attributes: Record< string, undefined | string | number | boolean | string[] | number[] | boolean[] > = {}; @@ -215,31 +209,14 @@ export class Stage1SATPHandler implements SATPHandler { span.setAttribute("sessionId", session.getSessionId()); span.setAttribute( "senderNetworkId", - session?.getServerSessionData().senderAsset?.networkId?.id ?? "", + session.getServerSessionData().senderAsset?.networkId?.id ?? "", ); span.setAttribute( "receiverNetworkId", - session?.getServerSessionData().receiverAsset?.networkId?.id ?? "", + session.getServerSessionData().receiverAsset?.networkId?.id ?? "", ); - attributes.senderNetworkId = - session?.getServerSessionData().senderAsset?.networkId?.id || - undefined; - attributes.receiverNetworkId = - session?.getServerSessionData().receiverAsset?.networkId?.id || - undefined; - attributes.senderGatewayNetworkId = - session?.getServerSessionData().senderGatewayNetworkId || undefined; - attributes.receiverGatewayNetworkId = - session?.getServerSessionData().recipientGatewayNetworkId || - undefined; - attributes.assetProfileId = - session?.getServerSessionData().assetProfileId || undefined; - attributes.sessionId = session?.getSessionId() || undefined; - attributes.sourceLedgerAssetId = - session?.getServerSessionData().sourceLedgerAssetId || undefined; - attributes.recipientLedgerAssetId = - session?.getServerSessionData().recipientLedgerAssetId || undefined; + attributes = collectSessionAttributes(session, "server"); this.monitorService.updateCounter( "initiated_transactions", @@ -277,28 +254,6 @@ export class Stage1SATPHandler implements SATPHandler { } saveMessageInSessionData(session.getServerSessionData(), message); - - attributes.senderNetworkId = - session?.getServerSessionData().senderAsset?.networkId?.id || - undefined; - attributes.receiverNetworkId = - session?.getServerSessionData().receiverAsset?.networkId?.id || - undefined; - attributes.senderGatewayNetworkId = - session?.getServerSessionData().senderGatewayNetworkId || undefined; - attributes.receiverGatewayNetworkId = - session?.getServerSessionData().recipientGatewayNetworkId || - undefined; - attributes.assetProfileId = - session?.getServerSessionData().assetProfileId || undefined; - attributes.sessionId = session?.getSessionId() || undefined; - attributes.sourceLedgerAssetId = - session?.getServerSessionData().sourceLedgerAssetId || undefined; - attributes.recipientLedgerAssetId = - session?.getServerSessionData().recipientLedgerAssetId || undefined; - attributes.satp_phase = 1; - attributes.operation = "transferCommence"; - const startTimestamp = session.getServerSessionData().receivedTimestamps?.stage1 ?.transferCommenceRequestMessageTimestamp; @@ -311,7 +266,11 @@ export class Stage1SATPHandler implements SATPHandler { await this.monitorService.recordHistogram( "operation_duration", duration, - attributes, + { ...attributes, satp_phase: 1, operation: "transferCommence" }, + ); + } else { + this.Log.warn( + `${fnTag}, Missing timestamps for operation duration calculation`, ); } @@ -325,26 +284,11 @@ export class Stage1SATPHandler implements SATPHandler { )}`, ); setError(session, MessageType.TRANSFER_COMMENCE_RESPONSE, error); - - attributes.senderNetworkId = - session?.getServerSessionData().senderAsset?.networkId?.id || - undefined; - attributes.receiverNetworkId = - session?.getServerSessionData().receiverAsset?.networkId?.id || - undefined; - attributes.senderGatewayNetworkId = - session?.getServerSessionData().senderGatewayNetworkId || undefined; - attributes.receiverGatewayNetworkId = - session?.getServerSessionData().recipientGatewayNetworkId || - undefined; - attributes.assetProfileId = - session?.getServerSessionData().assetProfileId || undefined; - attributes.sessionId = session?.getSessionId() || undefined; - attributes.sourceLedgerAssetId = - session?.getServerSessionData().sourceLedgerAssetId || undefined; - attributes.recipientLedgerAssetId = - session?.getServerSessionData().recipientLedgerAssetId || undefined; + if (session) { + attributes = collectSessionAttributes(session, "server"); + } attributes.satp_phase = 1; + attributes.operation = "transferCommence"; this.monitorService.updateCounter( "ongoing_transactions", @@ -468,7 +412,7 @@ export class Stage1SATPHandler implements SATPHandler { const fnTag = `${this.getHandlerIdentifier()}#${stepTag}`; const { span, context: ctx } = this.monitorService.startSpan(fnTag); return context.with(ctx, async () => { - const attributes: Record< + let attributes: Record< string, undefined | string | number | boolean | string[] | number[] | boolean[] > = {}; @@ -522,26 +466,9 @@ export class Stage1SATPHandler implements SATPHandler { ); setError(session, MessageType.TRANSFER_COMMENCE_REQUEST, error); - attributes.senderNetworkId = - session?.getClientSessionData()?.senderAsset?.networkId?.id || - undefined; - attributes.receiverNetworkId = - session?.getClientSessionData()?.receiverAsset?.networkId?.id || - undefined; - attributes.senderGatewayNetworkId = - session?.getClientSessionData()?.senderGatewayNetworkId || - undefined; - attributes.receiverGatewayNetworkId = - session?.getClientSessionData()?.recipientGatewayNetworkId || - undefined; - attributes.assetProfileId = - session?.getClientSessionData()?.assetProfileId || undefined; - attributes.sessionId = session?.getSessionId() || undefined; - attributes.sourceLedgerAssetId = - session?.getClientSessionData()?.sourceLedgerAssetId || undefined; - attributes.recipientLedgerAssetId = - session?.getClientSessionData()?.recipientLedgerAssetId || - undefined; + if (session) { + attributes = collectSessionAttributes(session, "client"); + } attributes.satp_phase = 1; this.monitorService.updateCounter( diff --git a/packages/cactus-plugin-satp-hermes/src/main/typescript/core/stage-handlers/stage2-handler.ts b/packages/cactus-plugin-satp-hermes/src/main/typescript/core/stage-handlers/stage2-handler.ts index 5b9bc7e742..e18f783509 100644 --- a/packages/cactus-plugin-satp-hermes/src/main/typescript/core/stage-handlers/stage2-handler.ts +++ b/packages/cactus-plugin-satp-hermes/src/main/typescript/core/stage-handlers/stage2-handler.ts @@ -24,7 +24,11 @@ import { import { getSessionId } from "./handler-utils"; import { getMessageTypeName } from "../satp-utils"; import { MessageType } from "../../generated/proto/cacti/satp/v02/common/message_pb"; -import { saveMessageInSessionData, setError } from "../session-utils"; +import { + collectSessionAttributes, + saveMessageInSessionData, + setError, +} from "../session-utils"; import { MonitorService } from "../../services/monitoring/monitor"; import { context, SpanStatusCode } from "@opentelemetry/api"; export class Stage2SATPHandler implements SATPHandler { @@ -71,7 +75,7 @@ export class Stage2SATPHandler implements SATPHandler { const fnTag = `${this.getHandlerIdentifier()}#${stepTag}`; const { span, context: ctx } = this.monitorService.startSpan(fnTag); return context.with(ctx, async () => { - const attributes: Record< + let attributes: Record< string, undefined | string | number | boolean | string[] | number[] | boolean[] > = {}; @@ -105,26 +109,7 @@ export class Stage2SATPHandler implements SATPHandler { ); } - attributes.senderNetworkId = - session?.getServerSessionData().senderAsset?.networkId?.id || - undefined; - attributes.receiverNetworkId = - session?.getServerSessionData().receiverAsset?.networkId?.id || - undefined; - attributes.senderGatewayNetworkId = - session?.getServerSessionData().senderGatewayNetworkId || undefined; - attributes.receiverGatewayNetworkId = - session?.getServerSessionData().recipientGatewayNetworkId || - undefined; - attributes.assetProfileId = - session?.getServerSessionData().assetProfileId || undefined; - attributes.sessionId = session?.getSessionId() || undefined; - attributes.sourceLedgerAssetId = - session?.getServerSessionData().sourceLedgerAssetId || undefined; - attributes.recipientLedgerAssetId = - session?.getServerSessionData().recipientLedgerAssetId || undefined; - attributes.satp_phase = 2; - attributes.operation = "lockAssertion"; + attributes = collectSessionAttributes(session, "server"); const startTimestamp = session.getServerSessionData().receivedTimestamps?.stage2 @@ -138,7 +123,11 @@ export class Stage2SATPHandler implements SATPHandler { await this.monitorService.recordHistogram( "operation_duration", duration, - attributes, + { ...attributes, operation: "lockAssertion", satp_phase: 2 }, + ); + } else { + this.Log.warn( + `${fnTag}, Missing timestamps for operation duration calculation`, ); } @@ -155,24 +144,9 @@ export class Stage2SATPHandler implements SATPHandler { ); setError(session, MessageType.ASSERTION_RECEIPT, error); - attributes.senderNetworkId = - session?.getServerSessionData().senderAsset?.networkId?.id || - undefined; - attributes.receiverNetworkId = - session?.getServerSessionData().receiverAsset?.networkId?.id || - undefined; - attributes.senderGatewayNetworkId = - session?.getServerSessionData().senderGatewayNetworkId || undefined; - attributes.receiverGatewayNetworkId = - session?.getServerSessionData().recipientGatewayNetworkId || - undefined; - attributes.assetProfileId = - session?.getServerSessionData().assetProfileId || undefined; - attributes.sessionId = session?.getSessionId() || undefined; - attributes.sourceLedgerAssetId = - session?.getServerSessionData().sourceLedgerAssetId || undefined; - attributes.recipientLedgerAssetId = - session?.getServerSessionData().recipientLedgerAssetId || undefined; + if (session) { + attributes = collectSessionAttributes(session, "server"); + } attributes.satp_phase = 2; this.monitorService.updateCounter( @@ -224,7 +198,7 @@ export class Stage2SATPHandler implements SATPHandler { const fnTag = `${this.getHandlerIdentifier()}#${stepTag}`; const { span, context: ctx } = this.monitorService.startSpan(fnTag); return context.with(ctx, async () => { - const attributes: Record< + let attributes: Record< string, undefined | string | number | boolean | string[] | number[] | boolean[] > = {}; @@ -275,26 +249,9 @@ export class Stage2SATPHandler implements SATPHandler { ); setError(session, MessageType.LOCK_ASSERT, error); - attributes.senderNetworkId = - session?.getClientSessionData()?.senderAsset?.networkId?.id || - undefined; - attributes.receiverNetworkId = - session?.getClientSessionData()?.receiverAsset?.networkId?.id || - undefined; - attributes.senderGatewayNetworkId = - session?.getClientSessionData()?.senderGatewayNetworkId || - undefined; - attributes.receiverGatewayNetworkId = - session?.getClientSessionData()?.recipientGatewayNetworkId || - undefined; - attributes.assetProfileId = - session?.getClientSessionData()?.assetProfileId || undefined; - attributes.sessionId = session?.getSessionId() || undefined; - attributes.sourceLedgerAssetId = - session?.getClientSessionData()?.sourceLedgerAssetId || undefined; - attributes.recipientLedgerAssetId = - session?.getClientSessionData()?.recipientLedgerAssetId || - undefined; + if (session) { + attributes = collectSessionAttributes(session, "client"); + } attributes.satp_phase = 2; this.monitorService.updateCounter( diff --git a/packages/cactus-plugin-satp-hermes/src/main/typescript/core/stage-handlers/stage3-handler.ts b/packages/cactus-plugin-satp-hermes/src/main/typescript/core/stage-handlers/stage3-handler.ts index 746dd46fd0..b7b087bef1 100644 --- a/packages/cactus-plugin-satp-hermes/src/main/typescript/core/stage-handlers/stage3-handler.ts +++ b/packages/cactus-plugin-satp-hermes/src/main/typescript/core/stage-handlers/stage3-handler.ts @@ -29,12 +29,17 @@ import { LockAssertionResponse } from "../../generated/proto/cacti/satp/v02/serv import { getMessageTypeName } from "../satp-utils"; import { MessageType } from "../../generated/proto/cacti/satp/v02/common/message_pb"; import { + collectSessionAttributes, saveMessageInSessionData, setError, setErrorChecking, } from "../session-utils"; import { MonitorService } from "../../services/monitoring/monitor"; import { context, SpanStatusCode } from "@opentelemetry/api"; +import { + PriceManager, + PriceManagerOptions, +} from "../../services/token-price-check/price-manager"; export class Stage3SATPHandler implements SATPHandler { public static readonly CLASS_NAME = SATPHandlerType.STAGE3; @@ -43,6 +48,7 @@ export class Stage3SATPHandler implements SATPHandler { private serverService: Stage3ServerService; private logger: Logger; private readonly monitorService: MonitorService; + private priceManager: PriceManager; constructor(ops: SATPHandlerOptions) { this.sessions = ops.sessions; @@ -53,6 +59,11 @@ export class Stage3SATPHandler implements SATPHandler { ops.loggerOptions, this.monitorService, ); + const priceManagerOptions: PriceManagerOptions = { + logLevel: ops.loggerOptions.level, + monitorService: this.monitorService, + }; + this.priceManager = new PriceManager(priceManagerOptions); this.logger.trace(`Initialized ${Stage3SATPHandler.CLASS_NAME}`); } @@ -80,7 +91,7 @@ export class Stage3SATPHandler implements SATPHandler { const fnTag = `${this.getHandlerIdentifier()}#${stepTag}`; const { span, context: ctx } = this.monitorService.startSpan(fnTag); return context.with(ctx, async () => { - const attributes: Record< + let attributes: Record< string, undefined | string | number | boolean | string[] | number[] | boolean[] > = {}; @@ -117,27 +128,7 @@ export class Stage3SATPHandler implements SATPHandler { } saveMessageInSessionData(session.getServerSessionData(), message); - - attributes.senderNetworkId = - session?.getServerSessionData().senderAsset?.networkId?.id || - undefined; - attributes.receiverNetworkId = - session?.getServerSessionData().receiverAsset?.networkId?.id || - undefined; - attributes.senderGatewayNetworkId = - session?.getServerSessionData().senderGatewayNetworkId || undefined; - attributes.receiverGatewayNetworkId = - session?.getServerSessionData().recipientGatewayNetworkId || - undefined; - attributes.assetProfileId = - session?.getServerSessionData().assetProfileId || undefined; - attributes.sessionId = session?.getSessionId() || undefined; - attributes.sourceLedgerAssetId = - session?.getServerSessionData().sourceLedgerAssetId || undefined; - attributes.recipientLedgerAssetId = - session?.getServerSessionData().recipientLedgerAssetId || undefined; - attributes.satp_phase = 3; - attributes.operation = "commitPreparation"; + attributes = collectSessionAttributes(session, "server"); const startTimestamp = session.getServerSessionData().receivedTimestamps?.stage3 @@ -151,7 +142,11 @@ export class Stage3SATPHandler implements SATPHandler { await this.monitorService.recordHistogram( "operation_duration", duration, - attributes, + { ...attributes, operation: "commitPreparation", satp_phase: 3 }, + ); + } else { + this.Log.warn( + `${fnTag}, Missing timestamps for operation duration calculation`, ); } @@ -166,25 +161,11 @@ export class Stage3SATPHandler implements SATPHandler { ); setError(session, MessageType.COMMIT_READY, error); - attributes.senderNetworkId = - session?.getServerSessionData().senderAsset?.networkId?.id || - undefined; - attributes.receiverNetworkId = - session?.getServerSessionData().receiverAsset?.networkId?.id || - undefined; - attributes.senderGatewayNetworkId = - session?.getServerSessionData().senderGatewayNetworkId || undefined; - attributes.receiverGatewayNetworkId = - session?.getServerSessionData().recipientGatewayNetworkId || - undefined; - attributes.assetProfileId = - session?.getServerSessionData().assetProfileId || undefined; - attributes.sessionId = session?.getSessionId() || undefined; - attributes.sourceLedgerAssetId = - session?.getServerSessionData().sourceLedgerAssetId || undefined; - attributes.recipientLedgerAssetId = - session?.getServerSessionData().recipientLedgerAssetId || undefined; + if (session) { + attributes = collectSessionAttributes(session, "server"); + } attributes.satp_phase = 3; + attributes.operation = "commitPreparation"; this.monitorService.updateCounter( "ongoing_transactions", @@ -213,7 +194,7 @@ export class Stage3SATPHandler implements SATPHandler { const fnTag = `${this.getHandlerIdentifier()}#${stepTag}`; const { span, context: ctx } = this.monitorService.startSpan(fnTag); return context.with(ctx, async () => { - const attributes: Record< + let attributes: Record< string, undefined | string | number | boolean | string[] | number[] | boolean[] > = {}; @@ -252,26 +233,7 @@ export class Stage3SATPHandler implements SATPHandler { saveMessageInSessionData(session.getServerSessionData(), message); - attributes.senderNetworkId = - session?.getServerSessionData().senderAsset?.networkId?.id || - undefined; - attributes.receiverNetworkId = - session?.getServerSessionData().receiverAsset?.networkId?.id || - undefined; - attributes.senderGatewayNetworkId = - session?.getServerSessionData().senderGatewayNetworkId || undefined; - attributes.receiverGatewayNetworkId = - session?.getServerSessionData().recipientGatewayNetworkId || - undefined; - attributes.assetProfileId = - session?.getServerSessionData().assetProfileId || undefined; - attributes.sessionId = session?.getSessionId() || undefined; - attributes.sourceLedgerAssetId = - session?.getServerSessionData().sourceLedgerAssetId || undefined; - attributes.recipientLedgerAssetId = - session?.getServerSessionData().recipientLedgerAssetId || undefined; - attributes.satp_phase = 3; - attributes.operation = "commitFinalAssertion"; + attributes = collectSessionAttributes(session, "server"); const startTimestamp = session.getServerSessionData().receivedTimestamps?.stage3 @@ -285,7 +247,11 @@ export class Stage3SATPHandler implements SATPHandler { await this.monitorService.recordHistogram( "operation_duration", duration, - attributes, + { ...attributes, satp_phase: 3, operation: "commitFinalAssertion" }, + ); + } else { + this.Log.warn( + `${fnTag}, Missing timestamps for operation duration calculation`, ); } @@ -300,25 +266,11 @@ export class Stage3SATPHandler implements SATPHandler { ); setError(session, MessageType.ACK_COMMIT_FINAL, error); - attributes.senderNetworkId = - session?.getServerSessionData().senderAsset?.networkId?.id || - undefined; - attributes.receiverNetworkId = - session?.getServerSessionData().receiverAsset?.networkId?.id || - undefined; - attributes.senderGatewayNetworkId = - session?.getServerSessionData().senderGatewayNetworkId || undefined; - attributes.receiverGatewayNetworkId = - session?.getServerSessionData().recipientGatewayNetworkId || - undefined; - attributes.assetProfileId = - session?.getServerSessionData().assetProfileId || undefined; - attributes.sessionId = session?.getSessionId() || undefined; - attributes.sourceLedgerAssetId = - session?.getServerSessionData().sourceLedgerAssetId || undefined; - attributes.recipientLedgerAssetId = - session?.getServerSessionData().recipientLedgerAssetId || undefined; + if (session) { + attributes = collectSessionAttributes(session, "server"); + } attributes.satp_phase = 3; + attributes.operation = "commitFinalAssertion"; this.monitorService.updateCounter( "ongoing_transactions", @@ -347,7 +299,7 @@ export class Stage3SATPHandler implements SATPHandler { const fnTag = `${this.getHandlerIdentifier()}#${stepTag}`; const { span, context: ctx } = this.monitorService.startSpan(fnTag); return context.with(ctx, async () => { - const attributes: Record< + let attributes: Record< string, undefined | string | number | boolean | string[] | number[] | boolean[] > = {}; @@ -381,8 +333,7 @@ export class Stage3SATPHandler implements SATPHandler { saveMessageInSessionData(session.getServerSessionData(), message); - attributes.satp_phase = 3; - attributes.operation = "transferComplete"; + attributes = collectSessionAttributes(session, "server"); const startTimestamp = session.getServerSessionData().receivedTimestamps?.stage3 @@ -396,10 +347,59 @@ export class Stage3SATPHandler implements SATPHandler { await this.monitorService.recordHistogram( "operation_duration", duration, - attributes, + { ...attributes, satp_phase: 3, operation: "transferComplete" }, + ); + } else { + this.Log.warn( + `${fnTag}, Missing timestamps for operation duration calculation`, ); } + const receiverAssetAmount = Number( + session.getServerSessionData().receiverAsset?.amount, + ); + + const receiverGasUsed = + Number( + JSON.parse( + session.getServerSessionData().receiverWrapAssertionClaim + ?.receipt ?? "{}", + ).gas ?? 0, + ) + + Number( + JSON.parse( + session.getServerSessionData().mintAssertionClaim?.receipt ?? + "{}", + ).gas ?? 0, + ) + + Number( + JSON.parse( + session.getServerSessionData().assignmentAssertionClaim + ?.receipt ?? "{}", + ).gas ?? 0, + ); + + this.monitorService.updateCounter( + "total_value_exchanged_token", + receiverAssetAmount, + { ...attributes, transaction_direction: "received" }, + ); + + this.monitorService.updateCounter( + "total_value_exchanged_USD", + this.priceManager.convertTokensToUSD( + receiverAssetAmount, + session.getServerSessionData().receiverAsset?.networkId?.id || "", + ), + { ...attributes, transaction_direction: "received" }, + ); + + this.monitorService.updateCounter( + "transaction_gas_used", + receiverGasUsed, + { ...attributes, side: "server" }, + ); + return message; } catch (error) { this.Log.error( @@ -411,25 +411,11 @@ export class Stage3SATPHandler implements SATPHandler { ); setError(session, MessageType.COMMIT_TRANSFER_COMPLETE_RESPONSE, error); - attributes.senderNetworkId = - session?.getServerSessionData().senderAsset?.networkId?.id || - undefined; - attributes.receiverNetworkId = - session?.getServerSessionData().receiverAsset?.networkId?.id || - undefined; - attributes.senderGatewayNetworkId = - session?.getServerSessionData().senderGatewayNetworkId || undefined; - attributes.receiverGatewayNetworkId = - session?.getServerSessionData().recipientGatewayNetworkId || - undefined; - attributes.assetProfileId = - session?.getServerSessionData().assetProfileId || undefined; - attributes.sessionId = session?.getSessionId() || undefined; - attributes.sourceLedgerAssetId = - session?.getServerSessionData().sourceLedgerAssetId || undefined; - attributes.recipientLedgerAssetId = - session?.getServerSessionData().recipientLedgerAssetId || undefined; + if (session) { + attributes = collectSessionAttributes(session, "server"); + } attributes.satp_phase = 3; + attributes.operation = "transferComplete"; this.monitorService.updateCounter( "ongoing_transactions", @@ -489,10 +475,6 @@ export class Stage3SATPHandler implements SATPHandler { const fnTag = `${this.getHandlerIdentifier()}#${stepTag}`; const { span, context: ctx } = this.monitorService.startSpan(fnTag); return context.with(ctx, async () => { - const attributes: Record< - string, - undefined | string | number | boolean | string[] | number[] | boolean[] - > = {}; try { let session: SATPSession | undefined; try { @@ -537,27 +519,20 @@ export class Stage3SATPHandler implements SATPHandler { )}`, ); setError(session, MessageType.COMMIT_PREPARE, error); - - attributes.senderNetworkId = - session?.getClientSessionData()?.senderAsset?.networkId?.id || - undefined; - attributes.receiverNetworkId = - session?.getClientSessionData()?.receiverAsset?.networkId?.id || - undefined; - attributes.senderGatewayNetworkId = - session?.getClientSessionData()?.senderGatewayNetworkId || - undefined; - attributes.receiverGatewayNetworkId = - session?.getClientSessionData()?.recipientGatewayNetworkId || - undefined; - attributes.assetProfileId = - session?.getClientSessionData()?.assetProfileId || undefined; - attributes.sessionId = session?.getSessionId() || undefined; - attributes.sourceLedgerAssetId = - session?.getClientSessionData()?.sourceLedgerAssetId || undefined; - attributes.recipientLedgerAssetId = - session?.getClientSessionData()?.recipientLedgerAssetId || - undefined; + let attributes: Record< + string, + | undefined + | string + | number + | boolean + | string[] + | number[] + | boolean[] + > = {}; + + if (session) { + attributes = collectSessionAttributes(session, "client"); + } attributes.satp_phase = 3; this.monitorService.updateCounter( @@ -594,7 +569,7 @@ export class Stage3SATPHandler implements SATPHandler { const fnTag = `${this.getHandlerIdentifier()}#${stepTag}`; const { span, context: ctx } = this.monitorService.startSpan(fnTag); return context.with(ctx, async () => { - const attributes: Record< + let attributes: Record< string, undefined | string | number | boolean | string[] | number[] | boolean[] > = {}; @@ -609,6 +584,7 @@ export class Stage3SATPHandler implements SATPHandler { throw new SessionNotFoundError(fnTag); } + attributes = collectSessionAttributes(session, "client"); span.setAttribute("sessionId", session.getSessionId() || ""); await this.clientService.checkCommitPreparationResponse( @@ -634,6 +610,25 @@ export class Stage3SATPHandler implements SATPHandler { saveMessageInSessionData(session.getClientSessionData(), request); + const senderAssetAmount = Number( + session.getClientSessionData().senderAsset?.amount, + ); + + this.monitorService.updateCounter( + "total_value_exchanged_token", + senderAssetAmount, + { ...attributes, transaction_direction: "sent" }, + ); + + this.monitorService.updateCounter( + "total_value_exchanged_USD", + this.priceManager.convertTokensToUSD( + senderAssetAmount, + session.getClientSessionData().senderAsset?.networkId?.id || "", + ), + { ...attributes, transaction_direction: "sent" }, + ); + return request; } catch (error) { this.Log.error( @@ -645,26 +640,9 @@ export class Stage3SATPHandler implements SATPHandler { ); setError(session, MessageType.COMMIT_FINAL, error); - attributes.senderNetworkId = - session?.getClientSessionData()?.senderAsset?.networkId?.id || - undefined; - attributes.receiverNetworkId = - session?.getClientSessionData()?.receiverAsset?.networkId?.id || - undefined; - attributes.senderGatewayNetworkId = - session?.getClientSessionData()?.senderGatewayNetworkId || - undefined; - attributes.receiverGatewayNetworkId = - session?.getClientSessionData()?.recipientGatewayNetworkId || - undefined; - attributes.assetProfileId = - session?.getClientSessionData()?.assetProfileId || undefined; - attributes.sessionId = session?.getSessionId() || undefined; - attributes.sourceLedgerAssetId = - session?.getClientSessionData()?.sourceLedgerAssetId || undefined; - attributes.recipientLedgerAssetId = - session?.getClientSessionData()?.recipientLedgerAssetId || - undefined; + if (session) { + attributes = collectSessionAttributes(session, "client"); + } attributes.satp_phase = 3; this.monitorService.updateCounter( @@ -701,7 +679,7 @@ export class Stage3SATPHandler implements SATPHandler { const fnTag = `${this.getHandlerIdentifier()}#${stepTag}`; const { span, context: ctx } = this.monitorService.startSpan(fnTag); return context.with(ctx, async () => { - const attributes: Record< + let attributes: Record< string, undefined | string | number | boolean | string[] | number[] | boolean[] > = {}; @@ -750,26 +728,9 @@ export class Stage3SATPHandler implements SATPHandler { ); setError(session, MessageType.ACK_COMMIT_FINAL, error); - attributes.senderNetworkId = - session?.getClientSessionData()?.senderAsset?.networkId?.id || - undefined; - attributes.receiverNetworkId = - session?.getClientSessionData()?.receiverAsset?.networkId?.id || - undefined; - attributes.senderGatewayNetworkId = - session?.getClientSessionData()?.senderGatewayNetworkId || - undefined; - attributes.receiverGatewayNetworkId = - session?.getClientSessionData()?.recipientGatewayNetworkId || - undefined; - attributes.assetProfileId = - session?.getClientSessionData()?.assetProfileId || undefined; - attributes.sessionId = session?.getSessionId() || undefined; - attributes.sourceLedgerAssetId = - session?.getClientSessionData()?.sourceLedgerAssetId || undefined; - attributes.recipientLedgerAssetId = - session?.getClientSessionData()?.recipientLedgerAssetId || - undefined; + if (session) { + attributes = collectSessionAttributes(session, "client"); + } attributes.satp_phase = 3; this.monitorService.updateCounter( @@ -806,7 +767,7 @@ export class Stage3SATPHandler implements SATPHandler { const fnTag = `${this.getHandlerIdentifier()}#${stepTag}`; const { span, context: ctx } = this.monitorService.startSpan(fnTag); await context.with(ctx, async () => { - const attributes: Record< + let attributes: Record< string, undefined | string | number | boolean | string[] | number[] | boolean[] > = {}; @@ -828,32 +789,13 @@ export class Stage3SATPHandler implements SATPHandler { session, ); - attributes.sessionId = session.getSessionId() || undefined; - attributes.senderNetworkId = - session?.getClientSessionData()?.senderAsset?.networkId?.id || - undefined; - attributes.receiverNetworkId = - session?.getClientSessionData()?.receiverAsset?.networkId?.id || - undefined; - attributes.senderGatewayNetworkId = - session?.getClientSessionData()?.senderGatewayNetworkId || - undefined; - attributes.receiverGatewayNetworkId = - session?.getClientSessionData()?.recipientGatewayNetworkId || - undefined; - attributes.assetProfileId = - session?.getClientSessionData()?.assetProfileId || undefined; - attributes.sourceLedgerAssetId = - session?.getClientSessionData()?.sourceLedgerAssetId || undefined; - attributes.recipientLedgerAssetId = - session?.getClientSessionData()?.recipientLedgerAssetId || - undefined; + attributes = collectSessionAttributes(session, "client"); const stage0Str = - session?.getClientSessionData()?.processedTimestamps?.stage0 + session.getClientSessionData().processedTimestamps?.stage0 ?.newSessionRequestMessageTimestamp; const stage3Str = - session?.getClientSessionData()?.receivedTimestamps?.stage3 + session.getClientSessionData().receivedTimestamps?.stage3 ?.transferCompleteResponseMessageTimestamp; if (stage0Str && stage3Str) { @@ -863,44 +805,35 @@ export class Stage3SATPHandler implements SATPHandler { duration, attributes, ); - } - this.monitorService.updateCounter( - "transaction_gas_used", + } else + this.Log.warn( + `${fnTag}, Missing timestamps for transaction duration calculation`, + ); + + const senderGasUsed = Number( JSON.parse( - session?.getClientSessionData()?.senderWrapAssertionClaim + session.getClientSessionData().senderWrapAssertionClaim ?.receipt ?? "{}", ).gas ?? 0, ) + - Number( - JSON.parse( - session?.getClientSessionData()?.lockAssertionClaim - ?.receipt ?? "{}", - ).gas ?? 0, - ) + - Number( - JSON.parse( - session?.getClientSessionData()?.burnAssertionClaim - ?.receipt ?? "{}", - ).gas ?? 0, - ), - { ...attributes, side: "client" }, - ); - this.monitorService.updateCounter( - "transaction_gas_used", Number( JSON.parse( - session?.getClientSessionData()?.receiverWrapAssertionClaim - ?.receipt ?? "{}", + session.getClientSessionData().lockAssertionClaim?.receipt ?? + "{}", ).gas ?? 0, ) + - Number( - JSON.parse( - session?.getClientSessionData()?.mintAssertionClaim - ?.receipt ?? "{}", - ).gas ?? 0, - ), - { ...attributes, side: "server" }, + Number( + JSON.parse( + session.getClientSessionData().burnAssertionClaim?.receipt ?? + "{}", + ).gas ?? 0, + ); + + this.monitorService.updateCounter( + "transaction_gas_used", + senderGasUsed, + { ...attributes, side: "client" }, ); this.monitorService.updateCounter( "ongoing_transactions", @@ -912,16 +845,6 @@ export class Stage3SATPHandler implements SATPHandler { 1, attributes, ); - this.monitorService.updateCounter( - "total_value_exchanged", - Number(session?.getClientSessionData()?.senderAsset?.amount), - { ...attributes, transaction_direction: "sent" }, - ); - this.monitorService.updateCounter( - "total_value_exchanged", - Number(session?.getClientSessionData()?.receiverAsset?.amount), - { ...attributes, transaction_direction: "received" }, - ); saveMessageInSessionData(session.getClientSessionData(), response); } catch (error) { @@ -941,26 +864,9 @@ export class Stage3SATPHandler implements SATPHandler { error, ); - attributes.senderNetworkId = - session?.getClientSessionData()?.senderAsset?.networkId?.id || - undefined; - attributes.receiverNetworkId = - session?.getClientSessionData()?.receiverAsset?.networkId?.id || - undefined; - attributes.senderGatewayNetworkId = - session?.getClientSessionData()?.senderGatewayNetworkId || - undefined; - attributes.receiverGatewayNetworkId = - session?.getClientSessionData()?.recipientGatewayNetworkId || - undefined; - attributes.assetProfileId = - session?.getClientSessionData()?.assetProfileId || undefined; - attributes.sessionId = session?.getSessionId() || undefined; - attributes.sourceLedgerAssetId = - session?.getClientSessionData()?.sourceLedgerAssetId || undefined; - attributes.recipientLedgerAssetId = - session?.getClientSessionData()?.recipientLedgerAssetId || - undefined; + if (session) { + attributes = collectSessionAttributes(session, "client"); + } attributes.satp_phase = 3; this.monitorService.updateCounter( diff --git a/packages/cactus-plugin-satp-hermes/src/main/typescript/cross-chain-mechanisms/common/errors.ts b/packages/cactus-plugin-satp-hermes/src/main/typescript/cross-chain-mechanisms/common/errors.ts index d12f2b7dd8..c5e54a04ad 100644 --- a/packages/cactus-plugin-satp-hermes/src/main/typescript/cross-chain-mechanisms/common/errors.ts +++ b/packages/cactus-plugin-satp-hermes/src/main/typescript/cross-chain-mechanisms/common/errors.ts @@ -289,3 +289,9 @@ export class UninitializedMonitorServiceError extends BridgeInternalError { super("Uninitialized MonitorService", cause ?? null, 500, traceID, trace); } } + +export class PriceNotFoundError extends BridgeInternalError { + constructor(cause?: string | Error | null, traceID?: string, trace?: string) { + super("Price Not Found", cause ?? null, 500, traceID, trace); + } +} diff --git a/packages/cactus-plugin-satp-hermes/src/main/typescript/cross-chain-mechanisms/satp-cc-manager.ts b/packages/cactus-plugin-satp-hermes/src/main/typescript/cross-chain-mechanisms/satp-cc-manager.ts index 5edcb4d8b4..3e56152bdd 100644 --- a/packages/cactus-plugin-satp-hermes/src/main/typescript/cross-chain-mechanisms/satp-cc-manager.ts +++ b/packages/cactus-plugin-satp-hermes/src/main/typescript/cross-chain-mechanisms/satp-cc-manager.ts @@ -190,13 +190,13 @@ export class SATPCrossChainManager { } /** - * Deploys bridges based on the provided configuration. + * Deploys oracles based on the provided configuration. * - * @param bridgesConfig - An array of bridge configuration options. + * @param oraclesConfig - An array of oracle configuration options. * @returns A promise that resolves when the deployment is complete. */ public async deployOracleFromConfig( - bridgesNetworkConfig: INetworkOptions[], + oraclesConfig: INetworkOptions[], ): Promise { const fnTag = `${SATPCrossChainManager.CLASS_NAME}#deployOracleFromConfig()`; const { span, context: ctx } = this.monitorService.startSpan(fnTag); @@ -204,7 +204,7 @@ export class SATPCrossChainManager { try { this.log.debug(`${fnTag}, Deploying Oracles...`); - for (const config of bridgesNetworkConfig) { + for (const config of oraclesConfig) { await this.oracleManager?.deployOracle(config); } } catch (err) { diff --git a/packages/cactus-plugin-satp-hermes/src/main/typescript/services/monitoring/monitor.ts b/packages/cactus-plugin-satp-hermes/src/main/typescript/services/monitoring/monitor.ts index 0e8f30bff4..d0549e328c 100644 --- a/packages/cactus-plugin-satp-hermes/src/main/typescript/services/monitoring/monitor.ts +++ b/packages/cactus-plugin-satp-hermes/src/main/typescript/services/monitoring/monitor.ts @@ -204,8 +204,12 @@ export class MonitorService { "Total number of sessions created", ); this.createCounter( - "total_value_exchanged", - "Total token value exchanged", + "total_value_exchanged_USD", + "Total token value exchanged in USD", + ); + this.createCounter( + "total_value_exchanged_token", + "Total token value exchanged in token units", ); this.createCounter( "initiated_transactions", diff --git a/packages/cactus-plugin-satp-hermes/src/main/typescript/services/token-price-check/price-manager.ts b/packages/cactus-plugin-satp-hermes/src/main/typescript/services/token-price-check/price-manager.ts new file mode 100644 index 0000000000..b463305fb3 --- /dev/null +++ b/packages/cactus-plugin-satp-hermes/src/main/typescript/services/token-price-check/price-manager.ts @@ -0,0 +1,86 @@ +/** + * @file price-manager.ts + * @description This file contains the mock implementation of the PriceManager class, which is responsible for managing token prices for different ledger types. + * It provides methods to check token prices. + */ +import { LogLevelDesc } from "@hyperledger/cactus-common"; +import { SATPLoggerProvider as LoggerProvider } from "../../core/satp-logger-provider"; +import { SATPLogger as Logger } from "../../core/satp-logger"; +import { MonitorService } from "../monitoring/monitor"; +import { PriceNotFoundError } from "../../cross-chain-mechanisms/common/errors"; + +/** + * Options for configuring the PriceManager. + * + * @property {LogLevelDesc} [logLevel] - The log level for the PriceManager. + * @property {MonitorService} [monitorService] - An instance of MonitorService to be used for logging and monitoring. + * @property {string} [configurationPath] - The path to the directory containing files with sources for token prices. + */ +export interface PriceManagerOptions { + logLevel?: LogLevelDesc; + configurationPath?: string; + monitorService: MonitorService; +} + +/** + * The PriceManager class is responsible for managing token price checks. + * WARNING: This is a mock implementation + * + * @class PriceManager + */ +export class PriceManager { + public static readonly CLASS_NAME = "PriceManager"; + private readonly logLevel: LogLevelDesc; + private readonly monitorService: MonitorService; + private readonly logger: Logger; + + private sources: Map> = new Map< + string, + Map + >(); + + /** + * Creates an instance of PriceManager. + * @constructor + * @param {PriceManagerOptions} options - The options for configuring the PriceManager. + */ + constructor(options: PriceManagerOptions) { + //const fnTag = `${PriceManager.CLASS_NAME}#constructor()`; + const label = PriceManager.CLASS_NAME; + this.logLevel = options.logLevel || "INFO"; + this.monitorService = options.monitorService; + this.logger = LoggerProvider.getOrCreate( + { label, level: this.logLevel }, + this.monitorService, + ); + } + + /** + * Converts token amounts to USD based on the network. + * WARNING: This is a mock implementation + * @param {number} amount - The amount of tokens to convert. + * @param {string} networkId - The network ID to determine the exchange rate. + * @returns {number} - The equivalent amount in USD. + * @throws {PriceNotFoundError} - If the price for the given networkId is not found or if the amount is invalid. + */ + public convertTokensToUSD(amount: number, networkId: string): number { + if (amount === undefined || isNaN(amount) || amount <= 0) { + this.logger.error(`Invalid amount: ${amount}`); + throw new PriceNotFoundError(`Invalid amount: ${amount}`); + } + const exchangeRates: { [key: string]: number } = { + BesuLedgerTestNetwork: 2, // 1 token = 2 USD + EthereumLedgerTestNetwork: 1.5, // 1 token = 1.5 USD + FabricLedgerTestNetwork: 0.5, // 1 token = 0.5 USD + }; + + const rate = exchangeRates[networkId]; + if (rate === undefined) { + this.logger.error(`Price not found for networkId: ${networkId}`); + throw new PriceNotFoundError( + `Price not found for networkId: ${networkId}`, + ); + } + return amount * rate; + } +}