/** * Load relay mappings, GRU transport overlay config, routing registry, and deployment JSON. * Used by relay service, token-aggregation, bridge/LP tooling, and docs. Safe to publish. * * @version 2026-03-30 */ const path = require('path'); const fs = require('fs'); const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; const DEFAULT_JSON_PATH = path.resolve(__dirname, 'token-mapping.json'); const DEFAULT_MULTICHAIN_JSON_PATH = path.resolve(__dirname, 'token-mapping-multichain.json'); const DEFAULT_GRU_ACTIVE_JSON_PATH = path.resolve(__dirname, 'gru-transport-active.json'); const DEFAULT_ROUTING_REGISTRY_JSON_PATH = path.resolve(__dirname, 'routing-registry.json'); const DEFAULT_DEPLOYMENT_STATUS_JSON_PATH = path.resolve( __dirname, '..', 'cross-chain-pmm-lps', 'config', 'deployment-status.json' ); const DEFAULT_POOL_MATRIX_JSON_PATH = path.resolve( __dirname, '..', 'cross-chain-pmm-lps', 'config', 'pool-matrix.json' ); const JSON_CACHES = { token: null, multichain: null, gruTransport: null, routingRegistry: null, deploymentStatus: null, poolMatrix: null, }; function loadCachedJson(cacheKey, jsonPath) { const current = JSON_CACHES[cacheKey]; if (current && current.path === jsonPath) return current.data; try { const raw = fs.readFileSync(jsonPath, 'utf8'); const data = JSON.parse(raw); JSON_CACHES[cacheKey] = { path: jsonPath, data }; return data; } catch (e) { return null; } } function normalizeAddress(address) { return typeof address === 'string' ? address.trim().toLowerCase() : ''; } function normalizeSymbol(symbol) { return typeof symbol === 'string' ? symbol.trim().toLowerCase() : ''; } function normalizeTransportSymbol(symbol) { const normalized = normalizeSymbol(symbol).replace(/[\s_-]/g, ''); if (normalized.startsWith('cw')) { return `c${normalized.slice(2)}`; } return normalized; } function isNonZeroAddress(address) { const normalized = normalizeAddress(address); return /^0x[a-f0-9]{40}$/.test(normalized) && normalized !== ZERO_ADDRESS; } function resolveConfigRef(ref) { if (!ref || typeof ref !== 'object') return ''; if (isNonZeroAddress(ref.address)) return ref.address; if (typeof ref.env === 'string' && isNonZeroAddress(process.env[ref.env])) { return process.env[ref.env]; } return ''; } function hasConfigRef(ref) { if (!ref || typeof ref !== 'object') return false; return isNonZeroAddress(ref.address) || (typeof ref.env === 'string' && ref.env.trim() !== ''); } function resolvePolicyRefValue(ref) { if (!ref || typeof ref !== 'object') return ''; if (typeof ref.amount === 'string' && ref.amount.trim() !== '') return ref.amount.trim(); if (typeof ref.env === 'string') { const value = process.env[ref.env]; if (typeof value === 'string' && value.trim() !== '') return value.trim(); } return ''; } function loadTokenMappingJson(jsonPath = DEFAULT_JSON_PATH) { return loadCachedJson('token', jsonPath); } function loadTokenMappingMultichainJson(jsonPath = DEFAULT_MULTICHAIN_JSON_PATH) { return loadCachedJson('multichain', jsonPath); } function loadGruTransportActiveJson(jsonPath = DEFAULT_GRU_ACTIVE_JSON_PATH) { return loadCachedJson('gruTransport', jsonPath); } function loadRoutingRegistryJson(jsonPath = DEFAULT_ROUTING_REGISTRY_JSON_PATH) { return loadCachedJson('routingRegistry', jsonPath); } function loadDeploymentStatusJson(jsonPath = DEFAULT_DEPLOYMENT_STATUS_JSON_PATH) { return loadCachedJson('deploymentStatus', jsonPath); } function loadPoolMatrixJson(jsonPath = DEFAULT_POOL_MATRIX_JSON_PATH) { return loadCachedJson('poolMatrix', jsonPath); } function getRelayTokenMapping(jsonPath) { const data = loadTokenMappingJson(jsonPath); if (!data || !Array.isArray(data.tokens)) return {}; const out = {}; for (const t of data.tokens) { if (t.chain138Address && t.mainnetAddress) { out[t.chain138Address] = t.mainnetAddress; } } return out; } function getTokenList(jsonPath) { const data = loadTokenMappingJson(jsonPath); if (!data || !Array.isArray(data.tokens)) return []; return data.tokens; } function getTokenMappingForPair(fromChainId, toChainId, jsonPath) { const data = loadTokenMappingMultichainJson(jsonPath); if (!data || !Array.isArray(data.pairs)) return null; const from = Number(fromChainId); const to = Number(toChainId); let pair = data.pairs.find((p) => p.fromChainId === from && p.toChainId === to); let reverse = false; if (!pair) { pair = data.pairs.find((p) => p.fromChainId === to && p.toChainId === from); reverse = true; } if (!pair || !Array.isArray(pair.tokens)) return null; const tokens = reverse ? pair.tokens.map((t) => ({ key: t.key, name: t.name, addressFrom: t.addressTo, addressTo: t.addressFrom, notes: t.notes, })) : pair.tokens; const addressMapFromTo = {}; const addressMapToFrom = {}; for (const t of tokens) { if (t.addressFrom && t.addressTo) { addressMapFromTo[t.addressFrom.toLowerCase()] = t.addressTo; addressMapToFrom[t.addressTo.toLowerCase()] = t.addressFrom; } } return { tokens, addressMapFromTo, addressMapToFrom }; } function getAllMultichainPairs(jsonPath) { const data = loadTokenMappingMultichainJson(jsonPath); if (!data || !Array.isArray(data.pairs)) return []; return data.pairs.map((p) => ({ fromChainId: p.fromChainId, toChainId: p.toChainId, notes: p.notes })); } function getMappedAddress(fromChainId, toChainId, tokenAddressOnSource, jsonPath) { const activeTransportPair = getActiveTransportPair( fromChainId, toChainId, { sourceTokenAddress: tokenAddressOnSource }, { multichainJsonPath: jsonPath } ); if (activeTransportPair) { const sameDirection = Number(activeTransportPair.canonicalChainId) === Number(fromChainId) && Number(activeTransportPair.destinationChainId) === Number(toChainId); const targetAddress = sameDirection ? activeTransportPair.mirroredAddress : activeTransportPair.canonicalAddress; if (isNonZeroAddress(targetAddress)) { return targetAddress; } } const result = getTokenMappingForPair(fromChainId, toChainId, jsonPath); if (!result) return undefined; return result.addressMapFromTo[String(tokenAddressOnSource).toLowerCase()]; } function getRoutingRegistryRoutes(jsonPath = DEFAULT_ROUTING_REGISTRY_JSON_PATH) { const data = loadRoutingRegistryJson(jsonPath); if (!data || !Array.isArray(data.routes)) return []; return data.routes; } function getGruTransportMetadata(jsonPath = DEFAULT_GRU_ACTIVE_JSON_PATH) { const data = loadGruTransportActiveJson(jsonPath); if (!data || typeof data !== 'object') return null; const activeTransportPairs = getActiveTransportPairs({ activeJsonPath: jsonPath }); const activePublicPools = getActivePublicPools(jsonPath); return { system: data.system || null, terminology: data.terminology || {}, enabledCanonicalTokens: Array.isArray(data.enabledCanonicalTokens) ? data.enabledCanonicalTokens : [], enabledDestinationChains: Array.isArray(data.enabledDestinationChains) ? data.enabledDestinationChains : [], counts: { enabledCanonicalTokens: Array.isArray(data.enabledCanonicalTokens) ? data.enabledCanonicalTokens.length : 0, enabledDestinationChains: Array.isArray(data.enabledDestinationChains) ? data.enabledDestinationChains.length : 0, approvedBridgePeers: Array.isArray(data.approvedBridgePeers) ? data.approvedBridgePeers.length : 0, transportPairs: Array.isArray(data.transportPairs) ? data.transportPairs.length : 0, eligibleTransportPairs: activeTransportPairs.filter((pair) => pair.eligible).length, runtimeReadyTransportPairs: activeTransportPairs.filter((pair) => pair.runtimeReady).length, publicPools: Array.isArray(data.publicPools) ? data.publicPools.length : 0, activePublicPools: activePublicPools.filter((pool) => pool.active === true).length, routablePublicPools: activePublicPools.filter( (pool) => pool.active === true && pool.routingEnabled === true ).length, mcpVisiblePublicPools: activePublicPools.filter( (pool) => pool.active === true && pool.mcpVisible === true ).length, }, }; } function getEnabledCanonicalTokens(jsonPath = DEFAULT_GRU_ACTIVE_JSON_PATH) { const data = loadGruTransportActiveJson(jsonPath); if (!data || !Array.isArray(data.enabledCanonicalTokens)) return []; return data.enabledCanonicalTokens; } function getEnabledCanonicalToken(identifier, jsonPath = DEFAULT_GRU_ACTIVE_JSON_PATH) { const normalizedSymbol = normalizeSymbol(identifier || ''); const normalizedAddress = normalizeAddress(identifier || ''); return ( getEnabledCanonicalTokens(jsonPath).find((token) => { if (normalizedSymbol) { if (normalizeSymbol(token.symbol) === normalizedSymbol) return true; if (normalizeSymbol(token.mirroredSymbol) === normalizedSymbol) return true; } if (!normalizedAddress) return false; if (normalizeAddress(token.activeAddress) === normalizedAddress) return true; if (normalizeAddress(token.x402PreferredAddress) === normalizedAddress) return true; if (Array.isArray(token.deployments)) { return token.deployments.some((deployment) => normalizeAddress(deployment.address) === normalizedAddress); } return false; }) || null ); } function getEnabledDestinationChains(jsonPath = DEFAULT_GRU_ACTIVE_JSON_PATH) { const data = loadGruTransportActiveJson(jsonPath); if (!data || !Array.isArray(data.enabledDestinationChains)) return []; return data.enabledDestinationChains; } function isCanonicalTokenActive(symbol, jsonPath = DEFAULT_GRU_ACTIVE_JSON_PATH) { const normalized = normalizeSymbol(symbol); return getEnabledCanonicalTokens(jsonPath).some((token) => normalizeSymbol(token.symbol) === normalized); } function isDestinationChainActive(chainId, jsonPath = DEFAULT_GRU_ACTIVE_JSON_PATH) { const numericChainId = Number(chainId); return getEnabledDestinationChains(jsonPath).some((chain) => Number(chain.chainId) === numericChainId); } function getApprovedBridgePeer(chainId, jsonPath = DEFAULT_GRU_ACTIVE_JSON_PATH) { const data = loadGruTransportActiveJson(jsonPath); if (!data || !Array.isArray(data.approvedBridgePeers)) return null; const numericChainId = Number(chainId); return data.approvedBridgePeers.find((peer) => Number(peer.chainId) === numericChainId) || null; } function getRawMappingTokenEntry(fromChainId, toChainId, mappingKey, jsonPath = DEFAULT_MULTICHAIN_JSON_PATH) { const data = loadTokenMappingMultichainJson(jsonPath); if (!data || !Array.isArray(data.pairs)) return null; const pair = data.pairs.find( (entry) => Number(entry.fromChainId) === Number(fromChainId) && Number(entry.toChainId) === Number(toChainId) ); if (!pair || !Array.isArray(pair.tokens)) return null; return pair.tokens.find((token) => token.key === mappingKey) || null; } function getActiveTransportPairs(options = {}) { const activeJsonPath = options.activeJsonPath || DEFAULT_GRU_ACTIVE_JSON_PATH; const multichainJsonPath = options.multichainJsonPath || DEFAULT_MULTICHAIN_JSON_PATH; const deploymentJsonPath = options.deploymentJsonPath || DEFAULT_DEPLOYMENT_STATUS_JSON_PATH; const active = loadGruTransportActiveJson(activeJsonPath); const deployment = loadDeploymentStatusJson(deploymentJsonPath); if (!active || !Array.isArray(active.transportPairs)) return []; const enabledCanonicalTokens = new Set( (Array.isArray(active.enabledCanonicalTokens) ? active.enabledCanonicalTokens : []).map((token) => normalizeSymbol(token.symbol)) ); const enabledDestinationChains = new Set( (Array.isArray(active.enabledDestinationChains) ? active.enabledDestinationChains : []).map((chain) => Number(chain.chainId)) ); const peersByKey = new Map( (Array.isArray(active.approvedBridgePeers) ? active.approvedBridgePeers : []).map((peer) => [String(peer.key), peer]) ); const reserveVerifiers = active.reserveVerifiers && typeof active.reserveVerifiers === 'object' ? active.reserveVerifiers : {}; return active.transportPairs.map((pair) => { const canonicalChainId = Number(pair.canonicalChainId ?? active.system?.canonicalChainId ?? 138); const destinationChainId = Number(pair.destinationChainId); const canonicalSymbol = String(pair.canonicalSymbol || '').trim(); const mirroredSymbol = String(pair.mirroredSymbol || '').trim(); const mappingEntry = getRawMappingTokenEntry(canonicalChainId, destinationChainId, pair.mappingKey, multichainJsonPath); const deploymentChain = deployment && deployment.chains && typeof deployment.chains === 'object' ? deployment.chains[String(destinationChainId)] || null : null; const mirrorDeploymentAddress = deploymentChain && deploymentChain.cwTokens && typeof deploymentChain.cwTokens === 'object' ? deploymentChain.cwTokens[mirroredSymbol] || null : null; const peer = peersByKey.get(String(pair.peerKey || '')) || null; const maxOutstanding = pair.maxOutstanding && typeof pair.maxOutstanding === 'object' ? pair.maxOutstanding : {}; const reserveVerifier = pair.reserveVerifierKey ? reserveVerifiers[pair.reserveVerifierKey] : null; const routeDiscoveryEnabled = pair.routeDiscoveryEnabled !== false; const canonicalAddress = mappingEntry?.addressFrom || null; const mirroredAddress = mappingEntry?.addressTo || null; const runtimeL1BridgeAddress = peer ? resolveConfigRef(peer.l1Bridge) : ''; const runtimeL2BridgeAddress = peer ? resolveConfigRef(peer.l2Bridge) : ''; const runtimeMaxOutstandingValue = resolvePolicyRefValue(maxOutstanding); const runtimeReserveVerifier = reserveVerifier && typeof reserveVerifier === 'object' ? reserveVerifier : null; const runtimeReserveVerifierBridgeAddress = runtimeReserveVerifier ? resolveConfigRef(runtimeReserveVerifier.bridgeRef) : ''; const runtimeReserveVerifierAddress = runtimeReserveVerifier ? resolveConfigRef(runtimeReserveVerifier.verifierRef) : ''; const runtimeReserveVaultAddress = runtimeReserveVerifier ? resolveConfigRef(runtimeReserveVerifier.vaultRef) : ''; const runtimeReserveSystemAddress = runtimeReserveVerifier ? resolveConfigRef(runtimeReserveVerifier.reserveSystemRef) : ''; const mirrorDeployed = isNonZeroAddress(mirrorDeploymentAddress) && isNonZeroAddress(mirroredAddress) && normalizeAddress(mirrorDeploymentAddress) === normalizeAddress(mirroredAddress); const bridgePeerConfigured = !!peer && hasConfigRef(peer.l1Bridge) && hasConfigRef(peer.l2Bridge); const maxOutstandingConfigured = !maxOutstanding.required || !!maxOutstanding.amount || !!maxOutstanding.env; const reserveVerifierConfigured = !pair.reserveVerifierKey || (!!runtimeReserveVerifier && hasConfigRef(runtimeReserveVerifier.bridgeRef) && hasConfigRef(runtimeReserveVerifier.verifierRef) && (!runtimeReserveVerifier.requireVaultBacking || hasConfigRef(runtimeReserveVerifier.vaultRef)) && (!runtimeReserveVerifier.requireReserveSystemBalance || hasConfigRef(runtimeReserveVerifier.reserveSystemRef)) && (!runtimeReserveVerifier.requireTokenOwnerMatchVault || hasConfigRef(runtimeReserveVerifier.vaultRef))); const runtimeBridgeReady = !!runtimeL1BridgeAddress && !!runtimeL2BridgeAddress; const runtimeMaxOutstandingReady = !maxOutstanding.required || !!runtimeMaxOutstandingValue; const runtimeReserveVerifierReady = !pair.reserveVerifierKey || (!!runtimeReserveVerifierBridgeAddress && !!runtimeReserveVerifierAddress && (!runtimeReserveVerifier.requireVaultBacking || !!runtimeReserveVaultAddress) && (!runtimeReserveVerifier.requireReserveSystemBalance || !!runtimeReserveSystemAddress) && (!runtimeReserveVerifier.requireTokenOwnerMatchVault || !!runtimeReserveVaultAddress)); const eligibilityBlockers = []; if (!routeDiscoveryEnabled) eligibilityBlockers.push('policy:routeDiscoveryDisabled'); if (!enabledCanonicalTokens.has(normalizeSymbol(canonicalSymbol))) { eligibilityBlockers.push('overlay:canonicalTokenDisabled'); } if (!enabledDestinationChains.has(destinationChainId)) { eligibilityBlockers.push('overlay:destinationChainDisabled'); } if (!mappingEntry) eligibilityBlockers.push('mapping:pairMissing'); if (!isNonZeroAddress(canonicalAddress)) eligibilityBlockers.push('mapping:canonicalAddressMissing'); if (!isNonZeroAddress(mirroredAddress)) eligibilityBlockers.push('mapping:mirroredAddressMissing'); if (!mirrorDeployed) eligibilityBlockers.push('deployment:mirroredTokenNotDeployed'); if (!bridgePeerConfigured) eligibilityBlockers.push('config:bridgePeerRefMissing'); if (!maxOutstandingConfigured) eligibilityBlockers.push('config:maxOutstandingRefMissing'); if (!reserveVerifierConfigured) eligibilityBlockers.push('config:reserveVerifierRefMissing'); const eligible = eligibilityBlockers.length === 0; const runtimeMissingRequirements = []; if (!runtimeL1BridgeAddress) runtimeMissingRequirements.push('bridge:l1Bridge'); if (!runtimeL2BridgeAddress) runtimeMissingRequirements.push('bridge:l2Bridge'); if (maxOutstanding.required && !runtimeMaxOutstandingValue) { runtimeMissingRequirements.push('policy:maxOutstanding'); } if (pair.reserveVerifierKey) { if (!runtimeReserveVerifierBridgeAddress) runtimeMissingRequirements.push('reserveVerifier:bridgeRef'); if (!runtimeReserveVerifierAddress) runtimeMissingRequirements.push('reserveVerifier:verifierRef'); if (runtimeReserveVerifier?.requireVaultBacking && !runtimeReserveVaultAddress) { runtimeMissingRequirements.push('reserveVerifier:vaultRef'); } if (runtimeReserveVerifier?.requireReserveSystemBalance && !runtimeReserveSystemAddress) { runtimeMissingRequirements.push('reserveVerifier:reserveSystemRef'); } } if (deploymentChain?.bridgeAvailable === false) { runtimeMissingRequirements.push('deployment:bridgeUnavailable'); } const runtimeReady = eligible && runtimeMissingRequirements.length === 0; return { ...pair, canonicalChainId, destinationChainId, canonicalSymbol, mirroredSymbol, canonicalAddress, mirroredAddress, mirrorDeploymentAddress, peer, mappingFound: !!mappingEntry, mirrorDeployed, canonicalEnabled: enabledCanonicalTokens.has(normalizeSymbol(canonicalSymbol)), destinationEnabled: enabledDestinationChains.has(destinationChainId), bridgeAvailable: deploymentChain?.bridgeAvailable ?? null, bridgePeerConfigured, maxOutstandingConfigured, reserveVerifierConfigured, runtimeL1BridgeAddress: runtimeL1BridgeAddress || null, runtimeL2BridgeAddress: runtimeL2BridgeAddress || null, runtimeBridgeReady, runtimeMaxOutstandingValue: runtimeMaxOutstandingValue || null, runtimeMaxOutstandingReady, runtimeReserveVerifierBridgeAddress: runtimeReserveVerifierBridgeAddress || null, runtimeReserveVerifierAddress: runtimeReserveVerifierAddress || null, runtimeReserveVaultAddress: runtimeReserveVaultAddress || null, runtimeReserveSystemAddress: runtimeReserveSystemAddress || null, runtimeReserveVerifierReady, runtimeMissingRequirements, eligibilityBlockers, runtimeReady, eligible, }; }); } function getActiveTransportPair(fromChainId, toChainId, criteria = {}, options = {}) { const from = Number(fromChainId); const to = Number(toChainId); const normalizedSymbol = normalizeTransportSymbol( criteria.symbol || criteria.canonicalSymbol || criteria.mirroredSymbol || '' ); const normalizedSourceAddress = normalizeAddress( criteria.address || criteria.sourceTokenAddress || criteria.tokenAddress || '' ); const normalizedTargetAddress = normalizeAddress(criteria.targetTokenAddress || ''); return ( getActiveTransportPairs(options).find((pair) => { const sameDirection = pair.canonicalChainId === from && pair.destinationChainId === to; const reverseDirection = pair.canonicalChainId === to && pair.destinationChainId === from; if (!sameDirection && !reverseDirection) return false; if (normalizedSymbol) { const pairSymbols = new Set([ normalizeTransportSymbol(pair.canonicalSymbol), normalizeTransportSymbol(pair.mirroredSymbol), normalizeSymbol(pair.canonicalSymbol), normalizeSymbol(pair.mirroredSymbol), ]); if (!pairSymbols.has(normalizedSymbol)) return false; } if (normalizedSourceAddress) { const allowedSourceAddresses = sameDirection ? [pair.canonicalAddress, pair.mirroredAddress] : [pair.mirroredAddress, pair.canonicalAddress]; if (!allowedSourceAddresses.some((address) => normalizeAddress(address) === normalizedSourceAddress)) { return false; } } if (normalizedTargetAddress) { const targetAddress = sameDirection ? pair.mirroredAddress : pair.canonicalAddress; if (normalizeAddress(targetAddress) !== normalizedTargetAddress) return false; } return true; }) || null ); } function getKnownMirroredTokenAddresses(chainId, options = {}) { const multichainJsonPath = options.multichainJsonPath || DEFAULT_MULTICHAIN_JSON_PATH; const deploymentJsonPath = options.deploymentJsonPath || DEFAULT_DEPLOYMENT_STATUS_JSON_PATH; const data = loadTokenMappingMultichainJson(multichainJsonPath); const deployment = loadDeploymentStatusJson(deploymentJsonPath); const chainKey = String(Number(chainId)); const out = new Set(); if (deployment && deployment.chains && deployment.chains[chainKey]?.cwTokens) { for (const address of Object.values(deployment.chains[chainKey].cwTokens)) { if (isNonZeroAddress(address)) out.add(normalizeAddress(address)); } } if (data && Array.isArray(data.pairs)) { const pair = data.pairs.find((entry) => Number(entry.fromChainId) === 138 && Number(entry.toChainId) === Number(chainId)); if (pair && Array.isArray(pair.tokens)) { for (const token of pair.tokens) { if (String(token.key || '').endsWith('_cW') && isNonZeroAddress(token.addressTo)) { out.add(normalizeAddress(token.addressTo)); } } } } return Array.from(out); } function getActivePublicPools(jsonPath = DEFAULT_GRU_ACTIVE_JSON_PATH) { const data = loadGruTransportActiveJson(jsonPath); if (!data || !Array.isArray(data.publicPools)) return []; return data.publicPools; } function getPublicPoolRecord(chainId, poolAddress, jsonPath = DEFAULT_GRU_ACTIVE_JSON_PATH) { if (!isNonZeroAddress(poolAddress)) return null; const normalizedPoolAddress = normalizeAddress(poolAddress); return ( getActivePublicPools(jsonPath).find( (pool) => Number(pool.chainId) === Number(chainId) && normalizeAddress(pool.poolAddress) === normalizedPoolAddress ) || null ); } function isPublicPoolActive(chainId, poolAddress, jsonPath = DEFAULT_GRU_ACTIVE_JSON_PATH) { const record = getPublicPoolRecord(chainId, poolAddress, jsonPath); return !!record && record.active === true; } function isPublicPoolRoutable(chainId, poolAddress, jsonPath = DEFAULT_GRU_ACTIVE_JSON_PATH) { const record = getPublicPoolRecord(chainId, poolAddress, jsonPath); return !!record && record.active === true && record.routingEnabled === true; } function isPublicPoolMcpVisible(chainId, poolAddress, jsonPath = DEFAULT_GRU_ACTIVE_JSON_PATH) { const record = getPublicPoolRecord(chainId, poolAddress, jsonPath); return !!record && record.active === true && record.mcpVisible === true; } function shouldExposePublicPool( chainId, poolAddress, token0Address, token1Address, activeJsonPath = DEFAULT_GRU_ACTIVE_JSON_PATH, multichainJsonPath = DEFAULT_MULTICHAIN_JSON_PATH, deploymentJsonPath = DEFAULT_DEPLOYMENT_STATUS_JSON_PATH ) { const mirroredAddresses = new Set(getKnownMirroredTokenAddresses(chainId, { multichainJsonPath, deploymentJsonPath })); const touchesMirroredToken = mirroredAddresses.has(normalizeAddress(token0Address)) || mirroredAddresses.has(normalizeAddress(token1Address)); if (!touchesMirroredToken) return true; return isPublicPoolActive(chainId, poolAddress, activeJsonPath); } function shouldUsePublicPoolForRouting( chainId, poolAddress, token0Address, token1Address, activeJsonPath = DEFAULT_GRU_ACTIVE_JSON_PATH, multichainJsonPath = DEFAULT_MULTICHAIN_JSON_PATH, deploymentJsonPath = DEFAULT_DEPLOYMENT_STATUS_JSON_PATH ) { const mirroredAddresses = new Set(getKnownMirroredTokenAddresses(chainId, { multichainJsonPath, deploymentJsonPath })); const touchesMirroredToken = mirroredAddresses.has(normalizeAddress(token0Address)) || mirroredAddresses.has(normalizeAddress(token1Address)); if (!touchesMirroredToken) return true; return isPublicPoolRoutable(chainId, poolAddress, activeJsonPath); } module.exports = { loadTokenMappingJson, loadTokenMappingMultichainJson, loadGruTransportActiveJson, loadRoutingRegistryJson, loadDeploymentStatusJson, loadPoolMatrixJson, getRelayTokenMapping, getTokenList, getTokenMappingForPair, getAllMultichainPairs, getMappedAddress, getRoutingRegistryRoutes, getGruTransportMetadata, getEnabledCanonicalTokens, getEnabledCanonicalToken, getEnabledDestinationChains, isCanonicalTokenActive, isDestinationChainActive, getApprovedBridgePeer, getActiveTransportPairs, getActiveTransportPair, getKnownMirroredTokenAddresses, getActivePublicPools, isPublicPoolActive, isPublicPoolRoutable, isPublicPoolMcpVisible, shouldExposePublicPool, shouldUsePublicPoolForRouting, resolveConfigRef, isNonZeroAddress, DEFAULT_JSON_PATH, DEFAULT_MULTICHAIN_JSON_PATH, DEFAULT_GRU_ACTIVE_JSON_PATH, DEFAULT_ROUTING_REGISTRY_JSON_PATH, DEFAULT_DEPLOYMENT_STATUS_JSON_PATH, DEFAULT_POOL_MATRIX_JSON_PATH, };