feat(token-aggregation): add historical pricing context, backfill, and indexer hardening
Some checks failed
CI/CD Pipeline / Solidity Contracts (pull_request) Failing after 1m6s
CI/CD Pipeline / Security Scanning (pull_request) Successful in 12m42s
CI/CD Pipeline / Lint and Format (pull_request) Failing after 42s
CI/CD Pipeline / Terraform Validation (pull_request) Failing after 25s
CI/CD Pipeline / Kubernetes Validation (pull_request) Successful in 27s
HYBX OMNL TypeScript & anchor / token-aggregation build + reconcile artifact (pull_request) Failing after 49s
OMNL reconcile anchor / Run omnl:reconcile and upload artifacts (pull_request) Failing after 26s
Validation / validate-genesis (pull_request) Successful in 36s
Validation / validate-terraform (pull_request) Failing after 28s
Validation / validate-kubernetes (pull_request) Failing after 12s
Validation / validate-smart-contracts (pull_request) Failing after 13s
Validation / validate-security (pull_request) Failing after 1m39s
Validation / validate-documentation (pull_request) Failing after 18s

This commit is contained in:
defiQUG
2026-04-25 23:45:07 -07:00
parent c3b1b2cebc
commit fcd55aa9c4
18 changed files with 1963 additions and 1095 deletions

View File

@@ -0,0 +1,99 @@
import { Pool } from 'pg';
import { getDatabasePool } from '../client';
export interface SwapEventRecord {
chainId: number;
poolAddress: string;
transactionHash: string;
blockNumber: number;
logIndex: number;
token0Address: string;
token1Address: string;
amount0In: string;
amount1In: string;
amount0Out: string;
amount1Out: string;
amountUsd?: number;
priceUsd?: number;
token0PriceUsd?: number;
token1PriceUsd?: number;
sender?: string;
toAddress?: string;
timestamp: Date;
}
export class SwapEventRepository {
private pool: Pool;
constructor() {
this.pool = getDatabasePool();
}
private isMissingRelationError(error: unknown): boolean {
if (!error || typeof error !== 'object') {
return false;
}
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 upsertSwapEvent(event: SwapEventRecord): Promise<void> {
try {
await this.pool.query(
`INSERT INTO swap_events (
chain_id, pool_address, transaction_hash, block_number, log_index,
token0_address, token1_address, amount0_in, amount1_in, amount0_out, amount1_out,
amount_usd, price_usd, token0_price_usd, token1_price_usd, sender, to_address, timestamp
)
VALUES (
$1, $2, $3, $4, $5,
$6, $7, $8, $9, $10, $11,
$12, $13, $14, $15, $16, $17, $18
)
ON CONFLICT (chain_id, transaction_hash, log_index) DO UPDATE SET
pool_address = EXCLUDED.pool_address,
block_number = EXCLUDED.block_number,
token0_address = EXCLUDED.token0_address,
token1_address = EXCLUDED.token1_address,
amount0_in = EXCLUDED.amount0_in,
amount1_in = EXCLUDED.amount1_in,
amount0_out = EXCLUDED.amount0_out,
amount1_out = EXCLUDED.amount1_out,
amount_usd = EXCLUDED.amount_usd,
price_usd = EXCLUDED.price_usd,
token0_price_usd = EXCLUDED.token0_price_usd,
token1_price_usd = EXCLUDED.token1_price_usd,
sender = EXCLUDED.sender,
to_address = EXCLUDED.to_address,
timestamp = EXCLUDED.timestamp`,
[
event.chainId,
event.poolAddress.toLowerCase(),
event.transactionHash.toLowerCase(),
event.blockNumber,
event.logIndex,
event.token0Address.toLowerCase(),
event.token1Address.toLowerCase(),
event.amount0In,
event.amount1In,
event.amount0Out,
event.amount1Out,
event.amountUsd,
event.priceUsd,
event.token0PriceUsd,
event.token1PriceUsd,
event.sender?.toLowerCase(),
event.toAddress?.toLowerCase(),
event.timestamp,
]
);
} catch (error) {
if (this.isMissingRelationError(error)) {
return;
}
throw error;
}
}
}