tangled
alpha
login
or
join now
ciaran.co.za
/
cumulus
0
fork
atom
A Prediction Market on the AT Protocol
0
fork
atom
overview
issues
pulls
pipelines
feat(markets.ts): add score / rep calculations
Ciaran
1 week ago
b1da0f1c
8a29dab2
+44
-5
3 changed files
expand all
collapse all
unified
split
src
core
markets.ts
web
app.tsx
providers
cumulus-provider.tsx
+23
-1
src/core/markets.ts
···
1
1
import type { Market } from "@/web/providers/cumulus-provider"
2
2
+
import type { Did } from "@atcute/lexicons";
2
3
import { getUnixTime } from "date-fns";
3
4
4
5
function lsmr(q1: number, q2: number, b: number) {
···
20
21
.map(bet => {
21
22
bet.position === "yes" ? countYes++ : countNo++;
22
23
const { priceYes, priceNo } = getPrices(countYes, countNo, market.liquidity);
23
23
-
return { ...bet, countYes, countNo, positionPriceYes: priceYes, positionPriceNo: priceNo }
24
24
+
const costPaid = bet.position === "yes" ? priceYes : priceNo;
25
25
+
return { ...bet, countYes, countNo, positionPriceYes: priceYes, positionPriceNo: priceNo, costPaid }
24
26
});
25
27
26
28
return {
···
35
37
isResolved: market.resolution !== null,
36
38
}
37
39
}
40
40
+
41
41
+
export function calculateScoreAndRep(markets: Array<ReturnType<typeof parseMarket>>, did: Did) {
42
42
+
let score = 0; // Profit and Loss
43
43
+
let rep = 0; // Popularity of markets
44
44
+
45
45
+
for (const market of markets) {
46
46
+
const answer = market?.resolution?.answer;
47
47
+
if (!answer) continue;
48
48
+
for (const bet of market.bets ?? []) {
49
49
+
if (market.did === did) rep++;
50
50
+
if (bet.did === did) {
51
51
+
if (bet.position === answer) score += (1.0 - parseFloat(bet.costPaid))
52
52
+
else if (bet.position === answer) score -= parseFloat(bet.costPaid)
53
53
+
}
54
54
+
}
55
55
+
}
56
56
+
57
57
+
58
58
+
return { score, rep };
59
59
+
}
+5
-1
src/web/app.tsx
···
5
5
6
6
7
7
export default function App() {
8
8
-
const { markets } = useCumulus();
8
8
+
const { markets, score, rep } = useCumulus();
9
9
10
10
if (markets.isLoading) return <div className="p-4"><Spinner className='m-auto' /></div>
11
11
12
12
return <div className="grid p-2 md:grid-cols-2 gap-2">
13
13
{markets.data?.map(market => <Market key={market.uri} market={market} />)}
14
14
+
<div>
15
15
+
<p className="text-6xl first-letter:text-coral-500">Score: {score}</p>
16
16
+
<p className="text-4xl first-letter:text-coral-500">Rep: {rep}</p>
17
17
+
</div>
14
18
<AddMarket />
15
19
</div>
16
20
}
+16
-3
src/web/providers/cumulus-provider.tsx
···
1
1
import { treaty } from "@elysiajs/eden"
2
2
-
import { createContext, type PropsWithChildren } from "react";
2
2
+
import { createContext, useMemo, type PropsWithChildren } from "react";
3
3
import { useQuery, type UseQueryResult } from "@tanstack/react-query";
4
4
import { type CumulusServer } from "@/server/types";
5
5
import type { InferSelectModel } from "drizzle-orm";
6
6
import type { betsTable, marketsTable, resolutionsTable } from "@/db";
7
7
-
import { parseMarket } from "@/core/markets";
7
7
+
import { calculateScoreAndRep, parseMarket } from "@/core/markets";
8
8
+
import { useAuth } from "../hooks/useAuth";
8
9
9
10
10
11
export type Market = InferSelectModel<typeof marketsTable> & {
···
14
15
15
16
export interface CumulusContext {
16
17
markets: UseQueryResult<Array<ReturnType<typeof parseMarket>>>,
18
18
+
score: number,
19
19
+
rep: number,
17
20
}
18
21
19
22
export const CumulusContext = createContext<CumulusContext | undefined>(undefined);
20
23
21
24
export default function Cumulus({ children }: PropsWithChildren) {
22
25
26
26
+
const { profile } = useAuth();
23
27
const server = treaty<CumulusServer>(window.location.origin);
24
28
25
29
const markets = useQuery({
···
31
35
},
32
36
});
33
37
34
34
-
return <CumulusContext.Provider value={{ markets }}>{children}</ CumulusContext.Provider>
38
38
+
const { score, rep } = useMemo(() =>
39
39
+
markets.data
40
40
+
? calculateScoreAndRep(markets.data, profile.did)
41
41
+
: { score: 0, rep: 0 },
42
42
+
[markets.data, profile.did]
43
43
+
);
44
44
+
45
45
+
return <CumulusContext.Provider value={{ markets, score, rep }}>
46
46
+
{children}
47
47
+
</ CumulusContext.Provider>
35
48
}