Free daily markets on hiatus
This commit is contained in:
parent
75907f6c18
commit
211905c27f
|
@ -22,7 +22,6 @@ import {
|
||||||
getCpmmInitialLiquidity,
|
getCpmmInitialLiquidity,
|
||||||
getFreeAnswerAnte,
|
getFreeAnswerAnte,
|
||||||
getNumericAnte,
|
getNumericAnte,
|
||||||
HOUSE_LIQUIDITY_PROVIDER_ID,
|
|
||||||
} from '../../common/antes'
|
} from '../../common/antes'
|
||||||
import { getNoneAnswer } from '../../common/answer'
|
import { getNoneAnswer } from '../../common/answer'
|
||||||
import { getNewContract } from '../../common/new-contract'
|
import { getNewContract } from '../../common/new-contract'
|
||||||
|
@ -64,31 +63,16 @@ export const createmarket = newEndpoint(['POST'], async (req, auth) => {
|
||||||
;({ initialProb } = validate(binarySchema, req.body))
|
;({ initialProb } = validate(binarySchema, req.body))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uses utc time on server:
|
|
||||||
const today = new Date()
|
|
||||||
let freeMarketResetTime = new Date().setUTCHours(16, 0, 0, 0)
|
|
||||||
if (today.getTime() < freeMarketResetTime) {
|
|
||||||
freeMarketResetTime = freeMarketResetTime - 24 * 60 * 60 * 1000
|
|
||||||
}
|
|
||||||
|
|
||||||
const userDoc = await firestore.collection('users').doc(auth.uid).get()
|
const userDoc = await firestore.collection('users').doc(auth.uid).get()
|
||||||
if (!userDoc.exists) {
|
if (!userDoc.exists) {
|
||||||
throw new APIError(400, 'No user exists with the authenticated user ID.')
|
throw new APIError(400, 'No user exists with the authenticated user ID.')
|
||||||
}
|
}
|
||||||
const user = userDoc.data() as User
|
const user = userDoc.data() as User
|
||||||
|
|
||||||
const userContractsCreatedTodaySnapshot = await firestore
|
|
||||||
.collection(`contracts`)
|
|
||||||
.where('creatorId', '==', auth.uid)
|
|
||||||
.where('createdTime', '>=', freeMarketResetTime)
|
|
||||||
.get()
|
|
||||||
console.log('free market reset time: ', freeMarketResetTime)
|
|
||||||
const isFree = userContractsCreatedTodaySnapshot.size === 0
|
|
||||||
|
|
||||||
const ante = FIXED_ANTE
|
const ante = FIXED_ANTE
|
||||||
|
|
||||||
// TODO: this is broken because it's not in a transaction
|
// TODO: this is broken because it's not in a transaction
|
||||||
if (ante > user.balance && !isFree)
|
if (ante > user.balance)
|
||||||
throw new APIError(400, `Balance must be at least ${ante}.`)
|
throw new APIError(400, `Balance must be at least ${ante}.`)
|
||||||
|
|
||||||
const slug = await getSlug(question)
|
const slug = await getSlug(question)
|
||||||
|
@ -140,11 +124,11 @@ export const createmarket = newEndpoint(['POST'], async (req, auth) => {
|
||||||
max ?? 0
|
max ?? 0
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!isFree && ante) await chargeUser(user.id, ante, true)
|
if (ante) await chargeUser(user.id, ante, true)
|
||||||
|
|
||||||
await contractRef.create(contract)
|
await contractRef.create(contract)
|
||||||
|
|
||||||
const providerId = isFree ? HOUSE_LIQUIDITY_PROVIDER_ID : user.id
|
const providerId = user.id
|
||||||
|
|
||||||
if (outcomeType === 'BINARY') {
|
if (outcomeType === 'BINARY') {
|
||||||
const liquidityDoc = firestore
|
const liquidityDoc = firestore
|
||||||
|
|
|
@ -181,28 +181,8 @@ export default function Sidebar(props: { className?: string }) {
|
||||||
const { className } = props
|
const { className } = props
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const currentPage = router.pathname
|
const currentPage = router.pathname
|
||||||
const [countdown, setCountdown] = useState('...')
|
|
||||||
useEffect(() => {
|
|
||||||
const nextUtcResetTime = getUtcFreeMarketResetTime({ previousTime: false })
|
|
||||||
const interval = setInterval(() => {
|
|
||||||
const now = new Date().getTime()
|
|
||||||
const timeUntil = nextUtcResetTime - now
|
|
||||||
const hoursUntil = timeUntil / 1000 / 60 / 60
|
|
||||||
const minutesUntil = (hoursUntil * 60) % 60
|
|
||||||
const secondsUntil = Math.round((hoursUntil * 60 * 60) % 60)
|
|
||||||
const timeString =
|
|
||||||
hoursUntil < 1 && minutesUntil < 1
|
|
||||||
? `${secondsUntil}s`
|
|
||||||
: hoursUntil < 1
|
|
||||||
? `${Math.round(minutesUntil)}m`
|
|
||||||
: `${Math.floor(hoursUntil)}h`
|
|
||||||
setCountdown(timeString)
|
|
||||||
}, 1000)
|
|
||||||
return () => clearInterval(interval)
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
const user = useUser()
|
const user = useUser()
|
||||||
const mustWaitForFreeMarketStatus = useHasCreatedContractToday(user)
|
|
||||||
const navigationOptions = !user
|
const navigationOptions = !user
|
||||||
? signedOutNavigation
|
? signedOutNavigation
|
||||||
: getNavigation(user?.username || 'error')
|
: getNavigation(user?.username || 'error')
|
||||||
|
@ -306,27 +286,6 @@ export default function Sidebar(props: { className?: string }) {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<CreateQuestionButton user={user} />
|
<CreateQuestionButton user={user} />
|
||||||
|
|
||||||
{user &&
|
|
||||||
mustWaitForFreeMarketStatus != 'loading' &&
|
|
||||||
mustWaitForFreeMarketStatus ? (
|
|
||||||
<Row className="mt-2 justify-center">
|
|
||||||
<Row className="gap-1 text-sm text-gray-400">
|
|
||||||
Next free question in {countdown}
|
|
||||||
</Row>
|
|
||||||
</Row>
|
|
||||||
) : (
|
|
||||||
user &&
|
|
||||||
mustWaitForFreeMarketStatus != 'loading' &&
|
|
||||||
!mustWaitForFreeMarketStatus && (
|
|
||||||
<Row className="mt-2 justify-center">
|
|
||||||
<Row className="gap-1 text-sm text-indigo-400">
|
|
||||||
Daily free question
|
|
||||||
<SparklesIcon className="mt-0.5 h-4 w-4" aria-hidden="true" />
|
|
||||||
</Row>
|
|
||||||
</Row>
|
|
||||||
)
|
|
||||||
)}
|
|
||||||
</nav>
|
</nav>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,11 +93,6 @@ export function NewContract(props: { question: string; groupId?: string }) {
|
||||||
}, [creator, groupId])
|
}, [creator, groupId])
|
||||||
const [ante, _setAnte] = useState(FIXED_ANTE)
|
const [ante, _setAnte] = useState(FIXED_ANTE)
|
||||||
|
|
||||||
const mustWaitForDailyFreeMarketStatus = useHasCreatedContractToday(creator)
|
|
||||||
const isFree =
|
|
||||||
mustWaitForDailyFreeMarketStatus != 'loading' &&
|
|
||||||
!mustWaitForDailyFreeMarketStatus
|
|
||||||
|
|
||||||
// useEffect(() => {
|
// useEffect(() => {
|
||||||
// if (ante === null && creator) {
|
// if (ante === null && creator) {
|
||||||
// const initialAnte = creator.balance < 100 ? MINIMUM_ANTE : 100
|
// const initialAnte = creator.balance < 100 ? MINIMUM_ANTE : 100
|
||||||
|
@ -138,9 +133,7 @@ export function NewContract(props: { question: string; groupId?: string }) {
|
||||||
ante !== undefined &&
|
ante !== undefined &&
|
||||||
ante !== null &&
|
ante !== null &&
|
||||||
ante >= MINIMUM_ANTE &&
|
ante >= MINIMUM_ANTE &&
|
||||||
(ante <= balance ||
|
ante <= balance &&
|
||||||
(mustWaitForDailyFreeMarketStatus != 'loading' &&
|
|
||||||
!mustWaitForDailyFreeMarketStatus)) &&
|
|
||||||
// closeTime must be in the future
|
// closeTime must be in the future
|
||||||
closeTime &&
|
closeTime &&
|
||||||
closeTime > Date.now() &&
|
closeTime > Date.now() &&
|
||||||
|
@ -181,7 +174,7 @@ export function NewContract(props: { question: string; groupId?: string }) {
|
||||||
slug: result.slug,
|
slug: result.slug,
|
||||||
initialProb,
|
initialProb,
|
||||||
selectedGroup: selectedGroup?.id,
|
selectedGroup: selectedGroup?.id,
|
||||||
isFree,
|
isFree: false,
|
||||||
})
|
})
|
||||||
if (result && selectedGroup) {
|
if (result && selectedGroup) {
|
||||||
await updateGroup(selectedGroup, {
|
await updateGroup(selectedGroup, {
|
||||||
|
@ -369,41 +362,26 @@ export function NewContract(props: { question: string; groupId?: string }) {
|
||||||
<div className="form-control mb-1 items-start">
|
<div className="form-control mb-1 items-start">
|
||||||
<label className="label mb-1 gap-2">
|
<label className="label mb-1 gap-2">
|
||||||
<span>Cost</span>
|
<span>Cost</span>
|
||||||
{mustWaitForDailyFreeMarketStatus != 'loading' &&
|
<InfoTooltip
|
||||||
mustWaitForDailyFreeMarketStatus && (
|
text={`Cost to create your question. This amount is used to subsidize betting.`}
|
||||||
<InfoTooltip
|
/>
|
||||||
text={`Cost to create your question. This amount is used to subsidize betting.`}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</label>
|
</label>
|
||||||
{mustWaitForDailyFreeMarketStatus != 'loading' &&
|
|
||||||
!mustWaitForDailyFreeMarketStatus ? (
|
<div className="label-text text-neutral pl-1">
|
||||||
<div className="label-text text-primary pl-1">
|
{formatMoney(ante)}
|
||||||
<span className={'label-text text-neutral line-through '}>
|
</div>
|
||||||
{formatMoney(ante)}
|
|
||||||
</span>{' '}
|
{ante > balance && (
|
||||||
FREE
|
<div className="mb-2 mt-2 mr-auto self-center whitespace-nowrap text-xs font-medium tracking-wide">
|
||||||
|
<span className="mr-2 text-red-500">Insufficient balance</span>
|
||||||
|
<button
|
||||||
|
className="btn btn-xs btn-primary"
|
||||||
|
onClick={() => (window.location.href = '/add-funds')}
|
||||||
|
>
|
||||||
|
Get M$
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
|
||||||
mustWaitForDailyFreeMarketStatus != 'loading' && (
|
|
||||||
<div className="label-text text-neutral pl-1">
|
|
||||||
{formatMoney(ante)}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
)}
|
)}
|
||||||
{mustWaitForDailyFreeMarketStatus != 'loading' &&
|
|
||||||
mustWaitForDailyFreeMarketStatus &&
|
|
||||||
ante > balance && (
|
|
||||||
<div className="mb-2 mt-2 mr-auto self-center whitespace-nowrap text-xs font-medium tracking-wide">
|
|
||||||
<span className="mr-2 text-red-500">Insufficient balance</span>
|
|
||||||
<button
|
|
||||||
className="btn btn-xs btn-primary"
|
|
||||||
onClick={() => (window.location.href = '/add-funds')}
|
|
||||||
>
|
|
||||||
Get M$
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
|
Loading…
Reference in New Issue
Block a user