diff --git a/website/src/lib/components/self/SendMoneyModal.svelte b/website/src/lib/components/self/SendMoneyModal.svelte index 2afc335..26f0b4a 100644 --- a/website/src/lib/components/self/SendMoneyModal.svelte +++ b/website/src/lib/components/self/SendMoneyModal.svelte @@ -35,6 +35,12 @@ coinHoldings.find((holding) => holding.symbol === selectedCoinSymbol) ); + let estimatedValue = $derived( + transferType === 'COIN' && selectedCoinHolding && numericAmount > 0 + ? numericAmount * selectedCoinHolding.currentPrice + : 0 + ); + let maxAmount = $derived( transferType === 'CASH' ? userBalance : selectedCoinHolding ? selectedCoinHolding.quantity : 0 ); @@ -47,10 +53,20 @@ : false ); + let isWithinCashLimit = $derived( + transferType === 'CASH' ? numericAmount >= 10 : true + ); + + let isWithinCoinValueLimit = $derived( + transferType === 'COIN' ? estimatedValue >= 10 : true + ); + let canSend = $derived( hasValidAmount && hasValidRecipient && hasEnoughFunds && + isWithinCashLimit && + isWithinCoinValueLimit && !loading && (transferType === 'CASH' || selectedCoinSymbol.length > 0) ); @@ -65,7 +81,11 @@ } function setMaxAmount() { - amount = maxAmount.toString(); + if (transferType === 'CASH') { + amount = Math.max(maxAmount, 10).toString(); + } else { + amount = maxAmount.toString(); + } } function handleTypeChange(value: string) { @@ -151,12 +171,6 @@ })() ); - let estimatedValue = $derived( - transferType === 'COIN' && selectedCoinHolding && numericAmount > 0 - ? numericAmount * selectedCoinHolding.currentPrice - : 0 - ); - function handleCoinChange(value: string) { selectedCoinSymbol = value; } @@ -267,15 +281,32 @@

{/if} + {#if transferType === 'CASH'} +

+ Minimum: $10.00 per transfer +

+ {:else if transferType === 'COIN'} +

+ Minimum estimated value: $10.00 per transfer +

+ {/if} {#if !hasEnoughFunds && hasValidAmount} Insufficient {transferType === 'CASH' ? 'funds' : 'coins'} + {:else if !isWithinCashLimit && hasValidAmount} + + Cash transfers require a minimum of $10.00 + + {:else if !isWithinCoinValueLimit && hasValidAmount} + + Coin transfers require a minimum estimated value of $10.00 + {/if} - {#if hasValidAmount && hasEnoughFunds && hasValidRecipient} + {#if hasValidAmount && hasEnoughFunds && hasValidRecipient && isWithinCashLimit && isWithinCoinValueLimit}
You're sending: diff --git a/website/src/routes/api/transfer/+server.ts b/website/src/routes/api/transfer/+server.ts index dfe77d8..e9ce233 100644 --- a/website/src/routes/api/transfer/+server.ts +++ b/website/src/routes/api/transfer/+server.ts @@ -30,6 +30,10 @@ export const POST: RequestHandler = async ({ request }) => { throw error(400, 'Transfer amount too large'); } + if (type === 'CASH' && amount < 10) { + throw error(400, 'Cash transfers require a minimum of $10.00'); + } + if (type === 'COIN' && !coinSymbol) { throw error(400, 'Coin symbol required for coin transfers'); } @@ -140,6 +144,13 @@ export const POST: RequestHandler = async ({ request }) => { throw error(404, 'Coin not found'); } + const coinPrice = Number(coinData.currentPrice) || 0; + const estimatedValue = amount * coinPrice; + + if (estimatedValue < 10) { + throw error(400, `Coin transfers require a minimum estimated value of $10.00. ${amount.toFixed(6)} ${coinData.symbol} is worth approximately $${estimatedValue.toFixed(2)}`); + } + const [senderHolding] = await tx .select({ quantity: userPortfolio.quantity @@ -167,7 +178,6 @@ export const POST: RequestHandler = async ({ request }) => { .for('update') .limit(1); - const coinPrice = Number(coinData.currentPrice) || 0; const totalValue = amount * coinPrice; const newSenderQuantity = Number(senderHolding.quantity) - amount; diff --git a/website/src/routes/hopium/+page.svelte b/website/src/routes/hopium/+page.svelte index 38da00b..9d0bbff 100644 --- a/website/src/routes/hopium/+page.svelte +++ b/website/src/routes/hopium/+page.svelte @@ -108,7 +108,7 @@ return; } if (userBalance <= 100_000) { - toast.error('You need at least $100,000 in your portfolio to create a question.'); + toast.error('You need at least $100,000 in your portfolio (cash) to create a question.'); return; } showCreateDialog = true;