Compare commits
No commits in common. "cb5132f2c15d94ff35eb967b677be2278500db05" and "bdc768cb27b826fcc3be351e7814599e42f32ffc" have entirely different histories.
cb5132f2c1
...
bdc768cb27
4
.gitignore
vendored
4
.gitignore
vendored
@ -13,7 +13,3 @@ public/hotreload
|
|||||||
|
|
||||||
# tailwindcss
|
# tailwindcss
|
||||||
public/css/tailwind.css
|
public/css/tailwind.css
|
||||||
|
|
||||||
# js
|
|
||||||
node_modules
|
|
||||||
public/js/*.min.js
|
|
||||||
|
7
Makefile
7
Makefile
@ -1,18 +1,15 @@
|
|||||||
.PHONY: build run test dev
|
.PHONY: build run test
|
||||||
|
|
||||||
SOURCE := $(shell find db env lib lnd public server -type f) main.go
|
SOURCE := $(shell find db env lib lnd public server -type f) main.go
|
||||||
|
|
||||||
|
build: delphi.market
|
||||||
|
|
||||||
delphi.market: $(SOURCE)
|
delphi.market: $(SOURCE)
|
||||||
npm run build
|
|
||||||
tailwindcss -i public/css/_tw-input.css -o public/css/tailwind.css
|
tailwindcss -i public/css/_tw-input.css -o public/css/tailwind.css
|
||||||
templ generate -path server/router/pages
|
templ generate -path server/router/pages
|
||||||
go build -o delphi.market .
|
go build -o delphi.market .
|
||||||
|
|
||||||
build: delphi.market
|
|
||||||
|
|
||||||
run:
|
run:
|
||||||
npm run build
|
|
||||||
tailwindcss -i public/css/_tw-input.css -o public/css/tailwind.css
|
tailwindcss -i public/css/_tw-input.css -o public/css/tailwind.css
|
||||||
templ generate -path server/router/pages
|
templ generate -path server/router/pages
|
||||||
go run .
|
go run .
|
||||||
|
51
package-lock.json
generated
51
package-lock.json
generated
@ -1,51 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "delphi.market",
|
|
||||||
"lockfileVersion": 3,
|
|
||||||
"requires": true,
|
|
||||||
"packages": {
|
|
||||||
"": {
|
|
||||||
"dependencies": {
|
|
||||||
"chart.js": "^4.4.4",
|
|
||||||
"chartjs-adapter-dayjs-4": "^1.0.4",
|
|
||||||
"dayjs": "^1.11.13"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@kurkle/color": {
|
|
||||||
"version": "0.3.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz",
|
|
||||||
"integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/chart.js": {
|
|
||||||
"version": "4.4.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.4.tgz",
|
|
||||||
"integrity": "sha512-emICKGBABnxhMjUjlYRR12PmOXhJ2eJjEHL2/dZlWjxRAZT1D8xplLFq5M0tMQK8ja+wBS/tuVEJB5C6r7VxJA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@kurkle/color": "^0.3.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"pnpm": ">=8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/chartjs-adapter-dayjs-4": {
|
|
||||||
"version": "1.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/chartjs-adapter-dayjs-4/-/chartjs-adapter-dayjs-4-1.0.4.tgz",
|
|
||||||
"integrity": "sha512-yy9BAYW4aNzPVrCWZetbILegTRb7HokhgospPoC3b5iZ5qdlqNmXts2KdSp6AqnjkPAp/YWyHDxLvIvwt5x81w==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"chart.js": ">=4.0.1",
|
|
||||||
"dayjs": "^1.9.7"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/dayjs": {
|
|
||||||
"version": "1.11.13",
|
|
||||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz",
|
|
||||||
"integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==",
|
|
||||||
"license": "MIT"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
10
package.json
10
package.json
@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"scripts": {
|
|
||||||
"build": "esbuild public/js/chart.js --bundle --minify --outfile=public/js/chart.min.js"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"chart.js": "^4.4.4",
|
|
||||||
"chartjs-adapter-dayjs-4": "^1.0.4",
|
|
||||||
"dayjs": "^1.11.13"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
import {
|
|
||||||
Chart,
|
|
||||||
LineController,
|
|
||||||
TimeScale,
|
|
||||||
LinearScale,
|
|
||||||
PointElement,
|
|
||||||
LineElement,
|
|
||||||
} from 'chart.js'
|
|
||||||
import 'chartjs-adapter-dayjs-4/dist/chartjs-adapter-dayjs-4.esm';
|
|
||||||
|
|
||||||
Chart.register(
|
|
||||||
LineController,
|
|
||||||
TimeScale,
|
|
||||||
LinearScale,
|
|
||||||
PointElement,
|
|
||||||
LineElement,
|
|
||||||
);
|
|
||||||
|
|
||||||
const element = document.getElementById('chart')
|
|
||||||
|
|
||||||
|
|
||||||
function transformPoint({ X, Y }) {
|
|
||||||
return { x: new Date(X), y: Y * 100 }
|
|
||||||
}
|
|
||||||
|
|
||||||
const no = JSON.parse($("#chart-data").getAttribute("chart-data-p0")).map(transformPoint)
|
|
||||||
const yes = JSON.parse($("#chart-data").getAttribute("chart-data-p1")).map(transformPoint)
|
|
||||||
|
|
||||||
const config = {
|
|
||||||
type: 'line',
|
|
||||||
data: {
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
data: yes,
|
|
||||||
backgroundColor: '#149e613d',
|
|
||||||
borderColor: '#149e613d',
|
|
||||||
borderWidth: 3,
|
|
||||||
tension: 0, // draw straight lines instead of bezier curves
|
|
||||||
pointStyle: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
data: no,
|
|
||||||
backgroundColor: '#f5395e3d',
|
|
||||||
borderColor: '#f5395e3d',
|
|
||||||
borderWidth: 3,
|
|
||||||
tension: 0,
|
|
||||||
pointStyle: false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
scales: {
|
|
||||||
x: {
|
|
||||||
type: 'time',
|
|
||||||
time: { unit: 'month' }
|
|
||||||
},
|
|
||||||
y: {
|
|
||||||
min: 0,
|
|
||||||
max: 100
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
new Chart(element, config);
|
|
@ -113,9 +113,6 @@ func HandleMarket(sc context.Context) echo.HandlerFunc {
|
|||||||
quote1 = types.MarketQuote{}
|
quote1 = types.MarketQuote{}
|
||||||
uQ0 int
|
uQ0 int
|
||||||
uQ1 int
|
uQ1 int
|
||||||
rows *sql.Rows
|
|
||||||
p0 []types.MarketPoint
|
|
||||||
p1 []types.MarketPoint
|
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -175,38 +172,6 @@ func HandleMarket(sc context.Context) echo.HandlerFunc {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if rows, err = db.QueryContext(ctx, ""+
|
|
||||||
"SELECT created_at, quote(b, q0, q1, 1) AS p0, quote(b, q1, q0, 1) AS p1 "+
|
|
||||||
"FROM ( "+
|
|
||||||
" SELECT "+
|
|
||||||
" m.lmsr_b AS b, o.created_at, "+
|
|
||||||
" COALESCE(SUM(quantity) FILTER(WHERE o.outcome = 0) OVER (ORDER BY o.created_at ASC), 0) AS q0, "+
|
|
||||||
" COALESCE(sum(quantity) filter(where o.outcome = 1) over (order by o.created_at ASC), 0) AS q1 "+
|
|
||||||
" FROM markets m "+
|
|
||||||
" JOIN orders o ON o.market_id = m.id "+
|
|
||||||
" JOIN invoices i ON i.id = o.invoice_id "+
|
|
||||||
" WHERE m.id = $1 AND i.confirmed_at IS NOT NULL "+
|
|
||||||
") AS o "+
|
|
||||||
"UNION "+
|
|
||||||
"SELECT m.created_at, quote(m.lmsr_b, 0, 0, 1) AS p0, quote(m.lmsr_b, 0, 0, 1) AS p1 "+
|
|
||||||
"FROM markets m "+
|
|
||||||
"ORDER BY created_at", id); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for rows.Next() {
|
|
||||||
var (
|
|
||||||
createdAt time.Time
|
|
||||||
_p0 float64
|
|
||||||
_p1 float64
|
|
||||||
)
|
|
||||||
if err = rows.Scan(&createdAt, &_p0, &_p1); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
p0 = append(p0, types.MarketPoint{X: createdAt, Y: _p0})
|
|
||||||
p1 = append(p1, types.MarketPoint{X: createdAt, Y: _p1})
|
|
||||||
}
|
|
||||||
|
|
||||||
total = lmsr.Quote(l.B, l.Q1, l.Q2, int(q))
|
total = lmsr.Quote(l.B, l.Q1, l.Q2, int(q))
|
||||||
quote0 = types.MarketQuote{
|
quote0 = types.MarketQuote{
|
||||||
Outcome: 0,
|
Outcome: 0,
|
||||||
@ -223,11 +188,7 @@ func HandleMarket(sc context.Context) echo.HandlerFunc {
|
|||||||
Reward: float64(q) - total,
|
Reward: float64(q) - total,
|
||||||
}
|
}
|
||||||
|
|
||||||
return pages.Market(
|
return pages.Market(m, quote0, quote1, uQ0, uQ1).Render(context.RenderContext(sc, c), c.Response().Writer)
|
||||||
m,
|
|
||||||
p0, p1,
|
|
||||||
quote0, quote1,
|
|
||||||
uQ0, uQ1).Render(context.RenderContext(sc, c), c.Response().Writer)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ templ Qr(value string, href string) {
|
|||||||
>
|
>
|
||||||
<img src={ "data:image/jpeg;base64," + qrEncode(value) }/>
|
<img src={ "data:image/jpeg;base64," + qrEncode(value) }/>
|
||||||
</a>
|
</a>
|
||||||
<small class="flex my-1 mx-auto" hx-preserve>
|
<small class="flex my-1 mx-auto">
|
||||||
<span class="block w-[188px] overflow-hidden">{ value }</span>
|
<span class="block w-[188px] overflow-hidden">{ value }</span>
|
||||||
<button id="copy" class="ms-1 button w-[64px]" hx-preserve>copy</button>
|
<button id="copy" class="ms-1 button w-[64px]" hx-preserve>copy</button>
|
||||||
</small>
|
</small>
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Add countdown? Use or at least show somewhere precise timestamps?
|
// TODO: Add countdown? Use or at least show somewhere precise timestamps?
|
||||||
templ Market(m types.Market, p0 []types.MarketPoint, p1 []types.MarketPoint, q0 types.MarketQuote, q1 types.MarketQuote, uQ0 int, uQ1 int) {
|
templ Market(m types.Market, q0 types.MarketQuote, q1 types.MarketQuote, uQ0 int, uQ1 int) {
|
||||||
<html>
|
<html>
|
||||||
@components.Head()
|
@components.Head()
|
||||||
<body
|
<body
|
||||||
@ -17,17 +17,12 @@ templ Market(m types.Market, p0 []types.MarketPoint, p1 []types.MarketPoint, q0
|
|||||||
>
|
>
|
||||||
@components.Nav()
|
@components.Nav()
|
||||||
<div id="content" class="flex flex-col">
|
<div id="content" class="flex flex-col">
|
||||||
<div class="text-center font-bold my-1 mt-3">{ m.Question }</div>
|
<small>
|
||||||
|
@components.Figlet("random", "market")
|
||||||
|
</small>
|
||||||
|
<div class="text-center font-bold my-1">{ m.Question }</div>
|
||||||
<div class="text-center text-muted my-1">{ humanize.Time(m.EndDate) }</div>
|
<div class="text-center text-muted my-1">{ humanize.Time(m.EndDate) }</div>
|
||||||
<div class="text-center text-muted my-1"></div>
|
<div class="text-center text-muted my-1"></div>
|
||||||
<div
|
|
||||||
class="none"
|
|
||||||
id="chart-data"
|
|
||||||
chart-data-p0={ templ.JSONString(p0) }
|
|
||||||
chart-data-p1={ templ.JSONString(p1) }
|
|
||||||
></div>
|
|
||||||
<div class="flex justify-center w-full max-h-64 my-3"><canvas id="chart"></canvas></div>
|
|
||||||
<script src="/js/chart.min.js"></script>
|
|
||||||
<blockquote class="p-4 mb-4 border-s-4 border-muted">
|
<blockquote class="p-4 mb-4 border-s-4 border-muted">
|
||||||
if m.Description != "" {
|
if m.Description != "" {
|
||||||
{ m.Description }
|
{ m.Description }
|
||||||
|
@ -50,8 +50,3 @@ type MarketQuote struct {
|
|||||||
TotalPrice float64
|
TotalPrice float64
|
||||||
Reward float64
|
Reward float64
|
||||||
}
|
}
|
||||||
|
|
||||||
type MarketPoint struct {
|
|
||||||
X time.Time
|
|
||||||
Y float64
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user