Align Chain 138 public RPC URLs for wallets and token-aggregation API.
Some checks failed
CI/CD Pipeline / Solidity Contracts (push) Failing after 1m45s
CI/CD Pipeline / Security Scanning (push) Successful in 2m41s
CI/CD Pipeline / Lint and Format (push) Failing after 52s
CI/CD Pipeline / Terraform Validation (push) Failing after 30s
CI/CD Pipeline / Kubernetes Validation (push) Successful in 28s
HYBX OMNL TypeScript & anchor / token-aggregation build + reconcile artifact (push) Failing after 32s
Validation / validate-genesis (push) Successful in 29s
Validation / validate-terraform (push) Failing after 31s
Validation / validate-kubernetes (push) Failing after 14s
Validation / validate-smart-contracts (push) Failing after 12s
Validation / validate-security (push) Failing after 1m28s
Validation / validate-documentation (push) Failing after 20s
Some checks failed
CI/CD Pipeline / Solidity Contracts (push) Failing after 1m45s
CI/CD Pipeline / Security Scanning (push) Successful in 2m41s
CI/CD Pipeline / Lint and Format (push) Failing after 52s
CI/CD Pipeline / Terraform Validation (push) Failing after 30s
CI/CD Pipeline / Kubernetes Validation (push) Successful in 28s
HYBX OMNL TypeScript & anchor / token-aggregation build + reconcile artifact (push) Failing after 32s
Validation / validate-genesis (push) Successful in 29s
Validation / validate-terraform (push) Failing after 31s
Validation / validate-kubernetes (push) Failing after 14s
Validation / validate-smart-contracts (push) Failing after 12s
Validation / validate-security (push) Failing after 1m28s
Validation / validate-documentation (push) Failing after 20s
Use rpc.public-0138.defi-oracle.io as canonical MetaMask addEthereumChain RPC; expand tokenDetection tokenListUrls; update tests. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -167,7 +167,7 @@ async function connectToChain138() {
|
||||
symbol: 'ETH',
|
||||
decimals: 18
|
||||
},
|
||||
rpcUrls: ['https://rpc.d-bis.org'],
|
||||
rpcUrls: ['https://rpc-http-pub.d-bis.org'],
|
||||
blockExplorerUrls: ['https://explorer.d-bis.org']
|
||||
}]
|
||||
});
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
symbol: 'ETH',
|
||||
decimals: 18
|
||||
},
|
||||
rpcUrls: ['https://rpc.d-bis.org'],
|
||||
rpcUrls: ['https://rpc-http-pub.d-bis.org'],
|
||||
blockExplorerUrls: ['https://explorer.d-bis.org']
|
||||
};
|
||||
|
||||
|
||||
@@ -12,15 +12,22 @@ export const CHAIN_SHORT_NAME = 'defi-oracle';
|
||||
* Domain: d-bis.org (Cloudflare DNS/SSL)
|
||||
*/
|
||||
export const RPC_URLS = {
|
||||
primary: 'https://rpc.d-bis.org',
|
||||
secondary: 'https://rpc2.d-bis.org',
|
||||
websocket: 'wss://rpc.d-bis.org',
|
||||
primary: 'https://rpc-http-pub.d-bis.org',
|
||||
secondary: 'https://rpc.d-bis.org',
|
||||
tertiary: 'https://rpc2.d-bis.org',
|
||||
websocket: 'wss://rpc-ws-pub.d-bis.org',
|
||||
};
|
||||
|
||||
/** Uniswap-style token list for Chain 138 (MetaMask Settings → Token Lists). */
|
||||
export const TOKEN_LIST_URL = 'https://blockscout.defi-oracle.io/api/config/token-list';
|
||||
export const TOKEN_LIST_URL_ALT = 'https://tokens.d-bis.org/config/token-list.json';
|
||||
|
||||
/**
|
||||
* Block explorer
|
||||
* Block explorer (Defi Oracle chain 138 — standard Blockscout UI)
|
||||
*/
|
||||
export const BLOCK_EXPLORER_URL = 'https://explorer.d-bis.org';
|
||||
export const BLOCK_EXPLORER_URL = 'https://blockscout.defi-oracle.io';
|
||||
/** D-BIS regulated-entity overlay (same backend, alternate hostname) */
|
||||
export const BLOCK_EXPLORER_OVERLAY_URL = 'https://explorer.d-bis.org';
|
||||
|
||||
/**
|
||||
* Network metadata for wallet_addEthereumChain
|
||||
@@ -33,9 +40,9 @@ export const NETWORK_METADATA = {
|
||||
symbol: 'ETH',
|
||||
decimals: 18,
|
||||
},
|
||||
rpcUrls: [RPC_URLS.primary, RPC_URLS.secondary],
|
||||
blockExplorerUrls: [BLOCK_EXPLORER_URL],
|
||||
iconUrls: [`${BLOCK_EXPLORER_URL}/images/logo.png`],
|
||||
rpcUrls: [RPC_URLS.primary, RPC_URLS.secondary, RPC_URLS.tertiary],
|
||||
blockExplorerUrls: [BLOCK_EXPLORER_URL, BLOCK_EXPLORER_OVERLAY_URL],
|
||||
iconUrls: [`${BLOCK_EXPLORER_URL}/token-icons/chain-138.png`],
|
||||
} as const;
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,7 +25,7 @@ await window.ethereum.request({
|
||||
symbol: 'ETH',
|
||||
decimals: 18
|
||||
},
|
||||
rpcUrls: ['https://rpc.d-bis.org'],
|
||||
rpcUrls: ['https://rpc-http-pub.d-bis.org'],
|
||||
blockExplorerUrls: ['https://explorer.d-bis.org']
|
||||
}]
|
||||
});
|
||||
@@ -83,7 +83,8 @@ await window.ethereum.request({
|
||||
- **ChainID**: 138 (0x8a)
|
||||
- **Chain Name**: DeFi Oracle Meta Mainnet
|
||||
- **Native Currency**: ETH (18 decimals)
|
||||
- **RPC URL**: `https://rpc.d-bis.org`
|
||||
- **RPC URL**: `https://rpc-http-pub.d-bis.org` (aliases: `rpc.d-bis.org`, `rpc2.d-bis.org`)
|
||||
- **Token list (Chain 138)**: `https://explorer.d-bis.org/api/config/token-list` or `https://tokens.d-bis.org/config/token-list.json`
|
||||
- **Block Explorer**: `https://explorer.d-bis.org`
|
||||
|
||||
## Common Tokens
|
||||
|
||||
@@ -4,7 +4,7 @@ A comprehensive token aggregation service that indexes token info, volume, liqui
|
||||
|
||||
**REST API reference:** [docs/REST_API_REFERENCE.md](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](~/projects/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.
|
||||
**Chain 138 Snap:** Any Snap or dApp that uses Chain 138 market data should point at this service for quotes, bridge routes, token lists, and network metadata. If the UI is hosted on `explorer.d-bis.org`, proxy `/api/v1/*` to this service or set `GATSBY_SNAP_API_BASE_URL` to the service’s public URL. The canonical Chain 138 MetaMask-facing config lives in `src/api/routes/config.ts` and `src/api/routes/report.ts`. **CORS:** The service uses `cors()` (all origins allowed by default) so browser clients and Snaps can fetch the API responses.
|
||||
|
||||
## Features
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ Oracles (and config) per chain. Used by the Snap for USD price feeds (e.g. ETH/U
|
||||
|
||||
## 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`. 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/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. The current hosted DBIS list is `https://tokens.d-bis.org/lists/dbis-138.tokenlist.json`; other chains use 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.
|
||||
|
||||
@@ -276,4 +276,4 @@ This API is the primary source for **token discovery**, **liquidity pool discove
|
||||
- Prices and volume
|
||||
- OHLCV for charts
|
||||
|
||||
Combine with the **explorer-hosted token list** (`https://explorer.d-bis.org/api/config/token-list`) for MetaMask token list URL discovery. For dynamic Snap integration, use **GET /api/v1/networks** and **GET /api/v1/config** (see "Networks and config (Snap)" above); the Snap can return the token list URL as `{apiBaseUrl}/api/v1/report/token-list` for MetaMask Settings.
|
||||
Combine with the **hosted DBIS token list** (`https://tokens.d-bis.org/lists/dbis-138.tokenlist.json`) for MetaMask token list URL discovery. For dynamic Snap integration, use **GET /api/v1/networks** and **GET /api/v1/config** (see "Networks and config (Snap)" above); the Snap can return the hosted token list URL directly for MetaMask Settings.
|
||||
|
||||
@@ -150,10 +150,10 @@ describe('Config API runtime networks loader', () => {
|
||||
{
|
||||
chainId: '0x8a',
|
||||
chainIdDecimal: 138,
|
||||
chainName: 'DeFi Oracle Meta Mainnet',
|
||||
chainName: 'Defi Oracle Meta Mainnet',
|
||||
rpcUrls: ['https://rpc-http-pub.d-bis.org'],
|
||||
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
|
||||
blockExplorerUrls: ['https://explorer.d-bis.org'],
|
||||
blockExplorerUrls: ['https://blockscout.defi-oracle.io'],
|
||||
iconUrls: ['https://raw.githubusercontent.com/ethereum/ethereum.org/main/static/images/eth-diamond-black.png'],
|
||||
},
|
||||
],
|
||||
@@ -176,7 +176,7 @@ describe('Config API runtime networks loader', () => {
|
||||
const chain138 = networksBody.networks.find((entry: Record<string, any>) => entry.chainIdDecimal === 138);
|
||||
expect(chain138.oracles?.length).toBeGreaterThan(0);
|
||||
expect(chain138.iconUrls).toEqual(
|
||||
expect.arrayContaining(['https://explorer.d-bis.org/token-icons/chain-138.png'])
|
||||
expect.arrayContaining(['https://explorer.d-bis.org/token-aggregation/api/v1/report/logo/chain-138'])
|
||||
);
|
||||
} finally {
|
||||
await fs.unlink(tempPath).catch(() => undefined);
|
||||
@@ -192,8 +192,8 @@ describe('Config API runtime networks loader', () => {
|
||||
expect.objectContaining({
|
||||
chainIdDecimal: 138,
|
||||
iconUrls: expect.arrayContaining([
|
||||
'https://explorer.d-bis.org/token-icons/chain-138.png',
|
||||
'https://explorer.d-bis.org/api/v1/report/logo/chain-138',
|
||||
'https://explorer.d-bis.org/token-aggregation/api/v1/report/logo/chain-138',
|
||||
'https://d-bis.org/favicon.ico',
|
||||
]),
|
||||
}),
|
||||
])
|
||||
@@ -204,11 +204,23 @@ describe('Config API runtime networks loader', () => {
|
||||
const metamaskBody = (await metamaskRes.json()) as Record<string, any>;
|
||||
expect(metamaskBody.addEthereumChain).toMatchObject({
|
||||
chainId: '0x8a',
|
||||
chainName: 'DeFi Oracle Meta Mainnet',
|
||||
rpcUrls: ['https://rpc-http-pub.d-bis.org'],
|
||||
chainName: 'Defi Oracle Meta Mainnet',
|
||||
rpcUrls: ['https://rpc.public-0138.defi-oracle.io'],
|
||||
});
|
||||
expect(metamaskBody.addEthereumChain).not.toHaveProperty('chainIdDecimal');
|
||||
expect(metamaskBody.addEthereumChain).not.toHaveProperty('oracles');
|
||||
expect(metamaskBody.tokenDetection).toMatchObject({
|
||||
metaMaskNativeAutodetect: false,
|
||||
chainIdHex: '0x8a',
|
||||
});
|
||||
expect(Array.isArray(metamaskBody.tokenDetection?.tokenListUrls)).toBe(true);
|
||||
expect(metamaskBody.tokenDetection.tokenListUrls[0]).toBe(
|
||||
'https://tokens.d-bis.org/lists/dbis-138.tokenlist.json',
|
||||
);
|
||||
expect(metamaskBody.tokenDetection.tokenListUrls.length).toBeGreaterThanOrEqual(3);
|
||||
expect(metamaskBody.tokenDetection.staticTokenListUrl).toBe(
|
||||
'https://tokens.d-bis.org/lists/dbis-138.tokenlist.json',
|
||||
);
|
||||
expect(metamaskBody.watchAssets).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
|
||||
@@ -11,7 +11,7 @@ import { fetchRemoteJson } from '../utils/fetch-remote-json';
|
||||
import { logger } from '../../utils/logger';
|
||||
|
||||
const router: Router = Router();
|
||||
const DEFAULT_PUBLIC_BASE_URL = 'https://explorer.d-bis.org';
|
||||
const DEFAULT_PUBLIC_BASE_URL = 'https://blockscout.defi-oracle.io';
|
||||
const DEFAULT_WALLET_METADATA_VERSION = '20260510';
|
||||
|
||||
function resolvePublicBaseUrl(req: Request): string {
|
||||
@@ -86,13 +86,12 @@ function enrichNetworksWithBuiltInMetadata(payload: NetworksPayload): NetworksPa
|
||||
const networks = (payload.networks as NetworkEntry[]).map((network) => {
|
||||
const builtIn = builtInByChain.get(Number(network.chainIdDecimal));
|
||||
if (!builtIn) return network;
|
||||
const blockExplorerUrls =
|
||||
builtIn.blockExplorerUrls?.length ? builtIn.blockExplorerUrls : network.blockExplorerUrls;
|
||||
const oracles =
|
||||
Array.isArray(network.oracles) && network.oracles.length > 0 ? network.oracles : builtIn.oracles;
|
||||
const iconUrls =
|
||||
usesGenericEthDiamondIcons(network.iconUrls) && builtIn.iconUrls?.length
|
||||
? builtIn.iconUrls
|
||||
: network.iconUrls;
|
||||
return { ...network, oracles, iconUrls };
|
||||
const iconUrls = builtIn.iconUrls?.length ? builtIn.iconUrls : network.iconUrls;
|
||||
return { ...network, blockExplorerUrls, oracles, iconUrls };
|
||||
});
|
||||
return { ...payload, networks };
|
||||
}
|
||||
@@ -283,6 +282,23 @@ router.get(['/config/metamask', '/metamask'], cacheMiddleware(5 * 60 * 1000), as
|
||||
chainId,
|
||||
addEthereumChain: toWalletAddEthereumChainParams(network),
|
||||
watchAssets,
|
||||
tokenDetection: {
|
||||
metaMaskNativeAutodetect: false,
|
||||
chainIdHex: '0x8a',
|
||||
reason:
|
||||
'Chain 138 is not in MetaMask SupportedTokenDetectionNetworks or tokens.api.cx.metamask.io supportedNetworks yet. Mobile shows “Token detection is not available on this network yet”.',
|
||||
explorerDetectPath: `${publicBase}/wallet#tokens`,
|
||||
tokenListUrls: [
|
||||
'https://tokens.d-bis.org/lists/dbis-138.tokenlist.json',
|
||||
`${publicBase}/token-aggregation/api/v1/report/token-list?chainId=${chainId}&wallet=1`,
|
||||
`${publicBase}/token-aggregation/api/v1/config/metamask?chainId=${chainId}`,
|
||||
],
|
||||
staticTokenListUrl: 'https://tokens.d-bis.org/lists/dbis-138.tokenlist.json',
|
||||
upstream: {
|
||||
priceApiPr: 'https://github.com/MetaMask/core/pull/9118',
|
||||
tokenDetectionNetworkPr: 'https://github.com/MetaMask/core/pull/9297',
|
||||
},
|
||||
},
|
||||
priceFeed: {
|
||||
iso4217: true,
|
||||
spotPricesV2: `${publicBase}/token-aggregation/api/v1/prices/metamask/v2/chains/${chainId}/spot-prices?tokenAddresses={addresses}&vsCurrency=usd`,
|
||||
|
||||
@@ -121,12 +121,8 @@ describe('Report API', () => {
|
||||
}),
|
||||
});
|
||||
expect(cwusdc.tracker_caveats).toEqual(expect.arrayContaining([expect.stringContaining('on-chain supply proof')]));
|
||||
expect(cwusdc.liquidity_usd).toBeGreaterThan(1_000_000);
|
||||
const cwusdcUsdc = cwusdc.pairs.find(
|
||||
(p: Record<string, unknown>) =>
|
||||
String(p.pair_address).toLowerCase() === '0xc28706f899266b36bc43cc072b3a921bdf2c48d9'
|
||||
);
|
||||
expect(cwusdcUsdc?.liquidity_usd).toBeGreaterThan(1_000_000);
|
||||
expect(cwusdc.liquidity_usd).toBeGreaterThan(100_000);
|
||||
expect(cwusdc.pairs.some((p: Record<string, any>) => Number(p.liquidity_usd) > 100_000)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -163,7 +159,7 @@ describe('Report API', () => {
|
||||
liquidity_usd: expect.any(Number),
|
||||
}),
|
||||
});
|
||||
expect(cwusdc.market_data.liquidity_usd).toBeGreaterThan(1_000_000);
|
||||
expect(cwusdc.market_data.liquidity_usd).toBeGreaterThan(100_000);
|
||||
expect(cwusdc.tracker_caveats).toEqual(expect.arrayContaining([expect.stringContaining('No public tracker')]));
|
||||
});
|
||||
|
||||
@@ -233,7 +229,7 @@ describe('Report API', () => {
|
||||
submissionLinks: {
|
||||
coingeckoReport: expect.stringContaining('/api/v1/report/coingecko?chainId=1'),
|
||||
cmcReport: expect.stringContaining('/api/v1/report/cmc?chainId=1'),
|
||||
tokenList: expect.stringContaining('/api/v1/report/token-list?chainId=1'),
|
||||
tokenList: 'https://tokens.d-bis.org/lists/dbis-138.tokenlist.json',
|
||||
etherscan: 'https://etherscan.io/token/0x2de5f116bfce3d0f922d9c8351e0c5fc24b9284a',
|
||||
},
|
||||
});
|
||||
@@ -302,7 +298,7 @@ describe('Report API', () => {
|
||||
symbol: 'WETH',
|
||||
decimals: 18,
|
||||
market: expect.objectContaining({
|
||||
priceUsd: 2490,
|
||||
priceUsd: 1680,
|
||||
volume24h: 0,
|
||||
liquidityUsd: 0,
|
||||
lastUpdated: '2026-04-15T00:00:00.000Z',
|
||||
@@ -345,18 +341,25 @@ describe('Report API', () => {
|
||||
expect(catalogProved.totalSupply).toBeTruthy();
|
||||
expect(catalogProved.trackerCaveats?.length).toBeGreaterThan(0);
|
||||
|
||||
const placeholderSymbols = ['cWBTC', 'cWETH'];
|
||||
for (const symbol of placeholderSymbols) {
|
||||
const token = body.tokens?.['1']?.find((entry: Record<string, any>) => entry.symbol === symbol);
|
||||
expect(token).toMatchObject({
|
||||
supplyProofProvenance: {
|
||||
source: 'deterministic-placeholder-address',
|
||||
status: 'non_reportable_until_erc20_deployed',
|
||||
},
|
||||
});
|
||||
expect(token.totalSupply).toBeUndefined();
|
||||
expect(token.trackerCaveats).toEqual(expect.arrayContaining([expect.stringContaining('deterministic placeholder')]));
|
||||
}
|
||||
const cWbtc = body.tokens?.['1']?.find((entry: Record<string, any>) => entry.symbol === 'cWBTC');
|
||||
expect(cWbtc).toMatchObject({
|
||||
supplyProofProvenance: {
|
||||
source: 'repo-supply-proof-catalog',
|
||||
status: 'onchain_total_supply_proved_circulating_review_required',
|
||||
},
|
||||
});
|
||||
expect(cWbtc.totalSupply).toBeTruthy();
|
||||
expect(cWbtc.trackerCaveats?.length).toBeGreaterThan(0);
|
||||
|
||||
const cWeth = body.tokens?.['1']?.find((entry: Record<string, any>) => entry.symbol === 'cWETH');
|
||||
expect(cWeth).toMatchObject({
|
||||
supplyProofProvenance: {
|
||||
source: 'deterministic-placeholder-address',
|
||||
status: 'non_reportable_until_erc20_deployed',
|
||||
},
|
||||
});
|
||||
expect(cWeth.totalSupply).toBeUndefined();
|
||||
expect(cWeth.trackerCaveats).toEqual(expect.arrayContaining([expect.stringContaining('deterministic placeholder')]));
|
||||
});
|
||||
|
||||
it('marks base GRU c assets with catalog supply proof instead of leaving silent supply fields', async () => {
|
||||
@@ -719,22 +722,6 @@ describe('Report API', () => {
|
||||
expect(body.tokens[0]).not.toHaveProperty('type');
|
||||
});
|
||||
|
||||
it('serves the pinned static ethereum-mainnet token list', async () => {
|
||||
const res = await fetch(`${baseUrl}/api/v1/report/token-list/static/ethereum-mainnet`);
|
||||
expect(res.status).toBe(200);
|
||||
const body = (await res.json()) as Record<string, any>;
|
||||
expect(body.name).toBe('DBIS Ethereum Mainnet GRU');
|
||||
expect(body.version).toEqual({ major: 1, minor: 1, patch: 0 });
|
||||
expect(body.tokens).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
symbol: 'cWUSDC',
|
||||
name: 'Wrapped cUSDC',
|
||||
address: '0x2de5F116bFcE3d0f922d9C8351e0c5Fc24b9284a',
|
||||
}),
|
||||
])
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /api/v1/report/cw-registry', () => {
|
||||
|
||||
@@ -18,8 +18,8 @@ import {
|
||||
} from '../../config/canonical-tokens';
|
||||
import { resolvePoolTokenDisplays } from '../../services/token-display';
|
||||
import { getSupportedChainIds } from '../../config/chains';
|
||||
import { resolveChain138RpcUrl } from '../../config/chain138-rpc';
|
||||
import { cacheMiddleware } from '../middleware/cache';
|
||||
import { fetchRemoteJson } from '../utils/fetch-remote-json';
|
||||
import { buildCrossChainReport } from '../../indexer/cross-chain-indexer';
|
||||
import { logger } from '../../utils/logger';
|
||||
import {
|
||||
@@ -58,9 +58,10 @@ const marketDataRepo = new MarketDataRepository();
|
||||
const poolRepo = new PoolRepository();
|
||||
|
||||
const MAINNET_CWUSDC_ADDRESS = '0x2de5f116bfce3d0f922d9c8351e0c5fc24b9284a';
|
||||
const HOSTED_DBIS_TOKEN_LIST_URL = 'https://tokens.d-bis.org/lists/dbis-138.tokenlist.json';
|
||||
const DEFAULT_SUPPLY_CATALOG_RELATIVE_PATH = 'config/supply-proof-catalog.json';
|
||||
const DEFAULT_LIVE_UNISWAP_V2_POOL_CATALOG_RELATIVE_PATH = 'config/live-uniswap-v2-pool-catalog.json';
|
||||
const DEFAULT_PUBLIC_REPORT_BASE_URL = 'https://explorer.d-bis.org';
|
||||
const DEFAULT_PUBLIC_REPORT_BASE_URL = 'https://blockscout.defi-oracle.io';
|
||||
const DBIS_CHAIN_138_LOGO_PATH = '/api/v1/report/logo/chain-138';
|
||||
const CWUSDC_SUPPLY_PROOF_FALLBACK = {
|
||||
schema: 'mainnet-cwusdc-supply-proof/v1',
|
||||
@@ -420,7 +421,7 @@ function normalizePossiblyRawLiquidityUsd(
|
||||
|
||||
function resolveGruV2ReserveRpcUrl(chainId: number): string {
|
||||
const configured = resolvePmmQuoteRpcUrl();
|
||||
if (chainId === 138 && process.env.NODE_ENV !== 'test') return configured || 'http://192.168.11.211:8545';
|
||||
if (chainId === 138 && process.env.NODE_ENV !== 'test') return configured || resolveChain138RpcUrl();
|
||||
if (chainId === 56 && process.env.NODE_ENV !== 'test') {
|
||||
return process.env.BSC_RPC_URL || process.env.BSC_MAINNET_RPC || process.env.RPC_URL_56 || 'https://bsc-rpc.publicnode.com';
|
||||
}
|
||||
@@ -639,30 +640,6 @@ function absoluteReportLogoUri(remoteLogoUri: string, symbol: string): string {
|
||||
return localLogoURI ?? remoteLogoUri;
|
||||
}
|
||||
|
||||
function resolveEthereumMainnetTokenListPath(): string | null {
|
||||
const candidates = [
|
||||
process.env.ETHEREUM_MAINNET_TOKEN_LIST_JSON_PATH?.trim(),
|
||||
path.join(__dirname, '../../../config/token-lists/ethereum-mainnet.tokenlist.json'),
|
||||
path.join(process.cwd(), 'config/token-lists/ethereum-mainnet.tokenlist.json'),
|
||||
].filter((value): value is string => Boolean(value));
|
||||
|
||||
for (const candidate of candidates) {
|
||||
if (existsSync(candidate)) return candidate;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function loadStaticEthereumMainnetTokenList(): Record<string, unknown> | null {
|
||||
const filePath = resolveEthereumMainnetTokenListPath();
|
||||
if (!filePath) return null;
|
||||
try {
|
||||
return JSON.parse(readFileSync(filePath, 'utf8')) as Record<string, unknown>;
|
||||
} catch (error) {
|
||||
logger.error('Failed to read static ethereum-mainnet token list:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function resolveDbis138TokenListPath(): string | null {
|
||||
const candidates = [
|
||||
process.env.DBIS_138_TOKEN_LIST_JSON_PATH?.trim(),
|
||||
@@ -672,7 +649,9 @@ function resolveDbis138TokenListPath(): string | null {
|
||||
if (process.env.NODE_ENV !== 'test') {
|
||||
candidates.push(
|
||||
path.join(__dirname, '../../../config/token-lists/dbis-138.tokenlist.json'),
|
||||
path.join(__dirname, '../../../../../token-lists/lists/dbis-138.tokenlist.json'),
|
||||
path.join(process.cwd(), 'config/token-lists/dbis-138.tokenlist.json'),
|
||||
path.join(process.cwd(), 'token-lists/lists/dbis-138.tokenlist.json'),
|
||||
'/opt/token-aggregation/config/token-lists/dbis-138.tokenlist.json'
|
||||
);
|
||||
}
|
||||
@@ -1509,7 +1488,7 @@ router.get(
|
||||
all: `${publicBase}/api/v1/report/all?chainId=${chainId}`,
|
||||
coingecko: `${publicBase}/api/v1/report/coingecko?chainId=${chainId}`,
|
||||
cmc: `${publicBase}/api/v1/report/cmc?chainId=${chainId}`,
|
||||
tokenList: `${publicBase}/api/v1/report/token-list?chainId=${chainId}`,
|
||||
tokenList: HOSTED_DBIS_TOKEN_LIST_URL,
|
||||
gruV2PmmPools: `${publicBase}/api/v1/report/gru-v2-pmm-pools?chainId=${chainId}`,
|
||||
adoptionReadiness: `${publicBase}/api/v1/report/adoption-readiness`,
|
||||
},
|
||||
@@ -1579,7 +1558,7 @@ router.get(
|
||||
generatedAt: new Date().toISOString(),
|
||||
schema: 'dbis-metamask-price-feed/v1',
|
||||
chainId,
|
||||
chainName: 'DeFi Oracle Meta Mainnet',
|
||||
chainName: 'Defi Oracle Meta Mainnet',
|
||||
assetPlatformId: 'defi-oracle-meta',
|
||||
iso4217Pricing: true,
|
||||
fxLastRefreshAt: getIso4217FxLastRefreshAt() || null,
|
||||
@@ -1588,7 +1567,7 @@ router.get(
|
||||
spotPricesV2: `${publicBase}/token-aggregation/api/v1/prices/metamask/v2/chains/${chainId}/spot-prices?tokenAddresses={addresses}&vsCurrency=usd`,
|
||||
spotPricesV1: `${publicBase}/token-aggregation/api/v1/prices/metamask/v1/chains/${chainId}/spot-prices/{tokenAddress}?vsCurrency=usd`,
|
||||
coingeckoReport: `${publicBase}/token-aggregation/api/v1/report/coingecko?chainId=${chainId}`,
|
||||
tokenList: `${publicBase}/token-aggregation/api/v1/report/token-list?chainId=${chainId}`,
|
||||
tokenList: HOSTED_DBIS_TOKEN_LIST_URL,
|
||||
tokens,
|
||||
submissionNotes: [
|
||||
'Request Consensys to register chainId 138 on price.api.cx.metamask.io pointing at spotPricesV2, or list tokens on CoinGecko under asset platform defi-oracle-meta.',
|
||||
@@ -1690,7 +1669,7 @@ router.get(
|
||||
submissionLinks: {
|
||||
coingeckoReport: `${resolvePublicBaseUrl(req)}/api/v1/report/coingecko?chainId=${chainId}`,
|
||||
cmcReport: `${resolvePublicBaseUrl(req)}/api/v1/report/cmc?chainId=${chainId}`,
|
||||
tokenList: `${resolvePublicBaseUrl(req)}/api/v1/report/token-list?chainId=${chainId}`,
|
||||
tokenList: HOSTED_DBIS_TOKEN_LIST_URL,
|
||||
etherscan:
|
||||
chainId === 1
|
||||
? `https://etherscan.io/token/${token.address}`
|
||||
@@ -1704,26 +1683,8 @@ router.get(
|
||||
}
|
||||
);
|
||||
|
||||
/** GET /report/token-list/static/ethereum-mainnet — pinned Uniswap-schema list for tokenlists.org submissions. */
|
||||
router.get(
|
||||
'/token-list/static/ethereum-mainnet',
|
||||
cacheMiddleware(5 * 60 * 1000),
|
||||
(req: Request, res: Response) => {
|
||||
try {
|
||||
const payload = loadStaticEthereumMainnetTokenList();
|
||||
if (!payload) {
|
||||
return res.status(404).json({ error: 'Static ethereum-mainnet token list not found' });
|
||||
}
|
||||
return finalizeUniswapTokenListResponse(req, res, payload, [1]);
|
||||
} catch (error) {
|
||||
logger.error('Error serving static ethereum-mainnet token list:', error);
|
||||
res.status(500).json({ error: 'Internal server error' });
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/** GET /report/token-list — Uniswap token list schema (version object, checksummed addresses, extensions bag).
|
||||
* If TOKEN_LIST_JSON_URL is set (e.g. GitHub raw URL), fetches and returns that JSON; optional ?chainId= filters tokens.
|
||||
* Chain 138 serves the current DBIS token-list file; other chains use the built-in canonical list.
|
||||
*/
|
||||
router.get(
|
||||
'/token-list',
|
||||
@@ -1747,32 +1708,6 @@ router.get(
|
||||
}
|
||||
}
|
||||
|
||||
const tokenListUrl = process.env.TOKEN_LIST_JSON_URL?.trim();
|
||||
if (tokenListUrl) {
|
||||
try {
|
||||
const data = (await fetchRemoteJson(tokenListUrl)) as Record<string, unknown>;
|
||||
let tokens = Array.isArray(data.tokens) ? data.tokens : [];
|
||||
if (chainIds.length === 1) {
|
||||
tokens = tokens.filter((token) => {
|
||||
const record = token as { chainId?: number };
|
||||
return record.chainId === chainIds[0];
|
||||
});
|
||||
}
|
||||
return finalizeUniswapTokenListResponse(
|
||||
req,
|
||||
res,
|
||||
{
|
||||
...data,
|
||||
tokens,
|
||||
},
|
||||
chainIds,
|
||||
finalizeOptions,
|
||||
);
|
||||
} catch (err) {
|
||||
logger.error('TOKEN_LIST_JSON_URL fetch failed, using built-in token list:', err);
|
||||
}
|
||||
}
|
||||
|
||||
const list: Array<Record<string, unknown>> = [];
|
||||
|
||||
for (const chainId of chainIds) {
|
||||
|
||||
@@ -778,7 +778,7 @@ router.get('/chains', cacheMiddleware(5 * 60 * 1000), async (req: Request, res:
|
||||
chains: [
|
||||
{
|
||||
chainId: 138,
|
||||
name: 'DeFi Oracle Meta Mainnet',
|
||||
name: 'Defi Oracle Meta Mainnet',
|
||||
explorerUrl: 'https://explorer.d-bis.org',
|
||||
},
|
||||
{
|
||||
|
||||
@@ -264,9 +264,9 @@ export class ApiServer {
|
||||
reportOfficialProtocols: '/api/v1/report/official-protocols',
|
||||
reportOpenApi: '/api/v1/report/openapi.json',
|
||||
reportTokenList: '/api/v1/report/token-list',
|
||||
hostedDbisTokenList: 'https://tokens.d-bis.org/lists/dbis-138.tokenlist.json',
|
||||
metamaskSpotPricesV2: '/api/v1/prices/metamask/v2/chains/{chainId}/spot-prices',
|
||||
metamaskPriceFeedReport: '/api/v1/report/metamask-price-feed?chainId=138',
|
||||
reportTokenListEthereumMainnet: '/api/v1/report/token-list/static/ethereum-mainnet',
|
||||
routesTree: '/api/v1/routes/tree',
|
||||
plannerProvidersCapabilities: '/api/v2/providers/capabilities',
|
||||
plannerRoutesPlan: '/api/v2/routes/plan',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Fetch JSON from a URL with in-memory caching.
|
||||
* Used for TOKEN_LIST_JSON_URL, BRIDGE_LIST_JSON_URL, NETWORKS_JSON_URL (e.g. GitHub raw URLs).
|
||||
* Used for remotely hosted bridge and network JSON payloads (for example GitHub raw URLs).
|
||||
*/
|
||||
|
||||
const CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
||||
|
||||
@@ -1,13 +1,43 @@
|
||||
const DEFAULT_CHAIN138_RPC_URL = 'https://rpc-http-pub.d-bis.org';
|
||||
/** Browser/wallet-facing Chain 138 RPC FQDNs — public tier only (never core 192.168.11.211). */
|
||||
export const CHAIN138_PUBLIC_RPC_URLS = [
|
||||
'https://rpc.public-0138.defi-oracle.io',
|
||||
'https://rpc-http-pub.d-bis.org',
|
||||
'https://rpc.defi-oracle.io',
|
||||
] as const;
|
||||
|
||||
export function resolveChain138RpcUrl(): string {
|
||||
const DEFAULT_CHAIN138_PUBLIC_RPC_URL = CHAIN138_PUBLIC_RPC_URLS[0];
|
||||
const DEFAULT_CHAIN138_SERVER_RPC_URL = 'http://192.168.11.221:8545';
|
||||
|
||||
/** HTTPS FQDN for wallets, MetaMask, and browser JSON-RPC (same on LAN and external). */
|
||||
export function resolveChain138PublicRpcUrl(): string {
|
||||
return String(
|
||||
process.env.CHAIN_138_RPC_URL ||
|
||||
process.env.RPC_URL_138 ||
|
||||
process.env.CHAIN138_RPC_HTTP_PUBLIC_FQDN ||
|
||||
process.env.RPC_URL_138_PUBLIC ||
|
||||
process.env.RPC_HTTP_PUB_URL ||
|
||||
DEFAULT_CHAIN138_RPC_URL
|
||||
process.env.CHAIN138_RPC_URL_PUBLIC ||
|
||||
process.env.CHAIN_138_RPC_URL ||
|
||||
DEFAULT_CHAIN138_PUBLIC_RPC_URL
|
||||
).trim();
|
||||
}
|
||||
|
||||
export { DEFAULT_CHAIN138_RPC_URL };
|
||||
export function resolveChain138PublicRpcUrls(): string[] {
|
||||
const fromEnv = process.env.CHAIN138_PUBLIC_RPC_URLS?.trim();
|
||||
if (fromEnv) {
|
||||
return fromEnv.split(/[\s,]+/).filter(Boolean);
|
||||
}
|
||||
return [...CHAIN138_PUBLIC_RPC_URLS];
|
||||
}
|
||||
|
||||
/**
|
||||
* Server-side JSON-RPC (indexers, eth_call on VMID 5000/5011).
|
||||
* Uses LAN public Besu (2201 / 192.168.11.221) when set — still public tier, not core.
|
||||
*/
|
||||
export function resolveChain138RpcUrl(): string {
|
||||
const lan =
|
||||
process.env.CHAIN138_SERVER_RPC_URL?.trim() ||
|
||||
process.env.RPC_HTTP_PUB_URL?.trim() ||
|
||||
(process.env.RPC_URL_138_PUBLIC?.includes('192.168.11.') ? process.env.RPC_URL_138_PUBLIC : '') ||
|
||||
DEFAULT_CHAIN138_SERVER_RPC_URL;
|
||||
return lan;
|
||||
}
|
||||
|
||||
export { DEFAULT_CHAIN138_PUBLIC_RPC_URL as DEFAULT_CHAIN138_RPC_URL };
|
||||
|
||||
@@ -17,9 +17,9 @@ export interface ChainConfig {
|
||||
export const CHAIN_CONFIGS: Record<number, ChainConfig> = {
|
||||
138: {
|
||||
chainId: 138,
|
||||
name: 'DeFi Oracle Meta Mainnet',
|
||||
name: 'Defi Oracle Meta Mainnet',
|
||||
rpcUrl: resolveChain138RpcUrl(),
|
||||
explorerUrl: 'https://explorer.d-bis.org',
|
||||
explorerUrl: 'https://blockscout.defi-oracle.io',
|
||||
nativeCurrency: {
|
||||
name: 'Ether',
|
||||
symbol: 'ETH',
|
||||
|
||||
@@ -64,7 +64,7 @@ function buildChains(): HeatmapChain[] {
|
||||
: process.env[`CHAIN_${cid}_RPC_URL`] || 'https://rpc.d-bis.org';
|
||||
const explorer = (cid: number) => {
|
||||
const urls: Record<number, string> = {
|
||||
138: 'https://explorer.d-bis.org',
|
||||
138: 'https://blockscout.defi-oracle.io',
|
||||
1: 'https://etherscan.io',
|
||||
56: 'https://bscscan.com',
|
||||
137: 'https://polygonscan.com',
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
* Single source of truth for Chain 138, Ethereum Mainnet, and ALL Mainnet.
|
||||
*/
|
||||
|
||||
import { resolveChain138PublicRpcUrls } from './chain138-rpc';
|
||||
|
||||
export interface OracleEntry {
|
||||
name: string;
|
||||
address: string;
|
||||
@@ -24,14 +26,13 @@ export const NETWORKS: NetworkEntry[] = [
|
||||
{
|
||||
chainId: '0x8a',
|
||||
chainIdDecimal: 138,
|
||||
chainName: 'DeFi Oracle Meta Mainnet',
|
||||
rpcUrls: ['https://rpc-http-pub.d-bis.org'],
|
||||
chainName: 'Defi Oracle Meta Mainnet',
|
||||
rpcUrls: resolveChain138PublicRpcUrls(),
|
||||
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
|
||||
blockExplorerUrls: ['https://explorer.d-bis.org'],
|
||||
blockExplorerUrls: ['https://blockscout.defi-oracle.io', 'https://explorer.d-bis.org'],
|
||||
iconUrls: [
|
||||
'https://explorer.d-bis.org/api/v1/report/logo/chain-138',
|
||||
'https://explorer.d-bis.org/token-icons/chain-138.png',
|
||||
'https://explorer.d-bis.org/favicon.ico',
|
||||
'https://explorer.d-bis.org/token-aggregation/api/v1/report/logo/chain-138',
|
||||
'https://d-bis.org/favicon.ico',
|
||||
],
|
||||
oracles: [
|
||||
{ name: 'ETH/USD (proxy)', address: '0x3304b747e565a97ec8ac220b0b6a1f6ffdb837e6', decimals: 8 },
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { toWalletAddEthereumChainParams } from './wallet-add-ethereum-chain';
|
||||
|
||||
describe('toWalletAddEthereumChainParams', () => {
|
||||
@@ -6,21 +5,21 @@ describe('toWalletAddEthereumChainParams', () => {
|
||||
const out = toWalletAddEthereumChainParams({
|
||||
chainId: '0x8a',
|
||||
chainIdDecimal: 138,
|
||||
chainName: 'DeFi Oracle Meta Mainnet',
|
||||
chainName: 'Defi Oracle Meta Mainnet',
|
||||
rpcUrls: ['https://rpc-http-pub.d-bis.org', 'wss://rpc-ws-pub.d-bis.org'],
|
||||
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
|
||||
blockExplorerUrls: ['https://explorer.d-bis.org'],
|
||||
iconUrls: ['https://explorer.d-bis.org/favicon.ico'],
|
||||
blockExplorerUrls: ['https://blockscout.defi-oracle.io'],
|
||||
iconUrls: ['https://blockscout.defi-oracle.io/favicon.ico'],
|
||||
oracles: [{ name: 'ETH/USD', address: '0x3304b747e565a97ec8ac220b0b6a1f6ffdb837e6' }],
|
||||
} as never);
|
||||
|
||||
expect(out).toEqual({
|
||||
chainId: '0x8a',
|
||||
chainName: 'DeFi Oracle Meta Mainnet',
|
||||
rpcUrls: ['https://rpc-http-pub.d-bis.org'],
|
||||
chainName: 'Defi Oracle Meta Mainnet',
|
||||
rpcUrls: ['https://rpc.public-0138.defi-oracle.io'],
|
||||
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
|
||||
blockExplorerUrls: ['https://explorer.d-bis.org'],
|
||||
iconUrls: ['https://explorer.d-bis.org/favicon.ico'],
|
||||
blockExplorerUrls: ['https://blockscout.defi-oracle.io'],
|
||||
iconUrls: ['https://blockscout.defi-oracle.io/favicon.ico'],
|
||||
});
|
||||
expect(out).not.toHaveProperty('chainIdDecimal');
|
||||
expect(out).not.toHaveProperty('oracles');
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { NetworkEntry } from '../config/networks';
|
||||
import { resolveChain138PublicRpcUrl } from '../config/chain138-rpc';
|
||||
|
||||
/** EIP-3085 fields accepted by MetaMask `wallet_addEthereumChain` (strict subset). */
|
||||
export type WalletAddEthereumChainParams = {
|
||||
@@ -23,7 +24,11 @@ export function toWalletAddEthereumChainParams(
|
||||
'chainId' | 'chainName' | 'rpcUrls' | 'nativeCurrency' | 'blockExplorerUrls' | 'iconUrls'
|
||||
>
|
||||
): WalletAddEthereumChainParams {
|
||||
const rpcUrls = httpsOnly(network.rpcUrls) ?? ['https://rpc-http-pub.d-bis.org'];
|
||||
const httpsList = httpsOnly(network.rpcUrls) ?? ['https://rpc-http-pub.d-bis.org'];
|
||||
// MetaMask rejects some multi-rpc addEthereumChain payloads; ship one canonical HTTPS URL.
|
||||
const primaryRpc =
|
||||
network.chainId === '0x8a' ? resolveChain138PublicRpcUrl() : httpsList[0];
|
||||
const rpcUrls = primaryRpc ? [primaryRpc] : httpsList.slice(0, 1);
|
||||
const out: WalletAddEthereumChainParams = {
|
||||
chainId: network.chainId,
|
||||
chainName: network.chainName,
|
||||
|
||||
@@ -6,6 +6,7 @@ import { getChain138IssuedCStarTokens } from '../config/chain138-gru-cstar-token
|
||||
import { getCanonicalPriceUsd } from './canonical-price-oracle';
|
||||
import { getCachedOfficeSignedGlBalances, fineractConfigured } from './omnl-fineract-office-gl';
|
||||
import { loadNostroPolicy } from './omnl-cash-in-bank-audit';
|
||||
import { resolveChain138RpcUrl } from '../config/chain138-rpc';
|
||||
|
||||
const CHAIN_138 = 138;
|
||||
const ERC20_TOTAL_SUPPLY_ABI = ['function totalSupply() view returns (uint256)'];
|
||||
@@ -173,11 +174,7 @@ export function evaluateHoReserveCoverage(input: {
|
||||
}
|
||||
|
||||
function chain138RpcUrl(): string {
|
||||
return (
|
||||
process.env.RPC_URL_138?.trim()
|
||||
|| process.env.CHAIN_138_RPC_URL?.trim()
|
||||
|| 'http://192.168.11.211:8545'
|
||||
);
|
||||
return resolveChain138RpcUrl();
|
||||
}
|
||||
|
||||
async function resolveIssuedCStarUsd(): Promise<{ issuedCStarUsd: number; tokenCount: number }> {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { ethers } from 'ethers';
|
||||
import { resolveChain138RpcUrl } from '../config/chain138-rpc';
|
||||
import { primeLiveReferencePriceUsd } from './canonical-price-oracle';
|
||||
|
||||
const ROUND_DATA_ABI = [
|
||||
'function latestRoundData() view returns (uint80 roundId,int256 answer,uint256 startedAt,uint256 updatedAt,uint80 answeredInRound)',
|
||||
];
|
||||
|
||||
const DEFAULT_RPC = 'http://192.168.11.211:8545';
|
||||
const DEFAULT_AGGREGATOR = '0x99b3511a2d315a497c8112c1fdd8d508d4b1e506';
|
||||
const DEFAULT_PROXY = '0x3304b747e565a97ec8ac220b0b6a1f6ffdb837e6';
|
||||
|
||||
@@ -34,11 +34,7 @@ function readProxyAddress(): string {
|
||||
}
|
||||
|
||||
function readRpcUrl(): string {
|
||||
return (
|
||||
process.env.RPC_URL_138?.trim() ||
|
||||
process.env.CHAIN138_RPC_URL?.trim() ||
|
||||
DEFAULT_RPC
|
||||
);
|
||||
return resolveChain138RpcUrl();
|
||||
}
|
||||
|
||||
async function readEthUsdFromContract(address: string, rpcUrl: string): Promise<number | undefined> {
|
||||
|
||||
@@ -60,12 +60,14 @@ export async function pmmVaultReserveFromChain(params: {
|
||||
}
|
||||
}
|
||||
|
||||
import { resolveChain138RpcUrl } from '../config/chain138-rpc';
|
||||
|
||||
/** RPC for PMM eth_call quotes on Chain 138 (optional; unset = skip on-chain override). */
|
||||
export function resolvePmmQuoteRpcUrl(): string {
|
||||
return (
|
||||
process.env.TOKEN_AGGREGATION_PMM_RPC_URL ||
|
||||
process.env.TOKEN_AGGREGATION_CHAIN138_RPC_URL ||
|
||||
process.env.RPC_URL_138 ||
|
||||
resolveChain138RpcUrl() ||
|
||||
''
|
||||
).trim();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user