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 7618x     18x   18x 209x     18x 19x 19x 57x 39x       19x 19x 19x 19x       18x                       19x 19x 19x 19x 19x 19x 19x 19x 5x         14x                           18x           7x 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>());