Show resolution on og card image (#834)
* Handle resolved markets * Add in group names as hashtags
This commit is contained in:
parent
1208694d2d
commit
8d853815d6
|
@ -27,10 +27,10 @@ export function contractMetrics(contract: Contract) {
|
||||||
export function contractTextDetails(contract: Contract) {
|
export function contractTextDetails(contract: Contract) {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const dayjs = require('dayjs')
|
const dayjs = require('dayjs')
|
||||||
const { closeTime, tags } = contract
|
const { closeTime, groupLinks } = contract
|
||||||
const { createdDate, resolvedDate, volumeLabel } = contractMetrics(contract)
|
const { createdDate, resolvedDate, volumeLabel } = contractMetrics(contract)
|
||||||
|
|
||||||
const hashtags = tags.map((tag) => `#${tag}`)
|
const groupHashtags = groupLinks?.slice(0, 5).map((g) => `#${g.name}`)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
`${resolvedDate ? `${createdDate} - ${resolvedDate}` : createdDate}` +
|
`${resolvedDate ? `${createdDate} - ${resolvedDate}` : createdDate}` +
|
||||||
|
@ -40,7 +40,7 @@ export function contractTextDetails(contract: Contract) {
|
||||||
).format('MMM D, h:mma')}`
|
).format('MMM D, h:mma')}`
|
||||||
: '') +
|
: '') +
|
||||||
` • ${volumeLabel}` +
|
` • ${volumeLabel}` +
|
||||||
(hashtags.length > 0 ? ` • ${hashtags.join(' ')}` : '')
|
(groupHashtags ? ` • ${groupHashtags.join(' ')}` : '')
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +92,7 @@ export const getOpenGraphProps = (contract: Contract) => {
|
||||||
creatorAvatarUrl,
|
creatorAvatarUrl,
|
||||||
description,
|
description,
|
||||||
numericValue,
|
numericValue,
|
||||||
|
resolution,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +104,7 @@ export type OgCardProps = {
|
||||||
creatorUsername: string
|
creatorUsername: string
|
||||||
creatorAvatarUrl?: string
|
creatorAvatarUrl?: string
|
||||||
numericValue?: string
|
numericValue?: string
|
||||||
|
resolution?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildCardUrl(props: OgCardProps, challenge?: Challenge) {
|
export function buildCardUrl(props: OgCardProps, challenge?: Challenge) {
|
||||||
|
@ -113,22 +115,32 @@ export function buildCardUrl(props: OgCardProps, challenge?: Challenge) {
|
||||||
creatorOutcome,
|
creatorOutcome,
|
||||||
acceptorOutcome,
|
acceptorOutcome,
|
||||||
} = challenge || {}
|
} = challenge || {}
|
||||||
|
const {
|
||||||
|
probability,
|
||||||
|
numericValue,
|
||||||
|
resolution,
|
||||||
|
creatorAvatarUrl,
|
||||||
|
question,
|
||||||
|
metadata,
|
||||||
|
creatorUsername,
|
||||||
|
creatorName,
|
||||||
|
} = props
|
||||||
const { userName, userAvatarUrl } = acceptances?.[0] ?? {}
|
const { userName, userAvatarUrl } = acceptances?.[0] ?? {}
|
||||||
|
|
||||||
const probabilityParam =
|
const probabilityParam =
|
||||||
props.probability === undefined
|
probability === undefined
|
||||||
? ''
|
? ''
|
||||||
: `&probability=${encodeURIComponent(props.probability ?? '')}`
|
: `&probability=${encodeURIComponent(probability ?? '')}`
|
||||||
|
|
||||||
const numericValueParam =
|
const numericValueParam =
|
||||||
props.numericValue === undefined
|
numericValue === undefined
|
||||||
? ''
|
? ''
|
||||||
: `&numericValue=${encodeURIComponent(props.numericValue ?? '')}`
|
: `&numericValue=${encodeURIComponent(numericValue ?? '')}`
|
||||||
|
|
||||||
const creatorAvatarUrlParam =
|
const creatorAvatarUrlParam =
|
||||||
props.creatorAvatarUrl === undefined
|
creatorAvatarUrl === undefined
|
||||||
? ''
|
? ''
|
||||||
: `&creatorAvatarUrl=${encodeURIComponent(props.creatorAvatarUrl ?? '')}`
|
: `&creatorAvatarUrl=${encodeURIComponent(creatorAvatarUrl ?? '')}`
|
||||||
|
|
||||||
const challengeUrlParams = challenge
|
const challengeUrlParams = challenge
|
||||||
? `&creatorAmount=${creatorAmount}&creatorOutcome=${creatorOutcome}` +
|
? `&creatorAmount=${creatorAmount}&creatorOutcome=${creatorOutcome}` +
|
||||||
|
@ -136,16 +148,21 @@ export function buildCardUrl(props: OgCardProps, challenge?: Challenge) {
|
||||||
`&acceptedName=${userName ?? ''}&acceptedAvatarUrl=${userAvatarUrl ?? ''}`
|
`&acceptedName=${userName ?? ''}&acceptedAvatarUrl=${userAvatarUrl ?? ''}`
|
||||||
: ''
|
: ''
|
||||||
|
|
||||||
|
const resolutionUrlParam = resolution
|
||||||
|
? `&resolution=${encodeURIComponent(resolution)}`
|
||||||
|
: ''
|
||||||
|
|
||||||
// URL encode each of the props, then add them as query params
|
// URL encode each of the props, then add them as query params
|
||||||
return (
|
return (
|
||||||
`https://manifold-og-image.vercel.app/m.png` +
|
`https://manifold-og-image.vercel.app/m.png` +
|
||||||
`?question=${encodeURIComponent(props.question)}` +
|
`?question=${encodeURIComponent(question)}` +
|
||||||
probabilityParam +
|
probabilityParam +
|
||||||
numericValueParam +
|
numericValueParam +
|
||||||
`&metadata=${encodeURIComponent(props.metadata)}` +
|
`&metadata=${encodeURIComponent(metadata)}` +
|
||||||
`&creatorName=${encodeURIComponent(props.creatorName)}` +
|
`&creatorName=${encodeURIComponent(creatorName)}` +
|
||||||
creatorAvatarUrlParam +
|
creatorAvatarUrlParam +
|
||||||
`&creatorUsername=${encodeURIComponent(props.creatorUsername)}` +
|
`&creatorUsername=${encodeURIComponent(creatorUsername)}` +
|
||||||
challengeUrlParams
|
challengeUrlParams +
|
||||||
|
resolutionUrlParam
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,85 +1,5 @@
|
||||||
import { sanitizeHtml } from './sanitizer'
|
|
||||||
import { ParsedRequest } from './types'
|
import { ParsedRequest } from './types'
|
||||||
|
import { getTemplateCss } from './template-css'
|
||||||
function getCss(theme: string, fontSize: string) {
|
|
||||||
let background = 'white'
|
|
||||||
let foreground = 'black'
|
|
||||||
let radial = 'lightgray'
|
|
||||||
|
|
||||||
if (theme === 'dark') {
|
|
||||||
background = 'black'
|
|
||||||
foreground = 'white'
|
|
||||||
radial = 'dimgray'
|
|
||||||
}
|
|
||||||
// To use Readex Pro: `font-family: 'Readex Pro', sans-serif;`
|
|
||||||
return `
|
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Major+Mono+Display&family=Readex+Pro:wght@400;700&display=swap');
|
|
||||||
|
|
||||||
body {
|
|
||||||
background: ${background};
|
|
||||||
background-image: radial-gradient(circle at 25px 25px, ${radial} 2%, transparent 0%), radial-gradient(circle at 75px 75px, ${radial} 2%, transparent 0%);
|
|
||||||
background-size: 100px 100px;
|
|
||||||
height: 100vh;
|
|
||||||
font-family: "Readex Pro", sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
code {
|
|
||||||
color: #D400FF;
|
|
||||||
font-family: 'Vera';
|
|
||||||
white-space: pre-wrap;
|
|
||||||
letter-spacing: -5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
code:before, code:after {
|
|
||||||
content: '\`';
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo-wrapper {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
align-content: center;
|
|
||||||
justify-content: center;
|
|
||||||
justify-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
margin: 0 75px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.plus {
|
|
||||||
color: #BBB;
|
|
||||||
font-family: Times New Roman, Verdana;
|
|
||||||
font-size: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.spacer {
|
|
||||||
margin: 150px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.emoji {
|
|
||||||
height: 1em;
|
|
||||||
width: 1em;
|
|
||||||
margin: 0 .05em 0 .1em;
|
|
||||||
vertical-align: -0.1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.heading {
|
|
||||||
font-family: 'Major Mono Display', monospace;
|
|
||||||
font-size: ${sanitizeHtml(fontSize)};
|
|
||||||
font-style: normal;
|
|
||||||
color: ${foreground};
|
|
||||||
line-height: 1.8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.font-major-mono {
|
|
||||||
font-family: "Major Mono Display", monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-primary {
|
|
||||||
color: #11b981;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getChallengeHtml(parsedReq: ParsedRequest) {
|
export function getChallengeHtml(parsedReq: ParsedRequest) {
|
||||||
const {
|
const {
|
||||||
|
@ -112,7 +32,7 @@ export function getChallengeHtml(parsedReq: ParsedRequest) {
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
</head>
|
</head>
|
||||||
<style>
|
<style>
|
||||||
${getCss(theme, fontSize)}
|
${getTemplateCss(theme, fontSize)}
|
||||||
</style>
|
</style>
|
||||||
<body>
|
<body>
|
||||||
<div class="px-24">
|
<div class="px-24">
|
||||||
|
|
|
@ -21,6 +21,7 @@ export function parseRequest(req: IncomingMessage) {
|
||||||
creatorName,
|
creatorName,
|
||||||
creatorUsername,
|
creatorUsername,
|
||||||
creatorAvatarUrl,
|
creatorAvatarUrl,
|
||||||
|
resolution,
|
||||||
|
|
||||||
// Challenge attributes:
|
// Challenge attributes:
|
||||||
challengerAmount,
|
challengerAmount,
|
||||||
|
@ -71,6 +72,7 @@ export function parseRequest(req: IncomingMessage) {
|
||||||
|
|
||||||
question:
|
question:
|
||||||
getString(question) || 'Will you create a prediction market on Manifold?',
|
getString(question) || 'Will you create a prediction market on Manifold?',
|
||||||
|
resolution: getString(resolution),
|
||||||
probability: getString(probability),
|
probability: getString(probability),
|
||||||
numericValue: getString(numericValue) || '',
|
numericValue: getString(numericValue) || '',
|
||||||
metadata: getString(metadata) || 'Jan 1 • M$ 123 pool',
|
metadata: getString(metadata) || 'Jan 1 • M$ 123 pool',
|
||||||
|
|
81
og-image/api/_lib/template-css.ts
Normal file
81
og-image/api/_lib/template-css.ts
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
import { sanitizeHtml } from './sanitizer'
|
||||||
|
|
||||||
|
export function getTemplateCss(theme: string, fontSize: string) {
|
||||||
|
let background = 'white'
|
||||||
|
let foreground = 'black'
|
||||||
|
let radial = 'lightgray'
|
||||||
|
|
||||||
|
if (theme === 'dark') {
|
||||||
|
background = 'black'
|
||||||
|
foreground = 'white'
|
||||||
|
radial = 'dimgray'
|
||||||
|
}
|
||||||
|
// To use Readex Pro: `font-family: 'Readex Pro', sans-serif;`
|
||||||
|
return `
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Major+Mono+Display&family=Readex+Pro:wght@400;700&display=swap');
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: ${background};
|
||||||
|
background-image: radial-gradient(circle at 25px 25px, ${radial} 2%, transparent 0%), radial-gradient(circle at 75px 75px, ${radial} 2%, transparent 0%);
|
||||||
|
background-size: 100px 100px;
|
||||||
|
height: 100vh;
|
||||||
|
font-family: "Readex Pro", sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
color: #D400FF;
|
||||||
|
font-family: 'Vera';
|
||||||
|
white-space: pre-wrap;
|
||||||
|
letter-spacing: -5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
code:before, code:after {
|
||||||
|
content: '\`';
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-wrapper {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
align-content: center;
|
||||||
|
justify-content: center;
|
||||||
|
justify-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
margin: 0 75px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.plus {
|
||||||
|
color: #BBB;
|
||||||
|
font-family: Times New Roman, Verdana;
|
||||||
|
font-size: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spacer {
|
||||||
|
margin: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji {
|
||||||
|
height: 1em;
|
||||||
|
width: 1em;
|
||||||
|
margin: 0 .05em 0 .1em;
|
||||||
|
vertical-align: -0.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heading {
|
||||||
|
font-family: 'Major Mono Display', monospace;
|
||||||
|
font-size: ${sanitizeHtml(fontSize)};
|
||||||
|
font-style: normal;
|
||||||
|
color: ${foreground};
|
||||||
|
line-height: 1.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-major-mono {
|
||||||
|
font-family: "Major Mono Display", monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-primary {
|
||||||
|
color: #11b981;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
|
@ -1,85 +1,5 @@
|
||||||
import { sanitizeHtml } from './sanitizer'
|
|
||||||
import { ParsedRequest } from './types'
|
import { ParsedRequest } from './types'
|
||||||
|
import { getTemplateCss } from './template-css'
|
||||||
function getCss(theme: string, fontSize: string) {
|
|
||||||
let background = 'white'
|
|
||||||
let foreground = 'black'
|
|
||||||
let radial = 'lightgray'
|
|
||||||
|
|
||||||
if (theme === 'dark') {
|
|
||||||
background = 'black'
|
|
||||||
foreground = 'white'
|
|
||||||
radial = 'dimgray'
|
|
||||||
}
|
|
||||||
// To use Readex Pro: `font-family: 'Readex Pro', sans-serif;`
|
|
||||||
return `
|
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Major+Mono+Display&family=Readex+Pro:wght@400;700&display=swap');
|
|
||||||
|
|
||||||
body {
|
|
||||||
background: ${background};
|
|
||||||
background-image: radial-gradient(circle at 25px 25px, ${radial} 2%, transparent 0%), radial-gradient(circle at 75px 75px, ${radial} 2%, transparent 0%);
|
|
||||||
background-size: 100px 100px;
|
|
||||||
height: 100vh;
|
|
||||||
font-family: "Readex Pro", sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
code {
|
|
||||||
color: #D400FF;
|
|
||||||
font-family: 'Vera';
|
|
||||||
white-space: pre-wrap;
|
|
||||||
letter-spacing: -5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
code:before, code:after {
|
|
||||||
content: '\`';
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo-wrapper {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
align-content: center;
|
|
||||||
justify-content: center;
|
|
||||||
justify-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
margin: 0 75px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.plus {
|
|
||||||
color: #BBB;
|
|
||||||
font-family: Times New Roman, Verdana;
|
|
||||||
font-size: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.spacer {
|
|
||||||
margin: 150px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.emoji {
|
|
||||||
height: 1em;
|
|
||||||
width: 1em;
|
|
||||||
margin: 0 .05em 0 .1em;
|
|
||||||
vertical-align: -0.1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.heading {
|
|
||||||
font-family: 'Major Mono Display', monospace;
|
|
||||||
font-size: ${sanitizeHtml(fontSize)};
|
|
||||||
font-style: normal;
|
|
||||||
color: ${foreground};
|
|
||||||
line-height: 1.8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.font-major-mono {
|
|
||||||
font-family: "Major Mono Display", monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-primary {
|
|
||||||
color: #11b981;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getHtml(parsedReq: ParsedRequest) {
|
export function getHtml(parsedReq: ParsedRequest) {
|
||||||
const {
|
const {
|
||||||
|
@ -92,6 +12,7 @@ export function getHtml(parsedReq: ParsedRequest) {
|
||||||
creatorUsername,
|
creatorUsername,
|
||||||
creatorAvatarUrl,
|
creatorAvatarUrl,
|
||||||
numericValue,
|
numericValue,
|
||||||
|
resolution,
|
||||||
} = parsedReq
|
} = parsedReq
|
||||||
const MAX_QUESTION_CHARS = 100
|
const MAX_QUESTION_CHARS = 100
|
||||||
const truncatedQuestion =
|
const truncatedQuestion =
|
||||||
|
@ -99,6 +20,49 @@ export function getHtml(parsedReq: ParsedRequest) {
|
||||||
? question.slice(0, MAX_QUESTION_CHARS) + '...'
|
? question.slice(0, MAX_QUESTION_CHARS) + '...'
|
||||||
: question
|
: question
|
||||||
const hideAvatar = creatorAvatarUrl ? '' : 'hidden'
|
const hideAvatar = creatorAvatarUrl ? '' : 'hidden'
|
||||||
|
|
||||||
|
let resolutionColor = 'text-primary'
|
||||||
|
let resolutionString = 'Yes'
|
||||||
|
switch (resolution) {
|
||||||
|
case 'YES':
|
||||||
|
break
|
||||||
|
case 'NO':
|
||||||
|
resolutionColor = 'text-red-500'
|
||||||
|
resolutionString = 'No'
|
||||||
|
break
|
||||||
|
case 'CANCEL':
|
||||||
|
resolutionColor = 'text-yellow-500'
|
||||||
|
resolutionString = 'N/A'
|
||||||
|
break
|
||||||
|
case 'MKT':
|
||||||
|
resolutionColor = 'text-blue-500'
|
||||||
|
resolutionString = numericValue ? numericValue : probability
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
const resolutionDiv = `
|
||||||
|
<span class='text-center ${resolutionColor}'>
|
||||||
|
<div class="text-8xl">
|
||||||
|
${resolutionString}
|
||||||
|
</div>
|
||||||
|
<div class="text-4xl">${
|
||||||
|
resolution === 'CANCEL' ? '' : 'resolved'
|
||||||
|
}</div>
|
||||||
|
</span>`
|
||||||
|
|
||||||
|
const probabilityDiv = `
|
||||||
|
<span class='text-primary text-center'>
|
||||||
|
<div class="text-8xl">${probability}</div>
|
||||||
|
<div class="text-4xl">chance</div>
|
||||||
|
</span>`
|
||||||
|
|
||||||
|
const numericValueDiv = `
|
||||||
|
<span class='text-blue-500 text-center'>
|
||||||
|
<div class="text-8xl ">${numericValue}</div>
|
||||||
|
<div class="text-4xl">expected</div>
|
||||||
|
</span>
|
||||||
|
`
|
||||||
|
|
||||||
return `<!DOCTYPE html>
|
return `<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
@ -108,7 +72,7 @@ export function getHtml(parsedReq: ParsedRequest) {
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
</head>
|
</head>
|
||||||
<style>
|
<style>
|
||||||
${getCss(theme, fontSize)}
|
${getTemplateCss(theme, fontSize)}
|
||||||
</style>
|
</style>
|
||||||
<body>
|
<body>
|
||||||
<div class="px-24">
|
<div class="px-24">
|
||||||
|
@ -148,21 +112,20 @@ export function getHtml(parsedReq: ParsedRequest) {
|
||||||
<div class="text-indigo-700 text-6xl leading-tight">
|
<div class="text-indigo-700 text-6xl leading-tight">
|
||||||
${truncatedQuestion}
|
${truncatedQuestion}
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col text-primary">
|
<div class="flex flex-col">
|
||||||
<div class="text-8xl">${probability}</div>
|
${
|
||||||
<div class="text-4xl">${probability !== '' ? 'chance' : ''}</div>
|
resolution
|
||||||
<span class='text-blue-500 text-center'>
|
? resolutionDiv
|
||||||
<div class="text-8xl ">${
|
: numericValue
|
||||||
numericValue !== '' && probability === '' ? numericValue : ''
|
? numericValueDiv
|
||||||
}</div>
|
: probabilityDiv
|
||||||
<div class="text-4xl">${numericValue !== '' ? 'expected' : ''}</div>
|
}
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Metadata -->
|
<!-- Metadata -->
|
||||||
<div class="absolute bottom-16">
|
<div class="absolute bottom-16">
|
||||||
<div class="text-gray-500 text-3xl">
|
<div class="text-gray-500 text-3xl max-w-[80vw]">
|
||||||
${metadata}
|
${metadata}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -19,6 +19,7 @@ export interface ParsedRequest {
|
||||||
creatorName: string
|
creatorName: string
|
||||||
creatorUsername: string
|
creatorUsername: string
|
||||||
creatorAvatarUrl: string
|
creatorAvatarUrl: string
|
||||||
|
resolution: string
|
||||||
// Challenge attributes:
|
// Challenge attributes:
|
||||||
challengerAmount: string
|
challengerAmount: string
|
||||||
challengerOutcome: string
|
challengerOutcome: string
|
||||||
|
|
Loading…
Reference in New Issue
Block a user