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(src/core/api.ts): move db calls here from server/index
Ciaran
2 weeks ago
17a72e11
f5f2bcb1
+88
-35
3 changed files
expand all
collapse all
unified
split
src
core
api.ts
db
schema.ts
server
index.ts
+53
src/core/api.ts
···
4
4
import { is, type ActorIdentifier } from '@atcute/lexicons';
5
5
import type { CreateCommit, DeleteCommit } from '@atcute/jetstream';
6
6
import * as schema from "../db/schema"
7
7
+
import { DEFAULT_MARKET_COLS, DEFAULT_BET_COLS, DEFAULT_RESOLUTION_COLS } from '../db/schema';
7
8
import { eq } from 'drizzle-orm';
9
9
+
8
10
9
11
export const db = drizzle(process.env.DATABASE_URL!, { schema });
10
12
13
13
+
export async function tryListMarkets() {
14
14
+
return await db.query.marketsTable.findMany({
15
15
+
columns: DEFAULT_MARKET_COLS,
16
16
+
orderBy: (markets, { desc }) => [desc(markets.createdAt)],
17
17
+
with: {
18
18
+
bets: { columns: DEFAULT_BET_COLS },
19
19
+
resolution: { columns: DEFAULT_RESOLUTION_COLS }
20
20
+
},
21
21
+
})
22
22
+
}
23
23
+
24
24
+
export async function tryFindMarket(uri: string) {
25
25
+
return await db.query.marketsTable.findFirst({
26
26
+
columns: DEFAULT_MARKET_COLS,
27
27
+
where: eq(schema.marketsTable.uri, uri),
28
28
+
with: {
29
29
+
bets: { columns: DEFAULT_BET_COLS },
30
30
+
resolution: { columns: DEFAULT_RESOLUTION_COLS }
31
31
+
}
32
32
+
})
33
33
+
}
34
34
+
35
35
+
export async function tryFindMarketBets(uri: string) {
36
36
+
return await db.query.betsTable.findMany({
37
37
+
columns: DEFAULT_BET_COLS,
38
38
+
where: eq(schema.betsTable.marketUri, uri),
39
39
+
orderBy: (bets, { desc }) => [desc(bets.createdAt)],
40
40
+
with: {
41
41
+
market: {
42
42
+
columns: DEFAULT_MARKET_COLS,
43
43
+
with: { resolution: { columns: DEFAULT_RESOLUTION_COLS } }
44
44
+
}
45
45
+
}
46
46
+
})
47
47
+
}
48
48
+
49
49
+
export async function tryFindMarketResolutions(uri: string) {
50
50
+
return await db.query.resolutionsTable.findFirst({
51
51
+
columns: DEFAULT_RESOLUTION_COLS,
52
52
+
where: eq(schema.resolutionsTable.marketUri, uri),
53
53
+
orderBy: (resolutions, { desc }) => [desc(resolutions.createdAt)],
54
54
+
with: {
55
55
+
market: {
56
56
+
columns: DEFAULT_MARKET_COLS,
57
57
+
with: { bets: { columns: DEFAULT_BET_COLS } }
58
58
+
}
59
59
+
}
60
60
+
})
61
61
+
}
62
62
+
11
63
export async function tryCreateMarket(did: ActorIdentifier, { record, rev, rkey, cid }: CreateCommit) {
12
64
if (is(ZaCoCiaranCumulusMarket.mainSchema, record)) {
13
65
const uri = `at://${did}/${record.$type}/${rkey}`;
14
66
console.log("> Creating Market:", uri);
67
67
+
15
68
const { question, liquidity } = record;
16
69
const [closesAt, createdAt] = [new Date(record.closesAt), new Date(record.createdAt)];
17
70
+26
src/db/schema.ts
···
21
21
closesAt: timestamp({ withTimezone: true }).notNull(),
22
22
});
23
23
24
24
+
export const DEFAULT_MARKET_COLS = {
25
25
+
uri: true,
26
26
+
did: true,
27
27
+
cid: true,
28
28
+
question: true,
29
29
+
liquidity: true,
30
30
+
closesAt: true,
31
31
+
createdAt: true,
32
32
+
}
33
33
+
24
34
export const betsTable = pgTable("bets", {
25
35
...SHARED_SCHEMA,
26
36
position: betPositionEnum().notNull(),
27
37
marketUri: text().notNull(),
28
38
});
29
39
40
40
+
export const DEFAULT_BET_COLS = {
41
41
+
uri: true,
42
42
+
did: true,
43
43
+
cid: true,
44
44
+
position: true,
45
45
+
createdAt: true,
46
46
+
}
47
47
+
30
48
export const resolutionsTable = pgTable("resolutions", {
31
49
...SHARED_SCHEMA,
32
50
answer: resolutionAnswerEnum().notNull(),
33
51
marketUri: text().notNull(),
34
52
});
53
53
+
54
54
+
export const DEFAULT_RESOLUTION_COLS = {
55
55
+
uri: true,
56
56
+
did: true,
57
57
+
cid: true,
58
58
+
answer: true,
59
59
+
createdAt: true,
60
60
+
}
35
61
36
62
export const marketsRelations = relations(marketsTable, ({ many, one }) => ({
37
63
bets: many(betsTable),
+9
-35
src/server/index.ts
···
2
2
import { staticPlugin } from '@elysiajs/static'
3
3
import { swagger } from '@elysiajs/swagger'
4
4
import { cors } from '@elysiajs/cors'
5
5
-
import { drizzle } from "drizzle-orm/node-postgres";
6
6
-
import * as schema from "../db/schema"
7
7
-
import { eq } from "drizzle-orm";
8
8
-
9
9
-
const db = drizzle(process.env.DATABASE_URL!, { schema });
5
5
+
import { tryFindMarket, tryFindMarketBets, tryFindMarketResolutions, tryListMarkets } from "@/core/api";
10
6
11
7
export const app = new Elysia()
12
8
.use(cors())
13
9
.use(swagger())
14
10
.use(staticPlugin({ prefix: "/", assets: "dist" }))
15
11
.get("/", () => new Response(Bun.file("dist/index.html")))
16
16
-
.group("/api", (app) => (
17
17
-
app.get("/markets", async () =>
18
18
-
Response.json(await db.query.marketsTable.findMany({
19
19
-
with: { bets: true, resolution: true },
20
20
-
orderBy: (markets, { desc }) => [desc(markets.createdAt)],
21
21
-
}))
22
22
-
).group("/market", (app) => (
23
23
-
app.get("/:uri", async ({ params: { uri } }) =>
24
24
-
Response.json(await db.query.marketsTable.findFirst({
25
25
-
where: eq(schema.marketsTable.uri, uri),
26
26
-
with: { bets: true, resolution: true }
27
27
-
}))
28
28
-
).get("/:uri/bets", async ({ params: { uri } }) =>
29
29
-
Response.json(await db.query.betsTable.findMany({
30
30
-
where: eq(schema.betsTable.marketUri, uri),
31
31
-
with: {
32
32
-
market: { with: { resolution: true } }
33
33
-
}
34
34
-
}))
35
35
-
).get("/:uri/resolutions", async ({ params: { uri } }) =>
36
36
-
Response.json(await db.query.resolutionsTable.findMany({
37
37
-
where: eq(schema.resolutionsTable.marketUri, uri),
38
38
-
with: {
39
39
-
market: { with: { bets: true } }
40
40
-
}
41
41
-
}))
42
42
-
)
43
43
-
))
44
44
-
))
45
45
-
.listen({ port: process.env.PORT!, hostname: "0.0.0.0" })
12
12
+
.group("/api", api => api
13
13
+
.get("/markets", async () => await tryListMarkets())
14
14
+
.group("/market", (market) => market
15
15
+
.get("/:uri", async ({ params }) => await tryFindMarket(params.uri))
16
16
+
.get("/:uri/bets", async ({ params }) => await tryFindMarketBets(params.uri))
17
17
+
.get("/:uri/resolutions", async ({ params }) => await tryFindMarketResolutions(params.uri))
18
18
+
)
19
19
+
).listen({ port: process.env.PORT!, hostname: "0.0.0.0" })
46
20
47
21
console.log(`> Server running on ${app.server?.protocol}://${app.server?.hostname}:${app.server?.port}`);