feat: bridges, PMM, flash workflow, token-aggregation, and deployment docs
- CCIP/trustless bridge contracts, GRU tokens, DEX/PMM tests, reserve vault. - Token-aggregation service routes, planner, chain config, relay env templates. - Config snapshots and multi-chain deployment markdown updates. - gitignore services/btc-intake/dist/ (tsc output); do not track dist. Run forge build && forge test before deploy (large solc graph). Made-with: Cursor
This commit is contained in:
@@ -99,7 +99,8 @@ Raw canonical token definitions (no DB merge): symbol, name, type, decimals, cur
|
||||
|
||||
The report uses the **canonical token list** in `src/config/canonical-tokens.ts`. It includes:
|
||||
|
||||
- **Base (GRU-M1):** cUSDC, cUSDT, cEURC, cEURT, cGBPC, cGBPT, cAUDC, cJPYC, cCHFC, cCADC, cXAUC, cXAUT
|
||||
- **Base (GRU-M1):** cUSDC, cUSDT, cAUSDT, cEURC, cEURT, cGBPC, cGBPT, cAUDC, cJPYC, cCHFC, cCADC, cXAUC, cXAUT, plus env-gated ALL Mainnet gold landings `cAXAUC` / `cAXAUT`
|
||||
- **Public transport mirrors (cW*):** cWUSDC, cWUSDT, cWUSDW, live cWAUSDT mirrors on BSC, Polygon, Avalanche, and Celo, plus env-gated ALL Mainnet gold wrappers `cWAXAUC` / `cWAXAUT`
|
||||
- **W-tokens (ISO-4217):** USDW, EURW, GBPW, AUDW, JPYW, CHFW, CADW
|
||||
- **Asset (ac*):** acUSDC, acUSDT, acEURC, acGBPC, acAUDC, acJPYC, acCHFC, acCADC, acXAUC
|
||||
- **Debt (vdc* / sdc*):** vdcUSDC, sdcUSDC, vdcEURC, sdcEURC, vdcGBPC, sdcGBPC, vdcAUDC, sdcAUDC, vdcJPYC, sdcJPYC, vdcCHFC, sdcCHFC, vdcCADC, sdcCADC, vdcXAUC, sdcXAUC
|
||||
@@ -112,6 +113,17 @@ Addresses per chain can be:
|
||||
|
||||
Only tokens with a non-empty address for the requested chain appear in `/report/coingecko`, `/report/cmc`, and in the per-chain sections of `/report/all` and `/report/token-list`.
|
||||
|
||||
For the live **ALL Mainnet AUSDT -> cWAUSDT -> cAUSDT** corridor, that means:
|
||||
|
||||
- `cWAUSDT` appears on BSC, Polygon, Avalanche, and Celo
|
||||
- `cAUSDT` appears on Chain 138 via the live deployed address
|
||||
|
||||
For the planned **ALL Mainnet gold** corridor, the report remains intentionally env-gated until the destination contracts are live:
|
||||
|
||||
- `cAXAUC` / `cAXAUT` only appear on chain `651940` when `CAXAUC_ADDRESS_651940` / `CAXAUT_ADDRESS_651940` are set
|
||||
- `cWAXAUC` / `cWAXAUT` only appear on chain `651940` when `CWAXAUC_ADDRESS_651940` / `CWAXAUT_ADDRESS_651940` are set
|
||||
- generic `cXAUC` / `cXAUT` do **not** appear on `651940`; those remain canonical Chain 138 symbols
|
||||
|
||||
## ERC-20 and DEX Compatibility
|
||||
|
||||
All canonical tokens are designed to be **ERC-20 compliant** and usable in DEX liquidity pools (see `smom-dbis-138/docs/tokenization/TOKEN_SCOPE_GRU.md`). Base and asset tokens are fully transferable; debt tokens can be deployed with optional transferability. The report API does not enforce on-chain checks; it reports whatever is in the canonical list and DB (addresses, market data, pools).
|
||||
|
||||
@@ -37,7 +37,7 @@ cp .env.example .env
|
||||
2. Configure required variables:
|
||||
```bash
|
||||
# Required
|
||||
CHAIN_138_RPC_URL=https://rpc-http-pub.d-bis.org
|
||||
CHAIN_138_RPC_URL=http://192.168.11.221:8545
|
||||
CHAIN_651940_RPC_URL=https://mainnet-rpc.alltra.global
|
||||
DATABASE_URL=postgresql://user:password@localhost:5432/explorer_db
|
||||
|
||||
@@ -47,6 +47,8 @@ COINMARKETCAP_API_KEY=your_key_here
|
||||
DEXSCREENER_API_KEY=your_key_here
|
||||
```
|
||||
|
||||
For explorer/LAN deployments, `CHAIN_138_RPC_URL` should point to the public Chain 138 RPC node directly at `http://192.168.11.221:8545`. Use `https://rpc-http-pub.d-bis.org` for external-only consumers. Do not point explorer/read services at the operator core RPC `http://192.168.11.211:8545`.
|
||||
|
||||
## Local Deployment
|
||||
|
||||
### Using npm
|
||||
@@ -105,12 +107,15 @@ kind: ConfigMap
|
||||
metadata:
|
||||
name: token-aggregation-config
|
||||
data:
|
||||
CHAIN_138_RPC_URL: "https://rpc-http-pub.d-bis.org"
|
||||
CHAIN_138_RPC_URL: "http://192.168.11.221:8545"
|
||||
CHAIN_651940_RPC_URL: "https://mainnet-rpc.alltra.global"
|
||||
INDEXING_INTERVAL: "5000"
|
||||
ENABLE_INDEXER: "true"
|
||||
LOG_LEVEL: "info"
|
||||
```
|
||||
|
||||
Set `ENABLE_INDEXER` to `"false"` for public read-only explorer deployments that should serve API traffic without running the in-process multi-chain indexer.
|
||||
|
||||
2. Create a Secret for sensitive data:
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
|
||||
@@ -16,9 +16,15 @@ Returns supported chains.
|
||||
|
||||
### GET /api/v1/networks
|
||||
|
||||
Full EIP-3085 chain params for `wallet_addEthereumChain` (Chain 138, Ethereum Mainnet 1, ALL Mainnet 651940). Includes RPC URLs, block explorer URLs, native currency, and oracles per chain. Used by the MetaMask Snap to serve dynamic network and oracle data. If **NETWORKS_JSON_URL** is set (e.g. GitHub raw URL), the service fetches that URL and returns `{ version, networks }`; otherwise uses built-in networks.
|
||||
Full EIP-3085 chain params for `wallet_addEthereumChain` (Chain 138, Ethereum Mainnet 1, ALL Mainnet 651940). Includes RPC URLs, block explorer URLs, native currency, and oracles per chain. Used by the MetaMask Snap to serve dynamic network and oracle data. Source priority is:
|
||||
|
||||
**Response:** `{ version: string, networks: NetworkEntry[] }`
|
||||
1. **NETWORKS_JSON_URL** when configured
|
||||
2. **NETWORKS_JSON_PATH** / **CONFIG_NETWORKS_JSON_PATH** runtime local JSON
|
||||
3. built-in network config
|
||||
|
||||
Responses include `source: "remote-url" | "runtime-file" | "built-in"` and send `Cache-Control: public, max-age=0, must-revalidate`.
|
||||
|
||||
**Response:** `{ source, version: string, networks: NetworkEntry[], lastModified?: string }`
|
||||
Each `NetworkEntry` has: `chainId` (hex), `chainIdDecimal`, `chainName`, `rpcUrls`, `nativeCurrency`, `blockExplorerUrls`, `iconUrls` (chain-specific logos; optional), `oracles: [{ name, address, decimals? }]`. Chain 138 and ALL Mainnet include explorer favicons; Ethereum includes standard ETH logo.
|
||||
|
||||
### GET /api/v1/config
|
||||
@@ -27,14 +33,18 @@ Oracles (and config) per chain. Used by the Snap for USD price feeds (e.g. ETH/U
|
||||
|
||||
**Query:** `chainId` (optional) — if provided, returns config for that chain only.
|
||||
|
||||
**Response (no query):** `{ version: string, chains: [{ chainId, oracles: [{ name, address }] }] }`
|
||||
**Response (chainId=138):** `{ version, chainId: 138, oracles: [{ name, address }] }`
|
||||
`/api/v1/config` follows the same source priority as `/api/v1/networks`, so both endpoints read from the same freshest source rather than drifting.
|
||||
|
||||
**Response (no query):** `{ source, version: string, chains: [{ chainId, oracles: [{ name, address }] }] }`
|
||||
**Response (chainId=138):** `{ source, version, chainId: 138, oracles: [{ name, address }] }`
|
||||
|
||||
---
|
||||
|
||||
## Token list (report)
|
||||
|
||||
**GET /api/v1/report/token-list** returns a Uniswap-style token list with **logoURI** per token and a list-level **logoURI**. Each token has: `chainId`, `address`, `symbol`, `name`, `decimals`, `type`, `logoURI`. Use for MetaMask token list URL or Snap `get_token_list`. Optional query `?chainId=138` filters by chain. If **TOKEN_LIST_JSON_URL** is set (e.g. GitHub raw URL), the service fetches that JSON and returns it (with optional chainId filter); otherwise uses the built-in canonical token list.
|
||||
**GET /api/v1/report/token-list** returns a Uniswap-style token list with **logoURI** per token and a list-level **logoURI**. Each token has: `chainId`, `address`, `symbol`, `name`, `decimals`, `type`, `logoURI`. Chain 138 also exposes staged GRU x402 deployments such as `cUSDT_V2` and `cUSDC_V2` explicitly, with optional metadata fields like `familySymbol`, `deploymentVersion`, and `preferredForX402`. Use for MetaMask token list URL or Snap `get_token_list`. Optional query `?chainId=138` filters by chain. If **TOKEN_LIST_JSON_URL** is set (e.g. GitHub raw URL), the service fetches that JSON and returns it (with optional chainId filter); otherwise uses the built-in canonical token list.
|
||||
|
||||
**GET /api/v1/report/cw-registry** returns the public-chain `cW*` registry grouped by chain. When `DEPLOYMENT_STATUS_JSON_PATH` / `CW_REGISTRY_JSON_PATH` points to `cross-chain-pmm-lps/config/deployment-status.json`, the endpoint reads that file at request time so explorer surfaces do not need a rebuild after registry edits. If the file is unavailable, it falls back to the built-in canonical `cW*` subset.
|
||||
|
||||
---
|
||||
|
||||
@@ -42,7 +52,7 @@ Oracles (and config) per chain. Used by the Snap for USD price feeds (e.g. ETH/U
|
||||
|
||||
### GET /api/v1/quote
|
||||
|
||||
Returns an estimated swap output amount (constant-product from first available pool for the token pair).
|
||||
Returns an estimated swap output amount (constant-product from first available pool for the token pair). When a staged Chain 138 deployment such as `cUSDT_V2` or `cUSDC_V2` is requested before pool cutover, the response includes `canonicalLiquidity` showing whether the quote was resolved through the current active liquidity deployment.
|
||||
|
||||
**Query:**
|
||||
|
||||
@@ -62,12 +72,41 @@ If no pool is found, `amountOut` is `null` and `error` describes. Used by the Me
|
||||
|
||||
### GET /api/v1/bridge/routes
|
||||
|
||||
Returns CCIP bridge routes for WETH9 and WETH10 (Chain 138 and Ethereum Mainnet). Used by the MetaMask Snap and dApps for bridge discovery. If **BRIDGE_LIST_JSON_URL** is set (e.g. GitHub raw URL), the service fetches that JSON and returns `{ routes, chain138Bridges }`; otherwise uses built-in routes.
|
||||
Returns CCIP bridge routes for WETH9 and WETH10 (Chain 138 and Ethereum Mainnet). Used by the MetaMask Snap and dApps for bridge discovery. Source priority is:
|
||||
|
||||
**Response:** `{ routes, chain138Bridges, tokenMappingApi? }`
|
||||
1. **BRIDGE_LIST_JSON_URL** when configured
|
||||
2. **BRIDGE_LIST_JSON_PATH** / **BRIDGE_ROUTES_JSON_PATH** runtime local JSON
|
||||
3. built-in routes
|
||||
|
||||
If the remote URL is configured but fails, the route falls back to the runtime file or built-in payload rather than returning stale hard failure data. Responses include `source` and send `Cache-Control: public, max-age=0, must-revalidate`.
|
||||
|
||||
**Response:** `{ source, routes, chain138Bridges, tokenMappingApi?, lastModified? }`
|
||||
- `routes`: `{ weth9: Record<string, string>, weth10: Record<string, string> }` — destination chain name → bridge address.
|
||||
- `chain138Bridges`: `{ weth9: string, weth10: string }` — Chain 138 bridge addresses.
|
||||
- `tokenMappingApi`: When the service runs from the monorepo, `{ basePath, pairs, resolve, note }` — use the same host and these paths for **cross-chain token address resolution** (138↔651940, 651940↔other chains). Bridge UIs should call `GET /api/v1/token-mapping?fromChain=&toChain=` or `GET /api/v1/token-mapping/resolve?fromChain=&toChain=&address=` when resolving token addresses on destination chains.
|
||||
- `gruTransport.summary`: when GRU Transport overlay is available, includes counts such as `transportPairs`, `eligibleTransportPairs`, and `runtimeReadyTransportPairs`.
|
||||
|
||||
### GET /api/v1/bridge/status
|
||||
|
||||
Returns GRU Monetary Transport Layer pair status, including structural `eligible`, operational `runtimeReady`, and per-pair blockers.
|
||||
|
||||
**Response:** `{ ok, bridges, gruTransport, message }`
|
||||
- `gruTransport.summary`: overlay counts
|
||||
- `gruTransport.pairs[]`: `{ key, canonicalSymbol, mirroredSymbol, destinationChainId, eligible, runtimeReady, eligibilityBlockers[], runtimeMissingRequirements[] }`
|
||||
|
||||
### GET /api/v1/bridge/metrics
|
||||
|
||||
Returns GRU Transport summary counts suitable for dashboards.
|
||||
|
||||
**Response:** `{ ok, lanes, gruTransport: { system, summary }, message }`
|
||||
|
||||
### GET /api/v1/bridge/preflight
|
||||
|
||||
Returns a preflight view of GRU Transport readiness. Use this before deploy, restart, or route enablement.
|
||||
|
||||
**Response:** `{ ok, generatedAt, gruTransport: { system, summary, blockedPairs[], readyPairs[] } }`
|
||||
- `blockedPairs[]`: pairs that are not structurally eligible or not runtime-ready, with `eligibilityBlockers[]` and `runtimeMissingRequirements[]`
|
||||
- `readyPairs[]`: minimal list of pairs fully ready to carry live traffic
|
||||
|
||||
---
|
||||
|
||||
@@ -79,8 +118,11 @@ When run from the monorepo (with `config/token-mapping-multichain.json` availabl
|
||||
|----------|-------------|
|
||||
| `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/transport/active` | Full GRU Transport overlay view, including counts and active transport pair metadata. |
|
||||
| `GET /api/v1/token-mapping/resolve?fromChain=&toChain=&address=` | Resolve token address on target chain. |
|
||||
|
||||
`GET /api/v1/token-mapping/resolve` also returns `activeTransportEligible`, `gruTransportRuntimeReady`, and `gruTransportPairKey` when the address maps into an active GRU pair.
|
||||
|
||||
Use these for bridge UIs and cross-chain address resolution. See token-aggregation README § Token mapping.
|
||||
|
||||
---
|
||||
@@ -187,7 +229,7 @@ Returns service and database health. Response: `{ status: 'healthy'|'unhealthy',
|
||||
|
||||
## Caching and rate limiting
|
||||
|
||||
- Endpoints use short-lived cache (e.g. 1–5 minutes). Use `Cache-Control` headers from responses.
|
||||
- Endpoints use short-lived cache (e.g. 1–5 minutes). Send `?refresh=1` to bypass the in-process cache when an explorer or operator view needs the latest read immediately.
|
||||
- `/api/v1` is rate-limited; see server configuration for limits.
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user