Files
smom-dbis-138/services/token-aggregation/src/api/routes/omnl.ts
zaragoza444 5a9889cace
Some checks failed
CI/CD Pipeline / Solidity Contracts (push) Failing after 1m3s
CI/CD Pipeline / Security Scanning (push) Successful in 2m58s
CI/CD Pipeline / Lint and Format (push) Failing after 46s
CI/CD Pipeline / Terraform Validation (push) Failing after 26s
CI/CD Pipeline / Kubernetes Validation (push) Successful in 29s
Deploy ChainID 138 / Deploy ChainID 138 (push) Failing after 41s
HYBX OMNL TypeScript & anchor / token-aggregation build + reconcile artifact (push) Failing after 22s
OMNL reconcile anchor / Run omnl:reconcile and upload artifacts (push) Failing after 24s
Validation / validate-genesis (push) Successful in 32s
Validation / validate-terraform (push) Failing after 28s
Validation / validate-kubernetes (push) Failing after 13s
Validation / validate-smart-contracts (push) Failing after 12s
Validation / validate-security (push) Failing after 1m31s
Validation / validate-documentation (push) Failing after 23s
Verify Deployment / Verify Deployment (push) Failing after 1m4s
feat(settlement): production BTC L1 rails, hot cBTC liquidity, Dfns/Cobo smoke
Add BTC L1 settle/reconcile/ledger APIs, bitcoind intake, cBTC PMM hot-LP scripts, and custody credential smoke tests (secrets stay gitignored). Enables full-prod local green health and server pull-deploy for secure.omdnl.org /btc/*.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 09:28:24 -07:00

599 lines
19 KiB
TypeScript

import { Router, Request, Response } from 'express';
import { Contract, JsonRpcProvider, type InterfaceAbi } from 'ethers';
import { omnlRateLimiter } from '../middleware/rate-limit';
import { omnlRequireApiKeyInProduction } from '../middleware/omnl-guards';
import { omnlAuditMiddleware } from '../middleware/omnl-audit-middleware';
import {
fetchOmnlCompliance,
fetchOmnlComplianceAggregated,
fetchLatestAttestation,
fetchBreakerStatus,
loadCrossChainLines,
loadCrossChainConfigPath,
} from '../../services/omnl-compliance';
import { omnlComplianceCore138, omnlReserveStore138 } from '../../services/omnl-chain138-addresses';
import { computeOmnlReconcileAnchor } from '../../services/omnl-reconcile-anchor';
import { getOmnlIntegrationStatus } from '../../services/omnl-integration-status';
import { getOmnlApiCatalog } from '../../services/omnl-api-catalog';
import { loadGuosmmNotices, getGuosmmNotice } from '../../services/omnl-gazette-notices';
import omnlOpenApi from '../../resources/omnl-openapi.json';
import {
executeErc20Transfer,
executeM2TokenMint,
chainRailConfigured,
} from '../../services/omnl-settlement-chain';
import {
convertFiatLpToLiquidity,
readFiatLpPositions,
} from '../../services/omnl-fiat-lp-liquidity';
import { loadFiatLpParityConfig } from '../../config/fiat-lp-liquidity';
import fs from 'fs';
import path from 'path';
function resolveMintTokenAddress(lineId: string, symbol?: string, tokenAddress?: string): string | undefined {
if (tokenAddress?.startsWith('0x')) return tokenAddress;
const registryPath =
process.env.OMNL_M2_TOKEN_REGISTRY ||
path.resolve(__dirname, '../../../../config/omnl-m2-token-registry.v1.json');
try {
const registry = JSON.parse(fs.readFileSync(registryPath, 'utf8')) as {
tokens: Array<{ omnlLine: string; symbol: string; address: string }>;
};
const id = lineId.trim().toUpperCase();
const byLine = registry.tokens.find((t) => t.omnlLine.toUpperCase() === id);
if (byLine?.address.startsWith('0x') && byLine.address !== '0x0000000000000000000000000000000000000000') {
return byLine.address;
}
if (symbol) {
const bySym = registry.tokens.find((t) => t.symbol.toLowerCase() === symbol.toLowerCase());
if (bySym?.address.startsWith('0x') && bySym.address !== '0x0000000000000000000000000000000000000000') {
return bySym.address;
}
}
} catch {
/* registry optional */
}
return undefined;
}
const router = Router();
router.use(omnlRateLimiter);
router.use(omnlAuditMiddleware);
/**
* Public discovery + gazette (registered before production API key gate).
*/
router.get('/omnl/openapi.json', (_req: Request, res: Response) => {
res.type('application/json').json(omnlOpenApi as Record<string, unknown>);
});
router.get('/omnl/catalog', (_req: Request, res: Response) => {
res.json(getOmnlApiCatalog());
});
router.get('/omnl/integration-status', (_req: Request, res: Response) => {
res.json({
generatedAt: new Date().toISOString(),
...getOmnlIntegrationStatus(),
});
});
router.get('/omnl/gazette/notices', (_req: Request, res: Response) => {
const reg = loadGuosmmNotices();
res.json({
generatedAt: new Date().toISOString(),
gazetteBase: reg.gazetteBase,
count: reg.notices.length,
notices: reg.notices,
});
});
router.get('/omnl/gazette/notices/:documentId', (req: Request, res: Response) => {
const documentId = String(req.params.documentId ?? '');
const notice = getGuosmmNotice(documentId);
if (!notice) {
res.status(404).json({ error: 'Notice not found' });
return;
}
res.json(notice);
});
router.use(omnlRequireApiKeyInProduction);
const REGISTRY_ABI: InterfaceAbi = [
'function allLineIds() view returns (bytes32[])',
'function getLine(bytes32 lineId) view returns (tuple(address tokenM0,address tokenM1,uint8 decimals,uint16 iso4217Numeric,bool isXAU,bool active))',
];
const COORDINATOR_ABI: InterfaceAbi = [
'function mirrorChainSelector() view returns (uint64)',
'function mirrorReceiver() view returns (address)',
'function feeToken() view returns (address)',
];
/**
* GET /omnl/reconcile-anchor — same SHA-256 as omnl-reconcile-report.mjs (IPSAS + matrix files).
*/
router.get('/omnl/reconcile-anchor', (_req: Request, res: Response) => {
const out = computeOmnlReconcileAnchor();
if (!out.ok) {
res.status(503).json(out);
return;
}
res.json(out);
});
/**
* GET /omnl/cross-chain-lines — logical lines from hybx-omnl-cross-chain-lines.json.
*/
router.get('/omnl/cross-chain-lines', (_req: Request, res: Response) => {
try {
res.json({
configPath: loadCrossChainConfigPath(),
lines: loadCrossChainLines(),
});
} catch (e) {
const msg = e instanceof Error ? e.message : String(e);
res.status(500).json({ error: msg });
}
});
/**
* GET /omnl/mirror-coordinator?chainId=138 — on-chain mirror destination (CCIP).
*/
/**
* GET /omnl/zk-verifier — env-configured verifier address (placeholder ok).
*/
router.get('/omnl/zk-verifier', (_req: Request, res: Response) => {
const a = process.env.OMNL_ZK_VERIFIER?.trim() || '';
res.json({
configured: Boolean(a),
address: a || null,
note: 'See docs/hybx-omnl/ZK_INTEGRATION.md for wiring a real verifier.',
});
});
router.get('/omnl/mirror-coordinator', async (req: Request, res: Response) => {
try {
const chainId = parseInt(String(req.query.chainId || '138'), 10);
const coord =
process.env[`OMNL_MIRROR_COORDINATOR_${chainId}`]?.trim() ||
process.env.OMNL_MIRROR_COORDINATOR?.trim();
if (!coord) {
res.status(503).json({
error: 'OMNL_MIRROR_COORDINATOR or OMNL_MIRROR_COORDINATOR_<chainId> not set',
chainId,
});
return;
}
const rpc = rpcUrl(chainId);
if (!rpc) {
res.status(503).json({ error: 'RPC not configured for chain', chainId });
return;
}
const c = new Contract(coord, COORDINATOR_ABI, new JsonRpcProvider(rpc, chainId));
const [mirrorChainSelector, mirrorReceiver, feeToken] = await Promise.all([
c.mirrorChainSelector(),
c.mirrorReceiver(),
c.feeToken(),
]);
res.json({
chainId,
coordinator: coord,
mirrorChainSelector: String(mirrorChainSelector),
mirrorReceiver,
feeToken,
});
} catch (e) {
const msg = e instanceof Error ? e.message : String(e);
res.status(500).json({ error: msg });
}
});
function addrForChain(chainId: number): string | undefined {
if (chainId === 138) {
return omnlComplianceCore138();
}
if (chainId === 651940) {
return process.env.OMNL_COMPLIANCE_CORE_651940;
}
return process.env[`OMNL_COMPLIANCE_CORE_${chainId}`];
}
function rpcUrl(chainId: number): string | undefined {
if (chainId === 138) return process.env.RPC_URL_138 || process.env.RPC_URL;
if (chainId === 651940) return process.env.CHAIN_651940_RPC_URL || 'https://mainnet-rpc.alltra.global';
return process.env[`CHAIN_${chainId}_RPC_URL`];
}
/**
* GET /omnl/compliance/:lineId?chainId=138|651940
*/
router.get('/omnl/compliance/:lineId', async (req: Request, res: Response) => {
try {
const chainId = parseInt(String(req.query.chainId || '138'), 10);
const lineId = req.params.lineId as string;
const addr = addrForChain(chainId);
if (!addr) {
res.status(503).json({
error: 'OMNL_COMPLIANCE_CORE not configured for this chain',
chainId,
});
return;
}
const snap = await fetchOmnlCompliance(chainId, lineId, addr);
res.json(snap);
} catch (e) {
const msg = e instanceof Error ? e.message : String(e);
res.status(500).json({ error: msg });
}
});
/**
* GET /omnl/compliance-aggregated/:lineId — summed supply across chains (see hybx-omnl-cross-chain-lines.json).
*/
router.get('/omnl/compliance-aggregated/:lineId', async (req: Request, res: Response) => {
try {
const lineId = req.params.lineId as string;
const snap = await fetchOmnlComplianceAggregated(lineId);
res.json(snap);
} catch (e) {
const msg = e instanceof Error ? e.message : String(e);
res.status(500).json({ error: msg });
}
});
/**
* GET /omnl/instruments?chainId=138 — InstrumentRegistry.allLineIds + getLine
*/
router.get('/omnl/instruments', async (req: Request, res: Response) => {
try {
const chainId = parseInt(String(req.query.chainId || '138'), 10);
const reg = process.env[`OMNL_INSTRUMENT_REGISTRY_${chainId}`] || process.env.OMNL_INSTRUMENT_REGISTRY_138;
const rpc = rpcUrl(chainId);
if (!reg || !rpc) {
res.status(503).json({ error: 'OMNL_INSTRUMENT_REGISTRY_* and RPC required', chainId });
return;
}
const c = new Contract(reg, REGISTRY_ABI, new JsonRpcProvider(rpc, chainId));
const ids = (await c.allLineIds()) as string[];
const lines = await Promise.all(
ids.map(async (id: string) => {
const line = await c.getLine(id);
return { lineId: id, line };
})
);
res.json({ chainId, lines, crossChainConfigLines: loadCrossChainLines().length });
} catch (e) {
const msg = e instanceof Error ? e.message : String(e);
res.status(500).json({ error: msg });
}
});
/**
* GET /omnl/attestations/:lineId?chainId=138 — ReserveCommitmentStore.getCommitment
*/
router.get('/omnl/attestations/:lineId', async (req: Request, res: Response) => {
try {
const chainId = parseInt(String(req.query.chainId || '138'), 10);
const lineId = req.params.lineId as string;
const out = await fetchLatestAttestation(chainId, lineId);
res.json({ chainId, lineId, ...out });
} catch (e) {
const msg = e instanceof Error ? e.message : String(e);
res.status(500).json({ error: msg });
}
});
/**
* GET /omnl/breaker?chainId=138&lineId=0x...
*/
router.get('/omnl/breaker', async (req: Request, res: Response) => {
try {
const chainId = parseInt(String(req.query.chainId || '138'), 10);
const lineId = String(req.query.lineId || '');
if (!lineId || lineId === 'undefined') {
res.status(400).json({ error: 'lineId query parameter required' });
return;
}
const s = await fetchBreakerStatus(chainId, lineId);
res.json({ chainId, lineId, ...s });
} catch (e) {
const msg = e instanceof Error ? e.message : String(e);
res.status(500).json({ error: msg });
}
});
/**
* GET /omnl/mirror-status/:lineId — compare reserve version (and R) across 138 and 651940.
*/
router.get('/omnl/mirror-status/:lineId', async (req: Request, res: Response) => {
try {
const lineId = req.params.lineId as string;
const a138 = omnlReserveStore138();
const a651940 = process.env.OMNL_RESERVE_STORE_651940;
const out: Record<string, unknown> = {
lineId,
configured138: Boolean(a138),
configured651940: Boolean(a651940),
};
if (!a138 || !a651940) {
res.status(503).json({
...out,
error: 'Set OMNL_RESERVE_STORE_138 and OMNL_RESERVE_STORE_651940 for mirror comparison',
});
return;
}
const [x138, x651] = await Promise.all([
fetchLatestAttestation(138, lineId),
fetchLatestAttestation(651940, lineId),
]);
out.attestation138 = x138;
out.attestation651940 = x651;
out.rSynced = x138.r === x651.r;
out.versionSynced = x138.version === x651.version;
out.merkleSynced = x138.merkleRoot === x651.merkleRoot;
out.inSync = out.rSynced && out.versionSynced;
res.json(out);
} catch (e) {
const msg = e instanceof Error ? e.message : String(e);
res.status(500).json({ error: msg });
}
});
/**
* GET /omnl/health — requires OMNL_HEALTH_LINE_ID when comparing chains (no default zero line).
*/
router.get('/omnl/health', async (req: Request, res: Response) => {
const line = process.env.OMNL_HEALTH_LINE_ID;
if (!line) {
res.status(400).json({
error: 'Set OMNL_HEALTH_LINE_ID to a registered bytes32 line id (0x-prefixed)',
});
return;
}
const a138 = omnlComplianceCore138();
const a651940 = process.env.OMNL_COMPLIANCE_CORE_651940;
const out: Record<string, unknown> = {
lineId: line,
configured138: Boolean(a138),
configured651940: Boolean(a651940),
};
try {
if (a138) {
out.compliance138 = await fetchOmnlCompliance(138, line, a138);
}
if (a651940) {
out.compliance651940 = await fetchOmnlCompliance(651940, line, a651940);
}
if (a138 && a651940 && out.compliance138 && out.compliance651940) {
const x = out.compliance138 as { r: string; reportingCompliant: boolean };
const y = out.compliance651940 as { r: string; reportingCompliant: boolean };
out.rSynced = x.r === y.r;
out.reportingSynced =
x.reportingCompliant === y.reportingCompliant && x.r === y.r;
}
res.json(out);
} catch (e) {
const msg = e instanceof Error ? e.message : String(e);
res.status(500).json({ ...out, error: msg });
}
});
/**
* POST /omnl/settlement/token-load — M2→M3 fiat-backed token mint (Office 24 settlement).
*/
router.post('/omnl/settlement/token-load', async (req: Request, res: Response) => {
const { lineId, amount, recipient, settlementRef, dryRun, symbol, tokenAddress } = req.body as {
lineId?: string;
amount?: string;
recipient?: string;
settlementRef?: string;
dryRun?: boolean;
symbol?: string;
tokenAddress?: string;
};
if (!lineId || !amount || !recipient) {
res.status(400).json({ error: 'lineId, amount, recipient required' });
return;
}
const execute =
!dryRun &&
(process.env.SETTLEMENT_ALLOW_CHAIN_MINT_EXECUTE === '1' ||
process.env.OMNL_ALLOW_CHAIN_MINT_EXECUTE === '1');
const loadId = settlementRef ?? `TL-${Date.now()}`;
const capabilities = {
swappable: true,
convertible: true,
transferableInternal: true,
transferableExternal: true,
};
let mintTokenAddress = resolveMintTokenAddress(lineId, symbol, tokenAddress);
if (!execute) {
res.json({
status: 'DRY_RUN',
loadId,
lineId,
amount,
recipient,
symbol: symbol ?? null,
tokenAddress: mintTokenAddress ?? null,
settlementRef: settlementRef ?? null,
moneyLayer: 'M3',
loadFromGl: '2200',
creditGl: '2300',
capabilities,
txHash: null,
chainRailConfigured: chainRailConfigured(),
message: 'M2→M3 token load validated — set SETTLEMENT_ALLOW_CHAIN_MINT_EXECUTE=1 to mint on-chain',
});
return;
}
if (!mintTokenAddress?.startsWith('0x')) {
res.status(400).json({
error: 'tokenAddress required for on-chain mint',
status: 'QUEUED',
loadId,
capabilities,
});
return;
}
try {
const { txHash } = await executeM2TokenMint({
tokenAddress: mintTokenAddress,
recipient,
amount,
});
res.json({
status: 'SETTLED',
loadId,
lineId,
amount,
recipient,
symbol: symbol ?? null,
tokenAddress: mintTokenAddress,
settlementRef: settlementRef ?? null,
moneyLayer: 'M3',
capabilities,
txHash,
message: 'M3 token minted on Chain 138 — tradable, swappable, transferable',
});
} catch (e) {
const msg = e instanceof Error ? e.message : String(e);
res.status(502).json({
error: msg,
status: 'CHAIN_MINT_FAILED',
loadId,
lineId,
capabilities,
});
}
});
/**
* POST /omnl/settlement/token-transfer — ERC-20 transfer to web3 wallet (internal rail).
*/
router.post('/omnl/settlement/token-transfer', async (req: Request, res: Response) => {
const { tokenAddress, amount, recipient, settlementRef, dryRun, symbol } = req.body as {
tokenAddress?: string;
amount?: string;
recipient?: string;
settlementRef?: string;
dryRun?: boolean;
symbol?: string;
};
if (!tokenAddress || !amount || !recipient) {
res.status(400).json({ error: 'tokenAddress, amount, recipient required' });
return;
}
const execute =
!dryRun &&
(process.env.SETTLEMENT_ALLOW_CHAIN_MINT_EXECUTE === '1' ||
process.env.OMNL_ALLOW_CHAIN_MINT_EXECUTE === '1');
if (!execute) {
res.json({
status: 'DRY_RUN',
transferId: settlementRef ?? `TT-${Date.now()}`,
tokenAddress,
amount,
recipient,
symbol: symbol ?? null,
txHash: null,
message: 'Transfer validated — enable SETTLEMENT_ALLOW_CHAIN_MINT_EXECUTE=1 for on-chain delivery',
});
return;
}
try {
const { txHash } = await executeErc20Transfer({ tokenAddress, recipient, amount });
res.json({
status: 'SETTLED',
transferId: settlementRef ?? `TT-${Date.now()}`,
tokenAddress,
amount,
recipient,
symbol: symbol ?? null,
txHash,
message: 'ERC-20 transferred to recipient wallet on Chain 138',
});
} catch (e) {
const msg = e instanceof Error ? e.message : String(e);
res.status(502).json({ error: msg, status: 'CHAIN_TRANSFER_FAILED' });
}
});
/**
* GET /omnl/settlement/fiat-lp-positions — read c* LP balances + quoted real-fund value.
*/
router.get('/omnl/settlement/fiat-lp-positions', async (req: Request, res: Response) => {
const holder = String(req.query.holder ?? '').trim();
if (!holder.startsWith('0x')) {
res.status(400).json({ error: 'holder query param (0x address) required' });
return;
}
try {
const positions = await readFiatLpPositions(holder);
const cfg = loadFiatLpParityConfig();
res.json({
chainId: cfg.chainId,
holder,
contracts: cfg.contracts,
positions,
chainRailConfigured: chainRailConfigured(),
});
} catch (e) {
const msg = e instanceof Error ? e.message : String(e);
res.status(500).json({ error: msg });
}
});
/**
* POST /omnl/settlement/fiat-lp-to-liquidity — swap c* LP tokens → real USDT/USDC/WETH on Chain 138.
*/
router.post('/omnl/settlement/fiat-lp-to-liquidity', async (req: Request, res: Response) => {
const body = req.body as {
holderAddress?: string;
recipientAddress?: string;
symbol?: string;
amount?: string;
convertAll?: boolean;
maxSlippageBps?: number;
dryRun?: boolean;
settlementRef?: string;
};
if (!body.holderAddress?.startsWith('0x')) {
res.status(400).json({ error: 'holderAddress (0x) required' });
return;
}
const execute =
body.dryRun === false &&
(process.env.SETTLEMENT_ALLOW_CHAIN_MINT_EXECUTE === '1' ||
process.env.OMNL_ALLOW_CHAIN_MINT_EXECUTE === '1');
const dryRun = body.dryRun !== false && !execute;
try {
const result = await convertFiatLpToLiquidity({
holderAddress: body.holderAddress,
recipientAddress: body.recipientAddress,
symbol: body.symbol,
amount: body.amount,
convertAll: Boolean(body.convertAll),
maxSlippageBps: body.maxSlippageBps,
dryRun,
settlementRef: body.settlementRef ?? `FLP-${Date.now()}`,
});
const failed = result.swaps.some((s) => s.status === 'FAILED');
res.status(failed && !dryRun ? 422 : 200).json(result);
} catch (e) {
const msg = e instanceof Error ? e.message : String(e);
res.status(502).json({ error: msg });
}
});
export default router;