Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion src/components/common/TradeDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from '@/components/ui/dialog';
import { cn } from '@/lib/utils';
import { formatNumber } from '@/utils/numberFormat.utils';
import { formatDisplayKeyPrice } from '@/utils/keyPriceDisplay.utils';
import { formatDisplayKeyPrice, estimateSellProceeds } from '@/utils/keyPriceDisplay.utils';
import PercentageBadge from '@/components/common/PercentageBadge';
import NetworkFeeHint from '@/components/common/NetworkFeeHint';
import { TRADE_FEE_ESTIMATE } from '@/constants/fees';
Expand All @@ -26,6 +26,8 @@ export interface TradeDialogProps {
availableHoldings: number;
/** Per-key price in stroops, shown on the buy confirmation step. */
keyPriceStroops?: number | null;
/** Current key supply for estimating sell proceeds. */
currentSupply?: number | null;
onOpenChange: (open: boolean) => void;
onConfirm: (amount: number) => Promise<void> | void;
isSubmitting?: boolean;
Expand All @@ -37,6 +39,7 @@ const TradeDialog: React.FC<TradeDialogProps> = ({
creatorName,
availableHoldings,
keyPriceStroops,
currentSupply,
onOpenChange,
onConfirm,
isSubmitting = false,
Expand Down Expand Up @@ -78,6 +81,13 @@ const TradeDialog: React.FC<TradeDialogProps> = ({
{ unit: TRADE_FEE_ESTIMATE.UNIT }
);

const estimatedProceedsStroops = useMemo(() => {
if (side !== 'sell' || !Number.isFinite(parsedAmount) || parsedAmount <= 0) {
return null;
}
return estimateSellProceeds(keyPriceStroops, currentSupply, parsedAmount);
}, [side, keyPriceStroops, currentSupply, parsedAmount]);

return (
<Dialog
open={open}
Expand Down Expand Up @@ -177,6 +187,20 @@ const TradeDialog: React.FC<TradeDialogProps> = ({
className="text-white/45"
/>
)}
{side === 'sell' && (
<div className="text-xs text-white/45 mt-2">
{estimatedProceedsStroops != null ? (
<>
Estimated proceeds (approximate):{' '}
<span className="font-semibold text-amber-300/90 tabular-nums">
{formatDisplayKeyPrice(estimatedProceedsStroops)}
</span>
</>
) : (
<>Estimated proceeds unavailable</>
)}
</div>
)}
</div>

{/*
Expand Down
1 change: 1 addition & 0 deletions src/pages/LandingPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1414,6 +1414,7 @@ function LandingPage() {
creatorName="Alex Rivers"
availableHoldings={featuredHoldings}
keyPriceStroops={resolveCreatorKeyPriceStroops(featuredCreator)}
currentSupply={featuredCreator.creatorShareSupply}
isSubmitting={tradeSubmitting}
onOpenChange={setTradeDialogOpen}
onConfirm={handleConfirmTrade}
Expand Down
25 changes: 25 additions & 0 deletions src/utils/keyPriceDisplay.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,31 @@ export function resolveCreatorKeyPriceStroops(
return null;
}

/**
* Estimates sell proceeds from current key price, supply, and sell quantity.
* Returns null if estimate cannot be computed.
*/
export function estimateSellProceeds(
keyPriceStroops: number | null | undefined,
currentSupply: number | null | undefined,
sellQuantity: number
): number | null {
if (
keyPriceStroops == null ||
!Number.isFinite(keyPriceStroops) ||
currentSupply == null ||
!Number.isFinite(currentSupply) ||
sellQuantity <= 0 ||
!Number.isFinite(sellQuantity)
) {
return null;
}

// For estimate purposes, calculate proceeds as key price multiplied by quantity
const estimatedProceeds = keyPriceStroops * sellQuantity;
return estimatedProceeds;
}

/**
* Formats a stroop amount for display as XLM, falling back to stroops when the
* XLM value would round to zero at the default display precision.
Expand Down
Loading