fix(marketplace): live BTC/USD sats estimate; drop dead Pay button
- Sats prices used a hardcoded $1 = 2500 sats (i.e. $40k/BTC), so buyers were quoted wrong amounts; now uses the live useUsdToSats rate, handles sats/BTC directly, and shows no estimate for unsupported fiat - Removed the 'Pay with Cashu' button, which only ever showed a 'coming soon' toast — a dead affordance. Buyers use Contact Seller.
This commit is contained in:
parent
dca0c0ede1
commit
102d6017bc
1 changed files with 19 additions and 14 deletions
|
|
@ -26,6 +26,7 @@ import { Label } from '@/components/ui/label';
|
||||||
import { useAuthor } from '@/hooks/useAuthor';
|
import { useAuthor } from '@/hooks/useAuthor';
|
||||||
import { useCurrentUser } from '@/hooks/useCurrentUser';
|
import { useCurrentUser } from '@/hooks/useCurrentUser';
|
||||||
import { useCashu } from '@/hooks/wallet/useCashu';
|
import { useCashu } from '@/hooks/wallet/useCashu';
|
||||||
|
import { useUsdToSats } from '@/hooks/useExchangeRate';
|
||||||
import { useToast } from '@/hooks/useToast';
|
import { useToast } from '@/hooks/useToast';
|
||||||
import { useNostrPublish } from '@/hooks/useNostrPublish';
|
import { useNostrPublish } from '@/hooks/useNostrPublish';
|
||||||
import { useListingReports } from '@/hooks/useListingReports';
|
import { useListingReports } from '@/hooks/useListingReports';
|
||||||
|
|
@ -84,7 +85,7 @@ export function MarketplaceItemCard({ item, compact = false }: MarketplaceItemCa
|
||||||
const { data: trustScore } = useTrustScore(item.pubkey);
|
const { data: trustScore } = useTrustScore(item.pubkey);
|
||||||
|
|
||||||
// Cashu wallet integration
|
// Cashu wallet integration
|
||||||
const { totalBalance: cashuBalance, isInitialized: hasCashu, coco } = useCashu();
|
const { totalBalance: cashuBalance, coco } = useCashu();
|
||||||
const [showPaymentDialog, setShowPaymentDialog] = useState(false);
|
const [showPaymentDialog, setShowPaymentDialog] = useState(false);
|
||||||
const [showReportDialog, setShowReportDialog] = useState(false);
|
const [showReportDialog, setShowReportDialog] = useState(false);
|
||||||
const [showDeleteDialog, setShowDeleteDialog] = useState(false);
|
const [showDeleteDialog, setShowDeleteDialog] = useState(false);
|
||||||
|
|
@ -116,9 +117,19 @@ export function MarketplaceItemCard({ item, compact = false }: MarketplaceItemCa
|
||||||
// Get price type label
|
// Get price type label
|
||||||
const priceTypeLabel = item.priceType ? PRICE_TYPES[item.priceType]?.label : null;
|
const priceTypeLabel = item.priceType ? PRICE_TYPES[item.priceType]?.label : null;
|
||||||
|
|
||||||
// Calculate price in sats (rough estimate: $1 = 2500 sats at $40k/BTC)
|
// Sats estimate from the LIVE BTC/USD rate — never a hardcoded constant
|
||||||
const priceInSats = item.price?.amount ? Math.round(parseFloat(item.price.amount) * 2500) : 0;
|
// (that quoted buyers wildly wrong amounts). Non-USD fiat is left unestimated
|
||||||
const canPayWithCashu = hasCashu && cashuBalance >= priceInSats && priceInSats > 0;
|
// rather than inventing a number.
|
||||||
|
const priceAmount = item.price?.amount ? parseFloat(item.price.amount) : 0;
|
||||||
|
const priceCurrency = item.price?.currency || 'USD';
|
||||||
|
const usdAsSats = useUsdToSats(priceCurrency === 'USD' ? priceAmount : null);
|
||||||
|
const priceInSats = !priceAmount
|
||||||
|
? 0
|
||||||
|
: priceCurrency === 'sats'
|
||||||
|
? Math.round(priceAmount)
|
||||||
|
: priceCurrency === 'BTC'
|
||||||
|
? Math.round(priceAmount * 100000000)
|
||||||
|
: (usdAsSats ?? 0);
|
||||||
|
|
||||||
// Seller verification status
|
// Seller verification status
|
||||||
const isVerifiedSeller = sellerInfo?.hasNip05 || false;
|
const isVerifiedSeller = sellerInfo?.hasNip05 || false;
|
||||||
|
|
@ -466,16 +477,10 @@ export function MarketplaceItemCard({ item, compact = false }: MarketplaceItemCa
|
||||||
|
|
||||||
{/* Action Buttons */}
|
{/* Action Buttons */}
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
{/* Pay with Cashu button */}
|
{/* NOTE: there is deliberately no "Pay with Cashu" button here.
|
||||||
{user && !isOwnListing && canPayWithCashu && item.status === 'active' && !isWTB && (
|
Payments are not implemented, and a button that only shows a
|
||||||
<Button
|
"coming soon" toast is a dead end — buyers contact the seller
|
||||||
onClick={() => setShowPaymentDialog(true)}
|
and arrange payment directly. */}
|
||||||
size="sm"
|
|
||||||
className="w-full gap-2 bg-orange-500 hover:bg-orange-600 text-white"
|
|
||||||
>
|
|
||||||
🥜 Pay {priceInSats.toLocaleString()} sats with Cashu
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Contact button */}
|
{/* Contact button */}
|
||||||
<Button
|
<Button
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue