From ecbf7f7b3e29bae4024882d48927a24db835e8eb Mon Sep 17 00:00:00 2001 From: "ceza.exe" Date: Thu, 28 May 2026 23:33:38 +0000 Subject: [PATCH 1/2] =?UTF-8?q?#296=20=F0=9F=93=9D=20QA=20|=20Automated=20?= =?UTF-8?q?Pre-Commit=20Linter=20Enforcement=20FIXED?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .husky/pre-commit | 4 +- dist/controllers/marketRatesController.d.ts | 2 +- .../marketRatesController.d.ts.map | 2 +- dist/controllers/marketRatesController.js | 21 +- dist/controllers/marketRatesController.js.map | 2 +- dist/index.d.ts.map | 2 +- dist/index.js | 99 ++- dist/index.js.map | 2 +- dist/middleware/apiKeyMiddleware.d.ts | 25 + dist/middleware/apiKeyMiddleware.d.ts.map | 2 +- dist/middleware/apiKeyMiddleware.js | 184 ++++-- dist/middleware/apiKeyMiddleware.js.map | 2 +- dist/routes/assets.d.ts.map | 2 +- dist/routes/assets.js | 6 +- dist/routes/assets.js.map | 2 +- dist/routes/history.d.ts.map | 2 +- dist/routes/history.js | 10 +- dist/routes/history.js.map | 2 +- dist/routes/intelligence.d.ts.map | 2 +- dist/routes/intelligence.js | 16 +- dist/routes/intelligence.js.map | 2 +- dist/routes/marketRates.d.ts.map | 2 +- dist/routes/marketRates.js | 65 +- dist/routes/marketRates.js.map | 2 +- dist/routes/priceUpdates.d.ts.map | 2 +- dist/routes/priceUpdates.js | 61 +- dist/routes/priceUpdates.js.map | 2 +- dist/routes/stats.d.ts.map | 2 +- dist/routes/stats.js | 117 +++- dist/routes/stats.js.map | 2 +- dist/services/errorTracker.d.ts.map | 2 +- dist/services/errorTracker.js | 2 + dist/services/errorTracker.js.map | 2 +- dist/services/marketRate/ghsFetcher.d.ts.map | 2 +- dist/services/marketRate/ghsFetcher.js | 9 + dist/services/marketRate/ghsFetcher.js.map | 2 +- dist/services/marketRate/index.d.ts | 1 + dist/services/marketRate/index.d.ts.map | 2 +- dist/services/marketRate/index.js | 1 + dist/services/marketRate/index.js.map | 2 +- dist/services/marketRate/kesFetcher.d.ts.map | 2 +- dist/services/marketRate/kesFetcher.js | 9 + dist/services/marketRate/kesFetcher.js.map | 2 +- .../marketRate/marketRateService.d.ts | 4 + .../marketRate/marketRateService.d.ts.map | 2 +- dist/services/marketRate/marketRateService.js | 96 ++- .../marketRate/marketRateService.js.map | 2 +- dist/services/marketRate/ngnFetcher.d.ts | 1 + dist/services/marketRate/ngnFetcher.d.ts.map | 2 +- dist/services/marketRate/ngnFetcher.js | 70 +- dist/services/marketRate/ngnFetcher.js.map | 2 +- dist/services/marketRate/types.d.ts | 7 + dist/services/marketRate/types.d.ts.map | 2 +- dist/services/marketRate/types.js.map | 2 +- dist/services/multiSigService.d.ts | 55 +- dist/services/multiSigService.d.ts.map | 2 +- dist/services/multiSigService.js | 151 ++--- dist/services/multiSigService.js.map | 2 +- dist/services/sorobanEventListener.d.ts.map | 2 +- dist/services/sorobanEventListener.js | 9 +- dist/services/sorobanEventListener.js.map | 2 +- dist/services/stellarService.d.ts | 62 +- dist/services/stellarService.d.ts.map | 2 +- dist/services/stellarService.js | 243 ++++--- dist/services/stellarService.js.map | 2 +- dist/services/webhook.d.ts | 16 + dist/services/webhook.d.ts.map | 2 +- dist/services/webhook.js | 193 +++++- dist/services/webhook.js.map | 2 +- dist/utils/envValidator.d.ts.map | 2 +- dist/utils/envValidator.js | 16 +- dist/utils/envValidator.js.map | 2 +- package-lock.json | 611 +++++++++++++++++- 73 files changed, 1700 insertions(+), 550 deletions(-) diff --git a/.husky/pre-commit b/.husky/pre-commit index 5a97ac05..a7fd738e 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,2 +1,4 @@ #!/usr/bin/env sh -npm run style:check +set -e +npm run lint +npx lint-staged diff --git a/dist/controllers/marketRatesController.d.ts b/dist/controllers/marketRatesController.d.ts index 8fad6b74..49af9792 100644 --- a/dist/controllers/marketRatesController.d.ts +++ b/dist/controllers/marketRatesController.d.ts @@ -1,4 +1,4 @@ import { Request, Response } from "express"; -export declare const getRate: (req: Request, res: Response) => Promise> | undefined>; +export declare const getRate: (req: Request, res: Response) => Promise; export declare const getAllRates: (req: Request, res: Response) => Promise; //# sourceMappingURL=marketRatesController.d.ts.map \ No newline at end of file diff --git a/dist/controllers/marketRatesController.d.ts.map b/dist/controllers/marketRatesController.d.ts.map index eeee99b0..c822331d 100644 --- a/dist/controllers/marketRatesController.d.ts.map +++ b/dist/controllers/marketRatesController.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"marketRatesController.d.ts","sourceRoot":"","sources":["../../src/controllers/marketRatesController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAK5C,eAAO,MAAM,OAAO,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,4DA2BxD,CAAC;AAEF,eAAO,MAAM,WAAW,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,kBAgB5D,CAAC"} \ No newline at end of file +{"version":3,"file":"marketRatesController.d.ts","sourceRoot":"","sources":["../../src/controllers/marketRatesController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAM5C,eAAO,MAAM,OAAO,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,kBAkBxD,CAAC;AAEF,eAAO,MAAM,WAAW,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,kBAa5D,CAAC"} \ No newline at end of file diff --git a/dist/controllers/marketRatesController.js b/dist/controllers/marketRatesController.js index 97176fef..5aaad2e5 100644 --- a/dist/controllers/marketRatesController.js +++ b/dist/controllers/marketRatesController.js @@ -1,13 +1,11 @@ +import { sendApiError } from "../lib/apiError.js"; import { MarketRateService } from "../services/marketRate"; const marketRateService = new MarketRateService(); export const getRate = async (req, res) => { try { const { currency } = req.params; if (!currency || typeof currency !== "string") { - return res.status(400).json({ - success: false, - error: "Currency parameter is required and must be a string", - }); + return sendApiError(res, 400, "BAD_REQUEST", "Currency parameter is required and must be a string"); } const result = await marketRateService.getRate(currency); if (result.success) { @@ -17,17 +15,11 @@ export const getRate = async (req, res) => { }); } else { - res.status(404).json({ - success: false, - error: result.error, - }); + sendApiError(res, 404, "NOT_FOUND", typeof (result.error) === "string" ? String(result.error) : undefined); } } catch (error) { - res.status(500).json({ - success: false, - error: error instanceof Error ? error.message : "Internal server error", - }); + sendApiError(res, 500, "INTERNAL_SERVER_ERROR", typeof (error instanceof Error ? error.message : "Internal server error") === "string" ? String(error instanceof Error ? error.message : "Internal server error") : undefined); } }; export const getAllRates = async (req, res) => { @@ -42,10 +34,7 @@ export const getAllRates = async (req, res) => { }); } catch (error) { - res.status(500).json({ - success: false, - error: error instanceof Error ? error.message : "Internal server error", - }); + sendApiError(res, 500, "INTERNAL_SERVER_ERROR", typeof (error instanceof Error ? error.message : "Internal server error") === "string" ? String(error instanceof Error ? error.message : "Internal server error") : undefined); } }; //# sourceMappingURL=marketRatesController.js.map \ No newline at end of file diff --git a/dist/controllers/marketRatesController.js.map b/dist/controllers/marketRatesController.js.map index 49266a1c..5066cab0 100644 --- a/dist/controllers/marketRatesController.js.map +++ b/dist/controllers/marketRatesController.js.map @@ -1 +1 @@ -{"version":3,"file":"marketRatesController.js","sourceRoot":"","sources":["../../src/controllers/marketRatesController.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,MAAM,iBAAiB,GAAG,IAAI,iBAAiB,EAAE,CAAC;AAElD,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;IAC3D,IAAI,CAAC;QACH,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC;QAChC,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC9C,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBAC1B,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,qDAAqD;aAC7D,CAAC,CAAC;QACL,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACzD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,GAAG,CAAC,IAAI,CAAC;gBACP,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE,MAAM,CAAC,IAAI;aAClB,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,MAAM,CAAC,KAAK;aACpB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB;SACxE,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;IAC/D,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,WAAW,EAAE,CAAC;QACtD,MAAM,KAAK,GAAG,OAAO;aAClB,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC;aAClC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAChC,GAAG,CAAC,IAAI,CAAC;YACP,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,KAAK;SACZ,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB;SACxE,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC"} \ No newline at end of file +{"version":3,"file":"marketRatesController.js","sourceRoot":"","sources":["../../src/controllers/marketRatesController.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,MAAM,iBAAiB,GAAG,IAAI,iBAAiB,EAAE,CAAC;AAElD,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;IAC3D,IAAI,CAAC;QACH,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC;QAChC,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC9C,OAAO,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,aAAa,EAAE,qDAAqD,CAAC,CAAC;QACtG,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACzD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,GAAG,CAAC,IAAI,CAAC;gBACP,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE,MAAM,CAAC,IAAI;aAClB,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC7G,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,uBAAuB,EAAE,OAAO,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACjO,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;IAC/D,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,WAAW,EAAE,CAAC;QACtD,MAAM,KAAK,GAAG,OAAO;aAClB,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC;aAClC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAChC,GAAG,CAAC,IAAI,CAAC;YACP,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,KAAK;SACZ,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,uBAAuB,EAAE,OAAO,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACjO,CAAC;AACH,CAAC,CAAC"} \ No newline at end of file diff --git a/dist/index.d.ts.map b/dist/index.d.ts.map index 1816972b..975ffa9f 100644 --- a/dist/index.d.ts.map +++ b/dist/index.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,GAAG,MAAM,OAAO,CAAC;AAwVxB,eAAe,GAAG,CAAC"} \ No newline at end of file +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,GAAG,MAAM,OAAO,CAAC;AA0bxB,eAAe,GAAG,CAAC"} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index e68395a1..c6efc026 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,20 +1,32 @@ import { createServer } from "http"; +import cors from "cors"; import dotenv from "dotenv"; +import express from "express"; import { Horizon } from "@stellar/stellar-sdk"; +import marketRatesRouter from "./routes/marketRates"; +import historyRouter from "./routes/history"; +import priceUpdatesRouter from "./routes/priceUpdates"; +import statsRouter from "./routes/stats"; import app from "./app"; import prisma from "./lib/prisma"; import { disconnectRedis } from "./lib/redis"; import { initSocket } from "./lib/socket"; import { SorobanEventListener } from "./services/sorobanEventListener"; import { multiSigSubmissionService } from "./services/multiSigSubmissionService"; +import { getGasBalanceMonitorService, } from "./services/gasBalanceMonitorService"; import { validateEnv } from "./utils/envValidator"; import { enableGlobalLogMasking } from "./utils/logMasker"; import { hourlyAverageService } from "./services/hourlyAverageService"; +import { getRegionalHealthService } from "./services/regionalHealthService"; import { watchConfig } from "./config/configWatcher"; +import { startEnvFileWatcher } from "./config/envFileWatcher"; import { validateDatabaseSchema } from "./utils/dbValidator"; import { initializeTracing } from "./config/tracingConfig"; import { setupAxiosTracing } from "./lib/tracing"; import { registerTracingShutdownHandlers } from "./utils/shutdownTracing"; +import { providerSecretRotationService } from "./services/providerSecretRotationService"; +import { priceAggregatorService } from "./services/priceAggregatorService"; +import { contractSanityCheckService } from "./services/contractSanityCheckService"; // Load environment variables dotenv.config(); // Initialize tracing before other services @@ -25,6 +37,8 @@ setupAxiosTracing(); registerTracingShutdownHandlers(); // Enable log masking to prevent sensitive data leaks enableGlobalLogMasking(); +// Start regional health monitoring before we accept requests. +await getRegionalHealthService().startMonitoring(); // [OPS] Implement "Environment Variable" Check on Start validateEnv(); // [OPS] Validate database schema on startup @@ -57,6 +71,14 @@ const horizonUrl = stellarNetwork === "PUBLIC" ? "https://horizon.stellar.org" : "https://horizon-testnet.stellar.org"; const horizonServer = new Horizon.Server(horizonUrl); +// Middleware +app.use(cors()); +app.use(express.json()); +// Routes +app.use("/api/market-rates", marketRatesRouter); +app.use("/api/history", historyRouter); +app.use("/api/price-updates", priceUpdatesRouter); +app.use("/api/stats", statsRouter); // Health check endpoint /** * @swagger @@ -173,6 +195,7 @@ app.get("/", (req, res) => { }, stats: { volume: "/api/v1/stats/volume?date=YYYY-MM-DD", + relayers: "/api/stats/relayers", }, history: { assetHistory: "/api/v1/history/:asset?range=1d|7d|30d|90d", @@ -189,6 +212,9 @@ app.get("/", (req, res) => { const httpServer = createServer(app); initSocket(httpServer); let sorobanEventListener = null; +// FIX 1: Typed as nullable — constructor is not called at module level, +// so a missing secret env var won't crash the process before the server starts. +let gasBalanceMonitorService = null; let isShuttingDown = false; let stopEnvFileWatcher; const stopConfigWatcher = watchConfig((cfg) => { @@ -222,7 +248,11 @@ const shutdown = async (signal) => { try { sorobanEventListener?.stop(); multiSigSubmissionService.stop(); + // FIX 2: Optional chaining — safe to call even if service never started + gasBalanceMonitorService?.stop(); hourlyAverageService.stop(); + priceAggregatorService.stop(); + providerSecretRotationService.stop(); stopConfigWatcher(); stopEnvFileWatcher?.(); await closeHttpServer(); @@ -250,23 +280,49 @@ process.once("SIGTERM", () => { process.exit(1); }); }); -httpServer.listen(PORT, () => { +httpServer.listen(PORT, async () => { console.log(`🌊 StellarFlow Backend running on port ${PORT}`); console.log(`📊 Market Rates API available at http://localhost:${PORT}/api/market-rates`); console.log(`📚 API Documentation available at http://localhost:${PORT}/api/docs`); console.log(`đŸĨ Health check at http://localhost:${PORT}/health`); console.log(`🔌 Socket.io ready for dashboard connections`); + // Perform contract sanity check before starting ingestion loop + let contractSanityPassed = true; + if (contractSanityCheckService.isConfigured()) { + try { + const sanityResult = await contractSanityCheckService.performSanityCheck(); + if (!sanityResult.success) { + console.error(`❌ Contract sanity check failed: ${sanityResult.error}`); + console.error("⛔ Preventing ingestion loop from starting due to contract failure"); + contractSanityPassed = false; + } + } + catch (err) { + console.error("❌ Contract sanity check error:", err instanceof Error ? err.message : err); + console.error("⛔ Preventing ingestion loop from starting due to contract check error"); + contractSanityPassed = false; + } + } + else { + console.log("â„šī¸ CONTRACT_ID not configured - skipping contract sanity check (ingestion loop will start)"); + } // Start Soroban event listener to track confirmed on-chain prices - try { - sorobanEventListener = new SorobanEventListener(); - sorobanEventListener.start().catch((err) => { - console.error("Failed to start event listener:", err); - }); - console.log(`👂 Soroban event listener started`); + // Only start if contract sanity check passed or if check is not configured + if (contractSanityPassed) { + try { + sorobanEventListener = new SorobanEventListener(); + sorobanEventListener.start().catch((err) => { + console.error("Failed to start event listener:", err); + }); + console.log(`👂 Soroban event listener started`); + } + catch (err) { + console.warn("Event listener not started:", err instanceof Error ? err.message : err); + sorobanEventListener = null; + } } - catch (err) { - console.warn("Event listener not started:", err instanceof Error ? err.message : err); - sorobanEventListener = null; + else { + console.warn("âš ī¸ Soroban event listener NOT started due to failed contract sanity check"); } // Start multi-sig submission service if enabled if (process.env.MULTI_SIG_ENABLED === "true") { @@ -290,6 +346,29 @@ httpServer.listen(PORT, () => { catch (err) { console.warn("Hourly average service not started:", err instanceof Error ? err.message : err); } + // Issue #208 – Start OHLC price aggregation worker + try { + priceAggregatorService.start().catch((err) => { + console.error("Failed to start OHLC price aggregator:", err); + }); + console.log(`📈 OHLC price aggregator started (MINUTE / HOUR / DAY)`); + } + catch (err) { + console.warn("OHLC price aggregator not started:", err instanceof Error ? err.message : err); + } + // FIX 3: getGasBalanceMonitorService() moved inside the listen callback so + // the constructor (and Keypair.fromSecret) only runs after the server is up. + // A missing secret env var now warns gracefully instead of crashing the process. + try { + gasBalanceMonitorService = getGasBalanceMonitorService(); + gasBalanceMonitorService.start().catch((err) => { + console.error("Failed to start gas balance monitor service:", err); + }); + console.log(`â›Ŋ Gas balance monitor service started`); + } + catch (err) { + console.warn("Gas balance monitor service not started:", err instanceof Error ? err.message : err); + } }); export default app; //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/index.js.map b/dist/index.js.map index 8a5c50e7..46495fc2 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/middleware/apiKeyMiddleware.d.ts b/dist/middleware/apiKeyMiddleware.d.ts index 7851b996..cfb08322 100644 --- a/dist/middleware/apiKeyMiddleware.d.ts +++ b/dist/middleware/apiKeyMiddleware.d.ts @@ -1,3 +1,28 @@ import { Request, Response, NextFunction } from "express"; +import { AuthenticatedApiKey } from "../types/apiKey.types"; +declare global { + namespace Express { + interface Request { + apiKey?: AuthenticatedApiKey; + } + } +} +/** + * `apiKeyAuth()` + * + * Drop this onto any router or individual route that needs + * API-key protection: + * + * router.use(apiKeyAuth()); // protect all verbs + * router.post("/prices", apiKeyAuth(), handler); // just POST + * + * The middleware automatically maps the HTTP method to the + * required scope, so you never have to pass a scope manually. + */ +export declare function apiKeyAuth(): (req: Request, res: Response, next: NextFunction) => Promise; export declare const apiKeyMiddleware: (req: Request, res: Response, next: NextFunction) => Promise; +/** Require the "read" scope explicitly (ignores HTTP method). */ +export declare function requireReadScope(): (_req: Request, res: Response, next: NextFunction) => void; +/** Require the "write" scope explicitly (ignores HTTP method). */ +export declare function requireWriteScope(): (_req: Request, res: Response, next: NextFunction) => void; //# sourceMappingURL=apiKeyMiddleware.d.ts.map \ No newline at end of file diff --git a/dist/middleware/apiKeyMiddleware.d.ts.map b/dist/middleware/apiKeyMiddleware.d.ts.map index a824661c..db42df23 100644 --- a/dist/middleware/apiKeyMiddleware.d.ts.map +++ b/dist/middleware/apiKeyMiddleware.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"apiKeyMiddleware.d.ts","sourceRoot":"","sources":["../../src/middleware/apiKeyMiddleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG1D,eAAO,MAAM,gBAAgB,GAC3B,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,MAAM,YAAY,KACjB,OAAO,CAAC,IAAI,CAgEd,CAAC"} \ No newline at end of file +{"version":3,"file":"apiKeyMiddleware.d.ts","sourceRoot":"","sources":["../../src/middleware/apiKeyMiddleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG1D,OAAO,EAEL,mBAAmB,EAGpB,MAAM,uBAAuB,CAAC;AAM/B,OAAO,CAAC,MAAM,CAAC;IAEb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,MAAM,CAAC,EAAE,mBAAmB,CAAC;SAC9B;KACF;CACF;AAeD;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,KAEtB,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,MAAM,YAAY,KACjB,OAAO,CAAC,IAAI,CAAC,CAsHjB;AAED,eAAO,MAAM,gBAAgB,QA3HpB,OAAO,OACP,QAAQ,QACP,YAAY,KACjB,OAAO,CAAC,IAAI,CAwH2B,CAAC;AAS7C,iEAAiE;AACjE,wBAAgB,gBAAgB,WAUhB,OAAO,OAAO,QAAQ,QAAQ,YAAY,KAAG,IAAI,CARhE;AAED,kEAAkE;AAClE,wBAAgB,iBAAiB,WAKjB,OAAO,OAAO,QAAQ,QAAQ,YAAY,KAAG,IAAI,CAHhE"} \ No newline at end of file diff --git a/dist/middleware/apiKeyMiddleware.js b/dist/middleware/apiKeyMiddleware.js index 1e2d9c0f..6d01bbc7 100644 --- a/dist/middleware/apiKeyMiddleware.js +++ b/dist/middleware/apiKeyMiddleware.js @@ -1,60 +1,130 @@ +import crypto from "crypto"; import prisma from "../lib/prisma"; -export const apiKeyMiddleware = async (req, res, next) => { - // Short-circuit if already authenticated by a previous middleware instance - if (req.relayer) { +import { sendApiError } from "../lib/apiError.js"; +import { hasScope, requiredScopeForMethod, } from "../types/apiKey.types"; +// ------------------------------------------------------------------ +// Helpers +// ------------------------------------------------------------------ +/** SHA-256 hash of the raw key (what we store in the DB) */ +function hashKey(rawKey) { + return crypto.createHash("sha256").update(rawKey).digest("hex"); +} +// ------------------------------------------------------------------ +// Main middleware factory +// ------------------------------------------------------------------ +/** + * `apiKeyAuth()` + * + * Drop this onto any router or individual route that needs + * API-key protection: + * + * router.use(apiKeyAuth()); // protect all verbs + * router.post("/prices", apiKeyAuth(), handler); // just POST + * + * The middleware automatically maps the HTTP method to the + * required scope, so you never have to pass a scope manually. + */ +export function apiKeyAuth() { + return async function (req, res, next) { + // ── 1. Extract raw key from header ────────────────────────── + const rawKey = req.headers["x-api-key"]; + if (!rawKey || typeof rawKey !== "string" || rawKey.trim() === "") { + sendApiError(res, 401, "MISSING_API_KEY"); + return; + } + // ── 2. Resolve the required scope ─────────────────────────── + const required = requiredScopeForMethod(req.method); + if (required === null) { + sendApiError(res, 405, "METHOD_NOT_ALLOWED", `HTTP method "${req.method}" is not supported.`); + return; + } + // ── 3. Look up the hashed key in PostgreSQL ────────────────── + let apiKeyRecord; + try { + apiKeyRecord = (await prisma.apiKey.findUnique({ + where: { key: hashKey(rawKey.trim()) }, + select: { + id: true, + label: true, + scopes: true, + ownerId: true, + isActive: true, + expiresAt: true, + lastUsedAt: true, + }, + })); + } + catch (dbError) { + console.error("[apiKeyAuth] DB lookup failed:", dbError); + sendApiError(res, 503, "SERVICE_UNAVAILABLE", "Authentication service temporarily unavailable."); + return; + } + // ── 4. Key not found ───────────────────────────────────────── + if (!apiKeyRecord) { + sendApiError(res, 401, "INVALID_API_KEY", "The provided API key is invalid."); + return; + } + // ── 5. Key disabled ────────────────────────────────────────── + if (!apiKeyRecord.isActive) { + sendApiError(res, 403, "API_KEY_INACTIVE"); + return; + } + // ── 6. Key expired ─────────────────────────────────────────── + if (apiKeyRecord.expiresAt && apiKeyRecord.expiresAt < new Date()) { + sendApiError(res, 403, "API_KEY_EXPIRED", `This API key expired on ${apiKeyRecord.expiresAt.toISOString()}.`); + return; + } + // ── 7. Scope check ─────────────────────────────────────────── + if (!hasScope(apiKeyRecord.scopes, required)) { + sendApiError(res, 403, "INSUFFICIENT_SCOPE", `This endpoint requires the "${required}" scope. ` + + `Your key has: [${apiKeyRecord.scopes.join(", ") || "none"}].`); + return; + } + // ── 8. Stamp req.apiKey and fire last-used update async ────── + req.apiKey = { + id: apiKeyRecord.id, + label: apiKeyRecord.label, + scopes: apiKeyRecord.scopes, + ownerId: apiKeyRecord.ownerId, + }; + // Non-blocking: update lastUsedAt in the background so we + // don't add DB latency to every authenticated request. + prisma.apiKey + .update({ + where: { id: apiKeyRecord.id }, + data: { lastUsedAt: new Date() }, + }) + .catch((err) => console.warn("[apiKeyAuth] lastUsedAt update failed:", err.message)); + next(); + }; +} +export const apiKeyMiddleware = apiKeyAuth(); +// ------------------------------------------------------------------ +// Optional: scope-specific shorthand helpers +// Use these when you want to lock a single route to one scope +// regardless of the HTTP method (e.g., an admin GET that touches +// sensitive data and should require write scope). +// ------------------------------------------------------------------ +/** Require the "read" scope explicitly (ignores HTTP method). */ +export function requireReadScope() { + return scopeGuard("read"); +} +/** Require the "write" scope explicitly (ignores HTTP method). */ +export function requireWriteScope() { + return scopeGuard("write"); +} +function scopeGuard(scope) { + return (_req, res, next) => { + const key = _req.apiKey; + if (!key) { + sendApiError(res, 401, "UNAUTHENTICATED", "apiKeyAuth() must run before scopeGuard."); + return; + } + if (!hasScope(key.scopes, scope)) { + sendApiError(res, 403, "INSUFFICIENT_SCOPE", `This action requires the "${scope}" scope.`); + return; + } next(); - return; - } - const apiKey = req.headers["x-api-key"]; - if (typeof apiKey !== "string" || apiKey.length === 0) { - res.status(401).json({ - success: false, - error: "Invalid or missing API key", - }); - return; - } - try { - // 1. Try to find an active relayer with this API key - const relayer = await prisma.relayer.findFirst({ - where: { - apiKey, - isActive: true, - }, - }); - if (relayer) { - req.relayer = { - id: relayer.id, - name: relayer.name, - allowedAssets: relayer.allowedAssets, - }; - next(); - return; - } - // 2. Fall back to global API key for backward compatibility - const expectedKey = process.env.API_KEY; - if (!expectedKey) { - console.error("Critical: API_KEY not set in environment"); - res.status(500).json({ - success: false, - error: "Authentication configuration error", - }); - return; - } - if (apiKey === expectedKey) { - next(); - return; - } - res.status(401).json({ - success: false, - error: "Invalid or missing API key", - }); - } - catch (error) { - console.error("[apiKeyMiddleware] Error during authentication:", error); - res.status(500).json({ - success: false, - error: "Authentication check failed", - }); - } -}; + }; +} //# sourceMappingURL=apiKeyMiddleware.js.map \ No newline at end of file diff --git a/dist/middleware/apiKeyMiddleware.js.map b/dist/middleware/apiKeyMiddleware.js.map index da1b6900..3b185bf7 100644 --- a/dist/middleware/apiKeyMiddleware.js.map +++ b/dist/middleware/apiKeyMiddleware.js.map @@ -1 +1 @@ -{"version":3,"file":"apiKeyMiddleware.js","sourceRoot":"","sources":["../../src/middleware/apiKeyMiddleware.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,eAAe,CAAC;AAEnC,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EACnC,GAAY,EACZ,GAAa,EACb,IAAkB,EACH,EAAE;IACjB,2EAA2E;IAC3E,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QAChB,IAAI,EAAE,CAAC;QACP,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAExC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,4BAA4B;SACpC,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,qDAAqD;QACrD,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC;YAC7C,KAAK,EAAE;gBACL,MAAM;gBACN,QAAQ,EAAE,IAAI;aACf;SACF,CAAC,CAAC;QAEH,IAAI,OAAO,EAAE,CAAC;YACZ,GAAG,CAAC,OAAO,GAAG;gBACZ,EAAE,EAAE,OAAO,CAAC,EAAE;gBACd,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,aAAa,EAAE,OAAO,CAAC,aAAa;aACrC,CAAC;YACF,IAAI,EAAE,CAAC;YACP,OAAO;QACT,CAAC;QAED,4DAA4D;QAC5D,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;QAExC,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;YAC1D,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,oCAAoC;aAC5C,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,IAAI,MAAM,KAAK,WAAW,EAAE,CAAC;YAC3B,IAAI,EAAE,CAAC;YACP,OAAO;QACT,CAAC;QAED,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,4BAA4B;SACpC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,iDAAiD,EAAE,KAAK,CAAC,CAAC;QACxE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,6BAA6B;SACrC,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC"} \ No newline at end of file +{"version":3,"file":"apiKeyMiddleware.js","sourceRoot":"","sources":["../../src/middleware/apiKeyMiddleware.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,OAAO,MAAM,MAAM,eAAe,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAGL,QAAQ,EACR,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAe/B,qEAAqE;AACrE,UAAU;AACV,qEAAqE;AAErE,4DAA4D;AAC5D,SAAS,OAAO,CAAC,MAAc;IAC7B,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAClE,CAAC;AAED,qEAAqE;AACrE,0BAA0B;AAC1B,qEAAqE;AAErE;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,UAAU;IACxB,OAAO,KAAK,WACV,GAAY,EACZ,GAAa,EACb,IAAkB;QAElB,+DAA+D;QAC/D,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAExC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAClE,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,iBAAiB,CAAC,CAAC;YAC1C,OAAO;QACT,CAAC;QAED,+DAA+D;QAC/D,MAAM,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAEpD,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACtB,YAAY,CACV,GAAG,EACH,GAAG,EACH,oBAAoB,EACpB,gBAAgB,GAAG,CAAC,MAAM,qBAAqB,CAChD,CAAC;YACF,OAAO;QACT,CAAC;QAED,gEAAgE;QAChE,IAAI,YAQI,CAAC;QAET,IAAI,CAAC;YACH,YAAY,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC;gBAC7C,KAAK,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE;gBACtC,MAAM,EAAE;oBACN,EAAE,EAAE,IAAI;oBACR,KAAK,EAAE,IAAI;oBACX,MAAM,EAAE,IAAI;oBACZ,OAAO,EAAE,IAAI;oBACb,QAAQ,EAAE,IAAI;oBACd,SAAS,EAAE,IAAI;oBACf,UAAU,EAAE,IAAI;iBACjB;aACF,CAAC,CAAwB,CAAC;QAC7B,CAAC;QAAC,OAAO,OAAO,EAAE,CAAC;YACjB,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,OAAO,CAAC,CAAC;YACzD,YAAY,CACV,GAAG,EACH,GAAG,EACH,qBAAqB,EACrB,iDAAiD,CAClD,CAAC;YACF,OAAO;QACT,CAAC;QAED,gEAAgE;QAChE,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,YAAY,CACV,GAAG,EACH,GAAG,EACH,iBAAiB,EACjB,kCAAkC,CACnC,CAAC;YACF,OAAO;QACT,CAAC;QAED,gEAAgE;QAChE,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;YAC3B,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,kBAAkB,CAAC,CAAC;YAC3C,OAAO;QACT,CAAC;QAED,gEAAgE;QAChE,IAAI,YAAY,CAAC,SAAS,IAAI,YAAY,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC;YAClE,YAAY,CACV,GAAG,EACH,GAAG,EACH,iBAAiB,EACjB,2BAA2B,YAAY,CAAC,SAAS,CAAC,WAAW,EAAE,GAAG,CACnE,CAAC;YACF,OAAO;QACT,CAAC;QAED,gEAAgE;QAChE,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,MAAoB,EAAE,QAAQ,CAAC,EAAE,CAAC;YAC3D,YAAY,CACV,GAAG,EACH,GAAG,EACH,oBAAoB,EACpB,+BAA+B,QAAQ,WAAW;gBAChD,kBAAkB,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,IAAI,CACjE,CAAC;YACF,OAAO;QACT,CAAC;QAED,gEAAgE;QAChE,GAAG,CAAC,MAAM,GAAG;YACX,EAAE,EAAE,YAAY,CAAC,EAAE;YACnB,KAAK,EAAE,YAAY,CAAC,KAAK;YACzB,MAAM,EAAE,YAAY,CAAC,MAAoB;YACzC,OAAO,EAAE,YAAY,CAAC,OAAO;SAC9B,CAAC;QAEF,0DAA0D;QAC1D,uDAAuD;QACvD,MAAM,CAAC,MAAM;aACV,MAAM,CAAC;YACN,KAAK,EAAE,EAAE,EAAE,EAAE,YAAY,CAAC,EAAE,EAAE;YAC9B,IAAI,EAAE,EAAE,UAAU,EAAE,IAAI,IAAI,EAAE,EAAE;SACjC,CAAC;aACD,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE,CACpB,OAAO,CAAC,IAAI,CAAC,wCAAwC,EAAE,GAAG,CAAC,OAAO,CAAC,CACpE,CAAC;QAEJ,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,UAAU,EAAE,CAAC;AAE7C,qEAAqE;AACrE,6CAA6C;AAC7C,8DAA8D;AAC9D,iEAAiE;AACjE,kDAAkD;AAClD,qEAAqE;AAErE,iEAAiE;AACjE,MAAM,UAAU,gBAAgB;IAC9B,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,iBAAiB;IAC/B,OAAO,UAAU,CAAC,OAAO,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,UAAU,CAAC,KAAe;IACjC,OAAO,CAAC,IAAa,EAAE,GAAa,EAAE,IAAkB,EAAQ,EAAE;QAChE,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;QAExB,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,YAAY,CACV,GAAG,EACH,GAAG,EACH,iBAAiB,EACjB,0CAA0C,CAC3C,CAAC;YACF,OAAO;QACT,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC;YACjC,YAAY,CACV,GAAG,EACH,GAAG,EACH,oBAAoB,EACpB,6BAA6B,KAAK,UAAU,CAC7C,CAAC;YACF,OAAO;QACT,CAAC;QAED,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC"} \ No newline at end of file diff --git a/dist/routes/assets.d.ts.map b/dist/routes/assets.d.ts.map index d7090b6d..3982aca9 100644 --- a/dist/routes/assets.d.ts.map +++ b/dist/routes/assets.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../src/routes/assets.ts"],"names":[],"mappings":"AAMA,QAAA,MAAM,MAAM,4CAAW,CAAC;AAgExB,eAAe,MAAM,CAAC"} \ No newline at end of file +{"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../src/routes/assets.ts"],"names":[],"mappings":"AAOA,QAAA,MAAM,MAAM,4CAAW,CAAC;AA6DxB,eAAe,MAAM,CAAC"} \ No newline at end of file diff --git a/dist/routes/assets.js b/dist/routes/assets.js index 4b2138ad..81bf6a0a 100644 --- a/dist/routes/assets.js +++ b/dist/routes/assets.js @@ -1,4 +1,5 @@ import { Router } from "express"; +import { sendApiError } from "../lib/apiError.js"; import prisma from "../lib/prisma"; import { cacheMiddleware } from "../cache/CacheMiddleware"; import { CACHE_CONFIG, CACHE_KEYS } from "../config/redis.config"; @@ -55,10 +56,7 @@ router.get("/", cacheMiddleware({ }); } catch (error) { - res.status(500).json({ - success: false, - error: error instanceof Error ? error.message : "Internal server error", - }); + sendApiError(res, 500, "INTERNAL_SERVER_ERROR", typeof (error instanceof Error ? error.message : "Internal server error") === "string" ? String(error instanceof Error ? error.message : "Internal server error") : undefined); } }); export default router; diff --git a/dist/routes/assets.js.map b/dist/routes/assets.js.map index 98bd320e..7640edf4 100644 --- a/dist/routes/assets.js.map +++ b/dist/routes/assets.js.map @@ -1 +1 @@ -{"version":3,"file":"assets.js","sourceRoot":"","sources":["../../src/routes/assets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,MAAM,MAAM,eAAe,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGlE,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,CAAC,GAAG,CACR,GAAG,EACH,eAAe,CAAC;IACd,GAAG,EAAE,YAAY,CAAC,GAAG,CAAC,MAAM;IAC5B,YAAY,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,EAAE;CAC5C,CAAC,EACF,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IACnB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAC5C,KAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;YACzB,MAAM,EAAE;gBACN,IAAI,EAAE,IAAI;gBACV,IAAI,EAAE,IAAI;gBACV,MAAM,EAAE,IAAI;aACb;YACD,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;SACzB,CAAC,CAAC;QAEH,GAAG,CAAC,IAAI,CAAC;YACP,OAAO,EAAE,IAAI;YACb,MAAM;SACP,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB;SACxE,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,eAAe,MAAM,CAAC"} \ No newline at end of file +{"version":3,"file":"assets.js","sourceRoot":"","sources":["../../src/routes/assets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,MAAM,MAAM,eAAe,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGlE,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,CAAC,GAAG,CACR,GAAG,EACH,eAAe,CAAC;IACd,GAAG,EAAE,YAAY,CAAC,GAAG,CAAC,MAAM;IAC5B,YAAY,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,EAAE;CAC5C,CAAC,EACF,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IACnB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAC5C,KAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;YACzB,MAAM,EAAE;gBACN,IAAI,EAAE,IAAI;gBACV,IAAI,EAAE,IAAI;gBACV,MAAM,EAAE,IAAI;aACb;YACD,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;SACzB,CAAC,CAAC;QAEH,GAAG,CAAC,IAAI,CAAC;YACP,OAAO,EAAE,IAAI;YACb,MAAM;SACP,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,uBAAuB,EAAE,OAAO,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACjO,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,eAAe,MAAM,CAAC"} \ No newline at end of file diff --git a/dist/routes/history.d.ts.map b/dist/routes/history.d.ts.map index 5635e137..5e617360 100644 --- a/dist/routes/history.d.ts.map +++ b/dist/routes/history.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/routes/history.ts"],"names":[],"mappings":"AAKA,QAAA,MAAM,MAAM,4CAAW,CAAC;AAgKxB,eAAe,MAAM,CAAC"} \ No newline at end of file +{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/routes/history.ts"],"names":[],"mappings":"AAMA,QAAA,MAAM,MAAM,4CAAW,CAAC;AA6JxB,eAAe,MAAM,CAAC"} \ No newline at end of file diff --git a/dist/routes/history.js b/dist/routes/history.js index bcb10324..a0be6f54 100644 --- a/dist/routes/history.js +++ b/dist/routes/history.js @@ -1,4 +1,5 @@ import { Router } from "express"; +import { sendApiError } from "../lib/apiError.js"; import prisma from "../lib/prisma"; import { cacheMiddleware } from "../cache/CacheMiddleware"; import { CACHE_CONFIG, CACHE_KEYS } from "../config/redis.config"; @@ -88,14 +89,14 @@ router.get("/:asset", cacheMiddleware({ if (fromParam) { since = new Date(fromParam); if (isNaN(since.getTime())) { - res.status(400).json({ success: false, error: "Invalid 'from' date" }); + sendApiError(res, 400, "BAD_REQUEST", "Invalid 'from' date"); return; } } if (toParam) { until = new Date(toParam); if (isNaN(until.getTime())) { - res.status(400).json({ success: false, error: "Invalid 'to' date" }); + sendApiError(res, 400, "BAD_REQUEST", "Invalid 'to' date"); return; } } @@ -145,10 +146,7 @@ router.get("/:asset", cacheMiddleware({ }); } catch (error) { - res.status(500).json({ - success: false, - error: error instanceof Error ? error.message : "Internal server error", - }); + sendApiError(res, 500, "INTERNAL_SERVER_ERROR", typeof (error instanceof Error ? error.message : "Internal server error") === "string" ? String(error instanceof Error ? error.message : "Internal server error") : undefined); } }); export default router; diff --git a/dist/routes/history.js.map b/dist/routes/history.js.map index e6f386da..dd11ed79 100644 --- a/dist/routes/history.js.map +++ b/dist/routes/history.js.map @@ -1 +1 @@ -{"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/routes/history.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/routes/history.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/routes/intelligence.d.ts.map b/dist/routes/intelligence.d.ts.map index 1f58f4a2..a085aa8d 100644 --- a/dist/routes/intelligence.d.ts.map +++ b/dist/routes/intelligence.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"intelligence.d.ts","sourceRoot":"","sources":["../../src/routes/intelligence.ts"],"names":[],"mappings":"AAKA,QAAA,MAAM,MAAM,4CAAW,CAAC;AA+IxB,eAAe,MAAM,CAAC"} \ No newline at end of file +{"version":3,"file":"intelligence.d.ts","sourceRoot":"","sources":["../../src/routes/intelligence.ts"],"names":[],"mappings":"AAMA,QAAA,MAAM,MAAM,4CAAW,CAAC;AAsIxB,eAAe,MAAM,CAAC"} \ No newline at end of file diff --git a/dist/routes/intelligence.js b/dist/routes/intelligence.js index 1d3fa779..7871f9d7 100644 --- a/dist/routes/intelligence.js +++ b/dist/routes/intelligence.js @@ -1,4 +1,5 @@ import { Router } from "express"; +import { sendApiError } from "../lib/apiError.js"; import { cacheMiddleware } from "../cache/CacheMiddleware"; import { CACHE_CONFIG, CACHE_KEYS } from "../config/redis.config"; import { intelligenceService } from "../services/intelligenceService"; @@ -39,10 +40,7 @@ router.get("/hourly-volatility", cacheMiddleware({ } catch (error) { console.error("Error fetching hourly volatility snapshot:", error); - res.status(500).json({ - success: false, - error: error instanceof Error ? error.message : "Internal server error", - }); + sendApiError(res, 500, "INTERNAL_SERVER_ERROR", typeof (error instanceof Error ? error.message : "Internal server error") === "string" ? String(error instanceof Error ? error.message : "Internal server error") : undefined); } }); /** @@ -90,10 +88,7 @@ router.get("/price-change/:currency", async (req, res) => { }); } catch (error) { - res.status(500).json({ - success: false, - error: error instanceof Error ? error.message : "Internal server error", - }); + sendApiError(res, 500, "INTERNAL_SERVER_ERROR", typeof (error instanceof Error ? error.message : "Internal server error") === "string" ? String(error instanceof Error ? error.message : "Internal server error") : undefined); } }); /** @@ -130,10 +125,7 @@ router.get("/stale", async (req, res) => { }); } catch (error) { - res.status(500).json({ - success: false, - error: error instanceof Error ? error.message : "Internal server error", - }); + sendApiError(res, 500, "INTERNAL_SERVER_ERROR", typeof (error instanceof Error ? error.message : "Internal server error") === "string" ? String(error instanceof Error ? error.message : "Internal server error") : undefined); } }); export default router; diff --git a/dist/routes/intelligence.js.map b/dist/routes/intelligence.js.map index 605bbb78..21fea070 100644 --- a/dist/routes/intelligence.js.map +++ b/dist/routes/intelligence.js.map @@ -1 +1 @@ -{"version":3,"file":"intelligence.js","sourceRoot":"","sources":["../../src/routes/intelligence.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAEtE,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,GAAG,CACR,oBAAoB,EACpB,eAAe,CAAC;IACd,GAAG,EAAE,YAAY,CAAC,GAAG,CAAC,YAAY;IAClC,YAAY,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,gBAAgB,EAAE;CAC/D,CAAC,EACF,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;IAClB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,2BAA2B,EAAE,CAAC;QAEzE,GAAG,CAAC,IAAI,CAAC;YACP,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,QAAQ;SACf,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,4CAA4C,EAAE,KAAK,CAAC,CAAC;QACnE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB;SACxE,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CACF,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,CAAC,GAAG,CAAC,yBAAyB,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IACvD,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IAEnD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAC;QAE3E,GAAG,CAAC,IAAI,CAAC;YACP,OAAO,EAAE,IAAI;YACb,QAAQ;YACR,SAAS,EAAE,MAAM;SAClB,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB;SACxE,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IACtC,IAAI,CAAC;QACH,MAAM,eAAe,GAAG,MAAM,mBAAmB,CAAC,kBAAkB,EAAE,CAAC;QAEvE,GAAG,CAAC,IAAI,CAAC;YACP,OAAO,EAAE,IAAI;YACb,eAAe;SAChB,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB;SACxE,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,eAAe,MAAM,CAAC"} \ No newline at end of file +{"version":3,"file":"intelligence.js","sourceRoot":"","sources":["../../src/routes/intelligence.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/routes/marketRates.d.ts.map b/dist/routes/marketRates.d.ts.map index 32916467..fa8a6f3f 100644 --- a/dist/routes/marketRates.d.ts.map +++ b/dist/routes/marketRates.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"marketRates.d.ts","sourceRoot":"","sources":["../../src/routes/marketRates.ts"],"names":[],"mappings":"AAUA,QAAA,MAAM,MAAM,4CAAW,CAAC;AAqPxB,eAAe,MAAM,CAAC"} \ No newline at end of file +{"version":3,"file":"marketRates.d.ts","sourceRoot":"","sources":["../../src/routes/marketRates.ts"],"names":[],"mappings":"AAWA,QAAA,MAAM,MAAM,4CAAW,CAAC;AA6NxB,eAAe,MAAM,CAAC"} \ No newline at end of file diff --git a/dist/routes/marketRates.js b/dist/routes/marketRates.js index d9d7a715..e3f0f104 100644 --- a/dist/routes/marketRates.js +++ b/dist/routes/marketRates.js @@ -1,4 +1,5 @@ import { Router } from "express"; +import { sendApiError } from "../lib/apiError.js"; import { getRate, getAllRates } from "../controllers/marketRatesController"; import { MarketRateService } from "../services/marketRate"; import { cacheMiddleware, invalidateCache } from "../cache/CacheMiddleware"; @@ -31,20 +32,12 @@ router.get("/latest", cacheMiddleware({ }); } else { - res.status(500).json({ - success: false, - error: result.error, - }); + sendApiError(res, 500, "INTERNAL_SERVER_ERROR", typeof (result.error) === "string" ? String(result.error) : undefined); } } catch (error) { console.error("Error fetching latest prices:", error); - res.status(500).json({ - success: false, - error: error instanceof Error - ? error.message - : "Failed to fetch latest prices", - }); + sendApiError(res, 500, "INTERNAL_SERVER_ERROR", error instanceof Error ? error.message : "Failed to fetch latest prices"); } }); // Pending reviews @@ -60,12 +53,7 @@ router.get("/reviews/pending", cacheMiddleware({ }); } catch (error) { - res.status(500).json({ - success: false, - error: error instanceof Error - ? error.message - : "Failed to fetch pending price reviews", - }); + sendApiError(res, 500, "INTERNAL_SERVER_ERROR", error instanceof Error ? error.message : "Failed to fetch pending price reviews"); } }); // Approve review @@ -73,10 +61,7 @@ router.post("/reviews/:id/approve", invalidateCache("market-rates:*"), async (re try { const reviewId = Number.parseInt(req.params.id, 10); if (!Number.isFinite(reviewId)) { - res.status(400).json({ - success: false, - error: "Review ID must be a valid number", - }); + sendApiError(res, 400, "BAD_REQUEST", "Review ID must be a valid number"); return; } const { reviewedBy, note } = req.body ?? {}; @@ -87,12 +72,8 @@ router.post("/reviews/:id/approve", invalidateCache("market-rates:*"), async (re }); } catch (error) { - res.status(isLockdownError(error) ? error.statusCode : 500).json({ - success: false, - error: error instanceof Error - ? error.message - : "Failed to approve price review", - }); + const status = isLockdownError(error) ? error.statusCode : 500; + sendApiError(res, status, status === 403 ? "LOCKDOWN_ACTIVE" : "INTERNAL_SERVER_ERROR", error instanceof Error ? error.message : "Failed to approve price review"); } }); // Reject review @@ -100,10 +81,7 @@ router.post("/reviews/:id/reject", invalidateCache("market-rates:*"), async (req try { const reviewId = Number.parseInt(req.params.id, 10); if (!Number.isFinite(reviewId)) { - res.status(400).json({ - success: false, - error: "Review ID must be a valid number", - }); + sendApiError(res, 400, "BAD_REQUEST", "Review ID must be a valid number"); return; } const { reviewedBy, note } = req.body ?? {}; @@ -114,12 +92,7 @@ router.post("/reviews/:id/reject", invalidateCache("market-rates:*"), async (req }); } catch (error) { - res.status(500).json({ - success: false, - error: error instanceof Error - ? error.message - : "Failed to reject price review", - }); + sendApiError(res, 500, "INTERNAL_SERVER_ERROR", error instanceof Error ? error.message : "Failed to reject price review"); } }); // Health check @@ -136,10 +109,7 @@ router.get("/health", cacheMiddleware({ }); } catch (error) { - res.status(500).json({ - success: false, - error: error instanceof Error ? error.message : "Internal server error", - }); + sendApiError(res, 500, "INTERNAL_SERVER_ERROR", typeof (error instanceof Error ? error.message : "Internal server error") === "string" ? String(error instanceof Error ? error.message : "Internal server error") : undefined); } }); // Supported currencies @@ -155,10 +125,7 @@ router.get("/currencies", cacheMiddleware({ }); } catch (error) { - res.status(500).json({ - success: false, - error: error instanceof Error ? error.message : "Internal server error", - }); + sendApiError(res, 500, "INTERNAL_SERVER_ERROR", typeof (error instanceof Error ? error.message : "Internal server error") === "string" ? String(error instanceof Error ? error.message : "Internal server error") : undefined); } }); // Cache status @@ -171,10 +138,7 @@ router.get("/cache", (req, res) => { }); } catch (error) { - res.status(500).json({ - success: false, - error: error instanceof Error ? error.message : "Internal server error", - }); + sendApiError(res, 500, "INTERNAL_SERVER_ERROR", typeof (error instanceof Error ? error.message : "Internal server error") === "string" ? String(error instanceof Error ? error.message : "Internal server error") : undefined); } }); // Clear cache @@ -187,10 +151,7 @@ router.post("/cache/clear", (req, res) => { }); } catch (error) { - res.status(500).json({ - success: false, - error: error instanceof Error ? error.message : "Internal server error", - }); + sendApiError(res, 500, "INTERNAL_SERVER_ERROR", typeof (error instanceof Error ? error.message : "Internal server error") === "string" ? String(error instanceof Error ? error.message : "Internal server error") : undefined); } }); export default router; diff --git a/dist/routes/marketRates.js.map b/dist/routes/marketRates.js.map index 9a12844d..e7832537 100644 --- a/dist/routes/marketRates.js.map +++ b/dist/routes/marketRates.js.map @@ -1 +1 @@ -{"version":3,"file":"marketRates.js","sourceRoot":"","sources":["../../src/routes/marketRates.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"marketRates.js","sourceRoot":"","sources":["../../src/routes/marketRates.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/routes/priceUpdates.d.ts.map b/dist/routes/priceUpdates.d.ts.map index de9690da..c868586a 100644 --- a/dist/routes/priceUpdates.d.ts.map +++ b/dist/routes/priceUpdates.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"priceUpdates.d.ts","sourceRoot":"","sources":["../../src/routes/priceUpdates.ts"],"names":[],"mappings":"AAQA,QAAA,MAAM,MAAM,4CAAmB,CAAC;AA4WhC,eAAe,MAAM,CAAC"} \ No newline at end of file +{"version":3,"file":"priceUpdates.d.ts","sourceRoot":"","sources":["../../src/routes/priceUpdates.ts"],"names":[],"mappings":"AASA,QAAA,MAAM,MAAM,4CAAmB,CAAC;AAuUhC,eAAe,MAAM,CAAC"} \ No newline at end of file diff --git a/dist/routes/priceUpdates.js b/dist/routes/priceUpdates.js index 5414c113..651b3996 100644 --- a/dist/routes/priceUpdates.js +++ b/dist/routes/priceUpdates.js @@ -1,4 +1,5 @@ import express from "express"; +import { sendApiError } from "../lib/apiError.js"; import { multiSigService } from "../services/multiSigService"; import { isLockdownError } from "../state/appState"; import { sanitizeMultiSigRequest, sanitizeSignatureRequest, } from "../middleware/payloadSanitizer"; @@ -31,10 +32,7 @@ router.post("/multi-sig/request", sanitizeMultiSigRequest, async (req, res) => { } catch (error) { console.error("[API] Multi-sig request creation failed:", error); - res.status(500).json({ - success: false, - error: String(error), - }); + sendApiError(res, 500, "INTERNAL_SERVER_ERROR", typeof (String(error)) === "string" ? String(String(error)) : undefined); } }); /** @@ -56,10 +54,7 @@ router.post("/sign", sanitizeSignatureRequest, async (req, res) => { ? authHeader.slice(7) : authHeader; if (token !== authToken) { - return res.status(403).json({ - success: false, - error: "Unauthorized - invalid token", - }); + return sendApiError(res, 403, "FORBIDDEN", "Unauthorized - invalid token"); } } const { multiSigPriceId } = req.body; @@ -96,26 +91,17 @@ router.post("/multi-sig/:multiSigPriceId/request-signature", async (req, res) => if (!multiSigPriceId || typeof multiSigPriceId !== "string" || !remoteServerUrl) { - return res.status(400).json({ - success: false, - error: "Missing multiSigPriceId (in URL) or remoteServerUrl (in body)", - }); + return sendApiError(res, 400, "BAD_REQUEST", "Missing multiSigPriceId (in URL) or remoteServerUrl (in body)"); } const result = await multiSigService.requestRemoteSignature(parseInt(multiSigPriceId, 10), remoteServerUrl); if (!result.success) { - return res.status(400).json({ - success: false, - error: result.error, - }); + return sendApiError(res, 400, "BAD_REQUEST", typeof (result.error) === "string" ? String(result.error) : undefined); } res.json({ success: true }); } catch (error) { console.error("[API] Remote signature request failed:", error); - res.status(500).json({ - success: false, - error: String(error), - }); + sendApiError(res, 500, "INTERNAL_SERVER_ERROR", typeof (String(error)) === "string" ? String(String(error)) : undefined); } }); /** @@ -126,10 +112,7 @@ router.get("/multi-sig/:multiSigPriceId/status", async (req, res) => { try { const multiSigPriceId = req.params.multiSigPriceId; if (!multiSigPriceId || typeof multiSigPriceId !== "string") { - return res.status(400).json({ - success: false, - error: "Missing multiSigPriceId in URL", - }); + return sendApiError(res, 400, "BAD_REQUEST", "Missing multiSigPriceId in URL"); } const multiSigPrice = await multiSigService.getMultiSigPrice(parseInt(multiSigPriceId, 10)); if (!multiSigPrice) { @@ -158,10 +141,7 @@ router.get("/multi-sig/:multiSigPriceId/status", async (req, res) => { } catch (error) { console.error("[API] Multi-sig status fetch failed:", error); - res.status(500).json({ - success: false, - error: String(error), - }); + sendApiError(res, 500, "INTERNAL_SERVER_ERROR", typeof (String(error)) === "string" ? String(String(error)) : undefined); } }); /** @@ -188,10 +168,7 @@ router.get("/multi-sig/pending", async (req, res) => { } catch (error) { console.error("[API] Pending multi-sig fetch failed:", error); - res.status(500).json({ - success: false, - error: String(error), - }); + sendApiError(res, 500, "INTERNAL_SERVER_ERROR", typeof (String(error)) === "string" ? String(String(error)) : undefined); } }); /** @@ -203,10 +180,7 @@ router.get("/multi-sig/:multiSigPriceId/signatures", async (req, res) => { try { const multiSigPriceId = req.params.multiSigPriceId; if (!multiSigPriceId || typeof multiSigPriceId !== "string") { - return res.status(400).json({ - success: false, - error: "Missing multiSigPriceId in URL", - }); + return sendApiError(res, 400, "BAD_REQUEST", "Missing multiSigPriceId in URL"); } const multiSigPrice = await multiSigService.getMultiSigPrice(parseInt(multiSigPriceId, 10)); if (!multiSigPrice) { @@ -238,10 +212,7 @@ router.get("/multi-sig/:multiSigPriceId/signatures", async (req, res) => { } catch (error) { console.error("[API] Signature fetch failed:", error); - res.status(500).json({ - success: false, - error: String(error), - }); + sendApiError(res, 500, "INTERNAL_SERVER_ERROR", typeof (String(error)) === "string" ? String(String(error)) : undefined); } }); /** @@ -266,10 +237,7 @@ router.post("/multi-sig/:multiSigPriceId/record-submission", async (req, res) => } catch (error) { console.error("[API] Submission recording failed:", error); - res.status(500).json({ - success: false, - error: String(error), - }); + sendApiError(res, 500, "INTERNAL_SERVER_ERROR", typeof (String(error)) === "string" ? String(String(error)) : undefined); } }); /** @@ -287,10 +255,7 @@ router.get("/multi-sig/signer-info", async (req, res) => { } catch (error) { console.error("[API] Signer info fetch failed:", error); - res.status(500).json({ - success: false, - error: String(error), - }); + sendApiError(res, 500, "INTERNAL_SERVER_ERROR", typeof (String(error)) === "string" ? String(String(error)) : undefined); } }); export default router; diff --git a/dist/routes/priceUpdates.js.map b/dist/routes/priceUpdates.js.map index 40263d83..a6ff4379 100644 --- a/dist/routes/priceUpdates.js.map +++ b/dist/routes/priceUpdates.js.map @@ -1 +1 @@ -{"version":3,"file":"priceUpdates.js","sourceRoot":"","sources":["../../src/routes/priceUpdates.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"priceUpdates.js","sourceRoot":"","sources":["../../src/routes/priceUpdates.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/routes/stats.d.ts.map b/dist/routes/stats.d.ts.map index 433a6f25..8623e09e 100644 --- a/dist/routes/stats.d.ts.map +++ b/dist/routes/stats.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/routes/stats.ts"],"names":[],"mappings":"AAKA,QAAA,MAAM,MAAM,4CAAW,CAAC;AAiKxB,eAAe,MAAM,CAAC"} \ No newline at end of file +{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/routes/stats.ts"],"names":[],"mappings":"AAMA,QAAA,MAAM,MAAM,4CAAW,CAAC;AAwSxB,eAAe,MAAM,CAAC"} \ No newline at end of file diff --git a/dist/routes/stats.js b/dist/routes/stats.js index 51df852c..5ed4f510 100644 --- a/dist/routes/stats.js +++ b/dist/routes/stats.js @@ -1,8 +1,112 @@ import { Router } from "express"; +import { sendApiError } from "../lib/apiError.js"; import prisma from "../lib/prisma"; import { cacheMiddleware } from "../cache/CacheMiddleware"; import { CACHE_CONFIG, CACHE_KEYS } from "../config/redis.config"; const router = Router(); +/** + * GET /api/stats/relayers + * + * Returns statistics for all relayers (oracle servers) including: + * - Uptime percentage + * - Average latency (time from request to signature) + * - Number of successful pushes (submitted prices) + */ +router.get("/relayers", async (req, res) => { + try { + // Get all unique signers/relayers + const signers = await prisma.multiSigSignature.groupBy({ + by: ["signerPublicKey", "signerName"], + _count: { + id: true, + }, + }); + // Get all submitted multi-sig prices + const submittedPrices = await prisma.multiSigPrice.findMany({ + where: { + status: "APPROVED", + submittedAt: { not: null }, + }, + include: { + multiSigSignatures: { + select: { + signerPublicKey: true, + signedAt: true, + }, + }, + }, + }); + // Calculate statistics for each relayer + const relayerStats = await Promise.all(signers.map(async (signer) => { + const { signerPublicKey, signerName, _count } = signer; + // Get all signatures by this relayer + const signatures = await prisma.multiSigSignature.findMany({ + where: { signerPublicKey }, + include: { + multiSigPrice: { + select: { + requestedAt: true, + submittedAt: true, + status: true, + }, + }, + }, + orderBy: { + signedAt: "desc", + }, + }); + // Calculate successful pushes (prices that were submitted to Stellar) + const successfulPushes = signatures.filter((sig) => sig.multiSigPrice.submittedAt !== null).length; + // Calculate total requests (number of multi-sig prices this relayer was asked to sign) + const totalRequests = signatures.length; + // Calculate uptime % (successful signatures / total requests * 100) + const uptimePercentage = totalRequests > 0 ? (successfulPushes / totalRequests) * 100 : 0; + // Calculate average latency (time from price request to signature) + const latencies = signatures + .filter((sig) => sig.multiSigPrice.requestedAt && sig.signedAt) + .map((sig) => { + const requestedAt = new Date(sig.multiSigPrice.requestedAt).getTime(); + const signedAt = new Date(sig.signedAt).getTime(); + return signedAt - requestedAt; // milliseconds + }); + const averageLatencyMs = latencies.length > 0 + ? latencies.reduce((sum, latency) => sum + latency, 0) / latencies.length + : 0; + // Get last activity + const lastActivity = signatures[0]?.signedAt || null; + // Get failed signatures (signed but price not submitted) + const failedSignatures = signatures.filter((sig) => sig.multiSigPrice.submittedAt === null).length; + return { + signerPublicKey, + signerName, + totalSignatures: _count.id, + successfulPushes, + failedSignatures, + uptimePercentage: Math.round(uptimePercentage * 100) / 100, + averageLatencyMs: Math.round(averageLatencyMs * 100) / 100, + lastActivity, + }; + })); + // Sort by uptime percentage (descending) + relayerStats.sort((a, b) => b.uptimePercentage - a.uptimePercentage); + res.json({ + success: true, + data: { + totalRelayers: relayerStats.length, + relayers: relayerStats, + }, + }); + } + catch (error) { + console.error("[API] Relayer stats fetch failed:", error); + res.status(500).json({ + success: false, + error: error instanceof Error + ? error.message + : "Failed to fetch relayer statistics", + }); + } +}); // GET /api/v1/stats/volume?date=2024-01-15 router.get("/volume", cacheMiddleware({ ttl: CACHE_CONFIG.ttl.stats, @@ -19,10 +123,7 @@ router.get("/volume", cacheMiddleware({ const targetDate = dateParam ? new Date(dateParam) : new Date(); // Validate date if (isNaN(targetDate.getTime())) { - res.status(400).json({ - success: false, - error: "Invalid date format. Use YYYY-MM-DD format.", - }); + sendApiError(res, 400, "BAD_REQUEST", "Invalid date format. Use YYYY-MM-DD format."); return; } // Set start and end of day (UTC) @@ -101,8 +202,7 @@ router.get("/volume", cacheMiddleware({ successful: totalSuccessfulRequests, failed: totalFailedRequests, successRate: totalApiRequests > 0 - ? ((totalSuccessfulRequests / totalApiRequests) * 100).toFixed(2) + - "%" + ? ((totalSuccessfulRequests / totalApiRequests) * 100).toFixed(2) + "%" : "0%", }, activity: { @@ -128,10 +228,7 @@ router.get("/volume", cacheMiddleware({ } catch (error) { console.error("Error fetching volume stats:", error); - res.status(500).json({ - success: false, - error: error instanceof Error ? error.message : "Internal server error", - }); + sendApiError(res, 500, "INTERNAL_SERVER_ERROR", typeof (error instanceof Error ? error.message : "Internal server error") === "string" ? String(error instanceof Error ? error.message : "Internal server error") : undefined); } }); export default router; diff --git a/dist/routes/stats.js.map b/dist/routes/stats.js.map index 4d2bcf95..e1b76e52 100644 --- a/dist/routes/stats.js.map +++ b/dist/routes/stats.js.map @@ -1 +1 @@ -{"version":3,"file":"stats.js","sourceRoot":"","sources":["../../src/routes/stats.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"stats.js","sourceRoot":"","sources":["../../src/routes/stats.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/errorTracker.d.ts.map b/dist/services/errorTracker.d.ts.map index 0e29eacf..55f323a8 100644 --- a/dist/services/errorTracker.d.ts.map +++ b/dist/services/errorTracker.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"errorTracker.d.ts","sourceRoot":"","sources":["../../src/services/errorTracker.ts"],"names":[],"mappings":"AAOA,qBAAa,YAAY;IACvB,OAAO,CAAC,eAAe,CAAoC;IAC3D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAK;IAC/B;;;;OAIG;IACH,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,OAAO;IAgBhE,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAItC,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;YAKjB,QAAQ;CA0BvB;AAED,eAAO,MAAM,YAAY,cAAqB,CAAC"} \ No newline at end of file +{"version":3,"file":"errorTracker.d.ts","sourceRoot":"","sources":["../../src/services/errorTracker.ts"],"names":[],"mappings":"AAQA,qBAAa,YAAY;IACvB,OAAO,CAAC,eAAe,CAAoC;IAC3D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAK;IAC/B;;;;OAIG;IACH,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,OAAO;IAgBhE,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAItC,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;YAKjB,QAAQ;CA2BvB;AAED,eAAO,MAAM,YAAY,cAAqB,CAAC"} \ No newline at end of file diff --git a/dist/services/errorTracker.js b/dist/services/errorTracker.js index c5bbe515..71c350b7 100644 --- a/dist/services/errorTracker.js +++ b/dist/services/errorTracker.js @@ -1,4 +1,5 @@ import prisma from "../lib/prisma"; +import { generateKsuid } from "../utils/ksuid.js"; export class ErrorTracker { failureCounters = new Map(); threshold = 3; @@ -34,6 +35,7 @@ export class ErrorTracker { typeof clientAny.errorLog.create === "function") { await clientAny.errorLog.create({ data: { + id: generateKsuid(), providerName: serviceKey, errorMessage: errorDetails instanceof Error ? errorDetails.message diff --git a/dist/services/errorTracker.js.map b/dist/services/errorTracker.js.map index 41500b16..4f8e5646 100644 --- a/dist/services/errorTracker.js.map +++ b/dist/services/errorTracker.js.map @@ -1 +1 @@ -{"version":3,"file":"errorTracker.js","sourceRoot":"","sources":["../../src/services/errorTracker.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,eAAe,CAAC;AAOnC,MAAM,OAAO,YAAY;IACf,eAAe,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC1C,SAAS,GAAG,CAAC,CAAC;IAC/B;;;;OAIG;IACH,YAAY,CAAC,UAAkB,EAAE,YAAqB;QACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAEtD,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAC;YACpB,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACnC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YAC/C,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;YACxC,OAAO,QAAQ,CAAC,KAAK,IAAI,IAAI,CAAC,SAAS,CAAC;QAC1C,CAAC;QAED,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QAC3E,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;QACxC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,YAAY,CAAC,UAAkB;QAC7B,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,UAAkB;QACtB,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAC1C,CAAC;IAED,sEAAsE;IAC9D,KAAK,CAAC,QAAQ,CACpB,UAAkB,EAClB,YAAqB;QAErB,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAa,CAAC;YAEhC,IACE,SAAS,EAAE,QAAQ;gBACnB,OAAO,SAAS,CAAC,QAAQ,CAAC,MAAM,KAAK,UAAU,EAC/C,CAAC;gBACD,MAAM,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;oBAC9B,IAAI,EAAE;wBACJ,YAAY,EAAE,UAAU;wBACxB,YAAY,EACV,YAAY,YAAY,KAAK;4BAC3B,CAAC,CAAC,YAAY,CAAC,OAAO;4BACtB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC;wBAClC,UAAU,EAAE,IAAI,IAAI,EAAE;qBACvB;iBACF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,mDAAmD;QACrD,CAAC;IACH,CAAC;CACF;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC"} \ No newline at end of file +{"version":3,"file":"errorTracker.js","sourceRoot":"","sources":["../../src/services/errorTracker.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,eAAe,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAOlD,MAAM,OAAO,YAAY;IACf,eAAe,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC1C,SAAS,GAAG,CAAC,CAAC;IAC/B;;;;OAIG;IACH,YAAY,CAAC,UAAkB,EAAE,YAAqB;QACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAEtD,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAC;YACpB,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACnC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YAC/C,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;YACxC,OAAO,QAAQ,CAAC,KAAK,IAAI,IAAI,CAAC,SAAS,CAAC;QAC1C,CAAC;QAED,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QAC3E,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;QACxC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,YAAY,CAAC,UAAkB;QAC7B,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,UAAkB;QACtB,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAC1C,CAAC;IAED,sEAAsE;IAC9D,KAAK,CAAC,QAAQ,CACpB,UAAkB,EAClB,YAAqB;QAErB,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAa,CAAC;YAEhC,IACE,SAAS,EAAE,QAAQ;gBACnB,OAAO,SAAS,CAAC,QAAQ,CAAC,MAAM,KAAK,UAAU,EAC/C,CAAC;gBACD,MAAM,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;oBAC9B,IAAI,EAAE;wBACJ,EAAE,EAAE,aAAa,EAAE;wBACnB,YAAY,EAAE,UAAU;wBACxB,YAAY,EACV,YAAY,YAAY,KAAK;4BAC3B,CAAC,CAAC,YAAY,CAAC,OAAO;4BACtB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC;wBAClC,UAAU,EAAE,IAAI,IAAI,EAAE;qBACvB;iBACF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,mDAAmD;QACrD,CAAC;IACH,CAAC;CACF;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC"} \ No newline at end of file diff --git a/dist/services/marketRate/ghsFetcher.d.ts.map b/dist/services/marketRate/ghsFetcher.d.ts.map index b7ac464e..407a48ee 100644 --- a/dist/services/marketRate/ghsFetcher.d.ts.map +++ b/dist/services/marketRate/ghsFetcher.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"ghsFetcher.d.ts","sourceRoot":"","sources":["../../../src/services/marketRate/ghsFetcher.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAIxD;;GAEG;AACH,qBAAa,cAAe,YAAW,iBAAiB;IACtD,OAAO,CAAC,QAAQ,CAAC,YAAY,CACgF;IAC7G,OAAO,CAAC,MAAM,CAAkC;IAEhD,WAAW,IAAI,MAAM;IAIf,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC;IA0ChC,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;CAQpC"} \ No newline at end of file +{"version":3,"file":"ghsFetcher.d.ts","sourceRoot":"","sources":["../../../src/services/marketRate/ghsFetcher.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAkB,MAAM,SAAS,CAAC;AAIxE;;GAEG;AACH,qBAAa,cAAe,YAAW,iBAAiB;IACtD,OAAO,CAAC,QAAQ,CAAC,YAAY,CACgF;IAC7G,OAAO,CAAC,MAAM,CAAkC;IAEhD,WAAW,IAAI,MAAM;IAIf,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC;IAoDhC,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;CAQpC"} \ No newline at end of file diff --git a/dist/services/marketRate/ghsFetcher.js b/dist/services/marketRate/ghsFetcher.js index 3f5d0177..8728ab0d 100644 --- a/dist/services/marketRate/ghsFetcher.js +++ b/dist/services/marketRate/ghsFetcher.js @@ -23,6 +23,14 @@ export class GHSRateFetcher { if (stellarPrice && typeof stellarPrice.ghs === "number" && stellarPrice.ghs > 0) { + const rawResponses = [ + { + provider: "CoinGecko", + endpoint: this.coinGeckoUrl, + payload: response.data, + receivedAt: new Date(), + }, + ]; const lastUpdatedAt = stellarPrice.last_updated_at ? new Date(stellarPrice.last_updated_at * 1000) : new Date(); @@ -31,6 +39,7 @@ export class GHSRateFetcher { rate: stellarPrice.ghs, timestamp: lastUpdatedAt, source: "CoinGecko (GHS)", + rawResponses, }; } throw new Error("Invalid response from CoinGecko for GHS"); diff --git a/dist/services/marketRate/ghsFetcher.js.map b/dist/services/marketRate/ghsFetcher.js.map index f69d6b0f..240c8949 100644 --- a/dist/services/marketRate/ghsFetcher.js.map +++ b/dist/services/marketRate/ghsFetcher.js.map @@ -1 +1 @@ -{"version":3,"file":"ghsFetcher.js","sourceRoot":"","sources":["../../../src/services/marketRate/ghsFetcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAEnE,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD;;GAEG;AACH,MAAM,OAAO,cAAc;IACR,YAAY,GAC3B,0GAA0G,CAAC;IACrG,MAAM,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAEhD,WAAW;QACT,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,SAAS;QACb,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,SAAS,CAC9B,GAAG,EAAE,CACH,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE;gBAC3B,OAAO,EAAE,wBAAwB;gBACjC,OAAO,EAAE;oBACP,YAAY,EAAE,wBAAwB;iBACvC;aACF,CAAC,EACJ,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CACpC,CAAC;YAEF,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC;YAC3C,IACE,YAAY;gBACZ,OAAO,YAAY,CAAC,GAAG,KAAK,QAAQ;gBACpC,YAAY,CAAC,GAAG,GAAG,CAAC,EACpB,CAAC;gBACD,MAAM,aAAa,GAAG,YAAY,CAAC,eAAe;oBAChD,CAAC,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,eAAe,GAAG,IAAI,CAAC;oBAC/C,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;gBAEf,OAAO;oBACL,QAAQ,EAAE,KAAK;oBACf,IAAI,EAAE,YAAY,CAAC,GAAG;oBACtB,SAAS,EAAE,aAAa;oBACxB,MAAM,EAAE,iBAAiB;iBAC1B,CAAC;YACJ,CAAC;YAED,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,0BAA0B,EAC1B,SAAS,EACT,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAC1D,CAAC;YACF,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,SAAS;QACb,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QACvB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF"} \ No newline at end of file +{"version":3,"file":"ghsFetcher.js","sourceRoot":"","sources":["../../../src/services/marketRate/ghsFetcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAEnE,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD;;GAEG;AACH,MAAM,OAAO,cAAc;IACR,YAAY,GAC3B,0GAA0G,CAAC;IACrG,MAAM,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAEhD,WAAW;QACT,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,SAAS;QACb,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,SAAS,CAC9B,GAAG,EAAE,CACH,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE;gBAC3B,OAAO,EAAE,wBAAwB;gBACjC,OAAO,EAAE;oBACP,YAAY,EAAE,wBAAwB;iBACvC;aACF,CAAC,EACJ,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CACpC,CAAC;YAEF,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC;YAC3C,IACE,YAAY;gBACZ,OAAO,YAAY,CAAC,GAAG,KAAK,QAAQ;gBACpC,YAAY,CAAC,GAAG,GAAG,CAAC,EACpB,CAAC;gBACD,MAAM,YAAY,GAAqB;oBACrC;wBACE,QAAQ,EAAE,WAAW;wBACrB,QAAQ,EAAE,IAAI,CAAC,YAAY;wBAC3B,OAAO,EAAE,QAAQ,CAAC,IAAI;wBACtB,UAAU,EAAE,IAAI,IAAI,EAAE;qBACvB;iBACF,CAAC;gBAEF,MAAM,aAAa,GAAG,YAAY,CAAC,eAAe;oBAChD,CAAC,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,eAAe,GAAG,IAAI,CAAC;oBAC/C,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;gBAEf,OAAO;oBACL,QAAQ,EAAE,KAAK;oBACf,IAAI,EAAE,YAAY,CAAC,GAAG;oBACtB,SAAS,EAAE,aAAa;oBACxB,MAAM,EAAE,iBAAiB;oBACzB,YAAY;iBACb,CAAC;YACJ,CAAC;YAED,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,0BAA0B,EAC1B,SAAS,EACT,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAC1D,CAAC;YACF,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,SAAS;QACb,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QACvB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF"} \ No newline at end of file diff --git a/dist/services/marketRate/index.d.ts b/dist/services/marketRate/index.d.ts index 6122c50c..e8b4f632 100644 --- a/dist/services/marketRate/index.d.ts +++ b/dist/services/marketRate/index.d.ts @@ -4,4 +4,5 @@ export * from "./ghsFetcher"; export * from "./ngnFetcher"; export * from "./marketRateService"; export * from "./middleValuePriceService"; +export * from "./medianPriceService"; //# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/services/marketRate/index.d.ts.map b/dist/services/marketRate/index.d.ts.map index 9ff9c961..01147947 100644 --- a/dist/services/marketRate/index.d.ts.map +++ b/dist/services/marketRate/index.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/marketRate/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC"} \ No newline at end of file +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/marketRate/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC"} \ No newline at end of file diff --git a/dist/services/marketRate/index.js b/dist/services/marketRate/index.js index f4e6a8d3..a9c8104e 100644 --- a/dist/services/marketRate/index.js +++ b/dist/services/marketRate/index.js @@ -4,4 +4,5 @@ export * from "./ghsFetcher"; export * from "./ngnFetcher"; export * from "./marketRateService"; export * from "./middleValuePriceService"; +export * from "./medianPriceService"; //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/services/marketRate/index.js.map b/dist/services/marketRate/index.js.map index 68c12b3e..59c193f6 100644 --- a/dist/services/marketRate/index.js.map +++ b/dist/services/marketRate/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/marketRate/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/marketRate/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC"} \ No newline at end of file diff --git a/dist/services/marketRate/kesFetcher.d.ts.map b/dist/services/marketRate/kesFetcher.d.ts.map index 8dcc027d..0dce0f7e 100644 --- a/dist/services/marketRate/kesFetcher.d.ts.map +++ b/dist/services/marketRate/kesFetcher.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"kesFetcher.d.ts","sourceRoot":"","sources":["../../../src/services/marketRate/kesFetcher.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAIxD;;GAEG;AACH,qBAAa,cAAe,YAAW,iBAAiB;IACtD,OAAO,CAAC,QAAQ,CAAC,YAAY,CACgF;IAC7G,OAAO,CAAC,MAAM,CAAkC;IAEhD,WAAW,IAAI,MAAM;IAIf,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC;IA0ChC,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;CAQpC"} \ No newline at end of file +{"version":3,"file":"kesFetcher.d.ts","sourceRoot":"","sources":["../../../src/services/marketRate/kesFetcher.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAkB,MAAM,SAAS,CAAC;AAIxE;;GAEG;AACH,qBAAa,cAAe,YAAW,iBAAiB;IACtD,OAAO,CAAC,QAAQ,CAAC,YAAY,CACgF;IAC7G,OAAO,CAAC,MAAM,CAAkC;IAEhD,WAAW,IAAI,MAAM;IAIf,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC;IAoDhC,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;CAQpC"} \ No newline at end of file diff --git a/dist/services/marketRate/kesFetcher.js b/dist/services/marketRate/kesFetcher.js index 732e3c1c..f866235c 100644 --- a/dist/services/marketRate/kesFetcher.js +++ b/dist/services/marketRate/kesFetcher.js @@ -23,6 +23,14 @@ export class KESRateFetcher { if (stellarPrice && typeof stellarPrice.kes === "number" && stellarPrice.kes > 0) { + const rawResponses = [ + { + provider: "CoinGecko", + endpoint: this.coinGeckoUrl, + payload: response.data, + receivedAt: new Date(), + }, + ]; const lastUpdatedAt = stellarPrice.last_updated_at ? new Date(stellarPrice.last_updated_at * 1000) : new Date(); @@ -31,6 +39,7 @@ export class KESRateFetcher { rate: stellarPrice.kes, timestamp: lastUpdatedAt, source: "CoinGecko (KES)", + rawResponses, }; } throw new Error("Invalid response from CoinGecko for KES"); diff --git a/dist/services/marketRate/kesFetcher.js.map b/dist/services/marketRate/kesFetcher.js.map index 5e30c6c7..23a33793 100644 --- a/dist/services/marketRate/kesFetcher.js.map +++ b/dist/services/marketRate/kesFetcher.js.map @@ -1 +1 @@ -{"version":3,"file":"kesFetcher.js","sourceRoot":"","sources":["../../../src/services/marketRate/kesFetcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAEnE,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD;;GAEG;AACH,MAAM,OAAO,cAAc;IACR,YAAY,GAC3B,0GAA0G,CAAC;IACrG,MAAM,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAEhD,WAAW;QACT,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,SAAS;QACb,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,SAAS,CAC9B,GAAG,EAAE,CACH,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE;gBAC3B,OAAO,EAAE,wBAAwB;gBACjC,OAAO,EAAE;oBACP,YAAY,EAAE,wBAAwB;iBACvC;aACF,CAAC,EACJ,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CACpC,CAAC;YAEF,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC;YAC3C,IACE,YAAY;gBACZ,OAAO,YAAY,CAAC,GAAG,KAAK,QAAQ;gBACpC,YAAY,CAAC,GAAG,GAAG,CAAC,EACpB,CAAC;gBACD,MAAM,aAAa,GAAG,YAAY,CAAC,eAAe;oBAChD,CAAC,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,eAAe,GAAG,IAAI,CAAC;oBAC/C,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;gBAEf,OAAO;oBACL,QAAQ,EAAE,KAAK;oBACf,IAAI,EAAE,YAAY,CAAC,GAAG;oBACtB,SAAS,EAAE,aAAa;oBACxB,MAAM,EAAE,iBAAiB;iBAC1B,CAAC;YACJ,CAAC;YAED,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,0BAA0B,EAC1B,SAAS,EACT,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAC1D,CAAC;YACF,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,SAAS;QACb,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QACvB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF"} \ No newline at end of file +{"version":3,"file":"kesFetcher.js","sourceRoot":"","sources":["../../../src/services/marketRate/kesFetcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAEnE,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD;;GAEG;AACH,MAAM,OAAO,cAAc;IACR,YAAY,GAC3B,0GAA0G,CAAC;IACrG,MAAM,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAEhD,WAAW;QACT,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,SAAS;QACb,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,SAAS,CAC9B,GAAG,EAAE,CACH,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE;gBAC3B,OAAO,EAAE,wBAAwB;gBACjC,OAAO,EAAE;oBACP,YAAY,EAAE,wBAAwB;iBACvC;aACF,CAAC,EACJ,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CACpC,CAAC;YAEF,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC;YAC3C,IACE,YAAY;gBACZ,OAAO,YAAY,CAAC,GAAG,KAAK,QAAQ;gBACpC,YAAY,CAAC,GAAG,GAAG,CAAC,EACpB,CAAC;gBACD,MAAM,YAAY,GAAqB;oBACrC;wBACE,QAAQ,EAAE,WAAW;wBACrB,QAAQ,EAAE,IAAI,CAAC,YAAY;wBAC3B,OAAO,EAAE,QAAQ,CAAC,IAAI;wBACtB,UAAU,EAAE,IAAI,IAAI,EAAE;qBACvB;iBACF,CAAC;gBAEF,MAAM,aAAa,GAAG,YAAY,CAAC,eAAe;oBAChD,CAAC,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,eAAe,GAAG,IAAI,CAAC;oBAC/C,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;gBAEf,OAAO;oBACL,QAAQ,EAAE,KAAK;oBACf,IAAI,EAAE,YAAY,CAAC,GAAG;oBACtB,SAAS,EAAE,aAAa;oBACxB,MAAM,EAAE,iBAAiB;oBACzB,YAAY;iBACb,CAAC;YACJ,CAAC;YAED,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,0BAA0B,EAC1B,SAAS,EACT,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAC1D,CAAC;YACF,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,SAAS;QACb,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QACvB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF"} \ No newline at end of file diff --git a/dist/services/marketRate/marketRateService.d.ts b/dist/services/marketRate/marketRateService.d.ts index 32bc32c1..7288612a 100644 --- a/dist/services/marketRate/marketRateService.d.ts +++ b/dist/services/marketRate/marketRateService.d.ts @@ -10,10 +10,13 @@ export declare class MarketRateService { private remoteOracleServers; private pendingSubmissions; private batchTimeout; + private readonly crossPairLogger; private get CACHE_DURATION_MS(); private get BATCH_WINDOW_MS(); constructor(); private initializeFetchers; + private serializeRawPayload; + private persistRawResponses; getRate(currency: string): Promise; getAllRates(): Promise; private flushBatchSubmissions; @@ -32,5 +35,6 @@ export declare class MarketRateService { expiry?: Date; }>; private requestRemoteSignaturesAsync; + private runCrossPairCheck; } //# sourceMappingURL=marketRateService.d.ts.map \ No newline at end of file diff --git a/dist/services/marketRate/marketRateService.d.ts.map b/dist/services/marketRate/marketRateService.d.ts.map index deb915bb..dfd34c05 100644 --- a/dist/services/marketRate/marketRateService.d.ts.map +++ b/dist/services/marketRate/marketRateService.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"marketRateService.d.ts","sourceRoot":"","sources":["../../../src/services/marketRate/marketRateService.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,UAAU,EACV,eAAe,EACf,yBAAyB,EAC1B,MAAM,SAAS,CAAC;AASjB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAW7C,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAA6C;IAC7D,OAAO,CAAC,KAAK,CAA8D;IAC3E,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAA4B;IACpE,OAAO,CAAC,QAAQ,CAAC,+BAA+B,CAAK;IACrD,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,mBAAmB,CAAgB;IAC3C,OAAO,CAAC,kBAAkB,CAIlB;IACR,OAAO,CAAC,YAAY,CAAa;IAEjC,OAAO,KAAK,iBAAiB,GAE5B;IAED,OAAO,KAAK,eAAe,GAE1B;;IAuBD,OAAO,CAAC,kBAAkB;IAMpB,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAkQnD,WAAW,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;YAOjC,qBAAqB;IAM7B,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAcrD,sBAAsB,IAAI,MAAM,EAAE;IAIlC,SAAS,CAAC,0BAA0B,IAAI,IAAI,CAC1C,eAAe,EACf,KAAK,GAAG,OAAO,GAAG,KAAK,CACxB,GAAG,IAAI;cAUQ,6BAA6B,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAmBtE,OAAO,CAAC,sBAAsB;IAsCxB,eAAe,IAAI,OAAO,CAAC,yBAAyB,CAAC;IA4D3D,UAAU,IAAI,IAAI;IAcZ,iBAAiB;IAIjB,oBAAoB,CACxB,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,EACnB,WAAW,CAAC,EAAE,MAAM;IAuChB,mBAAmB,CACvB,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,EACnB,WAAW,CAAC,EAAE,MAAM;IAsBtB,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,IAAI,CAAA;KAAE,CAAC;YAqBtD,4BAA4B;CAiC3C"} \ No newline at end of file +{"version":3,"file":"marketRateService.d.ts","sourceRoot":"","sources":["../../../src/services/marketRate/marketRateService.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,UAAU,EACV,eAAe,EACf,yBAAyB,EAE1B,MAAM,SAAS,CAAC;AASjB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAiB7C,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAA6C;IAC7D,OAAO,CAAC,KAAK,CAA8D;IAC3E,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAA4B;IACpE,OAAO,CAAC,QAAQ,CAAC,+BAA+B,CAAK;IACrD,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,mBAAmB,CAAgB;IAC3C,OAAO,CAAC,kBAAkB,CAIlB;IACR,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA6C;IAE7E,OAAO,KAAK,iBAAiB,GAE5B;IAED,OAAO,KAAK,eAAe,GAE1B;;IAuBD,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,mBAAmB;YAQb,mBAAmB;IA2B3B,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAkSnD,WAAW,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;YAOjC,qBAAqB;IAM7B,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAcrD,sBAAsB,IAAI,MAAM,EAAE;IAIlC,SAAS,CAAC,0BAA0B,IAAI,IAAI,CAC1C,eAAe,EACf,KAAK,GAAG,OAAO,GAAG,KAAK,CACxB,GAAG,IAAI;cAUQ,6BAA6B,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAmBtE,OAAO,CAAC,sBAAsB;IAsCxB,eAAe,IAAI,OAAO,CAAC,yBAAyB,CAAC;IA4D3D,UAAU,IAAI,IAAI;IAcZ,iBAAiB;IAIjB,oBAAoB,CACxB,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,EACnB,WAAW,CAAC,EAAE,MAAM;IAuChB,mBAAmB,CACvB,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,EACnB,WAAW,CAAC,EAAE,MAAM;IAsBtB,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,IAAI,CAAA;KAAE,CAAC;YAqBtD,4BAA4B;YAkC5B,iBAAiB;CA0ChC"} \ No newline at end of file diff --git a/dist/services/marketRate/marketRateService.js b/dist/services/marketRate/marketRateService.js index dd7087fb..2d0a51fc 100644 --- a/dist/services/marketRate/marketRateService.js +++ b/dist/services/marketRate/marketRateService.js @@ -11,8 +11,14 @@ import { normalizeDateToUTC } from "../../utils/timeUtils"; import { sanityCheckService } from "../sanityCheckService"; import { appConfig } from "../../config/configWatcher"; import { isLockdownEnabled } from "../../state/appState"; +import axios from "axios"; +import { createFetcherLogger } from "../../utils/logger"; +import { OUTGOING_HTTP_TIMEOUT_MS } from "../../utils/httpTimeout"; +import { checkCrossPairConsistency } from "../../logic/crossPairArbitrageDetection"; dotenv.config(); import { priceReviewService } from "../priceReviewService"; +import { webhookService } from "../webhook"; +import { anomalyDetectionService } from "../anomalyDetection"; export class MarketRateService { fetchers = new Map(); cache = new Map(); @@ -23,6 +29,7 @@ export class MarketRateService { remoteOracleServers = []; pendingSubmissions = []; batchTimeout = null; + crossPairLogger = createFetcherLogger('CrossPairArbitrage'); get CACHE_DURATION_MS() { return appConfig.cacheDurationMs; } @@ -49,6 +56,33 @@ export class MarketRateService { this.fetchers.set("GHS", new GHSRateFetcher()); this.fetchers.set("NGN", new NGNRateFetcher()); } + serializeRawPayload(payload) { + try { + return JSON.stringify(payload); + } + catch { + return String(payload); + } + } + async persistRawResponses(currency, rawResponses) { + if (!Array.isArray(rawResponses) || rawResponses.length === 0) { + return; + } + const clientAny = prisma; + if (!clientAny?.rawData || + typeof clientAny.rawData.createMany !== "function") { + return; + } + await clientAny.rawData.createMany({ + data: rawResponses.map((rawResponse) => ({ + currency, + provider: rawResponse.provider, + endpoint: rawResponse.endpoint ?? null, + payload: this.serializeRawPayload(rawResponse.payload), + fetchedAt: normalizeDateToUTC(rawResponse.receivedAt), + })), + }); + } async getRate(currency) { try { const normalizedCurrency = currency.toUpperCase(); @@ -101,6 +135,12 @@ export class MarketRateService { : "Unknown fetcher error", }; } + try { + await this.persistRawResponses(normalizedCurrency, rate.rawResponses); + } + catch (rawDataError) { + console.error("Failed to persist raw provider responses:", rawDataError); + } const normalizedRate = { ...rate, timestamp: normalizeDateToUTC(rate.timestamp), @@ -127,6 +167,23 @@ export class MarketRateService { comparisonTimestamp: reviewAssessment.comparisonTimestamp, }), }; + // Perform Anomaly Detection + const anomalyCheck = await anomalyDetectionService.checkAnomaly(normalizedCurrency, rate.rate); + if (anomalyCheck.isAnomalous) { + console.warn(`[MarketRateService] Anomaly detected for ${normalizedCurrency}: Z-Score ${anomalyCheck.zScore.toFixed(2)}΃`); + await webhookService.sendPriorityAlert({ + currency: normalizedCurrency, + rate: rate.rate, + zScore: anomalyCheck.zScore, + mean: anomalyCheck.mean, + stdDev: anomalyCheck.stdDev, + timestamp: rate.timestamp, + }); + } + // Cross-pair arbitrage detection (NGN only) + if (normalizedCurrency === 'NGN') { + void this.runCrossPairCheck(rate.rate); + } if (!reviewAssessment.manualReviewRequired) { try { await sanityCheckService.checkPrice(normalizedCurrency, rate.rate); @@ -156,8 +213,7 @@ export class MarketRateService { }); enrichedRate.contractSubmissionSkipped = false; enrichedRate.pendingMultiSig = true; - enrichedRate.multiSigPriceId = - signatureRequest.multiSigPriceId; + enrichedRate.multiSigPriceId = signatureRequest.multiSigPriceId; } else { const txHash = await this.stellarService.submitPriceUpdate(normalizedCurrency, rate.rate, memoId); @@ -456,5 +512,41 @@ export class MarketRateService { } }); } + async runCrossPairCheck(ngnXlmRate) { + try { + const response = await axios.get('https://api.coingecko.com/api/v3/simple/price?ids=stellar&vs_currencies=usd', { + timeout: OUTGOING_HTTP_TIMEOUT_MS, + headers: { 'User-Agent': 'StellarFlow-Oracle/1.0' }, + }); + const xlmUsd = response.data?.stellar?.usd; + if (typeof xlmUsd !== 'number' || xlmUsd <= 0) + return; + // Derive NGN/USD reference from the same CoinGecko data + const ngnUsdReference = ngnXlmRate / xlmUsd; + const result = checkCrossPairConsistency(ngnXlmRate, xlmUsd, ngnUsdReference); + if (result.flagged) { + this.crossPairLogger.warn(`âš ī¸ CROSS-PAIR ARBITRAGE DETECTED: NGN deviation ${result.deviationPercent.toFixed(2)}% exceeds threshold`, { + ngnXlmRate, + xlmUsdRate: xlmUsd, + impliedRate: result.impliedRate, + directRate: result.directRate, + deviationPercent: result.deviationPercent, + }); + } + else { + this.crossPairLogger.debug('✅ Cross-pair consistency check passed for NGN', { + ngnXlmRate, + xlmUsdRate: xlmUsd, + impliedRate: result.impliedRate, + deviationPercent: result.deviationPercent, + }); + } + } + catch (error) { + this.crossPairLogger.warn('Cross-pair check failed, skipping', { + error: error instanceof Error ? error.message : error, + }); + } + } } //# sourceMappingURL=marketRateService.js.map \ No newline at end of file diff --git a/dist/services/marketRate/marketRateService.js.map b/dist/services/marketRate/marketRateService.js.map index def3b95a..e7e194d4 100644 --- a/dist/services/marketRate/marketRateService.js.map +++ b/dist/services/marketRate/marketRateService.js.map @@ -1 +1 @@ -{"version":3,"file":"marketRateService.js","sourceRoot":"","sources":["../../../src/services/marketRate/marketRateService.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"marketRateService.js","sourceRoot":"","sources":["../../../src/services/marketRate/marketRateService.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAS,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,MAAM,MAAM,kBAAkB,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAC;AAEpF,MAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,MAAM,OAAO,iBAAiB;IACpB,QAAQ,GAAmC,IAAI,GAAG,EAAE,CAAC;IACrD,KAAK,GAAoD,IAAI,GAAG,EAAE,CAAC;IACnE,cAAc,CAAiB;IACtB,uBAAuB,GAAG,wBAAwB,CAAC;IACnD,+BAA+B,GAAG,CAAC,CAAC;IAC7C,eAAe,CAAU;IACzB,mBAAmB,GAAa,EAAE,CAAC;IACnC,kBAAkB,GAIrB,EAAE,CAAC;IACA,YAAY,GAAQ,IAAI,CAAC;IAChB,eAAe,GAAG,mBAAmB,CAAC,oBAAoB,CAAC,CAAC;IAE7E,IAAY,iBAAiB;QAC3B,OAAO,SAAS,CAAC,eAAe,CAAC;IACnC,CAAC;IAED,IAAY,eAAe;QACzB,OAAO,SAAS,CAAC,aAAa,CAAC;IACjC,CAAC;IAED;QACE,IAAI,CAAC,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC;QAC3C,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,KAAK,MAAM,CAAC;QAEhE,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,EAAE,CAAC;QACjE,IAAI,gBAAgB,EAAE,CAAC;YACrB,IAAI,CAAC,mBAAmB,GAAG,gBAAgB;iBACxC,KAAK,CAAC,GAAG,CAAC;iBACV,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;iBACxB,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACrC,CAAC;QAED,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,OAAO,CAAC,IAAI,CACV,mDAAmD,IAAI,CAAC,mBAAmB,CAAC,MAAM,iBAAiB,CACpG,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC5B,CAAC;IAEO,kBAAkB;QACxB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,cAAc,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,cAAc,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,cAAc,EAAE,CAAC,CAAC;IACjD,CAAC;IAEO,mBAAmB,CAAC,OAAgB;QAC1C,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,mBAAmB,CAC/B,QAAgB,EAChB,YAA+B;QAE/B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9D,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,MAAa,CAAC;QAChC,IACE,CAAC,SAAS,EAAE,OAAO;YACnB,OAAO,SAAS,CAAC,OAAO,CAAC,UAAU,KAAK,UAAU,EAClD,CAAC;YACD,OAAO;QACT,CAAC;QAED,MAAM,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC;YACjC,IAAI,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;gBACvC,QAAQ;gBACR,QAAQ,EAAE,WAAW,CAAC,QAAQ;gBAC9B,QAAQ,EAAE,WAAW,CAAC,QAAQ,IAAI,IAAI;gBACtC,OAAO,EAAE,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC,OAAO,CAAC;gBACtD,SAAS,EAAE,kBAAkB,CAAC,WAAW,CAAC,UAAU,CAAC;aACtD,CAAC,CAAC;SACJ,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,QAAgB;QAC5B,IAAI,CAAC;YACH,MAAM,kBAAkB,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;YAClD,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;YAEtD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,sCAAsC,QAAQ,EAAE;iBACxD,CAAC;YACJ,CAAC;YAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;YAClD,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC;gBACzC,OAAO;oBACL,OAAO,EAAE,IAAI;oBACb,IAAI,EAAE,MAAM,CAAC,IAAI;iBAClB,CAAC;YACJ,CAAC;YAED,IAAI,IAAgB,CAAC;YAErB,IAAI,CAAC;gBACH,IAAI,GAAG,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC;YACnC,CAAC;YAAC,OAAO,UAAU,EAAE,CAAC;gBACpB,IAAI,CAAC;oBACH,MAAM,YAAY,GAChB,OAAO,IAAI,OAAQ,OAAe,CAAC,WAAW,KAAK,UAAU;wBAC3D,CAAC,CAAE,OAAe,CAAC,WAAW,CAAC,IAAI;wBACnC,CAAC,CAAC,kBAAkB,CAAC;oBAEzB,MAAM,SAAS,GAAG,MAAa,CAAC;oBAChC,IACE,SAAS,EAAE,QAAQ;wBACnB,OAAO,SAAS,CAAC,QAAQ,CAAC,MAAM,KAAK,UAAU,EAC/C,CAAC;wBACD,SAAS,CAAC,QAAQ;6BACf,MAAM,CAAC;4BACN,IAAI,EAAE;gCACJ,YAAY;gCACZ,YAAY,EACV,UAAU,YAAY,KAAK;oCACzB,CAAC,CAAC,UAAU,CAAC,OAAO;oCACpB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;gCAChC,UAAU,EAAE,IAAI,IAAI,EAAE;6BACvB;yBACF,CAAC;6BACD,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;oBACrB,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,yBAAyB;gBAC3B,CAAC;gBAED,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EACH,UAAU,YAAY,KAAK;wBACzB,CAAC,CAAC,UAAU,CAAC,OAAO;wBACpB,CAAC,CAAC,uBAAuB;iBAC9B,CAAC;YACJ,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,mBAAmB,CAAC,kBAAkB,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;YACxE,CAAC;YAAC,OAAO,YAAY,EAAE,CAAC;gBACtB,OAAO,CAAC,KAAK,CACX,2CAA2C,EAC3C,YAAY,CACb,CAAC;YACJ,CAAC;YAED,MAAM,cAAc,GAAe;gBACjC,GAAG,IAAI;gBACP,SAAS,EAAE,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC;gBAC7C,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;oBAC3C,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,mBAAmB,CAAC;oBAC9C,CAAC,CAAC,SAAS;aACd,CAAC;YAEF,MAAM,gBAAgB,GACpB,MAAM,kBAAkB,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;YAEtD,MAAM,YAAY,GAAe;gBAC/B,GAAG,cAAc;gBACjB,oBAAoB,EAAE,gBAAgB,CAAC,oBAAoB;gBAC3D,QAAQ,EAAE,gBAAgB,CAAC,cAAc;gBACzC,yBAAyB,EAAE,gBAAgB,CAAC,oBAAoB;gBAChE,GAAG,CAAC,gBAAgB,CAAC,MAAM,KAAK,SAAS,IAAI;oBAC3C,YAAY,EAAE,gBAAgB,CAAC,MAAM;iBACtC,CAAC;gBACF,GAAG,CAAC,gBAAgB,CAAC,aAAa,KAAK,SAAS,IAAI;oBAClD,mBAAmB,EAAE,gBAAgB,CAAC,aAAa;iBACpD,CAAC;gBACF,GAAG,CAAC,gBAAgB,CAAC,cAAc,KAAK,SAAS,IAAI;oBACnD,cAAc,EAAE,gBAAgB,CAAC,cAAc;iBAChD,CAAC;gBACF,GAAG,CAAC,gBAAgB,CAAC,mBAAmB,KAAK,SAAS,IAAI;oBACxD,mBAAmB,EAAE,gBAAgB,CAAC,mBAAmB;iBAC1D,CAAC;aACH,CAAC;YAEF,4BAA4B;YAC5B,MAAM,YAAY,GAAG,MAAM,uBAAuB,CAAC,YAAY,CAC7D,kBAAkB,EAClB,IAAI,CAAC,IAAI,CACV,CAAC;YACF,IAAI,YAAY,CAAC,WAAW,EAAE,CAAC;gBAC7B,OAAO,CAAC,IAAI,CACV,4CAA4C,kBAAkB,aAAa,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAC7G,CAAC;gBACF,MAAM,cAAc,CAAC,iBAAiB,CAAC;oBACrC,QAAQ,EAAE,kBAAkB;oBAC5B,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,MAAM,EAAE,YAAY,CAAC,MAAM;oBAC3B,IAAI,EAAE,YAAY,CAAC,IAAI;oBACvB,MAAM,EAAE,YAAY,CAAC,MAAM;oBAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;iBAC1B,CAAC,CAAC;YACL,CAAC;YAED,4CAA4C;YAC5C,IAAI,kBAAkB,KAAK,KAAK,EAAE,CAAC;gBACjC,KAAK,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzC,CAAC;YAED,IAAI,CAAC,gBAAgB,CAAC,oBAAoB,EAAE,CAAC;gBAC3C,IAAI,CAAC;oBACH,MAAM,kBAAkB,CAAC,UAAU,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;gBACrE,CAAC;gBAAC,OAAO,WAAW,EAAE,CAAC;oBACrB,OAAO,CAAC,IAAI,CACV,2BAA2B,kBAAkB,GAAG,EAChD,WAAW,CACZ,CAAC;gBACJ,CAAC;gBAED,IAAI,MAAM,iBAAiB,EAAE,EAAE,CAAC;oBAC9B,YAAY,CAAC,yBAAyB,GAAG,IAAI,CAAC;oBAC9C,OAAO,CAAC,IAAI,CACV,kFAAkF,kBAAkB,GAAG,CACxG,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC;wBACH,MAAM,MAAM,GACV,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC;wBAEzD,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;4BACzB,OAAO,CAAC,IAAI,CACV,uDAAuD,kBAAkB,SAAS,IAAI,CAAC,IAAI,EAAE,CAC9F,CAAC;4BAEF,MAAM,gBAAgB,GACpB,MAAM,eAAe,CAAC,qBAAqB,CACzC,gBAAgB,CAAC,cAAc,EAC/B,kBAAkB,EAClB,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,MAAM,EACX,MAAM,CACP,CAAC;4BAEJ,IAAI,CAAC;gCACH,MAAM,eAAe,CAAC,iBAAiB,CACrC,gBAAgB,CAAC,eAAe,CACjC,CAAC;gCACF,OAAO,CAAC,IAAI,CACV,mEAAmE,gBAAgB,CAAC,eAAe,EAAE,CACtG,CAAC;4BACJ,CAAC;4BAAC,OAAO,KAAK,EAAE,CAAC;gCACf,OAAO,CAAC,KAAK,CACX,6CAA6C,EAC7C,KAAK,CACN,CAAC;4BACJ,CAAC;4BAED,IAAI,CAAC,4BAA4B,CAC/B,gBAAgB,CAAC,eAAe,EAChC,MAAM,CACP,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gCACd,OAAO,CAAC,KAAK,CACX,yDAAyD,EACzD,GAAG,CACJ,CAAC;4BACJ,CAAC,CAAC,CAAC;4BAEH,YAAY,CAAC,yBAAyB,GAAG,KAAK,CAAC;4BAC/C,YAAY,CAAC,eAAe,GAAG,IAAI,CAAC;4BACpC,YAAY,CAAC,eAAe,GAAG,gBAAgB,CAAC,eAAe,CAAC;wBAClE,CAAC;6BAAM,CAAC;4BACN,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,iBAAiB,CACxD,kBAAkB,EAClB,IAAI,CAAC,IAAI,EACT,MAAM,CACP,CAAC;4BAEF,MAAM,kBAAkB,CAAC,qBAAqB,CAC5C,gBAAgB,CAAC,cAAc,EAC/B,MAAM,EACN,MAAM,CACP,CAAC;4BAEF,OAAO,CAAC,IAAI,CACV,6DAA6D,kBAAkB,EAAE,CAClF,CAAC;4BAEF,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC;gCAC3B,QAAQ,EAAE,kBAAkB;gCAC5B,IAAI,EAAE,IAAI,CAAC,IAAI;gCACf,QAAQ,EAAE,gBAAgB,CAAC,cAAc;6BAC1C,CAAC,CAAC;4BAEH,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;gCACvB,IAAI,CAAC,YAAY,GAAG,UAAU,CAC5B,GAAG,EAAE,CAAC,IAAI,CAAC,qBAAqB,EAAE,EAClC,IAAI,CAAC,eAAe,CACrB,CAAC;4BACJ,CAAC;wBACH,CAAC;oBACH,CAAC;oBAAC,OAAO,YAAY,EAAE,CAAC;wBACtB,OAAO,CAAC,KAAK,CACX,mDAAmD,EACnD,YAAY,CACb,CAAC;oBACJ,CAAC;gBACH,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CACV,8BAA8B,kBAAkB,SAAS,IAAI,CAAC,IAAI,iCAAiC,CACpG,CAAC;YACJ,CAAC;YAED,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,EAAE;gBACjC,IAAI,EAAE,YAAY;gBAClB,MAAM,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC;aACtD,CAAC,CAAC;YAEH,IAAI,CAAC;gBACH,MAAM,mBAAmB,GAAG,kBAAkB,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;gBAEvE,MAAM,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC;oBAC/B,KAAK,EAAE;wBACL,yBAAyB,EAAE;4BACzB,QAAQ,EAAE,QAAQ,CAAC,WAAW,EAAE;4BAChC,MAAM,EAAE,YAAY,CAAC,MAAM;4BAC3B,SAAS,EAAE,mBAAmB;yBAC/B;qBACF;oBACD,MAAM,EAAE,EAAE;oBACV,MAAM,EAAE;wBACN,QAAQ,EAAE,QAAQ,CAAC,WAAW,EAAE;wBAChC,IAAI,EAAE,YAAY,CAAC,IAAI;wBACvB,MAAM,EAAE,YAAY,CAAC,MAAM;wBAC3B,SAAS,EAAE,mBAAmB;qBAC/B;iBACF,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,OAAO,EAAE,CAAC;gBACjB,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,OAAO,CAAC,CAAC;YAC7D,CAAC;YAED,IAAI,CAAC;gBACH,IAAI,CAAC,gBAAgB,CAAC,oBAAoB,EAAE,CAAC;oBAC3C,mBAAmB,CAAC,cAAc,EAAE;wBAClC,QAAQ,EAAE,kBAAkB;wBAC5B,IAAI,EAAE,YAAY,CAAC,IAAI;wBACvB,MAAM,EAAE,YAAY,CAAC,MAAM;wBAC3B,SAAS,EAAE,YAAY,CAAC,SAAS;qBAClC,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,mBAAmB,CAAC,uBAAuB,EAAE;wBAC3C,QAAQ,EAAE,kBAAkB;wBAC5B,IAAI,EAAE,YAAY,CAAC,IAAI;wBACvB,QAAQ,EAAE,YAAY,CAAC,QAAQ;wBAC/B,MAAM,EAAE,YAAY,CAAC,YAAY;qBAClC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,6BAA6B;YAC/B,CAAC;YAED,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE,YAAY;aACnB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EACH,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB;aACpE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,WAAW;QACf,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QACpD,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;QAEtE,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;IAEO,KAAK,CAAC,qBAAqB;QACjC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,IAAI,CAAC,kBAAkB,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACjD,IAAI,CAAC,kBAAkB,GAAG,EAAE,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,WAAW;QACf,MAAM,OAAO,GAA4B,EAAE,CAAC;QAE5C,KAAK,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChD,IAAI,CAAC;gBACH,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC;YAChD,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC;YAC5B,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,sBAAsB;QACpB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1C,CAAC;IAES,0BAA0B;QAIlC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;QAErC,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;YACzC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAES,KAAK,CAAC,6BAA6B;QAC3C,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC;YAC9C,KAAK,EAAE;gBACL,QAAQ,EAAE;oBACR,EAAE,EAAE,IAAI,CAAC,sBAAsB,EAAE;iBAClC;aACF;YACD,QAAQ,EAAE,CAAC,UAAU,CAAC;YACtB,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;SACtD,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAQ,EAAE,EAAE,CAAC,CAAC;YAC7B,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;YACtB,SAAS,EAAE,kBAAkB,CAAC,GAAG,CAAC,SAAS,CAAC;YAC5C,MAAM,EAAE,GAAG,CAAC,MAAM;SACnB,CAAC,CAAC,CAAC;IACN,CAAC;IAEO,sBAAsB,CAC5B,aAAqB;QAErB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAOtC,CAAC;YAEF,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;gBACxC,OAAO,IAAI,CAAC;YACd,CAAC;YAED,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;gBAC9C,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;oBACzB,GAAG,IAAI;oBACP,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;oBACnC,GAAG,CAAC,IAAI,CAAC,mBAAmB,IAAI;wBAC9B,mBAAmB,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC;qBACxD,CAAC;iBACH,CAAC,CAAC;gBACL,CAAC,CAAC,SAAS,CAAC;YAEd,OAAO;gBACL,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,GAAG,CAAC,aAAa,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;gBAC7C,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;gBAC5C,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;aAChD,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,MAAM,WAAW,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;QAEtD,IAAI,WAAW,EAAE,CAAC;YAChB,IAAI,CAAC;gBACH,MAAM,aAAa,GAAG,MAAM,WAAW,CAAC,GAAG,CACzC,IAAI,CAAC,uBAAuB,CAC7B,CAAC;gBAEF,IAAI,aAAa,EAAE,CAAC;oBAClB,MAAM,cAAc,GAAG,IAAI,CAAC,sBAAsB,CAAC,aAAa,CAAC,CAAC;oBAElE,IAAI,cAAc,EAAE,CAAC;wBACnB,OAAO,cAAc,CAAC;oBACxB,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,gDAAgD,EAAE,KAAK,CAAC,CAAC;YACxE,CAAC;QACH,CAAC;QAED,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,6BAA6B,EAAE,CAAC;YAE/D,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC7B,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,4BAA4B;iBACpC,CAAC;YACJ,CAAC;YAED,MAAM,QAAQ,GAA8B;gBAC1C,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE,WAAW;aAClB,CAAC;YAEF,IAAI,WAAW,EAAE,CAAC;gBAChB,IAAI,CAAC;oBACH,MAAM,WAAW,CAAC,KAAK,CACrB,IAAI,CAAC,uBAAuB,EAC5B,IAAI,CAAC,+BAA+B,EACpC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CACzB,CAAC;gBACJ,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,IAAI,CAAC,+CAA+C,EAAE,KAAK,CAAC,CAAC;gBACvE,CAAC;YACH,CAAC;YAED,OAAO,QAAQ,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EACH,KAAK,YAAY,KAAK;oBACpB,CAAC,CAAC,KAAK,CAAC,OAAO;oBACf,CAAC,CAAC,6CAA6C;aACpD,CAAC;QACJ,CAAC;IACH,CAAC;IAED,UAAU;QACR,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAEnB,MAAM,WAAW,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;QAEtD,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QAED,KAAK,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACjE,OAAO,CAAC,IAAI,CAAC,4CAA4C,EAAE,KAAK,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,iBAAiB;QACrB,OAAO,kBAAkB,CAAC,iBAAiB,EAAE,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,oBAAoB,CACxB,QAAgB,EAChB,UAAmB,EACnB,WAAoB;QAEpB,MAAM,aAAa,GACjB,MAAM,kBAAkB,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC;QAE1D,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,kBAAkB,QAAQ,gBAAgB,CAAC,CAAC;QAC9D,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAE1E,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,iBAAiB,CACxD,aAAa,CAAC,QAAQ,EACtB,aAAa,CAAC,IAAI,EAClB,MAAM,CACP,CAAC;QAEF,MAAM,cAAc,GAAG,MAAM,kBAAkB,CAAC,aAAa,CAAC;YAC5D,QAAQ;YACR,MAAM;YACN,aAAa,EAAE,MAAM;YACrB,GAAG,CAAC,UAAU,KAAK,SAAS,IAAI,EAAE,UAAU,EAAE,CAAC;YAC/C,GAAG,CAAC,WAAW,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,CAAC;SAClD,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;QAExD,IAAI,CAAC;YACH,mBAAmB,CAAC,uBAAuB,EAAE;gBAC3C,MAAM,EAAE,UAAU;gBAClB,MAAM,EAAE,cAAc;aACvB,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,6BAA6B;QAC/B,CAAC;QAED,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,mBAAmB,CACvB,QAAgB,EAChB,UAAmB,EACnB,WAAoB;QAEpB,MAAM,cAAc,GAAG,MAAM,kBAAkB,CAAC,YAAY,CAAC;YAC3D,QAAQ;YACR,GAAG,CAAC,UAAU,KAAK,SAAS,IAAI,EAAE,UAAU,EAAE,CAAC;YAC/C,GAAG,CAAC,WAAW,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,CAAC;SAClD,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;QAEzD,IAAI,CAAC;YACH,mBAAmB,CAAC,uBAAuB,EAAE;gBAC3C,MAAM,EAAE,UAAU;gBAClB,MAAM,EAAE,cAAc;aACvB,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,6BAA6B;QAC/B,CAAC;QAED,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,cAAc;QACZ,MAAM,MAAM,GAAuD,EAAE,CAAC;QAEtE,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;YAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAExC,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC;gBACzC,MAAM,CAAC,QAAQ,CAAC,GAAG;oBACjB,MAAM,EAAE,IAAI;oBACZ,MAAM,EAAE,MAAM,CAAC,MAAM;iBACtB,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,QAAQ,CAAC,GAAG;oBACjB,MAAM,EAAE,KAAK;iBACd,CAAC;YACJ,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,KAAK,CAAC,4BAA4B,CACxC,eAAuB,EACvB,OAAe;QAEf,OAAO,CAAC,IAAI,CACV,kDAAkD,IAAI,CAAC,mBAAmB,CAAC,MAAM,iCAAiC,eAAe,EAAE,CACpI,CAAC;QAEF,MAAM,iBAAiB,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CACnE,eAAe,CAAC,sBAAsB,CAAC,eAAe,EAAE,SAAS,CAAC,CACnE,CAAC;QAEF,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;QAE5D,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;YAChC,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;gBAClC,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;oBACzB,OAAO,CAAC,IAAI,CACV,mDAAmD,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE,CACrF,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,IAAI,CACV,uDAAuD,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,CAChH,CAAC;gBACJ,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CACX,yDAAyD,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,GAAG,EAC3F,MAAM,CAAC,MAAM,CACd,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,UAAkB;QAChD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAC9B,6EAA6E,EAC7E;gBACE,OAAO,EAAE,wBAAwB;gBACjC,OAAO,EAAE,EAAE,YAAY,EAAE,wBAAwB,EAAE;aACpD,CACF,CAAC;YACF,MAAM,MAAM,GAAY,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC;YACpD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,IAAI,CAAC;gBAAE,OAAO;YAEtD,wDAAwD;YACxD,MAAM,eAAe,GAAG,UAAU,GAAG,MAAM,CAAC;YAE5C,MAAM,MAAM,GAAG,yBAAyB,CAAC,UAAU,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;YAE9E,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,IAAI,CAAC,eAAe,CAAC,IAAI,CACvB,mDAAmD,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,qBAAqB,EAC1G;oBACE,UAAU;oBACV,UAAU,EAAE,MAAM;oBAClB,WAAW,EAAE,MAAM,CAAC,WAAW;oBAC/B,UAAU,EAAE,MAAM,CAAC,UAAU;oBAC7B,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;iBAC1C,CACF,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,+CAA+C,EAAE;oBAC1E,UAAU;oBACV,UAAU,EAAE,MAAM;oBAClB,WAAW,EAAE,MAAM,CAAC,WAAW;oBAC/B,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;iBAC1C,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,mCAAmC,EAAE;gBAC7D,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK;aACtD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;CACF"} \ No newline at end of file diff --git a/dist/services/marketRate/ngnFetcher.d.ts b/dist/services/marketRate/ngnFetcher.d.ts index 0d92faed..a664b260 100644 --- a/dist/services/marketRate/ngnFetcher.d.ts +++ b/dist/services/marketRate/ngnFetcher.d.ts @@ -13,6 +13,7 @@ export declare class NGNRateFetcher implements MarketRateFetcher { private readonly coinGeckoUrl; private readonly usdToNgnUrl; private logger; + private medianPriceService; private vtpassBase; private vtpassHeaders; getCurrency(): string; diff --git a/dist/services/marketRate/ngnFetcher.d.ts.map b/dist/services/marketRate/ngnFetcher.d.ts.map index 9a0c5b6d..a1eba66d 100644 --- a/dist/services/marketRate/ngnFetcher.d.ts.map +++ b/dist/services/marketRate/ngnFetcher.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"ngnFetcher.d.ts","sourceRoot":"","sources":["../../../src/services/marketRate/ngnFetcher.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,iBAAiB,EACjB,UAAU,EAGX,MAAM,SAAS,CAAC;AAqDjB;;;;;;;;;GASG;AACH,qBAAa,cAAe,YAAW,iBAAiB;IACtD,OAAO,CAAC,QAAQ,CAAC,YAAY,CACoF;IAEjH,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA2C;IACvE,OAAO,CAAC,MAAM,CAAkC;IAEhD,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,aAAa;IAYrB,WAAW,IAAI,MAAM;YAIP,wBAAwB;IA2ChC,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC;IAmKhC,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;CAUpC"} \ No newline at end of file +{"version":3,"file":"ngnFetcher.d.ts","sourceRoot":"","sources":["../../../src/services/marketRate/ngnFetcher.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,iBAAiB,EACjB,UAAU,EAIX,MAAM,SAAS,CAAC;AAiDjB;;;;;;;;;GASG;AACH,qBAAa,cAAe,YAAW,iBAAiB;IACtD,OAAO,CAAC,QAAQ,CAAC,YAAY,CACoF;IAEjH,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA2C;IACvE,OAAO,CAAC,MAAM,CAAkC;IAChD,OAAO,CAAC,kBAAkB,CAA4B;IAEtD,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,aAAa;IAYrB,WAAW,IAAI,MAAM;YAIP,wBAAwB;IAgDhC,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC;IA+MhC,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;CAUpC"} \ No newline at end of file diff --git a/dist/services/marketRate/ngnFetcher.js b/dist/services/marketRate/ngnFetcher.js index b88531b4..2ef6baed 100644 --- a/dist/services/marketRate/ngnFetcher.js +++ b/dist/services/marketRate/ngnFetcher.js @@ -1,9 +1,9 @@ import axios from "axios"; import { OUTGOING_HTTP_TIMEOUT_MS } from "../../utils/httpTimeout.js"; -import { calculateWeightedAverage, filterOutliers, } from "./types"; +import { filterOutliers, } from "./types"; import { withRetry } from "../../utils/retryUtil.js"; -import { getNGNProviderWeight, } from "../../config/providerWeights.js"; import { createFetcherLogger } from "../../utils/logger.js"; +import { MedianPriceService } from "./medianPriceService.js"; function parseAmount(value) { if (value == null) return null; @@ -26,6 +26,7 @@ export class NGNRateFetcher { coinGeckoUrl = "https://api.coingecko.com/api/v3/simple/price?ids=stellar&vs_currencies=ngn,usd&include_last_updated_at=true"; usdToNgnUrl = "https://open.er-api.com/v6/latest/USD"; logger = createFetcherLogger("NGNRate"); + medianPriceService = new MedianPriceService(); vtpassBase() { return (process.env.VTPASS_API_BASE_URL ?? "https://vtpass.com/api").replace(/\/$/, ""); } @@ -71,19 +72,36 @@ export class NGNRateFetcher { const ngnPerUsd = rateFromField ?? amount; if (ngnPerUsd == null) return null; - return { ngnPerUsd, timestamp: new Date() }; + return { + ngnPerUsd, + timestamp: new Date(), + rawResponse: response.data, + }; } async fetchRate() { const prices = []; + const rawResponses = []; try { const vt = await this.fetchNgnPerUsdFromVtpass(); if (vt) { + rawResponses.push({ + provider: "VTpass", + endpoint: `${this.vtpassBase()}/service-variations`, + payload: vt.rawResponse, + receivedAt: new Date(), + }); const coinGeckoResponse = await withRetry(() => axios.get(this.coinGeckoUrl, { timeout: OUTGOING_HTTP_TIMEOUT_MS, headers: { "User-Agent": "StellarFlow-Oracle/1.0", }, }), { maxRetries: 3, retryDelay: 1000 }); + rawResponses.push({ + provider: "CoinGecko", + endpoint: this.coinGeckoUrl, + payload: coinGeckoResponse.data, + receivedAt: new Date(), + }); const usd = coinGeckoResponse.data.stellar?.usd; if (typeof usd === "number" && usd > 0) { const lastUpdatedAt = coinGeckoResponse.data.stellar?.last_updated_at @@ -94,7 +112,6 @@ export class NGNRateFetcher { rate: usd * vt.ngnPerUsd, timestamp: ts, source: "VTpass variation + CoinGecko (XLM/USD)", - providerKey: "vtpassCoinGeckoUsd", }); } } @@ -109,6 +126,12 @@ export class NGNRateFetcher { "User-Agent": "StellarFlow-Oracle/1.0", }, }), { maxRetries: 3, retryDelay: 1000 }); + rawResponses.push({ + provider: "CoinGecko", + endpoint: this.coinGeckoUrl, + payload: coinGeckoResponse.data, + receivedAt: new Date(), + }); const stellarPrice = coinGeckoResponse.data.stellar; if (stellarPrice && typeof stellarPrice.ngn === "number" && @@ -120,7 +143,6 @@ export class NGNRateFetcher { rate: stellarPrice.ngn, timestamp: lastUpdatedAt, source: "CoinGecko (direct NGN)", - providerKey: "coinGeckoDirectNgn", }); } } @@ -134,6 +156,12 @@ export class NGNRateFetcher { "User-Agent": "StellarFlow-Oracle/1.0", }, }), { maxRetries: 3, retryDelay: 1000 }); + rawResponses.push({ + provider: "CoinGecko", + endpoint: this.coinGeckoUrl, + payload: coinGeckoResponse.data, + receivedAt: new Date(), + }); const stellarPrice = coinGeckoResponse.data.stellar; if (stellarPrice && typeof stellarPrice.usd === "number" && @@ -144,6 +172,12 @@ export class NGNRateFetcher { "User-Agent": "StellarFlow-Oracle/1.0", }, }), { maxRetries: 3, retryDelay: 1000 }); + rawResponses.push({ + provider: "ExchangeRate API", + endpoint: this.usdToNgnUrl, + payload: fxResponse.data, + receivedAt: new Date(), + }); const usdToNgn = fxResponse.data.rates?.NGN; if (fxResponse.data.result === "success" && typeof usdToNgn === "number" && @@ -158,7 +192,6 @@ export class NGNRateFetcher { rate: stellarPrice.usd * usdToNgn, timestamp: fxTimestamp > lastUpdatedAt ? fxTimestamp : lastUpdatedAt, source: "CoinGecko + ExchangeRate API (USD->NGN)", - providerKey: "coinGeckoExchangeRateUsdNgn", }); } } @@ -171,19 +204,28 @@ export class NGNRateFetcher { this.logger.fetcherError(error, "All price sources failed - no rates obtained", { attemptedSources: 3, pricesLength: prices.length }); throw error; } - const filteredRateValues = filterOutliers(prices.map((p) => p.rate).filter((rate) => rate > 0)); + const rateValues = prices + .map((price) => price.rate) + .filter((rate) => Number.isFinite(rate) && rate > 0); + const filteredRateValues = filterOutliers(rateValues); const filteredPrices = prices.filter((price) => filteredRateValues.includes(price.rate)); - const pricesToUse = filteredPrices.length > 0 ? filteredPrices : prices; - const mostRecentTimestamp = prices.reduce((latest, p) => (p.timestamp > latest ? p.timestamp : latest), prices[0]?.timestamp ?? new Date()); - const weightedRate = calculateWeightedAverage(pricesToUse.map((price) => ({ - value: price.rate, - weight: getNGNProviderWeight(price.providerKey), - }))); + const pricesToUse = filteredPrices.length >= 3 ? filteredPrices : prices; + if (pricesToUse.length < 3) { + const error = new Error(`Need at least 3 price sources for median calculation, got ${pricesToUse.length}`); + this.logger.fetcherError(error.message, { + attemptedSources: 3, + pricesLength: pricesToUse.length, + }); + throw error; + } + const mostRecentTimestamp = pricesToUse.reduce((latest, p) => (p.timestamp > latest ? p.timestamp : latest), pricesToUse[0]?.timestamp ?? new Date()); + const medianRate = this.medianPriceService.calculateMedian(pricesToUse.map((price) => price.rate)); return { currency: "NGN", - rate: weightedRate, + rate: medianRate, timestamp: mostRecentTimestamp, source: `Weighted average of ${pricesToUse.length} sources (outliers filtered)`, + rawResponses, }; } async isHealthy() { diff --git a/dist/services/marketRate/ngnFetcher.js.map b/dist/services/marketRate/ngnFetcher.js.map index 56141b9a..0288ce9e 100644 --- a/dist/services/marketRate/ngnFetcher.js.map +++ b/dist/services/marketRate/ngnFetcher.js.map @@ -1 +1 @@ -{"version":3,"file":"ngnFetcher.js","sourceRoot":"","sources":["../../../src/services/marketRate/ngnFetcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAGL,wBAAwB,EACxB,cAAc,GACf,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EACL,oBAAoB,GAErB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAwC5D,SAAS,WAAW,CAAC,KAAyB;IAC5C,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IAC/B,MAAM,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;IAC7D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/C,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,OAAO,cAAc;IACR,YAAY,GAC3B,8GAA8G,CAAC;IAEhG,WAAW,GAAG,uCAAuC,CAAC;IAC/D,MAAM,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAExC,UAAU;QAChB,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,wBAAwB,CAC5D,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACvB,CAAC;IAEO,aAAa;QACnB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QAC1C,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;QAChD,IAAI,MAAM,IAAI,SAAS,EAAE,CAAC;YACxB,OAAO;gBACL,SAAS,EAAE,MAAM;gBACjB,YAAY,EAAE,SAAS;aACxB,CAAC;QACJ,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,WAAW;QACT,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,KAAK,CAAC,wBAAwB;QAIpC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,IAAI,EAAE,CAAC;QAC5D,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,EAAE,IAAI,EAAE,CAAC;QACpE,IAAI,CAAC,SAAS,IAAI,CAAC,aAAa;YAAE,OAAO,IAAI,CAAC;QAE9C,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACrC,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAE1B,MAAM,QAAQ,GAAG,MAAM,SAAS,CAC9B,GAAG,EAAE,CACH,KAAK,CAAC,GAAG,CACP,GAAG,IAAI,CAAC,UAAU,EAAE,qBAAqB,EACzC;YACE,MAAM,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE;YAChC,OAAO,EAAE,wBAAwB;YACjC,OAAO,EAAE;gBACP,GAAG,OAAO;gBACV,YAAY,EAAE,wBAAwB;aACvC;SACF,CACF,EACH,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CACpC,CAAC;QAEF,IAAI,QAAQ,CAAC,IAAI,CAAC,oBAAoB,KAAK,KAAK,EAAE,CAAC;YACjD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,IAAI,EAAE,CAAC;QAC3D,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,KAAK,aAAa,CAAC,CAAC;QACzE,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAExB,MAAM,aAAa,GAAG,WAAW,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QACxD,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACnD,MAAM,SAAS,GAAG,aAAa,IAAI,MAAM,CAAC;QAC1C,IAAI,SAAS,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC;QAEnC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,SAAS;QACb,MAAM,MAAM,GAAwB,EAAE,CAAC;QAEvC,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,wBAAwB,EAAE,CAAC;YACjD,IAAI,EAAE,EAAE,CAAC;gBACP,MAAM,iBAAiB,GAAG,MAAM,SAAS,CACvC,GAAG,EAAE,CACH,KAAK,CAAC,GAAG,CAAyB,IAAI,CAAC,YAAY,EAAE;oBACnD,OAAO,EAAE,wBAAwB;oBACjC,OAAO,EAAE;wBACP,YAAY,EAAE,wBAAwB;qBACvC;iBACF,CAAC,EACJ,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CACpC,CAAC;gBAEF,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC;gBAChD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;oBACvC,MAAM,aAAa,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe;wBACnE,CAAC,CAAC,IAAI,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;wBACjE,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;oBACf,MAAM,EAAE,GACN,EAAE,CAAC,SAAS,GAAG,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC;oBAE9D,MAAM,CAAC,IAAI,CAAC;wBACV,IAAI,EAAE,GAAG,GAAG,EAAE,CAAC,SAAS;wBACxB,SAAS,EAAE,EAAE;wBACb,MAAM,EAAE,wCAAwC;wBAChD,WAAW,EAAE,oBAAoB;qBAClC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,EAAE,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QACpH,CAAC;QAED,IAAI,CAAC;YACH,MAAM,iBAAiB,GAAG,MAAM,SAAS,CACvC,GAAG,EAAE,CACH,KAAK,CAAC,GAAG,CAAyB,IAAI,CAAC,YAAY,EAAE;gBACnD,OAAO,EAAE,wBAAwB;gBACjC,OAAO,EAAE;oBACP,YAAY,EAAE,wBAAwB;iBACvC;aACF,CAAC,EACJ,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CACpC,CAAC;YAEF,MAAM,YAAY,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC;YACpD,IACE,YAAY;gBACZ,OAAO,YAAY,CAAC,GAAG,KAAK,QAAQ;gBACpC,YAAY,CAAC,GAAG,GAAG,CAAC,EACpB,CAAC;gBACD,MAAM,aAAa,GAAG,YAAY,CAAC,eAAe;oBAChD,CAAC,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,eAAe,GAAG,IAAI,CAAC;oBAC/C,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;gBAEf,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,YAAY,CAAC,GAAG;oBACtB,SAAS,EAAE,aAAa;oBACxB,MAAM,EAAE,wBAAwB;oBAChC,WAAW,EAAE,oBAAoB;iBAClC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,6BAA6B,EAAE,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QAC9G,CAAC;QAED,IAAI,CAAC;YACH,MAAM,iBAAiB,GAAG,MAAM,SAAS,CACvC,GAAG,EAAE,CACH,KAAK,CAAC,GAAG,CAAyB,IAAI,CAAC,YAAY,EAAE;gBACnD,OAAO,EAAE,wBAAwB;gBACjC,OAAO,EAAE;oBACP,YAAY,EAAE,wBAAwB;iBACvC;aACF,CAAC,EACJ,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CACpC,CAAC;YAEF,MAAM,YAAY,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC;YACpD,IACE,YAAY;gBACZ,OAAO,YAAY,CAAC,GAAG,KAAK,QAAQ;gBACpC,YAAY,CAAC,GAAG,GAAG,CAAC,EACpB,CAAC;gBACD,MAAM,UAAU,GAAG,MAAM,SAAS,CAChC,GAAG,EAAE,CACH,KAAK,CAAC,GAAG,CAA0B,IAAI,CAAC,WAAW,EAAE;oBACnD,OAAO,EAAE,wBAAwB;oBACjC,OAAO,EAAE;wBACP,YAAY,EAAE,wBAAwB;qBACvC;iBACF,CAAC,EACJ,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CACpC,CAAC;gBAEF,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC;gBAC5C,IACE,UAAU,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS;oBACpC,OAAO,QAAQ,KAAK,QAAQ;oBAC5B,QAAQ,GAAG,CAAC,EACZ,CAAC;oBACD,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,qBAAqB;wBACvD,CAAC,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;wBACxD,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;oBACf,MAAM,aAAa,GAAG,YAAY,CAAC,eAAe;wBAChD,CAAC,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,eAAe,GAAG,IAAI,CAAC;wBAC/C,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;oBAEf,MAAM,CAAC,IAAI,CAAC;wBACV,IAAI,EAAE,YAAY,CAAC,GAAG,GAAG,QAAQ;wBACjC,SAAS,EACP,WAAW,GAAG,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa;wBAC3D,MAAM,EAAE,yCAAyC;wBACjD,WAAW,EAAE,6BAA6B;qBAC3C,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,2CAA2C,EAAE,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5H,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;YACvD,IAAI,CAAC,MAAM,CAAC,YAAY,CACtB,KAAK,EACL,8CAA8C,EAC9C,EAAE,gBAAgB,EAAE,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,CACrD,CAAC;YACF,MAAM,KAAK,CAAC;QACd,CAAC;QAED,MAAM,kBAAkB,GAAG,cAAc,CACvC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CACrD,CAAC;QACF,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAC7C,kBAAkB,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CACxC,CAAC;QACF,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC;QAExE,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,CACvC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,EAC5D,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,IAAI,IAAI,IAAI,EAAE,CACnC,CAAC;QAEF,MAAM,YAAY,GAAG,wBAAwB,CAC3C,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC1B,KAAK,EAAE,KAAK,CAAC,IAAI;YACjB,MAAM,EAAE,oBAAoB,CAAC,KAAK,CAAC,WAAW,CAAC;SAChD,CAAC,CAAC,CACJ,CAAC;QAEF,OAAO;YACL,QAAQ,EAAE,KAAK;YACf,IAAI,EAAE,YAAY;YAClB,SAAS,EAAE,mBAAmB;YAC9B,MAAM,EAAE,uBAAuB,WAAW,CAAC,MAAM,8BAA8B;SAChF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,SAAS;QACb,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YACpC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YAClF,OAAO,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,SAAS,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC/G,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF"} \ No newline at end of file +{"version":3,"file":"ngnFetcher.js","sourceRoot":"","sources":["../../../src/services/marketRate/ngnFetcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAKL,cAAc,GACf,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAuC7D,SAAS,WAAW,CAAC,KAAyB;IAC5C,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IAC/B,MAAM,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;IAC7D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/C,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,OAAO,cAAc;IACR,YAAY,GAC3B,8GAA8G,CAAC;IAEhG,WAAW,GAAG,uCAAuC,CAAC;IAC/D,MAAM,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;IACxC,kBAAkB,GAAG,IAAI,kBAAkB,EAAE,CAAC;IAE9C,UAAU;QAChB,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,wBAAwB,CAC5D,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACvB,CAAC;IAEO,aAAa;QACnB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QAC1C,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;QAChD,IAAI,MAAM,IAAI,SAAS,EAAE,CAAC;YACxB,OAAO;gBACL,SAAS,EAAE,MAAM;gBACjB,YAAY,EAAE,SAAS;aACxB,CAAC;QACJ,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,WAAW;QACT,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,KAAK,CAAC,wBAAwB;QAKpC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,IAAI,EAAE,CAAC;QAC5D,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,EAAE,IAAI,EAAE,CAAC;QACpE,IAAI,CAAC,SAAS,IAAI,CAAC,aAAa;YAAE,OAAO,IAAI,CAAC;QAE9C,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACrC,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAE1B,MAAM,QAAQ,GAAG,MAAM,SAAS,CAC9B,GAAG,EAAE,CACH,KAAK,CAAC,GAAG,CACP,GAAG,IAAI,CAAC,UAAU,EAAE,qBAAqB,EACzC;YACE,MAAM,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE;YAChC,OAAO,EAAE,wBAAwB;YACjC,OAAO,EAAE;gBACP,GAAG,OAAO;gBACV,YAAY,EAAE,wBAAwB;aACvC;SACF,CACF,EACH,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CACpC,CAAC;QAEF,IAAI,QAAQ,CAAC,IAAI,CAAC,oBAAoB,KAAK,KAAK,EAAE,CAAC;YACjD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,IAAI,EAAE,CAAC;QAC3D,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,KAAK,aAAa,CAAC,CAAC;QACzE,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAExB,MAAM,aAAa,GAAG,WAAW,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QACxD,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACnD,MAAM,SAAS,GAAG,aAAa,IAAI,MAAM,CAAC;QAC1C,IAAI,SAAS,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC;QAEnC,OAAO;YACL,SAAS;YACT,SAAS,EAAE,IAAI,IAAI,EAAE;YACrB,WAAW,EAAE,QAAQ,CAAC,IAAI;SAC3B,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,SAAS;QACb,MAAM,MAAM,GAAwB,EAAE,CAAC;QACvC,MAAM,YAAY,GAAqB,EAAE,CAAC;QAE1C,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,wBAAwB,EAAE,CAAC;YACjD,IAAI,EAAE,EAAE,CAAC;gBACP,YAAY,CAAC,IAAI,CAAC;oBAChB,QAAQ,EAAE,QAAQ;oBAClB,QAAQ,EAAE,GAAG,IAAI,CAAC,UAAU,EAAE,qBAAqB;oBACnD,OAAO,EAAE,EAAE,CAAC,WAAW;oBACvB,UAAU,EAAE,IAAI,IAAI,EAAE;iBACvB,CAAC,CAAC;gBAEH,MAAM,iBAAiB,GAAG,MAAM,SAAS,CACvC,GAAG,EAAE,CACH,KAAK,CAAC,GAAG,CAAyB,IAAI,CAAC,YAAY,EAAE;oBACnD,OAAO,EAAE,wBAAwB;oBACjC,OAAO,EAAE;wBACP,YAAY,EAAE,wBAAwB;qBACvC;iBACF,CAAC,EACJ,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CACpC,CAAC;gBAEA,YAAY,CAAC,IAAI,CAAC;oBAChB,QAAQ,EAAE,WAAW;oBACrB,QAAQ,EAAE,IAAI,CAAC,YAAY;oBAC3B,OAAO,EAAE,iBAAiB,CAAC,IAAI;oBAC/B,UAAU,EAAE,IAAI,IAAI,EAAE;iBACvB,CAAC,CAAC;gBAEL,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC;gBAChD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;oBACvC,MAAM,aAAa,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe;wBACnE,CAAC,CAAC,IAAI,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;wBACjE,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;oBACf,MAAM,EAAE,GACN,EAAE,CAAC,SAAS,GAAG,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC;oBAE9D,MAAM,CAAC,IAAI,CAAC;wBACV,IAAI,EAAE,GAAG,GAAG,EAAE,CAAC,SAAS;wBACxB,SAAS,EAAE,EAAE;wBACb,MAAM,EAAE,wCAAwC;qBACjD,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,EAAE,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QACpH,CAAC;QAED,IAAI,CAAC;YACH,MAAM,iBAAiB,GAAG,MAAM,SAAS,CACvC,GAAG,EAAE,CACH,KAAK,CAAC,GAAG,CAAyB,IAAI,CAAC,YAAY,EAAE;gBACnD,OAAO,EAAE,wBAAwB;gBACjC,OAAO,EAAE;oBACP,YAAY,EAAE,wBAAwB;iBACvC;aACF,CAAC,EACJ,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CACpC,CAAC;YAEF,YAAY,CAAC,IAAI,CAAC;gBAChB,QAAQ,EAAE,WAAW;gBACrB,QAAQ,EAAE,IAAI,CAAC,YAAY;gBAC3B,OAAO,EAAE,iBAAiB,CAAC,IAAI;gBAC/B,UAAU,EAAE,IAAI,IAAI,EAAE;aACvB,CAAC,CAAC;YAEH,MAAM,YAAY,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC;YACpD,IACE,YAAY;gBACZ,OAAO,YAAY,CAAC,GAAG,KAAK,QAAQ;gBACpC,YAAY,CAAC,GAAG,GAAG,CAAC,EACpB,CAAC;gBACD,MAAM,aAAa,GAAG,YAAY,CAAC,eAAe;oBAChD,CAAC,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,eAAe,GAAG,IAAI,CAAC;oBAC/C,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;gBAEf,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,YAAY,CAAC,GAAG;oBACtB,SAAS,EAAE,aAAa;oBACxB,MAAM,EAAE,wBAAwB;iBACjC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,6BAA6B,EAAE,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QAC9G,CAAC;QAED,IAAI,CAAC;YACH,MAAM,iBAAiB,GAAG,MAAM,SAAS,CACvC,GAAG,EAAE,CACH,KAAK,CAAC,GAAG,CAAyB,IAAI,CAAC,YAAY,EAAE;gBACnD,OAAO,EAAE,wBAAwB;gBACjC,OAAO,EAAE;oBACP,YAAY,EAAE,wBAAwB;iBACvC;aACF,CAAC,EACJ,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CACpC,CAAC;YAEF,YAAY,CAAC,IAAI,CAAC;gBAChB,QAAQ,EAAE,WAAW;gBACrB,QAAQ,EAAE,IAAI,CAAC,YAAY;gBAC3B,OAAO,EAAE,iBAAiB,CAAC,IAAI;gBAC/B,UAAU,EAAE,IAAI,IAAI,EAAE;aACvB,CAAC,CAAC;YAEH,MAAM,YAAY,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC;YACpD,IACE,YAAY;gBACZ,OAAO,YAAY,CAAC,GAAG,KAAK,QAAQ;gBACpC,YAAY,CAAC,GAAG,GAAG,CAAC,EACpB,CAAC;gBACD,MAAM,UAAU,GAAG,MAAM,SAAS,CAChC,GAAG,EAAE,CACH,KAAK,CAAC,GAAG,CAA0B,IAAI,CAAC,WAAW,EAAE;oBACnD,OAAO,EAAE,wBAAwB;oBACjC,OAAO,EAAE;wBACP,YAAY,EAAE,wBAAwB;qBACvC;iBACF,CAAC,EACJ,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CACpC,CAAC;gBAEF,YAAY,CAAC,IAAI,CAAC;oBAChB,QAAQ,EAAE,kBAAkB;oBAC5B,QAAQ,EAAE,IAAI,CAAC,WAAW;oBAC1B,OAAO,EAAE,UAAU,CAAC,IAAI;oBACxB,UAAU,EAAE,IAAI,IAAI,EAAE;iBACvB,CAAC,CAAC;gBAEH,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC;gBAC5C,IACE,UAAU,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS;oBACpC,OAAO,QAAQ,KAAK,QAAQ;oBAC5B,QAAQ,GAAG,CAAC,EACZ,CAAC;oBACD,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,qBAAqB;wBACvD,CAAC,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;wBACxD,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;oBACf,MAAM,aAAa,GAAG,YAAY,CAAC,eAAe;wBAChD,CAAC,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,eAAe,GAAG,IAAI,CAAC;wBAC/C,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;oBAEf,MAAM,CAAC,IAAI,CAAC;wBACV,IAAI,EAAE,YAAY,CAAC,GAAG,GAAG,QAAQ;wBACjC,SAAS,EACP,WAAW,GAAG,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa;wBAC3D,MAAM,EAAE,yCAAyC;qBAClD,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,2CAA2C,EAAE,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5H,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;YACvD,IAAI,CAAC,MAAM,CAAC,YAAY,CACtB,KAAK,EACL,8CAA8C,EAC9C,EAAE,gBAAgB,EAAE,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,CACrD,CAAC;YACF,MAAM,KAAK,CAAC;QACd,CAAC;QAED,MAAM,UAAU,GAAG,MAAM;aACtB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;aAC1B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC;QACvD,MAAM,kBAAkB,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;QACtD,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAC7C,kBAAkB,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CACxC,CAAC;QACF,MAAM,WAAW,GACf,cAAc,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC;QAEvD,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,IAAI,KAAK,CACrB,6DAA6D,WAAW,CAAC,MAAM,EAAE,CAClF,CAAC;YACF,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE;gBACtC,gBAAgB,EAAE,CAAC;gBACnB,YAAY,EAAE,WAAW,CAAC,MAAM;aACjC,CAAC,CAAC;YACH,MAAM,KAAK,CAAC;QACd,CAAC;QAED,MAAM,mBAAmB,GAAG,WAAW,CAAC,MAAM,CAC5C,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,EAC5D,WAAW,CAAC,CAAC,CAAC,EAAE,SAAS,IAAI,IAAI,IAAI,EAAE,CACxC,CAAC;QAEF,MAAM,UAAU,GAAG,IAAI,CAAC,kBAAkB,CAAC,eAAe,CACxD,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CACvC,CAAC;QAEF,OAAO;YACL,QAAQ,EAAE,KAAK;YACf,IAAI,EAAE,UAAU;YAChB,SAAS,EAAE,mBAAmB;YAC9B,MAAM,EAAE,uBAAuB,WAAW,CAAC,MAAM,8BAA8B;YAC/E,YAAY;SACb,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,SAAS;QACb,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YACpC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YAClF,OAAO,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,SAAS,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC/G,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF"} \ No newline at end of file diff --git a/dist/services/marketRate/types.d.ts b/dist/services/marketRate/types.d.ts index 08fedf75..66efbda2 100644 --- a/dist/services/marketRate/types.d.ts +++ b/dist/services/marketRate/types.d.ts @@ -1,3 +1,9 @@ +export interface RawApiResponse { + provider: string; + endpoint?: string; + payload: unknown; + receivedAt: Date; +} /** * Market Rate Interface * Represents the fetched exchange rate data @@ -14,6 +20,7 @@ export interface MarketRate { comparisonRate?: number | undefined; comparisonTimestamp?: Date | undefined; contractSubmissionSkipped?: boolean; + rawResponses?: RawApiResponse[]; pendingMultiSig?: boolean; multiSigPriceId?: number; } diff --git a/dist/services/marketRate/types.d.ts.map b/dist/services/marketRate/types.d.ts.map index 1694e21b..0f80fd60 100644 --- a/dist/services/marketRate/types.d.ts.map +++ b/dist/services/marketRate/types.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/services/marketRate/types.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/services/marketRate/types.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/marketRate/types.js.map b/dist/services/marketRate/types.js.map index 6661823b..6c21aea1 100644 --- a/dist/services/marketRate/types.js.map +++ b/dist/services/marketRate/types.js.map @@ -1 +1 @@ -{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/services/marketRate/types.ts"],"names":[],"mappings":"AAqFA;;;GAGG;AACH,MAAM,CAAN,IAAY,mBAIX;AAJD,WAAY,mBAAmB;IAC7B,wCAAiB,CAAA;IACjB,oCAAa,CAAA;IACb,8CAAuB,CAAA;AACzB,CAAC,EAJW,mBAAmB,KAAnB,mBAAmB,QAI9B;AAkBD;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,MAAgB;IAC9C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAElC,MAAM,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAE7C,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAChC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QAC5B,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YAC7C,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;QACD,OAAO,IAAI,IAAI,IAAI,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAgB;IAC/C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAElC,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC;IAC1D,OAAO,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC;AAC7B,CAAC;AAQD,MAAM,oBAAoB,GAAqC;IAC7D,OAAO,EAAE,CAAC;IACV,QAAQ,EAAE,CAAC;IACX,GAAG,EAAE,CAAC;CACP,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAA4B;IACnE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAElC,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,WAAW,GAAG,oBAAoB,CAAC,KAAK,CAAC,UAAU,IAAI,UAAU,CAAC,CAAC;QACzE,MAAM,MAAM,GACV,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ;YAChC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC;YAC7B,KAAK,CAAC,MAAM,GAAG,CAAC;YACd,CAAC,CAAC,KAAK,CAAC,MAAM;YACd,CAAC,CAAC,WAAW,CAAC;QAElB,WAAW,IAAI,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC;QACpC,WAAW,IAAI,MAAM,CAAC;IACxB,CAAC;IAED,IAAI,WAAW,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAChC,OAAO,WAAW,GAAG,WAAW,CAAC;AACnC,CAAC;AAED;;;GAGG;AACH,OAAO,EACL,cAAc,EACd,SAAS,EACT,gBAAgB,GACjB,MAAM,2BAA2B,CAAC"} \ No newline at end of file +{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/services/marketRate/types.ts"],"names":[],"mappings":"AA6FA;;;GAGG;AACH,MAAM,CAAN,IAAY,mBAIX;AAJD,WAAY,mBAAmB;IAC7B,wCAAiB,CAAA;IACjB,oCAAa,CAAA;IACb,8CAAuB,CAAA;AACzB,CAAC,EAJW,mBAAmB,KAAnB,mBAAmB,QAI9B;AAkBD;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,MAAgB;IAC9C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAElC,MAAM,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAE7C,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAChC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QAC5B,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YAC7C,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;QACD,OAAO,IAAI,IAAI,IAAI,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAgB;IAC/C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAElC,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC;IAC1D,OAAO,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC;AAC7B,CAAC;AAQD,MAAM,oBAAoB,GAAqC;IAC7D,OAAO,EAAE,CAAC;IACV,QAAQ,EAAE,CAAC;IACX,GAAG,EAAE,CAAC;CACP,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAA4B;IACnE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAElC,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,WAAW,GAAG,oBAAoB,CAAC,KAAK,CAAC,UAAU,IAAI,UAAU,CAAC,CAAC;QACzE,MAAM,MAAM,GACV,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ;YAChC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC;YAC7B,KAAK,CAAC,MAAM,GAAG,CAAC;YACd,CAAC,CAAC,KAAK,CAAC,MAAM;YACd,CAAC,CAAC,WAAW,CAAC;QAElB,WAAW,IAAI,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC;QACpC,WAAW,IAAI,MAAM,CAAC;IACxB,CAAC;IAED,IAAI,WAAW,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAChC,OAAO,WAAW,GAAG,WAAW,CAAC;AACnC,CAAC;AAED;;;GAGG;AACH,OAAO,EACL,cAAc,EACd,SAAS,EACT,gBAAgB,GACjB,MAAM,2BAA2B,CAAC"} \ No newline at end of file diff --git a/dist/services/multiSigService.d.ts b/dist/services/multiSigService.d.ts index 2b605e5a..931c95f8 100644 --- a/dist/services/multiSigService.d.ts +++ b/dist/services/multiSigService.d.ts @@ -15,75 +15,44 @@ export interface SignaturePayload { signerPublicKey: string; } export declare class MultiSigService { - private readonly localSignerPublicKey; - private readonly localSignerSecret; + private localSignerPublicKey; private readonly signerName; private readonly SIGNATURE_EXPIRY_MS; private readonly REQUIRED_SIGNATURES; constructor(); - /** - * Create a multi-sig price update request. - * This initiates the process where the price needs to be signed by multiple servers. - */ + private initializeSigner; createMultiSigRequest(priceReviewId: number, currency: string, rate: number, source: string, memoId: string): Promise; - /** - * Sign a multi-sig price update locally. - * This creates a signature from the current server instance and records it. - */ signMultiSigPrice(multiSigPriceId: number): Promise<{ signature: string; signerPublicKey: string; }>; - /** - * Request a signature from a remote server. - * Sends an HTTP request to a peer server to sign the price update. - */ requestRemoteSignature(multiSigPriceId: number, remoteServerUrl: string): Promise<{ success: boolean; error?: string; }>; - /** - * Get a pending multi-sig price by ID. - * Returns the price details and current signature status. - */ getMultiSigPrice(multiSigPriceId: number): Promise; - /** - * Get all pending multi-sig prices. - * Useful for monitoring and checking expiration. - */ getPendingMultiSigPrices(): Promise; - /** - * Clean up expired multi-sig prices. - * Should be called periodically by a background job. - */ cleanupExpiredRequests(): Promise; - /** - * Get all signatures for a multi-sig price. - * Returns the signatures needed for submitting to Stellar. - */ getSignatures(multiSigPriceId: number): Promise; /** * Mark a multi-sig price as submitted to Stellar. - * Records the transaction hash and memo ID. - */ - recordSubmission(multiSigPriceId: number, memoId: string, stellarTxHash: string): Promise; - /** - * Get this server's signer identity. + * ── INSTRUMENTED ── + * This is the closest point to an actual Stellar submission in this service. + * We record success, duration, and fee here because by the time + * recordSubmission() is called, the tx has already landed on-chain. */ + recordSubmission(multiSigPriceId: number, memoId: string, stellarTxHash: string, asset?: string, // optional — caller can pass e.g. "XLM/USD" + feeStroops?: number): Promise; getLocalSignerInfo(): { publicKey: string; name: string; }; - /** - * Mark a multi-sig price as approved (all signatures collected). - * This happens automatically when all required signatures are collected. - */ private approveMultiSigPrice; - /** - * Create a deterministic message for signing. - * Must be consistent across all servers to ensure valid multi-sig. - */ private createSignatureMessage; + /** Look up the currency label for a multiSigPrice row. */ + private resolveCurrency; + /** Map errors to stable Prometheus label values. */ + private classifyError; } export declare const multiSigService: MultiSigService; //# sourceMappingURL=multiSigService.d.ts.map \ No newline at end of file diff --git a/dist/services/multiSigService.d.ts.map b/dist/services/multiSigService.d.ts.map index 76acd794..07899231 100644 --- a/dist/services/multiSigService.d.ts.map +++ b/dist/services/multiSigService.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"multiSigService.d.ts","sourceRoot":"","sources":["../../src/services/multiSigService.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,gBAAgB;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;CACzB;AAgBD,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAkB;IACtD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;;IAyB7C;;;OAGG;IACG,qBAAqB,CACzB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,gBAAgB,CAAC;IA+B5B;;;OAGG;IACG,iBAAiB,CACrB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAE,CAAC;IA2E1D;;;OAGG;IACG,sBAAsB,CAC1B,eAAe,EAAE,MAAM,EACvB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAoGhD;;;OAGG;IACG,gBAAgB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAgB7D;;;OAGG;IACG,wBAAwB,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAgBhD;;;OAGG;IACG,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC;IAoB/C;;;OAGG;IACG,aAAa,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAM5D;;;OAGG;IACG,gBAAgB,CACpB,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC;IAehB;;OAEG;IACH,kBAAkB,IAAI;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;KACd;IAOD;;;OAGG;YACW,oBAAoB;IAalC;;;OAGG;IACH,OAAO,CAAC,sBAAsB;CAO/B;AAGD,eAAO,MAAM,eAAe,iBAAwB,CAAC"} \ No newline at end of file +{"version":3,"file":"multiSigService.d.ts","sourceRoot":"","sources":["../../src/services/multiSigService.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,gBAAgB;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;CACzB;AAgBD,qBAAa,eAAe;IAC1B,OAAO,CAAC,oBAAoB,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAkB;IACtD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;;YAiB/B,gBAAgB;IAIxB,qBAAqB,CACzB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,gBAAgB,CAAC;IA+BtB,iBAAiB,CACrB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAE,CAAC;IAsEpD,sBAAsB,CAC1B,eAAe,EAAE,MAAM,EACvB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IA+F1C,gBAAgB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAgBvD,wBAAwB,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAgB1C,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC;IAkBzC,aAAa,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAM5D;;;;;;OAMG;IACG,gBAAgB,CACpB,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,KAAK,CAAC,EAAE,MAAM,EAAQ,4CAA4C;IAClE,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC;IAuChB,kBAAkB,IAAI;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;YAO3C,oBAAoB;IAWlC,OAAO,CAAC,sBAAsB;IAQ9B,0DAA0D;YAC5C,eAAe;IAQ7B,oDAAoD;IACpD,OAAO,CAAC,aAAa;CAUtB;AAED,eAAO,MAAM,eAAe,iBAAwB,CAAC"} \ No newline at end of file diff --git a/dist/services/multiSigService.js b/dist/services/multiSigService.js index c44a900c..ef41cdb7 100644 --- a/dist/services/multiSigService.js +++ b/dist/services/multiSigService.js @@ -1,33 +1,27 @@ import prisma from "../lib/prisma"; -import { Keypair } from "@stellar/stellar-sdk"; +import { signer } from "../signer"; import dotenv from "dotenv"; import axios from "axios"; import { assertSigningAllowed } from "../state/appState"; +import { successfulSubmissions, failedSubmissions, gasUsagePerAsset, submissionDuration, } from "../metrics"; dotenv.config(); export class MultiSigService { - localSignerPublicKey; - localSignerSecret; + localSignerPublicKey = ""; signerName; SIGNATURE_EXPIRY_MS = 60 * 60 * 1000; REQUIRED_SIGNATURES; constructor() { - const secret = process.env.ORACLE_SECRET_KEY || process.env.SOROBAN_ADMIN_SECRET; - if (!secret) { - throw new Error("ORACLE_SECRET_KEY or SOROBAN_ADMIN_SECRET not found in environment variables"); - } - this.localSignerSecret = secret; - this.localSignerPublicKey = Keypair.fromSecret(secret).publicKey(); this.signerName = process.env.ORACLE_SIGNER_NAME || "oracle-server"; const requiredSignatures = Number.parseInt(process.env.MULTI_SIG_REQUIRED_COUNT || "2", 10); this.REQUIRED_SIGNATURES = Number.isFinite(requiredSignatures) && requiredSignatures > 0 ? requiredSignatures : 2; + this.initializeSigner(); + } + async initializeSigner() { + this.localSignerPublicKey = await signer.getPublicKey(); } - /** - * Create a multi-sig price update request. - * This initiates the process where the price needs to be signed by multiple servers. - */ async createMultiSigRequest(priceReviewId, currency, rate, source, memoId) { const expiresAt = new Date(Date.now() + this.SIGNATURE_EXPIRY_MS); const created = await prisma.multiSigPrice.create({ @@ -53,10 +47,6 @@ export class MultiSigService { requiredSignatures: this.REQUIRED_SIGNATURES, }; } - /** - * Sign a multi-sig price update locally. - * This creates a signature from the current server instance and records it. - */ async signMultiSigPrice(multiSigPriceId) { const multiSigPrice = await prisma.multiSigPrice.findUnique({ where: { id: multiSigPriceId }, @@ -76,9 +66,7 @@ export class MultiSigService { } await assertSigningAllowed(); const signatureMessage = this.createSignatureMessage(multiSigPrice.currency, multiSigPrice.rate.toString(), multiSigPrice.source); - const signature = Keypair.fromSecret(this.localSignerSecret) - .sign(Buffer.from(signatureMessage, "utf-8")) - .toString("hex"); + const signature = (await signer.sign(Buffer.from(signatureMessage, "utf-8"))).toString("hex"); let createdSignature = true; try { await prisma.multiSigSignature.create({ @@ -99,11 +87,7 @@ export class MultiSigService { if (createdSignature) { const updated = await prisma.multiSigPrice.update({ where: { id: multiSigPriceId }, - data: { - collectedSignatures: { - increment: 1, - }, - }, + data: { collectedSignatures: { increment: 1 } }, }); console.info(`[MultiSig] Added signature ${updated.collectedSignatures}/${updated.requiredSignatures} for MultiSigPrice ${multiSigPriceId}`); if (updated.collectedSignatures >= updated.requiredSignatures) { @@ -112,10 +96,6 @@ export class MultiSigService { } return { signature, signerPublicKey: this.localSignerPublicKey }; } - /** - * Request a signature from a remote server. - * Sends an HTTP request to a peer server to sign the price update. - */ async requestRemoteSignature(multiSigPriceId, remoteServerUrl) { try { await assertSigningAllowed(); @@ -141,7 +121,7 @@ export class MultiSigService { "Content-Type": "application/json", Authorization: `Bearer ${process.env.MULTI_SIG_AUTH_TOKEN || ""}`, }, - timeout: 10000, // 10 second timeout + timeout: 10000, }); const result = response.data; if (result.success === false) { @@ -177,11 +157,7 @@ export class MultiSigService { if (createdSignature) { const updated = await prisma.multiSigPrice.update({ where: { id: multiSigPriceId }, - data: { - collectedSignatures: { - increment: 1, - }, - }, + data: { collectedSignatures: { increment: 1 } }, }); console.info(`[MultiSig] Added remote signature ${updated.collectedSignatures}/${updated.requiredSignatures} for MultiSigPrice ${multiSigPriceId}`); if (updated.collectedSignatures >= updated.requiredSignatures) { @@ -195,10 +171,6 @@ export class MultiSigService { return { success: false, error: String(error) }; } } - /** - * Get a pending multi-sig price by ID. - * Returns the price details and current signature status. - */ async getMultiSigPrice(multiSigPriceId) { return prisma.multiSigPrice.findUnique({ where: { id: multiSigPriceId }, @@ -214,10 +186,6 @@ export class MultiSigService { }, }); } - /** - * Get all pending multi-sig prices. - * Useful for monitoring and checking expiration. - */ async getPendingMultiSigPrices() { return prisma.multiSigPrice.findMany({ where: { status: "PENDING" }, @@ -233,29 +201,19 @@ export class MultiSigService { orderBy: { requestedAt: "desc" }, }); } - /** - * Clean up expired multi-sig prices. - * Should be called periodically by a background job. - */ async cleanupExpiredRequests() { const result = await prisma.multiSigPrice.updateMany({ where: { status: "PENDING", expiresAt: { lt: new Date() }, }, - data: { - status: "EXPIRED", - }, + data: { status: "EXPIRED" }, }); if (result.count > 0) { console.warn(`[MultiSig] Expired ${result.count} multi-sig price requests`); } return result.count; } - /** - * Get all signatures for a multi-sig price. - * Returns the signatures needed for submitting to Stellar. - */ async getSignatures(multiSigPriceId) { return prisma.multiSigSignature.findMany({ where: { multiSigPriceId }, @@ -263,49 +221,82 @@ export class MultiSigService { } /** * Mark a multi-sig price as submitted to Stellar. - * Records the transaction hash and memo ID. + * ── INSTRUMENTED ── + * This is the closest point to an actual Stellar submission in this service. + * We record success, duration, and fee here because by the time + * recordSubmission() is called, the tx has already landed on-chain. */ - async recordSubmission(multiSigPriceId, memoId, stellarTxHash) { - await prisma.multiSigPrice.update({ - where: { id: multiSigPriceId }, - data: { - memoId, - stellarTxHash, - submittedAt: new Date(), - }, - }); - console.info(`[MultiSig] MultiSigPrice ${multiSigPriceId} submitted to Stellar - TxHash: ${stellarTxHash}`); + async recordSubmission(multiSigPriceId, memoId, stellarTxHash, asset, // optional — caller can pass e.g. "XLM/USD" + feeStroops) { + // Resolve the asset label from DB if not supplied by caller + const label = asset ?? (await this.resolveCurrency(multiSigPriceId)); + // ── Stop the duration timer (started externally or approximated here) ── + const endTimer = submissionDuration.startTimer({ asset: label }); + try { + await prisma.multiSigPrice.update({ + where: { id: multiSigPriceId }, + data: { + memoId, + stellarTxHash, + submittedAt: new Date(), + }, + }); + // ── Record success ── + successfulSubmissions.inc({ asset: label }); + // ── Record fee if provided ── + if (feeStroops !== undefined && feeStroops > 0) { + gasUsagePerAsset.observe({ asset: label }, feeStroops); + } + endTimer(); + console.info(`[MultiSig] MultiSigPrice ${multiSigPriceId} submitted to Stellar - TxHash: ${stellarTxHash}`); + } + catch (error) { + // ── Record failure ── + const reason = this.classifyError(error); + failedSubmissions.inc({ asset: label, reason }); + endTimer(); + throw error; + } } - /** - * Get this server's signer identity. - */ getLocalSignerInfo() { return { publicKey: this.localSignerPublicKey, name: this.signerName, }; } - /** - * Mark a multi-sig price as approved (all signatures collected). - * This happens automatically when all required signatures are collected. - */ async approveMultiSigPrice(multiSigPriceId) { await prisma.multiSigPrice.update({ where: { id: multiSigPriceId }, - data: { - status: "APPROVED", - }, + data: { status: "APPROVED" }, }); console.info(`[MultiSig] MultiSigPrice ${multiSigPriceId} is now APPROVED (all signatures collected)`); } - /** - * Create a deterministic message for signing. - * Must be consistent across all servers to ensure valid multi-sig. - */ createSignatureMessage(currency, rate, source) { return `SF-PRICE-${currency}-${rate}-${source}`; } + /** Look up the currency label for a multiSigPrice row. */ + async resolveCurrency(multiSigPriceId) { + const row = await prisma.multiSigPrice.findUnique({ + where: { id: multiSigPriceId }, + select: { currency: true }, + }); + return row?.currency ?? "unknown"; + } + /** Map errors to stable Prometheus label values. */ + classifyError(error) { + if (error instanceof Error) { + const msg = error.message.toLowerCase(); + if (msg.includes("timeout")) + return "timeout"; + if (msg.includes("validation")) + return "validation"; + if (msg.includes("expired")) + return "expired"; + if (msg.includes("not found")) + return "not_found"; + } + return "unknown"; + } } -// Export singleton instance export const multiSigService = new MultiSigService(); //# sourceMappingURL=multiSigService.js.map \ No newline at end of file diff --git a/dist/services/multiSigService.js.map b/dist/services/multiSigService.js.map index ee657469..28a0051d 100644 --- a/dist/services/multiSigService.js.map +++ b/dist/services/multiSigService.js.map @@ -1 +1 @@ -{"version":3,"file":"multiSigService.js","sourceRoot":"","sources":["../../src/services/multiSigService.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,eAAe,CAAC;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzD,MAAM,CAAC,MAAM,EAAE,CAAC;AAkChB,MAAM,OAAO,eAAe;IACT,oBAAoB,CAAS;IAC7B,iBAAiB,CAAS;IAC1B,UAAU,CAAS;IACnB,mBAAmB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IACrC,mBAAmB,CAAS;IAE7C;QACE,MAAM,MAAM,GACV,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;QACpE,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CACb,8EAA8E,CAC/E,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,iBAAiB,GAAG,MAAM,CAAC;QAChC,IAAI,CAAC,oBAAoB,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC;QACnE,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,eAAe,CAAC;QAEpE,MAAM,kBAAkB,GAAG,MAAM,CAAC,QAAQ,CACxC,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,GAAG,EAC3C,EAAE,CACH,CAAC;QACF,IAAI,CAAC,mBAAmB;YACtB,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,kBAAkB,GAAG,CAAC;gBAC3D,CAAC,CAAC,kBAAkB;gBACpB,CAAC,CAAC,CAAC,CAAC;IACV,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,qBAAqB,CACzB,aAAqB,EACrB,QAAgB,EAChB,IAAY,EACZ,MAAc,EACd,MAAc;QAEd,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAElE,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC;YAChD,IAAI,EAAE;gBACJ,aAAa;gBACb,QAAQ;gBACR,IAAI;gBACJ,MAAM;gBACN,MAAM;gBACN,MAAM,EAAE,SAAS;gBACjB,kBAAkB,EAAE,IAAI,CAAC,mBAAmB;gBAC5C,mBAAmB,EAAE,CAAC;gBACtB,SAAS;aACV;SACF,CAAC,CAAC;QAEH,OAAO,CAAC,IAAI,CACV,wCAAwC,OAAO,CAAC,EAAE,QAAQ,QAAQ,SAAS,IAAI,EAAE,CAClF,CAAC;QAEF,OAAO;YACL,eAAe,EAAE,OAAO,CAAC,EAAE;YAC3B,QAAQ;YACR,IAAI;YACJ,MAAM;YACN,MAAM;YACN,kBAAkB,EAAE,IAAI,CAAC,mBAAmB;SAC7C,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,iBAAiB,CACrB,eAAuB;QAEvB,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC;YAC1D,KAAK,EAAE,EAAE,EAAE,EAAE,eAAe,EAAE;SAC/B,CAAC,CAAC;QAEH,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,iBAAiB,eAAe,YAAY,CAAC,CAAC;QAChE,CAAC;QAED,IAAI,aAAa,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CACb,6BAA6B,eAAe,gBAAgB,aAAa,CAAC,MAAM,EAAE,CACnF,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,IAAI,EAAE,GAAG,aAAa,CAAC,SAAS,EAAE,CAAC;YACzC,MAAM,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC;gBAChC,KAAK,EAAE,EAAE,EAAE,EAAE,eAAe,EAAE;gBAC9B,IAAI,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE;aAC5B,CAAC,CAAC;YACH,MAAM,IAAI,KAAK,CAAC,iBAAiB,eAAe,cAAc,CAAC,CAAC;QAClE,CAAC;QAED,MAAM,oBAAoB,EAAE,CAAC;QAE7B,MAAM,gBAAgB,GAAG,IAAI,CAAC,sBAAsB,CAClD,aAAa,CAAC,QAAQ,EACtB,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,EAC7B,aAAa,CAAC,MAAM,CACrB,CAAC;QACF,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,iBAAiB,CAAC;aACzD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;aAC5C,QAAQ,CAAC,KAAK,CAAC,CAAC;QAEnB,IAAI,gBAAgB,GAAG,IAAI,CAAC;QAE5B,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC;gBACpC,IAAI,EAAE;oBACJ,eAAe;oBACf,eAAe,EAAE,IAAI,CAAC,oBAAoB;oBAC1C,UAAU,EAAE,IAAI,CAAC,UAAU;oBAC3B,SAAS;iBACV;aACF,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,IAAI,KAAK,EAAE,IAAI,KAAK,OAAO,EAAE,CAAC;gBAC5B,MAAM,KAAK,CAAC;YACd,CAAC;YAED,gBAAgB,GAAG,KAAK,CAAC;QAC3B,CAAC;QAED,IAAI,gBAAgB,EAAE,CAAC;YACrB,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC;gBAChD,KAAK,EAAE,EAAE,EAAE,EAAE,eAAe,EAAE;gBAC9B,IAAI,EAAE;oBACJ,mBAAmB,EAAE;wBACnB,SAAS,EAAE,CAAC;qBACb;iBACF;aACF,CAAC,CAAC;YAEH,OAAO,CAAC,IAAI,CACV,8BAA8B,OAAO,CAAC,mBAAmB,IAAI,OAAO,CAAC,kBAAkB,sBAAsB,eAAe,EAAE,CAC/H,CAAC;YAEF,IAAI,OAAO,CAAC,mBAAmB,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;gBAC9D,MAAM,IAAI,CAAC,oBAAoB,CAAC,eAAe,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;QAED,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,IAAI,CAAC,oBAAoB,EAAE,CAAC;IACnE,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,sBAAsB,CAC1B,eAAuB,EACvB,eAAuB;QAEvB,IAAI,CAAC;YACH,MAAM,oBAAoB,EAAE,CAAC;YAE7B,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC;gBAC1D,KAAK,EAAE,EAAE,EAAE,EAAE,eAAe,EAAE;aAC/B,CAAC,CAAC;YAEH,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnB,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,iBAAiB,eAAe,YAAY;iBACpD,CAAC;YACJ,CAAC;YAED,MAAM,OAAO,GAAqB;gBAChC,eAAe;gBACf,QAAQ,EAAE,aAAa,CAAC,QAAQ;gBAChC,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE;gBACnC,MAAM,EAAE,aAAa,CAAC,MAAM;gBAC5B,MAAM,EAAE,aAAa,CAAC,MAAM,IAAI,EAAE;gBAClC,eAAe,EAAE,IAAI,CAAC,oBAAoB;aAC3C,CAAC;YAEF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAC/B,GAAG,eAAe,4BAA4B,EAC9C,OAAO,EACP;gBACE,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,aAAa,EAAE,UAAU,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,EAAE,EAAE;iBAClE;gBACD,OAAO,EAAE,KAAK,EAAE,oBAAoB;aACrC,CACF,CAAC;YAEF,MAAM,MAAM,GAAG,QAAQ,CAAC,IAA+B,CAAC;YACxD,IAAI,MAAM,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;gBAC7B,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,4CAA4C;iBACpE,CAAC;YACJ,CAAC;YAED,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC;YAC5C,IAAI,CAAC,aAAa,CAAC,SAAS,IAAI,CAAC,aAAa,CAAC,eAAe,EAAE,CAAC;gBAC/D,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,6CAA6C;iBACrD,CAAC;YACJ,CAAC;YAED,IAAI,gBAAgB,GAAG,IAAI,CAAC;YAE5B,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC;oBACpC,IAAI,EAAE;wBACJ,eAAe;wBACf,eAAe,EAAE,aAAa,CAAC,eAAe;wBAC9C,UAAU,EAAE,aAAa,CAAC,UAAU,IAAI,eAAe;wBACvD,SAAS,EAAE,aAAa,CAAC,SAAS;qBACnC;iBACF,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBACpB,IAAI,KAAK,EAAE,IAAI,KAAK,OAAO,EAAE,CAAC;oBAC5B,MAAM,KAAK,CAAC;gBACd,CAAC;gBAED,gBAAgB,GAAG,KAAK,CAAC;YAC3B,CAAC;YAED,IAAI,gBAAgB,EAAE,CAAC;gBACrB,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC;oBAChD,KAAK,EAAE,EAAE,EAAE,EAAE,eAAe,EAAE;oBAC9B,IAAI,EAAE;wBACJ,mBAAmB,EAAE;4BACnB,SAAS,EAAE,CAAC;yBACb;qBACF;iBACF,CAAC,CAAC;gBAEH,OAAO,CAAC,IAAI,CACV,qCAAqC,OAAO,CAAC,mBAAmB,IAAI,OAAO,CAAC,kBAAkB,sBAAsB,eAAe,EAAE,CACtI,CAAC;gBAEF,IAAI,OAAO,CAAC,mBAAmB,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;oBAC9D,MAAM,IAAI,CAAC,oBAAoB,CAAC,eAAe,CAAC,CAAC;gBACnD,CAAC;YACH,CAAC;YAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CACX,+CAA+C,eAAe,GAAG,EACjE,KAAK,CACN,CAAC;YACF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,gBAAgB,CAAC,eAAuB;QAC5C,OAAO,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC;YACrC,KAAK,EAAE,EAAE,EAAE,EAAE,eAAe,EAAE;YAC9B,OAAO,EAAE;gBACP,kBAAkB,EAAE;oBAClB,MAAM,EAAE;wBACN,eAAe,EAAE,IAAI;wBACrB,UAAU,EAAE,IAAI;wBAChB,SAAS,EAAE,IAAI;wBACf,QAAQ,EAAE,IAAI;qBACf;iBACF;aACF;SACF,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,wBAAwB;QAC5B,OAAO,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC;YACnC,KAAK,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE;YAC5B,OAAO,EAAE;gBACP,kBAAkB,EAAE;oBAClB,MAAM,EAAE;wBACN,eAAe,EAAE,IAAI;wBACrB,UAAU,EAAE,IAAI;wBAChB,QAAQ,EAAE,IAAI;qBACf;iBACF;aACF;YACD,OAAO,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE;SACjC,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,sBAAsB;QAC1B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC;YACnD,KAAK,EAAE;gBACL,MAAM,EAAE,SAAS;gBACjB,SAAS,EAAE,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE,EAAE;aAC9B;YACD,IAAI,EAAE;gBACJ,MAAM,EAAE,SAAS;aAClB;SACF,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,IAAI,CACV,sBAAsB,MAAM,CAAC,KAAK,2BAA2B,CAC9D,CAAC;QACJ,CAAC;QAED,OAAO,MAAM,CAAC,KAAK,CAAC;IACtB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,aAAa,CAAC,eAAuB;QACzC,OAAO,MAAM,CAAC,iBAAiB,CAAC,QAAQ,CAAC;YACvC,KAAK,EAAE,EAAE,eAAe,EAAE;SAC3B,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,gBAAgB,CACpB,eAAuB,EACvB,MAAc,EACd,aAAqB;QAErB,MAAM,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC;YAChC,KAAK,EAAE,EAAE,EAAE,EAAE,eAAe,EAAE;YAC9B,IAAI,EAAE;gBACJ,MAAM;gBACN,aAAa;gBACb,WAAW,EAAE,IAAI,IAAI,EAAE;aACxB;SACF,CAAC,CAAC;QAEH,OAAO,CAAC,IAAI,CACV,4BAA4B,eAAe,mCAAmC,aAAa,EAAE,CAC9F,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,kBAAkB;QAIhB,OAAO;YACL,SAAS,EAAE,IAAI,CAAC,oBAAoB;YACpC,IAAI,EAAE,IAAI,CAAC,UAAU;SACtB,CAAC;IACJ,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,oBAAoB,CAAC,eAAuB;QACxD,MAAM,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC;YAChC,KAAK,EAAE,EAAE,EAAE,EAAE,eAAe,EAAE;YAC9B,IAAI,EAAE;gBACJ,MAAM,EAAE,UAAU;aACnB;SACF,CAAC,CAAC;QAEH,OAAO,CAAC,IAAI,CACV,4BAA4B,eAAe,6CAA6C,CACzF,CAAC;IACJ,CAAC;IAED;;;OAGG;IACK,sBAAsB,CAC5B,QAAgB,EAChB,IAAY,EACZ,MAAc;QAEd,OAAO,YAAY,QAAQ,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;IAClD,CAAC;CACF;AAED,4BAA4B;AAC5B,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC"} \ No newline at end of file +{"version":3,"file":"multiSigService.js","sourceRoot":"","sources":["../../src/services/multiSigService.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/sorobanEventListener.d.ts.map b/dist/services/sorobanEventListener.d.ts.map index 4a62f5b9..63761a81 100644 --- a/dist/services/sorobanEventListener.d.ts.map +++ b/dist/services/sorobanEventListener.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"sorobanEventListener.d.ts","sourceRoot":"","sources":["../../src/services/sorobanEventListener.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,IAAI,CAAC;CACnB;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,mBAAmB,CAAa;IACxC,OAAO,CAAC,SAAS,CAA+C;gBAEpD,cAAc,GAAE,MAAc;IAiBpC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiC5B,IAAI,IAAI,IAAI;IASZ,OAAO,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI;YAetB,gBAAgB;IAwD9B,OAAO,CAAC,aAAa;YAOP,eAAe;YA2Df,mBAAmB;IAgCjC,OAAO,CAAC,gBAAgB;IAgBlB,uBAAuB,CAC3B,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAoB3B,wBAAwB,CAC5B,QAAQ,EAAE,MAAM,EAChB,KAAK,GAAE,MAAY,GAClB,OAAO,CAAC,cAAc,EAAE,CAAC;IAiB5B,QAAQ,IAAI,OAAO;IAInB,kBAAkB,IAAI,MAAM;CAG7B"} \ No newline at end of file +{"version":3,"file":"sorobanEventListener.d.ts","sourceRoot":"","sources":["../../src/services/sorobanEventListener.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,IAAI,CAAC;CACnB;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,mBAAmB,CAAa;IACxC,OAAO,CAAC,SAAS,CAA+C;gBAEpD,cAAc,GAAE,MAAc;IASpC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAmC5B,IAAI,IAAI,IAAI;IASZ,OAAO,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI;YAetB,gBAAgB;IAwD9B,OAAO,CAAC,aAAa;YAOP,eAAe;YA2Df,mBAAmB;IAgCjC,OAAO,CAAC,gBAAgB;IAgBlB,uBAAuB,CAC3B,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAoB3B,wBAAwB,CAC5B,QAAQ,EAAE,MAAM,EAChB,KAAK,GAAE,MAAY,GAClB,OAAO,CAAC,cAAc,EAAE,CAAC;IAiB5B,QAAQ,IAAI,OAAO;IAInB,kBAAkB,IAAI,MAAM;CAG7B"} \ No newline at end of file diff --git a/dist/services/sorobanEventListener.js b/dist/services/sorobanEventListener.js index 89b82313..2704e191 100644 --- a/dist/services/sorobanEventListener.js +++ b/dist/services/sorobanEventListener.js @@ -1,8 +1,8 @@ -import { Keypair } from "@stellar/stellar-sdk"; import prisma from "../lib/prisma"; import { broadcastToSessions } from "../lib/socket"; import stellarProvider from "../lib/stellarProvider"; import dotenv from "dotenv"; +import { signer } from "../signer"; dotenv.config(); export class SorobanEventListener { server; @@ -12,11 +12,7 @@ export class SorobanEventListener { lastProcessedLedger = 0; pollTimer = null; constructor(pollIntervalMs = 15000) { - const secret = process.env.ORACLE_SECRET_KEY || process.env.SOROBAN_ADMIN_SECRET; - if (!secret) { - throw new Error("ORACLE_SECRET_KEY or SOROBAN_ADMIN_SECRET not found in environment variables"); - } - this.oraclePublicKey = Keypair.fromSecret(secret).publicKey(); + this.oraclePublicKey = ""; // Initialized in start() this.pollIntervalMs = pollIntervalMs; // Use the shared StellarProvider so failover state is shared across all // services rather than each managing its own Horizon URL. @@ -28,6 +24,7 @@ export class SorobanEventListener { return; } this.isRunning = true; + this.oraclePublicKey = await signer.getPublicKey(); console.log(`[EventListener] Starting listener for account ${this.oraclePublicKey}`); // Initialize last processed ledger from the most recent on-chain record const lastRecord = await prisma.onChainPrice.findFirst({ diff --git a/dist/services/sorobanEventListener.js.map b/dist/services/sorobanEventListener.js.map index 2542706f..58ee3360 100644 --- a/dist/services/sorobanEventListener.js.map +++ b/dist/services/sorobanEventListener.js.map @@ -1 +1 @@ -{"version":3,"file":"sorobanEventListener.js","sourceRoot":"","sources":["../../src/services/sorobanEventListener.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"sorobanEventListener.js","sourceRoot":"","sources":["../../src/services/sorobanEventListener.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/stellarService.d.ts b/dist/services/stellarService.d.ts index 29e6fd93..06f21aed 100644 --- a/dist/services/stellarService.d.ts +++ b/dist/services/stellarService.d.ts @@ -1,82 +1,54 @@ -import { Transaction, Horizon } from "@stellar/stellar-sdk"; +import { Transaction, Horizon, Account } from "@stellar/stellar-sdk"; export declare class StellarService { private server; private network; private readonly MAX_RETRIES; private readonly FEE_INCREMENT_PERCENTAGE; private readonly RETRY_DELAY_MS; + private readonly TRANSACTION_TIME_BOUND_SECONDS; + private readonly pendingTimeBoundTransactions; constructor(); /** - * Returns a Keypair derived from the currently active secret key. - * Called at sign time so key rotations are reflected immediately. + * Returns the Stellar public key from the signer. */ - private getKeypair; + private getPublicKey; /** * Fetches the recommended transaction fee from Horizon fee_stats. - * Uses p50 (median) of recent fees to avoid overpaying while ensuring inclusion. - * @returns Recommended fee in stroops as a string (required by TransactionBuilder) */ getRecommendedFee(): Promise; /** - * Submit a price update to the Stellar network with a unique memo ID. - * Leverages submitTransactionWithRetries for automatic fee bumping if stuck. - * @param currency - The currency code (e.g., "NGN", "KES") - * @param price - The current price/rate - * @param memoId - Unique ID for auditing + * Submit a price update to the Stellar network. */ submitPriceUpdate(currency: string, price: number, memoId: string): Promise; /** - * Submit multiple price updates to the Stellar network in a single bundle transaction. - * Leverages submitTransactionWithRetries for automatic fee bumping if stuck. - * @param updates - Array of price updates { currency, price } - * @param memoId - Unique ID for auditing + * Submit multiple price updates in a single bundle. */ submitBatchedPriceUpdates(updates: Array<{ currency: string; price: number; }>, memoId: string): Promise; /** - * Submit a multi-signed price update to the Stellar network. - * Accepts signatures from multiple oracle servers. - * @param currency - The currency code (e.g., "NGN", "KES") - * @param price - The current price/rate - * @param memoId - Unique ID for auditing - * @param signatures - Array of signatures from different signers + * Submit a multi-signed price update. */ submitMultiSignedPriceUpdate(currency: string, price: number, memoId: string, signatures: Array<{ signerPublicKey: string; signature: string; }>): Promise; /** - * Generic method to submit a transaction with retries and automatic fee bumping. - * Optimizes interaction with the network (including Soroban contracts) by handling congestion. - * @param builderFn - Function that builds a new transaction for each attempt - * @param maxRetries - Max number of retries - * @param baseFee - The starting fee in stroops + * Generic method to submit a transaction with retries. */ - submitTransactionWithRetries(builderFn: (sourceAccount: Horizon.AccountResponse, currentFee: number) => Transaction, maxRetries: number | undefined, baseFee: number): Promise; + submitTransactionWithRetries(builderFn: (sourceAccount: Account | Horizon.AccountResponse, currentFee: number) => Transaction, maxRetries: number | undefined, baseFee: number): Promise; /** - * Submit a multi-signed transaction to the Stellar network. - * Adds multiple signatures to the transaction before submission. - * @param builderFn - Function that builds the transaction - * @param signatures - Array of signatures with signer public keys - * @param maxRetries - Max number of retries - * @param baseFee - The starting fee in stroops + * Submit a multi-signed transaction with retries. */ private submitMultiSignedTransaction; - /** - * Get the network passphrase for the current network. - * Ensures proper network identification for multi-sig operations. - */ - private getNetworkPassphrase; - /** - * Determines if a transaction error indicates it is "stuck" or needs a fee bump. - */ + private assertStrictTimeBounds; + private submitWithTimeoutListener; + private registerPendingTimeBoundTransaction; + private clearPendingTimeBoundTransaction; private isStuckError; - /** - * Generate a unique ID for the transaction memo - * Format: SF-- - */ + private shouldRecycleImmediately; + private isLocalTimeoutError; generateMemoId(currency: string): string; } //# sourceMappingURL=stellarService.d.ts.map \ No newline at end of file diff --git a/dist/services/stellarService.d.ts.map b/dist/services/stellarService.d.ts.map index 05fa2178..8228a0c0 100644 --- a/dist/services/stellarService.d.ts.map +++ b/dist/services/stellarService.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"stellarService.d.ts","sourceRoot":"","sources":["../../src/services/stellarService.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,WAAW,EAIX,OAAO,EAER,MAAM,sBAAsB,CAAC;AAQ9B,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAK;IACjC,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAO;IAChD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAQ;;IAUvC;;;OAGG;IACH,OAAO,CAAC,UAAU;IAIlB;;;;OAIG;IACG,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;IAO1C;;;;;;OAMG;IACG,iBAAiB,CACrB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC;IAgClB;;;;;OAKG;IACG,yBAAyB,CAC7B,OAAO,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,EACnD,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC;IAuClB;;;;;;;OAOG;IACG,4BAA4B,CAChC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,KAAK,CAAC;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,GAChE,OAAO,CAAC,MAAM,CAAC;IAiClB;;;;;;OAMG;IACG,4BAA4B,CAChC,SAAS,EAAE,CACT,aAAa,EAAE,OAAO,CAAC,eAAe,EACtC,UAAU,EAAE,MAAM,KACf,WAAW,EAChB,UAAU,oBAAmB,EAC7B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,GAAG,CAAC;IAiDf;;;;;;;OAOG;YACW,4BAA4B;IA0F1C;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAI5B;;OAEG;IACH,OAAO,CAAC,YAAY;IAgBpB;;;OAGG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;CASzC"} \ No newline at end of file +{"version":3,"file":"stellarService.d.ts","sourceRoot":"","sources":["../../src/services/stellarService.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,WAAW,EAIX,OAAO,EAEP,OAAO,EACR,MAAM,sBAAsB,CAAC;AAgC9B,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAK;IACjC,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAO;IAChD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAQ;IACvC,OAAO,CAAC,QAAQ,CAAC,8BAA8B,CAAM;IACrD,OAAO,CAAC,QAAQ,CAAC,4BAA4B,CAGzC;;IAUJ;;OAEG;YACW,YAAY;IAI1B;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;IAM1C;;OAEG;IACG,iBAAiB,CACrB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC;IA8BlB;;OAEG;IACG,yBAAyB,CAC7B,OAAO,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,EACnD,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC;IAuClB;;OAEG;IACG,4BAA4B,CAChC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,KAAK,CAAC;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,GAChE,OAAO,CAAC,MAAM,CAAC;IA8BlB;;OAEG;IACG,4BAA4B,CAChC,SAAS,EAAE,CACT,aAAa,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,EAChD,UAAU,EAAE,MAAM,KACf,WAAW,EAChB,UAAU,oBAAmB,EAC7B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,GAAG,CAAC;IAoEf;;OAEG;YACW,4BAA4B;IA0F1C,OAAO,CAAC,sBAAsB;YAgBhB,yBAAyB;IAsCvC,OAAO,CAAC,mCAAmC;IAmB3C,OAAO,CAAC,gCAAgC;IAaxC,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,wBAAwB;IAKhC,OAAO,CAAC,mBAAmB;IAM3B,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;CAMzC"} \ No newline at end of file diff --git a/dist/services/stellarService.js b/dist/services/stellarService.js index 15d6a312..aa789f30 100644 --- a/dist/services/stellarService.js +++ b/dist/services/stellarService.js @@ -1,45 +1,51 @@ -import { Keypair, TransactionBuilder, Operation, Networks, Memo, xdr, } from "@stellar/stellar-sdk"; import dotenv from "dotenv"; +import { Keypair, TransactionBuilder, Operation, Networks, Memo, xdr, Account, } from "@stellar/stellar-sdk"; import stellarProvider from "../lib/stellarProvider"; +import { sequenceManager } from "./sequence-manager"; import { assertSigningAllowed } from "../state/appState"; -import { getSecretKey } from "./secretManager"; +import { signer } from "../signer"; dotenv.config(); +class LocalTransactionTimeoutError extends Error { + code = "LOCAL_TX_TIME_BOUND_EXPIRED"; + transactionHash; + publicKey; + constructor(transactionHash, publicKey) { + super(`Transaction ${transactionHash} exceeded local time-bound and was recycled`); + this.name = "LocalTransactionTimeoutError"; + this.transactionHash = transactionHash; + this.publicKey = publicKey; + } +} export class StellarService { server; network; MAX_RETRIES = 3; FEE_INCREMENT_PERCENTAGE = 0.5; // 50% increase each retry RETRY_DELAY_MS = 2000; // 2 seconds delay between retries + TRANSACTION_TIME_BOUND_SECONDS = 15; + pendingTimeBoundTransactions = new Map(); constructor() { this.network = process.env.STELLAR_NETWORK || "TESTNET"; - // Use the shared StellarProvider so all services benefits from the same + // Use the shared StellarProvider so all services benefit from the same // failover state rather than each managing their own Horizon URL. this.server = stellarProvider.getServer(); } /** - * Returns a Keypair derived from the currently active secret key. - * Called at sign time so key rotations are reflected immediately. + * Returns the Stellar public key from the signer. */ - getKeypair() { - return Keypair.fromSecret(getSecretKey()); + async getPublicKey() { + return signer.getPublicKey(); } /** * Fetches the recommended transaction fee from Horizon fee_stats. - * Uses p50 (median) of recent fees to avoid overpaying while ensuring inclusion. - * @returns Recommended fee in stroops as a string (required by TransactionBuilder) */ async getRecommendedFee() { const feeStats = await this.server.feeStats(); - // p50 = median fee paid in recent ledgers — safe and cost-efficient const fee = parseInt(feeStats.fee_charged.p50, 10); - return Math.max(fee, 100).toString(); // floor at Stellar's base fee (100 stroops) + return Math.max(fee, 100).toString(); } /** - * Submit a price update to the Stellar network with a unique memo ID. - * Leverages submitTransactionWithRetries for automatic fee bumping if stuck. - * @param currency - The currency code (e.g., "NGN", "KES") - * @param price - The current price/rate - * @param memoId - Unique ID for auditing + * Submit a price update to the Stellar network. */ async submitPriceUpdate(currency, price, memoId) { await assertSigningAllowed(); @@ -54,17 +60,14 @@ export class StellarService { value: price.toString(), })) .addMemo(Memo.text(memoId)) - .setTimeout(60) + .setTimeout(this.TRANSACTION_TIME_BOUND_SECONDS) .build(); }, this.MAX_RETRIES, baseFee); console.info(`✅ Price update for ${currency} confirmed. Hash: ${result.hash}`); return result.hash; } /** - * Submit multiple price updates to the Stellar network in a single bundle transaction. - * Leverages submitTransactionWithRetries for automatic fee bumping if stuck. - * @param updates - Array of price updates { currency, price } - * @param memoId - Unique ID for auditing + * Submit multiple price updates in a single bundle. */ async submitBatchedPriceUpdates(updates, memoId) { if (updates.length === 0) { @@ -83,19 +86,17 @@ export class StellarService { value: update.price.toString(), })); } - return builder.addMemo(Memo.text(memoId)).setTimeout(60).build(); + return builder + .addMemo(Memo.text(memoId)) + .setTimeout(this.TRANSACTION_TIME_BOUND_SECONDS) + .build(); }, this.MAX_RETRIES, baseFee); const currencies = updates.map((u) => u.currency).join(", "); console.info(`✅ Batched price update for [${currencies}] confirmed. Hash: ${result.hash}`); return result.hash; } /** - * Submit a multi-signed price update to the Stellar network. - * Accepts signatures from multiple oracle servers. - * @param currency - The currency code (e.g., "NGN", "KES") - * @param price - The current price/rate - * @param memoId - Unique ID for auditing - * @param signatures - Array of signatures from different signers + * Submit a multi-signed price update. */ async submitMultiSignedPriceUpdate(currency, price, memoId, signatures) { await assertSigningAllowed(); @@ -110,18 +111,14 @@ export class StellarService { value: price.toString(), })) .addMemo(Memo.text(memoId)) - .setTimeout(60) + .setTimeout(this.TRANSACTION_TIME_BOUND_SECONDS) .build(); }, signatures, this.MAX_RETRIES, baseFee); console.info(`✅ Multi-signed price update for ${currency} confirmed. Hash: ${result.hash}`); return result.hash; } /** - * Generic method to submit a transaction with retries and automatic fee bumping. - * Optimizes interaction with the network (including Soroban contracts) by handling congestion. - * @param builderFn - Function that builds a new transaction for each attempt - * @param maxRetries - Max number of retries - * @param baseFee - The starting fee in stroops + * Generic method to submit a transaction with retries. */ async submitTransactionWithRetries(builderFn, maxRetries = this.MAX_RETRIES, baseFee) { let attempt = 0; @@ -129,23 +126,38 @@ export class StellarService { try { // Always resolve the current active server — may have changed after a failover this.server = stellarProvider.getServer(); - const sourceAccount = await this.server.loadAccount(this.getKeypair().publicKey()); + // Use SequenceManager to avoid collisions and redundant loadAccount calls + const publicKey = await this.getPublicKey(); + const nextSequence = await sequenceManager.getNextSequence(publicKey); + const sourceAccount = new Account(publicKey, nextSequence); const currentFee = Math.floor(baseFee * (1 + this.FEE_INCREMENT_PERCENTAGE * attempt)); const transaction = builderFn(sourceAccount, currentFee); + this.assertStrictTimeBounds(transaction); await assertSigningAllowed(); - transaction.sign(this.getKeypair()); - await assertSigningAllowed(); - return await this.server.submitTransaction(transaction); + const txHash = transaction.hash(); + const signature = await signer.sign(txHash); + const kp = Keypair.fromPublicKey(publicKey); + transaction.signatures.push(new xdr.DecoratedSignature({ + hint: kp.signatureHint(), + signature: signature, + })); + return await this.submitWithTimeoutListener(transaction, publicKey); } catch (error) { + const resultCode = error.response?.data?.extras?.result_codes?.transaction; + if (resultCode === "tx_bad_seq" || this.isLocalTimeoutError(error)) { + console.warn("âš ī¸ SequenceManager: stale or invalid local transaction assignment detected. Invalidating sequence and retrying..."); + sequenceManager.invalidate(await this.getPublicKey()); + } attempt++; - // Report to the provider — it will switch to the next node if this is - // a 5xx / network error, so the next attempt uses a healthy node. - stellarProvider.reportFailure(error); - const isStuck = this.isStuckError(error); - if (isStuck && attempt <= maxRetries) { - console.warn(`âš ī¸ Transaction stuck or fee too low (Attempt ${attempt}). Bumping fee and retrying in ${this.RETRY_DELAY_MS}ms...`); - await new Promise((resolve) => setTimeout(resolve, this.RETRY_DELAY_MS)); + if (!this.isLocalTimeoutError(error)) { + stellarProvider.reportFailure(error); + } + if (this.isStuckError(error) && attempt <= maxRetries) { + console.warn(`âš ī¸ Transaction stuck, expired, or fee too low (Attempt ${attempt}). Recycling locally and retrying...`); + if (!this.shouldRecycleImmediately(error)) { + await new Promise((resolve) => setTimeout(resolve, this.RETRY_DELAY_MS)); + } continue; } throw error; @@ -154,38 +166,33 @@ export class StellarService { throw new Error(`Failed to submit transaction after ${maxRetries + 1} attempts`); } /** - * Submit a multi-signed transaction to the Stellar network. - * Adds multiple signatures to the transaction before submission. - * @param builderFn - Function that builds the transaction - * @param signatures - Array of signatures with signer public keys - * @param maxRetries - Max number of retries - * @param baseFee - The starting fee in stroops + * Submit a multi-signed transaction with retries. */ async submitMultiSignedTransaction(builderFn, signatures, maxRetries = this.MAX_RETRIES, baseFee) { let attempt = 0; while (attempt <= maxRetries) { try { - // Always resolve the current active server — may have changed after a failover this.server = stellarProvider.getServer(); - const sourceAccount = await this.server.loadAccount(this.getKeypair().publicKey()); + const publicKey = await this.getPublicKey(); + const nextSequence = await sequenceManager.getNextSequence(publicKey); + const sourceAccount = new Account(publicKey, nextSequence); const currentFee = Math.floor(baseFee * (1 + this.FEE_INCREMENT_PERCENTAGE * attempt)); const transaction = builderFn(sourceAccount, currentFee); - // Sign with the local keypair first + this.assertStrictTimeBounds(transaction); await assertSigningAllowed(); - transaction.sign(this.getKeypair()); - // Add signatures from other signers + const txHash = transaction.hash(); + const signature = await signer.sign(txHash); + const kp = Keypair.fromPublicKey(publicKey); + transaction.signatures.push(new xdr.DecoratedSignature({ + hint: kp.signatureHint(), + signature: signature, + })); for (const sig of signatures) { - // Skip if this is the local signer's public key (already signed) - if (sig.signerPublicKey === this.getKeypair().publicKey()) { + if (sig.signerPublicKey === publicKey) continue; - } - // Add the remote signature to the transaction try { - // Convert hex signature to buffer const signatureBuffer = Buffer.from(sig.signature, "hex"); - // Create a keypair from the signer's public key to get the hint const signerKeypair = Keypair.fromPublicKey(sig.signerPublicKey); - // Add the signature to the transaction const decoratedSignature = new xdr.DecoratedSignature({ hint: signerKeypair.signatureHint(), signature: signatureBuffer, @@ -194,21 +201,24 @@ export class StellarService { } catch (error) { console.error(`[StellarService] Failed to add signature for ${sig.signerPublicKey}:`, error); - // Continue without this signature (may cause failure on Stellar side) } } - await assertSigningAllowed(); - return await this.server.submitTransaction(transaction); + return await this.submitWithTimeoutListener(transaction, publicKey); } catch (error) { + const resultCode = error.response?.data?.extras?.result_codes?.transaction; + if (resultCode === "tx_bad_seq" || this.isLocalTimeoutError(error)) { + console.warn("âš ī¸ SequenceManager: stale or invalid multi-sig assignment detected. Invalidating sequence..."); + sequenceManager.invalidate(await this.getPublicKey()); + } attempt++; - // Report to the provider — it will switch to the next node if this is - // a 5xx / network error, so the next attempt uses a healthy node. - stellarProvider.reportFailure(error); - const isStuck = this.isStuckError(error); - if (isStuck && attempt <= maxRetries) { - console.warn(`âš ī¸ Multi-sig transaction stuck or fee too low (Attempt ${attempt}). Bumping fee and retrying in ${this.RETRY_DELAY_MS}ms...`); - await new Promise((resolve) => setTimeout(resolve, this.RETRY_DELAY_MS)); + if (!this.isLocalTimeoutError(error)) { + stellarProvider.reportFailure(error); + } + if (this.isStuckError(error) && attempt <= maxRetries) { + if (!this.shouldRecycleImmediately(error)) { + await new Promise((resolve) => setTimeout(resolve, this.RETRY_DELAY_MS)); + } continue; } throw error; @@ -216,38 +226,81 @@ export class StellarService { } throw new Error(`Failed to submit multi-signed transaction after ${maxRetries + 1} attempts`); } - /** - * Get the network passphrase for the current network. - * Ensures proper network identification for multi-sig operations. - */ - getNetworkPassphrase() { - return this.network === "PUBLIC" ? Networks.PUBLIC : Networks.TESTNET; + assertStrictTimeBounds(transaction) { + const timeBounds = transaction.timeBounds; + const maxTime = Number(timeBounds?.maxTime); + const nowSeconds = Math.floor(Date.now() / 1000); + if (!Number.isFinite(maxTime) || + maxTime <= nowSeconds || + maxTime - nowSeconds > this.TRANSACTION_TIME_BOUND_SECONDS) { + throw new Error(`Transaction envelope must include strict time_bounds of ${this.TRANSACTION_TIME_BOUND_SECONDS}s or less`); + } + } + async submitWithTimeoutListener(transaction, publicKey) { + const pending = this.registerPendingTimeBoundTransaction(transaction, publicKey); + try { + return await Promise.race([ + this.server.submitTransaction(transaction), + new Promise((_, reject) => { + pending.timer = setTimeout(() => { + const activePending = this.pendingTimeBoundTransactions.get(pending.hash); + if (!activePending) { + return; + } + activePending.timedOut = true; + this.pendingTimeBoundTransactions.delete(pending.hash); + console.warn(`[StellarService] Transaction ${pending.hash} exceeded ${this.TRANSACTION_TIME_BOUND_SECONDS}s time-bound. Recycling local assignment.`); + reject(new LocalTransactionTimeoutError(pending.hash, pending.publicKey)); + }, Math.max(pending.expiresAtMs - Date.now(), 0)); + }), + ]); + } + finally { + this.clearPendingTimeBoundTransaction(pending.hash); + } + } + registerPendingTimeBoundTransaction(transaction, publicKey) { + const createdAtMs = Date.now(); + const hash = transaction.hash().toString("hex"); + const pending = { + hash, + publicKey, + createdAtMs, + expiresAtMs: createdAtMs + this.TRANSACTION_TIME_BOUND_SECONDS * 1000, + timedOut: false, + }; + this.pendingTimeBoundTransactions.set(hash, pending); + return pending; + } + clearPendingTimeBoundTransaction(hash) { + const pending = this.pendingTimeBoundTransactions.get(hash); + if (!pending) { + return; + } + if (pending.timer) { + clearTimeout(pending.timer); + } + this.pendingTimeBoundTransactions.delete(hash); } - /** - * Determines if a transaction error indicates it is "stuck" or needs a fee bump. - */ isStuckError(error) { const resultCode = error.response?.data?.extras?.result_codes?.transaction; - // tx_too_late: Transaction timebounds expired before inclusion - // tx_insufficient_fee: Mandatory fee not met - // tx_bad_seq: Sequence number mismatch (often due to race conditions/congestion) - // timeout: Network/SDK timeout during submission - return (resultCode === "tx_too_late" || + return (this.isLocalTimeoutError(error) || + resultCode === "tx_too_late" || resultCode === "tx_insufficient_fee" || resultCode === "tx_bad_seq" || error.message?.includes("timeout") || error.code === "ECONNABORTED"); } - /** - * Generate a unique ID for the transaction memo - * Format: SF-- - */ + shouldRecycleImmediately(error) { + const resultCode = error.response?.data?.extras?.result_codes?.transaction; + return this.isLocalTimeoutError(error) || resultCode === "tx_too_late"; + } + isLocalTimeoutError(error) { + return error instanceof LocalTransactionTimeoutError; + } generateMemoId(currency) { const timestamp = Math.floor(Date.now() / 1000); - const random = Math.floor(Math.random() * 1000) - .toString() - .padStart(3, "0"); - // Stellar MemoText limit is 28 bytes + const random = Math.floor(Math.random() * 1000).toString().padStart(3, "0"); const id = `SF-${currency}-${timestamp}-${random}`; return id.substring(0, 28); } diff --git a/dist/services/stellarService.js.map b/dist/services/stellarService.js.map index ede60311..7afd334c 100644 --- a/dist/services/stellarService.js.map +++ b/dist/services/stellarService.js.map @@ -1 +1 @@ -{"version":3,"file":"stellarService.js","sourceRoot":"","sources":["../../src/services/stellarService.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"stellarService.js","sourceRoot":"","sources":["../../src/services/stellarService.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/services/webhook.d.ts b/dist/services/webhook.d.ts index 577c6c5d..65ecf300 100644 --- a/dist/services/webhook.d.ts +++ b/dist/services/webhook.d.ts @@ -16,16 +16,32 @@ type ReviewDetails = { timestamp: Date; reason: string; }; +type GasBalanceAlertDetails = { + currentBalance: number; + threshold: number; + walletAddress?: string; + timestamp: Date; +}; +type MonitorFailureAlertDetails = { + consecutiveFailures: number; + lastKnownBalance: number | null; + timestamp: Date; +}; export declare class WebhookService { private webhookUrl; private platform; constructor(); sendErrorNotification(errorDetails: ErrorDetails): Promise; sendManualReviewNotification(reviewDetails: ReviewDetails): Promise; + sendGasBalanceAlert(alertDetails: GasBalanceAlertDetails): Promise; + sendMonitorFailureAlert(alertDetails: MonitorFailureAlertDetails): Promise; private postMessage; private formatErrorMessage; private formatReviewMessage; + private formatGasBalanceAlert; + private formatMonitorFailureAlert; } +export declare function getWebhookService(): WebhookService; export declare const webhookService: WebhookService; export {}; //# sourceMappingURL=webhook.d.ts.map \ No newline at end of file diff --git a/dist/services/webhook.d.ts.map b/dist/services/webhook.d.ts.map index 877fa947..1ba2c03f 100644 --- a/dist/services/webhook.d.ts.map +++ b/dist/services/webhook.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../src/services/webhook.ts"],"names":[],"mappings":"AAgDA,KAAK,YAAY,GAAG;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,IAAI,CAAC;CACjB,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,qBAAa,cAAc;IACzB,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,QAAQ,CAAS;;IAQnB,qBAAqB,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAShE,4BAA4B,CAChC,aAAa,EAAE,aAAa,GAC3B,OAAO,CAAC,IAAI,CAAC;YASF,WAAW;IAgCzB,OAAO,CAAC,kBAAkB;IAuD1B,OAAO,CAAC,mBAAmB;CAmF5B;AAED,eAAO,MAAM,cAAc,gBAAuB,CAAC"} \ No newline at end of file +{"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../src/services/webhook.ts"],"names":[],"mappings":"AAgDA,KAAK,YAAY,GAAG;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,IAAI,CAAC;CACjB,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,KAAK,sBAAsB,GAAG;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,IAAI,CAAC;CACjB,CAAC;AAEF,KAAK,0BAA0B,GAAG;IAChC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,SAAS,EAAE,IAAI,CAAC;CACjB,CAAC;AAEF,qBAAa,cAAc;IACzB,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,QAAQ,CAAS;;IAQnB,qBAAqB,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAShE,4BAA4B,CAChC,aAAa,EAAE,aAAa,GAC3B,OAAO,CAAC,IAAI,CAAC;IASV,mBAAmB,CACvB,YAAY,EAAE,sBAAsB,GACnC,OAAO,CAAC,IAAI,CAAC;IASV,uBAAuB,CAC3B,YAAY,EAAE,0BAA0B,GACvC,OAAO,CAAC,IAAI,CAAC;YASF,WAAW;IAgCzB,OAAO,CAAC,kBAAkB;IAuD1B,OAAO,CAAC,mBAAmB;IAsF3B,OAAO,CAAC,qBAAqB;IA+F7B,OAAO,CAAC,yBAAyB;CAqFlC;AAMD,wBAAgB,iBAAiB,IAAI,cAAc,CAKlD;AAED,eAAO,MAAM,cAAc,gBAAsB,CAAC"} \ No newline at end of file diff --git a/dist/services/webhook.js b/dist/services/webhook.js index ad4d17ae..c680db36 100644 --- a/dist/services/webhook.js +++ b/dist/services/webhook.js @@ -23,6 +23,20 @@ export class WebhookService { const message = this.formatReviewMessage(reviewDetails); await this.postMessage(message); } + async sendGasBalanceAlert(alertDetails) { + if (!this.webhookUrl) { + return; + } + const message = this.formatGasBalanceAlert(alertDetails); + await this.postMessage(message); + } + async sendMonitorFailureAlert(alertDetails) { + if (!this.webhookUrl) { + return; + } + const message = this.formatMonitorFailureAlert(alertDetails); + await this.postMessage(message); + } async postMessage(message) { if (!this.webhookUrl) { return; @@ -167,6 +181,183 @@ export class WebhookService { ], }; } + // FIX 1: Added Slack branch — previously always returned a Discord embed, + // which would be silently dropped or mangled when NOTIFICATION_PLATFORM=slack. + formatGasBalanceAlert(alertDetails) { + const { currentBalance, threshold, walletAddress, timestamp } = alertDetails; + const deficit = (threshold - currentBalance).toFixed(2); + if (this.platform === "discord") { + return { + embeds: [ + { + title: "🚨 CRITICAL: Low Gas Balance Alert", + color: 0xff0000, + fields: [ + { + name: "Current Balance", + value: `${currentBalance.toFixed(2)} XLM`, + inline: true, + }, + { + name: "Alert Threshold", + value: `${threshold} XLM`, + inline: true, + }, + { + name: "Deficit", + value: `${deficit} XLM`, + inline: true, + }, + ...(walletAddress + ? [ + { + name: "Wallet Address", + value: `${walletAddress.substring(0, 20)}...`, + }, + ] + : []), + { + name: "Action Required", + value: "Top up the admin wallet with XLM to ensure transaction fees can be paid", + }, + { name: "Time", value: timestamp.toISOString() }, + ], + }, + ], + }; + } + return { + blocks: [ + { + type: "header", + text: { + type: "plain_text", + text: "🚨 CRITICAL: Low Gas Balance Alert", + }, + }, + { + type: "section", + fields: [ + { + type: "mrkdwn", + text: `*Current Balance:*\n${currentBalance.toFixed(2)} XLM`, + }, + { type: "mrkdwn", text: `*Alert Threshold:*\n${threshold} XLM` }, + { type: "mrkdwn", text: `*Deficit:*\n${deficit} XLM` }, + ...(walletAddress + ? [ + { + type: "mrkdwn", + text: `*Wallet Address:*\n${walletAddress.substring(0, 20)}...`, + }, + ] + : []), + ], + }, + { + type: "section", + text: { + type: "mrkdwn", + text: "*Action Required:*\nTop up the admin wallet with XLM to ensure transaction fees can be paid", + }, + }, + { + type: "context", + elements: [ + { type: "mrkdwn", text: `Detected at ${timestamp.toISOString()}` }, + ], + }, + ], + }; + } + // FIX 1 (continued): Added Slack branch to formatMonitorFailureAlert for the same reason. + formatMonitorFailureAlert(alertDetails) { + const { consecutiveFailures, lastKnownBalance, timestamp } = alertDetails; + const lastBalance = lastKnownBalance !== null + ? `${lastKnownBalance.toFixed(2)} XLM` + : "Unknown"; + if (this.platform === "discord") { + return { + embeds: [ + { + title: "🚨 CRITICAL: Gas Monitor Failures", + color: 0xff0000, + fields: [ + { + name: "Consecutive Failures", + value: `${consecutiveFailures}`, + inline: true, + }, + { + name: "Last Known Balance", + value: lastBalance, + inline: true, + }, + { + name: "Issue", + value: "Unable to check admin wallet balance. Cannot confirm if funds are sufficient.", + }, + { + name: "Action Required", + value: "Investigate Stellar Horizon connectivity and verify environment variables.", + }, + { name: "Time", value: timestamp.toISOString() }, + ], + }, + ], + }; + } + return { + blocks: [ + { + type: "header", + text: { + type: "plain_text", + text: "🚨 CRITICAL: Gas Monitor Failures", + }, + }, + { + type: "section", + fields: [ + { + type: "mrkdwn", + text: `*Consecutive Failures:*\n${consecutiveFailures}`, + }, + { type: "mrkdwn", text: `*Last Known Balance:*\n${lastBalance}` }, + ], + }, + { + type: "section", + text: { + type: "mrkdwn", + text: "*Issue:*\nUnable to check admin wallet balance. Cannot confirm if funds are sufficient.", + }, + }, + { + type: "section", + text: { + type: "mrkdwn", + text: "*Action Required:*\nInvestigate Stellar Horizon connectivity and verify environment variables.", + }, + }, + { + type: "context", + elements: [ + { type: "mrkdwn", text: `Detected at ${timestamp.toISOString()}` }, + ], + }, + ], + }; + } +} +// FIX 2: Lazy singleton factory — avoids constructing WebhookService at import +// time, keeping it consistent with the pattern used in gasBalanceMonitorService. +let _instance = null; +export function getWebhookService() { + if (!_instance) { + _instance = new WebhookService(); + } + return _instance; } -export const webhookService = new WebhookService(); +export const webhookService = getWebhookService(); //# sourceMappingURL=webhook.js.map \ No newline at end of file diff --git a/dist/services/webhook.js.map b/dist/services/webhook.js.map index 143f8521..fa2e112c 100644 --- a/dist/services/webhook.js.map +++ b/dist/services/webhook.js.map @@ -1 +1 @@ -{"version":3,"file":"webhook.js","sourceRoot":"","sources":["../../src/services/webhook.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"webhook.js","sourceRoot":"","sources":["../../src/services/webhook.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/utils/envValidator.d.ts.map b/dist/utils/envValidator.d.ts.map index 3b227631..0480c560 100644 --- a/dist/utils/envValidator.d.ts.map +++ b/dist/utils/envValidator.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"envValidator.d.ts","sourceRoot":"","sources":["../../src/utils/envValidator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,wBAAgB,WAAW,SA+B1B;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAaxC"} \ No newline at end of file +{"version":3,"file":"envValidator.d.ts","sourceRoot":"","sources":["../../src/utils/envValidator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,wBAAgB,WAAW,SA2C1B;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAaxC"} \ No newline at end of file diff --git a/dist/utils/envValidator.js b/dist/utils/envValidator.js index e348d5e8..e20f4dc8 100644 --- a/dist/utils/envValidator.js +++ b/dist/utils/envValidator.js @@ -3,7 +3,12 @@ * Prevents the server from crashing mysteriously if a setting is missing. */ export function validateEnv() { - const requiredEnvVars = ["DB_URL", "STELLAR_KEY"]; + const requiredEnvVars = [ + "DB_URL", + "STELLAR_KEY", + "JWT_SECRET", + "SESSION_SECRET", + ]; const missingEnvVars = []; for (const envVar of requiredEnvVars) { if (!process.env[envVar]) { @@ -20,13 +25,18 @@ export function validateEnv() { process.exit(1); } // Log optional but recommended environment variables - const recommendedEnvVars = ["MAX_LATENCY_MS"]; + const recommendedEnvVars = [ + "MAX_LATENCY_MS", + "REDIS_URL", + "TRUST_PROXY", + "JWT_EXPIRY_HOURS", + ]; for (const envVar of recommendedEnvVars) { if (!process.env[envVar]) { console.warn(`âš ī¸ [OPS] Recommended environment variable not set: ${envVar}`); } else { - console.info(`✅ [OPS] ${envVar} = ${process.env[envVar]}ms`); + console.info(`✅ [OPS] ${envVar} = ${process.env[envVar]}`); } } } diff --git a/dist/utils/envValidator.js.map b/dist/utils/envValidator.js.map index e4bf39c4..0a144282 100644 --- a/dist/utils/envValidator.js.map +++ b/dist/utils/envValidator.js.map @@ -1 +1 @@ -{"version":3,"file":"envValidator.js","sourceRoot":"","sources":["../../src/utils/envValidator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,UAAU,WAAW;IACzB,MAAM,eAAe,GAAG,CAAC,QAAQ,EAAE,aAAa,CAAU,CAAC;IAC3D,MAAM,cAAc,GAAa,EAAE,CAAC;IAEpC,KAAK,MAAM,MAAM,IAAI,eAAe,EAAE,CAAC;QACrC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACzB,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACjE,cAAc,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YACjC,OAAO,CAAC,KAAK,CAAC,QAAQ,OAAO,EAAE,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,KAAK,CACX,wEAAwE,CACzE,CAAC;QACF,qCAAqC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,qDAAqD;IACrD,MAAM,kBAAkB,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC9C,KAAK,MAAM,MAAM,IAAI,kBAAkB,EAAE,CAAC;QACxC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,IAAI,CAAC,sDAAsD,MAAM,EAAE,CAAC,CAAC;QAC/E,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,WAAW,MAAM,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe;IAC7B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAC5C,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,EAAE,EAAE,CAAC;QAC9C,OAAO,KAAK,CAAC,CAAC,sBAAsB;IACtC,CAAC;IACD,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACtC,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,IAAI,CACV,2CAA2C,QAAQ,2BAA2B,CAC/E,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"} \ No newline at end of file +{"version":3,"file":"envValidator.js","sourceRoot":"","sources":["../../src/utils/envValidator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,UAAU,WAAW;IACzB,MAAM,eAAe,GAAG;QACtB,QAAQ;QACR,aAAa;QACb,YAAY;QACZ,gBAAgB;KACR,CAAC;IACX,MAAM,cAAc,GAAa,EAAE,CAAC;IAEpC,KAAK,MAAM,MAAM,IAAI,eAAe,EAAE,CAAC;QACrC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACzB,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACjE,cAAc,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YACjC,OAAO,CAAC,KAAK,CAAC,QAAQ,OAAO,EAAE,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,KAAK,CACX,wEAAwE,CACzE,CAAC;QACF,qCAAqC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,qDAAqD;IACrD,MAAM,kBAAkB,GAAG;QACzB,gBAAgB;QAChB,WAAW;QACX,aAAa;QACb,kBAAkB;KACnB,CAAC;IACF,KAAK,MAAM,MAAM,IAAI,kBAAkB,EAAE,CAAC;QACxC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,IAAI,CACV,sDAAsD,MAAM,EAAE,CAC/D,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,WAAW,MAAM,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe;IAC7B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAC5C,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,EAAE,EAAE,CAAC;QAC9C,OAAO,KAAK,CAAC,CAAC,sBAAsB;IACtC,CAAC;IACD,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACtC,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,IAAI,CACV,2CAA2C,QAAQ,2BAA2B,CAC/E,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 19d30709..61299597 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,7 @@ "@types/pg": "^8.20.0", "async-mutex": "^0.5.0", "axios": "^1.7.0", + "bcrypt": "^5.1.1", "color-name": "^2.1.0", "compression": "^1.8.1", "cors": "^2.8.6", @@ -38,6 +39,7 @@ "express-rate-limit": "^8.3.1", "helmet": "^8.1.0", "joi": "^17.13.3", + "jsonwebtoken": "^9.0.3", "morgan": "^1.10.1", "pdfkit": "^0.18.0", "pg": "^8.20.0", @@ -57,10 +59,11 @@ "winston-daily-rotate-file": "^5.0.0" }, "devDependencies": { + "@types/bcrypt": "^5.0.2", "@types/compression": "^1.8.1", - "@types/cors": "^2.8.19", "@types/express": "^5.0.6", "@types/jest": "^30.0.0", + "@types/jsonwebtoken": "^9.0.5", "@types/morgan": "^1.9.10", "@types/swagger-jsdoc": "^6.0.4", "@types/swagger-ui-express": "^4.1.8", @@ -2760,6 +2763,89 @@ "devOptional": true, "license": "MIT" }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/@napi-rs/wasm-runtime": { "version": "0.2.12", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", @@ -5574,6 +5660,15 @@ "@babel/types": "^7.28.2" } }, + "node_modules/@types/bcrypt": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.2.tgz", + "integrity": "sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/body-parser": { "version": "1.19.6", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", @@ -5716,6 +5811,16 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "license": "MIT" }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.10", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz", + "integrity": "sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==", + "dev": true, + "dependencies": { + "@types/ms": "*", + "@types/node": "*" + } + }, "node_modules/@types/memcached": { "version": "2.2.10", "resolved": "https://registry.npmjs.org/@types/memcached/-/memcached-2.2.10.tgz", @@ -5735,6 +5840,12 @@ "@types/node": "*" } }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "dev": true + }, "node_modules/@types/mysql": { "version": "2.15.27", "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.27.tgz", @@ -6419,6 +6530,11 @@ "win32" ] }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, "node_modules/accepts": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", @@ -6587,6 +6703,24 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/aproba": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.1.0.tgz", + "integrity": "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==" + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "deprecated": "This package is no longer supported.", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -6834,6 +6968,19 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "license": "MIT" }, + "node_modules/bcrypt": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz", + "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==", + "hasInstallScript": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.11", + "node-addon-api": "^5.0.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/better-result": { "version": "2.8.2", "resolved": "https://registry.npmjs.org/better-result/-/better-result-2.8.2.tgz", @@ -6998,6 +7145,11 @@ "ieee754": "^1.2.1" } }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -7207,6 +7359,14 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } + }, "node_modules/ci-info": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", @@ -7448,6 +7608,14 @@ "node": ">=18" } }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "bin": { + "color-support": "bin.js" + } + }, "node_modules/color/node_modules/color-convert": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-3.1.3.tgz", @@ -7546,6 +7714,11 @@ "devOptional": true, "license": "MIT" }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" + }, "node_modules/content-disposition": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", @@ -7753,6 +7926,11 @@ "node": ">=0.4.0" } }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + }, "node_modules/denque": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", @@ -7779,6 +7957,14 @@ "devOptional": true, "license": "MIT" }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "engines": { + "node": ">=8" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -7849,6 +8035,14 @@ "dev": true, "license": "MIT" }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -9003,6 +9197,33 @@ "node": ">= 0.8" } }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs-minipass/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -9033,6 +9254,76 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "deprecated": "This package is no longer supported.", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gauge/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/gauge/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/gauge/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/gauge/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/gauge/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/gauge/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/gaxios": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.4.tgz", @@ -9387,6 +9678,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + }, "node_modules/hasown": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", @@ -10594,6 +10890,46 @@ "node": ">=6" } }, + "node_modules/jsonwebtoken": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", + "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==", + "dependencies": { + "jws": "^4.0.1", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "dependencies": { + "jwa": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -10797,6 +11133,16 @@ "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.", "license": "MIT" }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, "node_modules/lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", @@ -10804,6 +11150,26 @@ "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", "license": "MIT" }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -10824,6 +11190,11 @@ "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", "license": "MIT" }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, "node_modules/log-update": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", @@ -11166,6 +11537,45 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/module-details-from-path": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz", @@ -11303,6 +11713,11 @@ "dev": true, "license": "MIT" }, + "node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" + }, "node_modules/node-domexception": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", @@ -11354,6 +11769,20 @@ "dev": true, "license": "MIT" }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -11377,6 +11806,18 @@ "node": ">=8" } }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "deprecated": "This package is no longer supported.", + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -12483,6 +12924,66 @@ "dev": true, "license": "MIT" }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", + "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/router": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", @@ -12546,7 +13047,6 @@ "version": "7.7.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -12606,6 +13106,11 @@ "url": "https://opencollective.com/express" } }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -13348,6 +13853,36 @@ "url": "https://opencollective.com/synckit" } }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "deprecated": "Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "node_modules/tdigest": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.2.tgz", @@ -13525,6 +14060,11 @@ "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==", "license": "MIT" }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "node_modules/triple-beam": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", @@ -14021,6 +14561,20 @@ "node": ">= 8" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -14058,6 +14612,59 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/wide-align/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/wide-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/wide-align/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/wide-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wide-align/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/winston": { "version": "3.19.0", "resolved": "https://registry.npmjs.org/winston/-/winston-3.19.0.tgz", From 95200077f430df45b78c767f3802474fedae5969 Mon Sep 17 00:00:00 2001 From: "ceza.exe" Date: Thu, 28 May 2026 23:34:13 +0000 Subject: [PATCH 2/2] =?UTF-8?q?#296=20=F0=9F=93=9D=20QA=20|=20Automated=20?= =?UTF-8?q?Pre-Commit=20Linter=20Enforcement=20FIXED?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- eslint.config.mjs | 19 +- src/lib/apiError.ts | 4 +- src/lib/tracing.ts | 225 ++++--- src/middleware/apiKeyMiddleware.ts | 1 - src/middleware/securityMiddleware.ts | 24 +- src/routes/admin.ts | 69 ++- src/routes/assets.ts | 49 +- src/utils/winstonLogger.ts | 2 + test.ts | 865 ++++++++++++++------------- test/intelligence.test.ts | 6 +- 10 files changed, 728 insertions(+), 536 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index 7e87a3c0..c5afed16 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -5,7 +5,13 @@ import eslintConfigPrettier from "eslint-config-prettier"; export default [ { - ignores: ["dist/**", "node_modules/**", "docs/**"], + ignores: [ + "dist/**", + "node_modules/**", + "docs/**", + "src/metrics /**", + "tests/load/**", + ], }, js.configs.recommended, { @@ -19,6 +25,7 @@ export default [ globals: { Buffer: "readonly", __dirname: "readonly", + __filename: "readonly", console: "readonly", process: "readonly", setTimeout: "readonly", @@ -29,6 +36,10 @@ export default [ btoa: "readonly", URL: "readonly", URLSearchParams: "readonly", + NodeJS: "readonly", + AbortSignal: "readonly", + require: "readonly", + module: "readonly", }, }, plugins: { @@ -45,6 +56,8 @@ export default [ varsIgnorePattern: "^_", }, ], + // Allow `declare global { namespace Express { ... } }` — standard TS augmentation + "@typescript-eslint/no-namespace": ["error", { allowDeclarations: true }], // Enforce PascalCase for classes/types/interfaces/enums, camelCase for everything else "@typescript-eslint/naming-convention": [ "error", @@ -84,7 +97,7 @@ export default [ }, { selector: "classProperty", - format: ["camelCase"], + format: ["camelCase", "UPPER_CASE"], leadingUnderscore: "allow", }, { @@ -101,7 +114,7 @@ export default [ }, }, { - files: ["test/**/*.ts", "tests/**/*.ts"], + files: ["test/**/*.ts", "tests/**/*.ts", "test.ts"], languageOptions: { globals: { describe: "readonly", diff --git a/src/lib/apiError.ts b/src/lib/apiError.ts index 3d84ca55..21b5dbed 100644 --- a/src/lib/apiError.ts +++ b/src/lib/apiError.ts @@ -28,8 +28,7 @@ export const ERROR_MESSAGES: Record = { RATE_LIMITED: "Too many requests. Please try again later.", INTERNAL_SERVER_ERROR: "An unexpected error occurred.", SERVICE_UNAVAILABLE: "The service is temporarily unavailable.", - MAINTENANCE_MODE: - "Service is under maintenance. Please try again later.", + MAINTENANCE_MODE: "Service is under maintenance. Please try again later.", MISSING_API_KEY: "Request must include a valid X-API-Key header.", INVALID_API_KEY: "The provided API key is invalid or inactive.", INSUFFICIENT_SCOPE: "This API key does not have the required scope.", @@ -49,7 +48,6 @@ export const ERROR_MESSAGES: Record = { CORS_DENIED: "Cross-origin request denied by CORS policy.", PAYLOAD_TOO_LARGE: "Request body exceeds the allowed size.", INVALID_JSON: "Request body must be valid JSON.", - METHOD_NOT_ALLOWED: "This HTTP method is not supported.", API_KEY_INACTIVE: "This API key has been revoked.", API_KEY_EXPIRED: "This API key has expired.", UNAUTHENTICATED: "Authentication middleware must run before this handler.", diff --git a/src/lib/tracing.ts b/src/lib/tracing.ts index bf92d594..04a6700d 100644 --- a/src/lib/tracing.ts +++ b/src/lib/tracing.ts @@ -1,13 +1,23 @@ -import { NodeSDK } from '@opentelemetry/sdk-node'; -import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'; -import { JaegerExporter as OTelJaegerExporter } from '@opentelemetry/exporter-jaeger'; -import { ConsoleSpanExporter, BatchSpanProcessor, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'; -import { trace, context, Span as OTelSpan, SpanStatusCode, Context, propagation } from '@opentelemetry/api'; -import { resourceFromAttributes } from '@opentelemetry/resources'; -import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'; -import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'; -import { W3CTraceContextPropagator } from '@opentelemetry/core'; -import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'; +import { NodeSDK } from "@opentelemetry/sdk-node"; +import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http"; +import { JaegerExporter as OTelJaegerExporter } from "@opentelemetry/exporter-jaeger"; +import { + ConsoleSpanExporter, + BatchSpanProcessor, +} from "@opentelemetry/sdk-trace-base"; +import { + trace, + context, + Span as OTelSpan, + SpanStatusCode, + Context, + propagation, +} from "@opentelemetry/api"; +import { resourceFromAttributes } from "@opentelemetry/resources"; +import { SemanticResourceAttributes } from "@opentelemetry/semantic-conventions"; +import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node"; +import { W3CTraceContextPropagator } from "@opentelemetry/core"; +import axios from "axios"; /** * Trace context interface for W3C trace context (backward compatible) @@ -37,7 +47,7 @@ export interface Span { message: string; fields?: Record; }>; - status: 'ok' | 'error'; + status: "ok" | "error"; error?: Error; // Internal OpenTelemetry span reference _otelSpan?: OTelSpan; @@ -55,7 +65,9 @@ export interface TraceExporter { */ export class JaegerExporter implements TraceExporter { async export(_spans: Span[]): Promise { - console.log('[Tracing] JaegerExporter is deprecated. Use initializeTracing() with Jaeger configuration instead.'); + console.log( + "[Tracing] JaegerExporter is deprecated. Use initializeTracing() with Jaeger configuration instead.", + ); } } @@ -64,7 +76,9 @@ export class JaegerExporter implements TraceExporter { */ export class HoneycombExporter implements TraceExporter { async export(_spans: Span[]): Promise { - console.log('[Tracing] HoneycombExporter is deprecated. Use initializeTracing() with OTLP/Honeycomb configuration instead.'); + console.log( + "[Tracing] HoneycombExporter is deprecated. Use initializeTracing() with OTLP/Honeycomb configuration instead.", + ); } } @@ -73,14 +87,18 @@ export class HoneycombExporter implements TraceExporter { */ export class ConsoleExporter implements TraceExporter { async export(spans: Span[]): Promise { - spans.forEach(span => { - const duration = span.endTime ? span.endTime - span.startTime : Date.now() - span.startTime; - console.log(`[Trace] ${span.operationName} - ${duration}ms - ${span.traceId}:${span.spanId}`); + spans.forEach((span) => { + const duration = span.endTime + ? span.endTime - span.startTime + : Date.now() - span.startTime; + console.log( + `[Trace] ${span.operationName} - ${duration}ms - ${span.traceId}:${span.spanId}`, + ); if (span.tags && Object.keys(span.tags).length > 0) { - console.log('[Trace] Tags:', span.tags); + console.log("[Trace] Tags:", span.tags); } if (span.logs.length > 0) { - console.log('[Trace] Logs:', span.logs); + console.log("[Trace] Logs:", span.logs); } }); } @@ -88,7 +106,7 @@ export class ConsoleExporter implements TraceExporter { // OpenTelemetry SDK instance let otelSDK: NodeSDK | null = null; -let tracer = trace.getTracer('stellarflow-backend'); +let tracer = trace.getTracer("stellarflow-backend"); /** * Initialize OpenTelemetry SDK with proper configuration @@ -102,32 +120,42 @@ export function initializeOpenTelemetry(config: { honeycombDataset?: string | undefined; consoleExporter?: boolean | undefined; }): void { - const exporters: (ConsoleSpanExporter | OTLPTraceExporter | OTelJaegerExporter)[] = []; + const exporters: ( + | ConsoleSpanExporter + | OTLPTraceExporter + | OTelJaegerExporter + )[] = []; if (config.consoleExporter) { exporters.push(new ConsoleSpanExporter()); } if (config.otlpEndpoint) { - exporters.push(new OTLPTraceExporter({ - url: config.otlpEndpoint, - })); + exporters.push( + new OTLPTraceExporter({ + url: config.otlpEndpoint, + }), + ); } if (config.honeycombEndpoint && config.honeycombApiKey) { - exporters.push(new OTLPTraceExporter({ - url: config.honeycombEndpoint, - headers: { - 'x-honeycomb-team': config.honeycombApiKey, - 'x-honeycomb-dataset': config.honeycombDataset || 'stellarflow' - } - })); + exporters.push( + new OTLPTraceExporter({ + url: config.honeycombEndpoint, + headers: { + "x-honeycomb-team": config.honeycombApiKey, + "x-honeycomb-dataset": config.honeycombDataset || "stellarflow", + }, + }), + ); } if (config.jaegerEndpoint) { - exporters.push(new OTelJaegerExporter({ - endpoint: config.jaegerEndpoint, - })); + exporters.push( + new OTelJaegerExporter({ + endpoint: config.jaegerEndpoint, + }), + ); } // Default to console if no exporters configured @@ -138,39 +166,52 @@ export function initializeOpenTelemetry(config: { otelSDK = new NodeSDK({ resource: resourceFromAttributes({ [SemanticResourceAttributes.SERVICE_NAME]: config.serviceName, - [SemanticResourceAttributes.SERVICE_VERSION]: '1.0.0', + [SemanticResourceAttributes.SERVICE_VERSION]: "1.0.0", }), - traceExporter: exporters.length === 1 ? exporters[0]! : new MultiExporter(exporters), - instrumentations: [getNodeAutoInstrumentations({ - '@opentelemetry/instrumentation-http': { enabled: true }, - '@opentelemetry/instrumentation-express': { enabled: true }, - })], - spanProcessor: new BatchSpanProcessor(exporters.length === 1 ? exporters[0]! : new MultiExporter(exporters)), + traceExporter: + exporters.length === 1 ? exporters[0]! : new MultiExporter(exporters), + instrumentations: [ + getNodeAutoInstrumentations({ + "@opentelemetry/instrumentation-http": { enabled: true }, + "@opentelemetry/instrumentation-express": { enabled: true }, + }), + ], + spanProcessor: new BatchSpanProcessor( + exporters.length === 1 ? exporters[0]! : new MultiExporter(exporters), + ), textMapPropagator: new W3CTraceContextPropagator(), }); otelSDK.start(); tracer = trace.getTracer(config.serviceName); - console.log(`[OpenTelemetry] SDK initialized for service: ${config.serviceName}`); + console.log( + `[OpenTelemetry] SDK initialized for service: ${config.serviceName}`, + ); } /** * Multi-exporter for sending spans to multiple destinations */ class MultiExporter extends ConsoleSpanExporter { - private exporters: (ConsoleSpanExporter | OTLPTraceExporter | OTelJaegerExporter)[]; - - constructor(exporters: (ConsoleSpanExporter | OTLPTraceExporter | OTelJaegerExporter)[]) { + private exporters: ( + | ConsoleSpanExporter + | OTLPTraceExporter + | OTelJaegerExporter + )[]; + + constructor( + exporters: (ConsoleSpanExporter | OTLPTraceExporter | OTelJaegerExporter)[], + ) { super(); this.exporters = exporters; } export(spans: any, resultCallback: any): void { - this.exporters.forEach(exporter => { + this.exporters.forEach((exporter) => { try { (exporter as any).export(spans, resultCallback); } catch (error) { - console.error('[Tracing] Exporter error:', error); + console.error("[Tracing] Exporter error:", error); } }); } @@ -200,7 +241,9 @@ export class Tracing { exporters?: TraceExporter[]; exportIntervalMs?: number; }): void { - console.log('[Tracing] Legacy initialize() called. Use initializeOpenTelemetry() for proper OTel SDK setup.'); + console.log( + "[Tracing] Legacy initialize() called. Use initializeOpenTelemetry() for proper OTel SDK setup.", + ); } /** @@ -209,10 +252,14 @@ export class Tracing { extractTraceContext(headers: Record): TraceContext | null { const getter = { get: (carrier: Record, key: string) => carrier[key], - keys: (carrier: Record) => Object.keys(carrier) + keys: (carrier: Record) => Object.keys(carrier), }; - const extractedContext = propagation.extract(context.active(), headers, getter); + const extractedContext = propagation.extract( + context.active(), + headers, + getter, + ); const spanContext = trace.getSpanContext(extractedContext); if (!spanContext) { @@ -230,7 +277,10 @@ export class Tracing { /** * Inject trace context into headers (W3C format) */ - injectTraceContext(headers: Record, traceContext: TraceContext): void { + injectTraceContext( + headers: Record, + traceContext: TraceContext, + ): void { const spanContext = { traceId: traceContext.traceId, spanId: traceContext.spanId, @@ -241,7 +291,7 @@ export class Tracing { const setter = { set: (carrier: Record, key: string, value: string) => { carrier[key] = value; - } + }, }; // Create a context with the span context and inject it @@ -252,7 +302,11 @@ export class Tracing { /** * Start a new span (backward compatible API) */ - startSpan(operationName: string, parentContext?: TraceContext, tags?: Record): Span { + startSpan( + operationName: string, + parentContext?: TraceContext, + tags?: Record, + ): Span { const startTime = Date.now(); let otelParentContext: Context | undefined; @@ -283,7 +337,7 @@ export class Tracing { startTime, tags: tags || {}, logs: [], - status: 'ok', + status: "ok", _otelSpan: otelSpan, }; @@ -297,7 +351,10 @@ export class Tracing { finishSpan(span: Span, error?: Error): void { if (span._otelSpan) { if (error) { - span._otelSpan.setStatus({ code: SpanStatusCode.ERROR, message: error.message }); + span._otelSpan.setStatus({ + code: SpanStatusCode.ERROR, + message: error.message, + }); span._otelSpan.recordException(error); } else { span._otelSpan.setStatus({ code: SpanStatusCode.OK }); @@ -306,7 +363,7 @@ export class Tracing { } span.endTime = Date.now(); - span.status = error ? 'error' : 'ok'; + span.status = error ? "error" : "ok"; if (error) { span.error = error; } @@ -317,22 +374,30 @@ export class Tracing { /** * Add a log entry to a span (backward compatible API) */ - log(span: Span, level: string, message: string, fields?: Record): void { + log( + span: Span, + level: string, + message: string, + fields?: Record, + ): void { span.logs.push({ timestamp: Date.now(), level, message, - ...(fields && { fields }) + ...(fields && { fields }), }); if (span._otelSpan) { - const attributes: Record = { 'log.level': level, 'log.message': message }; + const attributes: Record = { + "log.level": level, + "log.message": message, + }; if (fields) { Object.entries(fields).forEach(([key, value]) => { attributes[`log.field.${key}`] = value; }); } - span._otelSpan.addEvent('log', attributes); + span._otelSpan.addEvent("log", attributes); } } @@ -369,44 +434,53 @@ export class Tracing { * Note: OpenTelemetry auto-instrumentation handles this automatically */ export function setupAxiosTracing(axiosInstance = axios): void { - console.log('[Tracing] setupAxiosTracing() called. Setting up trace context propagation.'); - + console.log( + "[Tracing] setupAxiosTracing() called. Setting up trace context propagation.", + ); + // Add request interceptor to inject traceparent headers axiosInstance.interceptors.request.use((config) => { const currentSpan = trace.getSpan(context.active()); if (currentSpan) { const spanContext = currentSpan.spanContext(); - + // Inject W3C trace context headers for explicit propagation const carrier: Record = {}; const setter = { set: (carrier: Record, key: string, value: string) => { carrier[key] = value; - } + }, }; - + // Create context with current span and inject trace headers const ctx = trace.setSpan(context.active(), currentSpan); propagation.inject(ctx, carrier, setter); - + // Merge trace headers into existing config headers Object.assign(config.headers || {}, carrier); - + // Log in development - if (process.env.NODE_ENV === 'development') { - console.log(`[Tracing] HTTP ${config.method?.toUpperCase()} ${config.url} (trace: ${spanContext.traceId})`); - console.log(`[Tracing] Injected trace headers:`, Object.keys(carrier).filter(k => k.startsWith('trace'))); + if (process.env.NODE_ENV === "development") { + console.log( + `[Tracing] HTTP ${config.method?.toUpperCase()} ${config.url} (trace: ${spanContext.traceId})`, + ); + console.log( + `[Tracing] Injected trace headers:`, + Object.keys(carrier).filter((k) => k.startsWith("trace")), + ); } } return config; }); - + // Add response interceptor for tracing completion axiosInstance.interceptors.response.use( (response) => { const currentSpan = trace.getSpan(context.active()); - if (currentSpan && process.env.NODE_ENV === 'development') { - console.log(`[Tracing] HTTP Response: ${response.status} ${response.config.url}`); + if (currentSpan && process.env.NODE_ENV === "development") { + console.log( + `[Tracing] HTTP Response: ${response.status} ${response.config.url}`, + ); } return response; }, @@ -414,10 +488,13 @@ export function setupAxiosTracing(axiosInstance = axios): void { const currentSpan = trace.getSpan(context.active()); if (currentSpan) { currentSpan.recordException(error); - currentSpan.setStatus({ code: SpanStatusCode.ERROR, message: error.message }); + currentSpan.setStatus({ + code: SpanStatusCode.ERROR, + message: error.message, + }); } return Promise.reject(error); - } + }, ); } diff --git a/src/middleware/apiKeyMiddleware.ts b/src/middleware/apiKeyMiddleware.ts index 687e394a..ee7e9944 100644 --- a/src/middleware/apiKeyMiddleware.ts +++ b/src/middleware/apiKeyMiddleware.ts @@ -14,7 +14,6 @@ import { // req.apiKey without casting. // ------------------------------------------------------------------ declare global { - // eslint-disable-next-line @typescript-eslint/no-namespace namespace Express { interface Request { apiKey?: AuthenticatedApiKey; diff --git a/src/middleware/securityMiddleware.ts b/src/middleware/securityMiddleware.ts index c628e626..5587102a 100644 --- a/src/middleware/securityMiddleware.ts +++ b/src/middleware/securityMiddleware.ts @@ -3,8 +3,9 @@ import { sendApiError } from "../lib/apiError.js"; import { logger } from "../utils/logger"; // Regexes to detect SQLi and XSS-like patterns (including common encoded forms) -const suspiciousPattern = /(|onerror=|onload=|javascript:)|\b(select|union|insert|update|delete|drop|alter|create|exec)\b|['"`;--]|%27|%3C|%3E|%3B/i; -const strictParamPattern = /[<>{}"'`;\-\-]|%27|%3C|%3E|%3B/; +const suspiciousPattern = + /(|onerror=|onload=|javascript:)|\b(select|union|insert|update|delete|drop|alter|create|exec)\b|['"`;]|--|%27|%3C|%3E|%3B/i; +const strictParamPattern = /[<>{}"'`;]|--|%27|%3C|%3E|%3B/; /** * Middleware that inspects request headers for common attack patterns @@ -27,7 +28,10 @@ export function inspectHeadersMiddleware( if (suspiciousPattern.test(v)) { logger.warn("[SECURITY] Suspicious header detected", { header: name, - value: typeof v === "string" && v.length > 200 ? `${v.slice(0, 200)}...` : v, + value: + typeof v === "string" && v.length > 200 + ? `${v.slice(0, 200)}...` + : v, ip: req.ip, path: req.path, }); @@ -72,7 +76,8 @@ export function createStrictModeMiddleware(options: StrictOptions = {}) { return (req: Request, res: Response, next: NextFunction): void => { try { const envEnabled = process.env.STRICT_MODE === "true"; - const headerEnabled = String(req.headers[toggleHeader] || "").toLowerCase() === "true"; + const headerEnabled = + String(req.headers[toggleHeader] || "").toLowerCase() === "true"; const enabled = Boolean(options.enabled) || envEnabled || headerEnabled; if (!enabled) { @@ -85,7 +90,9 @@ export function createStrictModeMiddleware(options: StrictOptions = {}) { if (Array.isArray(val)) val = val[0]; if (typeof val !== "string") val = String(val); // trim and check for suspicious characters or encoded equivalents - return strictParamPattern.test(val) || /\b(or|and)\b\s+\d+=\d+/i.test(val); + return ( + strictParamPattern.test(val) || /\b(or|and)\b\s+\d+=\d+/i.test(val) + ); }; const { symbol, provider } = req.query as Record; @@ -98,7 +105,12 @@ export function createStrictModeMiddleware(options: StrictOptions = {}) { provider, }); - sendApiError(res, 400, "BAD_REQUEST", "Strict Mode: suspicious characters in query parameters"); + sendApiError( + res, + 400, + "BAD_REQUEST", + "Strict Mode: suspicious characters in query parameters", + ); return; } diff --git a/src/routes/admin.ts b/src/routes/admin.ts index 240a6faa..1c27cc58 100644 --- a/src/routes/admin.ts +++ b/src/routes/admin.ts @@ -11,6 +11,18 @@ import { import { updateSecretKey } from "../services/secretManager"; import { appConfig } from "../config/configWatcher"; import { refreshWhitelistCache } from "../middleware/rateLimitMiddleware"; +import { + getRelayerRegistry, + getRelayerRegistryById, +} from "../controllers/adminController"; + +const CONFIG_PATH = path.resolve(process.cwd(), "config.json"); + +const rateLimitUpdateSchema = Joi.object({ + windowMs: Joi.number().integer().min(1000).max(86400000).optional(), + maxRequests: Joi.number().integer().min(1).max(100000).optional(), + enabled: Joi.boolean().optional(), +}); const router = Router(); @@ -62,7 +74,12 @@ router.get("/reports/summary", async (req, res) => { const month = req.query.month as string | undefined; if (month && !/^\d{4}-\d{2}$/.test(month)) { - sendApiError(res, 400, "BAD_REQUEST", "Invalid month format. Use YYYY-MM (e.g. 2025-03)."); + sendApiError( + res, + 400, + "BAD_REQUEST", + "Invalid month format. Use YYYY-MM (e.g. 2025-03).", + ); return; } @@ -93,7 +110,20 @@ router.get("/reports/summary", async (req, res) => { res.send(renderHTML(summary)); } catch (error) { console.error("[AdminReports] Failed to generate report:", error); - sendApiError(res, 500, "INTERNAL_SERVER_ERROR", typeof (error instanceof Error ? error.message : "Failed to generate report") === "string" ? String(error instanceof Error ? error.message : "Failed to generate report") : undefined); + sendApiError( + res, + 500, + "INTERNAL_SERVER_ERROR", + typeof (error instanceof Error + ? error.message + : "Failed to generate report") === "string" + ? String( + error instanceof Error + ? error.message + : "Failed to generate report", + ) + : undefined, + ); } }); @@ -135,7 +165,12 @@ router.post("/reload-secret", async (req, res) => { const envKey = process.env.ORACLE_SECRET_KEY || process.env.SOROBAN_ADMIN_SECRET; if (!envKey) { - return sendApiError(res, 500, "INTERNAL_SERVER_ERROR", "Failed to reload secret key"); + return sendApiError( + res, + 500, + "INTERNAL_SERVER_ERROR", + "Failed to reload secret key", + ); } updateSecretKey(envKey, "admin-endpoint"); } @@ -151,10 +186,20 @@ router.post("/reload-secret", async (req, res) => { message === "Invalid Stellar secret key format"; if (isValidationError) { - return sendApiError(res, 400, "BAD_REQUEST", typeof (message) === "string" ? String(message) : undefined); + return sendApiError( + res, + 400, + "BAD_REQUEST", + typeof message === "string" ? String(message) : undefined, + ); } - return sendApiError(res, 500, "INTERNAL_SERVER_ERROR", "Failed to reload secret key"); + return sendApiError( + res, + 500, + "INTERNAL_SERVER_ERROR", + "Failed to reload secret key", + ); } }); @@ -274,7 +319,12 @@ router.put("/rate-limit", async (req, res) => { ); } catch (err) { console.error("[AdminRateLimit] Failed to persist config.json:", err); - return sendApiError(res, 500, "INTERNAL_SERVER_ERROR", "Rate-limit updated in memory but failed to persist to disk"); + return sendApiError( + res, + 500, + "INTERNAL_SERVER_ERROR", + "Rate-limit updated in memory but failed to persist to disk", + ); } console.info( @@ -312,7 +362,12 @@ router.post("/rate-limit/whitelist/refresh", async (_req, res) => { }); } catch (err) { console.error("[AdminRateLimit] Whitelist refresh failed:", err); - return sendApiError(res, 500, "INTERNAL_SERVER_ERROR", "Failed to refresh whitelist cache"); + return sendApiError( + res, + 500, + "INTERNAL_SERVER_ERROR", + "Failed to refresh whitelist cache", + ); } }); diff --git a/src/routes/assets.ts b/src/routes/assets.ts index b8cd6142..59037af6 100644 --- a/src/routes/assets.ts +++ b/src/routes/assets.ts @@ -3,7 +3,6 @@ import { sendApiError } from "../lib/apiError.js"; import prisma from "../lib/prisma"; import { cacheMiddleware } from "../cache/CacheMiddleware"; import { CACHE_CONFIG, CACHE_KEYS } from "../config/redis.config"; -import prisma from "../lib/prisma"; const router = Router(); @@ -46,24 +45,36 @@ router.get( keyGenerator: () => CACHE_KEYS.assets.all(), }), async (req, res) => { - try { - const assets = await prisma.currency.findMany({ - where: { isActive: true }, - select: { - code: true, - name: true, - symbol: true, - }, - orderBy: { code: "asc" }, - }); + try { + const assets = await prisma.currency.findMany({ + where: { isActive: true }, + select: { + code: true, + name: true, + symbol: true, + }, + orderBy: { code: "asc" }, + }); - res.json({ - success: true, - assets, - }); - } catch (error) { - sendApiError(res, 500, "INTERNAL_SERVER_ERROR", typeof (error instanceof Error ? error.message : "Internal server error") === "string" ? String(error instanceof Error ? error.message : "Internal server error") : undefined); - } -}); + res.json({ + success: true, + assets, + }); + } catch (error) { + sendApiError( + res, + 500, + "INTERNAL_SERVER_ERROR", + typeof (error instanceof Error + ? error.message + : "Internal server error") === "string" + ? String( + error instanceof Error ? error.message : "Internal server error", + ) + : undefined, + ); + } + }, +); export default router; diff --git a/src/utils/winstonLogger.ts b/src/utils/winstonLogger.ts index 37427a59..5b58a1cc 100644 --- a/src/utils/winstonLogger.ts +++ b/src/utils/winstonLogger.ts @@ -3,7 +3,9 @@ import DailyRotateFile from "winston-daily-rotate-file"; import path from "path"; import { fileURLToPath } from "url"; +// eslint-disable-next-line @typescript-eslint/naming-convention const __filename = fileURLToPath(import.meta.url); +// eslint-disable-next-line @typescript-eslint/naming-convention const __dirname = path.dirname(__filename); const logDir = path.resolve(__dirname, "../../logs"); diff --git a/test.ts b/test.ts index b2cb3a27..592fd6ae 100644 --- a/test.ts +++ b/test.ts @@ -6,43 +6,50 @@ * Run with: npx jest gasMonitor.test.ts */ -import { jest, describe, it, expect, beforeEach, afterEach } from "@jest/globals"; +import { + jest, + describe, + it, + expect, + beforeEach, + afterEach, +} from "@jest/globals"; // ─── Mock external modules before imports ──────────────────────────────────── jest.mock("@stellar/stellar-sdk", () => ({ - Keypair: { - fromSecret: jest.fn().mockReturnValue({ - publicKey: () => "GADMIN_WALLET_PUBLIC_KEY", - }), - }, - Horizon: { - Server: jest.fn().mockImplementation(() => ({ - loadAccount: jest.fn(), - root: jest.fn(), - })), - }, + Keypair: { + fromSecret: jest.fn().mockReturnValue({ + publicKey: () => "GADMIN_WALLET_PUBLIC_KEY", + }), + }, + Horizon: { + Server: jest.fn().mockImplementation(() => ({ + loadAccount: jest.fn(), + root: jest.fn(), + })), + }, })); jest.mock("fs", () => ({ - promises: { - writeFile: jest.fn().mockResolvedValue(undefined), - readFile: jest.fn().mockRejectedValue(new Error("File not found")), // No persisted state by default - }, + promises: { + writeFile: jest.fn().mockResolvedValue(undefined), + readFile: jest.fn().mockRejectedValue(new Error("File not found")), // No persisted state by default + }, })); jest.mock("axios", () => ({ - default: { - post: jest.fn().mockResolvedValue({ status: 200 }), - }, + default: { + post: jest.fn().mockResolvedValue({ status: 200 }), + }, })); jest.mock("../utils/retryUtil.js", () => ({ - withRetry: jest.fn().mockImplementation((fn: () => Promise) => fn()), + withRetry: jest.fn().mockImplementation((fn: () => Promise) => fn()), })); jest.mock("../utils/httpTimeout.js", () => ({ - OUTGOING_HTTP_TIMEOUT_MS: 5000, + OUTGOING_HTTP_TIMEOUT_MS: 5000, })); // ─── Imports after mocks ───────────────────────────────────────────────────── @@ -50,459 +57,477 @@ jest.mock("../utils/httpTimeout.js", () => ({ import { promises as fs } from "fs"; import { Horizon } from "@stellar/stellar-sdk"; import axios from "axios"; -import { GasBalanceMonitorService, getGasBalanceMonitorService } from "./gasBalanceMonitorService"; +import { + GasBalanceMonitorService, + getGasBalanceMonitorService, +} from "./gasBalanceMonitorService"; import { WebhookService, getWebhookService } from "./webhook"; // ─── Helpers ───────────────────────────────────────────────────────────────── const mockLoadAccount = (balance: string) => { - const server = new (Horizon.Server as jest.MockedClass)(""); - (server.loadAccount as jest.Mock).mockResolvedValue({ - balances: [{ asset_type: "native", balance }], - }); - return server; + const server = new (Horizon.Server as jest.MockedClass< + typeof Horizon.Server + >)(""); + (server.loadAccount as jest.Mock).mockResolvedValue({ + balances: [{ asset_type: "native", balance }], + }); + return server; }; const mockLoadAccountFailure = () => { - const server = new (Horizon.Server as jest.MockedClass)(""); - (server.loadAccount as jest.Mock).mockRejectedValue(new Error("Horizon unreachable")); - return server; + const server = new (Horizon.Server as jest.MockedClass< + typeof Horizon.Server + >)(""); + (server.loadAccount as jest.Mock).mockRejectedValue( + new Error("Horizon unreachable"), + ); + return server; }; // ─── GasBalanceMonitorService ───────────────────────────────────────────────── describe("GasBalanceMonitorService", () => { - let originalEnv: NodeJS.ProcessEnv; - - beforeEach(() => { - originalEnv = { ...process.env }; - process.env.ORACLE_SECRET_KEY = "STEST_SECRET_KEY"; - process.env.STELLAR_NETWORK = "TESTNET"; - process.env.GAS_BALANCE_ALERT_THRESHOLD_XLM = "20"; - jest.useFakeTimers(); + let originalEnv: NodeJS.ProcessEnv; + + beforeEach(() => { + originalEnv = { ...process.env }; + process.env.ORACLE_SECRET_KEY = "STEST_SECRET_KEY"; + process.env.STELLAR_NETWORK = "TESTNET"; + process.env.GAS_BALANCE_ALERT_THRESHOLD_XLM = "20"; + jest.useFakeTimers(); + }); + + afterEach(() => { + process.env = originalEnv; + jest.useRealTimers(); + jest.clearAllMocks(); + }); + + // ── Lazy singleton ────────────────────────────────────────────────────────── + + describe("Lazy singleton", () => { + it("does not throw at import time when env vars are missing", () => { + delete process.env.ORACLE_SECRET_KEY; + delete process.env.SOROBAN_ADMIN_SECRET; + + // Simply importing the module should not throw + // eslint-disable-next-line @typescript-eslint/no-require-imports + expect(() => require("./gasBalanceMonitorService")).not.toThrow(); + }); + + it("throws only when getGasBalanceMonitorService() is called with missing env vars", () => { + delete process.env.ORACLE_SECRET_KEY; + delete process.env.SOROBAN_ADMIN_SECRET; + + expect(() => getGasBalanceMonitorService()).toThrow( + "Stellar secret key not found in environment variables", + ); + }); + + it("returns the same instance on repeated calls", () => { + const a = getGasBalanceMonitorService(); + const b = getGasBalanceMonitorService(); + expect(a).toBe(b); + }); + }); + + // ── Threshold parsing ─────────────────────────────────────────────────────── + + describe("Threshold parsing", () => { + it("uses the env var threshold when valid", () => { + process.env.GAS_BALANCE_ALERT_THRESHOLD_XLM = "50"; + const service = new GasBalanceMonitorService(); + expect(service.getStatus().balanceThresholdXLM).toBe(50); + }); + + it("falls back to 20 XLM when env var is not a number", () => { + process.env.GAS_BALANCE_ALERT_THRESHOLD_XLM = "abc"; + const service = new GasBalanceMonitorService(); + expect(service.getStatus().balanceThresholdXLM).toBe(20); + }); + + it("falls back to 20 XLM when env var is missing", () => { + delete process.env.GAS_BALANCE_ALERT_THRESHOLD_XLM; + const service = new GasBalanceMonitorService(); + expect(service.getStatus().balanceThresholdXLM).toBe(20); + }); + }); + + // ── Balance check & alerting ──────────────────────────────────────────────── + + describe("Balance check and alerting", () => { + it("does not alert when balance is above threshold", async () => { + const service = new GasBalanceMonitorService(); + const sendAlertSpy = jest + .spyOn(service["webhookService"], "sendGasBalanceAlert") + .mockResolvedValue(undefined); + + (service["server"].loadAccount as jest.Mock).mockResolvedValue({ + balances: [{ asset_type: "native", balance: "50.0000000" }], + }); + + await service["checkBalance"](); + expect(sendAlertSpy).not.toHaveBeenCalled(); + }); + + it("sends alert when balance is below threshold", async () => { + const service = new GasBalanceMonitorService(); + const sendAlertSpy = jest + .spyOn(service["webhookService"], "sendGasBalanceAlert") + .mockResolvedValue(undefined); + + (service["server"].loadAccount as jest.Mock).mockResolvedValue({ + balances: [{ asset_type: "native", balance: "5.0000000" }], + }); + + await service["checkBalance"](); + expect(sendAlertSpy).toHaveBeenCalledWith( + expect.objectContaining({ currentBalance: 5, threshold: 20 }), + ); }); - afterEach(() => { - process.env = originalEnv; - jest.useRealTimers(); - jest.clearAllMocks(); + it("rate-limits alerts to once per hour", async () => { + const service = new GasBalanceMonitorService(); + service["lastAlertTime"] = Date.now(); // Simulate a recent alert + + const sendAlertSpy = jest + .spyOn(service["webhookService"], "sendGasBalanceAlert") + .mockResolvedValue(undefined); + + (service["server"].loadAccount as jest.Mock).mockResolvedValue({ + balances: [{ asset_type: "native", balance: "5.0000000" }], + }); + + await service["checkBalance"](); + expect(sendAlertSpy).not.toHaveBeenCalled(); }); - // ── Lazy singleton ────────────────────────────────────────────────────────── + it("sends alert again after the rate-limit window has passed", async () => { + const service = new GasBalanceMonitorService(); + // Set lastAlertTime to 2 hours ago + service["lastAlertTime"] = Date.now() - 2 * 60 * 60 * 1000; - describe("Lazy singleton", () => { - it("does not throw at import time when env vars are missing", () => { - delete process.env.ORACLE_SECRET_KEY; - delete process.env.SOROBAN_ADMIN_SECRET; + const sendAlertSpy = jest + .spyOn(service["webhookService"], "sendGasBalanceAlert") + .mockResolvedValue(undefined); + + (service["server"].loadAccount as jest.Mock).mockResolvedValue({ + balances: [{ asset_type: "native", balance: "5.0000000" }], + }); + + await service["checkBalance"](); + expect(sendAlertSpy).toHaveBeenCalledTimes(1); + }); + }); - // Simply importing the module should not throw - expect(() => require("./gasBalanceMonitorService")).not.toThrow(); - }); + // ── Retry escalation ──────────────────────────────────────────────────────── - it("throws only when getGasBalanceMonitorService() is called with missing env vars", () => { - delete process.env.ORACLE_SECRET_KEY; - delete process.env.SOROBAN_ADMIN_SECRET; + describe("Retry escalation", () => { + it("increments consecutiveFailures on each Horizon error", async () => { + const service = new GasBalanceMonitorService(); + (service["server"].loadAccount as jest.Mock).mockRejectedValue( + new Error("Horizon unreachable"), + ); - expect(() => getGasBalanceMonitorService()).toThrow( - "Stellar secret key not found in environment variables", - ); - }); + await service["checkBalance"](); + expect(service.getStatus().consecutiveFailures).toBe(1); - it("returns the same instance on repeated calls", () => { - const a = getGasBalanceMonitorService(); - const b = getGasBalanceMonitorService(); - expect(a).toBe(b); - }); + await service["checkBalance"](); + expect(service.getStatus().consecutiveFailures).toBe(2); }); - // ── Threshold parsing ─────────────────────────────────────────────────────── - - describe("Threshold parsing", () => { - it("uses the env var threshold when valid", () => { - process.env.GAS_BALANCE_ALERT_THRESHOLD_XLM = "50"; - const service = new GasBalanceMonitorService(); - expect(service.getStatus().balanceThresholdXLM).toBe(50); - }); - - it("falls back to 20 XLM when env var is not a number", () => { - process.env.GAS_BALANCE_ALERT_THRESHOLD_XLM = "abc"; - const service = new GasBalanceMonitorService(); - expect(service.getStatus().balanceThresholdXLM).toBe(20); - }); - - it("falls back to 20 XLM when env var is missing", () => { - delete process.env.GAS_BALANCE_ALERT_THRESHOLD_XLM; - const service = new GasBalanceMonitorService(); - expect(service.getStatus().balanceThresholdXLM).toBe(20); - }); + it("sends monitor failure alert after 3 consecutive failures and resets counter", async () => { + const service = new GasBalanceMonitorService(); + const failureAlertSpy = jest + .spyOn(service["webhookService"], "sendMonitorFailureAlert") + .mockResolvedValue(undefined); + + (service["server"].loadAccount as jest.Mock).mockRejectedValue( + new Error("Horizon unreachable"), + ); + + await service["checkBalance"](); + await service["checkBalance"](); + await service["checkBalance"](); // 3rd failure — should escalate + + expect(failureAlertSpy).toHaveBeenCalledTimes(1); + expect(failureAlertSpy).toHaveBeenCalledWith( + expect.objectContaining({ consecutiveFailures: 3 }), + ); + // Counter resets after escalation + expect(service.getStatus().consecutiveFailures).toBe(0); + }); + + it("resets consecutiveFailures on a successful check", async () => { + const service = new GasBalanceMonitorService(); + (service["server"].loadAccount as jest.Mock).mockRejectedValue( + new Error("Horizon unreachable"), + ); + + await service["checkBalance"](); + await service["checkBalance"](); + expect(service.getStatus().consecutiveFailures).toBe(2); + + // Now recover + (service["server"].loadAccount as jest.Mock).mockResolvedValue({ + balances: [{ asset_type: "native", balance: "50.0000000" }], + }); + + await service["checkBalance"](); + expect(service.getStatus().consecutiveFailures).toBe(0); }); + }); + + // ── Persisted alert time ──────────────────────────────────────────────────── + + describe("Persisted alert time", () => { + it("writes lastAlertTime to disk after sending an alert", async () => { + const service = new GasBalanceMonitorService(); + jest + .spyOn(service["webhookService"], "sendGasBalanceAlert") + .mockResolvedValue(undefined); + + (service["server"].loadAccount as jest.Mock).mockResolvedValue({ + balances: [{ asset_type: "native", balance: "5.0000000" }], + }); + + await service["checkBalance"](); + expect(fs.writeFile).toHaveBeenCalledWith( + "/tmp/gas_balance_last_alert_time.json", + expect.stringContaining("lastAlertTime"), + "utf-8", + ); + }); + + it("restores lastAlertTime from disk on start", async () => { + const savedTime = Date.now() - 30 * 60 * 1000; // 30 minutes ago + (fs.readFile as jest.Mock).mockResolvedValueOnce( + JSON.stringify({ lastAlertTime: savedTime }), + ); + + const service = new GasBalanceMonitorService(); + // Mock loadAccount so start() doesn't error + (service["server"].loadAccount as jest.Mock).mockResolvedValue({ + balances: [{ asset_type: "native", balance: "50.0000000" }], + }); - // ── Balance check & alerting ──────────────────────────────────────────────── - - describe("Balance check and alerting", () => { - it("does not alert when balance is above threshold", async () => { - const service = new GasBalanceMonitorService(); - const sendAlertSpy = jest - .spyOn(service["webhookService"], "sendGasBalanceAlert") - .mockResolvedValue(undefined); - - (service["server"].loadAccount as jest.Mock).mockResolvedValue({ - balances: [{ asset_type: "native", balance: "50.0000000" }], - }); - - await service["checkBalance"](); - expect(sendAlertSpy).not.toHaveBeenCalled(); - }); - - it("sends alert when balance is below threshold", async () => { - const service = new GasBalanceMonitorService(); - const sendAlertSpy = jest - .spyOn(service["webhookService"], "sendGasBalanceAlert") - .mockResolvedValue(undefined); - - (service["server"].loadAccount as jest.Mock).mockResolvedValue({ - balances: [{ asset_type: "native", balance: "5.0000000" }], - }); - - await service["checkBalance"](); - expect(sendAlertSpy).toHaveBeenCalledWith( - expect.objectContaining({ currentBalance: 5, threshold: 20 }), - ); - }); - - it("rate-limits alerts to once per hour", async () => { - const service = new GasBalanceMonitorService(); - service["lastAlertTime"] = Date.now(); // Simulate a recent alert - - const sendAlertSpy = jest - .spyOn(service["webhookService"], "sendGasBalanceAlert") - .mockResolvedValue(undefined); - - (service["server"].loadAccount as jest.Mock).mockResolvedValue({ - balances: [{ asset_type: "native", balance: "5.0000000" }], - }); - - await service["checkBalance"](); - expect(sendAlertSpy).not.toHaveBeenCalled(); - }); - - it("sends alert again after the rate-limit window has passed", async () => { - const service = new GasBalanceMonitorService(); - // Set lastAlertTime to 2 hours ago - service["lastAlertTime"] = Date.now() - 2 * 60 * 60 * 1000; - - const sendAlertSpy = jest - .spyOn(service["webhookService"], "sendGasBalanceAlert") - .mockResolvedValue(undefined); - - (service["server"].loadAccount as jest.Mock).mockResolvedValue({ - balances: [{ asset_type: "native", balance: "5.0000000" }], - }); - - await service["checkBalance"](); - expect(sendAlertSpy).toHaveBeenCalledTimes(1); - }); + await service["loadLastAlertTime"](); + expect(service["lastAlertTime"]).toBe(savedTime); }); - // ── Retry escalation ──────────────────────────────────────────────────────── - - describe("Retry escalation", () => { - it("increments consecutiveFailures on each Horizon error", async () => { - const service = new GasBalanceMonitorService(); - (service["server"].loadAccount as jest.Mock).mockRejectedValue( - new Error("Horizon unreachable"), - ); - - await service["checkBalance"](); - expect(service.getStatus().consecutiveFailures).toBe(1); - - await service["checkBalance"](); - expect(service.getStatus().consecutiveFailures).toBe(2); - }); - - it("sends monitor failure alert after 3 consecutive failures and resets counter", async () => { - const service = new GasBalanceMonitorService(); - const failureAlertSpy = jest - .spyOn(service["webhookService"], "sendMonitorFailureAlert") - .mockResolvedValue(undefined); - - (service["server"].loadAccount as jest.Mock).mockRejectedValue( - new Error("Horizon unreachable"), - ); - - await service["checkBalance"](); - await service["checkBalance"](); - await service["checkBalance"](); // 3rd failure — should escalate - - expect(failureAlertSpy).toHaveBeenCalledTimes(1); - expect(failureAlertSpy).toHaveBeenCalledWith( - expect.objectContaining({ consecutiveFailures: 3 }), - ); - // Counter resets after escalation - expect(service.getStatus().consecutiveFailures).toBe(0); - }); - - it("resets consecutiveFailures on a successful check", async () => { - const service = new GasBalanceMonitorService(); - (service["server"].loadAccount as jest.Mock).mockRejectedValue( - new Error("Horizon unreachable"), - ); - - await service["checkBalance"](); - await service["checkBalance"](); - expect(service.getStatus().consecutiveFailures).toBe(2); - - // Now recover - (service["server"].loadAccount as jest.Mock).mockResolvedValue({ - balances: [{ asset_type: "native", balance: "50.0000000" }], - }); - - await service["checkBalance"](); - expect(service.getStatus().consecutiveFailures).toBe(0); - }); + it("starts fresh if persisted file is missing", async () => { + (fs.readFile as jest.Mock).mockRejectedValueOnce(new Error("ENOENT")); + const service = new GasBalanceMonitorService(); + await service["loadLastAlertTime"](); + expect(service["lastAlertTime"]).toBe(0); }); + }); - // ── Persisted alert time ──────────────────────────────────────────────────── - - describe("Persisted alert time", () => { - it("writes lastAlertTime to disk after sending an alert", async () => { - const service = new GasBalanceMonitorService(); - jest - .spyOn(service["webhookService"], "sendGasBalanceAlert") - .mockResolvedValue(undefined); - - (service["server"].loadAccount as jest.Mock).mockResolvedValue({ - balances: [{ asset_type: "native", balance: "5.0000000" }], - }); - - await service["checkBalance"](); - expect(fs.writeFile).toHaveBeenCalledWith( - "/tmp/gas_balance_last_alert_time.json", - expect.stringContaining("lastAlertTime"), - "utf-8", - ); - }); - - it("restores lastAlertTime from disk on start", async () => { - const savedTime = Date.now() - 30 * 60 * 1000; // 30 minutes ago - (fs.readFile as jest.Mock).mockResolvedValueOnce( - JSON.stringify({ lastAlertTime: savedTime }), - ); - - const service = new GasBalanceMonitorService(); - // Mock loadAccount so start() doesn't error - (service["server"].loadAccount as jest.Mock).mockResolvedValue({ - balances: [{ asset_type: "native", balance: "50.0000000" }], - }); - - await service["loadLastAlertTime"](); - expect(service["lastAlertTime"]).toBe(savedTime); - }); - - it("starts fresh if persisted file is missing", async () => { - (fs.readFile as jest.Mock).mockRejectedValueOnce(new Error("ENOENT")); - const service = new GasBalanceMonitorService(); - await service["loadLastAlertTime"](); - expect(service["lastAlertTime"]).toBe(0); - }); + // ── Stop behaviour ────────────────────────────────────────────────────────── + + describe("Stop behaviour", () => { + it("clears lastKnownBalance on stop", async () => { + const service = new GasBalanceMonitorService(); + service["lastKnownBalance"] = 42; + service.stop(); + expect(service.getStatus().lastKnownBalance).toBeNull(); }); - // ── Stop behaviour ────────────────────────────────────────────────────────── - - describe("Stop behaviour", () => { - it("clears lastKnownBalance on stop", async () => { - const service = new GasBalanceMonitorService(); - service["lastKnownBalance"] = 42; - service.stop(); - expect(service.getStatus().lastKnownBalance).toBeNull(); - }); - - it("sets isRunning to false on stop", () => { - const service = new GasBalanceMonitorService(); - service["isRunning"] = true; - service.stop(); - expect(service.getStatus().isRunning).toBe(false); - }); + it("sets isRunning to false on stop", () => { + const service = new GasBalanceMonitorService(); + service["isRunning"] = true; + service.stop(); + expect(service.getStatus().isRunning).toBe(false); + }); + }); + + // ── Debug gating ──────────────────────────────────────────────────────────── + + describe("Debug log gating", () => { + it("does not log balance when DEBUG is not set", async () => { + delete process.env.DEBUG; + const service = new GasBalanceMonitorService(); + const debugSpy = jest + .spyOn(console, "debug") + .mockImplementation(() => {}); + + (service["server"].loadAccount as jest.Mock).mockResolvedValue({ + balances: [{ asset_type: "native", balance: "50.0000000" }], + }); + + await service["checkBalance"](); + expect(debugSpy).not.toHaveBeenCalledWith( + expect.stringContaining("Admin wallet balance"), + ); + debugSpy.mockRestore(); }); - // ── Debug gating ──────────────────────────────────────────────────────────── - - describe("Debug log gating", () => { - it("does not log balance when DEBUG is not set", async () => { - delete process.env.DEBUG; - const service = new GasBalanceMonitorService(); - const debugSpy = jest.spyOn(console, "debug").mockImplementation(() => { }); - - (service["server"].loadAccount as jest.Mock).mockResolvedValue({ - balances: [{ asset_type: "native", balance: "50.0000000" }], - }); - - await service["checkBalance"](); - expect(debugSpy).not.toHaveBeenCalledWith( - expect.stringContaining("Admin wallet balance"), - ); - debugSpy.mockRestore(); - }); - - it("logs balance when DEBUG is set", async () => { - process.env.DEBUG = "true"; - const service = new GasBalanceMonitorService(); - const debugSpy = jest.spyOn(console, "debug").mockImplementation(() => { }); - - (service["server"].loadAccount as jest.Mock).mockResolvedValue({ - balances: [{ asset_type: "native", balance: "50.0000000" }], - }); - - await service["checkBalance"](); - expect(debugSpy).toHaveBeenCalledWith( - expect.stringContaining("Admin wallet balance"), - ); - debugSpy.mockRestore(); - }); + it("logs balance when DEBUG is set", async () => { + process.env.DEBUG = "true"; + const service = new GasBalanceMonitorService(); + const debugSpy = jest + .spyOn(console, "debug") + .mockImplementation(() => {}); + + (service["server"].loadAccount as jest.Mock).mockResolvedValue({ + balances: [{ asset_type: "native", balance: "50.0000000" }], + }); + + await service["checkBalance"](); + expect(debugSpy).toHaveBeenCalledWith( + expect.stringContaining("Admin wallet balance"), + ); + debugSpy.mockRestore(); }); + }); }); // ─── WebhookService ─────────────────────────────────────────────────────────── describe("WebhookService", () => { - let originalEnv: NodeJS.ProcessEnv; + let originalEnv: NodeJS.ProcessEnv; + + beforeEach(() => { + originalEnv = { ...process.env }; + process.env.SLACK_WEBHOOK_URL = "https://hooks.slack.com/test"; + jest.clearAllMocks(); + }); - beforeEach(() => { - originalEnv = { ...process.env }; - process.env.SLACK_WEBHOOK_URL = "https://hooks.slack.com/test"; - jest.clearAllMocks(); + afterEach(() => { + process.env = originalEnv; + }); + + // ── Lazy singleton ────────────────────────────────────────────────────────── + + describe("Lazy singleton", () => { + it("returns the same instance on repeated calls", () => { + const a = getWebhookService(); + const b = getWebhookService(); + expect(a).toBe(b); + }); + }); + + // ── Gas balance alert formatting ──────────────────────────────────────────── + + describe("formatGasBalanceAlert", () => { + const alertDetails = { + currentBalance: 5.5, + threshold: 20, + timestamp: new Date("2026-01-01T00:00:00Z"), + }; + + it("returns Slack blocks when NOTIFICATION_PLATFORM=slack", () => { + process.env.NOTIFICATION_PLATFORM = "slack"; + const service = new WebhookService(); + const result = service["formatGasBalanceAlert"](alertDetails) as any; + + expect(result.blocks).toBeDefined(); + expect(result.embeds).toBeUndefined(); + // Check key fields are present in Slack payload + const allText = JSON.stringify(result.blocks); + expect(allText).toContain("5.50 XLM"); + expect(allText).toContain("20 XLM"); + expect(allText).toContain("14.50 XLM"); // deficit }); - afterEach(() => { - process.env = originalEnv; + it("returns Discord embed when NOTIFICATION_PLATFORM=discord", () => { + process.env.NOTIFICATION_PLATFORM = "discord"; + const service = new WebhookService(); + const result = service["formatGasBalanceAlert"](alertDetails) as any; + + expect(result.embeds).toBeDefined(); + expect(result.blocks).toBeUndefined(); + expect(result.embeds[0].color).toBe(0xff0000); + const allText = JSON.stringify(result.embeds); + expect(allText).toContain("5.50 XLM"); + expect(allText).toContain("14.50 XLM"); // deficit }); - // ── Lazy singleton ────────────────────────────────────────────────────────── + it("omits wallet address field when not provided", () => { + process.env.NOTIFICATION_PLATFORM = "discord"; + const service = new WebhookService(); + const result = service["formatGasBalanceAlert"](alertDetails) as any; + const allText = JSON.stringify(result); + expect(allText).not.toContain("Wallet Address"); + }); - describe("Lazy singleton", () => { - it("returns the same instance on repeated calls", () => { - const a = getWebhookService(); - const b = getWebhookService(); - expect(a).toBe(b); - }); + it("includes truncated wallet address when provided", () => { + process.env.NOTIFICATION_PLATFORM = "discord"; + const service = new WebhookService(); + const result = service["formatGasBalanceAlert"]({ + ...alertDetails, + walletAddress: "GADMIN_WALLET_PUBLIC_KEY_FULL", + }) as any; + const allText = JSON.stringify(result); + expect(allText).toContain("Wallet Address"); + expect(allText).toContain("..."); + }); + }); + + // ── Monitor failure alert formatting ──────────────────────────────────────── + + describe("formatMonitorFailureAlert", () => { + const failureDetails = { + consecutiveFailures: 3, + lastKnownBalance: 12.5, + timestamp: new Date("2026-01-01T00:00:00Z"), + }; + + it("returns Slack blocks when NOTIFICATION_PLATFORM=slack", () => { + process.env.NOTIFICATION_PLATFORM = "slack"; + const service = new WebhookService(); + const result = service["formatMonitorFailureAlert"]( + failureDetails, + ) as any; + + expect(result.blocks).toBeDefined(); + expect(result.embeds).toBeUndefined(); + const allText = JSON.stringify(result.blocks); + expect(allText).toContain("3"); + expect(allText).toContain("12.50 XLM"); }); - // ── Gas balance alert formatting ──────────────────────────────────────────── - - describe("formatGasBalanceAlert", () => { - const alertDetails = { - currentBalance: 5.5, - threshold: 20, - timestamp: new Date("2026-01-01T00:00:00Z"), - }; - - it("returns Slack blocks when NOTIFICATION_PLATFORM=slack", () => { - process.env.NOTIFICATION_PLATFORM = "slack"; - const service = new WebhookService(); - const result = service["formatGasBalanceAlert"](alertDetails) as any; - - expect(result.blocks).toBeDefined(); - expect(result.embeds).toBeUndefined(); - // Check key fields are present in Slack payload - const allText = JSON.stringify(result.blocks); - expect(allText).toContain("5.50 XLM"); - expect(allText).toContain("20 XLM"); - expect(allText).toContain("14.50 XLM"); // deficit - }); - - it("returns Discord embed when NOTIFICATION_PLATFORM=discord", () => { - process.env.NOTIFICATION_PLATFORM = "discord"; - const service = new WebhookService(); - const result = service["formatGasBalanceAlert"](alertDetails) as any; - - expect(result.embeds).toBeDefined(); - expect(result.blocks).toBeUndefined(); - expect(result.embeds[0].color).toBe(0xff0000); - const allText = JSON.stringify(result.embeds); - expect(allText).toContain("5.50 XLM"); - expect(allText).toContain("14.50 XLM"); // deficit - }); - - it("omits wallet address field when not provided", () => { - process.env.NOTIFICATION_PLATFORM = "discord"; - const service = new WebhookService(); - const result = service["formatGasBalanceAlert"](alertDetails) as any; - const allText = JSON.stringify(result); - expect(allText).not.toContain("Wallet Address"); - }); - - it("includes truncated wallet address when provided", () => { - process.env.NOTIFICATION_PLATFORM = "discord"; - const service = new WebhookService(); - const result = service["formatGasBalanceAlert"]({ - ...alertDetails, - walletAddress: "GADMIN_WALLET_PUBLIC_KEY_FULL", - }) as any; - const allText = JSON.stringify(result); - expect(allText).toContain("Wallet Address"); - expect(allText).toContain("..."); - }); + it("returns Discord embed when NOTIFICATION_PLATFORM=discord", () => { + process.env.NOTIFICATION_PLATFORM = "discord"; + const service = new WebhookService(); + const result = service["formatMonitorFailureAlert"]( + failureDetails, + ) as any; + + expect(result.embeds).toBeDefined(); + expect(result.blocks).toBeUndefined(); + expect(result.embeds[0].color).toBe(0xff0000); + const allText = JSON.stringify(result.embeds); + expect(allText).toContain("12.50 XLM"); }); - // ── Monitor failure alert formatting ──────────────────────────────────────── - - describe("formatMonitorFailureAlert", () => { - const failureDetails = { - consecutiveFailures: 3, - lastKnownBalance: 12.5, - timestamp: new Date("2026-01-01T00:00:00Z"), - }; - - it("returns Slack blocks when NOTIFICATION_PLATFORM=slack", () => { - process.env.NOTIFICATION_PLATFORM = "slack"; - const service = new WebhookService(); - const result = service["formatMonitorFailureAlert"](failureDetails) as any; - - expect(result.blocks).toBeDefined(); - expect(result.embeds).toBeUndefined(); - const allText = JSON.stringify(result.blocks); - expect(allText).toContain("3"); - expect(allText).toContain("12.50 XLM"); - }); - - it("returns Discord embed when NOTIFICATION_PLATFORM=discord", () => { - process.env.NOTIFICATION_PLATFORM = "discord"; - const service = new WebhookService(); - const result = service["formatMonitorFailureAlert"](failureDetails) as any; - - expect(result.embeds).toBeDefined(); - expect(result.blocks).toBeUndefined(); - expect(result.embeds[0].color).toBe(0xff0000); - const allText = JSON.stringify(result.embeds); - expect(allText).toContain("12.50 XLM"); - }); - - it("shows Unknown when lastKnownBalance is null", () => { - process.env.NOTIFICATION_PLATFORM = "slack"; - const service = new WebhookService(); - const result = service["formatMonitorFailureAlert"]({ - ...failureDetails, - lastKnownBalance: null, - }) as any; - expect(JSON.stringify(result)).toContain("Unknown"); - }); + it("shows Unknown when lastKnownBalance is null", () => { + process.env.NOTIFICATION_PLATFORM = "slack"; + const service = new WebhookService(); + const result = service["formatMonitorFailureAlert"]({ + ...failureDetails, + lastKnownBalance: null, + }) as any; + expect(JSON.stringify(result)).toContain("Unknown"); }); + }); - // ── No webhook URL ────────────────────────────────────────────────────────── + // ── No webhook URL ────────────────────────────────────────────────────────── - describe("Missing webhook URL", () => { - it("does not call axios when no webhook URL is configured", async () => { - delete process.env.SLACK_WEBHOOK_URL; - delete process.env.DISCORD_WEBHOOK_URL; - const service = new WebhookService(); + describe("Missing webhook URL", () => { + it("does not call axios when no webhook URL is configured", async () => { + delete process.env.SLACK_WEBHOOK_URL; + delete process.env.DISCORD_WEBHOOK_URL; + const service = new WebhookService(); - await service.sendGasBalanceAlert({ - currentBalance: 5, - threshold: 20, - timestamp: new Date(), - }); + await service.sendGasBalanceAlert({ + currentBalance: 5, + threshold: 20, + timestamp: new Date(), + }); - expect(axios.post).not.toHaveBeenCalled(); - }); + expect(axios.post).not.toHaveBeenCalled(); }); + }); }); diff --git a/test/intelligence.test.ts b/test/intelligence.test.ts index 182f6d2d..3bf45bcb 100644 --- a/test/intelligence.test.ts +++ b/test/intelligence.test.ts @@ -46,7 +46,7 @@ const mockPrisma = { // For this test, I'll create a subclass that overrides the prisma dependency. class TestableIntelligenceService extends IntelligenceService { - // @ts-ignore + // @ts-expect-error — overriding private prisma for testing private prisma = mockPrisma; // Override method to use mock prisma @@ -56,7 +56,7 @@ class TestableIntelligenceService extends IntelligenceService { const oneDayAgo = new Date(now.getTime() - 24 * 60 * 60 * 1000); try { - // @ts-ignore + // @ts-expect-error — overriding private prisma for testing const latestRecord = await this.prisma.priceHistory.findFirst({ where: { currency: asset }, orderBy: { timestamp: "desc" }, @@ -64,7 +64,7 @@ class TestableIntelligenceService extends IntelligenceService { if (!latestRecord) return "0.0%"; - // @ts-ignore + // @ts-expect-error — overriding private prisma for testing const historicalRecord = await this.prisma.priceHistory.findFirst({ where: { currency: asset, timestamp: { lte: oneDayAgo } }, orderBy: { timestamp: "desc" },