All files / src/blockfrost BlockfrostProvider.ts

58.06% Statements 18/31
0% Branches 0/11
60% Functions 3/5
58.06% Lines 18/31

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 7318x 18x   18x       18x                                       18x   22x     22x 22x                 253x 253x 253x 50x 50x   203x 203x                           203x     203x     203x      
import { BlockfrostClient, BlockfrostError } from './BlockfrostClient';
import { HealthCheckResponse, Provider, ProviderError, ProviderFailure } from '@cardano-sdk/core';
import { Logger } from 'ts-log';
import { contextLogger } from '@cardano-sdk/util';
import type { AsyncReturnType } from 'type-fest';
import type { BlockFrostAPI } from '@blockfrost/blockfrost-js';
 
const toProviderFailure = (status: number | undefined): ProviderFailure => {
  switch (status) {
    case 400:
      return ProviderFailure.BadRequest;
    case 403:
      return ProviderFailure.Forbidden;
    case 404:
      return ProviderFailure.NotFound;
    case 402:
    case 418:
    case 425:
    case 429:
      return ProviderFailure.ServerUnavailable;
    case 500:
      return ProviderFailure.Unhealthy;
    default:
      return ProviderFailure.Unknown;
  }
};
 
export abstract class BlockfrostProvider implements Provider {
  protected logger: Logger;
  #client: BlockfrostClient;
 
  constructor(client: BlockfrostClient, logger: Logger) {
    this.#client = client;
    this.logger = contextLogger(logger, this.constructor.name);
  }
 
  /**
   * @param endpoint e.g. 'blocks/latest'
   * @param requestInit request options
   * @throws {ProviderError}
   */
  protected async request<T>(endpoint: string, requestInit?: RequestInit): Promise<T> {
    try {
      this.logger.debug('request', endpoint);
      const response = await this.#client.request<T>(endpoint, requestInit);
      this.logger.debug('response', response);
      return response;
    } catch (error) {
      this.logger.error('error', error);
      throw this.toProviderError(error);
    }
  }
 
  async healthCheck(): Promise<HealthCheckResponse> {
    try {
      const result = await this.#client.request<AsyncReturnType<BlockFrostAPI['health']>>('health');
      return { ok: result.is_healthy };
    } catch (error) {
      return { ok: false, reason: this.toProviderError(error).message };
    }
  }
 
  protected toProviderError(error: unknown): ProviderError {
    Iif (error instanceof ProviderError) {
      return error;
    }
    Iif (error instanceof BlockfrostError) {
      return new ProviderError(toProviderFailure(error.status), error);
    }
    return new ProviderError(ProviderFailure.Unknown, error);
  }
}