UNPKG

@ledgerhq/coin-canton

Version:
54 lines (42 loc) 1.8 kB
import type { CryptoCurrency } from "@ledgerhq/ledger-wallet-framework/types"; import coinConfig from "../../config"; const magnitude: bigint = 10n ** 38n; type FeeTier = { limit: bigint | null; // `null` means no upper limit rateNumerator: bigint; // e.g., 1 for 1% rateDenominator: bigint; // e.g., 100 for 1% }; const cantonCoinTiers: FeeTier[] = [ // 100n because of rateDenominator for percentages { limit: 100n * 100n * magnitude, rateNumerator: 1n, rateDenominator: 100n }, // 1.0% { limit: 1000n * 100n * magnitude, rateNumerator: 1n, rateDenominator: 1000n }, // 0.1% { limit: 1_000_000n * 100n * magnitude, rateNumerator: 1n, rateDenominator: 10_000n }, // 0.01% { limit: null, rateNumerator: 1n, rateDenominator: 100_000n }, // 0.001% ]; const feeValue = (currency: CryptoCurrency) => coinConfig.getCoinConfig(currency.id).fee; export async function estimateFees(currency: CryptoCurrency, amount: bigint): Promise<bigint> { const forcedValue = feeValue(currency); if (forcedValue !== undefined) { return Promise.resolve(BigInt(forcedValue) * magnitude); } else { return Promise.resolve( // Add 1 CC as base fee 1n * magnitude + BigInt(calculateFeeWithTiers(amount, cantonCoinTiers)), ); } } function calculateFeeWithTiers(value: bigint, tiers: FeeTier[]): bigint { let remaining = value; let lastLimit = 0n; let fee = 0n; for (const tier of tiers) { if (remaining <= 0n) break; const currentLimit = tier.limit ?? BigInt(2 ** 62); // highest bigint value const tierCap = currentLimit - lastLimit; const applicable = remaining < tierCap ? remaining : tierCap; fee += (applicable * tier.rateNumerator) / tier.rateDenominator; remaining -= applicable; lastLimit = currentLimit; } return fee; }