Scaffold endpoint to add to a bounty

This commit is contained in:
Austin Chen 2022-08-15 16:37:23 -07:00
parent 7e177c0ebf
commit f73b13644f
4 changed files with 62 additions and 0 deletions

View File

@ -0,0 +1,53 @@
import * as admin from 'firebase-admin'
import { z } from 'zod'
import { Contract } from '../../common/contract'
import { User } from '../../common/user'
import { APIError, newEndpoint, validate } from './api'
const firestore = admin.firestore()
const bodySchema = z.object({
contractId: z.string(),
amount: z.number().gt(0),
})
export const addbounty = newEndpoint({}, async (req, auth) => {
const { amount, contractId } = validate(bodySchema, req.body)
return await firestore.runTransaction(async (transaction) => {
const userDoc = firestore.doc(`users/${auth.uid}`)
const userSnap = await transaction.get(userDoc)
if (!userSnap.exists) throw new APIError(400, 'User not found')
const user = userSnap.data() as User
const contractDoc = firestore.doc(`contracts/${contractId}`)
const contractSnap = await transaction.get(contractDoc)
if (!contractSnap.exists) throw new APIError(400, 'Invalid contract')
const contract = contractSnap.data() as Contract
if (contract.outcomeType !== 'BOUNTY')
throw new APIError(400, "Can't add bounties to non-BOUNTY contracts")
const { closeTime } = contract
if (closeTime && Date.now() > closeTime)
throw new APIError(400, 'Contract is closed')
if (user.balance < amount) throw new APIError(400, 'Insufficient balance')
transaction.update(userDoc, {
balance: user.balance - amount,
totalDeposits: user.totalDeposits - amount,
})
const existingPrize = contract.prizes[user.id] ?? 0
transaction.update(contractDoc, {
prizes: {
...contract.prizes,
[user.id]: existingPrize + amount,
},
})
return { status: 'success' }
})
})

View File

@ -66,6 +66,7 @@ import { stripewebhook, createcheckoutsession } from './stripe'
import { getcurrentuser } from './get-current-user'
import { acceptchallenge } from './accept-challenge'
import { getcustomtoken } from './get-custom-token'
import { addbounty } from './add-bounty'
const toCloudFunction = ({ opts, handler }: EndpointDefinition) => {
return onRequest(opts, handler as any)
@ -91,6 +92,7 @@ const createCheckoutSessionFunction = toCloudFunction(createcheckoutsession)
const getCurrentUserFunction = toCloudFunction(getcurrentuser)
const acceptChallenge = toCloudFunction(acceptchallenge)
const getCustomTokenFunction = toCloudFunction(getcustomtoken)
const addBountyFunction = toCloudFunction(addbounty)
export {
healthFunction as health,
@ -114,4 +116,5 @@ export {
getCurrentUserFunction as getcurrentuser,
acceptChallenge as acceptchallenge,
getCustomTokenFunction as getcustomtoken,
addBountyFunction as addbounty,
}

View File

@ -27,6 +27,7 @@ import { unsubscribe } from './unsubscribe'
import { stripewebhook, createcheckoutsession } from './stripe'
import { getcurrentuser } from './get-current-user'
import { getcustomtoken } from './get-custom-token'
import { addbounty } from './add-bounty'
type Middleware = (req: Request, res: Response, next: NextFunction) => void
const app = express()
@ -65,6 +66,7 @@ addJsonEndpointRoute('/resolvemarket', resolvemarket)
addJsonEndpointRoute('/unsubscribe', unsubscribe)
addJsonEndpointRoute('/createcheckoutsession', createcheckoutsession)
addJsonEndpointRoute('/getcurrentuser', getcurrentuser)
addJsonEndpointRoute('/addbounty', addbounty)
addEndpointRoute('/getcustomtoken', getcustomtoken)
addEndpointRoute('/stripewebhook', stripewebhook, express.raw())

View File

@ -88,3 +88,7 @@ export function acceptChallenge(params: any) {
export function getCurrentUser(params: any) {
return call(getFunctionUrl('getcurrentuser'), 'GET', params)
}
export function addBounty(params: any) {
return call(getFunctionUrl('addbounty'), 'POST', params)
}