All files / src/blockfrost util.ts

88.88% Statements 32/36
85% Branches 17/20
100% Functions 6/6
90.62% Lines 29/32

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 3x     18x 12x 12x 36x 24x       12x 12x 12x 12x       18x                         12x 12x 12x 12x 12x 12x 12x 5x   7x                           18x           4x 6x 6x 6x 6x    
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 <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;
  },
  page = 1,
  accumulated: Item[] = []
): Promise<Item[]> => {
  const count = props.paginationOptions?.count || 100;
  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<Item, Response>(props, 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>());