Token Aggregation Service
A comprehensive token aggregation service that indexes token info, volume, liquidity, and market signals from on-chain data and enriches with CoinGecko, CoinMarketCap, and DexScreener APIs for ChainID 138 (DeFi Oracle Meta Mainnet) and ChainID 651940 (ALL Mainnet).
REST API reference: docs/REST_API_REFERENCE.md — tokens, pools, prices, volume, OHLCV for dApps and MetaMask Snap discovery.
Chain 138 Snap: The MetaMask Chain 138 Snap (companion site at e.g. https://explorer.d-bis.org/snap/) calls this service for market data, swap quotes, and bridge routes. If the Snap is built with GATSBY_SNAP_API_BASE_URL=https://explorer.d-bis.org, then explorer.d-bis.org must serve this API (e.g. proxy /api/v1/* to this service). Otherwise build the Snap site with GATSBY_SNAP_API_BASE_URL set to this service’s public URL. See metamask-integration/chain138-snap/docs/CHAIN138_SNAP_TROUBLESHOOTING.md. CORS: The service uses cors() (all origins allowed by default) so MetaMask Snap and browser clients can fetch token list and networks.
Features
- Chain-Native Indexing: Indexes tokens, DEX pools, and swap events directly from blockchain
- External API Enrichment: Enriches data with CoinGecko, CoinMarketCap, and DexScreener
- Multi-DEX Support: Supports UniswapV2, UniswapV3, and DODO PMM protocols
- OHLCV Data: Generates Open, High, Low, Close, Volume data for price charts
- Volume Analytics: Calculates 5m, 1h, 24h, 7d, 30d volume metrics
- REST API: Unified REST API for all token data
Architecture
Three-Layer Design
- Layer 1: Chain-Native Indexer - Source of truth from on-chain data
- Layer 2: External Enrichment Adapters - Best-effort enrichment from external APIs
- Layer 3: Unified REST API - Single API endpoint for consumption
Prerequisites
- Node.js 20+
- PostgreSQL 14+ with TimescaleDB extension
- Access to RPC endpoints for ChainID 138 and 651940
- (Optional) API keys for CoinGecko, CoinMarketCap, DexScreener
Installation
- Clone the repository and navigate to the service directory:
cd smom-dbis-138/services/token-aggregation
- Install dependencies:
npm install
- Copy environment file:
cp .env.example .env
- Configure environment variables in
.env(see.env.examplefor full list):
# Chain RPCs
CHAIN_138_RPC_URL=https://rpc-http-pub.d-bis.org
CHAIN_651940_RPC_URL=https://mainnet-rpc.alltra.global
# Database
DATABASE_URL=postgresql://user:password@localhost:5432/explorer_db
# External APIs (optional) — use placeholders in .env.example; get keys from provider dashboards
COINGECKO_API_KEY=your_key_here
COINMARKETCAP_API_KEY=your_key_here
DEXSCREENER_API_KEY=your_key_here
Canonical token addresses (report API): Set per-chain env vars for tokens you want in /api/v1/report/*. Required/minimal for report: CUSDC_ADDRESS_138, CUSDT_ADDRESS_138 (Chain 138); optionally CUSDC_ADDRESS_651940, CUSDT_ADDRESS_651940 for Chain 651940. Chain 138 compliant fiat (cEURC, cEURT, cGBPC, cGBPT, cAUDC, cJPYC, cCHFC, cCADC, cXAUC, cXAUT) have fallback addresses in src/config/canonical-tokens.ts (DeployCompliantFiatTokens 2026-02-27); they are included in the report without env. Override with CEURC_ADDRESS_138, etc. if needed. Other symbols (USDW, acUSDC, vdcUSDC, sdcUSDC, etc.) — see .env.example. Unset tokens (with no fallback) are omitted from the report.
Required environment variables (canonical tokens — Blitzkrieg Step 1/9)
The canonical token list is defined in src/config/canonical-tokens.ts and is the single source of truth for the Token Aggregation API and report endpoints. Addresses are read from environment variables; unset tokens are omitted from getCanonicalTokensByChain and report output.
| Purpose | Env var pattern | Example |
|---|---|---|
| Chain 138 | {SYMBOL}_ADDRESS_138 (symbol with - → _, uppercase) |
CUSDC_ADDRESS_138, CUSDT_ADDRESS_138, USDW_ADDRESS_138, ACUSDC_ADDRESS_138, VDCUSDC_ADDRESS_138, SDCUSDC_ADDRESS_138 |
| Chain 651940 (ALL Mainnet) | {SYMBOL}_ADDRESS_651940 |
CUSDC_ADDRESS_651940, CUSDT_ADDRESS_651940 |
Minimum for report API: CUSDC_ADDRESS_138, CUSDT_ADDRESS_138. For full GRU M1 + W-tokens + ac*/vdc*/sdc* coverage, set the corresponding *_ADDRESS_138 and *_ADDRESS_651940 vars. See .env.example for the full commented list. Refs: BLITZKRIEG_SUPER_PRO_MAX_MASTER_PLAN §2–§3, PLACEHOLDERS_AND_COMPLETION_MASTER_LIST.
CoinGecko/CMC chain support: ChainID 138 and 651940 are not yet supported by CoinGecko/CMC; external price/volume for these chains will be empty in the report until the platforms add support or you use another source. The report API still returns chain-native token/pool data.
Bridge routes (CCIP + Trustless): GET /api/v1/bridge/routes returns CCIP (WETH9/WETH10) and Trustless bridge data. Trustless is enabled in production by default: the deployed Lockbox138 address on Chain 138 is included when LOCKBOX_138 is not set. Optional env (restart after change):
LOCKBOX_138— Override Lockbox contract address on Chain 138 (default: deployed Lockbox138).INBOX_ETH— (Optional) InboxETH contract on Ethereum Mainnet; when set, the Snap shows "Trustless → Ethereum Mainnet" with this address.
The MetaMask Snap bridge dialog always shows the Trustless (Lockbox) route when using this API. Full Trustless operations (user lock/claim) also require the Trustless stack on Ethereum (InboxETH, BondManager, LiquidityPool, etc.) to be deployed and operational; see smom-dbis-138/docs/bridge/trustless.
Token mapping (multichain): When run from the monorepo (proxmox), GET /api/v1/token-mapping?fromChain=138&toChain=651940 (and ?fromChain=&toChain= for any pair), GET /api/v1/token-mapping/pairs, and GET /api/v1/token-mapping/resolve?fromChain=&toChain=&address= expose config/token-mapping-multichain.json for bridge UIs and cross-chain address resolution.
- Run database migrations:
# Ensure the migration has been run in the explorer database
# Migration file: explorer-monorepo/backend/database/migrations/0011_token_aggregation_schema.up.sql
- Build the project:
npm run build
- Start the service:
npm start
Development
# Run in development mode with hot reload
npm run dev
# Run tests
npm test
# Lint code
npm run lint
Docker Deployment
Build and run with Docker Compose
docker-compose up -d
Build Docker image
docker build -t token-aggregation-service .
docker run -p 3000:3000 --env-file .env token-aggregation-service
API Endpoints
Health Check
GET /health
List Chains
GET /api/v1/chains
List Tokens
GET /api/v1/tokens?chainId=138&limit=50&offset=0
Get Token Details
GET /api/v1/tokens/:address?chainId=138
Get Token Pools
GET /api/v1/tokens/:address/pools?chainId=138
Get OHLCV Data
GET /api/v1/tokens/:address/ohlcv?chainId=138&interval=1h&from=timestamp&to=timestamp
Get Token Signals
GET /api/v1/tokens/:address/signals?chainId=138
Search Tokens
GET /api/v1/search?q=USDT&chainId=138
Get Pool Details
GET /api/v1/pools/:poolAddress?chainId=138
CMC and CoinGecko Reporting (all tokens, liquidity, volume)
Full API for all coins, tokens, liquidity, and reportable data in CMC/CoinGecko-friendly formats:
| Endpoint | Description |
|---|---|
GET /api/v1/report/all |
All tokens, pools, liquidity, volume, and summary by chain |
GET /api/v1/report/coingecko?chainId=138 |
Token list in CoinGecko submission format |
GET /api/v1/report/cmc?chainId=138 |
Token list and DEX pairs in CoinMarketCap format |
GET /api/v1/report/token-list |
Flat canonical token list (all chains or ?chainId=138) |
GET /api/v1/report/canonical |
Raw canonical token spec (symbol, name, type, decimals, addresses) |
See docs/CMC_COINGECKO_REPORTING.md for usage and listing submission.
Token mapping (multichain)
When the service runs from the monorepo (with config/token-mapping-multichain.json available):
| Endpoint | Description |
|---|---|
GET /api/v1/token-mapping?fromChain=138&toChain=651940 |
Token mapping for a chain pair (tokens, addressMapFromTo, addressMapToFrom) |
GET /api/v1/token-mapping/pairs |
All defined chain pairs |
GET /api/v1/token-mapping/resolve?fromChain=&toChain=&address= |
Resolve token address on target chain |
Configuration
DEX Factory Configuration
Configure DEX factory addresses in src/config/dex-factories.ts or via environment variables:
# ChainID 138
CHAIN_138_DODO_POOL_MANAGER=0x...
CHAIN_138_UNISWAP_V2_FACTORY=0x...
CHAIN_138_UNISWAP_V3_FACTORY=0x...
# ChainID 651940
CHAIN_651940_UNISWAP_V2_FACTORY=0x...
CHAIN_651940_UNISWAP_V3_FACTORY=0x...
Monitoring
The service includes:
- Health check endpoint at
/health - Structured logging with Winston
- Request rate limiting
- Response caching
License
MIT