chore: sync submodule state (parent ref update)
Made-with: Cursor
This commit is contained in:
@@ -27,9 +27,11 @@ export class RelayService {
|
||||
async start() {
|
||||
this.logger.info('Initializing relay service...');
|
||||
|
||||
// Initialize providers
|
||||
this.sourceProvider = new ethers.JsonRpcProvider(this.config.sourceChain.rpcUrl);
|
||||
this.destinationProvider = new ethers.JsonRpcProvider(this.config.destinationChain.rpcUrl);
|
||||
// Initialize providers with explicit network to avoid "failed to detect network" on slow/unusual RPCs
|
||||
const sourceNetwork = { chainId: this.config.sourceChain.chainId, name: this.config.sourceChain.name };
|
||||
const destNetwork = { chainId: this.config.destinationChain.chainId, name: this.config.destinationChain.name };
|
||||
this.sourceProvider = new ethers.JsonRpcProvider(this.config.sourceChain.rpcUrl, sourceNetwork);
|
||||
this.destinationProvider = new ethers.JsonRpcProvider(this.config.destinationChain.rpcUrl, destNetwork);
|
||||
|
||||
// Initialize signers
|
||||
if (!this.config.relayer.privateKey) {
|
||||
@@ -38,7 +40,7 @@ export class RelayService {
|
||||
this.sourceSigner = new ethers.Wallet(this.config.relayer.privateKey, this.sourceProvider);
|
||||
this.destinationSigner = new ethers.Wallet(this.config.relayer.privateKey, this.destinationProvider);
|
||||
|
||||
this.logger.info('Relayer address:', this.destinationSigner.address);
|
||||
this.logger.info('Relayer address: %s', String(this.destinationSigner.address));
|
||||
|
||||
// Validate relay router and bridge addresses
|
||||
if (!this.config.destinationChain.relayRouterAddress ||
|
||||
|
||||
@@ -2,40 +2,108 @@
|
||||
* Configuration for CCIP Relay Service
|
||||
*/
|
||||
|
||||
import dotenv from 'dotenv';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { createRequire } from 'module';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
// Load project root first so PRIVATE_KEY is set, then relay .env
|
||||
const projectEnv = path.resolve(__dirname, '../../.env');
|
||||
const relayEnv = path.resolve(__dirname, '../.env');
|
||||
dotenv.config({ path: projectEnv });
|
||||
dotenv.config({ path: relayEnv });
|
||||
// Fill contract addresses from master JSON (config/smart-contracts-master.json) when not set in .env
|
||||
const proxmoxRoot = path.resolve(__dirname, '../../../../');
|
||||
const contractsLoaderPath = path.join(proxmoxRoot, 'config', 'contracts-loader.cjs');
|
||||
const tokenMappingLoaderPath = path.join(proxmoxRoot, 'config', 'token-mapping-loader.cjs');
|
||||
try {
|
||||
const require = createRequire(import.meta.url);
|
||||
const { loadContractsIntoProcessEnv } = require(contractsLoaderPath);
|
||||
if (typeof loadContractsIntoProcessEnv === 'function') loadContractsIntoProcessEnv([138, 1]);
|
||||
} catch (_) { /* run from smom-dbis-138 only: loader not found */ }
|
||||
|
||||
// Token mapping (Chain 138 -> Mainnet): prefer config/token-mapping.json when available
|
||||
function getTokenMapping() {
|
||||
try {
|
||||
const require = createRequire(import.meta.url);
|
||||
const { getRelayTokenMapping } = require(tokenMappingLoaderPath);
|
||||
const fromFile = getRelayTokenMapping && getRelayTokenMapping();
|
||||
if (fromFile && Object.keys(fromFile).length > 0) return fromFile;
|
||||
} catch (_) { /* config not available */ }
|
||||
// Fallback: only WETH9 is accepted by Mainnet CCIPRelayBridge; LINK mapped for future bridge support
|
||||
return {
|
||||
'0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2': '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // WETH9
|
||||
'0xb7721dD53A8c629d9f1Ba31a5819AFe250002b03': '0x514910771AF9Ca656af840dff83E8264EcF986CA' // LINK (bridge does not accept yet)
|
||||
};
|
||||
}
|
||||
// If PRIVATE_KEY still missing, try cwd-relative paths (e.g. run from repo root or relay dir)
|
||||
if (!process.env.PRIVATE_KEY || process.env.PRIVATE_KEY.includes('${')) {
|
||||
const cwd = process.cwd();
|
||||
const tries = [
|
||||
path.resolve(cwd, '../../.env'), // cwd is services/relay
|
||||
path.resolve(cwd, 'smom-dbis-138/.env') // cwd is project root (proxmox)
|
||||
];
|
||||
for (const p of tries) {
|
||||
if (p !== projectEnv && p !== relayEnv) dotenv.config({ path: p });
|
||||
}
|
||||
}
|
||||
|
||||
function getEffectivePrivateKey() {
|
||||
const v = process.env.RELAYER_PRIVATE_KEY || process.env.PRIVATE_KEY || '';
|
||||
return (v && !v.includes('${')) ? v : (process.env.PRIVATE_KEY || '');
|
||||
}
|
||||
|
||||
// Build mainnet RPC URL; use INFURA_PROJECT_SECRET (or METAMASK_SECRET) for Basic Auth when using Infura
|
||||
function getMainnetRpcUrl() {
|
||||
let raw = process.env.RPC_URL_MAINNET || process.env.ETHEREUM_MAINNET_RPC || '';
|
||||
if (!raw && process.env.INFURA_PROJECT_ID && !String(process.env.INFURA_PROJECT_ID).includes('${')) {
|
||||
raw = `https://mainnet.infura.io/v3/${process.env.INFURA_PROJECT_ID}`;
|
||||
}
|
||||
if (!raw) raw = 'https://ethereum.publicnode.com';
|
||||
const secret = process.env.INFURA_PROJECT_SECRET || process.env.METAMASK_SECRET || '';
|
||||
const infuraMatch = raw.match(/^https:\/\/mainnet\.infura\.io\/v3\/([a-f0-9]+)$/i);
|
||||
if (infuraMatch && secret && !secret.includes('${')) {
|
||||
const projectId = infuraMatch[1];
|
||||
return `https://${encodeURIComponent(projectId)}:${encodeURIComponent(secret)}@mainnet.infura.io/v3/${projectId}`;
|
||||
}
|
||||
return raw;
|
||||
}
|
||||
|
||||
export const config = {
|
||||
// Source chain (Chain 138)
|
||||
// Source chain (Chain 138) — use Public RPC (VMID 2201) per standard; fallback to Core (RPC_URL_138)
|
||||
sourceChain: {
|
||||
name: 'Chain 138',
|
||||
chainId: 138,
|
||||
rpcUrl: process.env.RPC_URL_138 || process.env.RPC_URL || 'http://192.168.11.250:8545',
|
||||
routerAddress: process.env.CCIP_ROUTER_CHAIN138 || '0xd49B579DfC5912fA7CAa76893302c6e58f231431',
|
||||
bridgeAddress: process.env.CCIPWETH9_BRIDGE_CHAIN138 || '0xBBb4a9202716eAAB3644120001cC46096913a3C8'
|
||||
rpcUrl: process.env.RPC_URL_138_PUBLIC || process.env.RPC_URL_138 || process.env.RPC_URL || 'https://rpc-http-pub.d-bis.org',
|
||||
routerAddress: process.env.CCIP_ROUTER_CHAIN138 || process.env.CCIP_ROUTER || '0x8078A09637e47Fa5Ed34F626046Ea2094a5CDE5e',
|
||||
bridgeAddress: process.env.CCIPWETH9_BRIDGE_CHAIN138 || '0x971cD9D156f193df8051E48043C476e53ECd4693'
|
||||
},
|
||||
|
||||
// Destination chain (Ethereum Mainnet)
|
||||
// Destination chain (Ethereum Mainnet) — deployed relay contracts receive and release WETH
|
||||
destinationChain: {
|
||||
name: 'Ethereum Mainnet',
|
||||
chainId: 1,
|
||||
rpcUrl: process.env.RPC_URL_MAINNET || 'https://eth.llamarpc.com',
|
||||
relayRouterAddress: process.env.CCIP_RELAY_ROUTER_MAINNET || process.env.RELAY_ROUTER_MAINNET || '',
|
||||
relayBridgeAddress: process.env.CCIP_RELAY_BRIDGE_MAINNET || process.env.RELAY_BRIDGE_MAINNET || '',
|
||||
rpcUrl: getMainnetRpcUrl(),
|
||||
relayRouterAddress: process.env.CCIP_RELAY_ROUTER_MAINNET || process.env.RELAY_ROUTER_MAINNET || '0xAd9A228CcEB4cbB612cD165FFB72fE090ff10Afb',
|
||||
relayBridgeAddress: process.env.CCIP_RELAY_BRIDGE_MAINNET || process.env.RELAY_BRIDGE_MAINNET || '0xF9A32F37099c582D28b4dE7Fca6eaC1e5259f939',
|
||||
chainSelector: BigInt('5009297550715157269'),
|
||||
weth9Address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' // WETH9 on Ethereum Mainnet
|
||||
},
|
||||
|
||||
// Token address mapping (Chain 138 -> Ethereum Mainnet)
|
||||
tokenMapping: {
|
||||
// WETH9: Same address but represents different tokens
|
||||
'0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2': '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' // WETH9 on Mainnet
|
||||
},
|
||||
// Token address mapping (Chain 138 -> Ethereum Mainnet). Source of truth: config/token-mapping.json
|
||||
// Note: Mainnet CCIPRelayBridge is WETH9-only; other tokens will revert at bridge until bridge is extended.
|
||||
tokenMapping: getTokenMapping(),
|
||||
|
||||
// Chain 138 selector - using chain ID directly for now (uint64 max is 2^64-1)
|
||||
// Note: Official CCIP chain selectors are calculated differently, but for custom relay we use chain ID
|
||||
sourceChainSelector: BigInt('138'), // Using chain ID as selector for custom relay
|
||||
|
||||
// Relayer configuration
|
||||
// Relayer configuration (dotenv does not expand ${PRIVATE_KEY}; getter uses effective key)
|
||||
relayer: {
|
||||
privateKey: process.env.RELAYER_PRIVATE_KEY || process.env.PRIVATE_KEY,
|
||||
get privateKey() {
|
||||
return getEffectivePrivateKey();
|
||||
},
|
||||
address: process.env.RELAYER_ADDRESS || ''
|
||||
},
|
||||
|
||||
@@ -53,9 +121,9 @@ export const config = {
|
||||
}
|
||||
};
|
||||
|
||||
// Validate required configuration
|
||||
if (!config.relayer.privateKey) {
|
||||
throw new Error('RELAYER_PRIVATE_KEY or PRIVATE_KEY environment variable is required');
|
||||
// Validate required configuration (use same helper so we validate the effective key)
|
||||
if (!getEffectivePrivateKey()) {
|
||||
throw new Error('RELAYER_PRIVATE_KEY or PRIVATE_KEY environment variable is required. Set PRIVATE_KEY in smom-dbis-138/.env or RELAYER_PRIVATE_KEY in services/relay/.env');
|
||||
}
|
||||
|
||||
// Validate relay addresses (warn but don't fail - they may be set later)
|
||||
|
||||
Reference in New Issue
Block a user