mirror of
https://github.com/cf-sonr/motr.git
synced 2026-01-12 02:59:13 +00:00
feat: streamline front-end dependencies and build process
This commit is contained in:
83
Makefile
83
Makefile
@@ -1,60 +1,55 @@
|
||||
export ROOT_DIR := $(shell git rev-parse --show-toplevel)
|
||||
|
||||
export ENCLAVE_ROOT := $(ROOT_DIR)/cmd/enclave
|
||||
export RADAR_ROOT := $(ROOT_DIR)/cmd/radar
|
||||
export SIGNER_ROOT := $(ROOT_DIR)/cmd/signer
|
||||
export WORKER_ROOT := $(ROOT_DIR)/cmd/worker
|
||||
export VERIFIER_ROOT := $(ROOT_DIR)/cmd/verifier
|
||||
|
||||
export SQLC_ROOT := $(ROOT_DIR)/internal/db
|
||||
export MIGRATE_ROOT := $(ROOT_DIR)/internal/migrations
|
||||
export RADAR_OUT := $(RADAR_ROOT)/build/app.wasm
|
||||
export WORKER_OUT := $(WORKER_ROOT)/build/app.wasm
|
||||
|
||||
.PHONY: install clean help
|
||||
|
||||
install:
|
||||
@go mod download
|
||||
@go install github.com/syumai/workers/cmd/workers-assets-gen@latest
|
||||
|
||||
clean:
|
||||
@rm -rf ./build
|
||||
@rm -rf ./bin
|
||||
@rm -rf ./dist
|
||||
@rm -rf ./cmd/worker/node_modules
|
||||
@rm -rf ./cmd/radar/node_modules
|
||||
|
||||
help:
|
||||
@echo "Usage: make <command>"
|
||||
@echo ""
|
||||
@echo "Commands:"
|
||||
@echo " help Show this help message"
|
||||
@echo " tidy Tidy up the project"
|
||||
@echo " templ Generate templates"
|
||||
@echo " sqlc Generate SQL schema"
|
||||
@echo " worker Build and deploy worker"
|
||||
@echo " radar Build and deploy radar"
|
||||
|
||||
.PHONY: templ sqlc
|
||||
|
||||
templ:
|
||||
@templ generate
|
||||
|
||||
sqlc:
|
||||
@devbox run gen:sqlc
|
||||
|
||||
migrate:
|
||||
@cd $(MIGRATE_ROOT) && task
|
||||
|
||||
worker:
|
||||
@devbox run serve:worker
|
||||
.PHONY: worker worker-build worker-deploy worker-start
|
||||
worker: worker-deploy
|
||||
worker-build:
|
||||
@make -C $(WORKER_ROOT) build
|
||||
worker-deploy:
|
||||
@make -C $(WORKER_ROOT) deploy
|
||||
worker-start:
|
||||
@make -C $(WORKER_ROOT) start
|
||||
|
||||
radar:
|
||||
@devbox run serve:radar
|
||||
.PHONY: radar radar-build radar-deploy radar-start
|
||||
radar: radar-deploy
|
||||
radar-build:
|
||||
@make -C $(RADAR_ROOT) build
|
||||
radar-deploy:
|
||||
@make -C $(RADAR_ROOT) deploy
|
||||
radar-start:
|
||||
@make -C $(RADAR_ROOT) start
|
||||
|
||||
deploy:
|
||||
@devbox run deploy
|
||||
.PHONY: enclave enclave-build enclave-publish
|
||||
enclave: enclave-publish
|
||||
enclave-build:
|
||||
@make -C $(ENCLAVE_ROOT) build
|
||||
enclave-publish:
|
||||
@make -C $(ENCLAVE_ROOT) publish
|
||||
|
||||
release:
|
||||
@devbox run release
|
||||
.PHONY: signer signer-build signer-publish
|
||||
signer: signer-publish
|
||||
signer-build:
|
||||
@make -C $(SIGNER_ROOT) build
|
||||
signer-publish:
|
||||
@make -C $(SIGNER_ROOT) publish
|
||||
|
||||
templ-watch:
|
||||
@devbox run watch:templ
|
||||
|
||||
migrate:
|
||||
@devbox run db:migrate
|
||||
.PHONY: verifier verifier-build verifier-publish
|
||||
verifier: verifier-publish
|
||||
verifier-build:
|
||||
@make -C $(VERIFIER_ROOT) build
|
||||
verifier-publish:
|
||||
@make -C $(VERIFIER_ROOT) publish
|
||||
|
||||
1
cmd/enclave/.gitignore
vendored
Normal file
1
cmd/enclave/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.wasm
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
all: build publish
|
||||
|
||||
build: tidy
|
||||
build:
|
||||
@gum spin --show-error --title "[ENCLAVE] Running go build..." -- sh -c "GOOS=wasip1 GOARCH=wasm go build -buildmode=c-shared -o enclave.wasm"
|
||||
@gum log --level info --time kitchen "[ENCLAVE] Completed go build successfully."
|
||||
|
||||
|
||||
37
cmd/enclave/README.md
Normal file
37
cmd/enclave/README.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# `enclave`
|
||||
|
||||
## Features
|
||||
|
||||
The Motr Enclave is used for DKG-MPC Generation of Decentralized Web Nodes.
|
||||
|
||||
## Usage
|
||||
|
||||
### Call Plugin from JavaScript
|
||||
|
||||
```bash
|
||||
git clone https://github.com/sonr-io/motr.git
|
||||
cd motr
|
||||
go mod tidy
|
||||
```
|
||||
|
||||
### Call Plugin from Extism CLI
|
||||
|
||||
```bash
|
||||
git clone https://github.com/sonr-io/motr.git
|
||||
cd motr
|
||||
go mod tidy
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
## API Reference
|
||||
|
||||
### `generate()`
|
||||
|
||||
The Generate function initializes an MPC Vault
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE)
|
||||
|
||||
Copyright (c) 2025, Sonr Inc.
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
all: build publish
|
||||
|
||||
tidy:
|
||||
@gum spin --show-error --title "[SIGNER] Running go mod tidy..." -- sh -c "go mod tidy"
|
||||
@gum log --level info --time kitchen "[SIGNER] Completed go mod tidy successfully."
|
||||
|
||||
build: tidy
|
||||
build:
|
||||
@gum spin --show-error --title "[SIGNER] Running tinygo build..." -- sh -c "tinygo build -o signer.wasm -target wasip1 -buildmode=c-shared main.go"
|
||||
@gum log --level info --time kitchen "[SIGNER] Completed tinygo build successfully."
|
||||
|
||||
|
||||
1
cmd/verifier/.gitignore
vendored
Normal file
1
cmd/verifier/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.wasm
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
all: build publish
|
||||
|
||||
tidy:
|
||||
@gum spin --show-error --title "[VERIFIER] Running go mod tidy..." -- sh -c "go mod tidy"
|
||||
@gum log --level info --time kitchen "[VERIFIER] Completed go mod tidy successfully."
|
||||
|
||||
build: tidy
|
||||
build:
|
||||
@gum spin --show-error --title "[VERIFIER] Running tinygo build..." -- sh -c "tinygo build -o verifier.wasm -target wasip1 -buildmode=c-shared main.go"
|
||||
@gum log --level info --time kitchen "[VERIFIER] Completed tinygo build successfully."
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
templ:
|
||||
go run github.com/a-h/templ/cmd/templ generate
|
||||
|
||||
assets:
|
||||
go run github.com/syumai/workers/cmd/workers-assets-gen -mode=go
|
||||
generate:
|
||||
@go run github.com/a-h/templ/cmd/templ generate
|
||||
@go run github.com/syumai/workers/cmd/workers-assets-gen -mode=go
|
||||
|
||||
build: generate
|
||||
GOOS=js GOARCH=wasm go build -ldflags="-s -w" -o ./build/app.wasm .
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
"sqlc@latest",
|
||||
"nodejs@latest",
|
||||
"goreleaser@latest",
|
||||
"go-task@latest",
|
||||
"doppler@latest"
|
||||
"rclone@latest",
|
||||
"go-task@latest"
|
||||
],
|
||||
"env": {
|
||||
"SONR_API_URL": "https://api.sonr.ws",
|
||||
|
||||
113
pkg/render/ui/layout.templ
Normal file
113
pkg/render/ui/layout.templ
Normal file
@@ -0,0 +1,113 @@
|
||||
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>
|
||||
}
|
||||
139
pkg/render/ui/providers.templ
Normal file
139
pkg/render/ui/providers.templ
Normal file
@@ -0,0 +1,139 @@
|
||||
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)
|
||||
}
|
||||
54
pkg/render/ui/styles.templ
Normal file
54
pkg/render/ui/styles.templ
Normal file
@@ -0,0 +1,54 @@
|
||||
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>
|
||||
}
|
||||
Reference in New Issue
Block a user