Skip to content

Commit ed0e685

Browse files
fix(fee-utils): replace hardcoded XLM_PRICE with live useTokenPrice lib/fee-utils.ts hardcoded XLM_PRICE = 0.12 as the default for USD fee estimates. This value becomes stale as the real XLM/USD price moves, causing the displayed fee-in-USD to be arbitrarily wrong. Changes: - Remove the XLM_PRICE constant from fee-utils.ts - Make xlmPrice an optional param (undefined -> estimatedUsd omitted) - Pass the live usdPrice from useTokenPrice('XLM') at every call site: * components/streams/create-confirmation.tsx * app/app/stream/[id]/page.tsx (WithdrawDialog + CancelDialog) Closes #288
1 parent 61f2532 commit ed0e685

3 files changed

Lines changed: 19 additions & 8 deletions

File tree

‎app/app/stream/[id]/page.tsx‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ import {
6060
import { explorerUrl } from "@/lib/stellar";
6161
import { useNetwork } from "@/components/providers/network-provider";
6262
import { useAutoWithdraw } from "@/hooks/use-auto-withdraw";
63+
import { useTokenPrice } from "@/hooks/use-token-price";
6364
import { UnlockChart } from "@/components/streams/unlock-chart";
6465
import { StreamTimeline } from "@/components/streams/stream-timeline";
6566
import { DownloadReceiptButton } from "@/components/streams/download-receipt-button";
@@ -144,6 +145,7 @@ function WithdrawDialog({
144145
}) {
145146
const { withdraw, pending, error } = useContract();
146147
const { network } = useNetwork();
148+
const { usdPrice: xlmPrice } = useTokenPrice("XLM");
147149
const [inputAmount, setInputAmount] = useState("");
148150
const [showFeeEstimate, setShowFeeEstimate] = useState(false);
149151

@@ -155,7 +157,7 @@ function WithdrawDialog({
155157

156158
// Calculate estimated fees
157159
const estimatedFee = TYPICAL_FEES.withdraw.typical;
158-
const feeBreakdown = calculateFeeBreakdown(estimatedFee);
160+
const feeBreakdown = calculateFeeBreakdown(estimatedFee, xlmPrice ?? undefined);
159161
const withdrawFeeHigh = isHighFee(
160162
estimatedFee,
161163
TYPICAL_FEES.withdraw.typical,
@@ -284,10 +286,11 @@ function CancelDialog({
284286
const { cancel, pending, error } = useContract();
285287
const { network } = useNetwork();
286288
const router = useRouter();
289+
const { usdPrice: xlmPrice } = useTokenPrice("XLM");
287290
const [showFeeEstimate, setShowFeeEstimate] = useState(false);
288291

289292
const estimatedFee = TYPICAL_FEES.cancel.typical;
290-
const feeBreakdown = calculateFeeBreakdown(estimatedFee);
293+
const feeBreakdown = calculateFeeBreakdown(estimatedFee, xlmPrice ?? undefined);
291294
const cancelFeeHigh = isHighFee(estimatedFee, TYPICAL_FEES.cancel.typical);
292295

293296
async function handleCancel() {

‎components/streams/create-confirmation.tsx‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
shortenAddress,
1717
} from "@/lib/stream-utils";
1818
import { calculateFeeBreakdown, TYPICAL_FEES } from "@/lib/fee-utils";
19+
import { useTokenPrice } from "@/hooks/use-token-price";
1920
import type { TokenInfo } from "@/types/stream";
2021

2122
interface ConfirmationProps {
@@ -60,11 +61,17 @@ export function CreateConfirmation({
6061
}: ConfirmationProps) {
6162
const rate = formatRate(amountPerSecond, token.decimals, token.symbol);
6263

64+
// Fetch live XLM/USD price for fee USD estimate
65+
const { usdPrice: xlmPrice } = useTokenPrice("XLM");
66+
6367
// Calculate fee breakdown if estimate is available
6468
const estimatedFeeStroops = feeEstimate
6569
? Math.ceil(parseFloat(feeEstimate) * 1e7)
6670
: TYPICAL_FEES.createStream.typical;
67-
const feeBreakdown = calculateFeeBreakdown(estimatedFeeStroops);
71+
const feeBreakdown = calculateFeeBreakdown(
72+
estimatedFeeStroops,
73+
xlmPrice ?? undefined,
74+
);
6875

6976
return (
7077
<Dialog open={open} onOpenChange={(o) => !o && !pending && onCancel()}>

‎lib/fee-utils.ts‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,26 @@ export interface FeeBreakdown {
55
estimatedUsd?: number;
66
}
77

8-
const XLM_PRICE = 0.12; // Average XLM price in USD for estimation
9-
108
/**
119
* Calculate fee breakdown from transaction simulation
1210
* @param minResourceFee Minimum resource fee from simulation in stroops
13-
* @param xlmPrice Current XLM price in USD (optional)
11+
* @param xlmPrice Current XLM/USD price. Pass the live value from useTokenPrice;
12+
* omit (or pass undefined) when no price is available and USD
13+
* estimate should be suppressed.
1414
* @returns Fee breakdown: base estimate, safety buffer, and total
1515
*/
1616
export function calculateFeeBreakdown(
1717
minResourceFee: number,
18-
xlmPrice: number = XLM_PRICE,
18+
xlmPrice?: number,
1919
): FeeBreakdown {
2020
// Apply 15% buffer to ensure inclusion
2121
const bufferMultiplier = 1.15;
2222
const totalFee = Math.ceil(minResourceFee * bufferMultiplier);
2323
const bufferFee = totalFee - minResourceFee;
2424

2525
const totalXlm = totalFee / 1e7;
26-
const estimatedUsd = totalXlm * xlmPrice;
26+
const estimatedUsd =
27+
xlmPrice !== undefined ? totalXlm * xlmPrice : undefined;
2728

2829
return {
2930
minFee: minResourceFee,

0 commit comments

Comments
 (0)