Let it be hermes

* rename to hermes
* use echo+htmx+templ stack
* use code from delphi.market as scaffolding
This commit is contained in:
ekzyis 2024-10-25 04:32:25 +02:00
parent 97c25541e1
commit abad39a2bc
15 changed files with 5373 additions and 26 deletions

15
.gitignore vendored Normal file
View File

@ -0,0 +1,15 @@
# go executable
hermes
# environment
.env
# templ
*_templ.go
# tailwindcss
public/css/tailwind.css
# js
node_modules
public/js/*.min.js

View File

@ -1,2 +1,16 @@
dev:
.PHONY: build run
SOURCE := $(shell find fonts lib pages server -type f) main.go
# build binary for deployment
build: hermes
hermes: $(SOURCE)
tailwindcss -i public/css/base.css -o public/css/tailwind.css
templ generate -path pages
go build -o hermes .
# run code for development (no watch mode yet)
run:
tailwindcss -i public/css/base.css -o public/css/tailwind.css
templ generate -path pages
go run .

View File

@ -1,3 +1,16 @@
# baas
# hermes
> [bankify](https://github.com/supertestnet/bankify) as a service
```
.__
| |__ ___________ _____ ____ ______
| | \_/ __ \_ __ \/ \_/ __ \ / ___/
| Y \ ___/| | \/ Y Y \ ___/ \___ \
|___| /\___ >__| |__|_| /\___ >____ >
\/ \/....wallet....\/ \/ \/
```
> _Not the wallet you need, but the wallet you deserve._
**Development**
See [Makefile](./Makefile).

11
go.mod
View File

@ -1,4 +1,4 @@
module github.com/ekzyis/baas
module github.com/ekzyis/hermes
go 1.22.0
@ -11,15 +11,16 @@ require (
)
require (
github.com/a-h/templ v0.2.778 // indirect
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/labstack/gommon v0.4.2 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect
golang.org/x/crypto v0.22.0 // indirect
golang.org/x/net v0.24.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/crypto v0.26.0 // indirect
golang.org/x/net v0.28.0 // indirect
golang.org/x/sys v0.23.0 // indirect
golang.org/x/text v0.17.0 // indirect
golang.org/x/time v0.5.0 // indirect
)

18
go.sum
View File

@ -1,3 +1,5 @@
github.com/a-h/templ v0.2.778 h1:VzhOuvWECrwOec4790lcLlZpP4Iptt5Q4K9aFxQmtaM=
github.com/a-h/templ v0.2.778/go.mod h1:lq48JXoUvuQrU0VThrK31yFwdRjTCnIE5bcPCM9IP1w=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
@ -21,18 +23,18 @@ 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/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY=
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
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.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

22
main.go
View File

@ -5,16 +5,24 @@ import (
"log"
"net/http"
"github.com/ekzyis/baas/baas"
"github.com/ekzyis/baas/lib"
"github.com/ekzyis/hermes/server"
)
func main() {
fmt.Printf("%s%s\n\n",
lib.Figlet("graffiti", "baas"),
" --- bankify as a service --- ")
func banner() {
fmt.Printf("" +
".__\n" +
"| |__ ___________ _____ ____ ______\n" +
"| | \\_/ __ \\_ __ \\/ \\_/ __ \\ / ___/\n" +
"| Y \\ ___/| | \\/ Y Y \\ ___/ \\___ \\\n" +
"|___| /\\___ >__| |__|_| /\\___ >____ >\n" +
" \\/ \\/...wallet...\\/ \\/ \\/\n",
)
}
s := baas.NewServer()
func main() {
banner()
s := server.New()
// TODO: read port from env
if err := s.Start("127.0.0.1:8888"); err != http.ErrServerClosed {

View File

@ -0,0 +1,31 @@
package components
templ Head() {
<head>
<title>hermes</title>
<!-- TODO: add favicon, manifest etc. -->
<link rel="icon" type="image/x-icon" href="/favicon.ico"/>
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"/>
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/>
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/>
<link rel="manifest" href="/site.webmanifest"/>
<link rel="stylesheet" href="/css/tailwind.css"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="theme-color" content="#191d21"/>
<meta
name="htmx-config"
content='{
"responseHandling": [
{ "code": "204", "swap": false },
{ "code": "[23]..", "swap": true },
{ "code": "[45]..", "swap": true, "error": true }
]
}'
/>
<script src="/js/htmx.js" integrity="sha384-Xh+GLLi0SMFPwtHQjT72aPG19QvKB8grnyRbYBNIdHWc2NkCrz65jlU7YrzO6qRp" crossorigin="anonymous"></script>
<script type="text/javascript">
// helper functions
var $ = selector => document.querySelector(selector)
</script>
</head>
}

26
pages/index.templ Normal file
View File

@ -0,0 +1,26 @@
package pages
import "github.com/ekzyis/hermes/pages/components"
templ Index() {
<html>
@components.Head()
<body class="container">
<div id="content" class="grid mt-3">
<div class="grid gap-10 self-center justify-self-center">
<h1 class="text-center text-5xl font-bold">0 sats</h1>
<div class="flex justify-self-center">
<button class="flex items-center justify-center text-xl mx-3 w-[120px]">
<img src="/svg/arrow-left-down-line.svg" width="24px" height="24px"/>
receive
</button>
<button class="flex items-center justify-center text-xl mx-3 w-[120px]">
<img src="/svg/arrow-right-up-line.svg" width="24px" height="24px"/>
send
</button>
</div>
</div>
</div>
</body>
</html>
}

52
public/css/base.css Normal file
View File

@ -0,0 +1,52 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
:root {
--background: #191d21;
--color: #d3d3d3;
--muted: #6c757d;
--lightning: #fada5e;
--nostr: #8d45dd;
--black: #000;
--white: #fff;
--bg-success: #149e613d;
--fg-success: #35df8d;
--bg-error: #f5395e3d;
--fg-error: #ff7386;
--bg-btn: #ebebeb;
--fg-btn: #0a0a0a;
}
@layer base {
body {
background-color: var(--background);
color: var(--color);
font-family: Roboto, -apple-system, Helvetica Neue, Helvetica, Arial, sans-serif;
-webkit-text-size-adjust: 100%;
-webkit-font-smoothing: antialiased;
}
#content {
min-height: 85svh;
}
@media (min-width: 768px) {
#content {
min-height: 90svh;
}
}
button {
background-color: var(--bg-btn);
color: var(--fg-btn);
border-radius: 28px;
outline: 0;
min-height: 2rem;
padding: 0 1rem;
}
button:hover {
filter: brightness(130%) drop-shadow(0 0 0.3em var(--bg-btn));
}
}

5129
public/js/htmx.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M9 13.589L17.6066 4.98242L19.0208 6.39664L10.4142 15.0032H18V17.0032H7V6.00324H9V13.589Z"></path></svg>

After

Width:  |  Height:  |  Size: 192 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M16.0037 9.41421L7.39712 18.0208L5.98291 16.6066L14.5895 8H7.00373V6H18.0037V17H16.0037V9.41421Z"></path></svg>

After

Width:  |  Height:  |  Size: 200 B

View File

@ -1,6 +1,7 @@
package baas
package server
import (
"github.com/ekzyis/hermes/pages"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
)
@ -9,13 +10,13 @@ type Server struct {
*echo.Echo
}
func NewServer() *Server {
func New() *Server {
e := echo.New()
e.Static("/", "public")
e.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
Format: "${time_custom} ${method} ${uri} ${status}\n",
Format: "${time_custom} ${remote_ip} ${method} ${uri} ${status}\n",
CustomTimeFormat: "2006-01-02 15:04:05.00000-0700",
}))
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
@ -28,6 +29,10 @@ func NewServer() *Server {
// TODO: attach error handler
// e.HTTPErrorHandler = ...
e.GET("/", func(c echo.Context) error {
return pages.Index().Render(c.Request().Context(), c.Response().Writer)
})
s := &Server{e}
return s

19
shell.nix Normal file
View File

@ -0,0 +1,19 @@
let
nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-23.11";
pkgs = import nixpkgs { config = {}; overlays = []; };
in
pkgs.mkShell {
packages = with pkgs; [
go
tailwindcss
gnumake
inotify-tools
figlet
postgresql
];
shellHook = ''
# install templ if not already installed
command -v templ > /dev/null || go install github.com/a-h/templ/cmd/templ@latest
'';
}

30
tailwind.config.js Normal file
View File

@ -0,0 +1,30 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./pages/**/*.templ"],
theme: {
container: {
center: true,
padding: '1rem'
},
extend: {
colors: {
'background': '191d21',
'muted': '#6c757d',
},
},
},
plugins: [
function ({ addComponents }) {
addComponents({
'.container': {
'@screen lg': {
maxWidth: '768px',
},
'@screen xl': {
maxWidth: '768px',
},
}
})
}
],
}