Files
proxmox/config/contracts-loader.cjs

107 lines
3.9 KiB
JavaScript
Raw Permalink Normal View History

/**
* Load contract addresses from config/smart-contracts-master.json.
* Usable from any Node app (CommonJS). Safe to publish (no secrets in JSON).
*
* Usage:
* const { getContractAddress, getChainContracts, loadContractsIntoProcessEnv } = require('../config/contracts-loader.cjs');
* getContractAddress(138, 'CCIP_Router') // => '0x8078A09637e47Fa5Ed34F626046Ea2094a5CDE5e'
* getContractAddress(138, 'CCIPWETH9_Bridge') // by contract key
* loadContractsIntoProcessEnv() // set process.env.CCIP_ROUTER etc. from envVarMap when unset
*
* @version 2026-02-13
*/
const path = require('path');
const fs = require('fs');
const DEFAULT_JSON_PATH = path.resolve(__dirname, 'smart-contracts-master.json');
let _cache = null;
function loadMasterJson(jsonPath = DEFAULT_JSON_PATH) {
if (_cache && _cache.path === jsonPath) return _cache.data;
const raw = fs.readFileSync(jsonPath, 'utf8');
const data = JSON.parse(raw);
_cache = { path: jsonPath, data };
return data;
}
/**
* @param {number|string} chainId - e.g. 138 or '138'
* @param {string} contractKey - key from contracts object (e.g. 'CCIP_Router') or env var name (e.g. 'CCIP_ROUTER' via envVarMap)
* @param {string} [jsonPath] - optional path to master JSON
* @returns {string|undefined} contract address or undefined
*/
function getContractAddress(chainId, contractKey, jsonPath) {
const data = loadMasterJson(jsonPath);
const chain = String(chainId);
const chainData = data.chains && data.chains[chain];
if (!chainData) return undefined;
const contracts = chainData.contracts || {};
const envVarMap = chainData.envVarMap || {};
// Direct contract key
if (contracts[contractKey]) return contracts[contractKey];
// Env var name -> contract key -> address
const mappedKey = envVarMap[contractKey];
if (mappedKey && contracts[mappedKey]) return contracts[mappedKey];
return undefined;
}
/**
* @param {number|string} chainId
* @param {string} [jsonPath]
* @returns {{ [contractKey: string]: string }} all contracts for the chain
*/
function getChainContracts(chainId, jsonPath) {
const data = loadMasterJson(jsonPath);
const chain = String(chainId);
const chainData = data.chains && data.chains[chain];
if (!chainData) return {};
return { ...(chainData.contracts || {}) };
}
/**
* Get mapper for a chain: either on-chain AddressMapper address or "canonical" (use canonical addresses, no contract).
* Ensures mapper is provided across all networks with bridges or liquidity pools.
*
* @param {number|string} chainId - e.g. 138 or '651940'
* @param {string} [jsonPath]
* @returns {string|undefined} AddressMapper contract address, "canonical", or undefined if chain not in config
*/
function getMapperAddress(chainId, jsonPath) {
const data = loadMasterJson(jsonPath);
const chain = String(chainId);
const chainData = data.chains && data.chains[chain];
if (!chainData) return undefined;
return chainData.mapper;
}
/**
* Set process.env from envVarMap for the given chain(s) when not already set.
* @param {number|string|(number|string)[]} [chainIds] - default [138, 1]
* @param {string} [jsonPath]
*/
function loadContractsIntoProcessEnv(chainIds, jsonPath) {
const chains = Array.isArray(chainIds) ? chainIds : (chainIds != null ? [chainIds] : ['138', '1']);
const data = loadMasterJson(jsonPath);
for (const chain of chains) {
const chainData = data.chains && data.chains[String(chain)];
if (!chainData || !chainData.envVarMap) continue;
const contracts = chainData.contracts || {};
for (const [envVar, contractKey] of Object.entries(chainData.envVarMap)) {
if (process.env[envVar] != null && process.env[envVar] !== '') continue;
const addr = contracts[contractKey];
if (addr) process.env[envVar] = addr;
}
}
}
module.exports = {
loadMasterJson,
getContractAddress,
getChainContracts,
getMapperAddress,
loadContractsIntoProcessEnv,
DEFAULT_JSON_PATH
};