Bot & Automation

Market AI

/root/hermes-projects/Market AI

packages/provider-adapters/src/provider-router.ts text
import { logger, type ScannerCriteria } from "@market-ai/core";
import { dexScreenerAdapter } from "./dexscreener.js";
import { mockMemeMarketDataAdapter } from "./mock-market-data.js";
import type { MemeMarketDataAdapter } from "./provider-types.js";

export class MemeMarketDataRouter {
  constructor(private readonly adapters: MemeMarketDataAdapter[] = [dexScreenerAdapter, mockMemeMarketDataAdapter]) {}

  async scanMemeCoins(criteria?: ScannerCriteria) {
    return this.tryAdapters((adapter) => adapter.scanMemeCoins(criteria));
  }

  async searchMemeCoins(query: string, criteria?: ScannerCriteria) {
    return this.tryAdapters((adapter) => adapter.searchMemeCoins(query, criteria));
  }

  async getMemeCandidate(query: string, chainId?: string) {
    return this.tryAdapters((adapter) => adapter.getMemeCandidate(query, chainId));
  }

  private async tryAdapters<T>(operation: (adapter: MemeMarketDataAdapter) => Promise<T>): Promise<T> {
    let lastError: unknown;

    for (const adapter of this.adapters) {
      try {
        return await operation(adapter);
      } catch (error) {
        lastError = error;
        logger.error("market_data_adapter_failed", {
          adapter: adapter.id,
          message: error instanceof Error ? error.message : "unknown",
        });
      }
    }

    throw lastError instanceof Error ? lastError : new Error("All market data adapters failed.");
  }
}

export const memeMarketDataRouter = new MemeMarketDataRouter();