All files / src/Rewards/BlockfrostRewardsProvider BlockfrostRewardsProvider.ts

100% Statements 30/30
75% Branches 6/8
100% Functions 8/8
100% Lines 27/27

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 5740x   40x   40x   40x   40x   3x 3x 1x   2x 1x   1x                   4x 4x 4x 4x 4x 4x 5x   4x   104x 4x         4x 4x   3x   1x       4x 3x      
import { Cardano, Reward, RewardAccountBalanceArgs, RewardsHistoryArgs, RewardsProvider } from '@cardano-sdk/core';
 
import { BlockfrostProvider } from '../../util/BlockfrostProvider/BlockfrostProvider';
import { Range } from '@cardano-sdk/util';
import { blockfrostToProviderError, isBlockfrostNotFoundError } from '../../util';
 
const stringToBigInt = (str: string) => BigInt(str);
 
export class BlockfrostRewardsProvider extends BlockfrostProvider implements RewardsProvider {
  public async rewardAccountBalance({ rewardAccount }: RewardAccountBalanceArgs) {
    try {
      const accountResponse = await this.blockfrost.accounts(rewardAccount.toString());
      return BigInt(accountResponse.withdrawable_amount);
    } catch (error) {
      if (isBlockfrostNotFoundError(error)) {
        return 0n;
      }
      throw blockfrostToProviderError(error);
    }
  }
  protected async accountRewards(
    stakeAddress: Cardano.RewardAccount,
    {
      lowerBound = Cardano.EpochNo(0),
      upperBound = Cardano.EpochNo(Number.MAX_SAFE_INTEGER)
    }: Range<Cardano.EpochNo> = {}
  ): Promise<Reward[]> {
    try {
      const result: Reward[] = [];
      const batchSize = 100;
      let page = 1;
      let haveMorePages = true;
      while (haveMorePages) {
        const rewardsPage = await this.blockfrost.accountsRewards(stakeAddress.toString(), { count: batchSize, page });
 
        result.push(
          ...rewardsPage
            .filter(({ epoch }) => lowerBound <= epoch && epoch <= upperBound)
            .map(({ epoch, amount }) => ({
              epoch: Cardano.EpochNo(epoch),
              rewards: stringToBigInt(amount)
            }))
        );
        haveMorePages = rewardsPage.length === batchSize && rewardsPage[rewardsPage.length - 1].epoch < upperBound;
        page += 1;
      }
      return result;
    } catch (error) {
      throw blockfrostToProviderError(error);
    }
  }
  public async rewardsHistory({ rewardAccounts, epochs }: RewardsHistoryArgs) {
    const allAddressRewards = await Promise.all(rewardAccounts.map((address) => this.accountRewards(address, epochs)));
    return new Map(allAddressRewards.map((epochRewards, i) => [rewardAccounts[i], epochRewards]));
  }
}