From a8e98bebe189411dbf39590e8e8f90f8834335e5 Mon Sep 17 00:00:00 2001 From: Samuel Manzanera Date: Tue, 14 May 2024 16:14:37 +0200 Subject: [PATCH] Add page to list the refundable HTLCs --- analytics/index.js | 2 + analytics/src/controllers/refunds.js | 98 ++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 analytics/src/controllers/refunds.js diff --git a/analytics/index.js b/analytics/index.js index 5a68178..fd5072d 100644 --- a/analytics/index.js +++ b/analytics/index.js @@ -8,6 +8,7 @@ import Debug from "debug"; import { tick as tickArchethic } from "./src/archethic.js"; import { tick as tickEVM } from "./src/evm.js"; import htlcsController from "./src/controllers/htlcs.js"; +import refundsController from "./src/controllers/refunds.js"; const debug = Debug("server"); const ENDPOINT = config.get("archethic.endpoint"); @@ -33,6 +34,7 @@ app.set("views", "./src/views"); app.set("view engine", "jade"); app.get("/htlcs", htlcsController(db)); +app.get("/refunds", refundsController(db)); app.get("/metrics", (req, res) => { let text = ""; diff --git a/analytics/src/controllers/refunds.js b/analytics/src/controllers/refunds.js new file mode 100644 index 0000000..5fd349d --- /dev/null +++ b/analytics/src/controllers/refunds.js @@ -0,0 +1,98 @@ +import { getHTLCs as getEVMHTLCs } from "../registry/evm-htlcs.js"; +import { getHTLCs as getArchethicHtlcs } from "../registry/archethic-htlcs.js"; +import { HTLC_STATUS } from "../archethic/get-htlc-statuses.js"; +import config from "config"; + +const ARCHETHIC_ENDPOINT = config.get("archethic.endpoint"); +const EVM_NETWORKS = config.get("evm"); + +export default function (db) { + return async (req, res) => { + const chargeableHTLCs = filterRefund(merge( + await getArchethicHtlcs(db, "chargeable"), + await getEVMHTLCs(db, "chargeable"), + "chargeable", + )); + + const signedHTLCs = filterRefund(merge( + await getArchethicHtlcs(db, "signed"), + await getEVMHTLCs(db, "signed"), + "signed", + )); + + const htlcs = [...chargeableHTLCs, ...signedHTLCs]; + + res.json(htlcs.map((htlc) => { + if (htlc.type == "chargeable") { + return { archethicAddress: htlc.address, claimingAmount: htlc.amount / 100_000_000, type: htlc.type } + } + else { + return { evmAddress: htlc.evmHtlc.address, chain: htlc.evmHtlc.chain, claimingAmount: htlc.evmHtlc.amount, type: htlc.type } + } + })); + }; +} + +function merge(archethicHtlcs, evmHtlcs, type) { + // dump mumbai + archethicHtlcs = archethicHtlcs.filter((htlc) => htlc.evmChainID != 80001); + + let evmHtlcsToDiscard = []; + + // match HTLCs (best effort) + for (const archethicHtlc of archethicHtlcs) { + archethicHtlc.type = type; + if (archethicHtlc.evmContract) { + const match = evmHtlcs.find( + (evmHtlc) => + evmHtlc.address.toLowerCase() == + archethicHtlc.evmContract.toLowerCase(), + ); + if (match != null) { + archethicHtlc.evmHtlc = match; + evmHtlcsToDiscard.push(archethicHtlc.evmHtlc.address); + } + } else { + // try to match based on the secrethash + if (archethicHtlc.secretHash) { + const match = evmHtlcs.find((evmHtlc) => { + // secrethash is not set on chargeable + if (evmHtlc.secretHash) { + console.log( + evmHtlc.secretHash.toLowerCase(), + archethicHtlc.secretHash.toLowerCase(), + ); + return ( + evmHtlc.secretHash.toLowerCase() == + archethicHtlc.secretHash.toLowerCase() + ); + } else { + return false; + } + }); + if (match != null) { + archethicHtlc.evmHtlc = match; + evmHtlcsToDiscard.push(archethicHtlc.evmHtlc.address); + } + } + } + } + + // evm HTLCs with no match in archethic + for (const evmHtlc of evmHtlcs) { + if (evmHtlcsToDiscard.includes(evmHtlc.address)) continue; + + archethicHtlcs.push({ evmHtlc: evmHtlc }); + } + return archethicHtlcs; +} + +function filterRefund(htlcs) { + return htlcs.filter((htlc) => { + if (!htlc.evmHtlc || !htlc.creationTime) { + return false + } + + return (htlc.evmHtlc.status == "REFUNDED" && htlc.status != 2) || (htlc.status == 2 && htlc.evmHtlc.status != "REFUNDED") + }) +}