diff --git a/libs/pricing/src/services/coingecko.service.spec.ts b/libs/pricing/src/services/coingecko.service.spec.ts index 2dcbc4a..66d384c 100644 --- a/libs/pricing/src/services/coingecko.service.spec.ts +++ b/libs/pricing/src/services/coingecko.service.spec.ts @@ -69,6 +69,7 @@ describe("CoingeckoService", () => { params: { vs_currencies: currency, ids: tokenIds.join(","), + precision: service["DECIMALS_PRECISION"].toString(), }, headers: { "x-cg-pro-api-key": apiKey, diff --git a/libs/pricing/src/services/coingecko.service.ts b/libs/pricing/src/services/coingecko.service.ts index dfcb566..e6e8c6b 100644 --- a/libs/pricing/src/services/coingecko.service.ts +++ b/libs/pricing/src/services/coingecko.service.ts @@ -6,31 +6,56 @@ import { ApiNotAvailable, RateLimitExceeded } from "@zkchainhub/pricing/exceptio import { IPricingService } from "@zkchainhub/pricing/interfaces"; import { TokenPrices } from "@zkchainhub/pricing/types/tokenPrice.type"; +/** + * Service for fetching token prices from Coingecko API. + */ @Injectable() export class CoingeckoService implements IPricingService { private readonly logger = new Logger(CoingeckoService.name); private readonly AUTH_HEADER = "x-cg-pro-api-key"; + private readonly DECIMALS_PRECISION = 3; + + /** + * + * @param apiKey * @param apiKey - Coingecko API key. + * @param apiBaseUrl - Base URL for Coingecko API. If you have a Pro account, you can use the Pro API URL. + */ constructor( private readonly apiKey: string, private readonly apiBaseUrl: string = "https://api.coingecko.com/api/v3/", private readonly httpService: HttpService, ) {} + /** + * @param tokenIds - An array of Coingecko Tokens IDs. + * @param config.currency - The currency in which the prices should be returned (default: "usd"). + */ async getTokenPrices( tokenIds: string[], config: { currency: string } = { currency: "usd" }, ): Promise> { const { currency } = config; - return this.get("/simple/price", { + return this.httpGet("/simple/price", { vs_currencies: currency, ids: tokenIds.join(","), + precision: this.DECIMALS_PRECISION.toString(), }).then((data) => { return Object.fromEntries(Object.entries(data).map(([key, value]) => [key, value.usd])); }); } - private async get(endpoint: string, params: Record = {}) { + /** + * HTTP GET wrapper to perform a GET request to the specified endpoint with optional parameters. + * Also injects the API key and sets the Accept header to "application/json". + * @param endpoint - The endpoint to send the GET request to. + * @param params - Optional parameters to include in the request. + * @returns A promise that resolves to the response data. + * @throws {ApiNotAvailable} If the Coingecko API is not available (status code >= 500). + * @throws {RateLimitExceeded} If the rate limit for the API is exceeded (status code 429). + * @throws {Error} If an error occurs while fetching data or a non-network related error occurs. + */ + private async httpGet(endpoint: string, params: Record = {}) { try { const response = await this.httpService.axiosRef.get( `${this.apiBaseUrl}${endpoint}`,