Skip to content

Commit

Permalink
feat: Add chain Id validation (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
jsanmigimeno authored Jul 24, 2024
1 parent 6880909 commit cb4c844
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 0 deletions.
32 changes: 32 additions & 0 deletions src/config/config.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import dotenv from 'dotenv';
import { getConfigValidator } from './config.schema';
import { GlobalConfig, ChainConfig, AMBConfig, MonitorGlobalConfig, ListenerGlobalConfig, UnderwriterGlobalConfig, ExpirerGlobalConfig, WalletGlobalConfig, MonitorConfig, ListenerConfig, UnderwriterConfig, WalletConfig, ExpirerConfig, TokensConfig, EndpointConfig, VaultTemplateConfig, RelayDeliveryCosts } from './config.types';
import { loadPrivateKeyLoader } from './privateKeyLoaders/privateKeyLoader';
import { JsonRpcProvider } from 'ethers';

@Injectable()
export class ConfigService {
Expand All @@ -17,6 +18,8 @@ export class ConfigService {
readonly ambsConfig: Map<string, AMBConfig>;
readonly endpointsConfig: Map<string, EndpointConfig[]>;

readonly isReady: Promise<void>;

constructor() {
this.nodeEnv = this.loadNodeEnv();

Expand All @@ -30,6 +33,16 @@ export class ConfigService {
const ambNames = Array.from(this.ambsConfig.keys());
const chainIds = Array.from(this.chainsConfig.keys());
this.endpointsConfig = this.loadEndpointsConfig(chainIds, ambNames);

this.isReady = this.initialize();
}


// NOTE: The OnModuleInit hook is not being used as it does not guarantee the order in which it
// is executed across services (i.e. there is no guarantee that the config service will be the
// first to initialize). The `isReady` promise must be awaited on the underwriter initialization.
private async initialize(): Promise<void> {
await this.validateChainIds(this.chainsConfig);
}

private loadNodeEnv(): string {
Expand Down Expand Up @@ -261,6 +274,25 @@ export class ConfigService {
return this.ambsConfig.get(amb)?.globalProperties[key];
}

private async validateChainIds(chainsConfig: Map<string, ChainConfig>): Promise<void> {

const validationPromises = [];
for (const [chainId, config] of chainsConfig) {
const provider = new JsonRpcProvider(config.rpc, undefined, { staticNetwork: true });
const validationPromise = provider.getNetwork().then(
(network) => {
const rpcChainId = network.chainId.toString();
if (rpcChainId !== chainId) {
throw new Error(`Error validating the chain ID of chain ${chainId}: the RPC chain ID is ${rpcChainId}.`)
}
}
)
validationPromises.push(validationPromise);
}

await Promise.all(validationPromises);
}


// Formatting helpers
// ********************************************************************************************
Expand Down
2 changes: 2 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ async function bootstrap() {

await logLoadedOptions(configService, loggerService);

await configService.isReady;

await app.listen(configService.globalConfig.port);
}

Expand Down

0 comments on commit cb4c844

Please sign in to comment.