From 8aeeeae3af3d10d0bf0572958ef186222425b356 Mon Sep 17 00:00:00 2001 From: n0 Date: Wed, 5 Aug 2026 14:12:41 -0700 Subject: [PATCH] fix: accept percent-suffixed affiliate fees --- src/father/category-fees.test.ts | 5 +++++ src/father/father.ts | 7 ++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/father/category-fees.test.ts b/src/father/category-fees.test.ts index 9ffeba6..f1c8f3b 100644 --- a/src/father/category-fees.test.ts +++ b/src/father/category-fees.test.ts @@ -21,10 +21,15 @@ describe("SwapFather category fees", () => { expect(parseAffiliateFeePercent("0.01", 1_500)).toBe(1); expect(parseAffiliateFeePercent("10", 1_500)).toBe(1_000); expect(parseAffiliateFeePercent("12.5", 1_500)).toBe(1_250); + expect(parseAffiliateFeePercent("7.25%", 1_500)).toBe(725); + expect(parseAffiliateFeePercent(" 7.25% ", 1_500)).toBe(725); + expect(parseAffiliateFeePercent("7.25$", 1_500)).toBe(725); expect(parseAffiliateFeePercent("15", 1_500)).toBe(1_500); expect(parseAffiliateFeePercent("0", 1_500)).toBeNull(); expect(parseAffiliateFeePercent("15.01", 1_500)).toBeNull(); expect(parseAffiliateFeePercent("10.123", 1_500)).toBeNull(); + expect(parseAffiliateFeePercent("7.25%$", 1_500)).toBeNull(); + expect(parseAffiliateFeePercent("fee 7.25", 1_500)).toBeNull(); expect(parseAffiliateFeePercent("2", 200)).toBe(200); expect(parseAffiliateFeePercent("2.01", 200)).toBeNull(); expect(formatAffiliateFeeBps(1_250)).toBe("12.5%"); diff --git a/src/father/father.ts b/src/father/father.ts index d680b5b..e530f68 100644 --- a/src/father/father.ts +++ b/src/father/father.ts @@ -249,7 +249,7 @@ export function registerFather(bot: Bot, fleet: Fleet, opts: FatherOptions = {}) const totalFeeBps = parseAffiliateFeePercent(text, setting.fee_cap_bps); if (totalFeeBps === null) { await ctx.reply( - `Enter a percentage from 0.01 to ${formatAffiliateFeeInput(setting.fee_cap_bps)} (for example, 10 or 12.5).`, + `Enter a percentage from 0.01 to ${formatAffiliateFeeInput(setting.fee_cap_bps)} (for example, 7.25 or 7.25%).`, { parse_mode: "HTML" }, ); return; @@ -1227,8 +1227,9 @@ export function visibleAffiliateFeeItems( } export function parseAffiliateFeePercent(value: string, capBps: number): number | null { - if (!/^\d+(\.\d{1,2})?$/.test(value.trim())) return null; - const bps = Math.round(Number(value.trim()) * 100); + const normalized = value.trim().replace(/(?:%|\$)$/, "").trim(); + if (!/^\d+(\.\d{1,2})?$/.test(normalized)) return null; + const bps = Math.round(Number(normalized) * 100); return Number.isInteger(bps) && bps >= 1 && bps <= capBps ? bps : null; }