fix(token-aggregation): resolve TypeScript build errors

- token-mapping: use createRequire(proxmox package.json) and process.cwd(), drop import.meta to allow commonjs build
- Add routes/bridge.ts stub (status + metrics) so server.ts import resolves
- Add config/cross-chain-bridges.ts with BridgeConfig/BridgeLane and CHAIN_138_BRIDGES from env
- cross-chain-indexer: import BridgeLane, add explicit types for .find/.map callbacks, bridgeType fallback to b.type

Made-with: Cursor
This commit is contained in:
defiQUG
2026-03-03 21:12:52 -08:00
parent 010ae8341c
commit 51b9b7458b
4 changed files with 114 additions and 13 deletions

View File

@@ -0,0 +1,26 @@
/**
* Bridge API: cross-chain bridge status and metrics.
* GET /api/v1/bridge/status, /api/v1/bridge/metrics — stubbed or delegated to cross-chain report.
*/
import { Router, Request, Response } from 'express';
const router: Router = Router();
router.get('/status', (_req: Request, res: Response) => {
res.json({
ok: true,
bridges: [],
message: 'Bridge status: use /api/v1/report/cross-chain for volume/lanes.',
});
});
router.get('/metrics', (_req: Request, res: Response) => {
res.json({
ok: true,
lanes: [],
message: 'Bridge metrics: use /api/v1/report/cross-chain for aggregated data.',
});
});
export default router;

View File

@@ -6,17 +6,15 @@
import { Router, Request, Response } from 'express';
import path from 'path';
import { fileURLToPath } from 'url';
import { createRequire } from 'module';
import { cacheMiddleware } from '../middleware/cache';
const router: Router = Router();
const require = createRequire(import.meta.url);
const __dirname = path.dirname(fileURLToPath(import.meta.url));
/** Resolve path to repo root (proxmox) from token-aggregation src/api/routes -> 5 levels up */
const PROXMOX_ROOT = path.resolve(__dirname, '../../../../../');
/** Repo root (proxmox): when run from token-aggregation cwd, 2 levels up to smom-dbis-138, 1 more to proxmox */
const PROXMOX_ROOT = path.resolve(process.cwd(), '../../..');
const LOADER_PATH = path.join(PROXMOX_ROOT, 'config', 'token-mapping-loader.cjs');
const requireLoader = createRequire(path.join(PROXMOX_ROOT, 'package.json'));
function loadMultichainLoader(): {
getTokenMappingForPair: (from: number, to: number) => { tokens: unknown[]; addressMapFromTo: Record<string, string>; addressMapToFrom: Record<string, string> } | null;
@@ -24,7 +22,7 @@ function loadMultichainLoader(): {
getMappedAddress: (from: number, to: number, addr: string) => string | undefined;
} | null {
try {
const loader = require(LOADER_PATH);
const loader = requireLoader(LOADER_PATH);
if (loader?.getTokenMappingForPair && loader?.getAllMultichainPairs && loader?.getMappedAddress) {
return loader;
}

View File

@@ -0,0 +1,77 @@
/**
* Cross-chain bridge config for Chain 138 (and optional 651940).
* Used by cross-chain-indexer for CCIP/Alltra/UniversalCCIP event aggregation.
*/
export interface BridgeLane {
destSelector: string;
destChainId: number;
destChainName: string;
bridgeType?: string;
}
export interface BridgeConfig {
address: string;
chainId: number;
type: 'ccip_weth9' | 'ccip_weth10' | 'alltra' | 'universal_ccip';
tokenSymbol?: string;
lanes: BridgeLane[];
}
/** Chain 138 bridge addresses from env; lanes can be extended per deployment. */
const chainId138 = 138;
function envAddr(key: string): string {
const v = process.env[key];
return typeof v === 'string' && v.startsWith('0x') ? v : '';
}
export const CHAIN_138_BRIDGES: BridgeConfig[] = [];
if (envAddr('CCIPWETH9_BRIDGE_CHAIN138')) {
CHAIN_138_BRIDGES.push({
address: envAddr('CCIPWETH9_BRIDGE_CHAIN138'),
chainId: chainId138,
type: 'ccip_weth9',
tokenSymbol: 'WETH',
lanes: [
{ destSelector: '5009297550715157269', destChainId: 1, destChainName: 'Ethereum' },
{ destSelector: '16015286601757825753', destChainId: 651940, destChainName: 'ALL Mainnet' },
],
});
}
if (envAddr('CCIPWETH10_BRIDGE_CHAIN138')) {
CHAIN_138_BRIDGES.push({
address: envAddr('CCIPWETH10_BRIDGE_CHAIN138'),
chainId: chainId138,
type: 'ccip_weth10',
tokenSymbol: 'WETH',
lanes: [
{ destSelector: '5009297550715157269', destChainId: 1, destChainName: 'Ethereum' },
{ destSelector: '16015286601757825753', destChainId: 651940, destChainName: 'ALL Mainnet' },
],
});
}
if (envAddr('ALLTRA_CUSTOM_BRIDGE_ADDRESS') || envAddr('ALLTRA_ADAPTER_ADDRESS')) {
const addr = envAddr('ALLTRA_CUSTOM_BRIDGE_ADDRESS') || envAddr('ALLTRA_ADAPTER_ADDRESS');
CHAIN_138_BRIDGES.push({
address: addr,
chainId: chainId138,
type: 'alltra',
lanes: [{ destSelector: '0', destChainId: 651940, destChainName: 'ALL Mainnet' }],
});
}
if (envAddr('UNIVERSAL_CCIP_BRIDGE_ADDRESS')) {
CHAIN_138_BRIDGES.push({
address: envAddr('UNIVERSAL_CCIP_BRIDGE_ADDRESS'),
chainId: chainId138,
type: 'universal_ccip',
lanes: [
{ destSelector: '5009297550715157269', destChainId: 1, destChainName: 'Ethereum' },
{ destSelector: '16015286601757825753', destChainId: 651940, destChainName: 'ALL Mainnet' },
],
});
}

View File

@@ -6,7 +6,7 @@
import { ethers } from 'ethers';
import { getChainConfig } from '../config/chains';
import { CHAIN_138_BRIDGES, BridgeConfig } from '../config/cross-chain-bridges';
import { CHAIN_138_BRIDGES, BridgeConfig, BridgeLane } from '../config/cross-chain-bridges';
export interface CrossChainEvent {
txHash: string;
@@ -104,7 +104,7 @@ async function fetchCCIPEvents(
for (const log of logs) {
const args = (log as ethers.EventLog).args as unknown as { messageId: string; sender: string; destinationChainSelector: bigint; recipient: string; amount: bigint };
const lane = bridge.lanes.find((l) => l.destSelector === args.destinationChainSelector?.toString());
const lane = bridge.lanes.find((l: BridgeLane) => l.destSelector === args.destinationChainSelector?.toString());
const destChainId = lane?.destChainId ?? 0;
const destChainName = lane?.destChainName ?? `Chain ${args.destinationChainSelector}`;
@@ -253,7 +253,7 @@ async function fetchUniversalCCIPEvents(
for (const log of logs) {
const args = (log as ethers.EventLog).args as unknown as { messageId: string; token: string; sender: string; amount: bigint; destinationChain: bigint; recipient: string };
const selector = args.destinationChain?.toString();
const lane = bridge.lanes.find((l) => l.destSelector === selector);
const lane = bridge.lanes.find((l: BridgeLane) => l.destSelector === selector);
const destChainId = lane?.destChainId ?? (selector === '5009297550715157269' ? 1 : 651940);
const destChainName = lane?.destChainName ?? `Chain ${selector}`;
@@ -379,7 +379,7 @@ export async function buildCrossChainReport(chainId: number = 138): Promise<Cros
const allEvents: CrossChainEvent[] = [];
const bridges = CHAIN_138_BRIDGES.filter((b) => b.chainId === chainId);
const bridges = CHAIN_138_BRIDGES.filter((b: BridgeConfig) => b.chainId === chainId);
for (const bridge of bridges) {
if (bridge.type === 'ccip_weth9' || bridge.type === 'ccip_weth10') {
@@ -406,15 +406,15 @@ export async function buildCrossChainReport(chainId: number = 138): Promise<Cros
bridgeVolume24hTotal += amt; // Approximate; real USD would need price oracle
}
const crossChainPools = bridges.map((b) =>
b.lanes.map((lane) => ({
const crossChainPools = bridges.map((b: BridgeConfig) =>
b.lanes.map((lane: BridgeLane) => ({
type: b.type,
sourceChainId: b.chainId,
destChainId: lane.destChainId,
destChainName: lane.destChainName,
bridgeAddress: b.address,
tokenSymbol: b.tokenSymbol,
bridgeType: lane.bridgeType,
bridgeType: lane.bridgeType ?? b.type,
isActive: true,
}))
).flat();