All files / src/services DrepInfoTracker.ts

100% Statements 32/32
100% Branches 3/3
100% Functions 12/12
100% Lines 29/29

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 6844x   44x   44x 44x 44x                   44x 44x 122x 122x     193x         44x 44x 143x 214x 223x 203x   20x 8x 11x   8x   1x   7x   12x       143x         8x       44x       123x     91x   73x  
import { Cardano, DRepInfo, DRepProvider } from '@cardano-sdk/core';
import { Logger } from 'ts-log';
import { Observable, map, merge, of, withLatestFrom } from 'rxjs';
import { RetryBackoffConfig } from 'backoff-rxjs';
import { distinctBlock } from './util';
import { isNotNil } from '@cardano-sdk/util';
import { poll } from '@cardano-sdk/util-rxjs';
 
type DrepInfoObservableProps = {
  drepProvider: DRepProvider;
  logger: Logger;
  retryBackoffConfig: RetryBackoffConfig;
  refetchTrigger$: Observable<void>;
};
 
/** Use DRepProvider to fetch DRepInfos with retry backoff logic */
export const createDrepInfoColdObservable =
  ({ drepProvider, retryBackoffConfig, refetchTrigger$, logger }: DrepInfoObservableProps) =>
  (drepIds: Cardano.DRepID[]) =>
    poll<DRepInfo[]>({
      logger,
      retryBackoffConfig,
      sample: () => drepProvider.getDRepsInfo({ ids: drepIds }),
      trigger$: merge(of(true), refetchTrigger$)
    });
 
/** Replaces drep credential entries with DrepInfo. Undefined if drep not found in drepInfo */
export const drepsToDelegatees =
  (dreps: (Cardano.DelegateRepresentative | undefined)[]) =>
  (drepInfos: DRepInfo[]): (Cardano.DRepDelegatee | undefined)[] =>
    dreps.map((drep) => {
      if (!drep) {
        return;
      }
      if (Cardano.isDRepCredential(drep)) {
        const drepInfo = drepInfos.find(
          (info) => Cardano.DRepID.toCip129DRepID(info.id) === Cardano.DRepID.cip129FromCredential(drep)
        );
        if (!drepInfo) {
          // DRep not found, assume it's inactive
          return;
        }
        return { delegateRepresentative: drepInfo };
      }
      return { delegateRepresentative: drep };
    });
 
/** Removes undefined, AlwaysAbstain and AlwaysNoConfidence, removes duplicates and maps to DRepID[] */
export const drepsToDrepIds = (dreps: Array<Cardano.DelegateRepresentative | undefined>): Cardano.DRepID[] => [
  ...new Set<Cardano.DRepID>(
    dreps
      .filter(isNotNil)
      .filter(Cardano.isDRepCredential)
      .map((drepCredential) => Cardano.DRepID.cip129FromCredential(drepCredential))
  )
];
 
export const onlyDistinctBlockRefetch = (
  refetchTrigger$: Observable<void>,
  tip$: Observable<Pick<Cardano.PartialBlockHeader, 'blockNo'>>
): Observable<void> =>
  distinctBlock(
    refetchTrigger$.pipe(
      withLatestFrom(tip$),
      map(([, tip]) => tip)
    )
  ).pipe(map(() => void 0));