Files
proxmox/config/token-mapping-loader.cjs
defiQUG 7ac74f432b chore: sync docs, config schemas, scripts, and meta task alignment
- Institutional / JVMTM / reserve-provenance / GRU transport + standards JSON
- Validation and verify scripts (Blockscout labels, x402, GRU preflight, P1 local path)
- Wormhole wiring in AGENTS, MCP_SETUP, MASTER_INDEX, 04-configuration README
- Meta docs, integration gaps, live verification log, architecture updates
- CI validate-config workflow updates

Operator/LAN items, submodule working trees, and public token-aggregation edge
routes remain follow-up (see TODOS_CONSOLIDATED P1).

Made-with: Cursor
2026-03-31 22:31:39 -07:00

622 lines
26 KiB
JavaScript

/**
* 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,
};