2022-05-22 08:36:05 +00:00
|
|
|
import { range } from 'lodash'
|
2022-03-15 22:27:51 +00:00
|
|
|
import {
|
|
|
|
Binary,
|
|
|
|
Contract,
|
|
|
|
CPMM,
|
|
|
|
DPM,
|
|
|
|
FreeResponse,
|
2022-07-28 02:40:33 +00:00
|
|
|
MultipleChoice,
|
2022-05-19 17:42:03 +00:00
|
|
|
Numeric,
|
2022-03-15 22:27:51 +00:00
|
|
|
outcomeType,
|
2022-07-02 19:37:59 +00:00
|
|
|
PseudoNumeric,
|
2022-08-20 19:31:32 +00:00
|
|
|
visibility,
|
2022-03-15 22:27:51 +00:00
|
|
|
} from './contract'
|
2022-01-10 23:52:03 +00:00
|
|
|
import { User } from './user'
|
Rich content (#620)
* Add TipTap editor and renderer components
* Change market description editor to rich text
* Type description as JSON, fix string-based logic
- Delete make-predictions.tsx
- Delete feed logic that showed descriptions
* wip Fix API validation
* fix type error
* fix extension import (backend)
In firebase, typescript compiles imports into common js imports
like `const StarterKit = require("@tiptap/starter-kit")`
Even though StarterKit is exported from the cjs file, it gets imported
as undefined. But it magically works if we import *
If you're reading this in the future, consider replacing StarterKit with
the entire list of extensions.
* Stop load on fail create market, improve warning
* Refactor editor as hook / fix infinite submit bug
Move state of editor back up to parent
We have to do this later anyways to allow parent to edit
* Add images - display, paste + uploading
* add uploading state of image
* Fix placeholder, misc styling
min height, quote
* Fix appending to description
* code review fixes: rename, refactor, chop carets
* Add hint & upload button on new lines
- bump to Tailwind 3.1 for arbitrary variants
* clean up, run prettier
* rename FileButton to FileUploadButton
* add image extension as functions dependency
2022-07-13 18:58:22 +00:00
|
|
|
import { parseTags, richTextToString } from './util/parse'
|
2022-02-17 23:00:19 +00:00
|
|
|
import { removeUndefinedProps } from './util/object'
|
Rich content (#620)
* Add TipTap editor and renderer components
* Change market description editor to rich text
* Type description as JSON, fix string-based logic
- Delete make-predictions.tsx
- Delete feed logic that showed descriptions
* wip Fix API validation
* fix type error
* fix extension import (backend)
In firebase, typescript compiles imports into common js imports
like `const StarterKit = require("@tiptap/starter-kit")`
Even though StarterKit is exported from the cjs file, it gets imported
as undefined. But it magically works if we import *
If you're reading this in the future, consider replacing StarterKit with
the entire list of extensions.
* Stop load on fail create market, improve warning
* Refactor editor as hook / fix infinite submit bug
Move state of editor back up to parent
We have to do this later anyways to allow parent to edit
* Add images - display, paste + uploading
* add uploading state of image
* Fix placeholder, misc styling
min height, quote
* Fix appending to description
* code review fixes: rename, refactor, chop carets
* Add hint & upload button on new lines
- bump to Tailwind 3.1 for arbitrary variants
* clean up, run prettier
* rename FileButton to FileUploadButton
* add image extension as functions dependency
2022-07-13 18:58:22 +00:00
|
|
|
import { JSONContent } from '@tiptap/core'
|
2022-01-10 22:49:04 +00:00
|
|
|
|
|
|
|
export function getNewContract(
|
|
|
|
id: string,
|
|
|
|
slug: string,
|
|
|
|
creator: User,
|
|
|
|
question: string,
|
2022-02-17 23:00:19 +00:00
|
|
|
outcomeType: outcomeType,
|
Rich content (#620)
* Add TipTap editor and renderer components
* Change market description editor to rich text
* Type description as JSON, fix string-based logic
- Delete make-predictions.tsx
- Delete feed logic that showed descriptions
* wip Fix API validation
* fix type error
* fix extension import (backend)
In firebase, typescript compiles imports into common js imports
like `const StarterKit = require("@tiptap/starter-kit")`
Even though StarterKit is exported from the cjs file, it gets imported
as undefined. But it magically works if we import *
If you're reading this in the future, consider replacing StarterKit with
the entire list of extensions.
* Stop load on fail create market, improve warning
* Refactor editor as hook / fix infinite submit bug
Move state of editor back up to parent
We have to do this later anyways to allow parent to edit
* Add images - display, paste + uploading
* add uploading state of image
* Fix placeholder, misc styling
min height, quote
* Fix appending to description
* code review fixes: rename, refactor, chop carets
* Add hint & upload button on new lines
- bump to Tailwind 3.1 for arbitrary variants
* clean up, run prettier
* rename FileButton to FileUploadButton
* add image extension as functions dependency
2022-07-13 18:58:22 +00:00
|
|
|
description: JSONContent,
|
2022-01-10 22:49:04 +00:00
|
|
|
initialProb: number,
|
2022-01-24 22:33:02 +00:00
|
|
|
ante: number,
|
2022-01-27 18:45:35 +00:00
|
|
|
closeTime: number,
|
2022-05-09 20:09:07 +00:00
|
|
|
extraTags: string[],
|
2022-05-19 17:42:03 +00:00
|
|
|
|
|
|
|
// used for numeric markets
|
|
|
|
bucketCount: number,
|
|
|
|
min: number,
|
2022-07-02 19:37:59 +00:00
|
|
|
max: number,
|
2022-07-28 02:40:33 +00:00
|
|
|
isLogScale: boolean,
|
|
|
|
|
|
|
|
// for multiple choice
|
2022-08-20 19:31:32 +00:00
|
|
|
answers: string[],
|
|
|
|
visibility: visibility
|
2022-01-10 22:49:04 +00:00
|
|
|
) {
|
2022-01-27 18:45:35 +00:00
|
|
|
const tags = parseTags(
|
Rich content (#620)
* Add TipTap editor and renderer components
* Change market description editor to rich text
* Type description as JSON, fix string-based logic
- Delete make-predictions.tsx
- Delete feed logic that showed descriptions
* wip Fix API validation
* fix type error
* fix extension import (backend)
In firebase, typescript compiles imports into common js imports
like `const StarterKit = require("@tiptap/starter-kit")`
Even though StarterKit is exported from the cjs file, it gets imported
as undefined. But it magically works if we import *
If you're reading this in the future, consider replacing StarterKit with
the entire list of extensions.
* Stop load on fail create market, improve warning
* Refactor editor as hook / fix infinite submit bug
Move state of editor back up to parent
We have to do this later anyways to allow parent to edit
* Add images - display, paste + uploading
* add uploading state of image
* Fix placeholder, misc styling
min height, quote
* Fix appending to description
* code review fixes: rename, refactor, chop carets
* Add hint & upload button on new lines
- bump to Tailwind 3.1 for arbitrary variants
* clean up, run prettier
* rename FileButton to FileUploadButton
* add image extension as functions dependency
2022-07-13 18:58:22 +00:00
|
|
|
[
|
|
|
|
question,
|
|
|
|
richTextToString(description),
|
|
|
|
...extraTags.map((tag) => `#${tag}`),
|
|
|
|
].join(' ')
|
2022-01-27 18:45:35 +00:00
|
|
|
)
|
2022-01-24 22:33:02 +00:00
|
|
|
const lowercaseTags = tags.map((tag) => tag.toLowerCase())
|
|
|
|
|
2022-02-17 23:00:19 +00:00
|
|
|
const propsByOutcomeType =
|
|
|
|
outcomeType === 'BINARY'
|
2022-03-15 22:27:51 +00:00
|
|
|
? getBinaryCpmmProps(initialProb, ante) // getBinaryDpmProps(initialProb, ante)
|
2022-07-02 19:37:59 +00:00
|
|
|
: outcomeType === 'PSEUDO_NUMERIC'
|
|
|
|
? getPseudoNumericCpmmProps(initialProb, ante, min, max, isLogScale)
|
2022-05-19 17:42:03 +00:00
|
|
|
: outcomeType === 'NUMERIC'
|
|
|
|
? getNumericProps(ante, bucketCount, min, max)
|
2022-07-28 02:40:33 +00:00
|
|
|
: outcomeType === 'MULTIPLE_CHOICE'
|
|
|
|
? getMultipleChoiceProps(ante, answers)
|
2022-02-17 23:00:19 +00:00
|
|
|
: getFreeAnswerProps(ante)
|
|
|
|
|
|
|
|
const contract: Contract = removeUndefinedProps({
|
2022-01-10 22:49:04 +00:00
|
|
|
id,
|
|
|
|
slug,
|
2022-02-17 23:00:19 +00:00
|
|
|
...propsByOutcomeType,
|
2022-01-10 22:49:04 +00:00
|
|
|
|
|
|
|
creatorId: creator.id,
|
|
|
|
creatorName: creator.name,
|
|
|
|
creatorUsername: creator.username,
|
2022-01-16 06:03:59 +00:00
|
|
|
creatorAvatarUrl: creator.avatarUrl,
|
2022-01-10 22:49:04 +00:00
|
|
|
|
|
|
|
question: question.trim(),
|
Rich content (#620)
* Add TipTap editor and renderer components
* Change market description editor to rich text
* Type description as JSON, fix string-based logic
- Delete make-predictions.tsx
- Delete feed logic that showed descriptions
* wip Fix API validation
* fix type error
* fix extension import (backend)
In firebase, typescript compiles imports into common js imports
like `const StarterKit = require("@tiptap/starter-kit")`
Even though StarterKit is exported from the cjs file, it gets imported
as undefined. But it magically works if we import *
If you're reading this in the future, consider replacing StarterKit with
the entire list of extensions.
* Stop load on fail create market, improve warning
* Refactor editor as hook / fix infinite submit bug
Move state of editor back up to parent
We have to do this later anyways to allow parent to edit
* Add images - display, paste + uploading
* add uploading state of image
* Fix placeholder, misc styling
min height, quote
* Fix appending to description
* code review fixes: rename, refactor, chop carets
* Add hint & upload button on new lines
- bump to Tailwind 3.1 for arbitrary variants
* clean up, run prettier
* rename FileButton to FileUploadButton
* add image extension as functions dependency
2022-07-13 18:58:22 +00:00
|
|
|
description,
|
2022-01-24 22:33:02 +00:00
|
|
|
tags,
|
|
|
|
lowercaseTags,
|
2022-08-20 19:31:32 +00:00
|
|
|
visibility,
|
2022-01-10 22:49:04 +00:00
|
|
|
isResolved: false,
|
|
|
|
createdTime: Date.now(),
|
2022-02-17 23:00:19 +00:00
|
|
|
closeTime,
|
2022-01-10 22:49:04 +00:00
|
|
|
|
2022-05-13 13:43:12 +00:00
|
|
|
volume: 0,
|
2022-01-10 22:49:04 +00:00
|
|
|
volume24Hours: 0,
|
|
|
|
volume7Days: 0,
|
2022-03-15 22:27:51 +00:00
|
|
|
|
|
|
|
collectedFees: {
|
|
|
|
creatorFee: 0,
|
|
|
|
liquidityFee: 0,
|
|
|
|
platformFee: 0,
|
|
|
|
},
|
2022-02-17 23:00:19 +00:00
|
|
|
})
|
|
|
|
|
2022-03-15 22:27:51 +00:00
|
|
|
return contract as Contract
|
2022-02-17 23:00:19 +00:00
|
|
|
}
|
|
|
|
|
2022-05-26 00:12:36 +00:00
|
|
|
/*
|
|
|
|
import { PHANTOM_ANTE } from './antes'
|
|
|
|
import { calcDpmInitialPool } from './calculate-dpm'
|
2022-03-15 22:27:51 +00:00
|
|
|
const getBinaryDpmProps = (initialProb: number, ante: number) => {
|
2022-02-17 23:00:19 +00:00
|
|
|
const { sharesYes, sharesNo, poolYes, poolNo, phantomYes, phantomNo } =
|
2022-03-15 22:27:51 +00:00
|
|
|
calcDpmInitialPool(initialProb, ante, PHANTOM_ANTE)
|
2022-02-17 23:00:19 +00:00
|
|
|
|
2022-03-15 22:27:51 +00:00
|
|
|
const system: DPM & Binary = {
|
|
|
|
mechanism: 'dpm-2',
|
|
|
|
outcomeType: 'BINARY',
|
|
|
|
initialProbability: initialProb / 100,
|
2022-02-17 23:00:19 +00:00
|
|
|
phantomShares: { YES: phantomYes, NO: phantomNo },
|
|
|
|
pool: { YES: poolYes, NO: poolNo },
|
|
|
|
totalShares: { YES: sharesYes, NO: sharesNo },
|
|
|
|
totalBets: { YES: poolYes, NO: poolNo },
|
2022-01-10 23:52:03 +00:00
|
|
|
}
|
2022-03-15 22:27:51 +00:00
|
|
|
|
|
|
|
return system
|
|
|
|
}
|
2022-05-26 00:12:36 +00:00
|
|
|
*/
|
2022-03-15 22:27:51 +00:00
|
|
|
|
|
|
|
const getBinaryCpmmProps = (initialProb: number, ante: number) => {
|
|
|
|
const pool = { YES: ante, NO: ante }
|
|
|
|
const p = initialProb / 100
|
|
|
|
|
|
|
|
const system: CPMM & Binary = {
|
|
|
|
mechanism: 'cpmm-1',
|
|
|
|
outcomeType: 'BINARY',
|
|
|
|
totalLiquidity: ante,
|
|
|
|
initialProbability: p,
|
|
|
|
p,
|
|
|
|
pool: pool,
|
|
|
|
}
|
|
|
|
|
|
|
|
return system
|
2022-02-17 23:00:19 +00:00
|
|
|
}
|
2022-01-10 22:49:04 +00:00
|
|
|
|
2022-07-02 19:37:59 +00:00
|
|
|
const getPseudoNumericCpmmProps = (
|
|
|
|
initialProb: number,
|
|
|
|
ante: number,
|
|
|
|
min: number,
|
|
|
|
max: number,
|
|
|
|
isLogScale: boolean
|
|
|
|
) => {
|
|
|
|
const system: CPMM & PseudoNumeric = {
|
|
|
|
...getBinaryCpmmProps(initialProb, ante),
|
|
|
|
outcomeType: 'PSEUDO_NUMERIC',
|
|
|
|
min,
|
|
|
|
max,
|
|
|
|
isLogScale,
|
|
|
|
}
|
|
|
|
|
|
|
|
return system
|
|
|
|
}
|
|
|
|
|
2022-02-17 23:00:19 +00:00
|
|
|
const getFreeAnswerProps = (ante: number) => {
|
2022-03-15 22:27:51 +00:00
|
|
|
const system: DPM & FreeResponse = {
|
|
|
|
mechanism: 'dpm-2',
|
|
|
|
outcomeType: 'FREE_RESPONSE',
|
2022-02-17 23:00:19 +00:00
|
|
|
pool: { '0': ante },
|
|
|
|
totalShares: { '0': ante },
|
|
|
|
totalBets: { '0': ante },
|
|
|
|
answers: [],
|
|
|
|
}
|
2022-03-15 22:27:51 +00:00
|
|
|
|
|
|
|
return system
|
2022-02-17 23:00:19 +00:00
|
|
|
}
|
2022-01-10 22:49:04 +00:00
|
|
|
|
2022-07-28 02:40:33 +00:00
|
|
|
const getMultipleChoiceProps = (ante: number, answers: string[]) => {
|
|
|
|
const numAnswers = answers.length
|
|
|
|
const betAnte = ante / numAnswers
|
|
|
|
const betShares = Math.sqrt(ante ** 2 / numAnswers)
|
|
|
|
|
|
|
|
const defaultValues = (x: any) =>
|
|
|
|
Object.fromEntries(range(0, numAnswers).map((k) => [k, x]))
|
|
|
|
|
|
|
|
const system: DPM & MultipleChoice = {
|
|
|
|
mechanism: 'dpm-2',
|
|
|
|
outcomeType: 'MULTIPLE_CHOICE',
|
|
|
|
pool: defaultValues(betAnte),
|
|
|
|
totalShares: defaultValues(betShares),
|
|
|
|
totalBets: defaultValues(betAnte),
|
|
|
|
answers: [],
|
|
|
|
}
|
|
|
|
|
|
|
|
return system
|
|
|
|
}
|
|
|
|
|
2022-05-19 17:42:03 +00:00
|
|
|
const getNumericProps = (
|
|
|
|
ante: number,
|
|
|
|
bucketCount: number,
|
|
|
|
min: number,
|
|
|
|
max: number
|
|
|
|
) => {
|
2022-05-22 08:36:05 +00:00
|
|
|
const buckets = range(0, bucketCount).map((i) => i.toString())
|
2022-05-19 17:42:03 +00:00
|
|
|
|
|
|
|
const betAnte = ante / bucketCount
|
|
|
|
const pool = Object.fromEntries(buckets.map((answer) => [answer, betAnte]))
|
|
|
|
const totalBets = pool
|
|
|
|
|
|
|
|
const betShares = Math.sqrt(ante ** 2 / bucketCount)
|
|
|
|
const totalShares = Object.fromEntries(
|
|
|
|
buckets.map((answer) => [answer, betShares])
|
|
|
|
)
|
|
|
|
|
|
|
|
const system: DPM & Numeric = {
|
|
|
|
mechanism: 'dpm-2',
|
|
|
|
outcomeType: 'NUMERIC',
|
|
|
|
pool,
|
|
|
|
totalBets,
|
|
|
|
totalShares,
|
|
|
|
bucketCount,
|
|
|
|
min,
|
|
|
|
max,
|
|
|
|
}
|
|
|
|
|
|
|
|
return system
|
|
|
|
}
|