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 | 19x 19x 19x 19x 3x 1x 1x 1x 3x 3x 4x 4x 4x 4x 104x 4x 3x 3x | import { Cardano, Reward, RewardAccountBalanceArgs, RewardsHistoryArgs, RewardsProvider } from '@cardano-sdk/core';
import { BlockfrostClient, BlockfrostProvider, fetchSequentially, isBlockfrostNotFoundError } from '../blockfrost';
import { Logger } from 'ts-log';
import { Range } from '@cardano-sdk/util';
import type { Responses } from '@blockfrost/blockfrost-js';
const stringToBigInt = (str: string) => BigInt(str);
export class BlockfrostRewardsProvider extends BlockfrostProvider implements RewardsProvider {
constructor(client: BlockfrostClient, logger: Logger) {
super(client, logger);
}
public async rewardAccountBalance({ rewardAccount }: RewardAccountBalanceArgs) {
try {
const accountResponse = await this.request<Responses['account_content']>(`accounts/${rewardAccount.toString()}`);
return BigInt(accountResponse.withdrawable_amount);
} catch (error) {
Iif (isBlockfrostNotFoundError(error)) {
return 0n;
}
throw this.toProviderError(error);
}
}
protected async accountRewards(
stakeAddress: Cardano.RewardAccount,
{
lowerBound = Cardano.EpochNo(0),
upperBound = Cardano.EpochNo(Number.MAX_SAFE_INTEGER)
}: Range<Cardano.EpochNo> = {}
): Promise<Reward[]> {
const batchSize = 100;
return fetchSequentially<Responses['account_reward_content'][0], Reward>({
haveEnoughItems: (_, rewardsPage) => {
const lastReward = rewardsPage[rewardsPage.length - 1];
return !lastReward || lastReward.epoch >= upperBound;
},
paginationOptions: { count: batchSize },
request: (paginationQueryString) =>
this.request<Responses['account_reward_content']>(
`accounts/${stakeAddress.toString()}/rewards?${paginationQueryString}`
),
responseTranslator: (rewardsPage) =>
rewardsPage
.filter(({ epoch }) => lowerBound <= epoch && epoch <= upperBound)
.map(({ epoch, amount, pool_id }) => ({
epoch: Cardano.EpochNo(epoch),
rewards: stringToBigInt(amount),
...(pool_id && { poolId: Cardano.PoolId(pool_id) })
}))
});
}
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]));
}
}
|