- Organized 252 files across project - Root directory: 187 → 2 files (98.9% reduction) - Moved configuration guides to docs/04-configuration/ - Moved troubleshooting guides to docs/09-troubleshooting/ - Moved quick start guides to docs/01-getting-started/ - Moved reports to reports/ directory - Archived temporary files - Generated comprehensive reports and documentation - Created maintenance scripts and guides All files organized according to established standards.
135 lines
4.0 KiB
TypeScript
135 lines
4.0 KiB
TypeScript
/**
|
|
* RPC Translator Service - Main Entry Point
|
|
* ChainID 138 - Thirdweb compatibility with eth_sendTransaction support
|
|
*/
|
|
|
|
import { loadConfig } from './config';
|
|
import { HttpServer } from './servers/http-server';
|
|
import { WsServer } from './servers/ws-server';
|
|
import { BesuClient } from './clients/besu-client';
|
|
import { Web3SignerClient } from './clients/web3signer-client';
|
|
import { VaultClient } from './clients/vault-client';
|
|
import { NonceManager } from './services/nonce-manager';
|
|
import { RpcHandler } from './handlers/rpc-handler';
|
|
import { TxInterceptor } from './interceptors/tx-interceptor';
|
|
import Redis from 'ioredis';
|
|
|
|
async function main() {
|
|
const config = loadConfig();
|
|
|
|
console.log('Starting RPC Translator Service for ChainID', config.besu.chainId);
|
|
console.log('HTTP Port:', config.server.httpPort);
|
|
console.log('WebSocket Port:', config.server.wsPort);
|
|
|
|
// Initialize Redis
|
|
const redis = new Redis({
|
|
host: config.redis.host,
|
|
port: config.redis.port,
|
|
password: config.redis.password,
|
|
db: config.redis.db,
|
|
retryStrategy: (times: number) => {
|
|
const delay = Math.min(times * 50, 2000);
|
|
return delay;
|
|
},
|
|
});
|
|
|
|
redis.on('error', (err: Error) => {
|
|
console.error('Redis connection error:', err);
|
|
});
|
|
|
|
redis.on('connect', () => {
|
|
console.log('Redis connected');
|
|
});
|
|
|
|
// Initialize clients
|
|
const besuClient = new BesuClient(config.besu);
|
|
const web3SignerClient = new Web3SignerClient(config.web3signer);
|
|
const vaultClient = new VaultClient(config.vault);
|
|
const nonceManager = new NonceManager(redis, besuClient, config.redis.keyPrefix, config.besu.chainId);
|
|
|
|
// Initialize Vault and load config
|
|
try {
|
|
await vaultClient.initialize();
|
|
const vaultConfig = await vaultClient.getTranslatorConfig();
|
|
|
|
// Merge vault config into policy
|
|
if (vaultConfig.walletAllowlist && vaultConfig.walletAllowlist.length > 0) {
|
|
config.policy.walletAllowlist = vaultConfig.walletAllowlist;
|
|
}
|
|
if (vaultConfig.maxGasLimit) {
|
|
config.policy.maxGasLimit = BigInt(vaultConfig.maxGasLimit);
|
|
}
|
|
if (vaultConfig.maxGasPriceWei) {
|
|
config.policy.maxGasPriceWei = BigInt(vaultConfig.maxGasPriceWei);
|
|
}
|
|
if (vaultConfig.minGasPriceWei) {
|
|
config.policy.minGasPriceWei = BigInt(vaultConfig.minGasPriceWei);
|
|
}
|
|
|
|
console.log('Vault configuration loaded');
|
|
} catch (error) {
|
|
console.warn('Failed to load Vault config, using environment/defaults:', error);
|
|
}
|
|
|
|
// Initialize interceptor
|
|
const txInterceptor = new TxInterceptor(
|
|
besuClient,
|
|
web3SignerClient,
|
|
nonceManager,
|
|
config.besu.chainId,
|
|
config.policy
|
|
);
|
|
|
|
// Initialize RPC handler with Web3Signer client for smart interception
|
|
const rpcHandler = new RpcHandler(
|
|
besuClient,
|
|
txInterceptor,
|
|
config.besu.chainId,
|
|
config.allowPrivateNetworkMethods,
|
|
web3SignerClient
|
|
);
|
|
|
|
// Initialize servers
|
|
const httpServer = new HttpServer(
|
|
config.server.httpPort,
|
|
rpcHandler,
|
|
besuClient,
|
|
web3SignerClient,
|
|
vaultClient,
|
|
redis
|
|
);
|
|
const wsServer = new WsServer(config.server.wsPort, rpcHandler, besuClient);
|
|
|
|
// Start servers
|
|
await httpServer.start();
|
|
await wsServer.start();
|
|
|
|
console.log('RPC Translator Service started successfully');
|
|
console.log(`HTTP server listening on port ${config.server.httpPort}`);
|
|
console.log(`WebSocket server listening on port ${config.server.wsPort}`);
|
|
|
|
// Graceful shutdown
|
|
process.on('SIGINT', async () => {
|
|
console.log('\nReceived SIGINT, shutting down gracefully...');
|
|
await httpServer.stop();
|
|
await wsServer.stop();
|
|
await besuClient.close();
|
|
redis.disconnect();
|
|
process.exit(0);
|
|
});
|
|
|
|
process.on('SIGTERM', async () => {
|
|
console.log('\nReceived SIGTERM, shutting down gracefully...');
|
|
await httpServer.stop();
|
|
await wsServer.stop();
|
|
await besuClient.close();
|
|
redis.disconnect();
|
|
process.exit(0);
|
|
});
|
|
}
|
|
|
|
main().catch((error) => {
|
|
console.error('Fatal error:', error);
|
|
process.exit(1);
|
|
});
|