All files / src/blockfrost util.ts

89.18% Statements 33/37
85.71% Branches 18/21
100% Functions 6/6
90.9% Lines 30/33

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 73 74 75 7620x     20x   20x 419x     20x 38x 38x 114x 86x       38x 38x 38x 38x       20x                       38x 38x 38x 38x 38x 38x 38x 38x 6x         32x                           20x           217x 12x 12x 12x 12x    
import { Cardano, ProviderError, ProviderFailure, ProviderUtil } from '@cardano-sdk/core';
import type { PaginationOptions } from '@blockfrost/blockfrost-js/lib/types';
 
import { BlockfrostError } from './BlockfrostClient';
 
export const isBlockfrostNotFoundError = (error: unknown) =>
  (error instanceof BlockfrostError && error.status === 404) ||
  (error instanceof ProviderError && error.reason === ProviderFailure.NotFound);
 
const buildQueryString = ({ page, count, order }: PaginationOptions) => {
  let queryString = '';
  const appendIfDefined = (value: unknown, param: string) => {
    if (typeof value !== 'undefined') {
      queryString += queryString ? `&${param}` : param;
    }
  };
 
  appendIfDefined(page, `page=${page}`);
  appendIfDefined(count, `count=${count}`);
  appendIfDefined(order, `order=${order}`);
  return queryString;
};
 
// copied from @cardano-sdk/cardano-services and updated to use custom blockfrost client instead of blockfrost-js
export const fetchSequentially = async <Response, Item = Response>(
  props: {
    request: (paginationQueryString: string) => Promise<Response[]>;
    responseTranslator?: (response: Response[]) => Item[];
    /**
     * @returns true to indicatate that current result set should be returned
     */
    haveEnoughItems?: (allItems: Item[], lastResponseBatch: Response[]) => boolean;
    paginationOptions?: PaginationOptions;
  },
  accumulated: Item[] = []
): Promise<Item[]> => {
  const count = props.paginationOptions?.count || 100;
  const page = props.paginationOptions?.page || 1;
  try {
    const response = await props.request(buildQueryString({ count, order: props.paginationOptions?.order, page }));
    const maybeTranslatedResponse = props.responseTranslator ? props.responseTranslator(response) : response;
    const newAccumulatedItems = [...accumulated, ...maybeTranslatedResponse] as Item[];
    const haveEnoughItems = props.haveEnoughItems?.(newAccumulatedItems, response);
    if (response.length === count && !haveEnoughItems) {
      return fetchSequentially<Response, Item>(
        { ...props, paginationOptions: { ...props.paginationOptions, page: page + 1 } },
        newAccumulatedItems
      );
    }
    return newAccumulatedItems;
  } catch (error) {
    Iif (isBlockfrostNotFoundError(error)) {
      return [];
    }
    throw error;
  }
};
 
/**
 * Maps txs metadata from blockfrost into to a TxMetadata
 *
 * @returns {Cardano.TxMetadata} map with bigint as key and Metadatum as value
 */
export const blockfrostMetadataToTxMetadata = (
  metadata: {
    label: string;
    json_metadata: unknown;
  }[]
): Cardano.TxMetadata =>
  metadata.reduce((map, metadatum) => {
    const { json_metadata, label } = metadatum;
    Iif (!json_metadata || !label) return map;
    map.set(BigInt(label), ProviderUtil.jsonToMetadatum(json_metadata));
    return map;
  }, new Map<bigint, Cardano.Metadatum>());