feat: migrate to go-sonr/middleware

This commit is contained in:
2025-06-08 14:26:51 +08:00
parent 40bd369e07
commit 9628fa56ef
129 changed files with 43 additions and 19195 deletions

View File

@@ -1,43 +0,0 @@
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
version: 2
before:
hooks:
- go mod tidy
- sqlc generate
- templ generate
builds:
- env:
- CGO_ENABLED=0
goos:
- linux
- windows
- darwin
archives:
- formats: [tar.gz]
name_template: >-
{{ .ProjectName }}_
{{- title .Os }}_
{{- if eq .Arch "amd64" }}x86_64
{{- else if eq .Arch "386" }}i386
{{- else }}{{ .Arch }}{{ end }}
{{- if .Arm }}v{{ .Arm }}{{ end }}
# use zip for windows archives
format_overrides:
- goos: windows
formats: [zip]
changelog:
sort: desc
filters:
exclude:
- "^docs:"
- "^test:"
release:
footer: >-
---
Released by [GoReleaser](https://github.com/goreleaser/goreleaser).

View File

@@ -8,12 +8,11 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"github.com/cf-sonr/motr/config"
"github.com/go-sonr/middleware/kvstore"
"github.com/go-sonr/middleware/session"
"github.com/go-sonr/middleware/webauthn"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/sonr-io/motr/config"
"github.com/sonr-io/motr/middleware/database"
"github.com/sonr-io/motr/middleware/kvstore"
"github.com/sonr-io/motr/middleware/session"
"github.com/sonr-io/motr/middleware/webauthn"
"github.com/syumai/workers" "github.com/syumai/workers"
"github.com/syumai/workers/cloudflare/cron" "github.com/syumai/workers/cloudflare/cron"
@@ -29,7 +28,6 @@ func loadHandler() http.Handler {
e := echo.New() e := echo.New()
e.Use( e.Use(
session.Middleware(), session.Middleware(),
database.Middleware(),
kvstore.Middleware(), kvstore.Middleware(),
webauthn.Middleware(), webauthn.Middleware(),
) )

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +0,0 @@
{
"name": "@sonr-io/radar-worker",
"version": "0.0.1",
"private": true,
"dependencies": {
"@extism/extism": "^2.0.0-rc11",
"@helia/dag-cbor": "^1.0.1",
"@helia/dag-json": "^1.0.1",
"@helia/json": "^1.0.1",
"@helia/strings": "^1.0.1",
"@helia/unixfs": "^1.4.1",
"helia": "^2.1.0",
"sonr-cosmes": "^0.0.5"
}
}

View File

@@ -1,59 +0,0 @@
# Top-level configuration
name = "motr-radar"
main = "build/worker.mjs"
compatibility_date = "2025-04-14"
routes = [
{ pattern = "did.run", custom_domain = true },
]
[build]
command = "make build"
[dev]
port = 4242
[observability]
enabled = true
[triggers]
crons = ["0 */1 * * *"]
[[d1_databases]]
binding = "ACTIVITY_DB"
database_name = "motr-activity"
database_id = "a7ccb4bb-c529-4f42-8029-92564a3aecb8"
[[d1_databases]]
binding = "NETWORK_DB"
database_name = "motr-network"
database_id = "acb75499-3502-4052-9604-263a913e077a"
[[d1_databases]]
binding = "USERS_DB"
database_name = "motr-users"
database_id = "8ed4d399-5932-419c-b92f-9c20d7a36ad2"
[[kv_namespaces]]
binding = "SESSIONS_KV"
id = "ea5de66fcfc14b5eba170395e29432ee"
[[kv_namespaces]]
binding = "HANDLES_KV"
id = "271d47087a8842b2aac5ee79cf7bb203"
[[r2_buckets]]
binding = 'PROFILES'
bucket_name = 'profiles'
[vars]
SONR_CHAIN_ID = 'sonr-testnet-1'
IPFS_GATEWAY = 'https://ipfs.sonr.land'
SONR_API_URL = 'https://api.sonr.land'
SONR_RPC_URL = 'https://rpc.sonr.land'
SONR_GRPC_URL = 'https://grpc.sonr.land'
MATRIX_SERVER = 'https://bm.chat'
MOTR_GATEWAY = 'https://sonr.id'
MOTR_VAULT = 'https://did.run'
MOTR_MODE = 'controller'

View File

@@ -1,13 +0,0 @@
generate:
@gum spin --show-error --title "(1/3) Running templ generate" -- sh -c "templ generate"
@gum log --level info --time kitchen "[GENERATE] Completed templ generate successfully."
assets:
@gum spin --show-error --title "(2/3) Running workers-assets-gen" -- sh -c "go run github.com/syumai/workers/cmd/workers-assets-gen -mode=go"
@gum log --level info --time kitchen "[GENERATE] Completed workers-assets-gen successfully."
build: generate assets
@GOOS=js GOARCH=wasm go build -ldflags="-s -w" -o ./build/app.wasm .
@gum log --level info --time kitchen "[BUILD] Completed Go WASM Build successfully."

View File

@@ -1,72 +0,0 @@
//go:build js && wasm
// +build js,wasm
package main
import (
"context"
"fmt"
"net/http"
"github.com/labstack/echo/v4"
"github.com/sonr-io/motr/config"
"github.com/sonr-io/motr/middleware/database"
"github.com/sonr-io/motr/middleware/kvstore"
"github.com/sonr-io/motr/middleware/session"
"github.com/sonr-io/motr/middleware/webauthn"
"github.com/syumai/workers"
"github.com/syumai/workers/cloudflare/cron"
_ "github.com/syumai/workers/cloudflare/d1"
)
// ╭──────────────────────────────────────────────────╮
// │ Initialization │
// ╰──────────────────────────────────────────────────╯
// Setup the HTTP handler
func loadHandler() http.Handler {
e := echo.New()
e.Use(
session.Middleware(),
database.Middleware(),
kvstore.Middleware(),
webauthn.Middleware(),
)
config.RegisterViews(e)
config.RegisterPartials(e)
return e
}
// Setup the cron task
func loadTask() cron.Task {
return func(ctx context.Context) error {
e, err := cron.NewEvent(ctx)
if err != nil {
return err
}
fmt.Println(e.ScheduledTime.Unix())
return nil
}
}
// ╭─────────────────────────────────────────────────╮
// │ Main Function │
// ╰─────────────────────────────────────────────────╯
func main() {
// Setup CRON jobs
e := loadHandler()
t := loadTask()
// Configure Worker
cron.ScheduleTaskNonBlock(t)
workers.ServeNonBlock(e)
workers.Ready()
// Block until handler/task is done
select {
case <-workers.Done():
case <-cron.Done():
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -4,8 +4,8 @@
package config package config
import ( import (
"github.com/cf-sonr/motr/handlers"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/sonr-io/motr/handlers"
) )
// ╭────────────────────────────────────────────────╮ // ╭────────────────────────────────────────────────╮

View File

@@ -4,7 +4,6 @@
"templ@latest", "templ@latest",
"sqlc@latest", "sqlc@latest",
"nodejs@latest", "nodejs@latest",
"goreleaser@latest",
"rclone@latest", "rclone@latest",
"go-task@latest" "go-task@latest"
], ],
@@ -25,11 +24,6 @@
"go mod download" "go mod download"
], ],
"scripts": { "scripts": {
"release": [
"check_deps",
"check_vars",
"publish_release"
],
"build:radar": [ "build:radar": [
"cd $RADAR_ROOT", "cd $RADAR_ROOT",
"workers-assets-gen -mode=go", "workers-assets-gen -mode=go",

48
go.mod
View File

@@ -1,48 +1,26 @@
module github.com/sonr-io/motr module github.com/cf-sonr/motr
go 1.24.2 go 1.24.2
require ( require (
github.com/a-h/templ v0.3.857 github.com/go-sonr/middleware v0.0.0-20250608031920-68e2abc4810a
github.com/golang-jwt/jwt v3.2.2+incompatible github.com/go-sonr/ui v0.0.0-20250608032352-45d7117e9607
github.com/labstack/echo/v4 v4.13.3 github.com/labstack/echo/v4 v4.13.4
github.com/segmentio/ksuid v1.0.4
github.com/sonr-io/crypto v0.13.2
github.com/syumai/workers v0.30.2 github.com/syumai/workers v0.30.2
lukechampine.com/blake3 v1.4.1
) )
require ( require (
filippo.io/edwards25519 v1.1.0 // indirect github.com/a-h/templ v0.3.894 // indirect
github.com/bits-and-blooms/bitset v1.20.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
github.com/bwesterb/go-ristretto v1.2.3 // indirect
github.com/consensys/bavard v0.1.27 // indirect
github.com/consensys/gnark-crypto v0.16.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
github.com/dustinxie/ecc v0.0.0-20210511000915-959544187564 // indirect
github.com/ipfs/go-cid v0.5.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
github.com/labstack/gommon v0.4.2 // indirect github.com/labstack/gommon v0.4.2 // indirect
github.com/libp2p/go-libp2p v0.41.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/minio/sha256-simd v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/segmentio/ksuid v1.0.4 // indirect
github.com/mr-tron/base58 v1.2.0 // indirect
github.com/multiformats/go-base32 v0.1.0 // indirect
github.com/multiformats/go-base36 v0.2.0 // indirect
github.com/multiformats/go-multibase v0.2.0 // indirect
github.com/multiformats/go-multihash v0.2.3 // indirect
github.com/multiformats/go-varint v0.0.7 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect
golang.org/x/crypto v0.36.0 // indirect golang.org/x/crypto v0.38.0 // indirect
golang.org/x/net v0.37.0 // indirect golang.org/x/net v0.40.0 // indirect
golang.org/x/sys v0.31.0 // indirect golang.org/x/sys v0.33.0 // indirect
golang.org/x/text v0.23.0 // indirect golang.org/x/text v0.25.0 // indirect
google.golang.org/protobuf v1.36.5 // indirect
rsc.io/tmplfunc v0.0.3 // indirect
) )

100
go.sum
View File

@@ -1,80 +1,25 @@
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= github.com/a-h/templ v0.3.894 h1:umG2i6ypJXtm9CrOZxwlYBXgDnpcUnMl6IaHpXGXiGE=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/a-h/templ v0.3.894/go.mod h1:oLBbZVQ6//Q6zpvSMPTuBK0F3qOtBdFBcGRspcT+VNQ=
github.com/a-h/templ v0.3.857 h1:6EqcJuGZW4OL+2iZ3MD+NnIcG7nGkaQeF2Zq5kf9ZGg=
github.com/a-h/templ v0.3.857/go.mod h1:qhrhAkRFubE7khxLZHsBFHfX+gWwVNKbzKeF9GlPV4M=
github.com/bits-and-blooms/bitset v1.20.0 h1:2F+rfL86jE2d/bmw7OhqUg2Sj/1rURkBn3MdfoPyRVU=
github.com/bits-and-blooms/bitset v1.20.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
github.com/bwesterb/go-ristretto v1.2.3 h1:1w53tCkGhCQ5djbat3+MH0BAQ5Kfgbt56UZQ/JMzngw=
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/consensys/bavard v0.1.27 h1:j6hKUrGAy/H+gpNrpLU3I26n1yc+VMGmd6ID5+gAhOs=
github.com/consensys/bavard v0.1.27/go.mod h1:k/zVjHHC4B+PQy1Pg7fgvG3ALicQw540Crag8qx+dZs=
github.com/consensys/gnark-crypto v0.16.0 h1:8Dl4eYmUWK9WmlP1Bj6je688gBRJCJbT8Mw4KoTAawo=
github.com/consensys/gnark-crypto v0.16.0/go.mod h1:Ke3j06ndtPTVvo++PhGNgvm+lgpLvzbcE2MqljY7diU=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U0x++OzVrdms8= github.com/go-sonr/middleware v0.0.0-20250608031920-68e2abc4810a h1:d0A1X8+1oORje2sSidSQ6eplWUswivYHC0+gbwsu8m0=
github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/go-sonr/middleware v0.0.0-20250608031920-68e2abc4810a/go.mod h1:JiIWsa7/YDxAMijHr+rQoSFKSp6A9x02PF6rHgNz4I0=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= github.com/go-sonr/ui v0.0.0-20250608032352-45d7117e9607 h1:BKYQ1ptEnng0dzXQEnAeRvbqW78yVgVf4X7928zguyQ=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= github.com/go-sonr/ui v0.0.0-20250608032352-45d7117e9607/go.mod h1:OHWQZlChuDOmtlZNdSumNC7n5MZx3hx0t58AnlL9SNw=
github.com/dustinxie/ecc v0.0.0-20210511000915-959544187564 h1:I6KUy4CI6hHjqnyJLNCEi7YHVMkwwtfSr2k9splgdSM=
github.com/dustinxie/ecc v0.0.0-20210511000915-959544187564/go.mod h1:yekO+3ZShy19S+bsmnERmznGy9Rfg6dWWWpiGJjNAz8=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/labstack/echo/v4 v4.13.4 h1:oTZZW+T3s9gAu5L8vmzihV7/lkXGZuITzTQkTEhcXEA=
github.com/ipfs/go-cid v0.5.0 h1:goEKKhaGm0ul11IHA7I6p1GmKz8kEYniqFopaB5Otwg= github.com/labstack/echo/v4 v4.13.4/go.mod h1:g63b33BZ5vZzcIUF8AtRH40DrTlXnx4UMC8rBdndmjQ=
github.com/ipfs/go-cid v0.5.0/go.mod h1:0L7vmeNXpQpUS9vt+yEARkJ8rOg43DF3iPgn4GIN0mk=
github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY=
github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g=
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
github.com/libp2p/go-libp2p v0.41.0 h1:JRaD39dqf/tBBGapJ0T38N73vOaDCsWgcx3mE6HgXWk=
github.com/libp2p/go-libp2p v0.41.0/go.mod h1:Be8QYqC4JW6Xq8buukNeoZJjyT1XUDcGoIooCHm1ye4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY=
github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU=
github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU=
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE=
github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI=
github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0=
github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4=
github.com/multiformats/go-multiaddr v0.15.0 h1:zB/HeaI/apcZiTDwhY5YqMvNVl/oQYvs3XySU+qeAVo=
github.com/multiformats/go-multiaddr v0.15.0/go.mod h1:JSVUmXDjsVFiW7RjIFMP7+Ev+h1DTbiJgVeTV/tcmP0=
github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g=
github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk=
github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg=
github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k=
github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U=
github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM=
github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8=
github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c= github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c=
github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE=
github.com/sonr-io/crypto v0.13.2 h1:KVm8iJpKXZ68W3TabbpB2jV0nADquMrs4w8E7RHZqCU=
github.com/sonr-io/crypto v0.13.2/go.mod h1:IyerhVPf5ZFodZTluKTbeFqZ1jk0GSHbC5/rY030LrQ=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/syumai/workers v0.30.2 h1:ZefPdAoXBsw87Bxy1LTAR6Pm9Gbxw/iM7DNraPSput0= github.com/syumai/workers v0.30.2 h1:ZefPdAoXBsw87Bxy1LTAR6Pm9Gbxw/iM7DNraPSput0=
@@ -83,23 +28,14 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa h1:t2QcU6V556bFjYgu4L6C+6VrCPyJZ+eyRsABUPs1mz4= golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk= golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
lukechampine.com/blake3 v1.4.1 h1:I3Smz7gso8w4/TunLKec6K2fn+kyKtDxr/xcQEN84Wg=
lukechampine.com/blake3 v1.4.1/go.mod h1:QFosUxmjB8mnrWFSNwKmvxHpfY72bmD2tQ0kBMM3kwo=
rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU=
rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA=

View File

@@ -1,10 +1,10 @@
package handlers package handlers
import ( import (
"github.com/go-sonr/middleware/render"
"github.com/go-sonr/ui/pages/login"
"github.com/go-sonr/ui/pages/register"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/sonr-io/motr/pkg/render"
"github.com/sonr-io/motr/ui/login"
"github.com/sonr-io/motr/ui/register"
) )
func HandleLoginCheck(c echo.Context) error { func HandleLoginCheck(c echo.Context) error {

View File

@@ -1,4 +0,0 @@
//go:build js && wasm
// +build js,wasm
package handlers

View File

@@ -4,11 +4,11 @@
package handlers package handlers
import ( import (
"github.com/go-sonr/middleware/render"
"github.com/go-sonr/ui/pages/home"
"github.com/go-sonr/ui/pages/login"
"github.com/go-sonr/ui/pages/register"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/sonr-io/motr/ui/register"
"github.com/sonr-io/motr/pkg/render"
"github.com/sonr-io/motr/ui/home"
"github.com/sonr-io/motr/ui/login"
) )
func RenderHomePage(c echo.Context) error { func RenderHomePage(c echo.Context) error {

View File

@@ -1,35 +0,0 @@
//go:build js && wasm
// +build js,wasm
package api
import (
"context"
"github.com/syumai/workers/cloudflare/fetch"
)
type Response interface {
UnmarshalJSON(data []byte) error
}
type Client interface {
MarketAPI
}
type client struct {
fc *fetch.Client
ctx context.Context
MarketAPI
}
func NewClient(ctx context.Context) *client {
fc := fetch.NewClient()
c := &client{
fc: fc,
ctx: ctx,
}
marketAPI := NewMarketAPI(c, ctx)
c.MarketAPI = marketAPI
return c
}

View File

@@ -1,117 +0,0 @@
//go:build js && wasm
// +build js,wasm
package api
import (
"context"
"encoding/json"
"fmt"
)
const (
kCryptoAPIURL = "https://api.alternative.me"
kCryptoAPIListings = "/v2/listings"
kCryptoAPITickers = "/v2/ticker"
kCryptoAPIGlobal = "/v2/global"
)
type MarketAPI interface {
Listings(symbol string) (*ListingsResponse, error)
Ticker(symbol string) (*TickersResponse, error)
GlobalMarket() (*GlobalMarketResponse, error)
}
type marketAPI struct {
client *client
ctx context.Context
}
func NewMarketAPI(c *client, ctx context.Context) *marketAPI {
return &marketAPI{
client: c,
ctx: ctx,
}
}
func (m *marketAPI) Listings(symbol string) (*ListingsResponse, error) {
r := buildRequest(m.ctx, fmt.Sprintf("%s/%s", kCryptoAPIListings, symbol))
v := &ListingsResponse{}
err := doFetch(m.client.fc, r, v)
if err != nil {
return nil, err
}
return v, nil
}
func (m *marketAPI) Ticker(symbol string) (*TickersResponse, error) {
r := buildRequest(m.ctx, fmt.Sprintf("%s/%s", kCryptoAPITickers, symbol))
v := &TickersResponse{}
err := doFetch(m.client.fc, r, v)
if err != nil {
return nil, err
}
return v, nil
}
func (m *marketAPI) GlobalMarket() (*GlobalMarketResponse, error) {
r := buildRequest(m.ctx, kCryptoAPIGlobal)
v := &GlobalMarketResponse{}
err := doFetch(m.client.fc, r, v)
if err != nil {
return nil, err
}
return v, nil
}
type ListingsResponse struct {
Data []struct {
ID string `json:"id"`
Name string `json:"name"`
Symbol string `json:"symbol"`
WebsiteSlug string `json:"website_slug"`
} `json:"data"`
Metadata struct {
Timestamp int `json:"timestamp"`
NumCryptocurrencies int `json:"num_cryptocurrencies"`
Error any `json:"error"`
} `json:"metadata"`
}
func (r *ListingsResponse) UnmarshalJSON(data []byte) error {
return json.Unmarshal(data, r)
}
type TickersResponse struct {
Data []struct {
Symbol string `json:"symbol"`
Price struct {
USD float64 `json:"USD"`
} `json:"price"`
} `json:"data"`
Metadata struct {
Timestamp int `json:"timestamp"`
Error any `json:"error"`
} `json:"metadata"`
}
func (r *TickersResponse) UnmarshalJSON(data []byte) error {
return json.Unmarshal(data, r)
}
type GlobalMarketResponse struct {
Data []struct {
Symbol string `json:"symbol"`
Price struct {
USD float64 `json:"USD"`
} `json:"price"`
} `json:"data"`
Metadata struct {
Timestamp int `json:"timestamp"`
Error any `json:"error"`
} `json:"metadata"`
}
func (r *GlobalMarketResponse) UnmarshalJSON(data []byte) error {
return json.Unmarshal(data, r)
}

View File

@@ -1,43 +0,0 @@
//go:build js && wasm
// +build js,wasm
package api
import (
"context"
"encoding/json"
"fmt"
"net/http"
"github.com/syumai/workers/cloudflare/fetch"
)
func buildRequest(c context.Context, url string) *fetch.Request {
r, err := fetch.NewRequest(c, http.MethodGet, url, nil)
if err != nil {
fmt.Println(err)
return nil
}
r.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/111.0")
return r
}
func doFetch(c *fetch.Client, r *fetch.Request, v Response) error {
resp, err := c.Do(r, nil)
if err != nil {
return fmt.Errorf("request failed: %w", err)
}
defer resp.Body.Close() // Ensure body is always closed
// Check for non-200 status codes
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}
// Directly decode JSON into the response struct
if err := json.NewDecoder(resp.Body).Decode(v); err != nil {
return fmt.Errorf("failed to decode response: %w", err)
}
return nil
}

View File

@@ -1 +0,0 @@
package jobs

View File

@@ -1,12 +0,0 @@
package jobs
type EventTrigger string
var (
EventTriggerMinute = EventTrigger("0 * * * * *") // Every minute (with seconds)
EventTriggerHourly = EventTrigger("0 */1 * * *") // Every hour at minute 0
EventTriggerDaily = EventTrigger("0 0 0 * * *") // Every day at 00:00:00
EventTriggerWeekly = EventTrigger("0 0 0 * * 0") // Every Sunday at 00:00:00
EventTriggerMonthly = EventTrigger("0 0 0 1 * *") // First day of every month at 00:00:00
EventTriggerYearly = EventTrigger("0 0 0 1 1 *") // January 1st every year at 00:00:00
)

View File

@@ -1 +0,0 @@
package jobs

View File

@@ -1,97 +0,0 @@
package meta
import "github.com/labstack/echo/v4"
func GetMetadata(c echo.Context) Metadata {
return DefaultMetadata()
}
func GetMetaComponent(c echo.Context) templ.Component {
return MetaComponent(GetMetadata(c))
}
func DefaultMetadata() Metadata {
return Metadata{
Title: "Motr",
Author: "Sonr",
Favicon: "https://cdn.sonr.id/favicon.png",
Robots: "index, follow",
Googlebot: "index, follow",
Google: "nositelinkssearchbox",
Description: "Sonr is a decentralized social network that allows you to create your own personalized digital identity.",
Keywords: "Sonr, social network, decentralized, identity, decentralized social network, decentralized identity, self-sovereign identity, self-sovereign, self-sovereign social network, self-sovereign identity network, sso, sso network, sso identity, sso social network, digital identity, digital social network",
CanonicalURL: "https://sonr.io",
OGImage: "https://cdn.sonr.id/og.png",
OGURL: "https://sonr.io",
OGSiteName: "Sonr",
TwitterSite: "@sonr_io",
TwitterCreator: "@sonr_io",
TwitterImage: "https://cdn.sonr.id/og.png",
}
}
type Metadata struct {
Title string
Author string
Favicon string
Robots string
Googlebot string
Google string
Description string
Keywords string
CanonicalURL string
OGImage string
OGURL string
OGSiteName string
TwitterSite string
TwitterCreator string
TwitterImage string
}
templ DefaultMetaComponent() {
<title>Motr</title>
<link rel="icon" type="image/png" href="https://cdn.sonr.id/favicon.png"/>
<meta name="description" content="Sonr is a decentralized social network that allows you to create your own personalized digital identity."/>
<meta name="keywords" content="Sonr, social network, decentralized, identity, decentralized social network, decentralized identity, self-sovereign identity, self-sovereign, self-sovereign social network, self-sovereign identity network, sso, sso network, sso identity, sso social network, digital identity, digital social network"/>
<meta name="author" content="Sonr"/>
<meta name="robots" content="index, follow"/>
<meta name="googlebot" content="index, follow"/>
<meta name="google" content="nositelinkssearchbox"/>
<meta property="og:title" content="Motr"/>
<meta property="og:description" content="Sonr is a decentralized social network that allows you to create your own personalized digital identity."/>
<meta property="og:image" content="https://cdn.sonr.id/og.png"/>
<meta property="og:url" content="https://sonr.io"/>
<meta property="og:site_name" content="Sonr"/>
<meta property="og:type" content="website"/>
<meta property="og:locale" content="en_US"/>
<meta name="twitter:card" content="summary_large_image"/>
<meta name="twitter:site" content="@sonr_io"/>
<meta name="twitter:creator" content="@sonr_io"/>
<meta name="twitter:title" content="Motr"/>
<meta name="twitter:description" content="Sonr is a decentralized social network that allows you to create your own personalized digital identity."/>
<meta name="twitter:image" content="https://cdn.sonr.id/og.png"/>
}
templ MetaComponent(m Metadata) {
<title>{ m.Title }</title>
<link rel="icon" type="image/png" href={ m.Favicon }/>
<meta name="description" content={ m.Description }/>
<meta name="keywords" content={ m.Keywords }/>
<meta name="author" content={ m.Author }/>
<meta name="robots" content={ m.Robots }/>
<meta name="googlebot" content={ m.Googlebot }/>
<meta name="google" content={ m.Google }/>
<meta property="og:title" content={ m.Title }/>
<meta property="og:description" content={ m.Description }/>
<meta property="og:image" content={ m.OGImage }/>
<meta property="og:url" content={ m.OGURL }/>
<meta property="og:site_name" content={ m.OGSiteName }/>
<meta property="og:type" content="website"/>
<meta property="og:locale" content="en_US"/>
<meta name="twitter:card" content="summary_large_image"/>
<meta name="twitter:site" content={ m.TwitterSite }/>
<meta name="twitter:creator" content={ m.TwitterCreator }/>
<meta name="twitter:title" content={ m.Title }/>
<meta name="twitter:description" content={ m.Description }/>
<meta name="twitter:image" content={ m.TwitterImage }/>
}

View File

@@ -1,351 +0,0 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.857
package meta
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import "github.com/labstack/echo/v4"
func GetMetadata(c echo.Context) Metadata {
return DefaultMetadata()
}
func GetMetaComponent(c echo.Context) templ.Component {
return MetaComponent(GetMetadata(c))
}
func DefaultMetadata() Metadata {
return Metadata{
Title: "Motr",
Author: "Sonr",
Favicon: "https://cdn.sonr.id/favicon.png",
Robots: "index, follow",
Googlebot: "index, follow",
Google: "nositelinkssearchbox",
Description: "Sonr is a decentralized social network that allows you to create your own personalized digital identity.",
Keywords: "Sonr, social network, decentralized, identity, decentralized social network, decentralized identity, self-sovereign identity, self-sovereign, self-sovereign social network, self-sovereign identity network, sso, sso network, sso identity, sso social network, digital identity, digital social network",
CanonicalURL: "https://sonr.io",
OGImage: "https://cdn.sonr.id/og.png",
OGURL: "https://sonr.io",
OGSiteName: "Sonr",
TwitterSite: "@sonr_io",
TwitterCreator: "@sonr_io",
TwitterImage: "https://cdn.sonr.id/og.png",
}
}
type Metadata struct {
Title string
Author string
Favicon string
Robots string
Googlebot string
Google string
Description string
Keywords string
CanonicalURL string
OGImage string
OGURL string
OGSiteName string
TwitterSite string
TwitterCreator string
TwitterImage string
}
func DefaultMetaComponent() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<title>Motr</title><link rel=\"icon\" type=\"image/png\" href=\"https://cdn.sonr.id/favicon.png\"><meta name=\"description\" content=\"Sonr is a decentralized social network that allows you to create your own personalized digital identity.\"><meta name=\"keywords\" content=\"Sonr, social network, decentralized, identity, decentralized social network, decentralized identity, self-sovereign identity, self-sovereign, self-sovereign social network, self-sovereign identity network, sso, sso network, sso identity, sso social network, digital identity, digital social network\"><meta name=\"author\" content=\"Sonr\"><meta name=\"robots\" content=\"index, follow\"><meta name=\"googlebot\" content=\"index, follow\"><meta name=\"google\" content=\"nositelinkssearchbox\"><meta property=\"og:title\" content=\"Motr\"><meta property=\"og:description\" content=\"Sonr is a decentralized social network that allows you to create your own personalized digital identity.\"><meta property=\"og:image\" content=\"https://cdn.sonr.id/og.png\"><meta property=\"og:url\" content=\"https://sonr.io\"><meta property=\"og:site_name\" content=\"Sonr\"><meta property=\"og:type\" content=\"website\"><meta property=\"og:locale\" content=\"en_US\"><meta name=\"twitter:card\" content=\"summary_large_image\"><meta name=\"twitter:site\" content=\"@sonr_io\"><meta name=\"twitter:creator\" content=\"@sonr_io\"><meta name=\"twitter:title\" content=\"Motr\"><meta name=\"twitter:description\" content=\"Sonr is a decentralized social network that allows you to create your own personalized digital identity.\"><meta name=\"twitter:image\" content=\"https://cdn.sonr.id/og.png\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func MetaComponent(m Metadata) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var2 := templ.GetChildren(ctx)
if templ_7745c5c3_Var2 == nil {
templ_7745c5c3_Var2 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<title>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(m.Title)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/meta/metadata.templ`, Line: 76, Col: 17}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</title><link rel=\"icon\" type=\"image/png\" href=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(m.Favicon)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/meta/metadata.templ`, Line: 77, Col: 51}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "\"><meta name=\"description\" content=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(m.Description)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/meta/metadata.templ`, Line: 78, Col: 49}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\"><meta name=\"keywords\" content=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(m.Keywords)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/meta/metadata.templ`, Line: 79, Col: 43}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "\"><meta name=\"author\" content=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(m.Author)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/meta/metadata.templ`, Line: 80, Col: 39}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "\"><meta name=\"robots\" content=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(m.Robots)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/meta/metadata.templ`, Line: 81, Col: 39}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "\"><meta name=\"googlebot\" content=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var9 string
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(m.Googlebot)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/meta/metadata.templ`, Line: 82, Col: 45}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\"><meta name=\"google\" content=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var10 string
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(m.Google)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/meta/metadata.templ`, Line: 83, Col: 39}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\"><meta property=\"og:title\" content=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(m.Title)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/meta/metadata.templ`, Line: 84, Col: 44}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "\"><meta property=\"og:description\" content=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var12 string
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(m.Description)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/meta/metadata.templ`, Line: 85, Col: 56}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "\"><meta property=\"og:image\" content=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var13 string
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(m.OGImage)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/meta/metadata.templ`, Line: 86, Col: 46}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "\"><meta property=\"og:url\" content=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var14 string
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(m.OGURL)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/meta/metadata.templ`, Line: 87, Col: 42}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "\"><meta property=\"og:site_name\" content=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var15 string
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(m.OGSiteName)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/meta/metadata.templ`, Line: 88, Col: 53}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "\"><meta property=\"og:type\" content=\"website\"><meta property=\"og:locale\" content=\"en_US\"><meta name=\"twitter:card\" content=\"summary_large_image\"><meta name=\"twitter:site\" content=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var16 string
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(m.TwitterSite)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/meta/metadata.templ`, Line: 92, Col: 50}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "\"><meta name=\"twitter:creator\" content=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var17 string
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(m.TwitterCreator)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/meta/metadata.templ`, Line: 93, Col: 56}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "\"><meta name=\"twitter:title\" content=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var18 string
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(m.Title)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/meta/metadata.templ`, Line: 94, Col: 45}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "\"><meta name=\"twitter:description\" content=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var19 string
templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(m.Description)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/meta/metadata.templ`, Line: 95, Col: 57}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "\"><meta name=\"twitter:image\" content=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var20 string
templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(m.TwitterImage)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/meta/metadata.templ`, Line: 96, Col: 52}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View File

@@ -1 +0,0 @@
DROP TABLE accounts;

View File

@@ -1,30 +0,0 @@
-- Accounts represent blockchain accounts
CREATE TABLE accounts (
id TEXT PRIMARY KEY,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP,
number INTEGER NOT NULL,
sequence INTEGER NOT NULL DEFAULT 0,
address TEXT NOT NULL UNIQUE,
public_key TEXT NOT NULL CHECK(json_valid(public_key)),
chain_id TEXT NOT NULL,
block_created INTEGER NOT NULL,
controller TEXT NOT NULL,
label TEXT NOT NULL,
handle TEXT NOT NULL,
is_subsidiary BOOLEAN NOT NULL DEFAULT FALSE CHECK(is_subsidiary IN (0,1)),
is_validator BOOLEAN NOT NULL DEFAULT FALSE CHECK(is_validator IN (0,1)),
is_delegator BOOLEAN NOT NULL DEFAULT FALSE CHECK(is_delegator IN (0,1)),
is_accountable BOOLEAN NOT NULL DEFAULT TRUE CHECK(is_accountable IN (0,1))
);
CREATE INDEX idx_accounts_address ON accounts(address);
CREATE INDEX idx_accounts_chain_id ON accounts(chain_id);
CREATE INDEX idx_accounts_block_created ON accounts(block_created);
CREATE INDEX idx_accounts_label ON accounts(label);
CREATE INDEX idx_accounts_controller ON accounts(controller);
CREATE INDEX idx_accounts_deleted_at ON accounts(deleted_at);

View File

@@ -1 +0,0 @@
DROP TABLE credentials;

View File

@@ -1,19 +0,0 @@
-- Credentials store WebAuthn credentials
CREATE TABLE credentials (
id TEXT PRIMARY KEY,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP,
handle TEXT NOT NULL,
credential_id TEXT NOT NULL UNIQUE,
authenticator_attachment TEXT NOT NULL,
origin TEXT NOT NULL,
type TEXT NOT NULL,
transports TEXT NOT NULL
);
CREATE INDEX idx_credentials_handle ON credentials(handle);
CREATE INDEX idx_credentials_origin ON credentials(origin);
CREATE INDEX idx_credentials_deleted_at ON credentials(deleted_at);

View File

@@ -1 +0,0 @@
DROP TABLE profiles;

View File

@@ -1,18 +0,0 @@
-- Profiles represent user identities
CREATE TABLE profiles (
id TEXT PRIMARY KEY,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP,
address TEXT NOT NULL,
handle TEXT NOT NULL UNIQUE,
origin TEXT NOT NULL,
name TEXT NOT NULL,
UNIQUE(address, origin)
);
CREATE INDEX idx_profiles_handle ON profiles(handle);
CREATE INDEX idx_profiles_address ON profiles(address);
CREATE INDEX idx_profiles_deleted_at ON profiles(deleted_at);

View File

@@ -1 +0,0 @@
DROP TABLE vaults;

View File

@@ -1,19 +0,0 @@
-- Vaults store encrypted data
CREATE TABLE vaults (
id TEXT PRIMARY KEY,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP,
handle TEXT NOT NULL,
origin TEXT NOT NULL,
address TEXT NOT NULL,
cid TEXT NOT NULL UNIQUE,
config TEXT NOT NULL CHECK(json_valid(config)),
session_id TEXT NOT NULL,
redirect_uri TEXT NOT NULL
);
CREATE INDEX idx_vaults_handle ON vaults(handle);
CREATE INDEX idx_vaults_session_id ON vaults(session_id);
CREATE INDEX idx_vaults_deleted_at ON vaults(deleted_at)

View File

@@ -1 +0,0 @@
DROP TABLE assets;

View File

@@ -1,21 +0,0 @@
-- Assets represent tokens and coins
CREATE TABLE assets (
id TEXT PRIMARY KEY,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP,
name TEXT NOT NULL,
symbol TEXT NOT NULL,
decimals INTEGER NOT NULL CHECK(decimals >= 0),
chain_id TEXT NOT NULL,
channel TEXT NOT NULL,
asset_type TEXT NOT NULL,
coingecko_id TEXT,
UNIQUE(chain_id, symbol)
);
CREATE INDEX idx_assets_symbol ON assets(symbol);
CREATE INDEX idx_assets_chain_id ON assets(chain_id);
CREATE INDEX idx_assets_deleted_at ON assets(deleted_at);

View File

@@ -1 +0,0 @@
DROP TABLE prices;

View File

@@ -1,28 +0,0 @@
-- Prices entity based on the Alternative.me API for crypto prices
CREATE TABLE prices (
id TEXT PRIMARY KEY,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP,
asset_id TEXT NOT NULL,
price_usd REAL,
price_btc REAL,
volume_24h_usd REAL,
market_cap_usd REAL,
available_supply REAL,
total_supply REAL,
max_supply REAL,
percent_change_1h REAL,
percent_change_24h REAL,
percent_change_7d REAL,
rank INTEGER,
last_updated TIMESTAMP NOT NULL,
FOREIGN KEY (asset_id) REFERENCES assets(id)
);
CREATE INDEX idx_prices_asset_id ON prices(asset_id);
CREATE INDEX idx_prices_rank ON prices(rank);
CREATE INDEX idx_prices_last_updated ON prices(last_updated);
CREATE INDEX idx_prices_deleted_at ON prices(deleted_at);

View File

@@ -1 +0,0 @@
DROP TABLE price_conversions;

View File

@@ -1,21 +0,0 @@
-- Currency conversion rates for crypto prices
CREATE TABLE price_conversions (
id TEXT PRIMARY KEY,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP,
price_id TEXT NOT NULL,
currency_code TEXT NOT NULL,
price REAL,
volume_24h REAL,
market_cap REAL,
last_updated TIMESTAMP NOT NULL,
FOREIGN KEY (price_id) REFERENCES prices(id),
UNIQUE(price_id, currency_code)
);
CREATE INDEX idx_price_conversions_price_id ON price_conversions(price_id);
CREATE INDEX idx_price_conversions_currency_code ON price_conversions(currency_code);
CREATE INDEX idx_price_conversions_deleted_at ON price_conversions(deleted_at);

View File

@@ -1 +0,0 @@
DROP TABLE blockchains;

View File

@@ -1,71 +0,0 @@
-- Blockchains table to store chain configuration parameters
CREATE TABLE blockchains (
id TEXT PRIMARY KEY,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP,
-- Basic chain information
chain_name TEXT NOT NULL,
chain_id_cosmos TEXT,
chain_id_evm TEXT,
api_name TEXT,
bech_account_prefix TEXT,
bech_validator_prefix TEXT,
-- Chain assets
main_asset_symbol TEXT,
main_asset_denom TEXT,
staking_asset_symbol TEXT,
staking_asset_denom TEXT,
is_stake_enabled BOOLEAN NOT NULL DEFAULT FALSE CHECK(is_stake_enabled IN (0,1)),
-- Chain images
chain_image TEXT,
main_asset_image TEXT,
staking_asset_image TEXT,
-- Chain types and features
chain_type TEXT NOT NULL CHECK(json_valid(chain_type)),
is_support_mobile_wallet BOOLEAN NOT NULL DEFAULT FALSE CHECK(is_support_mobile_wallet IN (0,1)),
is_support_extension_wallet BOOLEAN NOT NULL DEFAULT FALSE CHECK(is_support_extension_wallet IN (0,1)),
is_support_erc20 BOOLEAN NOT NULL DEFAULT FALSE CHECK(is_support_erc20 IN (0,1)),
-- Descriptions in multiple languages
description_en TEXT,
description_ko TEXT,
description_ja TEXT,
-- Genesis information
origin_genesis_time TIMESTAMP,
-- Account types configuration
account_type TEXT NOT NULL CHECK(json_valid(account_type)),
-- BTC staking specific
btc_staking TEXT CHECK(json_valid(btc_staking)),
-- Cosmos fee information
cosmos_fee_info TEXT CHECK(json_valid(cosmos_fee_info)),
-- EVM fee information
evm_fee_info TEXT CHECK(json_valid(evm_fee_info)),
-- Endpoints
lcd_endpoint TEXT CHECK(json_valid(lcd_endpoint)),
grpc_endpoint TEXT CHECK(json_valid(grpc_endpoint)),
evm_rpc_endpoint TEXT CHECK(json_valid(evm_rpc_endpoint)),
-- Explorer information
explorer TEXT CHECK(json_valid(explorer)),
-- Social and documentation links
about TEXT CHECK(json_valid(about)),
forum TEXT CHECK(json_valid(forum))
);
CREATE INDEX idx_blockchains_chain_name ON blockchains(chain_name);
CREATE INDEX idx_blockchains_chain_id_cosmos ON blockchains(chain_id_cosmos);
CREATE INDEX idx_blockchains_chain_id_evm ON blockchains(chain_id_evm);
CREATE INDEX idx_blockchains_main_asset_symbol ON blockchains(main_asset_symbol);
CREATE INDEX idx_blockchains_deleted_at ON blockchains(deleted_at);

View File

@@ -1 +0,0 @@
DROP TABLE services;

View File

@@ -1,24 +0,0 @@
-- Service for Service Records sourced on chain
CREATE TABLE services (
id TEXT PRIMARY KEY,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP,
name TEXT NOT NULL,
description TEXT,
chain_id TEXT NOT NULL,
address TEXT NOT NULL,
owner_address TEXT NOT NULL,
metadata TEXT CHECK(json_valid(metadata)),
status TEXT NOT NULL,
block_height INTEGER NOT NULL,
FOREIGN KEY (chain_id) REFERENCES assets(chain_id),
UNIQUE(chain_id, address)
);
CREATE INDEX idx_services_name ON services(name);
CREATE INDEX idx_services_chain_id ON services(chain_id);
CREATE INDEX idx_services_address ON services(address);
CREATE INDEX idx_services_owner_address ON services(owner_address);
CREATE INDEX idx_services_status ON services(status);
CREATE INDEX idx_services_deleted_at ON services(deleted_at);

View File

@@ -1 +0,0 @@
DROP TABLE activities;

View File

@@ -1,32 +0,0 @@
-- Activity table for basic transaction broadcast activity
CREATE TABLE activities (
id TEXT PRIMARY KEY,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP,
account_id TEXT NOT NULL,
tx_hash TEXT,
tx_type TEXT NOT NULL,
status TEXT NOT NULL,
amount TEXT,
fee TEXT,
gas_used INTEGER,
gas_wanted INTEGER,
memo TEXT,
block_height INTEGER,
timestamp TIMESTAMP NOT NULL,
raw_log TEXT,
error TEXT,
FOREIGN KEY (account_id) REFERENCES accounts(id)
);
CREATE INDEX idx_activities_account_id ON activities(account_id);
CREATE INDEX idx_activities_tx_hash ON activities(tx_hash);
CREATE INDEX idx_activities_tx_type ON activities(tx_type);
CREATE INDEX idx_activities_status ON activities(status);
CREATE INDEX idx_activities_timestamp ON activities(timestamp);
CREATE INDEX idx_activities_block_height ON activities(block_height);
CREATE INDEX idx_activities_deleted_at ON activities(deleted_at);

View File

@@ -1 +0,0 @@
DROP TABLE health;

View File

@@ -1,28 +0,0 @@
-- Health table for scheduled checks for API endpoints
CREATE TABLE health (
id TEXT PRIMARY KEY,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP,
endpoint_url TEXT NOT NULL,
endpoint_type TEXT NOT NULL,
chain_id TEXT,
status TEXT NOT NULL,
response_time_ms INTEGER,
last_checked TIMESTAMP NOT NULL,
next_check TIMESTAMP,
failure_count INTEGER NOT NULL DEFAULT 0,
success_count INTEGER NOT NULL DEFAULT 0,
response_data TEXT,
error_message TEXT,
FOREIGN KEY (chain_id) REFERENCES assets(chain_id)
);
CREATE INDEX idx_health_endpoint_url ON health(endpoint_url);
CREATE INDEX idx_health_endpoint_type ON health(endpoint_type);
CREATE INDEX idx_health_chain_id ON health(chain_id);
CREATE INDEX idx_health_status ON health(status);
CREATE INDEX idx_health_last_checked ON health(last_checked);
CREATE INDEX idx_health_next_check ON health(next_check);
CREATE INDEX idx_health_deleted_at ON health(deleted_at);

View File

@@ -1 +0,0 @@
DROP TABLE global_market;

View File

@@ -1,19 +0,0 @@
-- Global market data from Alternative.me API
CREATE TABLE global_market (
id TEXT PRIMARY KEY,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP,
total_market_cap_usd REAL,
total_24h_volume_usd REAL,
bitcoin_percentage_of_market_cap REAL,
active_currencies INTEGER,
active_assets INTEGER,
active_markets INTEGER,
last_updated TIMESTAMP NOT NULL
);
CREATE INDEX idx_global_market_last_updated ON global_market(last_updated);
CREATE INDEX idx_global_market_deleted_at ON global_market(deleted_at);

View File

@@ -1 +0,0 @@
DROP TABLE fear_greed_index;

View File

@@ -1,15 +0,0 @@
-- Fear and Greed Index data from Alternative.me
CREATE TABLE fear_greed_index (
id TEXT PRIMARY KEY,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP,
value INTEGER NOT NULL,
value_classification TEXT NOT NULL,
timestamp TIMESTAMP NOT NULL,
time_until_update TEXT
);
CREATE INDEX idx_fear_greed_index_timestamp ON fear_greed_index(timestamp);
CREATE INDEX idx_fear_greed_index_value ON fear_greed_index(value);
CREATE INDEX idx_fear_greed_index_deleted_at ON fear_greed_index(deleted_at);

View File

@@ -1 +0,0 @@
DROP TABLE crypto_listings;

View File

@@ -1,18 +0,0 @@
-- Listings data from Alternative.me API
CREATE TABLE crypto_listings (
id TEXT PRIMARY KEY,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP,
api_id TEXT NOT NULL,
name TEXT NOT NULL,
symbol TEXT NOT NULL,
website_slug TEXT NOT NULL,
UNIQUE(api_id)
);
CREATE INDEX idx_crypto_listings_api_id ON crypto_listings(api_id);
CREATE INDEX idx_crypto_listings_symbol ON crypto_listings(symbol);
CREATE INDEX idx_crypto_listings_website_slug ON crypto_listings(website_slug);
CREATE INDEX idx_crypto_listings_deleted_at ON crypto_listings(deleted_at);

View File

@@ -1,200 +0,0 @@
# yaml-language-server: $schema=https://taskfile.dev/schema.json
version: "3"
silent: true
tasks:
default:
cmds:
- task: migrate
initialize:
cmds:
- task: migrate:accounts:up
- task: migrate:credentials:up
- task: migrate:profiles:up
- task: migrate:vaults:up
- task: migrate:assets:up
- task: migrate:prices:up
- task: migrate:price_conversions:up
- task: migrate:blockchains:up
- task: migrate:services:up
- task: migrate:activities:up
- task: migrate:health:up
- task: migrate:global_market:up
- task: migrate:fear_greed_index:up
- task: migrate:crypto_listings:up
migrate:
cmds:
- task: migrate:accounts
- task: migrate:credentials
- task: migrate:profiles
- task: migrate:vaults
- task: migrate:assets
- task: migrate:prices
- task: migrate:price_conversions
- task: migrate:blockchains
- task: migrate:services
- task: migrate:activities
- task: migrate:health
- task: migrate:global_market
- task: migrate:fear_greed_index
- task: migrate:crypto_listings
# ---------------
# Main Tasks
# ---------------
migrate:accounts:
cmds:
- task: migrate:accounts:down
- task: migrate:accounts:up
migrate:accounts:up:
cmd: wrangler d1 execute USERS_DB --file 001_accounts_table.up.sql --remote -y
migrate:accounts:down:
cmd: wrangler d1 execute USERS_DB --file 001_accounts_table.down.sql --remote -y
migrate:credentials:
cmds:
- task: migrate:credentials:down
- task: migrate:credentials:up
migrate:credentials:up:
cmd: wrangler d1 execute USERS_DB --file 002_credentials_table.up.sql --remote -y
migrate:credentials:down:
cmd: wrangler d1 execute USERS_DB --file 002_credentials_table.down.sql --remote -y
migrate:profiles:
cmds:
- task: migrate:profiles:down
- task: migrate:profiles:up
migrate:profiles:up:
cmd: wrangler d1 execute USERS_DB --file 003_profiles_table.up.sql --remote -y
migrate:profiles:down:
cmd: wrangler d1 execute USERS_DB --file 003_profiles_table.down.sql --remote -y
migrate:vaults:
cmds:
- task: migrate:vaults:down
- task: migrate:vaults:up
migrate:vaults:down:
cmd: wrangler d1 execute USERS_DB --file 004_vaults_table.down.sql --remote -y
migrate:vaults:up:
cmd: wrangler d1 execute USERS_DB --file 004_vaults_table.up.sql --remote -y
migrate:assets:
cmds:
- task: migrate:assets:down
- task: migrate:assets:up
migrate:assets:up:
cmd: wrangler d1 execute NETWORK_DB --file 005_assets_table.up.sql --remote -y
migrate:assets:down:
cmd: wrangler d1 execute NETWORK_DB --file 005_assets_table.down.sql --remote -y
migrate:prices:
cmds:
- task: migrate:prices:down
- task: migrate:prices:up
migrate:prices:up:
cmd: wrangler d1 execute NETWORK_DB --file 006_prices_table.up.sql --remote -y
migrate:prices:down:
cmd: wrangler d1 execute NETWORK_DB --file 006_prices_table.down.sql --remote -y
migrate:price_conversions:
cmds:
- task: migrate:price_conversions:down
- task: migrate:price_conversions:up
migrate:price_conversions:up:
cmd: wrangler d1 execute NETWORK_DB --file 007_price_conversions_table.up.sql --remote -y
migrate:price_conversions:down:
cmd: wrangler d1 execute NETWORK_DB --file 007_price_conversions_table.down.sql --remote -y
migrate:blockchains:
cmds:
- task: migrate:blockchains:down
- task: migrate:blockchains:up
migrate:blockchains:up:
cmd: wrangler d1 execute NETWORK_DB --file 008_blockchains_table.up.sql --remote -y
migrate:blockchains:down:
cmd: wrangler d1 execute NETWORK_DB --file 008_blockchains_table.down.sql --remote -y
migrate:services:
cmds:
- task: migrate:services:down
- task: migrate:services:up
migrate:services:up:
cmd: wrangler d1 execute ACTIVITY_DB --file 009_services_table.up.sql --remote -y
migrate:services:down:
cmd: wrangler d1 execute ACTIVITY_DB --file 009_services_table.down.sql --remote -y
migrate:activities:
cmds:
- task: migrate:activities:down
- task: migrate:activities:up
migrate:activities:up:
cmd: wrangler d1 execute ACTIVITY_DB --file 010_activities_table.up.sql --remote -y
migrate:activities:down:
cmd: wrangler d1 execute ACTIVITY_DB --file 010_activities_table.down.sql --remote -y
migrate:health:
cmds:
- task: migrate:health:down
- task: migrate:health:up
migrate:health:up:
cmd: wrangler d1 execute ACTIVITY_DB --file 011_health_table.up.sql --remote -y
migrate:health:down:
cmd: wrangler d1 execute ACTIVITY_DB --file 011_health_table.down.sql --remote -y
migrate:global_market:
cmds:
- task: global_market:down
- task: global_market:up
migrate:global_market:up:
cmd: wrangler d1 execute ACTIVITY_DB --file 012_global_market_table.up.sql --remote -y
migrate:global_market:down:
cmd: wrangler d1 execute ACTIVITY_DB --file 012_global_market_table.down.sql --remote -y
migrate:fear_greed_index:
cmds:
- task: migrate:fear_greed_index:down
- task: migrate:fear_greed_index:up
migrate:fear_greed_index:up:
cmd: wrangler d1 execute ACTIVITY_DB --file 013_fear_greed_index_table.up.sql --remote -y
migrate:fear_greed_index:down:
cmd: wrangler d1 execute ACTIVITY_DB --file 013_fear_greed_index_table.down.sql --remote -y
migrate:crypto_listings:
cmds:
- task: migrate:crypto_listings:down
- task: migrate:crypto_listings:up
migrate:crypto_listings:up:
cmd: wrangler d1 execute ACTIVITY_DB --file 014_crypto_listings_table.up.sql --remote -y
migrate:crypto_listings:down:
cmd: wrangler d1 execute ACTIVITY_DB --file 014_crypto_listings_table.down.sql --remote -y

View File

@@ -1,64 +0,0 @@
# Top-level configuration
name = "motr-worker"
main = "worker.mjs"
compatibility_date = "2025-04-14"
routes = [
{ pattern = "sonr.id", custom_domain = true },
]
[build]
command = "devbox run build:worker"
[dev]
port = 6969
[observability]
enabled = true
[triggers]
crons = ["0 */1 * * *"]
[[d1_databases]]
binding = "ACTIVITY_DB"
database_name = "motr-activity"
database_id = "a7ccb4bb-c529-4f42-8029-92564a3aecb8"
[[d1_databases]]
binding = "NETWORK_DB"
database_name = "motr-network"
database_id = "acb75499-3502-4052-9604-263a913e077a"
[[d1_databases]]
binding = "USERS_DB"
database_name = "motr-users"
database_id = "8ed4d399-5932-419c-b92f-9c20d7a36ad2"
[[kv_namespaces]]
binding = "SESSIONS_KV"
id = "ea5de66fcfc14b5eba170395e29432ee"
[[kv_namespaces]]
binding = "HANDLES_KV"
id = "271d47087a8842b2aac5ee79cf7bb203"
[[r2_buckets]]
binding = 'PROFILES'
bucket_name = 'profiles'
[vars]
SONR_CHAIN_ID = 'sonr-testnet-1'
IPFS_GATEWAY = 'https://ipfs.sonr.land'
SONR_API_URL = 'https://api.sonr.land'
SONR_RPC_URL = 'https://rpc.sonr.land'
SONR_GRPC_URL = 'https://grpc.sonr.land'
MATRIX_SERVER = 'https://bm.chat'
MOTR_GATEWAY = 'https://sonr.id'
MOTR_VAULT = 'https://did.run'
[durable_objects]
bindings = [{name = "VAULT", class_name = "Vault"}]
[[migrations]]
tag = "v1" # Should be unique for each entry
new_classes = ["Vault"] # List the classes that should be created

View File

@@ -1,20 +0,0 @@
package charts
import "fmt"
type DateValue struct {
Date string
Value int
}
templ AreaChart(data []DateValue) {
for _, d := range data {
<div class="flex flex-col">
<div class="flex justify-between">
<span class="text-sm font-medium text-gray-900">${ d.Date }</span>
<span class="text-sm font-medium text-gray-900">${ fmt.Sprintf("%d", d.Value) }</span>
</div>
<div class="h-1 bg-gray-200 rounded-full"></div>
</div>
}
}

View File

@@ -1,75 +0,0 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.857
package charts
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import "fmt"
type DateValue struct {
Date string
Value int
}
func AreaChart(data []DateValue) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
for _, d := range data {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"flex flex-col\"><div class=\"flex justify-between\"><span class=\"text-sm font-medium text-gray-900\">$")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(d.Date)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/ui/charts/area_chart.templ`, Line: 14, Col: 61}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</span> <span class=\"text-sm font-medium text-gray-900\">$")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", d.Value))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/ui/charts/area_chart.templ`, Line: 15, Col: 81}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</span></div><div class=\"h-1 bg-gray-200 rounded-full\"></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View File

@@ -1,21 +0,0 @@
package charts
import "fmt"
type KeyValue struct {
Key string
Value int
Color string
}
templ BarChart(data []KeyValue) {
for _, d := range data {
<div class="flex flex-col">
<div class="flex justify-between">
<span class="text-sm font-medium text-gray-900">${ d.Key }</span>
<span class="text-sm font-medium text-gray-900">${ fmt.Sprintf("%d", d.Value) }</span>
</div>
<div class="h-1 bg-gray-200 rounded-full"></div>
</div>
}
}

View File

@@ -1,76 +0,0 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.857
package charts
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import "fmt"
type KeyValue struct {
Key string
Value int
Color string
}
func BarChart(data []KeyValue) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
for _, d := range data {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"flex flex-col\"><div class=\"flex justify-between\"><span class=\"text-sm font-medium text-gray-900\">$")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(d.Key)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/ui/charts/bar_chart.templ`, Line: 15, Col: 60}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</span> <span class=\"text-sm font-medium text-gray-900\">$")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", d.Value))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/ui/charts/bar_chart.templ`, Line: 16, Col: 81}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</span></div><div class=\"h-1 bg-gray-200 rounded-full\"></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View File

@@ -1,106 +0,0 @@
package charts
import (
"encoding/json"
"time"
)
type CandleData struct {
Open float64
Close float64
High float64
Low float64
Date time.Time
}
// D3 script handle for deduplication
var d3Handle = templ.NewOnceHandle()
// D3 component for loading D3.js
templ D3() {
@d3Handle.Once() {
<script type="module">
window.d3 = d3;
</script>
}
}
// CandleChart component
templ CandleChart(data []CandleData) {
@D3()
<div id="candleChart" class="@container relative">
<div
class="relative h-72 w-full"
style="--marginTop: 10px; --marginRight: 60px; --marginBottom: 56px; --marginLeft: 30px;"
></div>
</div>
<script type="module">
import * as d3 from "https://cdn.jsdelivr.net/npm/d3@7/+esm";
// Convert Go data to JavaScript
// Declare the chart dimensions and margins.
const width = 640;
const height = 400;
const marginTop = 20;
const marginRight = 20;
const marginBottom = 30;
const marginLeft = 40;
// Declare the x (horizontal position) scale.
const x = d3.scaleUtc()
.domain([new Date("2023-01-01"), new Date("2024-01-01")])
.range([marginLeft, width - marginRight]);
// Declare the y (vertical position) scale.
const y = d3.scaleLinear()
.domain([0, 100])
.range([height - marginBottom, marginTop]);
// Create the SVG container.
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height);
// Add the x-axis.
svg.append("g")
.attr("transform", `translate(0,${height - marginBottom})`)
.call(d3.axisBottom(x));
// Add the y-axis.
svg.append("g")
.attr("transform", `translate(${marginLeft},0)`)
.call(d3.axisLeft(y));
// Append the SVG element.
container.append(svg.node());
</script>
}
// formatDataForJS converts the Go data structure to a JavaScript-compatible JSON string
func formatDataForJS(data []CandleData) string {
type jsData struct {
Date string `json:"date"`
Open float64 `json:"open"`
Close float64 `json:"close"`
High float64 `json:"high"`
Low float64 `json:"low"`
}
jsDataArray := make([]jsData, len(data))
for i, d := range data {
jsDataArray[i] = jsData{
Date: d.Date.Format(time.RFC3339),
Open: d.Open,
Close: d.Close,
High: d.High,
Low: d.Low,
}
}
jsonBytes, err := json.Marshal(jsDataArray)
if err != nil {
return "[]"
}
return string(jsonBytes)
}

View File

@@ -1,137 +0,0 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.857
package charts
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import (
"encoding/json"
"time"
)
type CandleData struct {
Open float64
Close float64
High float64
Low float64
Date time.Time
}
// D3 script handle for deduplication
var d3Handle = templ.NewOnceHandle()
// D3 component for loading D3.js
func D3() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<script type=\"module\">\n \n window.d3 = d3;\n </script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = d3Handle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// CandleChart component
func CandleChart(data []CandleData) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
if templ_7745c5c3_Var3 == nil {
templ_7745c5c3_Var3 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = D3().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<div id=\"candleChart\" class=\"@container relative\"><div class=\"relative h-72 w-full\" style=\"--marginTop: 10px; --marginRight: 60px; --marginBottom: 56px; --marginLeft: 30px;\"></div></div><script type=\"module\">\n\t import * as d3 from \"https://cdn.jsdelivr.net/npm/d3@7/+esm\";\n // Convert Go data to JavaScript\n \n // Declare the chart dimensions and margins.\n const width = 640;\n const height = 400;\n const marginTop = 20;\n const marginRight = 20;\n const marginBottom = 30;\n const marginLeft = 40;\n\n // Declare the x (horizontal position) scale.\n const x = d3.scaleUtc()\n .domain([new Date(\"2023-01-01\"), new Date(\"2024-01-01\")])\n .range([marginLeft, width - marginRight]);\n\n // Declare the y (vertical position) scale.\n const y = d3.scaleLinear()\n .domain([0, 100])\n .range([height - marginBottom, marginTop]);\n\n // Create the SVG container.\n const svg = d3.create(\"svg\")\n .attr(\"width\", width)\n .attr(\"height\", height);\n\n // Add the x-axis.\n svg.append(\"g\")\n .attr(\"transform\", `translate(0,${height - marginBottom})`)\n .call(d3.axisBottom(x));\n\n // Add the y-axis.\n svg.append(\"g\")\n .attr(\"transform\", `translate(${marginLeft},0)`)\n .call(d3.axisLeft(y));\n\n // Append the SVG element.\n container.append(svg.node()); \n </script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// formatDataForJS converts the Go data structure to a JavaScript-compatible JSON string
func formatDataForJS(data []CandleData) string {
type jsData struct {
Date string `json:"date"`
Open float64 `json:"open"`
Close float64 `json:"close"`
High float64 `json:"high"`
Low float64 `json:"low"`
}
jsDataArray := make([]jsData, len(data))
for i, d := range data {
jsDataArray[i] = jsData{
Date: d.Date.Format(time.RFC3339),
Open: d.Open,
Close: d.Close,
High: d.High,
Low: d.Low,
}
}
jsonBytes, err := json.Marshal(jsDataArray)
if err != nil {
return "[]"
}
return string(jsonBytes)
}
var _ = templruntime.GeneratedTemplate

View File

@@ -1,15 +0,0 @@
package charts
import "fmt"
templ LineChart(data []DateValue) {
for _, d := range data {
<div class="flex flex-col">
<div class="flex justify-between">
<span class="text-sm font-medium text-gray-900">${ d.Date }</span>
<span class="text-sm font-medium text-gray-900">${ fmt.Sprintf("%d", d.Value) }</span>
</div>
<div class="h-1 bg-gray-200 rounded-full"></div>
</div>
}
}

View File

@@ -1,70 +0,0 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.857
package charts
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import "fmt"
func LineChart(data []DateValue) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
for _, d := range data {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"flex flex-col\"><div class=\"flex justify-between\"><span class=\"text-sm font-medium text-gray-900\">$")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(d.Date)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/ui/charts/line_chart.templ`, Line: 9, Col: 61}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</span> <span class=\"text-sm font-medium text-gray-900\">$")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", d.Value))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/ui/charts/line_chart.templ`, Line: 10, Col: 81}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</span></div><div class=\"h-1 bg-gray-200 rounded-full\"></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View File

@@ -1,22 +0,0 @@
package charts
import "fmt"
type CategoryValue struct {
Category string
Value int
ColorFrom string
ColorTo string
}
templ PieChart(data []CategoryValue) {
for _, d := range data {
<div class="flex flex-col">
<div class="flex justify-between">
<span class="text-sm font-medium text-gray-900">${ d.Category }</span>
<span class="text-sm font-medium text-gray-900">${ fmt.Sprintf("%d", d.Value) }</span>
</div>
<div class="h-1 bg-gray-200 rounded-full"></div>
</div>
}
}

View File

@@ -1,77 +0,0 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.857
package charts
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import "fmt"
type CategoryValue struct {
Category string
Value int
ColorFrom string
ColorTo string
}
func PieChart(data []CategoryValue) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
for _, d := range data {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"flex flex-col\"><div class=\"flex justify-between\"><span class=\"text-sm font-medium text-gray-900\">$")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(d.Category)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/ui/charts/pie_chart.templ`, Line: 16, Col: 65}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</span> <span class=\"text-sm font-medium text-gray-900\">$")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", d.Value))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/ui/charts/pie_chart.templ`, Line: 17, Col: 81}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</span></div><div class=\"h-1 bg-gray-200 rounded-full\"></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View File

@@ -1,113 +0,0 @@
package ui
// Body is a component that renders the body tag
templ Body() {
<body>
{ children... }
</body>
}
// Head is a component that renders the head of the document
templ Head() {
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
@ApexCharts()
@Helia()
@Dexie()
@Htmx()
@Tailwind()
@Shoelace()
@DefaultStyles()
{ children... }
</head>
}
// HTML is a component that renders the html tag
templ HTML() {
<!DOCTYPE html>
<html lang="en">
{ children... }
</html>
}
// Columns is a component that renders a responsive flex container that stacks on mobile
templ Columns() {
<div class="flex flex-col h-full w-full gap-4 md:gap-6 md:flex-row md:flex-wrap">
{ children... }
</div>
}
// Container is a component that renders a full screen container
templ Container() {
<div id="container" class="flex fixed inset-0 z-[99] w-screen min-h-screen">
<div class="relative flex flex-wrap items-center w-full min-h-full px-4 py-6 sm:px-6 md:px-8">
<div class="relative w-full max-w-screen-lg mx-auto">
<div class="flex flex-col items-center justify-center min-h-full gap-4">
{ children... }
</div>
</div>
</div>
</div>
}
// Tailwind css dependencies
templ Tailwind() {
@tailwindHandle.Once() {
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
}
}
// Nav is a component that renders the navigation bar
templ Nav() {
<nav class="absolute inset-x-0 top-0 z-[100] flex h-16 w-full items-center justify-between px-4 py-4 sm:px-6 md:px-8">
{ children... }
</nav>
}
// NavCTA is a component that renders a call to action button
templ NavCTA(href string, text string) {
<sl-button type="primary" href={ href }>{ text }</sl-button>
}
// NavItem is a component that renders a navigation item
templ NavItem(href string, text string) {
<sl-button type="text" href={ href }>{ text }</sl-button>
}
// NavLogo is a component that renders a logo
templ NavLogo(title string) {
<a href="/" class="flex items-center justify-center gap-1.5 px-2 py-2">
{ children... }
<span class="text-xl font-bold pb-1.5">{ title }</span>
</a>
}
// NavLeft is a component that renders the left side of the navigation bar
templ NavLeft() {
<div class="flex items-center gap-4">
{ children... }
</div>
}
templ NavRight() {
<div class="flex items-center gap-4">
{ children... }
</div>
}
// Rows is a component that renders a responsive flex container that wraps on mobile
templ Rows() {
<div class="flex flex-col w-full gap-3 sm:flex-row sm:flex-wrap sm:gap-4">
{ children... }
</div>
}
templ Separator(text string) {
<div class="relative py-6">
<div class="absolute inset-0 flex items-center"><span class="w-full border-t"></span></div>
<div class="relative flex justify-center text-xs uppercase">
<span class="px-2 text-neutral-500">{ text }</span>
</div>
</div>
}

View File

@@ -1,633 +0,0 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.857
package ui
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
// Body is a component that renders the body tag
func Body() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<body>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</body>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// Head is a component that renders the head of the document
func Head() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var2 := templ.GetChildren(ctx)
if templ_7745c5c3_Var2 == nil {
templ_7745c5c3_Var2 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = ApexCharts().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = Helia().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = Dexie().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = Htmx().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = Tailwind().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = Shoelace().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = DefaultStyles().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var2.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "</head>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// HTML is a component that renders the html tag
func HTML() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
if templ_7745c5c3_Var3 == nil {
templ_7745c5c3_Var3 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<!doctype html><html lang=\"en\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var3.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "</html>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// Columns is a component that renders a responsive flex container that stacks on mobile
func Columns() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var4 := templ.GetChildren(ctx)
if templ_7745c5c3_Var4 == nil {
templ_7745c5c3_Var4 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "<div class=\"flex flex-col h-full w-full gap-4 md:gap-6 md:flex-row md:flex-wrap\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var4.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// Container is a component that renders a full screen container
func Container() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var5 := templ.GetChildren(ctx)
if templ_7745c5c3_Var5 == nil {
templ_7745c5c3_Var5 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "<div id=\"container\" class=\"flex fixed inset-0 z-[99] w-screen min-h-screen\"><div class=\"relative flex flex-wrap items-center w-full min-h-full px-4 py-6 sm:px-6 md:px-8\"><div class=\"relative w-full max-w-screen-lg mx-auto\"><div class=\"flex flex-col items-center justify-center min-h-full gap-4\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var5.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "</div></div></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// Tailwind css dependencies
func Tailwind() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var6 := templ.GetChildren(ctx)
if templ_7745c5c3_Var6 == nil {
templ_7745c5c3_Var6 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var7 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "<script src=\"https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4\"></script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = tailwindHandle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var7), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// Nav is a component that renders the navigation bar
func Nav() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var8 := templ.GetChildren(ctx)
if templ_7745c5c3_Var8 == nil {
templ_7745c5c3_Var8 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "<nav class=\"absolute inset-x-0 top-0 z-[100] flex h-16 w-full items-center justify-between px-4 py-4 sm:px-6 md:px-8\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var8.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "</nav>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// NavCTA is a component that renders a call to action button
func NavCTA(href string, text string) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var9 := templ.GetChildren(ctx)
if templ_7745c5c3_Var9 == nil {
templ_7745c5c3_Var9 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "<sl-button type=\"primary\" href=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var10 string
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(href)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/ui/layout.templ`, Line: 70, Col: 38}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(text)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/ui/layout.templ`, Line: 70, Col: 47}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "</sl-button>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// NavItem is a component that renders a navigation item
func NavItem(href string, text string) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var12 := templ.GetChildren(ctx)
if templ_7745c5c3_Var12 == nil {
templ_7745c5c3_Var12 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "<sl-button type=\"text\" href=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var13 string
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(href)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/ui/layout.templ`, Line: 75, Col: 35}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var14 string
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(text)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/ui/layout.templ`, Line: 75, Col: 44}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "</sl-button>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// NavLogo is a component that renders a logo
func NavLogo(title string) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var15 := templ.GetChildren(ctx)
if templ_7745c5c3_Var15 == nil {
templ_7745c5c3_Var15 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "<a href=\"/\" class=\"flex items-center justify-center gap-1.5 px-2 py-2\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var15.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "<span class=\"text-xl font-bold pb-1.5\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var16 string
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(title)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/ui/layout.templ`, Line: 82, Col: 48}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "</span></a>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// NavLeft is a component that renders the left side of the navigation bar
func NavLeft() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var17 := templ.GetChildren(ctx)
if templ_7745c5c3_Var17 == nil {
templ_7745c5c3_Var17 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "<div class=\"flex items-center gap-4\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var17.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func NavRight() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var18 := templ.GetChildren(ctx)
if templ_7745c5c3_Var18 == nil {
templ_7745c5c3_Var18 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "<div class=\"flex items-center gap-4\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var18.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// Rows is a component that renders a responsive flex container that wraps on mobile
func Rows() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var19 := templ.GetChildren(ctx)
if templ_7745c5c3_Var19 == nil {
templ_7745c5c3_Var19 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "<div class=\"flex flex-col w-full gap-3 sm:flex-row sm:flex-wrap sm:gap-4\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var19.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Separator(text string) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var20 := templ.GetChildren(ctx)
if templ_7745c5c3_Var20 == nil {
templ_7745c5c3_Var20 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "<div class=\"relative py-6\"><div class=\"absolute inset-0 flex items-center\"><span class=\"w-full border-t\"></span></div><div class=\"relative flex justify-center text-xs uppercase\"><span class=\"px-2 text-neutral-500\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var21 string
templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(text)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/ui/layout.templ`, Line: 110, Col: 45}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "</span></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View File

@@ -1,139 +0,0 @@
package ui
import "fmt"
var (
apexChartsHandle = templ.NewOnceHandle()
d3Handle = templ.NewOnceHandle()
dexieHandle = templ.NewOnceHandle()
heliaHandle = templ.NewOnceHandle()
htmxHandle = templ.NewOnceHandle()
tailwindHandle = templ.NewOnceHandle()
)
// ApexCharts is a component that renders the ApexCharts.js library
templ ApexCharts() {
@apexChartsHandle.Once() {
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
}
}
// d3 is a component that renders the D3.js library
templ D3() {
@d3Handle.Once() {
<script type="module">
import * as d3 from "https://cdn.jsdelivr.net/npm/d3@7/+esm";
</script>
}
}
// dexie is a component that renders the Dexie.js library
templ Dexie() {
@dexieHandle.Once() {
<script src={ jsDelivrURL("dexie", "4.0.10", "dist/dexie.min.js") }></script>
<script src={ jsDelivrURL("dexie-export-import", "4.1.4", "dist/dexie-export-import.min.js") }></script>
}
}
// In package deps
templ Helia() {
@heliaHandle.Once() {
<script src="https://unpkg.com/@helia/unixfs/dist/index.min.js"></script>
<script src="https://unpkg.com/blockstore-core/dist/index.min.js"></script>
<script src="https://unpkg.com/datastore-core/dist/index.min.js"></script>
<script src="https://unpkg.com/helia/dist/index.min.js"></script>
<script>
// Time formatting helper
function ms2TimeString(a) {
const k = a % 1e3
const s = a / 1e3 % 60 | 0
const m = a / 6e4 % 60 | 0
const h = a / 36e5 % 24 | 0
return (h ? (h < 10 ? '0' + h : h) + ':' : '00:') +
(m < 10 ? 0 : '') + m + ':' +
(s < 10 ? 0 : '') + s + ':' +
(k < 100 ? k < 10 ? '00' : 0 : '') + k
}
// Log management
const getLogLineEl = (msg) => {
const logLine = document.createElement('span')
logLine.innerHTML = `${ms2TimeString(performance.now())} - ${msg}`
return logLine
}
const addToLog = (msg) => {
const logEl = document.getElementById('runningLog')
if (logEl) {
logEl.appendChild(getLogLineEl(msg))
logEl.appendChild(document.createElement('br'))
}
}
// Peer management
window.discoveredPeers = new Map()
const updateConnectedPeers = () => {
if (!window.helia || !window.helia.libp2p) return
const peers = window.helia.libp2p.getPeers()
const connectedPeerCountEl = document.getElementById('connectedPeerCount')
const connectedPeersListEl = document.getElementById('connectedPeersList')
if (connectedPeerCountEl) {
connectedPeerCountEl.innerHTML = peers.length
}
if (connectedPeersListEl) {
connectedPeersListEl.innerHTML = ''
for (const peer of peers) {
const peerEl = document.createElement('li')
peerEl.innerText = peer.toString()
connectedPeersListEl.appendChild(peerEl)
}
}
}
const updateDiscoveredPeers = () => {
const discoveredPeerCountEl = document.getElementById('discoveredPeerCount')
if (discoveredPeerCountEl) {
discoveredPeerCountEl.innerHTML = window.discoveredPeers.size
}
}
// Helia node instantiation
let heliaInstance = null
window.instantiateHeliaNode = async () => {
// application-specific data lives in the datastore
const datastore = new DatastoreCore.MemoryDatastore()
const blockstore = new BlockstoreCore.MemoryBlockstore()
if (heliaInstance != null) {
return heliaInstance
}
heliaInstance = await Helia.createHelia({
datastore,
blockstore
})
addToLog('Created Helia instance')
return heliaInstance
}
</script>
}
}
// Htmx is a component that renders the Htmx.js library
templ Htmx() {
@htmxHandle.Once() {
<script src={ jsDelivrURL("htmx.org", "1.9.12", "dist/htmx.min.js") }></script>
<script src={ jsDelivrURL("htmx-ext-include-vals", "2.0.0", "include-vals.min.js") }></script>
<script src={ jsDelivrURL("htmx-ext-path-params", "2.0.0", "path-params.min.js") }></script>
<script src={ jsDelivrURL("htmx-ext-alpine-morph", "2.0.0", "alpine-morph.min.js") }></script>
<script src={ jsDelivrURL("htmx-ext-sse", "2.2.2", "sse.min.js") }></script>
<script src={ jsDelivrURL("htmx-ext-ws", "2.0.2", "ws.min.js") }></script>
}
}
// jsDelivrURL returns the URL of a package on jsDelivr
func jsDelivrURL(pkg string, version string, path string) string {
return fmt.Sprintf("https://cdn.jsdelivr.net/npm/%s/%s/%s", pkg, version, path)
}

View File

@@ -1,371 +0,0 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.857
package ui
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import "fmt"
var (
apexChartsHandle = templ.NewOnceHandle()
d3Handle = templ.NewOnceHandle()
dexieHandle = templ.NewOnceHandle()
heliaHandle = templ.NewOnceHandle()
htmxHandle = templ.NewOnceHandle()
tailwindHandle = templ.NewOnceHandle()
)
// ApexCharts is a component that renders the ApexCharts.js library
func ApexCharts() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<script src=\"https://cdn.jsdelivr.net/npm/apexcharts\"></script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = apexChartsHandle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// d3 is a component that renders the D3.js library
func D3() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
if templ_7745c5c3_Var3 == nil {
templ_7745c5c3_Var3 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var4 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<script type=\"module\">\n import * as d3 from \"https://cdn.jsdelivr.net/npm/d3@7/+esm\";\n\t </script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = d3Handle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var4), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// dexie is a component that renders the Dexie.js library
func Dexie() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var5 := templ.GetChildren(ctx)
if templ_7745c5c3_Var5 == nil {
templ_7745c5c3_Var5 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var6 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<script src=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(jsDelivrURL("dexie", "4.0.10", "dist/dexie.min.js"))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/ui/providers.templ`, Line: 33, Col: 67}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "\"></script> <script src=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(jsDelivrURL("dexie-export-import", "4.1.4", "dist/dexie-export-import.min.js"))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/ui/providers.templ`, Line: 34, Col: 94}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\"></script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = dexieHandle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var6), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// In package deps
func Helia() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var9 := templ.GetChildren(ctx)
if templ_7745c5c3_Var9 == nil {
templ_7745c5c3_Var9 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var10 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "<script src=\"https://unpkg.com/@helia/unixfs/dist/index.min.js\"></script> <script src=\"https://unpkg.com/blockstore-core/dist/index.min.js\"></script> <script src=\"https://unpkg.com/datastore-core/dist/index.min.js\"></script> <script src=\"https://unpkg.com/helia/dist/index.min.js\"></script> <script>\n // Time formatting helper\n function ms2TimeString(a) {\n const k = a % 1e3\n const s = a / 1e3 % 60 | 0\n const m = a / 6e4 % 60 | 0\n const h = a / 36e5 % 24 | 0\n\n return (h ? (h < 10 ? '0' + h : h) + ':' : '00:') +\n (m < 10 ? 0 : '') + m + ':' +\n (s < 10 ? 0 : '') + s + ':' +\n (k < 100 ? k < 10 ? '00' : 0 : '') + k\n }\n\n // Log management\n const getLogLineEl = (msg) => {\n const logLine = document.createElement('span')\n logLine.innerHTML = `${ms2TimeString(performance.now())} - ${msg}`\n return logLine\n }\n \n const addToLog = (msg) => {\n const logEl = document.getElementById('runningLog')\n if (logEl) {\n logEl.appendChild(getLogLineEl(msg))\n logEl.appendChild(document.createElement('br'))\n }\n }\n\n // Peer management\n window.discoveredPeers = new Map()\n const updateConnectedPeers = () => {\n if (!window.helia || !window.helia.libp2p) return\n \n const peers = window.helia.libp2p.getPeers()\n const connectedPeerCountEl = document.getElementById('connectedPeerCount')\n const connectedPeersListEl = document.getElementById('connectedPeersList')\n \n if (connectedPeerCountEl) {\n connectedPeerCountEl.innerHTML = peers.length\n }\n \n if (connectedPeersListEl) {\n connectedPeersListEl.innerHTML = ''\n \n for (const peer of peers) {\n const peerEl = document.createElement('li')\n peerEl.innerText = peer.toString()\n connectedPeersListEl.appendChild(peerEl)\n }\n }\n }\n const updateDiscoveredPeers = () => {\n const discoveredPeerCountEl = document.getElementById('discoveredPeerCount')\n if (discoveredPeerCountEl) {\n discoveredPeerCountEl.innerHTML = window.discoveredPeers.size\n }\n }\n // Helia node instantiation\n let heliaInstance = null\n window.instantiateHeliaNode = async () => {\n // application-specific data lives in the datastore\n const datastore = new DatastoreCore.MemoryDatastore()\n const blockstore = new BlockstoreCore.MemoryBlockstore()\n\n if (heliaInstance != null) {\n return heliaInstance\n }\n heliaInstance = await Helia.createHelia({\n datastore,\n blockstore\n })\n addToLog('Created Helia instance')\n return heliaInstance\n }\n </script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = heliaHandle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var10), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// Htmx is a component that renders the Htmx.js library
func Htmx() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var11 := templ.GetChildren(ctx)
if templ_7745c5c3_Var11 == nil {
templ_7745c5c3_Var11 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var12 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "<script src=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var13 string
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(jsDelivrURL("htmx.org", "1.9.12", "dist/htmx.min.js"))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/ui/providers.templ`, Line: 127, Col: 69}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "\"></script> <script src=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var14 string
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(jsDelivrURL("htmx-ext-include-vals", "2.0.0", "include-vals.min.js"))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/ui/providers.templ`, Line: 128, Col: 84}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\"></script> <script src=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var15 string
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(jsDelivrURL("htmx-ext-path-params", "2.0.0", "path-params.min.js"))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/ui/providers.templ`, Line: 129, Col: 82}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\"></script> <script src=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var16 string
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(jsDelivrURL("htmx-ext-alpine-morph", "2.0.0", "alpine-morph.min.js"))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/ui/providers.templ`, Line: 130, Col: 84}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "\"></script> <script src=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var17 string
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(jsDelivrURL("htmx-ext-sse", "2.2.2", "sse.min.js"))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/ui/providers.templ`, Line: 131, Col: 66}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "\"></script> <script src=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var18 string
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(jsDelivrURL("htmx-ext-ws", "2.0.2", "ws.min.js"))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/ui/providers.templ`, Line: 132, Col: 64}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "\"></script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = htmxHandle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var12), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// jsDelivrURL returns the URL of a package on jsDelivr
func jsDelivrURL(pkg string, version string, path string) string {
return fmt.Sprintf("https://cdn.jsdelivr.net/npm/%s/%s/%s", pkg, version, path)
}
var _ = templruntime.GeneratedTemplate

View File

@@ -1,54 +0,0 @@
package ui
templ DefaultStyles() {
<style>
@theme {
--color-primary: #17c2ff;
}
@keyframes fade-in {
from { opacity: 0; }
}
@keyframes fade-out {
to { opacity: 0; }
}
@keyframes slide-from-right {
from { transform: translateX(90px); }
}
@keyframes slide-to-left {
to { transform: translateX(-90px); }
}
.slide-it {
view-transition-name: slide-it;
}
::view-transition-old(slide-it) {
animation: 180ms cubic-bezier(0.4, 0, 1, 1) both fade-out,
600ms cubic-bezier(0.4, 0, 0.2, 1) both slide-to-left;
}
::view-transition-new(slide-it) {
animation: 420ms cubic-bezier(0, 0, 0.2, 1) 90ms both fade-in,
600ms cubic-bezier(0.4, 0, 0.2, 1) both slide-from-right;
}
</style>
}
// Shoelace dependencies
templ Shoelace() {
<link
rel="stylesheet"
media="(prefers-color-scheme:light)"
href="https://cdn.jsdelivr.net/npm/sonr-shoelace/cdn/themes/light.css"
/>
<link
rel="stylesheet"
media="(prefers-color-scheme:dark)"
href="https://cdn.jsdelivr.net/npm/sonr-shoelace/cdn/themes/dark.css"
onload="document.documentElement.classList.add('sl-theme-dark');"
/>
<script type="module" src="https://cdn.jsdelivr.net/npm/sonr-shoelace/cdn/shoelace-autoloader.js"></script>
}

View File

@@ -1,70 +0,0 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.857
package ui
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
func DefaultStyles() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<style>\n\t @theme {\n --color-primary: #17c2ff;\n }\n\n \t\t@keyframes fade-in {\n \t\tfrom { opacity: 0; }\n \t\t}\n\n \t\t@keyframes fade-out {\n \t\tto { opacity: 0; }\n \t\t}\n\n \t\t@keyframes slide-from-right {\n \t\tfrom { transform: translateX(90px); }\n \t\t}\n\n \t\t@keyframes slide-to-left {\n \t\tto { transform: translateX(-90px); }\n \t\t}\n\n \t\t.slide-it {\n \t\tview-transition-name: slide-it;\n \t\t}\n\n \t\t::view-transition-old(slide-it) {\n \t\tanimation: 180ms cubic-bezier(0.4, 0, 1, 1) both fade-out,\n \t\t600ms cubic-bezier(0.4, 0, 0.2, 1) both slide-to-left;\n \t\t}\n \t\t::view-transition-new(slide-it) {\n \t\tanimation: 420ms cubic-bezier(0, 0, 0.2, 1) 90ms both fade-in,\n \t\t600ms cubic-bezier(0.4, 0, 0.2, 1) both slide-from-right;\n \t\t}\n\t\t</style>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// Shoelace dependencies
func Shoelace() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var2 := templ.GetChildren(ctx)
if templ_7745c5c3_Var2 == nil {
templ_7745c5c3_Var2 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<link rel=\"stylesheet\" media=\"(prefers-color-scheme:light)\" href=\"https://cdn.jsdelivr.net/npm/sonr-shoelace/cdn/themes/light.css\"><link rel=\"stylesheet\" media=\"(prefers-color-scheme:dark)\" href=\"https://cdn.jsdelivr.net/npm/sonr-shoelace/cdn/themes/dark.css\" onload=\"document.documentElement.classList.add(&#39;sl-theme-dark&#39;);\"><script type=\"module\" src=\"https://cdn.jsdelivr.net/npm/sonr-shoelace/cdn/shoelace-autoloader.js\"></script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View File

@@ -1,83 +0,0 @@
package authz
import (
"crypto/sha256"
"github.com/golang-jwt/jwt"
)
// MPCSigningMethod implements the SigningMethod interface for MPC-based signing
type MPCSigningMethod struct {
Name string
ks ucanKeyshare
}
// NewJWTSigningMethod creates a new MPC signing method with the given keyshare source
func NewJWTSigningMethod(name string, ks ucanKeyshare) *MPCSigningMethod {
return &MPCSigningMethod{
Name: name,
ks: ks,
}
}
// Alg returns the signing method's name
func (m *MPCSigningMethod) Alg() string {
return m.Name
}
// Verify verifies the signature using the MPC public key
func (m *MPCSigningMethod) Verify(signingString, signature string, key any) error {
// // Decode the signature
// sig, err := base64.RawURLEncoding.DecodeString(signature)
// if err != nil {
// return err
// }
//
// // Hash the signing string
// hasher := sha256.New()
// hasher.Write([]byte(signingString))
// digest := hasher.Sum(nil)
// valid, err := m.ks.valShare.PublicKey().Verify(digest, sig)
// if !valid || err != nil {
// return fmt.Errorf("invalid signature")
// }
return nil
}
// Sign signs the data using MPC
func (m *MPCSigningMethod) Sign(signingString string, key any) (string, error) {
// Hash the signing string
hasher := sha256.New()
hasher.Write([]byte(signingString))
// digest := hasher.Sum(nil)
//
// // Create signing functions
// signFunc, err := m.ks.userShare.SignFunc(digest)
// if err != nil {
// return "", fmt.Errorf("failed to create sign function: %w", err)
// }
//
// valSignFunc, err := m.ks.valShare.SignFunc(digest)
// if err != nil {
// return "", fmt.Errorf("failed to create validator sign function: %w", err)
// }
// // Run the signing protocol
// sig, err := mpc.ExecuteSigning(valSignFunc, signFunc)
// if err != nil {
// return "", fmt.Errorf("failed to run sign protocol: %w", err)
// }
// Encode the signature
// encoded := base64.RawURLEncoding.EncodeToString(sig)
return "", nil
}
func init() {
// Register the MPC signing method
jwt.RegisterSigningMethod("MPC256", func() jwt.SigningMethod {
return &MPCSigningMethod{
Name: "MPC256",
}
})
}

View File

@@ -1,126 +0,0 @@
package authz
import (
"context"
"fmt"
"time"
"github.com/sonr-io/crypto/keys"
"github.com/sonr-io/crypto/ucan"
"lukechampine.com/blake3"
)
type KeyshareSource interface {
ucan.Source
Address() string
Issuer() string
ChainCode() ([]byte, error)
OriginToken() (*Token, error)
SignData(data []byte) ([]byte, error)
VerifyData(data []byte, sig []byte) (bool, error)
UCANParser() *ucan.TokenParser
}
// func NewSource(ks mpc.KeyEnclave) (KeyshareSource, error) {
// iss, addr, err := getIssuerDID(val.PublicKey())
// if err != nil {
// return nil, err
// }
//
// return ucanKeyshare{
// issuerDID: iss,
// addr: addr,
// }, nil
// }
//
// Address returns the address of the keyshare
func (k ucanKeyshare) Address() string {
return k.addr
}
// Issuer returns the DID of the issuer of the keyshare
func (k ucanKeyshare) Issuer() string {
return k.issuerDID
}
// ChainCode returns the chain code of the keyshare
func (k ucanKeyshare) ChainCode() ([]byte, error) {
sig, err := k.SignData([]byte(k.addr))
if err != nil {
return nil, err
}
hash := blake3.Sum256(sig)
// Return the first 32 bytes of the hash
return hash[:32], nil
}
// DefaultOriginToken returns a default token with the keyshare's issuer as the audience
func (k ucanKeyshare) OriginToken() (*Token, error) {
// att := ucan.NewSmartAccount(k.addr)
zero := time.Time{}
// return k.NewOriginToken(k.issuerDID, att, nil, zero, zero)
return k.newToken(k.issuerDID, nil, nil, nil, zero, zero)
}
func (k ucanKeyshare) SignData(data []byte) ([]byte, error) {
// // Create signing functions
// signFunc, err := k.userShare.SignFunc(data)
// if err != nil {
// return nil, fmt.Errorf("failed to create sign function: %w", err)
// }
//
// valSignFunc, err := k.valShare.SignFunc(data)
// if err != nil {
// return nil, fmt.Errorf("failed to create validator sign function: %w", err)
// }
// Run the signing protocol
// return mpc.ExecuteSigning(valSignFunc, signFunc)
return nil, nil
}
func (k ucanKeyshare) VerifyData(data []byte, sig []byte) (bool, error) {
return false, nil
// return k.valShare.PublicKey().Verify(data, sig)
}
// TokenParser returns a token parser that can be used to parse tokens
func (k ucanKeyshare) UCANParser() *ucan.TokenParser {
caps := ucan.AccountPermissions.GetCapabilities()
ac := func(m map[string]any) (ucan.Attenuation, error) {
var (
cap string
rsc ucan.Resource
)
for key, vali := range m {
val, ok := vali.(string)
if !ok {
return ucan.Attenuation{}, fmt.Errorf(`expected attenuation value to be a string`)
}
if key == ucan.CapKey {
cap = val
} else {
}
}
return ucan.Attenuation{
Rsc: rsc,
Cap: caps.Cap(cap),
}, nil
}
store := ucan.NewMemTokenStore()
return ucan.NewTokenParser(ac, customDIDPubKeyResolver{}, store.(ucan.CIDBytesResolver))
}
// customDIDPubKeyResolver implements the DIDPubKeyResolver interface without
// any network backing. Works if the key string given contains the public key
// itself
type customDIDPubKeyResolver struct{}
// ResolveDIDKey extracts a public key from a did:key string
func (customDIDPubKeyResolver) ResolveDIDKey(ctx context.Context, didStr string) (keys.DID, error) {
return keys.Parse(didStr)
}

View File

@@ -1,92 +0,0 @@
package authz
import (
"fmt"
"time"
"github.com/golang-jwt/jwt"
"github.com/sonr-io/crypto/ucan"
)
type (
Token = ucan.Token
Claims = ucan.Claims
Proof = ucan.Proof
Attenuations = ucan.Attenuations
Fact = ucan.Fact
)
var (
UCANVersion = ucan.UCANVersion
UCANVersionKey = ucan.UCANVersionKey
PrfKey = ucan.PrfKey
FctKey = ucan.FctKey
AttKey = ucan.AttKey
CapKey = ucan.CapKey
)
type ucanKeyshare struct {
addr string
issuerDID string
}
func (k ucanKeyshare) NewOriginToken(audienceDID string, att Attenuations, fct []Fact, notBefore, expires time.Time) (*ucan.Token, error) {
return k.newToken(audienceDID, nil, att, fct, notBefore, expires)
}
func (k ucanKeyshare) NewAttenuatedToken(parent *Token, audienceDID string, att ucan.Attenuations, fct []ucan.Fact, nbf, exp time.Time) (*Token, error) {
if !parent.Attenuations.Contains(att) {
return nil, fmt.Errorf("scope of ucan attenuations must be less than it's parent")
}
return k.newToken(audienceDID, append(parent.Proofs, Proof(parent.Raw)), att, fct, nbf, exp)
}
func (k ucanKeyshare) newToken(audienceDID string, prf []Proof, att Attenuations, fct []Fact, nbf, exp time.Time) (*ucan.Token, error) {
t := jwt.New(NewJWTSigningMethod("MPC256", k))
// if _, err := did.Parse(audienceDID); err != nil {
// return nil, fmt.Errorf("invalid audience DID: %w", err)
// }
t.Header[UCANVersionKey] = UCANVersion
var (
nbfUnix int64
expUnix int64
)
if !nbf.IsZero() {
nbfUnix = nbf.Unix()
}
if !exp.IsZero() {
expUnix = exp.Unix()
}
// set our claims
t.Claims = &Claims{
StandardClaims: &jwt.StandardClaims{
Issuer: k.issuerDID,
Audience: audienceDID,
NotBefore: nbfUnix,
// set the expire time
// see http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4.1.4
ExpiresAt: expUnix,
},
Attenuations: att,
Facts: fct,
Proofs: prf,
}
raw, err := t.SignedString(nil)
if err != nil {
return nil, err
}
return &Token{
Raw: raw,
Attenuations: att,
Facts: fct,
Proofs: prf,
}, nil
}

View File

@@ -1,66 +0,0 @@
//go:build js && wasm
// +build js,wasm
package database
import (
"database/sql"
"github.com/sonr-io/motr/internal/db/activity"
"github.com/sonr-io/motr/internal/db/network"
"github.com/sonr-io/motr/internal/db/users"
_ "github.com/syumai/workers/cloudflare/d1"
)
var (
activityDB activity.Querier
networkDB network.Querier
userDB users.Querier
)
const (
kActivityBinding = "ACTIVITY_DB"
kNetworkBinding = "NETWORK_DB"
kUsersBinding = "USERS_DB"
)
func IsReady() bool {
return activityDB != nil && networkDB != nil && userDB != nil
}
func (c *connection) initialize() {
c.activity = activity.New(openD1(kActivityBinding))
c.network = network.New(openD1(kNetworkBinding))
c.users = users.New(openD1(kUsersBinding))
c.ready = true
}
func openD1(name string) *sql.DB {
db, err := sql.Open("d1", name)
if err != nil {
panic(err)
}
return db
}
func Activity() activity.Querier {
if activityDB == nil {
panic("activityDB is not initialized")
}
return activityDB
}
func Network() network.Querier {
if networkDB == nil {
panic("networkDB is not initialized")
}
return networkDB
}
func Users() users.Querier {
if userDB == nil {
panic("userDB is not initialized")
}
return userDB
}

View File

@@ -1,54 +0,0 @@
//go:build js && wasm
// +build js,wasm
package database
import (
"github.com/sonr-io/motr/internal/db/activity"
"github.com/sonr-io/motr/internal/db/network"
"github.com/sonr-io/motr/internal/db/users"
)
// connection is a database context
type Connection interface {
IsReady() bool
Activity() activity.Querier
Network() network.Querier
Users() users.Querier
}
type connection struct {
activity activity.Querier
network network.Querier
users users.Querier
ready bool
}
func (q *connection) IsReady() bool {
return q.ready
}
func (q *connection) Activity() activity.Querier {
return q.activity
}
func (q *connection) Network() network.Querier {
return q.network
}
func (q *connection) Users() users.Querier {
return q.users
}
// open creates a new database connection
func open() Connection {
conn := &connection{
ready: false,
}
conn.initialize()
activityDB = conn.Activity()
networkDB = conn.Network()
userDB = conn.Users()
return conn
}

View File

@@ -1,44 +0,0 @@
//go:build js && wasm
// +build js,wasm
package database
import (
"errors"
"github.com/labstack/echo/v4"
)
type Context interface {
echo.Context
Connection
}
// context is a database context
type context struct {
echo.Context
Connection
}
// Middleware is a middleware that adds a new key to the context
func Middleware() echo.MiddlewareFunc {
conn := open()
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
ctx := &context{
Context: c,
Connection: conn,
}
return next(ctx)
}
}
}
// Unwrap unwraps the session context
func Unwrap(c echo.Context) (Context, error) {
cc := c.(*context)
if cc == nil {
return nil, errors.New("failed to unwrap session context")
}
return cc, nil
}

View File

@@ -1,32 +0,0 @@
//go:build js && wasm
// +build js,wasm
package kvstore
var (
sessionsKV Store
handlesKV Store
)
const (
kHandlesBinding = "HANDLES_KV"
kSessionsBinding = "SESSIONS_KV"
)
func IsReady() bool {
return sessionsKV != nil && handlesKV != nil
}
func Sessions() Store {
if sessionsKV == nil {
panic("sessionsKV is not initialized")
}
return sessionsKV
}
func Handles() Store {
if handlesKV == nil {
panic("handlesKV is not initialized")
}
return handlesKV
}

View File

@@ -1,46 +0,0 @@
//go:build js && wasm
// +build js,wasm
package kvstore
// connection is a database context
type Connection interface {
Handles() Store
Sessions() Store
IsReady() bool
}
type connection struct {
ready bool
handles Store
sessions Store
}
func (q *connection) initialize() {
q.handles = openStore(kHandlesBinding)
q.sessions = openStore(kSessionsBinding)
q.ready = true
}
func (q *connection) IsReady() bool {
return q.ready
}
func (q *connection) Handles() Store {
return q.handles
}
func (q *connection) Sessions() Store {
return q.sessions
}
// open creates a new database connection
func open() Connection {
conn := &connection{
ready: false,
}
conn.initialize()
handlesKV = conn.Handles()
sessionsKV = conn.Sessions()
return conn
}

View File

@@ -1,44 +0,0 @@
//go:build js && wasm
// +build js,wasm
package kvstore
import (
"errors"
"github.com/labstack/echo/v4"
)
type Context interface {
echo.Context
Connection
}
// context is a database context
type context struct {
echo.Context
Connection
}
// Middleware is a middleware that adds a new key to the context
func Middleware() echo.MiddlewareFunc {
conn := open()
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
ctx := &context{
Context: c,
Connection: conn,
}
return next(ctx)
}
}
}
// Unwrap unwraps the session context
func Unwrap(c echo.Context) (Context, error) {
cc := c.(*context)
if cc == nil {
return nil, errors.New("failed to unwrap session context")
}
return cc, nil
}

View File

@@ -1,95 +0,0 @@
//go:build js && wasm
// +build js,wasm
package kvstore
import (
"encoding/json"
"strconv"
"github.com/syumai/workers/cloudflare/kv"
)
type Store interface {
Get(key string) (string, error)
Exists(key string) bool
Set(key string, value string) error
Delete(key string) error
Namespace() *kv.Namespace
GetInt(key string) (int, error)
SetInt(key string, value int) error
GetJSON(key string, v any) error
SetJSON(key string, v any) error
}
func openStore(name string) Store {
k, err := kv.NewNamespace(name)
if err != nil {
panic(err)
}
return &store{
namespace: k,
}
}
type store struct {
namespace *kv.Namespace
}
func (s *store) Namespace() *kv.Namespace {
return s.namespace
}
func (s *store) Get(key string) (string, error) {
return s.namespace.GetString(key, nil)
}
func (s *store) Exists(key string) bool {
_, err := s.namespace.GetString(key, nil)
return err == nil
}
func (s *store) Set(key string, value string) error {
return s.namespace.PutString(key, value, nil)
}
func (s *store) Delete(key string) error {
return s.namespace.Delete(key)
}
func (s *store) GetInt(key string) (int, error) {
v, err := s.namespace.GetString(key, nil)
if err != nil {
return 0, err
}
i, err := strconv.Atoi(v)
if err != nil {
return 0, err
}
return i, nil
}
func (s *store) SetInt(key string, value int) error {
return s.namespace.PutString(key, strconv.Itoa(value), nil)
}
func (s *store) GetJSON(key string, v any) error {
jsonString, err := s.namespace.GetString(key, nil)
if err != nil {
return err
}
err = json.Unmarshal([]byte(jsonString), v)
if err != nil {
return err
}
return nil
}
func (s *store) SetJSON(key string, v any) error {
jsonString, err := json.Marshal(v)
if err != nil {
return err
}
s.namespace.PutString(key, string(jsonString), nil)
return nil
}

View File

@@ -1,41 +0,0 @@
package render
import (
"bytes"
"github.com/a-h/templ"
"github.com/labstack/echo/v4"
)
type (
EchoView func(c echo.Context) error
EchoViewFunc func(c echo.Context, b templ.Component) error
EchoPartialView func(c echo.Context) templ.Component
)
func Page(cmp templ.Component) echo.HandlerFunc {
return func(c echo.Context) error {
return Component(c, cmp)
}
}
func Component(c echo.Context, cmp templ.Component) error {
// Create a buffer to store the rendered HTML
buf := &bytes.Buffer{}
// Render the component to the buffer
err := cmp.Render(c.Request().Context(), buf)
if err != nil {
return err
}
// Set the content type
c.Response().Header().Set(echo.HeaderContentType, echo.MIMETextHTML)
// Write the buffered content to the response
_, err = c.Response().Write(buf.Bytes())
if err != nil {
return err
}
c.Response().WriteHeader(200)
return nil
}

View File

@@ -1,37 +0,0 @@
//go:build js && wasm
// +build js,wasm
package session
import (
"github.com/labstack/echo/v4"
)
// Context is a session context
type Context struct {
echo.Context
ID string `json:"id"`
}
// Middleware is a middleware that adds a new key to the context
func Middleware() echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
id := DetermineID(c)
ctx := &Context{
Context: c,
ID: id,
}
return next(ctx)
}
}
}
// Unwrap unwraps the session context
func Unwrap(c echo.Context) *Context {
cc := c.(*Context)
if cc == nil {
panic("failed to unwrap session context")
}
return cc
}

View File

@@ -1,72 +0,0 @@
//go:build js && wasm
// +build js,wasm
package session
import (
"time"
"github.com/labstack/echo/v4"
"github.com/segmentio/ksuid"
"github.com/sonr-io/motr/middleware/kvstore"
"github.com/sonr-io/motr/pkg/cookies"
)
const kDefaultSessionTTL = 1 * time.Hour
func DetermineID(c echo.Context) string {
if ok := cookies.SessionID.Exists(c); ok {
c.Echo().Logger.Debug("Has session ID in cookie")
if checkSessionTTL(c) {
sessionID, err := cookies.SessionID.Read(c)
if err != nil {
sessionID = initNewID(c)
}
return sessionID
}
c.Echo().Logger.Debug("Session TTL expired, writing new session ID to cookie")
cookies.SessionID.Write(c, initNewID(c))
return getIDFromCookie(c)
}
c.Echo().Logger.Debug("Has session ID in cookie")
sessionID, err := cookies.SessionID.Read(c)
if err != nil {
sessionID = initNewID(c)
}
return sessionID
}
func initNewID(c echo.Context) string {
id := ksuid.New().String()
cookies.SessionID.Write(c, id)
ttl := time.Now().Add(kDefaultSessionTTL)
kvstore.Sessions().SetInt(id, int(ttl.Unix()))
c.Echo().Logger.Debug("Wrote new session ID to cookie")
return id
}
func checkSessionTTL(c echo.Context) bool {
ttl := getSessionTTL(c)
if ttl < int(time.Now().Unix()) {
c.Echo().Logger.Debug("Session TTL expired")
return false
}
return true
}
func getIDFromCookie(c echo.Context) string {
sessionID, err := cookies.SessionID.Read(c)
if err != nil {
sessionID = initNewID(c)
}
return sessionID
}
func getSessionTTL(c echo.Context) int {
ttl, err := kvstore.Sessions().GetInt(getIDFromCookie(c))
if err != nil {
ttl = int(time.Now().Add(kDefaultSessionTTL).Unix())
kvstore.Sessions().SetInt(getIDFromCookie(c), ttl)
}
return ttl
}

View File

@@ -1,7 +0,0 @@
package webauthn
type RegisterOptions struct {
Address string
Handle string
Challenge string
}

View File

@@ -1,9 +0,0 @@
package webauthn
type LoginOptions struct {
Account string
Handle string
HelpText string
Label string
Challenge string
}

View File

@@ -1,35 +0,0 @@
//go:build js && wasm
// +build js,wasm
package webauthn
import (
"errors"
"github.com/labstack/echo/v4"
)
type Context struct {
echo.Context
}
// Middleware is a middleware that adds a new key to the context
func Middleware() echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
ctx := &Context{
Context: c,
}
return next(ctx)
}
}
}
// Unwrap unwraps the session context
func Unwrap(c echo.Context) (*Context, error) {
cc := c.(*Context)
if cc == nil {
return nil, errors.New("failed to unwrap session context")
}
return cc, nil
}

View File

@@ -1,43 +0,0 @@
package webauthn
import models "github.com/sonr-io/motr/internal/db/users"
// Define the credential structure matching our frontend data
type CredentialDescriptor struct {
ID string `json:"id"`
RawID string `json:"rawId"`
Type string `json:"type"`
AuthenticatorAttachment string `json:"authenticatorAttachment"`
Transports string `json:"transports"`
ClientExtensionResults map[string]string `json:"clientExtensionResults"`
Response struct {
AttestationObject string `json:"attestationObject"`
ClientDataJSON string `json:"clientDataJSON"`
} `json:"response"`
}
func (c *CredentialDescriptor) ToModel(handle, origin string) *models.Credential {
return &models.Credential{
Handle: handle,
Origin: origin,
CredentialID: c.ID,
Type: c.Type,
Transports: c.Transports,
AuthenticatorAttachment: c.AuthenticatorAttachment,
}
}
func CredentialArrayToDescriptors(credentials []models.Credential) []*CredentialDescriptor {
var descriptors []*CredentialDescriptor
for _, cred := range credentials {
cd := &CredentialDescriptor{
ID: cred.CredentialID,
RawID: cred.CredentialID,
Type: cred.Type,
AuthenticatorAttachment: cred.AuthenticatorAttachment,
Transports: cred.Transports,
}
descriptors = append(descriptors, cd)
}
return descriptors
}

View File

@@ -1,83 +0,0 @@
package dash
// StatusCard component for displaying Helia node status
templ StatusCard() {
<div class="p-4 flex flex-col bg-white border border-gray-200 rounded-xl dark:bg-neutral-800 dark:border-neutral-700">
<div class="flex justify-between items-center mb-1">
<h2 class="text-4xl font-semibold text-gray-800 dark:text-neutral-200">
<span id="statusValue">Offline</span>
</h2>
<div class="flex items-center -space-x-2">
<img class="shrink-0 size-7 rounded-full" src="https://images.unsplash.com/photo-1659482633369-9fe69af50bfb?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=facearea&facepad=3&w=320&h=320&q=80" alt="Avatar"/>
</div>
</div>
<h3 class="text-gray-500 dark:text-neutral-500">
Status
</h3>
</div>
}
// NodeIDCard component for displaying Helia node ID
templ NodeIDCard() {
<div>
<div class="p-4 flex flex-col bg-white border border-gray-200 rounded-xl dark:bg-neutral-800 dark:border-neutral-700">
<div class="flex justify-between items-center mb-1">
<h2 class="text-4xl font-semibold text-gray-800 dark:text-neutral-200">
Node ID
</h2>
</div>
</div>
<div class="inline-flex items-center gap-x-2">
<h3 class="text-gray-500 dark:text-neutral-500">
<span id="nodeId">-</span>
</h3>
</div>
</div>
}
// DiscoveredPeersCard component for displaying discovered peers count
templ DiscoveredPeersCard() {
<div class="p-4 flex flex-col bg-white border border-gray-200 rounded-xl dark:bg-neutral-800 dark:border-neutral-700">
<div class="flex justify-between items-center mb-1">
<h2 class="text-4xl font-semibold text-gray-800 dark:text-neutral-200">
<span id="discoveredPeerCount">0</span>
</h2>
</div>
<div class="inline-flex items-center gap-x-2">
<h3 class="text-gray-500 dark:text-neutral-500">
Discovered Peers
</h3>
</div>
</div>
}
// ConnectedPeersCard component for displaying connected peers count
templ ConnectedPeersCard() {
<div class="p-4 flex flex-col bg-white border border-gray-200 rounded-xl dark:bg-neutral-800 dark:border-neutral-700">
<div class="flex justify-between items-center mb-1">
<h2 class="text-4xl font-semibold text-gray-800 dark:text-neutral-200">
<span id="connectedPeerCount">0</span>
</h2>
<div class="flex items-center -space-x-2"></div>
</div>
<h3 class="text-gray-500 dark:text-neutral-500">
Connected Peers
</h3>
</div>
}
// Optional: Create a component for a connected peers list if needed
templ ConnectedPeersList() {
<div class="p-4 bg-white border border-gray-200 rounded-xl dark:bg-neutral-800 dark:border-neutral-700">
<h3 class="text-lg font-medium text-gray-800 dark:text-neutral-200 mb-2">Connected Peers List</h3>
<ul id="connectedPeersList" class="text-sm text-gray-600 dark:text-neutral-400"></ul>
</div>
}
// Optional: Create a component for the running log
templ RunningLog() {
<div class="p-4 bg-white border border-gray-200 rounded-xl dark:bg-neutral-800 dark:border-neutral-700">
<h3 class="text-lg font-medium text-gray-800 dark:text-neutral-200 mb-2">Running Log</h3>
<div id="runningLog" class="text-sm text-gray-600 dark:text-neutral-400 h-40 overflow-y-auto font-mono"></div>
</div>
}

View File

@@ -1,191 +0,0 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.857
package dash
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
// StatusCard component for displaying Helia node status
func StatusCard() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"p-4 flex flex-col bg-white border border-gray-200 rounded-xl dark:bg-neutral-800 dark:border-neutral-700\"><div class=\"flex justify-between items-center mb-1\"><h2 class=\"text-4xl font-semibold text-gray-800 dark:text-neutral-200\"><span id=\"statusValue\">Offline</span></h2><div class=\"flex items-center -space-x-2\"><img class=\"shrink-0 size-7 rounded-full\" src=\"https://images.unsplash.com/photo-1659482633369-9fe69af50bfb?ixlib=rb-4.0.3&amp;ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&amp;auto=format&amp;fit=facearea&amp;facepad=3&amp;w=320&amp;h=320&amp;q=80\" alt=\"Avatar\"></div></div><h3 class=\"text-gray-500 dark:text-neutral-500\">Status</h3></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// NodeIDCard component for displaying Helia node ID
func NodeIDCard() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var2 := templ.GetChildren(ctx)
if templ_7745c5c3_Var2 == nil {
templ_7745c5c3_Var2 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<div><div class=\"p-4 flex flex-col bg-white border border-gray-200 rounded-xl dark:bg-neutral-800 dark:border-neutral-700\"><div class=\"flex justify-between items-center mb-1\"><h2 class=\"text-4xl font-semibold text-gray-800 dark:text-neutral-200\">Node ID</h2></div></div><div class=\"inline-flex items-center gap-x-2\"><h3 class=\"text-gray-500 dark:text-neutral-500\"><span id=\"nodeId\">-</span></h3></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// DiscoveredPeersCard component for displaying discovered peers count
func DiscoveredPeersCard() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
if templ_7745c5c3_Var3 == nil {
templ_7745c5c3_Var3 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<div class=\"p-4 flex flex-col bg-white border border-gray-200 rounded-xl dark:bg-neutral-800 dark:border-neutral-700\"><div class=\"flex justify-between items-center mb-1\"><h2 class=\"text-4xl font-semibold text-gray-800 dark:text-neutral-200\"><span id=\"discoveredPeerCount\">0</span></h2></div><div class=\"inline-flex items-center gap-x-2\"><h3 class=\"text-gray-500 dark:text-neutral-500\">Discovered Peers</h3></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// ConnectedPeersCard component for displaying connected peers count
func ConnectedPeersCard() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var4 := templ.GetChildren(ctx)
if templ_7745c5c3_Var4 == nil {
templ_7745c5c3_Var4 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "<div class=\"p-4 flex flex-col bg-white border border-gray-200 rounded-xl dark:bg-neutral-800 dark:border-neutral-700\"><div class=\"flex justify-between items-center mb-1\"><h2 class=\"text-4xl font-semibold text-gray-800 dark:text-neutral-200\"><span id=\"connectedPeerCount\">0</span></h2><div class=\"flex items-center -space-x-2\"></div></div><h3 class=\"text-gray-500 dark:text-neutral-500\">Connected Peers</h3></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// Optional: Create a component for a connected peers list if needed
func ConnectedPeersList() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var5 := templ.GetChildren(ctx)
if templ_7745c5c3_Var5 == nil {
templ_7745c5c3_Var5 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<div class=\"p-4 bg-white border border-gray-200 rounded-xl dark:bg-neutral-800 dark:border-neutral-700\"><h3 class=\"text-lg font-medium text-gray-800 dark:text-neutral-200 mb-2\">Connected Peers List</h3><ul id=\"connectedPeersList\" class=\"text-sm text-gray-600 dark:text-neutral-400\"></ul></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// Optional: Create a component for the running log
func RunningLog() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var6 := templ.GetChildren(ctx)
if templ_7745c5c3_Var6 == nil {
templ_7745c5c3_Var6 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "<div class=\"p-4 bg-white border border-gray-200 rounded-xl dark:bg-neutral-800 dark:border-neutral-700\"><h3 class=\"text-lg font-medium text-gray-800 dark:text-neutral-200 mb-2\">Running Log</h3><div id=\"runningLog\" class=\"text-sm text-gray-600 dark:text-neutral-400 h-40 overflow-y-auto font-mono\"></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View File

@@ -1,20 +0,0 @@
package charts
import "fmt"
type DateValue struct {
Date string
Value int
}
templ AreaChart(data []DateValue) {
for _, d := range data {
<div class="flex flex-col">
<div class="flex justify-between">
<span class="text-sm font-medium text-gray-900">${ d.Date }</span>
<span class="text-sm font-medium text-gray-900">${ fmt.Sprintf("%d", d.Value) }</span>
</div>
<div class="h-1 bg-gray-200 rounded-full"></div>
</div>
}
}

View File

@@ -1,75 +0,0 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.857
package charts
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import "fmt"
type DateValue struct {
Date string
Value int
}
func AreaChart(data []DateValue) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
for _, d := range data {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"flex flex-col\"><div class=\"flex justify-between\"><span class=\"text-sm font-medium text-gray-900\">$")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(d.Date)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/dash/charts/area_chart.templ`, Line: 14, Col: 61}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</span> <span class=\"text-sm font-medium text-gray-900\">$")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", d.Value))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/dash/charts/area_chart.templ`, Line: 15, Col: 81}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</span></div><div class=\"h-1 bg-gray-200 rounded-full\"></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View File

@@ -1,21 +0,0 @@
package charts
import "fmt"
type KeyValue struct {
Key string
Value int
Color string
}
templ BarChart(data []KeyValue) {
for _, d := range data {
<div class="flex flex-col">
<div class="flex justify-between">
<span class="text-sm font-medium text-gray-900">${ d.Key }</span>
<span class="text-sm font-medium text-gray-900">${ fmt.Sprintf("%d", d.Value) }</span>
</div>
<div class="h-1 bg-gray-200 rounded-full"></div>
</div>
}
}

View File

@@ -1,76 +0,0 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.857
package charts
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import "fmt"
type KeyValue struct {
Key string
Value int
Color string
}
func BarChart(data []KeyValue) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
for _, d := range data {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"flex flex-col\"><div class=\"flex justify-between\"><span class=\"text-sm font-medium text-gray-900\">$")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(d.Key)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/dash/charts/bar_chart.templ`, Line: 15, Col: 60}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</span> <span class=\"text-sm font-medium text-gray-900\">$")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", d.Value))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/dash/charts/bar_chart.templ`, Line: 16, Col: 81}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</span></div><div class=\"h-1 bg-gray-200 rounded-full\"></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View File

@@ -1,106 +0,0 @@
package charts
import (
"encoding/json"
"time"
)
type CandleData struct {
Open float64
Close float64
High float64
Low float64
Date time.Time
}
// D3 script handle for deduplication
var d3Handle = templ.NewOnceHandle()
// D3 component for loading D3.js
templ D3() {
@d3Handle.Once() {
<script type="module">
window.d3 = d3;
</script>
}
}
// CandleChart component
templ CandleChart(data []CandleData) {
@D3()
<div id="candleChart" class="@container relative">
<div
class="relative h-72 w-full"
style="--marginTop: 10px; --marginRight: 60px; --marginBottom: 56px; --marginLeft: 30px;"
></div>
</div>
<script type="module">
import * as d3 from "https://cdn.jsdelivr.net/npm/d3@7/+esm";
// Convert Go data to JavaScript
// Declare the chart dimensions and margins.
const width = 640;
const height = 400;
const marginTop = 20;
const marginRight = 20;
const marginBottom = 30;
const marginLeft = 40;
// Declare the x (horizontal position) scale.
const x = d3.scaleUtc()
.domain([new Date("2023-01-01"), new Date("2024-01-01")])
.range([marginLeft, width - marginRight]);
// Declare the y (vertical position) scale.
const y = d3.scaleLinear()
.domain([0, 100])
.range([height - marginBottom, marginTop]);
// Create the SVG container.
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height);
// Add the x-axis.
svg.append("g")
.attr("transform", `translate(0,${height - marginBottom})`)
.call(d3.axisBottom(x));
// Add the y-axis.
svg.append("g")
.attr("transform", `translate(${marginLeft},0)`)
.call(d3.axisLeft(y));
// Append the SVG element.
container.append(svg.node());
</script>
}
// formatDataForJS converts the Go data structure to a JavaScript-compatible JSON string
func formatDataForJS(data []CandleData) string {
type jsData struct {
Date string `json:"date"`
Open float64 `json:"open"`
Close float64 `json:"close"`
High float64 `json:"high"`
Low float64 `json:"low"`
}
jsDataArray := make([]jsData, len(data))
for i, d := range data {
jsDataArray[i] = jsData{
Date: d.Date.Format(time.RFC3339),
Open: d.Open,
Close: d.Close,
High: d.High,
Low: d.Low,
}
}
jsonBytes, err := json.Marshal(jsDataArray)
if err != nil {
return "[]"
}
return string(jsonBytes)
}

View File

@@ -1,137 +0,0 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.857
package charts
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import (
"encoding/json"
"time"
)
type CandleData struct {
Open float64
Close float64
High float64
Low float64
Date time.Time
}
// D3 script handle for deduplication
var d3Handle = templ.NewOnceHandle()
// D3 component for loading D3.js
func D3() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<script type=\"module\">\n \n window.d3 = d3;\n </script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = d3Handle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// CandleChart component
func CandleChart(data []CandleData) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
if templ_7745c5c3_Var3 == nil {
templ_7745c5c3_Var3 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = D3().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<div id=\"candleChart\" class=\"@container relative\"><div class=\"relative h-72 w-full\" style=\"--marginTop: 10px; --marginRight: 60px; --marginBottom: 56px; --marginLeft: 30px;\"></div></div><script type=\"module\">\n\t import * as d3 from \"https://cdn.jsdelivr.net/npm/d3@7/+esm\";\n // Convert Go data to JavaScript\n \n // Declare the chart dimensions and margins.\n const width = 640;\n const height = 400;\n const marginTop = 20;\n const marginRight = 20;\n const marginBottom = 30;\n const marginLeft = 40;\n\n // Declare the x (horizontal position) scale.\n const x = d3.scaleUtc()\n .domain([new Date(\"2023-01-01\"), new Date(\"2024-01-01\")])\n .range([marginLeft, width - marginRight]);\n\n // Declare the y (vertical position) scale.\n const y = d3.scaleLinear()\n .domain([0, 100])\n .range([height - marginBottom, marginTop]);\n\n // Create the SVG container.\n const svg = d3.create(\"svg\")\n .attr(\"width\", width)\n .attr(\"height\", height);\n\n // Add the x-axis.\n svg.append(\"g\")\n .attr(\"transform\", `translate(0,${height - marginBottom})`)\n .call(d3.axisBottom(x));\n\n // Add the y-axis.\n svg.append(\"g\")\n .attr(\"transform\", `translate(${marginLeft},0)`)\n .call(d3.axisLeft(y));\n\n // Append the SVG element.\n container.append(svg.node()); \n </script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// formatDataForJS converts the Go data structure to a JavaScript-compatible JSON string
func formatDataForJS(data []CandleData) string {
type jsData struct {
Date string `json:"date"`
Open float64 `json:"open"`
Close float64 `json:"close"`
High float64 `json:"high"`
Low float64 `json:"low"`
}
jsDataArray := make([]jsData, len(data))
for i, d := range data {
jsDataArray[i] = jsData{
Date: d.Date.Format(time.RFC3339),
Open: d.Open,
Close: d.Close,
High: d.High,
Low: d.Low,
}
}
jsonBytes, err := json.Marshal(jsDataArray)
if err != nil {
return "[]"
}
return string(jsonBytes)
}
var _ = templruntime.GeneratedTemplate

View File

@@ -1,15 +0,0 @@
package charts
import "fmt"
templ LineChart(data []DateValue) {
for _, d := range data {
<div class="flex flex-col">
<div class="flex justify-between">
<span class="text-sm font-medium text-gray-900">${ d.Date }</span>
<span class="text-sm font-medium text-gray-900">${ fmt.Sprintf("%d", d.Value) }</span>
</div>
<div class="h-1 bg-gray-200 rounded-full"></div>
</div>
}
}

View File

@@ -1,70 +0,0 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.857
package charts
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import "fmt"
func LineChart(data []DateValue) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
for _, d := range data {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"flex flex-col\"><div class=\"flex justify-between\"><span class=\"text-sm font-medium text-gray-900\">$")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(d.Date)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/dash/charts/line_chart.templ`, Line: 9, Col: 61}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</span> <span class=\"text-sm font-medium text-gray-900\">$")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", d.Value))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/dash/charts/line_chart.templ`, Line: 10, Col: 81}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</span></div><div class=\"h-1 bg-gray-200 rounded-full\"></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

Some files were not shown because too many files have changed in this diff Show More