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

@@ -43,114 +43,159 @@ export class PoolRepository {
this.pool = getDatabasePool();
}
async getPool(chainId: number, poolAddress: string): Promise<LiquidityPool | null> {
const result = await this.pool.query(
`SELECT id, chain_id, pool_address, token0_address, token1_address, dex_type,
factory_address, router_address, reserve0, reserve1, reserve0_usd, reserve1_usd,
total_liquidity_usd, volume_24h, fee_tier, created_at_block, created_at_timestamp, last_updated
FROM liquidity_pools
WHERE chain_id = $1 AND pool_address = $2`,
[chainId, poolAddress.toLowerCase()]
);
if (result.rows.length === 0) {
return null;
private isMissingRelationError(error: unknown): boolean {
if (!error || typeof error !== 'object') {
return false;
}
return this.mapRowToPool(result.rows[0]);
const code = (error as { code?: string }).code;
const message = (error as { message?: string }).message || '';
return code === '42P01' || message.includes('relation "') && message.includes('" does not exist');
}
async getPool(chainId: number, poolAddress: string): Promise<LiquidityPool | null> {
try {
const result = await this.pool.query(
`SELECT id, chain_id, pool_address, token0_address, token1_address, dex_type,
factory_address, router_address, reserve0, reserve1, reserve0_usd, reserve1_usd,
total_liquidity_usd, volume_24h, fee_tier, created_at_block, created_at_timestamp, last_updated
FROM liquidity_pools
WHERE chain_id = $1 AND pool_address = $2`,
[chainId, poolAddress.toLowerCase()]
);
if (result.rows.length === 0) {
return null;
}
return this.mapRowToPool(result.rows[0]);
} catch (error) {
if (this.isMissingRelationError(error)) {
return null;
}
throw error;
}
}
async getPoolsByChain(chainId: number, limit: number = 500): Promise<LiquidityPool[]> {
const result = await this.pool.query(
`SELECT id, chain_id, pool_address, token0_address, token1_address, dex_type,
factory_address, router_address, reserve0, reserve1, reserve0_usd, reserve1_usd,
total_liquidity_usd, volume_24h, fee_tier, created_at_block, created_at_timestamp, last_updated
FROM liquidity_pools
WHERE chain_id = $1
ORDER BY total_liquidity_usd DESC NULLS LAST
LIMIT $2`,
[chainId, limit]
);
return result.rows.map((row) => this.mapRowToPool(row));
try {
const result = await this.pool.query(
`SELECT id, chain_id, pool_address, token0_address, token1_address, dex_type,
factory_address, router_address, reserve0, reserve1, reserve0_usd, reserve1_usd,
total_liquidity_usd, volume_24h, fee_tier, created_at_block, created_at_timestamp, last_updated
FROM liquidity_pools
WHERE chain_id = $1
ORDER BY total_liquidity_usd DESC NULLS LAST
LIMIT $2`,
[chainId, limit]
);
return result.rows.map((row) => this.mapRowToPool(row));
} catch (error) {
if (this.isMissingRelationError(error)) {
return [];
}
throw error;
}
}
async getPoolsByToken(chainId: number, tokenAddress: string): Promise<LiquidityPool[]> {
const result = await this.pool.query(
`SELECT id, chain_id, pool_address, token0_address, token1_address, dex_type,
factory_address, router_address, reserve0, reserve1, reserve0_usd, reserve1_usd,
total_liquidity_usd, volume_24h, fee_tier, created_at_block, created_at_timestamp, last_updated
FROM liquidity_pools
WHERE chain_id = $1 AND (token0_address = $2 OR token1_address = $2)
ORDER BY total_liquidity_usd DESC`,
[chainId, tokenAddress.toLowerCase()]
);
try {
const result = await this.pool.query(
`SELECT id, chain_id, pool_address, token0_address, token1_address, dex_type,
factory_address, router_address, reserve0, reserve1, reserve0_usd, reserve1_usd,
total_liquidity_usd, volume_24h, fee_tier, created_at_block, created_at_timestamp, last_updated
FROM liquidity_pools
WHERE chain_id = $1 AND (token0_address = $2 OR token1_address = $2)
ORDER BY total_liquidity_usd DESC`,
[chainId, tokenAddress.toLowerCase()]
);
return result.rows.map((row) => this.mapRowToPool(row));
return result.rows.map((row) => this.mapRowToPool(row));
} catch (error) {
if (this.isMissingRelationError(error)) {
return [];
}
throw error;
}
}
async upsertPool(pool: LiquidityPool): Promise<void> {
await this.pool.query(
`INSERT INTO liquidity_pools (
chain_id, pool_address, token0_address, token1_address, dex_type,
factory_address, router_address, reserve0, reserve1, reserve0_usd, reserve1_usd,
total_liquidity_usd, volume_24h, fee_tier, created_at_block, created_at_timestamp, last_updated
)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)
ON CONFLICT (chain_id, pool_address) DO UPDATE SET
token0_address = EXCLUDED.token0_address,
token1_address = EXCLUDED.token1_address,
dex_type = EXCLUDED.dex_type,
factory_address = EXCLUDED.factory_address,
router_address = EXCLUDED.router_address,
reserve0 = EXCLUDED.reserve0,
reserve1 = EXCLUDED.reserve1,
reserve0_usd = EXCLUDED.reserve0_usd,
reserve1_usd = EXCLUDED.reserve1_usd,
total_liquidity_usd = EXCLUDED.total_liquidity_usd,
volume_24h = EXCLUDED.volume_24h,
fee_tier = EXCLUDED.fee_tier,
last_updated = EXCLUDED.last_updated`,
[
pool.chainId,
pool.poolAddress.toLowerCase(),
pool.token0Address.toLowerCase(),
pool.token1Address.toLowerCase(),
pool.dexType,
pool.factoryAddress?.toLowerCase(),
pool.routerAddress?.toLowerCase(),
pool.reserve0,
pool.reserve1,
pool.reserve0Usd,
pool.reserve1Usd,
pool.totalLiquidityUsd,
pool.volume24h,
pool.feeTier,
pool.createdAtBlock,
pool.createdAtTimestamp,
pool.lastUpdated,
]
);
try {
await this.pool.query(
`INSERT INTO liquidity_pools (
chain_id, pool_address, token0_address, token1_address, dex_type,
factory_address, router_address, reserve0, reserve1, reserve0_usd, reserve1_usd,
total_liquidity_usd, volume_24h, fee_tier, created_at_block, created_at_timestamp, last_updated
)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)
ON CONFLICT (chain_id, pool_address) DO UPDATE SET
token0_address = EXCLUDED.token0_address,
token1_address = EXCLUDED.token1_address,
dex_type = EXCLUDED.dex_type,
factory_address = EXCLUDED.factory_address,
router_address = EXCLUDED.router_address,
reserve0 = EXCLUDED.reserve0,
reserve1 = EXCLUDED.reserve1,
reserve0_usd = EXCLUDED.reserve0_usd,
reserve1_usd = EXCLUDED.reserve1_usd,
total_liquidity_usd = EXCLUDED.total_liquidity_usd,
volume_24h = EXCLUDED.volume_24h,
fee_tier = EXCLUDED.fee_tier,
last_updated = EXCLUDED.last_updated`,
[
pool.chainId,
pool.poolAddress.toLowerCase(),
pool.token0Address.toLowerCase(),
pool.token1Address.toLowerCase(),
pool.dexType,
pool.factoryAddress?.toLowerCase(),
pool.routerAddress?.toLowerCase(),
pool.reserve0,
pool.reserve1,
pool.reserve0Usd,
pool.reserve1Usd,
pool.totalLiquidityUsd,
pool.volume24h,
pool.feeTier,
pool.createdAtBlock,
pool.createdAtTimestamp,
pool.lastUpdated,
]
);
} catch (error) {
if (this.isMissingRelationError(error)) {
return;
}
throw error;
}
}
async addReserveSnapshot(snapshot: PoolReserveSnapshot): Promise<void> {
await this.pool.query(
`INSERT INTO pool_reserves_history (
chain_id, pool_address, reserve0, reserve1, reserve0_usd, reserve1_usd,
total_liquidity_usd, block_number, timestamp
)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
[
snapshot.chainId,
snapshot.poolAddress.toLowerCase(),
snapshot.reserve0,
snapshot.reserve1,
snapshot.reserve0Usd,
snapshot.reserve1Usd,
snapshot.totalLiquidityUsd,
snapshot.blockNumber,
snapshot.timestamp,
]
);
try {
await this.pool.query(
`INSERT INTO pool_reserves_history (
chain_id, pool_address, reserve0, reserve1, reserve0_usd, reserve1_usd,
total_liquidity_usd, block_number, timestamp
)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
[
snapshot.chainId,
snapshot.poolAddress.toLowerCase(),
snapshot.reserve0,
snapshot.reserve1,
snapshot.reserve0Usd,
snapshot.reserve1Usd,
snapshot.totalLiquidityUsd,
snapshot.blockNumber,
snapshot.timestamp,
]
);
} catch (error) {
if (this.isMissingRelationError(error)) {
return;
}
throw error;
}
}
async getReserveHistory(
@@ -160,27 +205,34 @@ export class PoolRepository {
to: Date,
limit: number = 1000
): Promise<PoolReserveSnapshot[]> {
const result = await this.pool.query(
`SELECT chain_id, pool_address, reserve0, reserve1, reserve0_usd, reserve1_usd,
total_liquidity_usd, block_number, timestamp
FROM pool_reserves_history
WHERE chain_id = $1 AND pool_address = $2 AND timestamp >= $3 AND timestamp <= $4
ORDER BY timestamp DESC
LIMIT $5`,
[chainId, poolAddress.toLowerCase(), from, to, limit]
);
try {
const result = await this.pool.query(
`SELECT chain_id, pool_address, reserve0, reserve1, reserve0_usd, reserve1_usd,
total_liquidity_usd, block_number, timestamp
FROM pool_reserves_history
WHERE chain_id = $1 AND pool_address = $2 AND timestamp >= $3 AND timestamp <= $4
ORDER BY timestamp DESC
LIMIT $5`,
[chainId, poolAddress.toLowerCase(), from, to, limit]
);
return result.rows.map((row) => ({
chainId: row.chain_id,
poolAddress: row.pool_address,
reserve0: row.reserve0,
reserve1: row.reserve1,
reserve0Usd: row.reserve0_usd ? parseFloat(row.reserve0_usd) : undefined,
reserve1Usd: row.reserve1_usd ? parseFloat(row.reserve1_usd) : undefined,
totalLiquidityUsd: row.total_liquidity_usd ? parseFloat(row.total_liquidity_usd) : undefined,
blockNumber: parseInt(row.block_number, 10),
timestamp: row.timestamp,
}));
return result.rows.map((row) => ({
chainId: row.chain_id,
poolAddress: row.pool_address,
reserve0: row.reserve0,
reserve1: row.reserve1,
reserve0Usd: row.reserve0_usd ? parseFloat(row.reserve0_usd) : undefined,
reserve1Usd: row.reserve1_usd ? parseFloat(row.reserve1_usd) : undefined,
totalLiquidityUsd: row.total_liquidity_usd ? parseFloat(row.total_liquidity_usd) : undefined,
blockNumber: parseInt(row.block_number, 10),
timestamp: row.timestamp,
}));
} catch (error) {
if (this.isMissingRelationError(error)) {
return [];
}
throw error;
}
}
/* eslint-disable @typescript-eslint/no-explicit-any */