Cancel bet endpoint.
This commit is contained in:
parent
83557515ad
commit
f98bc17bc1
35
functions/src/cancel-bet.ts
Normal file
35
functions/src/cancel-bet.ts
Normal file
|
@ -0,0 +1,35 @@
|
|||
import * as admin from 'firebase-admin'
|
||||
import { z } from 'zod'
|
||||
import { APIError, newEndpoint, validate } from './api'
|
||||
import { LimitBet } from '../../common/bet'
|
||||
|
||||
const bodySchema = z.object({
|
||||
betId: z.string(),
|
||||
})
|
||||
|
||||
export const cancelbet = newEndpoint({}, async (req, auth) => {
|
||||
const { betId } = validate(bodySchema, req.body)
|
||||
|
||||
const result = await firestore.runTransaction(async (trans) => {
|
||||
const snap = await trans.get(
|
||||
firestore.collectionGroup('bets').where('id', '==', betId)
|
||||
)
|
||||
const betDoc = snap.docs[0]
|
||||
if (!betDoc?.exists) throw new APIError(400, 'Bet not found.')
|
||||
|
||||
const bet = betDoc.data() as LimitBet
|
||||
if (bet.userId !== auth.uid)
|
||||
throw new APIError(400, 'Not authorized to cancel bet.')
|
||||
if (bet.limitProb === undefined)
|
||||
throw new APIError(400, 'Not a limit bet: Cannot cancel.')
|
||||
if (bet.isCancelled) throw new APIError(400, 'Bet already cancelled.')
|
||||
|
||||
trans.update(betDoc.ref, { isCancelled: true })
|
||||
|
||||
return { ...bet, isCancelled: true }
|
||||
})
|
||||
|
||||
return result
|
||||
})
|
||||
|
||||
const firestore = admin.firestore()
|
|
@ -32,6 +32,7 @@ export * from './on-update-user'
|
|||
// v2
|
||||
export * from './health'
|
||||
export * from './place-bet'
|
||||
export * from './cancel-bet'
|
||||
export * from './sell-bet'
|
||||
export * from './sell-shares'
|
||||
export * from './create-contract'
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import * as admin from 'firebase-admin'
|
||||
import { z } from 'zod'
|
||||
import { Query } from 'firebase-admin/firestore'
|
||||
import { sumBy } from 'lodash'
|
||||
|
||||
import { APIError, newEndpoint, validate } from './api'
|
||||
import { Contract, CPMM_MIN_POOL_QTY } from '../../common/contract'
|
||||
|
@ -11,12 +13,10 @@ import {
|
|||
getNumericBetsInfo,
|
||||
} from '../../common/new-bet'
|
||||
import { addObjects, removeUndefinedProps } from '../../common/util/object'
|
||||
import { LimitBet } from '../../common/bet'
|
||||
import { floatingEqual } from '../../common/util/math'
|
||||
import { redeemShares } from './redeem-shares'
|
||||
import { log } from './utils'
|
||||
import { LimitBet } from 'common/bet'
|
||||
import { Query } from 'firebase-admin/firestore'
|
||||
import { sumBy } from 'lodash'
|
||||
import { floatingEqual } from 'common/util/math'
|
||||
|
||||
const bodySchema = z.object({
|
||||
contractId: z.string(),
|
||||
|
|
|
@ -3,7 +3,10 @@ import { LimitBet } from 'common/bet'
|
|||
import { formatPercent } from 'common/lib/util/format'
|
||||
import { formatMoney } from 'common/util/format'
|
||||
import { sortBy, sumBy } from 'lodash'
|
||||
import { useState } from 'react'
|
||||
import { cancelBet } from 'web/lib/firebase/api-call'
|
||||
import { Col } from './layout/col'
|
||||
import { LoadingIndicator } from './loading-indicator'
|
||||
import { BinaryOutcomeLabel } from './outcome-label'
|
||||
|
||||
export function OpenBets(props: { bets: LimitBet[]; className?: string }) {
|
||||
|
@ -16,13 +19,7 @@ export function OpenBets(props: { bets: LimitBet[]; className?: string }) {
|
|||
<table className="table-compact table w-full rounded text-gray-500">
|
||||
<tbody>
|
||||
{recentBets.map((bet) => (
|
||||
<LimitBet
|
||||
key={bet.id}
|
||||
bet={bet}
|
||||
onCancel={() => {
|
||||
console.log('Cancel', bet)
|
||||
}}
|
||||
/>
|
||||
<LimitBet key={bet.id} bet={bet} />
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -30,9 +27,16 @@ export function OpenBets(props: { bets: LimitBet[]; className?: string }) {
|
|||
)
|
||||
}
|
||||
|
||||
function LimitBet(props: { bet: LimitBet; onCancel: () => void }) {
|
||||
const { bet, onCancel } = props
|
||||
function LimitBet(props: { bet: LimitBet }) {
|
||||
const { bet } = props
|
||||
const filledAmount = sumBy(bet.fills, (fill) => fill.amount)
|
||||
const [isCancelling, setIsCancelling] = useState(false)
|
||||
|
||||
const onCancel = () => {
|
||||
cancelBet({ betId: bet.id })
|
||||
setIsCancelling(true)
|
||||
}
|
||||
|
||||
return (
|
||||
<tr>
|
||||
<td>
|
||||
|
@ -43,12 +47,16 @@ function LimitBet(props: { bet: LimitBet; onCancel: () => void }) {
|
|||
<td>{formatMoney(bet.amount - filledAmount)}</td>
|
||||
<td>{formatPercent(bet.limitProb)}</td>
|
||||
<td>
|
||||
<button
|
||||
className="btn btn-xs btn-outline my-auto normal-case"
|
||||
onClick={onCancel}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
{isCancelling ? (
|
||||
<LoadingIndicator />
|
||||
) : (
|
||||
<button
|
||||
className="btn btn-xs btn-outline my-auto normal-case"
|
||||
onClick={onCancel}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
|
|
|
@ -62,6 +62,10 @@ export function placeBet(params: any) {
|
|||
return call(getFunctionUrl('placebet'), 'POST', params)
|
||||
}
|
||||
|
||||
export function cancelBet(params: { betId: string }) {
|
||||
return call(getFunctionUrl('cancelbet'), 'POST', params)
|
||||
}
|
||||
|
||||
export function sellShares(params: any) {
|
||||
return call(getFunctionUrl('sellshares'), 'POST', params)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user