From fbdc6eacad98b0d471844e82eae2f61d33bbfcd2 Mon Sep 17 00:00:00 2001 From: James Grugett Date: Mon, 14 Feb 2022 23:21:44 -0600 Subject: [PATCH] Can bet. More layout tweaks! --- functions/src/place-bet.ts | 31 +++++++++++-- web/components/answers-panel.tsx | 60 +++++++++++++------------ web/pages/[username]/[contractSlug].tsx | 1 + 3 files changed, 60 insertions(+), 32 deletions(-) diff --git a/functions/src/place-bet.ts b/functions/src/place-bet.ts index 333928d8..3be51790 100644 --- a/functions/src/place-bet.ts +++ b/functions/src/place-bet.ts @@ -3,7 +3,7 @@ import * as admin from 'firebase-admin' import { Contract } from '../../common/contract' import { User } from '../../common/user' -import { getNewBinaryBetInfo } from '../../common/new-bet' +import { getNewBinaryBetInfo, getNewMultiBetInfo } from '../../common/new-bet' export const placeBet = functions.runWith({ minInstances: 1 }).https.onCall( async ( @@ -22,7 +22,7 @@ export const placeBet = functions.runWith({ minInstances: 1 }).https.onCall( if (amount <= 0 || isNaN(amount) || !isFinite(amount)) return { status: 'error', message: 'Invalid amount' } - if (outcome !== 'YES' && outcome !== 'NO') + if (outcome !== 'YES' && outcome !== 'NO' && isNaN(+outcome)) return { status: 'error', message: 'Invalid outcome' } // run as transaction to prevent race conditions @@ -42,16 +42,39 @@ export const placeBet = functions.runWith({ minInstances: 1 }).https.onCall( return { status: 'error', message: 'Invalid contract' } const contract = contractSnap.data() as Contract - const { closeTime } = contract + const { closeTime, outcomes } = contract if (closeTime && Date.now() > closeTime) return { status: 'error', message: 'Trading is closed' } + const isFreeAnswer = outcomes === 'FREE_ANSWER' + if (isFreeAnswer) { + const answerSnap = await transaction.get( + contractDoc.collection('answers').doc(outcome) + ) + if (!answerSnap.exists) + return { status: 'error', message: 'Invalid contract' } + } + const newBetDoc = firestore .collection(`contracts/${contractId}/bets`) .doc() const { newBet, newPool, newTotalShares, newTotalBets, newBalance } = - getNewBinaryBetInfo(user, outcome, amount, contract, newBetDoc.id) + isFreeAnswer + ? getNewMultiBetInfo( + user, + outcome, + amount, + contract as any, + newBetDoc.id + ) + : getNewBinaryBetInfo( + user, + outcome as 'YES' | 'NO', + amount, + contract, + newBetDoc.id + ) transaction.create(newBetDoc, newBet) transaction.update(contractDoc, { diff --git a/web/components/answers-panel.tsx b/web/components/answers-panel.tsx index 21e3b799..a49523be 100644 --- a/web/components/answers-panel.tsx +++ b/web/components/answers-panel.tsx @@ -46,7 +46,7 @@ export function AnswersPanel(props: { ) return ( - + {sortedAnswers.map((answer) => ( ))} @@ -66,7 +66,7 @@ function AnswerItem(props: { answer: Answer; contract: Contract<'MULTI'> }) { const [isBetting, setIsBetting] = useState(false) return ( - +
{text}
@@ -150,6 +150,7 @@ function AnswerBetPanel(props: { console.log('placed bet. Result:', result) if (result?.status === 'success') { + setIsSubmitting(false) closePanel() } else { setError(result?.error || 'Error placing bet') @@ -184,7 +185,7 @@ function AnswerBetPanel(props: { const currentReturnPercent = (currentReturn * 100).toFixed() + '%' return ( - +
Buy this answer
@@ -266,14 +267,12 @@ function CreateAnswerInput(props: { contract: Contract<'MULTI'> }) { const submitAnswer = async () => { if (canSubmit) { setIsSubmitting(true) - console.log('submitting', { text, betAmount }) const result = await createAnswer({ contractId: contract.id, text, amount: betAmount, }).then((r) => r.data) - console.log('submit complte', result) setIsSubmitting(false) if (result.status === 'success') { @@ -285,18 +284,34 @@ function CreateAnswerInput(props: { contract: Contract<'MULTI'> }) { } return ( - - - -
Add your answer
-