Answer datatype and MULTI outcome type for Contract

This commit is contained in:
James Grugett 2022-02-11 01:10:59 -06:00
parent dc0c9cf1d4
commit 34607262f3
4 changed files with 99 additions and 7 deletions

12
common/answer.ts Normal file
View File

@ -0,0 +1,12 @@
export type Answer = {
id: string
contractId: string
createdTime: number
userId: string
username: string
name: string
avatarUrl?: string
text: string
}

View File

@ -1,4 +1,4 @@
export type Contract = {
export type Contract<outcomeType extends 'BINARY' | 'MULTI' = 'BINARY'> = {
id: string
slug: string // auto-generated; must be unique
@ -11,14 +11,26 @@ export type Contract = {
description: string // More info about what the contract is about
tags: string[]
lowercaseTags: string[]
outcomeType: 'BINARY' // | 'MULTI' | 'interval' | 'date'
outcomeType: outcomeType
visibility: 'public' | 'unlisted'
mechanism: 'dpm-2'
phantomShares: { YES: number; NO: number }
pool: { YES: number; NO: number }
totalShares: { YES: number; NO: number }
totalBets: { YES: number; NO: number }
phantomShares: {
BINARY: { YES: number; NO: number }
MULTI: { [answerId: string]: number }
}[outcomeType]
pool: {
BINARY: { YES: number; NO: number }
MULTI: { [answerId: string]: number }
}[outcomeType]
totalShares: {
BINARY: { YES: number; NO: number }
MULTI: { [answerId: string]: number }
}[outcomeType]
totalBets: {
BINARY: { YES: number; NO: number }
MULTI: { [answerId: string]: number }
}[outcomeType]
createdTime: number // Milliseconds since epoch
lastUpdatedTime: number // If the question or description was changed
@ -26,7 +38,10 @@ export type Contract = {
isResolved: boolean
resolutionTime?: number // When the contract creator resolved the market
resolution?: outcome // Chosen by creator; must be one of outcomes
resolution?: {
BINARY: outcome
MULTI: string
}[outcomeType]
resolutionProbability?: number
volume24Hours: number

13
web/hooks/use-answers.ts Normal file
View File

@ -0,0 +1,13 @@
import { useEffect, useState } from 'react'
import { Answer } from '../../common/answer'
import { listenForAnswers } from '../lib/firebase/answers'
export const useAnswers = (contractId: string) => {
const [answers, setAnswers] = useState<Answer[] | undefined>()
useEffect(() => {
if (contractId) return listenForAnswers(contractId, setAnswers)
}, [contractId])
return answers
}

View File

@ -0,0 +1,52 @@
import { doc, collection, setDoc } from 'firebase/firestore'
import { getValues, listenForValues } from './utils'
import { db } from './init'
import { User } from '../../../common/user'
import { Answer } from '../../../common/answer'
function getAnswersCollection(contractId: string) {
return collection(db, 'contracts', contractId, 'answers')
}
export async function createAnswer(
contractId: string,
text: string,
user: User
) {
const { id: userId, username, name, avatarUrl } = user
const ref = doc(getAnswersCollection(contractId))
const answer: Answer = {
id: ref.id,
contractId,
createdTime: Date.now(),
userId,
username,
name,
avatarUrl,
text,
}
return await setDoc(ref, answer)
}
export async function listAllAnswers(contractId: string) {
const answers = await getValues<Answer>(getAnswersCollection(contractId))
answers.sort((c1, c2) => c1.createdTime - c2.createdTime)
return answers
}
export function listenForAnswers(
contractId: string,
setAnswers: (answers: Answer[]) => void
) {
return listenForValues<Answer>(
getAnswersCollection(contractId),
(answers) => {
answers.sort((c1, c2) => c1.createdTime - c2.createdTime)
setAnswers(answers)
}
)
}