UNPKG

@frak-labs/core-sdk

Version:

Core SDK of the Frak wallet, low level library to interact directly with the frak ecosystem.

74 lines (69 loc) 2.79 kB
import type { EstimatedReward, TokenAmountType } from "../types"; /** * Comparable fiat value of a single reward, used to rank rewards against each * other. * * - `fixed` → the token amount in the requested currency * - `tiered` → the highest token amount across tiers * - `percentage` → the capped (`maxAmount`) value when present, otherwise `0` * (an uncapped percentage has no comparable fiat value) */ export function getRewardValue( reward: EstimatedReward, key: keyof TokenAmountType ): number { switch (reward.payoutType) { case "fixed": return reward.amount[key]; case "percentage": return reward.maxAmount?.[key] ?? 0; case "tiered": return reward.tiers.reduce( (max, tier) => "amount" in tier ? Math.max(max, tier.amount[key]) : max, 0 ); } } /** * Highest percent a reward exposes: the flat `percentage` percent, or the * richest percent across `tiered` tiers, or `0` when it carries none. * * Shared by {@link getRewardRank} (to weight a percentage-only reward) and * `formatEstimatedReward` (to render it as `"X %"`), so the value the UI ranks * by and the value it prints stay derived from one tier traversal. */ export function maxRewardPercent(reward: EstimatedReward): number { if (reward.payoutType === "percentage") return reward.percent; if (reward.payoutType === "tiered") { return reward.tiers.reduce( (max, tier) => "percent" in tier ? Math.max(max, tier.percent) : max, 0 ); } return 0; } // A reward with no money value (an uncapped percentage, or a percent-only // tier set) still renders as "X %", so it is worth surfacing. We give it a // positive ranking weight derived from its percent but scaled far below any // real-money reward, so the two invariants the UI relies on hold: (1) a reward // with real money always outranks a percentage-only reward, and (2) a // percentage-only reward still outranks a zero-value reward. Together they // guarantee the reward the ranking picks is always one we can display. const PERCENT_ONLY_RANK_WEIGHT = 1e-6; /** * Ranking weight used to pick the single most attractive reward to surface. * * Mirrors {@link getRewardValue} (money value) but lifts a percentage-only * reward to a tiny positive weight instead of `0`, so it is never buried * behind a zero-value reward when choosing what to display. */ export function getRewardRank( reward: EstimatedReward, key: keyof TokenAmountType ): number { const value = getRewardValue(reward, key); if (value > 0) return value; return maxRewardPercent(reward) * PERCENT_ONLY_RANK_WEIGHT; }