Files
smom-dbis-138/services/checkpoint-aggregator/dist/index.js
defiQUG c336809676
Some checks failed
CI/CD Pipeline / Solidity Contracts (push) Failing after 1m3s
CI/CD Pipeline / Security Scanning (push) Successful in 2m18s
CI/CD Pipeline / Lint and Format (push) Failing after 34s
CI/CD Pipeline / Terraform Validation (push) Failing after 20s
CI/CD Pipeline / Kubernetes Validation (push) Successful in 22s
Deploy ChainID 138 / Deploy ChainID 138 (push) Failing after 40s
HYBX OMNL TypeScript & anchor / token-aggregation build + reconcile artifact (push) Failing after 49s
OMNL reconcile anchor / Run omnl:reconcile and upload artifacts (push) Failing after 21s
Validation / validate-genesis (push) Successful in 25s
Validation / validate-terraform (push) Failing after 21s
Validation / validate-kubernetes (push) Failing after 8s
Validation / validate-smart-contracts (push) Failing after 8s
Validation / validate-security (push) Failing after 1m11s
Validation / validate-documentation (push) Failing after 14s
Verify Deployment / Verify Deployment (push) Failing after 45s
Add mainnet checkpoint stack: ISO attestation, participant Etherscan surface, and services.
Ship AddressActivityRegistry V1/V2, ISO20022IntakeGateway, Chain138ParticipantSurface,
checkpoint hub contracts, checkpoint-core package, aggregator/indexer/sdk services,
relay profile guards, M00 diamond bridge facet, and OMNL compliance contracts.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-25 00:30:45 -07:00

373 lines
18 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const ethers_1 = require("ethers");
const config_1 = require("./config");
const eip712_1 = require("./eip712");
const ipfs_1 = require("./ipfs");
const blockscout_1 = require("./blockscout");
const usdEnrich_1 = require("./usdEnrich");
const scanState_1 = require("./scanState");
const checkpoint_core_1 = require("@dbis/checkpoint-core");
const leafCodec_1 = require("./leafCodec");
const adminIngress_1 = require("./ingress/adminIngress");
const dualMirror_1 = require("./dualMirror");
const activityRegistry_1 = require("./activityRegistry");
const activityRegistryV2_1 = require("./activityRegistryV2");
const iso20022Enrich_1 = require("./iso20022Enrich");
const iso20022LocalStore_1 = require("./iso20022LocalStore");
const participantSurface_1 = require("./participantSurface");
const receiptsRoot_1 = require("./receiptsRoot");
(0, config_1.assertAggregatorConfig)();
const BLOCK_ORACLE_ABI = ['function setBlockHeader(uint256,bytes32,bytes32) external'];
class CheckpointAggregator {
chain138;
mainnetWallet;
checkpoint;
ingress;
blockOracle;
buffer = [];
nextBatchId = 1n;
hubImplVersion = 3n;
flushTimer;
scanning = false;
includedTxCache = new Map();
constructor() {
const mainnet = new ethers_1.ethers.JsonRpcProvider(config_1.checkpointAggregatorConfig.mainnetRpc);
this.mainnetWallet = new ethers_1.ethers.Wallet(process.env.PRIVATE_KEY, mainnet);
this.checkpoint = (0, adminIngress_1.buildCheckpointContract)(this.mainnetWallet, config_1.checkpointAggregatorConfig.checkpointProxy, config_1.checkpointAggregatorConfig.submitMode);
this.ingress = new adminIngress_1.AdminCheckpointIngress(this.checkpoint, config_1.checkpointAggregatorConfig.submitMode);
this.chain138 = new ethers_1.ethers.JsonRpcProvider(config_1.checkpointAggregatorConfig.chain138Rpc);
if (config_1.checkpointAggregatorConfig.blockOracleExtension) {
this.blockOracle = new ethers_1.ethers.Contract(config_1.checkpointAggregatorConfig.blockOracleExtension, BLOCK_ORACLE_ABI, this.mainnetWallet);
}
}
async start() {
await this.syncBatchId();
const state = (0, scanState_1.loadScanState)(config_1.checkpointAggregatorConfig.scanStatePath, config_1.checkpointAggregatorConfig.scanFromBlock);
console.log(`Checkpoint aggregator mode=${config_1.checkpointAggregatorConfig.submitMode} batch=${config_1.checkpointAggregatorConfig.batchSize} nextBatchId=${this.nextBatchId} impl=${this.hubImplVersion} blockscout=${config_1.checkpointAggregatorConfig.useBlockscout} emitter=${config_1.checkpointAggregatorConfig.batchEmitter138 || 'n/a'}`);
this.schedulePartialFlush();
await this.runScanLoop(state);
}
async syncBatchId() {
const latest = await this.checkpoint.getLatestBatchId();
this.nextBatchId = latest > 0n ? BigInt(latest) + 1n : 1n;
try {
this.hubImplVersion = await this.checkpoint.IMPLEMENTATION_VERSION();
}
catch {
this.hubImplVersion = 3n;
}
}
schedulePartialFlush() {
if (this.flushTimer)
clearTimeout(this.flushTimer);
this.flushTimer = setTimeout(() => this.flush(true), config_1.checkpointAggregatorConfig.maxWaitMs);
}
async runScanLoop(initialState) {
const state = { ...initialState };
for (;;) {
try {
await this.scanCatchUp(state);
}
catch (e) {
console.error('scanCatchUp', e);
}
await new Promise((r) => setTimeout(r, config_1.checkpointAggregatorConfig.scanPollMs));
}
}
async scanCatchUp(state) {
if (this.scanning)
return;
this.scanning = true;
try {
const head = await this.chain138.getBlockNumber();
const safeHead = head - config_1.checkpointAggregatorConfig.confirmationBlocks;
let from = state.lastScannedBlock + 1;
while (from <= safeHead) {
const to = Math.min(from + config_1.checkpointAggregatorConfig.scanChunkBlocks - 1, safeHead);
let added = 0;
if (config_1.checkpointAggregatorConfig.useBlockscout) {
added = await this.scanBlockscoutRange(from, to);
}
else {
for (let b = from; b <= to; b++)
added += await this.scanBlockRpc(b);
}
state.lastScannedBlock = to;
(0, scanState_1.saveScanState)(config_1.checkpointAggregatorConfig.scanStatePath, state);
console.log(`Scanned blocks ${from}-${to} (+${added} txs) buffer=${this.buffer.length}`);
from = to + 1;
}
}
finally {
this.scanning = false;
}
}
async scanBlockscoutRange(from, to) {
const txs = await (0, blockscout_1.fetchTransactionsInBlockRange)(config_1.checkpointAggregatorConfig.blockscoutApi, from, to);
let added = 0;
for (const tx of txs) {
if (await this.txAlreadyIncluded(tx.hash))
continue;
const receipt = await this.chain138.getTransactionReceipt(tx.hash);
const leaf = {
txHash: tx.hash,
from: tx.from,
to: tx.to,
value: tx.value,
blockNumber: tx.blockNumber,
blockTimestamp: tx.blockTimestamp,
gasUsed: receipt?.gasUsed ?? 0n,
success: receipt?.status === 1,
};
await this.enrichLeafFromBlockscout(leaf);
if ((0, leafCodec_1.effectiveValue)(leaf) < config_1.checkpointAggregatorConfig.minValueWei)
continue;
this.buffer.push(leaf);
added++;
if (this.buffer.length >= config_1.checkpointAggregatorConfig.batchSize)
await this.flush(false);
}
return added;
}
async scanBlockRpc(blockNumber) {
const block = await this.chain138.getBlock(blockNumber, true);
if (!block)
return 0;
let added = 0;
const entries = block.prefetchedTransactions?.length
? block.prefetchedTransactions
: block.transactions ?? [];
for (const entry of entries) {
const tx = typeof entry === 'string' ? await this.chain138.getTransaction(entry) : entry;
if (!tx || typeof tx === 'string')
continue;
const value = tx.value ?? 0n;
if (await this.txAlreadyIncluded(tx.hash))
continue;
const receipt = await this.chain138.getTransactionReceipt(tx.hash);
const leaf = {
txHash: tx.hash,
from: tx.from,
to: tx.to ?? ethers_1.ethers.ZeroAddress,
value,
blockNumber,
blockTimestamp: block.timestamp,
gasUsed: receipt?.gasUsed ?? 0n,
success: receipt?.status === 1,
};
await this.enrichLeafFromBlockscout(leaf);
if ((0, leafCodec_1.effectiveValue)(leaf) < config_1.checkpointAggregatorConfig.minValueWei)
continue;
this.buffer.push(leaf);
added++;
if (this.buffer.length >= config_1.checkpointAggregatorConfig.batchSize)
await this.flush(false);
}
return added;
}
async enrichLeafFromBlockscout(leaf) {
const { allErc20 } = await (0, usdEnrich_1.enrichLeafFromBlockscoutApi)(leaf, config_1.checkpointAggregatorConfig.blockscoutApi, config_1.checkpointAggregatorConfig.useBlockscout);
await (0, usdEnrich_1.enrichLeafUsd)(leaf, {
apiBaseUrl: config_1.checkpointAggregatorConfig.tokenAggregationApiUrl,
chainId: 138,
enabled: config_1.checkpointAggregatorConfig.usdEnrichEnabled,
requestDelayMs: config_1.checkpointAggregatorConfig.usdRequestDelayMs,
blockscoutApi: config_1.checkpointAggregatorConfig.blockscoutApi,
useBlockscout: config_1.checkpointAggregatorConfig.useBlockscout,
}, allErc20);
}
async txAlreadyIncluded(txHash) {
const cached = this.includedTxCache.get(txHash);
if (cached !== undefined)
return cached;
try {
const [included] = await this.checkpoint.isTxIncluded(txHash);
this.includedTxCache.set(txHash, included);
return included;
}
catch {
return false;
}
}
async flush(partial) {
if (this.buffer.length === 0)
return;
const leaves = this.buffer.splice(0, config_1.checkpointAggregatorConfig.batchSize);
if (config_1.checkpointAggregatorConfig.attachReceiptMeta) {
await (0, receiptsRoot_1.attachReceiptMeta)(this.chain138, leaves);
}
else {
for (const leaf of leaves) {
const meta = await (0, receiptsRoot_1.fetchReceiptMeta)(this.chain138, leaf.txHash);
leaf.logCount = meta.logCount;
leaf.receiptHash = meta.receiptHash;
}
}
(0, iso20022Enrich_1.attachIso20022ToLeaves)(leaves);
const root = (0, leafCodec_1.paymentsRoot)(138, leaves);
const receiptMetas = leaves.map((l) => ({
logCount: l.logCount ?? 0,
receiptHash: l.receiptHash ?? ethers_1.ethers.ZeroHash,
}));
const receiptsRootHash = (0, receiptsRoot_1.receiptsRoot)(leaves.map((l) => l.txHash), receiptMetas);
const checkpointBlock = Math.max(...leaves.map((l) => l.blockNumber));
const block = await this.chain138.getBlock(checkpointBlock);
const blockHash = block?.hash ?? ethers_1.ethers.ZeroHash;
const stateRoot = block?.stateRoot ?? ethers_1.ethers.ZeroHash;
if (config_1.checkpointAggregatorConfig.updateBlockOracle && this.blockOracle) {
const tx = await this.blockOracle.setBlockHeader(checkpointBlock, blockHash, stateRoot);
await tx.wait();
}
const header = {
batchId: this.nextBatchId,
previousBatchId: this.nextBatchId > 1n ? this.nextBatchId - 1n : 0n,
chainId: 138n,
checkpointBlock: BigInt(checkpointBlock),
startBlock: BigInt(Math.min(...leaves.map((l) => l.blockNumber))),
endBlock: BigInt(checkpointBlock),
blockHash,
stateRoot,
paymentsRoot: root,
receiptsRoot: receiptsRootHash,
txCount: partial && leaves.length < config_1.checkpointAggregatorConfig.batchSize ? leaves.length : config_1.checkpointAggregatorConfig.batchSize,
flags: partial && leaves.length < config_1.checkpointAggregatorConfig.batchSize ? 1 : 0,
submittedAt: 0n,
submitter: ethers_1.ethers.ZeroAddress,
contentURI: ethers_1.ethers.ZeroHash,
};
const payload = {
batchId: this.nextBatchId.toString(),
chainId: 138,
checkpointBlock,
paymentsRoot: root,
leaves: leaves.map((l) => ({
txHash: l.txHash,
from: l.from,
to: l.to,
value: l.value.toString(),
nativeValueWei: l.value.toString(),
onChainValueWei: (0, leafCodec_1.effectiveValue)(l).toString(),
blockNumber: l.blockNumber,
blockTimestamp: l.blockTimestamp,
gasUsed: l.gasUsed.toString(),
success: l.success,
...(l.token
? {
token: l.token,
tokenSymbol: l.tokenSymbol,
tokenDecimals: l.tokenDecimals,
tokenValue: l.tokenValue?.toString(),
tokenLogIndex: l.tokenLogIndex,
}
: {}),
...(l.valueUsd ? { valueUsd: l.valueUsd } : {}),
...(l.nativeValueUsd ? { nativeValueUsd: l.nativeValueUsd } : {}),
...(l.tokenValueUsd ? { tokenValueUsd: l.tokenValueUsd } : {}),
...(l.nativePriceUsd != null ? { nativePriceUsd: l.nativePriceUsd } : {}),
...(l.tokenPriceUsd != null ? { tokenPriceUsd: l.tokenPriceUsd } : {}),
...(l.priceSource ? { priceSource: l.priceSource } : {}),
...(l.priceEffectiveTimestamp ? { priceEffectiveTimestamp: l.priceEffectiveTimestamp } : {}),
...(l.totalTransfersUsd ? { totalTransfersUsd: l.totalTransfersUsd } : {}),
...(l.transfers?.length ? { transfers: l.transfers } : {}),
...(l.logCount != null ? { logCount: l.logCount } : {}),
...(l.receiptHash ? { receiptHash: l.receiptHash } : {}),
...(l.iso20022 ? { iso20022: l.iso20022 } : {}),
})),
submittedAt: new Date().toISOString(),
...(config_1.checkpointAggregatorConfig.isoEnrichEnabled
? { iso20022Schema: 'canonical-v1', isoMsgTypeDefault: 'chain138.synthetic' }
: {}),
...(config_1.checkpointAggregatorConfig.usdEnrichEnabled
? {
batchTotalUsd: (0, checkpoint_core_1.sumUsdStrings)(leaves.map((l) => l.totalTransfersUsd ?? l.valueUsd)) ?? '0.000000',
usdEnrichedAt: new Date().toISOString(),
}
: {}),
};
const contentURI = await (0, ipfs_1.publishBatchPayload)(this.nextBatchId, payload);
header.contentURI = contentURI;
const validatorSignatures = config_1.checkpointAggregatorConfig.requireValidatorSigs
? await (0, eip712_1.signBatchAttestation)(this.mainnetWallet, config_1.checkpointAggregatorConfig.checkpointProxy, header)
: '0x01';
const txHashes = config_1.checkpointAggregatorConfig.submitMode === 'commitment' ? [] : leaves.map((l) => l.txHash);
const extensionData = adminIngress_1.AdminCheckpointIngress.extensionDataForMode(config_1.checkpointAggregatorConfig.submitMode, leaves);
const { hash } = await this.ingress.submit({
header,
leaves,
txHashes,
extensionData,
contentURI,
validatorSignatures,
});
const batchIdSubmitted = this.nextBatchId;
console.log(`Submitted batch ${batchIdSubmitted} (${leaves.length} txs) mode=${config_1.checkpointAggregatorConfig.submitMode} tx=${hash}`);
if (config_1.checkpointAggregatorConfig.dualWriteV1Mirror) {
try {
const mirrorTx = await (0, dualMirror_1.dualWriteV1Mirror)(this.mainnetWallet, config_1.checkpointAggregatorConfig.transactionMirrorMainnet, leaves);
if (mirrorTx)
console.log(` v1 TransactionMirror dual-write tx=${mirrorTx}`);
}
catch (e) {
console.error(' v1 TransactionMirror dual-write failed', e);
}
}
if (config_1.checkpointAggregatorConfig.recordAddressActivity && config_1.checkpointAggregatorConfig.addressActivityRegistry) {
try {
const activityTx = await (0, activityRegistry_1.recordActivityBatch)(this.mainnetWallet, config_1.checkpointAggregatorConfig.addressActivityRegistry, batchIdSubmitted, leaves);
if (activityTx)
console.log(` AddressActivityRegistry tx=${activityTx}`);
}
catch (e) {
console.error(' AddressActivityRegistry record failed', e);
}
}
if (config_1.checkpointAggregatorConfig.recordIsoAttestation && config_1.checkpointAggregatorConfig.addressActivityRegistryV2) {
try {
const isoTx = await (0, activityRegistryV2_1.recordIsoAttestationBatch)(this.mainnetWallet, config_1.checkpointAggregatorConfig.addressActivityRegistryV2, batchIdSubmitted, leaves);
if (isoTx)
console.log(` AddressActivityRegistryV2 tx=${isoTx}`);
}
catch (e) {
console.error(' AddressActivityRegistryV2 record failed', e);
}
}
if (config_1.checkpointAggregatorConfig.isoEnrichEnabled) {
try {
const stored = (0, iso20022LocalStore_1.persistIso20022ForLeaves)(leaves, batchIdSubmitted);
if (stored.length)
console.log(` ISO20022 OMNL store: ${stored.length} message(s)`);
}
catch (e) {
console.error(' ISO20022 local store failed', e);
}
}
if (config_1.checkpointAggregatorConfig.surfaceParticipants && config_1.checkpointAggregatorConfig.participantSurface) {
try {
const surfaceTx = await (0, participantSurface_1.surfaceParticipantsOnMainnet)(this.mainnetWallet, config_1.checkpointAggregatorConfig.participantSurface, batchIdSubmitted, leaves);
if (surfaceTx)
console.log(` Chain138ParticipantSurface tx=${surfaceTx}`);
}
catch (e) {
console.error(' Chain138ParticipantSurface failed', e);
}
}
if (config_1.checkpointAggregatorConfig.surfaceTopLevelZeroEth) {
try {
const n = await (0, participantSurface_1.surfaceTopLevelZeroEth)(this.mainnetWallet, leaves);
if (n > 0)
console.log(` Top-level 0 ETH surface txs=${n} (Etherscan Transactions tab)`);
}
catch (e) {
console.error(' Top-level 0 ETH surface failed', e);
}
}
this.nextBatchId += 1n;
this.schedulePartialFlush();
}
}
new CheckpointAggregator().start().catch((e) => {
console.error(e);
process.exit(1);
});