feat: restore operator WIP — PMM JSON sync entrypoint, dotenv RPC trim + secrets, pool env alignment

- Resolve stash: merge load_deployment_env path with secure-secrets and CR/LF RPC strip
- create-pmm-full-mesh-chain138.sh delegates to sync-chain138-pmm-pools-from-json.sh
- env.additions.example: canonical PMM pool defaults (cUSDT/USDT per crosscheck)
- Include Chain138 scripts, official mirror deploy scaffolding, and prior staged changes

Made-with: Cursor
This commit is contained in:
defiQUG
2026-03-27 19:02:30 -07:00
parent c6e7bad15e
commit 2a4753eb2d
200 changed files with 5987 additions and 913 deletions

View File

@@ -1,6 +1,7 @@
import { Router, Request, Response } from 'express';
import { PoolRepository } from '../../database/repositories/pool-repo';
import { TokenRepository } from '../../database/repositories/token-repo';
import { resolvePoolTokenDisplays } from '../../services/token-display';
import {
HEATMAP_CHAINS,
getRoutesList,
@@ -37,12 +38,9 @@ router.get('/heatmap', cacheMiddleware(60 * 1000), async (req: Request, res: Res
for (const pool of pools) {
const tvl = pool.totalLiquidityUsd || 0;
const half = tvl / 2;
const token0 = await tokenRepo.getToken(chainId, pool.token0Address);
const token1 = await tokenRepo.getToken(chainId, pool.token1Address);
const sym0 = token0?.symbol || '';
const sym1 = token1?.symbol || '';
if (assets.includes(sym0)) symbolToTvl[sym0] = (symbolToTvl[sym0] || 0) + half;
if (assets.includes(sym1)) symbolToTvl[sym1] = (symbolToTvl[sym1] || 0) + half;
const { token0, token1 } = await resolvePoolTokenDisplays(tokenRepo, chainId, pool.token0Address, pool.token1Address);
if (assets.includes(token0.symbol)) symbolToTvl[token0.symbol] = (symbolToTvl[token0.symbol] || 0) + half;
if (assets.includes(token1.symbol)) symbolToTvl[token1.symbol] = (symbolToTvl[token1.symbol] || 0) + half;
}
for (const asset of assets) {
const val = metric === 'tvlUsd' ? (symbolToTvl[asset] || 0) : 0;
@@ -77,15 +75,14 @@ router.get('/pools', cacheMiddleware(60 * 1000), async (req: Request, res: Respo
const pools = await poolRepo.getPoolsByChain(chainId, 500);
const list = await Promise.all(
pools.map(async (p) => {
const token0 = await tokenRepo.getToken(chainId, p.token0Address);
const token1 = await tokenRepo.getToken(chainId, p.token1Address);
const { token0, token1 } = await resolvePoolTokenDisplays(tokenRepo, chainId, p.token0Address, p.token1Address);
return {
poolId: `${chainId}:${(p.dexType || 'dodo').toLowerCase()}:${token0?.symbol || p.token0Address}-${token1?.symbol || p.token1Address}:${p.poolAddress}`,
poolId: `${chainId}:${(p.dexType || 'dodo').toLowerCase()}:${token0.symbol}-${token1.symbol}:${p.poolAddress}`,
chainId: p.chainId,
dex: p.dexType,
poolAddress: p.poolAddress,
token0: { symbol: token0?.symbol || '?', address: p.token0Address },
token1: { symbol: token1?.symbol || '?', address: p.token1Address },
token0: { symbol: token0.symbol, name: token0.name, address: p.token0Address, source: token0.source },
token1: { symbol: token1.symbol, name: token1.name, address: p.token1Address, source: token1.source },
liquidity: {
tvlUsd: p.totalLiquidityUsd,
reserve0: p.reserve0,

View File

@@ -12,6 +12,7 @@ import {
getCanonicalTokensByChain,
getLogoUriForSpec,
} from '../../config/canonical-tokens';
import { resolvePoolTokenDisplays } from '../../services/token-display';
import { getSupportedChainIds } from '../../config/chains';
import { cacheMiddleware } from '../middleware/cache';
import { fetchRemoteJson } from '../utils/fetch-remote-json';
@@ -64,6 +65,20 @@ async function buildTokenReport(chainId: number) {
poolRepo.getPoolsByToken(chainId, address),
]);
const resolvedPools = await Promise.all(
pools.map(async (p) => {
const { token0, token1 } = await resolvePoolTokenDisplays(tokenRepo, chainId, p.token0Address, p.token1Address);
return {
poolAddress: p.poolAddress,
dex: p.dexType,
token0,
token1,
tvl: p.totalLiquidityUsd,
volume24h: p.volume24h,
};
})
);
out.push({
chainId,
address: address.toLowerCase(),
@@ -83,12 +98,14 @@ async function buildTokenReport(chainId: number) {
lastUpdated: marketData.lastUpdated?.toISOString() ?? '',
}
: undefined,
pools: pools.map((p) => ({
pools: resolvedPools.map((p) => ({
poolAddress: p.poolAddress,
dex: p.dexType,
token0: p.token0Address,
token1: p.token1Address,
tvl: p.totalLiquidityUsd,
dex: p.dex,
token0: p.token0.address,
token1: p.token1.address,
token0Symbol: p.token0.symbol,
token1Symbol: p.token1.symbol,
tvl: p.tvl,
volume24h: p.volume24h,
})),
fromDb: !!dbToken,

View File

@@ -7,6 +7,7 @@ import { CoinGeckoAdapter } from '../../adapters/coingecko-adapter';
import { CoinMarketCapAdapter } from '../../adapters/cmc-adapter';
import { DexScreenerAdapter } from '../../adapters/dexscreener-adapter';
import { cacheMiddleware } from '../middleware/cache';
import { resolvePoolTokenDisplays } from '../../services/token-display';
import { logger } from '../../utils/logger';
const router: Router = Router();
@@ -150,19 +151,34 @@ router.get('/tokens/:address/pools', cacheMiddleware(60 * 1000), async (req: Req
const pools = await poolRepo.getPoolsByToken(chainId, address);
res.json({
pools: pools.map((pool) => ({
address: pool.poolAddress,
dex: pool.dexType,
token0: pool.token0Address,
token1: pool.token1Address,
reserves: {
token0: pool.reserve0,
token1: pool.reserve1,
},
tvl: pool.totalLiquidityUsd,
volume24h: pool.volume24h,
feeTier: pool.feeTier,
})),
pools: await Promise.all(
pools.map(async (pool) => {
const { token0, token1 } = await resolvePoolTokenDisplays(tokenRepo, chainId, pool.token0Address, pool.token1Address);
return {
address: pool.poolAddress,
dex: pool.dexType,
token0: {
address: pool.token0Address,
symbol: token0.symbol,
name: token0.name,
source: token0.source,
},
token1: {
address: pool.token1Address,
symbol: token1.symbol,
name: token1.name,
source: token1.source,
},
reserves: {
token0: pool.reserve0,
token1: pool.reserve1,
},
tvl: pool.totalLiquidityUsd,
volume24h: pool.volume24h,
feeTier: pool.feeTier,
};
})
),
});
} catch (error) {
logger.error('Error fetching pools:', error);
@@ -272,8 +288,12 @@ router.get('/pools/:poolAddress', cacheMiddleware(60 * 1000), async (req: Reques
pool: {
address: pool.poolAddress,
dex: pool.dexType,
token0: pool.token0Address,
token1: pool.token1Address,
token0: {
address: pool.token0Address,
},
token1: {
address: pool.token1Address,
},
reserves: {
token0: pool.reserve0,
token1: pool.reserve1,