2023-11-10 04:28:37 -08:00
|
|
|
import { SNSClient, SNSClientConfig } from "@aws-sdk/client-sns";
|
2023-11-21 04:37:21 -08:00
|
|
|
import { Connection } from "@solana/web3.js";
|
2023-11-10 04:28:37 -08:00
|
|
|
import { Config } from "./config";
|
|
|
|
import {
|
|
|
|
SnsEventRepository,
|
|
|
|
EvmJsonRPCBlockRepository,
|
|
|
|
EvmJsonRPCBlockRepositoryCfg,
|
2023-11-24 08:03:48 -08:00
|
|
|
FileMetadataRepository,
|
2023-11-12 18:53:11 -08:00
|
|
|
PromStatRepository,
|
2023-11-14 09:03:11 -08:00
|
|
|
StaticJobRepository,
|
2023-11-21 04:37:21 -08:00
|
|
|
Web3SolanaSlotRepository,
|
2023-11-10 04:28:37 -08:00
|
|
|
} from "./repositories";
|
2023-11-14 04:52:04 -08:00
|
|
|
|
2023-11-24 08:03:48 -08:00
|
|
|
import { HttpClient } from "./http/HttpClient";
|
2023-11-14 09:03:11 -08:00
|
|
|
import { JobRepository } from "../domain/repositories";
|
2023-11-10 04:28:37 -08:00
|
|
|
|
|
|
|
export class RepositoriesBuilder {
|
|
|
|
private cfg: Config;
|
|
|
|
private snsClient?: SNSClient;
|
|
|
|
private repositories = new Map();
|
|
|
|
|
|
|
|
constructor(cfg: Config) {
|
|
|
|
this.cfg = cfg;
|
|
|
|
this.build();
|
|
|
|
}
|
|
|
|
|
|
|
|
private build() {
|
|
|
|
this.snsClient = this.createSnsClient();
|
|
|
|
|
|
|
|
this.repositories.set("sns", new SnsEventRepository(this.snsClient, this.cfg.sns));
|
2023-11-12 18:53:11 -08:00
|
|
|
this.repositories.set("metrics", new PromStatRepository());
|
2023-11-10 04:28:37 -08:00
|
|
|
|
|
|
|
this.cfg.metadata?.dir &&
|
2023-11-24 08:03:48 -08:00
|
|
|
this.repositories.set("metadata", new FileMetadataRepository(this.cfg.metadata.dir));
|
2023-11-10 04:28:37 -08:00
|
|
|
|
|
|
|
this.cfg.supportedChains.forEach((chain) => {
|
2023-11-21 04:37:21 -08:00
|
|
|
if (!this.cfg.platforms[chain]) throw new Error(`No config for chain ${chain}`);
|
|
|
|
|
|
|
|
if (chain === "solana") {
|
|
|
|
const cfg = this.cfg.platforms[chain];
|
|
|
|
const solanaSlotRepository = new Web3SolanaSlotRepository(new Connection(cfg.rpcs[0]));
|
|
|
|
this.repositories.set("solana-slotRepo", solanaSlotRepository);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (chain === "ethereum") {
|
|
|
|
const httpClient = this.createHttpClient(this.cfg.platforms[chain].timeout);
|
|
|
|
const repoCfg: EvmJsonRPCBlockRepositoryCfg = {
|
|
|
|
chain,
|
|
|
|
rpc: this.cfg.platforms[chain].rpcs[0],
|
|
|
|
timeout: this.cfg.platforms[chain].timeout,
|
|
|
|
};
|
|
|
|
this.repositories.set(
|
|
|
|
`${chain}-evmRepo`,
|
|
|
|
new EvmJsonRPCBlockRepository(repoCfg, httpClient)
|
|
|
|
);
|
|
|
|
}
|
2023-11-10 04:28:37 -08:00
|
|
|
});
|
2023-11-14 09:03:11 -08:00
|
|
|
|
|
|
|
this.repositories.set(
|
|
|
|
"jobs",
|
|
|
|
new StaticJobRepository(
|
|
|
|
this.cfg.jobs.dir,
|
|
|
|
this.cfg.dryRun,
|
|
|
|
(chain: string) => this.getEvmBlockRepository(chain),
|
|
|
|
{
|
|
|
|
metadataRepo: this.getMetadataRepository(),
|
|
|
|
statsRepo: this.getStatsRepository(),
|
|
|
|
snsRepo: this.getSnsEventRepository(),
|
2023-11-21 06:58:52 -08:00
|
|
|
solanaSlotRepo: this.getSolanaSlotRepository(),
|
2023-11-14 09:03:11 -08:00
|
|
|
}
|
|
|
|
)
|
|
|
|
);
|
2023-11-10 04:28:37 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
public getEvmBlockRepository(chain: string): EvmJsonRPCBlockRepository {
|
2023-11-21 04:37:21 -08:00
|
|
|
return this.getRepo(`${chain}-evmRepo`);
|
2023-11-10 04:28:37 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
public getSnsEventRepository(): SnsEventRepository {
|
2023-11-21 04:37:21 -08:00
|
|
|
return this.getRepo("sns");
|
2023-11-10 04:28:37 -08:00
|
|
|
}
|
|
|
|
|
2023-11-24 08:03:48 -08:00
|
|
|
public getMetadataRepository(): FileMetadataRepository {
|
2023-11-21 04:37:21 -08:00
|
|
|
return this.getRepo("metadata");
|
2023-11-10 04:28:37 -08:00
|
|
|
}
|
|
|
|
|
2023-11-12 18:53:11 -08:00
|
|
|
public getStatsRepository(): PromStatRepository {
|
2023-11-21 04:37:21 -08:00
|
|
|
return this.getRepo("metrics");
|
2023-11-12 18:53:11 -08:00
|
|
|
}
|
|
|
|
|
2023-11-14 09:03:11 -08:00
|
|
|
public getJobsRepository(): JobRepository {
|
2023-11-21 04:37:21 -08:00
|
|
|
return this.getRepo("jobs");
|
|
|
|
}
|
|
|
|
|
|
|
|
public getSolanaSlotRepository(): Web3SolanaSlotRepository {
|
|
|
|
return this.getRepo("solana-slotRepo");
|
|
|
|
}
|
|
|
|
|
|
|
|
private getRepo(name: string): any {
|
|
|
|
const repo = this.repositories.get(name);
|
|
|
|
if (!repo) throw new Error(`No repository ${name}`);
|
2023-11-14 09:03:11 -08:00
|
|
|
|
|
|
|
return repo;
|
|
|
|
}
|
|
|
|
|
2023-11-10 04:28:37 -08:00
|
|
|
public close(): void {
|
|
|
|
this.snsClient?.destroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
private createSnsClient(): SNSClient {
|
|
|
|
const snsCfg: SNSClientConfig = { region: this.cfg.sns.region };
|
|
|
|
if (this.cfg.sns.credentials) {
|
|
|
|
snsCfg.credentials = {
|
|
|
|
accessKeyId: this.cfg.sns.credentials.accessKeyId,
|
|
|
|
secretAccessKey: this.cfg.sns.credentials.secretAccessKey,
|
|
|
|
};
|
|
|
|
snsCfg.endpoint = this.cfg.sns.credentials.url;
|
|
|
|
}
|
|
|
|
|
|
|
|
return new SNSClient(snsCfg);
|
|
|
|
}
|
|
|
|
|
2023-11-14 04:52:04 -08:00
|
|
|
private createHttpClient(timeout?: number, retries?: number): HttpClient {
|
|
|
|
return new HttpClient({
|
|
|
|
retries: retries ?? 3,
|
|
|
|
timeout: timeout ?? 5_000,
|
|
|
|
initialDelay: 1_000,
|
|
|
|
maxDelay: 30_000,
|
|
|
|
});
|
2023-11-10 04:28:37 -08:00
|
|
|
}
|
|
|
|
}
|