Change outcomeType to include 'MULTI' and 'FREE_RESPONSE'
This commit is contained in:
parent
445176fad2
commit
58cec94b72
|
@ -80,7 +80,7 @@ export function getFreeAnswerAnte(
|
||||||
amount,
|
amount,
|
||||||
shares,
|
shares,
|
||||||
outcome: '0',
|
outcome: '0',
|
||||||
probBefore: 1,
|
probBefore: 0,
|
||||||
probAfter: 1,
|
probAfter: 1,
|
||||||
createdTime,
|
createdTime,
|
||||||
isAnte: true,
|
isAnte: true,
|
||||||
|
|
|
@ -13,8 +13,8 @@ export type Contract = {
|
||||||
lowercaseTags: string[]
|
lowercaseTags: string[]
|
||||||
visibility: 'public' | 'unlisted'
|
visibility: 'public' | 'unlisted'
|
||||||
|
|
||||||
outcomeType: 'BINARY' | 'MULTI'
|
outcomeType: 'BINARY' | 'MULTI' | 'FREE_RESPONSE'
|
||||||
outcomes?: 'FREE_ANSWER' | string[]
|
multiOutcomes?: string[] // Used for outcomeType 'MULTI'.
|
||||||
|
|
||||||
mechanism: 'dpm-2'
|
mechanism: 'dpm-2'
|
||||||
phantomShares?: { [outcome: string]: number }
|
phantomShares?: { [outcome: string]: number }
|
||||||
|
@ -34,3 +34,5 @@ export type Contract = {
|
||||||
volume24Hours: number
|
volume24Hours: number
|
||||||
volume7Days: number
|
volume7Days: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type outcomeType = 'BINARY' | 'MULTI' | 'FREE_RESPONSE'
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { calcStartPool } from './antes'
|
import { calcStartPool } from './antes'
|
||||||
import { Contract } from './contract'
|
import { Contract, outcomeType } from './contract'
|
||||||
import { User } from './user'
|
import { User } from './user'
|
||||||
import { parseTags } from './util/parse'
|
import { parseTags } from './util/parse'
|
||||||
import { removeUndefinedProps } from './util/object'
|
import { removeUndefinedProps } from './util/object'
|
||||||
|
@ -9,7 +9,7 @@ export function getNewContract(
|
||||||
slug: string,
|
slug: string,
|
||||||
creator: User,
|
creator: User,
|
||||||
question: string,
|
question: string,
|
||||||
outcomeType: 'BINARY' | 'MULTI',
|
outcomeType: outcomeType,
|
||||||
description: string,
|
description: string,
|
||||||
initialProb: number,
|
initialProb: number,
|
||||||
ante: number,
|
ante: number,
|
||||||
|
@ -64,7 +64,6 @@ const getBinaryProps = (initialProb: number, ante: number) => {
|
||||||
pool: { YES: poolYes, NO: poolNo },
|
pool: { YES: poolYes, NO: poolNo },
|
||||||
totalShares: { YES: sharesYes, NO: sharesNo },
|
totalShares: { YES: sharesYes, NO: sharesNo },
|
||||||
totalBets: { YES: poolYes, NO: poolNo },
|
totalBets: { YES: poolYes, NO: poolNo },
|
||||||
outcomes: undefined,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,8 +72,6 @@ const getFreeAnswerProps = (ante: number) => {
|
||||||
pool: { '0': ante },
|
pool: { '0': ante },
|
||||||
totalShares: { '0': ante },
|
totalShares: { '0': ante },
|
||||||
totalBets: { '0': ante },
|
totalBets: { '0': ante },
|
||||||
phantomShares: undefined,
|
|
||||||
outcomes: 'FREE_ANSWER' as const,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,13 +44,10 @@ export const createAnswer = functions.runWith({ minInstances: 1 }).https.onCall(
|
||||||
return { status: 'error', message: 'Invalid contract' }
|
return { status: 'error', message: 'Invalid contract' }
|
||||||
const contract = contractSnap.data() as Contract
|
const contract = contractSnap.data() as Contract
|
||||||
|
|
||||||
if (
|
if (contract.outcomeType !== 'FREE_RESPONSE')
|
||||||
contract.outcomeType !== 'MULTI' ||
|
|
||||||
contract.outcomes !== 'FREE_ANSWER'
|
|
||||||
)
|
|
||||||
return {
|
return {
|
||||||
status: 'error',
|
status: 'error',
|
||||||
message: 'Requires a multi, free answer contract',
|
message: 'Requires a free response contract',
|
||||||
}
|
}
|
||||||
|
|
||||||
const { closeTime } = contract
|
const { closeTime } = contract
|
||||||
|
|
|
@ -2,7 +2,7 @@ import * as functions from 'firebase-functions'
|
||||||
import * as admin from 'firebase-admin'
|
import * as admin from 'firebase-admin'
|
||||||
|
|
||||||
import { chargeUser, getUser } from './utils'
|
import { chargeUser, getUser } from './utils'
|
||||||
import { Contract } from '../../common/contract'
|
import { Contract, outcomeType } from '../../common/contract'
|
||||||
import { slugify } from '../../common/util/slugify'
|
import { slugify } from '../../common/util/slugify'
|
||||||
import { randomString } from '../../common/util/random'
|
import { randomString } from '../../common/util/random'
|
||||||
import { getNewContract } from '../../common/new-contract'
|
import { getNewContract } from '../../common/new-contract'
|
||||||
|
@ -19,7 +19,7 @@ export const createContract = functions
|
||||||
async (
|
async (
|
||||||
data: {
|
data: {
|
||||||
question: string
|
question: string
|
||||||
outcomeType: 'BINARY' | 'MULTI'
|
outcomeType: outcomeType
|
||||||
description: string
|
description: string
|
||||||
initialProb: number
|
initialProb: number
|
||||||
ante: number
|
ante: number
|
||||||
|
@ -40,7 +40,7 @@ export const createContract = functions
|
||||||
return { status: 'error', message: 'Missing question field' }
|
return { status: 'error', message: 'Missing question field' }
|
||||||
|
|
||||||
let outcomeType = data.outcomeType ?? 'BINARY'
|
let outcomeType = data.outcomeType ?? 'BINARY'
|
||||||
if (outcomeType !== 'BINARY' && outcomeType !== 'MULTI')
|
if (!['BINARY', 'MULTI', 'FREE_RESPONSE'].includes(outcomeType))
|
||||||
return { status: 'error', message: 'Invalid outcomeType' }
|
return { status: 'error', message: 'Invalid outcomeType' }
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -106,7 +106,7 @@ export const createContract = functions
|
||||||
)
|
)
|
||||||
await yesBetDoc.set(yesBet)
|
await yesBetDoc.set(yesBet)
|
||||||
await noBetDoc.set(noBet)
|
await noBetDoc.set(noBet)
|
||||||
} else if (outcomeType === 'MULTI') {
|
} else if (outcomeType === 'FREE_RESPONSE') {
|
||||||
const noneAnswerDoc = firestore
|
const noneAnswerDoc = firestore
|
||||||
.collection(`contracts/${contract.id}/answers`)
|
.collection(`contracts/${contract.id}/answers`)
|
||||||
.doc('0')
|
.doc('0')
|
||||||
|
|
|
@ -42,12 +42,11 @@ export const placeBet = functions.runWith({ minInstances: 1 }).https.onCall(
|
||||||
return { status: 'error', message: 'Invalid contract' }
|
return { status: 'error', message: 'Invalid contract' }
|
||||||
const contract = contractSnap.data() as Contract
|
const contract = contractSnap.data() as Contract
|
||||||
|
|
||||||
const { closeTime, outcomes } = contract
|
const { closeTime, outcomeType } = contract
|
||||||
if (closeTime && Date.now() > closeTime)
|
if (closeTime && Date.now() > closeTime)
|
||||||
return { status: 'error', message: 'Trading is closed' }
|
return { status: 'error', message: 'Trading is closed' }
|
||||||
|
|
||||||
const isFreeAnswer = outcomes === 'FREE_ANSWER'
|
if (outcomeType === 'FREE_RESPONSE') {
|
||||||
if (isFreeAnswer) {
|
|
||||||
const answerSnap = await transaction.get(
|
const answerSnap = await transaction.get(
|
||||||
contractDoc.collection('answers').doc(outcome)
|
contractDoc.collection('answers').doc(outcome)
|
||||||
)
|
)
|
||||||
|
@ -60,21 +59,15 @@ export const placeBet = functions.runWith({ minInstances: 1 }).https.onCall(
|
||||||
.doc()
|
.doc()
|
||||||
|
|
||||||
const { newBet, newPool, newTotalShares, newTotalBets, newBalance } =
|
const { newBet, newPool, newTotalShares, newTotalBets, newBalance } =
|
||||||
isFreeAnswer
|
outcomeType === 'BINARY'
|
||||||
? getNewMultiBetInfo(
|
? getNewBinaryBetInfo(
|
||||||
user,
|
|
||||||
outcome,
|
|
||||||
amount,
|
|
||||||
contract as any,
|
|
||||||
newBetDoc.id
|
|
||||||
)
|
|
||||||
: getNewBinaryBetInfo(
|
|
||||||
user,
|
user,
|
||||||
outcome as 'YES' | 'NO',
|
outcome as 'YES' | 'NO',
|
||||||
amount,
|
amount,
|
||||||
contract,
|
contract,
|
||||||
newBetDoc.id
|
newBetDoc.id
|
||||||
)
|
)
|
||||||
|
: getNewMultiBetInfo(user, outcome, amount, contract, newBetDoc.id)
|
||||||
|
|
||||||
transaction.create(newBetDoc, newBet)
|
transaction.create(newBetDoc, newBet)
|
||||||
transaction.update(contractDoc, {
|
transaction.update(contractDoc, {
|
||||||
|
|
|
@ -35,7 +35,7 @@ export const resolveMarket = functions
|
||||||
if (outcomeType === 'BINARY') {
|
if (outcomeType === 'BINARY') {
|
||||||
if (!['YES', 'NO', 'MKT', 'CANCEL'].includes(outcome))
|
if (!['YES', 'NO', 'MKT', 'CANCEL'].includes(outcome))
|
||||||
return { status: 'error', message: 'Invalid outcome' }
|
return { status: 'error', message: 'Invalid outcome' }
|
||||||
} else if (outcomeType === 'MULTI') {
|
} else if (outcomeType === 'FREE_RESPONSE') {
|
||||||
if (outcome !== 'CANCEL' && isNaN(+outcome))
|
if (outcome !== 'CANCEL' && isNaN(+outcome))
|
||||||
return { status: 'error', message: 'Invalid outcome' }
|
return { status: 'error', message: 'Invalid outcome' }
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -42,7 +42,7 @@ export async function getStaticProps(props: {
|
||||||
const [bets, comments, answers] = await Promise.all([
|
const [bets, comments, answers] = await Promise.all([
|
||||||
contractId ? listAllBets(contractId) : [],
|
contractId ? listAllBets(contractId) : [],
|
||||||
contractId ? listAllComments(contractId) : [],
|
contractId ? listAllComments(contractId) : [],
|
||||||
contractId && contract.outcomes === 'FREE_ANSWER'
|
contractId && contract.outcomeType === 'FREE_RESPONSE'
|
||||||
? listAllAnswers(contractId)
|
? listAllAnswers(contractId)
|
||||||
: [],
|
: [],
|
||||||
])
|
])
|
||||||
|
@ -120,7 +120,7 @@ export default function ContractPage(props: {
|
||||||
comments={comments ?? []}
|
comments={comments ?? []}
|
||||||
folds={folds}
|
folds={folds}
|
||||||
>
|
>
|
||||||
{contract.outcomes === 'FREE_ANSWER' && (
|
{contract.outcomeType === 'FREE_RESPONSE' && (
|
||||||
<>
|
<>
|
||||||
<Spacer h={4} />
|
<Spacer h={4} />
|
||||||
<AnswersPanel
|
<AnswersPanel
|
||||||
|
|
|
@ -18,6 +18,7 @@ import { ProbabilitySelector } from '../components/probability-selector'
|
||||||
import { parseWordsAsTags } from '../../common/util/parse'
|
import { parseWordsAsTags } from '../../common/util/parse'
|
||||||
import { TagsList } from '../components/tags-list'
|
import { TagsList } from '../components/tags-list'
|
||||||
import { Row } from '../components/layout/row'
|
import { Row } from '../components/layout/row'
|
||||||
|
import { outcomeType } from '../../common/contract'
|
||||||
|
|
||||||
export default function Create() {
|
export default function Create() {
|
||||||
const [question, setQuestion] = useState('')
|
const [question, setQuestion] = useState('')
|
||||||
|
@ -62,7 +63,7 @@ export function NewContract(props: { question: string; tag?: string }) {
|
||||||
createContract({}).catch() // warm up function
|
createContract({}).catch() // warm up function
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const [outcomeType, setOutcomeType] = useState<'BINARY' | 'MULTI'>('BINARY')
|
const [outcomeType, setOutcomeType] = useState<outcomeType>('BINARY')
|
||||||
const [initialProb, setInitialProb] = useState(50)
|
const [initialProb, setInitialProb] = useState(50)
|
||||||
const [description, setDescription] = useState('')
|
const [description, setDescription] = useState('')
|
||||||
const [tagText, setTagText] = useState<string>(tag ?? '')
|
const [tagText, setTagText] = useState<string>(tag ?? '')
|
||||||
|
@ -143,7 +144,7 @@ export function NewContract(props: { question: string; tag?: string }) {
|
||||||
name="opt"
|
name="opt"
|
||||||
checked={outcomeType === 'BINARY'}
|
checked={outcomeType === 'BINARY'}
|
||||||
value="BINARY"
|
value="BINARY"
|
||||||
onChange={(e) => setOutcomeType(e.target.value as 'BINARY')}
|
onChange={() => setOutcomeType('BINARY')}
|
||||||
/>
|
/>
|
||||||
<span className="label-text">Yes / No</span>
|
<span className="label-text">Yes / No</span>
|
||||||
</label>
|
</label>
|
||||||
|
@ -153,9 +154,9 @@ export function NewContract(props: { question: string; tag?: string }) {
|
||||||
className="radio"
|
className="radio"
|
||||||
type="radio"
|
type="radio"
|
||||||
name="opt"
|
name="opt"
|
||||||
checked={outcomeType === 'MULTI'}
|
checked={outcomeType === 'FREE_RESPONSE'}
|
||||||
value="MULTI"
|
value="FREE_RESPONSE"
|
||||||
onChange={(e) => setOutcomeType(e.target.value as 'MULTI')}
|
onChange={() => setOutcomeType('FREE_RESPONSE')}
|
||||||
/>
|
/>
|
||||||
<span className="label-text">Free response</span>
|
<span className="label-text">Free response</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user