Step 5: Update exchange price endpoint to use new pricing config
- Update ExchangeConfigResponse schema with direction-specific fields - Remove premium_percentage from PriceResponse (now in config) - Update price endpoint to load pricing config from database - Update frontend to use direction-specific min/max and calculate premium - Update tests to seed pricing config - Add logic to clamp amount when direction changes
This commit is contained in:
parent
d838d1be96
commit
d317939ad0
5 changed files with 145 additions and 44 deletions
|
|
@ -13,6 +13,7 @@ interface PriceDisplayProps {
|
|||
lastUpdate: Date | null;
|
||||
direction: "buy" | "sell";
|
||||
agreedPrice: number;
|
||||
premiumPercent: number;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -94,10 +95,10 @@ export function PriceDisplay({
|
|||
lastUpdate,
|
||||
direction,
|
||||
agreedPrice,
|
||||
premiumPercent,
|
||||
}: PriceDisplayProps) {
|
||||
const t = useTranslation("exchange");
|
||||
const marketPrice = priceData?.price?.market_price ?? 0;
|
||||
const premiumPercent = priceData?.price?.premium_percentage ?? 5;
|
||||
const isPriceStale = priceData?.price?.is_stale ?? false;
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -116,24 +116,42 @@ export default function ExchangePage() {
|
|||
|
||||
// Config from API
|
||||
const config = priceData?.config;
|
||||
const eurMin = config?.eur_min ?? 100;
|
||||
const eurMax = config?.eur_max ?? 3000;
|
||||
const eurMinBuy = config?.eur_min_buy ?? 10000;
|
||||
const eurMaxBuy = config?.eur_max_buy ?? 300000;
|
||||
const eurMinSell = config?.eur_min_sell ?? 10000;
|
||||
const eurMaxSell = config?.eur_max_sell ?? 300000;
|
||||
const eurIncrement = config?.eur_increment ?? 20;
|
||||
|
||||
// Get direction-specific min/max
|
||||
const eurMin = direction === "buy" ? eurMinBuy : eurMinSell;
|
||||
const eurMax = direction === "buy" ? eurMaxBuy : eurMaxSell;
|
||||
|
||||
// Compute trade details
|
||||
const price = priceData?.price;
|
||||
const marketPrice = price?.market_price ?? 0;
|
||||
const premiumPercent = price?.premium_percentage ?? 5;
|
||||
const premiumBuy = config?.premium_buy ?? 5;
|
||||
const premiumSell = config?.premium_sell ?? 5;
|
||||
const smallTradeThreshold = config?.small_trade_threshold_eur ?? 0;
|
||||
const smallTradeExtraPremium = config?.small_trade_extra_premium ?? 0;
|
||||
|
||||
// Calculate agreed price based on direction
|
||||
// Calculate total premium: base premium for direction + extra if small trade
|
||||
const totalPremiumPercent = useMemo(() => {
|
||||
const basePremium = direction === "buy" ? premiumBuy : premiumSell;
|
||||
if (eurAmount <= smallTradeThreshold) {
|
||||
return basePremium + smallTradeExtraPremium;
|
||||
}
|
||||
return basePremium;
|
||||
}, [direction, premiumBuy, premiumSell, eurAmount, smallTradeThreshold, smallTradeExtraPremium]);
|
||||
|
||||
// Calculate agreed price based on direction and total premium
|
||||
const agreedPrice = useMemo(() => {
|
||||
if (!marketPrice) return 0;
|
||||
if (direction === "buy") {
|
||||
return marketPrice * (1 + premiumPercent / 100);
|
||||
return marketPrice * (1 + totalPremiumPercent / 100);
|
||||
} else {
|
||||
return marketPrice * (1 - premiumPercent / 100);
|
||||
return marketPrice * (1 - totalPremiumPercent / 100);
|
||||
}
|
||||
}, [marketPrice, premiumPercent, direction]);
|
||||
}, [marketPrice, totalPremiumPercent, direction]);
|
||||
|
||||
// Calculate sats amount
|
||||
const satsAmount = useMemo(() => {
|
||||
|
|
@ -155,6 +173,15 @@ export default function ExchangePage() {
|
|||
}
|
||||
}, [isLightningDisabled, bitcoinTransferMethod]);
|
||||
|
||||
// Clamp amount when direction changes (min/max may differ per direction)
|
||||
useEffect(() => {
|
||||
if (eurAmount < eurMin) {
|
||||
setEurAmount(eurMin);
|
||||
} else if (eurAmount > eurMax) {
|
||||
setEurAmount(eurMax);
|
||||
}
|
||||
}, [direction, eurMin, eurMax]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
// Fetch slots when date is selected
|
||||
useEffect(() => {
|
||||
if (selectedDate && user && isAuthorized) {
|
||||
|
|
@ -307,6 +334,7 @@ export default function ExchangePage() {
|
|||
lastUpdate={lastPriceUpdate}
|
||||
direction={direction}
|
||||
agreedPrice={agreedPrice}
|
||||
premiumPercent={totalPremiumPercent}
|
||||
/>
|
||||
|
||||
{/* Step Indicator */}
|
||||
|
|
@ -322,8 +350,8 @@ export default function ExchangePage() {
|
|||
eurAmount={eurAmount}
|
||||
onEurAmountChange={setEurAmount}
|
||||
satsAmount={satsAmount}
|
||||
eurMin={eurMin}
|
||||
eurMax={eurMax}
|
||||
eurMin={eurMin / 100}
|
||||
eurMax={eurMax / 100}
|
||||
eurIncrement={eurIncrement}
|
||||
isPriceStale={isPriceStale}
|
||||
hasPrice={!!priceData?.price}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue