mirror of
https://github.com/onsonr/hway.git
synced 2025-03-10 13:07:09 +00:00
feat: add goreleaser config for building and releasing the application
This commit is contained in:
commit
c31f5b67b7
182
.goreleaser.yaml
Normal file
182
.goreleaser.yaml
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
# yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json
|
||||||
|
version: 2
|
||||||
|
project_name: sonr
|
||||||
|
|
||||||
|
builds:
|
||||||
|
- id: motr
|
||||||
|
main: ./cmd/motr
|
||||||
|
binary: app
|
||||||
|
goos:
|
||||||
|
- js
|
||||||
|
goarch:
|
||||||
|
- wasm
|
||||||
|
|
||||||
|
- id: sonr
|
||||||
|
main: ./cmd/sonrd
|
||||||
|
binary: sonrd
|
||||||
|
mod_timestamp: "{{ .CommitTimestamp }}"
|
||||||
|
goos:
|
||||||
|
- linux
|
||||||
|
- darwin
|
||||||
|
goarch:
|
||||||
|
- amd64
|
||||||
|
- arm64
|
||||||
|
goamd64:
|
||||||
|
- v1
|
||||||
|
flags:
|
||||||
|
- -mod=readonly
|
||||||
|
- -trimpath
|
||||||
|
ldflags:
|
||||||
|
- -X github.com/cosmos/cosmos-sdk/version.Name=sonr
|
||||||
|
- -X github.com/cosmos/cosmos-sdk/version.AppName=sonrd
|
||||||
|
- -X github.com/cosmos/cosmos-sdk/version.Version={{.Version}}
|
||||||
|
- -X github.com/cosmos/cosmos-sdk/version.Commit={{.Commit}}
|
||||||
|
- -X "github.com/cosmos/cosmos-sdk/version.BuildTags=netgo,ledger"
|
||||||
|
tags:
|
||||||
|
- netgo
|
||||||
|
- ledger
|
||||||
|
|
||||||
|
- id: hway
|
||||||
|
main: ./cmd/hway
|
||||||
|
binary: hway
|
||||||
|
goos:
|
||||||
|
- linux
|
||||||
|
- darwin
|
||||||
|
goarch:
|
||||||
|
- amd64
|
||||||
|
- arm64
|
||||||
|
mod_timestamp: "{{ .CommitTimestamp }}"
|
||||||
|
flags:
|
||||||
|
- -mod=readonly
|
||||||
|
- -trimpath
|
||||||
|
goamd64:
|
||||||
|
- v1
|
||||||
|
tags:
|
||||||
|
- netgo
|
||||||
|
ldflags:
|
||||||
|
- -X main.version={{.Version}}
|
||||||
|
- -X main.commit={{.Commit}}
|
||||||
|
- -X main.date={{.Date}}
|
||||||
|
archives:
|
||||||
|
- id: sonr
|
||||||
|
builds: [sonr]
|
||||||
|
name_template: >-
|
||||||
|
sonr_{{ .Os }}_{{- if eq .Arch "amd64" }}x86_64
|
||||||
|
{{- else if eq .Arch "386" }}i386
|
||||||
|
{{- else }}{{ .Arch }}{{ end }}
|
||||||
|
format: tar.gz
|
||||||
|
files:
|
||||||
|
- src: README*
|
||||||
|
wrap_in_directory: true
|
||||||
|
|
||||||
|
- id: hway
|
||||||
|
builds: [hway]
|
||||||
|
name_template: >-
|
||||||
|
hway_{{ .Os }}_{{- if eq .Arch "amd64" }}x86_64
|
||||||
|
{{- else if eq .Arch "386" }}i386
|
||||||
|
{{- else }}{{ .Arch }}{{ end }}
|
||||||
|
format: tar.gz
|
||||||
|
files:
|
||||||
|
- src: README*
|
||||||
|
wrap_in_directory: true
|
||||||
|
|
||||||
|
nfpms:
|
||||||
|
- id: hway
|
||||||
|
package_name: hway
|
||||||
|
file_name_template: "hway_{{ .Os }}_{{ .Arch }}{{ .ConventionalExtension }}"
|
||||||
|
builds: [hway]
|
||||||
|
vendor: Sonr
|
||||||
|
homepage: "https://onsonr.dev"
|
||||||
|
maintainer: "Sonr <support@onsonr.dev>"
|
||||||
|
description: "Sonr Highway is a decentralized, permissionless, and censorship-resistant identity network proxy."
|
||||||
|
license: "Apache 2.0"
|
||||||
|
formats:
|
||||||
|
- rpm
|
||||||
|
- deb
|
||||||
|
- apk
|
||||||
|
dependencies:
|
||||||
|
- ipfs
|
||||||
|
contents:
|
||||||
|
- src: README*
|
||||||
|
dst: /usr/share/doc/hway
|
||||||
|
bindir: /usr/bin
|
||||||
|
section: net
|
||||||
|
priority: optional
|
||||||
|
# Add these lines to match build config
|
||||||
|
|
||||||
|
- id: sonr
|
||||||
|
package_name: sonrd
|
||||||
|
file_name_template: "sonrd_{{ .Os }}_{{ .Arch }}{{ .ConventionalExtension }}"
|
||||||
|
builds: [sonr]
|
||||||
|
vendor: Sonr
|
||||||
|
homepage: "https://onsonr.dev"
|
||||||
|
maintainer: "Sonr <support@onsonr.dev>"
|
||||||
|
description: "Sonr is a decentralized, permissionless, and censorship-resistant identity network."
|
||||||
|
license: "Apache 2.0"
|
||||||
|
formats:
|
||||||
|
- rpm
|
||||||
|
- deb
|
||||||
|
- apk
|
||||||
|
dependencies:
|
||||||
|
- ipfs
|
||||||
|
contents:
|
||||||
|
- src: README*
|
||||||
|
dst: /usr/share/doc/sonrd
|
||||||
|
bindir: /usr/bin
|
||||||
|
section: net
|
||||||
|
priority: optional
|
||||||
|
# Add these lines to match build config
|
||||||
|
|
||||||
|
brews:
|
||||||
|
- name: hway
|
||||||
|
ids: [hway]
|
||||||
|
commit_author:
|
||||||
|
name: goreleaserbot
|
||||||
|
email: bot@goreleaser.com
|
||||||
|
directory: Formula
|
||||||
|
caveats: "Run a local hway node and access it with the hway proxy"
|
||||||
|
homepage: "https://onsonr.dev"
|
||||||
|
description: "Sonr is a decentralized, permissionless, and censorship-resistant identity network."
|
||||||
|
dependencies:
|
||||||
|
- name: ipfs
|
||||||
|
repository:
|
||||||
|
owner: onsonr
|
||||||
|
name: homebrew-tap
|
||||||
|
branch: master
|
||||||
|
token: "{{ .Env.GITHUB_PERSONAL_AUTH_TOKEN }}"
|
||||||
|
|
||||||
|
- name: sonr
|
||||||
|
ids: [sonr]
|
||||||
|
commit_author:
|
||||||
|
name: goreleaserbot
|
||||||
|
email: bot@goreleaser.com
|
||||||
|
directory: Formula
|
||||||
|
caveats: "Run a local sonr node and access it with the hway proxy"
|
||||||
|
homepage: "https://onsonr.dev"
|
||||||
|
description: "Sonr is a decentralized, permissionless, and censorship-resistant identity network."
|
||||||
|
dependencies:
|
||||||
|
- name: ipfs
|
||||||
|
repository:
|
||||||
|
owner: onsonr
|
||||||
|
name: homebrew-tap
|
||||||
|
branch: master
|
||||||
|
token: "{{ .Env.GITHUB_PERSONAL_AUTH_TOKEN }}"
|
||||||
|
|
||||||
|
release:
|
||||||
|
github:
|
||||||
|
owner: onsonr
|
||||||
|
name: sonr
|
||||||
|
name_template: 'Release {{ .Env.RELEASE_DATE }}'
|
||||||
|
draft: false
|
||||||
|
replace_existing_draft: true
|
||||||
|
replace_existing_artifacts: true
|
||||||
|
extra_files:
|
||||||
|
- glob: ./README*
|
||||||
|
- glob: ./scripts/install.sh
|
||||||
|
- glob: ./scripts/test_node.sh
|
||||||
|
- glob: ./scripts/test_ics_node.sh
|
||||||
|
|
||||||
|
announce:
|
||||||
|
telegram:
|
||||||
|
enabled: true
|
||||||
|
chat_id: -1002222617755
|
12
.taskfiles/Taskfile.yml
Normal file
12
.taskfiles/Taskfile.yml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# https://taskfile.dev
|
||||||
|
|
||||||
|
version: '3'
|
||||||
|
|
||||||
|
vars:
|
||||||
|
GREETING: Hello, World!
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
default:
|
||||||
|
cmds:
|
||||||
|
- echo "{{.GREETING}}"
|
||||||
|
silent: true
|
12
.taskfiles/es.yml
Normal file
12
.taskfiles/es.yml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# https://taskfile.dev
|
||||||
|
|
||||||
|
version: '3'
|
||||||
|
|
||||||
|
vars:
|
||||||
|
GREETING: Hello, World!
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
default:
|
||||||
|
cmds:
|
||||||
|
- echo "{{.GREETING}}"
|
||||||
|
silent: true
|
0
CONVENTIONS.md
Normal file
0
CONVENTIONS.md
Normal file
329
Makefile
Normal file
329
Makefile
Normal file
@ -0,0 +1,329 @@
|
|||||||
|
#!/usr/bin/make -f
|
||||||
|
|
||||||
|
PACKAGES_SIMTEST=$(shell go list ./... | grep '/simulation')
|
||||||
|
VERSION := $(shell echo $(shell git describe --tags) | sed 's/^v//')
|
||||||
|
COMMIT := $(shell git log -1 --format='%H')
|
||||||
|
LEDGER_ENABLED ?= true
|
||||||
|
SDK_PACK := $(shell go list -m github.com/cosmos/cosmos-sdk | sed 's/ /\@/g')
|
||||||
|
BINDIR ?= $(GOPATH)/bin
|
||||||
|
SIMAPP = ./app
|
||||||
|
|
||||||
|
PC_PORT_NUM=42069
|
||||||
|
PC_LOG_FILE=./sonr.log
|
||||||
|
PC_SOCKET_PATH=/tmp/sonr-net.sock
|
||||||
|
|
||||||
|
# for dockerized protobuf tools
|
||||||
|
DOCKER := $(shell which docker)
|
||||||
|
HTTPS_GIT := github.com/onsonr/sonr.git
|
||||||
|
PROCESS_COMPOSE := $(shell which process-compose)
|
||||||
|
|
||||||
|
export GO111MODULE = on
|
||||||
|
|
||||||
|
# process build tags
|
||||||
|
|
||||||
|
build_tags = netgo
|
||||||
|
ifeq ($(LEDGER_ENABLED),true)
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
GCCEXE = $(shell where gcc.exe 2> NUL)
|
||||||
|
ifeq ($(GCCEXE),)
|
||||||
|
$(error gcc.exe not installed for ledger support, please install or set LEDGER_ENABLED=false)
|
||||||
|
else
|
||||||
|
build_tags += ledger
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
UNAME_S = $(shell uname -s)
|
||||||
|
ifeq ($(UNAME_S),OpenBSD)
|
||||||
|
$(warning OpenBSD detected, disabling ledger support (https://github.com/cosmos/cosmos-sdk/issues/1988))
|
||||||
|
else
|
||||||
|
GCC = $(shell command -v gcc 2> /dev/null)
|
||||||
|
ifeq ($(GCC),)
|
||||||
|
$(error gcc not installed for ledger support, please install or set LEDGER_ENABLED=false)
|
||||||
|
else
|
||||||
|
build_tags += ledger
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(WITH_CLEVELDB),yes)
|
||||||
|
build_tags += gcc
|
||||||
|
endif
|
||||||
|
build_tags += $(BUILD_TAGS)
|
||||||
|
build_tags := $(strip $(build_tags))
|
||||||
|
|
||||||
|
whitespace :=
|
||||||
|
empty = $(whitespace) $(whitespace)
|
||||||
|
comma := ,
|
||||||
|
build_tags_comma_sep := $(subst $(empty),$(comma),$(build_tags))
|
||||||
|
|
||||||
|
# process linker flags
|
||||||
|
ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=sonr \
|
||||||
|
-X github.com/cosmos/cosmos-sdk/version.AppName=sonrd \
|
||||||
|
-X github.com/cosmos/cosmos-sdk/version.Version=$(VERSION) \
|
||||||
|
-X github.com/cosmos/cosmos-sdk/version.Commit=$(COMMIT) \
|
||||||
|
-X "github.com/cosmos/cosmos-sdk/version.BuildTags=$(build_tags_comma_sep)"
|
||||||
|
|
||||||
|
ifeq ($(WITH_CLEVELDB),yes)
|
||||||
|
ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=cleveldb
|
||||||
|
endif
|
||||||
|
ifeq ($(LINK_STATICALLY),true)
|
||||||
|
ldflags += -linkmode=external -extldflags "-Wl,-z,muldefs -static"
|
||||||
|
endif
|
||||||
|
ldflags += $(LDFLAGS)
|
||||||
|
ldflags := $(strip $(ldflags))
|
||||||
|
|
||||||
|
BUILD_FLAGS := -tags "$(build_tags_comma_sep)" -ldflags '$(ldflags)' -trimpath
|
||||||
|
|
||||||
|
# The below include contains the tools and runsim targets.
|
||||||
|
all: install lint test
|
||||||
|
|
||||||
|
build: go.sum
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
$(error wasmd server not supported. Use "make build-windows-client" for client)
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
go build -mod=readonly $(BUILD_FLAGS) -o build/sonrd ./cmd/sonrd
|
||||||
|
endif
|
||||||
|
|
||||||
|
build-motr: go.sum
|
||||||
|
GOOS=js GOARCH=wasm go build -o static/wasm/app.wasm ./cmd/motr/main.go
|
||||||
|
|
||||||
|
build-hway: go.sum
|
||||||
|
go build -o build/hway ./cmd/hway
|
||||||
|
|
||||||
|
build-windows-client: go.sum
|
||||||
|
GOOS=windows GOARCH=amd64 go build -mod=readonly $(BUILD_FLAGS) -o build/sonrd.exe ./cmd/sonrd
|
||||||
|
|
||||||
|
build-contract-tests-hooks:
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
go build -mod=readonly $(BUILD_FLAGS) -o build/contract_tests.exe ./cmd/contract_tests
|
||||||
|
else
|
||||||
|
go build -mod=readonly $(BUILD_FLAGS) -o build/contract_tests ./cmd/contract_tests
|
||||||
|
endif
|
||||||
|
|
||||||
|
install: go.sum
|
||||||
|
go install -mod=readonly $(BUILD_FLAGS) ./cmd/sonrd
|
||||||
|
|
||||||
|
install-hway: go.sum
|
||||||
|
go install -mod=readonly ./cmd/hway
|
||||||
|
|
||||||
|
########################################
|
||||||
|
### Tools & dependencies
|
||||||
|
|
||||||
|
go-mod-cache: go.sum
|
||||||
|
@echo "--> Download go modules to local cache"
|
||||||
|
@go mod download
|
||||||
|
|
||||||
|
go.sum: go.mod
|
||||||
|
@echo "--> Ensure dependencies have not been modified"
|
||||||
|
@go mod verify
|
||||||
|
|
||||||
|
draw-deps:
|
||||||
|
@# requires brew install graphviz or apt-get install graphviz
|
||||||
|
go install github.com/RobotsAndPencils/goviz@latest
|
||||||
|
@goviz -i ./cmd/sonrd -d 2 | dot -Tpng -o dependency-graph.png
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf .aider*
|
||||||
|
rm -rf static
|
||||||
|
rm -rf .out
|
||||||
|
rm -rf hway.db
|
||||||
|
rm -rf snapcraft-local.yaml build/
|
||||||
|
rm -rf build
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
rm -rf vendor/
|
||||||
|
|
||||||
|
init-env:
|
||||||
|
@echo "Installing process-compose"
|
||||||
|
sh scripts/init_env.sh
|
||||||
|
|
||||||
|
########################################
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
test: test-unit
|
||||||
|
test-all: test-race test-cover test-system
|
||||||
|
|
||||||
|
test-unit:
|
||||||
|
@VERSION=$(VERSION) go test -mod=readonly -tags='ledger test_ledger_mock' ./...
|
||||||
|
|
||||||
|
test-race:
|
||||||
|
@VERSION=$(VERSION) go test -mod=readonly -race -tags='ledger test_ledger_mock' ./...
|
||||||
|
|
||||||
|
test-cover:
|
||||||
|
@go test -mod=readonly -timeout 30m -race -coverprofile=coverage.txt -covermode=atomic -tags='ledger test_ledger_mock' ./...
|
||||||
|
|
||||||
|
benchmark:
|
||||||
|
@go test -mod=readonly -bench=. ./...
|
||||||
|
|
||||||
|
test-sim-import-export: runsim
|
||||||
|
@echo "Running application import/export simulation. This may take several minutes..."
|
||||||
|
@$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 50 5 TestAppImportExport
|
||||||
|
|
||||||
|
test-sim-multi-seed-short: runsim
|
||||||
|
@echo "Running short multi-seed application simulation. This may take awhile!"
|
||||||
|
@$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 50 5 TestFullAppSimulation
|
||||||
|
|
||||||
|
test-sim-deterministic: runsim
|
||||||
|
@echo "Running application deterministic simulation. This may take awhile!"
|
||||||
|
@$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 1 1 TestAppStateDeterminism
|
||||||
|
|
||||||
|
test-system: install
|
||||||
|
$(MAKE) -C tests/system/ test
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
### Linting ###
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
format-tools:
|
||||||
|
go install mvdan.cc/gofumpt@v0.4.0
|
||||||
|
go install github.com/client9/misspell/cmd/misspell@v0.3.4
|
||||||
|
go install github.com/daixiang0/gci@v0.11.2
|
||||||
|
|
||||||
|
lint: format-tools
|
||||||
|
golangci-lint run --tests=false
|
||||||
|
find . -name '*.go' -type f -not -path "./vendor*" -not -path "./tests/system/vendor*" -not -path "*.git*" -not -path "*_test.go" | xargs gofumpt -d
|
||||||
|
|
||||||
|
format: format-tools
|
||||||
|
find . -name '*.go' -type f -not -path "./vendor*" -not -path "./tests/system/vendor*" -not -path "*.git*" -not -path "./client/lcd/statik/statik.go" | xargs gofumpt -w
|
||||||
|
find . -name '*.go' -type f -not -path "./vendor*" -not -path "./tests/system/vendor*" -not -path "*.git*" -not -path "./client/lcd/statik/statik.go" | xargs misspell -w
|
||||||
|
find . -name '*.go' -type f -not -path "./vendor*" -not -path "./tests/system/vendor*" -not -path "*.git*" -not -path "./client/lcd/statik/statik.go" | xargs gci write --skip-generated -s standard -s default -s "prefix(cosmossdk.io)" -s "prefix(github.com/cosmos/cosmos-sdk)" -s "prefix(github.com/CosmWasm/wasmd)" --custom-order
|
||||||
|
|
||||||
|
mod-tidy:
|
||||||
|
go mod tidy
|
||||||
|
|
||||||
|
.PHONY: format-tools lint format mod-tidy
|
||||||
|
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
### Protobuf ###
|
||||||
|
###############################################################################
|
||||||
|
protoVer=0.15.1
|
||||||
|
protoImageName=ghcr.io/cosmos/proto-builder:$(protoVer)
|
||||||
|
protoImage=$(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace $(protoImageName)
|
||||||
|
|
||||||
|
proto-gen:
|
||||||
|
@echo "Generating Protobuf files"
|
||||||
|
@go install cosmossdk.io/orm/cmd/protoc-gen-go-cosmos-orm@latest
|
||||||
|
@$(protoImage) sh ./scripts/protocgen.sh
|
||||||
|
spawn stub-gen
|
||||||
|
|
||||||
|
proto-format:
|
||||||
|
@echo "Formatting Protobuf files"
|
||||||
|
@$(protoImage) find ./ -name "*.proto" -exec clang-format -i {} \;
|
||||||
|
|
||||||
|
proto-lint:
|
||||||
|
@$(protoImage) buf lint --error-format=json
|
||||||
|
|
||||||
|
proto-check-breaking:
|
||||||
|
@$(protoImage) buf breaking --against $(HTTPS_GIT)#branch=master
|
||||||
|
|
||||||
|
.PHONY: all install install-debug \
|
||||||
|
go-mod-cache draw-deps clean build format \
|
||||||
|
test test-all test-build test-cover test-unit test-race \
|
||||||
|
test-sim-import-export build-windows-client \
|
||||||
|
test-system
|
||||||
|
|
||||||
|
## --- Testnet Utilities ---
|
||||||
|
get-localic:
|
||||||
|
@echo "Installing local-interchain"
|
||||||
|
git clone --branch v8.7.0 https://github.com/strangelove-ventures/interchaintest.git interchaintest-downloader
|
||||||
|
cd interchaintest-downloader/local-interchain && make install
|
||||||
|
@echo ✅ local-interchain installed $(shell which local-ic)
|
||||||
|
|
||||||
|
is-localic-installed:
|
||||||
|
ifeq (,$(shell which local-ic))
|
||||||
|
make get-localic
|
||||||
|
endif
|
||||||
|
|
||||||
|
get-heighliner:
|
||||||
|
git clone https://github.com/strangelove-ventures/heighliner.git
|
||||||
|
cd heighliner && go install
|
||||||
|
|
||||||
|
local-image:
|
||||||
|
ifeq (,$(shell which heighliner))
|
||||||
|
echo 'heighliner' binary not found. Consider running `make get-heighliner`
|
||||||
|
else
|
||||||
|
heighliner build -c sonrd --local -f chains.yaml
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: get-heighliner local-image is-localic-installed
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
### e2e ###
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
ictest-basic:
|
||||||
|
@echo "Running basic interchain tests"
|
||||||
|
@cd interchaintest && go test -race -v -run TestBasicChain .
|
||||||
|
|
||||||
|
ictest-ibc:
|
||||||
|
@echo "Running IBC interchain tests"
|
||||||
|
@cd interchaintest && go test -race -v -run TestIBC .
|
||||||
|
|
||||||
|
ictest-wasm:
|
||||||
|
@echo "Running cosmwasm interchain tests"
|
||||||
|
@cd interchaintest && go test -race -v -run TestCosmWasmIntegration .
|
||||||
|
|
||||||
|
ictest-packetforward:
|
||||||
|
@echo "Running packet forward middleware interchain tests"
|
||||||
|
@cd interchaintest && go test -race -v -run TestPacketForwardMiddleware .
|
||||||
|
|
||||||
|
ictest-poa:
|
||||||
|
@echo "Running proof of authority interchain tests"
|
||||||
|
@cd interchaintest && go test -race -v -run TestPOA .
|
||||||
|
|
||||||
|
ictest-tokenfactory:
|
||||||
|
@echo "Running token factory interchain tests"
|
||||||
|
@cd interchaintest && go test -race -v -run TestTokenFactory .
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
### testnet ###
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
setup-ipfs:
|
||||||
|
./scripts/ipfs_config.sh
|
||||||
|
|
||||||
|
setup-testnet: mod-tidy is-localic-installed install local-image set-testnet-configs setup-testnet-keys
|
||||||
|
|
||||||
|
# Run this before testnet keys are added
|
||||||
|
# chainid-1 is used in the testnet.json
|
||||||
|
set-testnet-configs:
|
||||||
|
sonrd config set client chain-id sonr-testnet-1
|
||||||
|
sonrd config set client keyring-backend test
|
||||||
|
sonrd config set client output text
|
||||||
|
|
||||||
|
# import keys from testnet.json into test keyring
|
||||||
|
setup-testnet-keys:
|
||||||
|
-`echo "decorate bright ozone fork gallery riot bus exhaust worth way bone indoor calm squirrel merry zero scheme cotton until shop any excess stage laundry" | sonrd keys add acc0 --recover`
|
||||||
|
-`echo "wealth flavor believe regret funny network recall kiss grape useless pepper cram hint member few certain unveil rather brick bargain curious require crowd raise" | sonrd keys add acc1 --recover`
|
||||||
|
|
||||||
|
# default testnet is with IBC
|
||||||
|
testnet: setup-testnet
|
||||||
|
spawn local-ic start ibc-testnet
|
||||||
|
|
||||||
|
testnet-basic: setup-testnet
|
||||||
|
spawn local-ic start testnet
|
||||||
|
|
||||||
|
sh-testnet: mod-tidy
|
||||||
|
CHAIN_ID="sonr-testnet-1" BLOCK_TIME="1000ms" CLEAN=true sh scripts/test_node.sh
|
||||||
|
|
||||||
|
.PHONY: setup-testnet set-testnet-configs testnet testnet-basic sh-testnet dop-testnet
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
### help ###
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
help:
|
||||||
|
@echo "Usage: make <target>"
|
||||||
|
@echo ""
|
||||||
|
@echo "Available targets:"
|
||||||
|
@echo " install : Install the binary"
|
||||||
|
@echo " local-image : Install the docker image"
|
||||||
|
@echo " proto-gen : Generate code from proto files"
|
||||||
|
@echo " testnet : Local devnet with IBC"
|
||||||
|
@echo " sh-testnet : Shell local devnet"
|
||||||
|
@echo " ictest-basic : Basic end-to-end test"
|
||||||
|
@echo " ictest-ibc : IBC end-to-end test"
|
||||||
|
|
||||||
|
.PHONY: help
|
33
app/routes.go
Normal file
33
app/routes.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Package gateway provides the default routes for the Sonr hway.
|
||||||
|
package gateway
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/labstack/echo-contrib/echoprometheus"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
echomiddleware "github.com/labstack/echo/v4/middleware"
|
||||||
|
"github.com/onsonr/sonr/gateway/context"
|
||||||
|
"github.com/onsonr/sonr/gateway/handlers"
|
||||||
|
"github.com/onsonr/sonr/internal/common"
|
||||||
|
config "github.com/onsonr/sonr/internal/config/hway"
|
||||||
|
hwayorm "github.com/onsonr/sonr/internal/database/hwayorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Gateway = *echo.Echo
|
||||||
|
|
||||||
|
// New returns a new Gateway instance
|
||||||
|
func New(env config.Hway, ipc common.IPFS, dbq *hwayorm.Queries) (Gateway, error) {
|
||||||
|
e := echo.New()
|
||||||
|
|
||||||
|
// Built-in middleware
|
||||||
|
e.Use(echomiddleware.Logger())
|
||||||
|
e.Use(echomiddleware.Recover())
|
||||||
|
e.IPExtractor = echo.ExtractIPDirect()
|
||||||
|
e.Use(echoprometheus.NewMiddleware("hway"))
|
||||||
|
e.Use(context.UseGateway(env, ipc, dbq))
|
||||||
|
|
||||||
|
// Register View Handlers
|
||||||
|
e.HTTPErrorHandler = handlers.ErrorHandler
|
||||||
|
e.GET("/", handlers.IndexHandler)
|
||||||
|
handlers.RegisterHandler(e.Group("/register"))
|
||||||
|
return e, nil
|
||||||
|
}
|
92
cmd/cmds.go
Normal file
92
cmd/cmds.go
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/onsonr/sonr/gateway"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Command line flags
|
||||||
|
var (
|
||||||
|
servePort int // Gateway http entry point (default 3000)
|
||||||
|
chainID string // Current chain ID (default sonr-testnet-1)
|
||||||
|
ipfsGatewayURL string // IPFS gateway URL (default localhost:8080)
|
||||||
|
sonrAPIURL string // Sonr API URL (default localhost:1317)
|
||||||
|
sonrGrpcURL string // Sonr gRPC URL (default localhost:9090)
|
||||||
|
sonrRPCURL string // Sonr RPC URL (default localhost:26657)
|
||||||
|
|
||||||
|
psqlHost string // PostgresSQL Host Flag
|
||||||
|
psqlPort string // PostgresSQL Port Flag
|
||||||
|
psqlUser string // PostgresSQL User Flag
|
||||||
|
psqlPass string // PostgresSQL Password Flag
|
||||||
|
psqlDB string // PostgresSQL Database Flag
|
||||||
|
)
|
||||||
|
|
||||||
|
func rootCmd() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "hway",
|
||||||
|
Short: "Sonr DID gateway",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
env, err := loadEnvImplFromArgs(args)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
ipc, err := common.NewIPFS()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
dbq, err := setupPostgresDB()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
e, err := gateway.New(env, ipc, dbq)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if err := e.Start(fmt.Sprintf(":%d", env.GetServePort())); err != http.ErrServerClosed {
|
||||||
|
log.Fatal(err)
|
||||||
|
os.Exit(1)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cmd.Flags().IntVar(&servePort, "serve-port", 3000, "Port to serve the gateway on")
|
||||||
|
cmd.Flags().StringVar(&chainID, "chain-id", "sonr-testnet-1", "Chain ID")
|
||||||
|
cmd.Flags().StringVar(&ipfsGatewayURL, "ipfs-gateway-url", "localhost:8080", "IPFS gateway URL")
|
||||||
|
cmd.Flags().StringVar(&sonrAPIURL, "sonr-api-url", "localhost:1317", "Sonr API URL")
|
||||||
|
cmd.Flags().StringVar(&sonrGrpcURL, "sonr-grpc-url", "localhost:9090", "Sonr gRPC URL")
|
||||||
|
cmd.Flags().StringVar(&sonrRPCURL, "sonr-rpc-url", "localhost:26657", "Sonr RPC URL")
|
||||||
|
cmd.Flags().StringVar(&psqlHost, "psql-host", "localhost", "PostgresSQL Host")
|
||||||
|
cmd.Flags().StringVar(&psqlPort, "psql-port", "5432", "PostgresSQL Port")
|
||||||
|
cmd.Flags().StringVar(&psqlUser, "psql-user", "highway_user", "PostgresSQL User")
|
||||||
|
cmd.Flags().StringVar(&psqlPass, "psql-pass", "highway_password123", "PostgresSQL Password")
|
||||||
|
cmd.Flags().StringVar(&psqlDB, "psql-db", "highway", "PostgresSQL Database")
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatPsqlDSN() string {
|
||||||
|
if psqlHost == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
host := psqlHost
|
||||||
|
port := "5432"
|
||||||
|
|
||||||
|
if parts := strings.Split(psqlHost, ":"); len(parts) == 2 {
|
||||||
|
host = parts[0]
|
||||||
|
port = parts[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
dsn := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=verify-full",
|
||||||
|
host, port, psqlUser, psqlPass, psqlDB)
|
||||||
|
|
||||||
|
log.Printf("Attempting to connect to PostgreSQL with DSN: host=%s port=%s user=%s dbname=%s",
|
||||||
|
host, port, psqlUser, psqlDB) // Don't log the password
|
||||||
|
|
||||||
|
return dsn
|
||||||
|
}
|
48
cmd/main.go
Normal file
48
cmd/main.go
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
_ "embed"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/jackc/pgx/v5"
|
||||||
|
hwayorm "github.com/onsonr/sonr/internal/database/hwayorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// main is the entry point for the application
|
||||||
|
func main() {
|
||||||
|
cmd := rootCmd()
|
||||||
|
if err := cmd.Execute(); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadEnvImplFromArgs(args []string) (config.Hway, error) {
|
||||||
|
cmd := rootCmd()
|
||||||
|
if err := cmd.ParseFlags(args); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
env := &config.HwayImpl{
|
||||||
|
ServePort: servePort,
|
||||||
|
ChainId: chainID,
|
||||||
|
IpfsGatewayUrl: ipfsGatewayURL,
|
||||||
|
SonrApiUrl: sonrAPIURL,
|
||||||
|
SonrGrpcUrl: sonrGrpcURL,
|
||||||
|
SonrRpcUrl: sonrRPCURL,
|
||||||
|
PsqlDSN: formatPsqlDSN(),
|
||||||
|
}
|
||||||
|
return env, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupPostgresDB() (*hwayorm.Queries, error) {
|
||||||
|
pgdsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s sslmode=disable", psqlHost, psqlUser, psqlPass, psqlDB)
|
||||||
|
conn, err := pgx.Connect(context.Background(), pgdsn)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return hwayorm.New(conn), nil
|
||||||
|
}
|
289
go.mod
Normal file
289
go.mod
Normal file
@ -0,0 +1,289 @@
|
|||||||
|
module github.com/onsonr/hway
|
||||||
|
|
||||||
|
go 1.23.4
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/a-h/templ v0.3.819
|
||||||
|
github.com/go-webauthn/webauthn v0.11.2
|
||||||
|
github.com/jackc/pgx/v5 v5.7.2
|
||||||
|
github.com/labstack/echo-contrib v0.17.2
|
||||||
|
github.com/labstack/echo/v4 v4.13.3
|
||||||
|
github.com/medama-io/go-useragent v1.0.1
|
||||||
|
github.com/onsonr/sonr v0.6.1
|
||||||
|
github.com/segmentio/ksuid v1.0.4
|
||||||
|
github.com/spf13/cobra v1.8.1
|
||||||
|
lukechampine.com/blake3 v1.3.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
cosmossdk.io/api v0.7.6 // indirect
|
||||||
|
cosmossdk.io/collections v0.4.0 // indirect
|
||||||
|
cosmossdk.io/core v0.12.0 // indirect
|
||||||
|
cosmossdk.io/depinject v1.0.0-alpha.4 // indirect
|
||||||
|
cosmossdk.io/errors v1.0.1 // indirect
|
||||||
|
cosmossdk.io/log v1.3.1 // indirect
|
||||||
|
cosmossdk.io/math v1.3.0 // indirect
|
||||||
|
cosmossdk.io/orm v1.0.0-beta.3 // indirect
|
||||||
|
cosmossdk.io/store v1.1.0 // indirect
|
||||||
|
cosmossdk.io/x/tx v0.13.5 // indirect
|
||||||
|
filippo.io/edwards25519 v1.1.0 // indirect
|
||||||
|
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
|
||||||
|
github.com/99designs/keyring v1.2.1 // indirect
|
||||||
|
github.com/DataDog/datadog-go v3.2.0+incompatible // indirect
|
||||||
|
github.com/DataDog/zstd v1.5.5 // indirect
|
||||||
|
github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect
|
||||||
|
github.com/apple/pkl-go v0.8.0 // indirect
|
||||||
|
github.com/benbjohnson/clock v1.3.5 // indirect
|
||||||
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
|
github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect
|
||||||
|
github.com/bits-and-blooms/bitset v1.19.1 // indirect
|
||||||
|
github.com/blang/semver/v4 v4.0.0 // indirect
|
||||||
|
github.com/boyter/go-string v1.0.5 // indirect
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
|
||||||
|
github.com/bwesterb/go-ristretto v1.2.3 // indirect
|
||||||
|
github.com/caddyserver/certmagic v0.21.4 // indirect
|
||||||
|
github.com/caddyserver/zerossl v0.1.3 // indirect
|
||||||
|
github.com/cespare/xxhash v1.1.0 // indirect
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
|
github.com/cockroachdb/errors v1.11.3 // indirect
|
||||||
|
github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect
|
||||||
|
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
|
||||||
|
github.com/cockroachdb/pebble v1.1.2 // indirect
|
||||||
|
github.com/cockroachdb/redact v1.1.5 // indirect
|
||||||
|
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
|
||||||
|
github.com/cometbft/cometbft v0.38.12 // indirect
|
||||||
|
github.com/cometbft/cometbft-db v0.11.0 // indirect
|
||||||
|
github.com/consensys/bavard v0.1.24 // indirect
|
||||||
|
github.com/consensys/gnark-crypto v0.14.0 // indirect
|
||||||
|
github.com/cosmos/btcutil v1.0.5 // indirect
|
||||||
|
github.com/cosmos/cosmos-db v1.1.1 // indirect
|
||||||
|
github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect
|
||||||
|
github.com/cosmos/cosmos-sdk v0.50.5 // indirect
|
||||||
|
github.com/cosmos/go-bip39 v1.0.0 // indirect
|
||||||
|
github.com/cosmos/gogoproto v1.7.0 // indirect
|
||||||
|
github.com/cosmos/iavl v1.1.2 // indirect
|
||||||
|
github.com/cosmos/ics23/go v0.10.0 // indirect
|
||||||
|
github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect
|
||||||
|
github.com/crackcomm/go-gitignore v0.0.0-20241020182519-7843d2ba8fdf // indirect
|
||||||
|
github.com/danieljoos/wincred v1.1.2 // indirect
|
||||||
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||||
|
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
|
||||||
|
github.com/dgraph-io/badger/v2 v2.2007.4 // indirect
|
||||||
|
github.com/dgraph-io/ristretto v0.1.1 // indirect
|
||||||
|
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect
|
||||||
|
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||||
|
github.com/dustinxie/ecc v0.0.0-20210511000915-959544187564 // indirect
|
||||||
|
github.com/dvsekhvalnov/jose2go v1.6.0 // indirect
|
||||||
|
github.com/emicklei/dot v1.6.1 // indirect
|
||||||
|
github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 // indirect
|
||||||
|
github.com/flynn/noise v1.1.0 // indirect
|
||||||
|
github.com/francoispqt/gojay v1.2.13 // indirect
|
||||||
|
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||||
|
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
|
||||||
|
github.com/getsentry/sentry-go v0.27.0 // indirect
|
||||||
|
github.com/go-kit/kit v0.12.0 // indirect
|
||||||
|
github.com/go-kit/log v0.2.1 // indirect
|
||||||
|
github.com/go-logfmt/logfmt v0.6.0 // indirect
|
||||||
|
github.com/go-logr/logr v1.4.2 // indirect
|
||||||
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
|
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
||||||
|
github.com/go-webauthn/x v0.1.14 // indirect
|
||||||
|
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
|
||||||
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
|
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||||
|
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
|
||||||
|
github.com/golang/glog v1.2.2 // indirect
|
||||||
|
github.com/golang/protobuf v1.5.4 // indirect
|
||||||
|
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
|
||||||
|
github.com/google/btree v1.1.3 // indirect
|
||||||
|
github.com/google/go-cmp v0.6.0 // indirect
|
||||||
|
github.com/google/go-tpm v0.9.1 // indirect
|
||||||
|
github.com/google/gopacket v1.1.19 // indirect
|
||||||
|
github.com/google/pprof v0.0.0-20241203143554-1e3fdc7de467 // indirect
|
||||||
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
|
github.com/gorilla/websocket v1.5.3 // indirect
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
|
||||||
|
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
|
||||||
|
github.com/gtank/merlin v0.1.1 // indirect
|
||||||
|
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||||
|
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||||
|
github.com/hashicorp/go-metrics v0.5.3 // indirect
|
||||||
|
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||||
|
github.com/hashicorp/golang-lru v1.0.2 // indirect
|
||||||
|
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||||
|
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||||
|
github.com/hdevalence/ed25519consensus v0.1.0 // indirect
|
||||||
|
github.com/huin/goupnp v1.3.0 // indirect
|
||||||
|
github.com/iancoleman/strcase v0.3.0 // indirect
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
|
github.com/ipfs/bbloom v0.0.4 // indirect
|
||||||
|
github.com/ipfs/boxo v0.24.3 // indirect
|
||||||
|
github.com/ipfs/go-bitfield v1.1.0 // indirect
|
||||||
|
github.com/ipfs/go-block-format v0.2.0 // indirect
|
||||||
|
github.com/ipfs/go-cid v0.4.1 // indirect
|
||||||
|
github.com/ipfs/go-datastore v0.6.0 // indirect
|
||||||
|
github.com/ipfs/go-ds-measure v0.2.0 // indirect
|
||||||
|
github.com/ipfs/go-fs-lock v0.0.7 // indirect
|
||||||
|
github.com/ipfs/go-ipfs-cmds v0.14.0 // indirect
|
||||||
|
github.com/ipfs/go-ipfs-util v0.0.3 // indirect
|
||||||
|
github.com/ipfs/go-ipld-cbor v0.2.0 // indirect
|
||||||
|
github.com/ipfs/go-ipld-format v0.6.0 // indirect
|
||||||
|
github.com/ipfs/go-ipld-legacy v0.2.1 // indirect
|
||||||
|
github.com/ipfs/go-log v1.0.5 // indirect
|
||||||
|
github.com/ipfs/go-log/v2 v2.5.1 // indirect
|
||||||
|
github.com/ipfs/go-metrics-interface v0.0.1 // indirect
|
||||||
|
github.com/ipfs/go-unixfsnode v1.9.2 // indirect
|
||||||
|
github.com/ipfs/kubo v0.32.1 // indirect
|
||||||
|
github.com/ipld/go-car/v2 v2.14.2 // indirect
|
||||||
|
github.com/ipld/go-codec-dagpb v1.6.0 // indirect
|
||||||
|
github.com/ipld/go-ipld-prime v0.21.0 // indirect
|
||||||
|
github.com/ipshipyard/p2p-forge v0.0.2 // indirect
|
||||||
|
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||||
|
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
|
||||||
|
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
|
||||||
|
github.com/jbenet/goprocess v0.1.4 // indirect
|
||||||
|
github.com/jmhodges/levigo v1.0.0 // indirect
|
||||||
|
github.com/klauspost/compress v1.17.11 // indirect
|
||||||
|
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
|
||||||
|
github.com/koron/go-ssdp v0.0.4 // indirect
|
||||||
|
github.com/kr/pretty v0.3.1 // indirect
|
||||||
|
github.com/kr/text v0.2.0 // indirect
|
||||||
|
github.com/labstack/gommon v0.4.2 // indirect
|
||||||
|
github.com/libdns/libdns v0.2.2 // indirect
|
||||||
|
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
|
||||||
|
github.com/libp2p/go-cidranger v1.1.0 // indirect
|
||||||
|
github.com/libp2p/go-flow-metrics v0.2.0 // indirect
|
||||||
|
github.com/libp2p/go-libp2p v0.37.2 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-kad-dht v0.28.1 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-kbucket v0.6.4 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-record v0.2.0 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-routing-helpers v0.7.4 // indirect
|
||||||
|
github.com/libp2p/go-msgio v0.3.0 // indirect
|
||||||
|
github.com/libp2p/go-nat v0.2.0 // indirect
|
||||||
|
github.com/libp2p/go-netroute v0.2.2 // indirect
|
||||||
|
github.com/linxGnu/grocksdb v1.8.14 // indirect
|
||||||
|
github.com/magiconair/properties v1.8.7 // indirect
|
||||||
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
|
github.com/mholt/acmez/v2 v2.0.3 // indirect
|
||||||
|
github.com/miekg/dns v1.1.62 // indirect
|
||||||
|
github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 // indirect
|
||||||
|
github.com/minio/sha256-simd v1.0.1 // indirect
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
|
github.com/mmcloughlin/addchain v0.4.0 // indirect
|
||||||
|
github.com/mr-tron/base58 v1.2.0 // indirect
|
||||||
|
github.com/mtibben/percent v0.2.1 // indirect
|
||||||
|
github.com/multiformats/go-base32 v0.1.0 // indirect
|
||||||
|
github.com/multiformats/go-base36 v0.2.0 // indirect
|
||||||
|
github.com/multiformats/go-multiaddr v0.14.0 // indirect
|
||||||
|
github.com/multiformats/go-multiaddr-dns v0.4.1 // indirect
|
||||||
|
github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect
|
||||||
|
github.com/multiformats/go-multibase v0.2.0 // indirect
|
||||||
|
github.com/multiformats/go-multicodec v0.9.0 // indirect
|
||||||
|
github.com/multiformats/go-multihash v0.2.3 // indirect
|
||||||
|
github.com/multiformats/go-multistream v0.6.0 // indirect
|
||||||
|
github.com/multiformats/go-varint v0.0.7 // indirect
|
||||||
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
|
github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a // indirect
|
||||||
|
github.com/onsi/ginkgo/v2 v2.22.0 // indirect
|
||||||
|
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||||
|
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||||
|
github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect
|
||||||
|
github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67 // indirect
|
||||||
|
github.com/pion/datachannel v1.5.9 // indirect
|
||||||
|
github.com/pion/dtls/v2 v2.2.12 // indirect
|
||||||
|
github.com/pion/ice/v2 v2.3.37 // indirect
|
||||||
|
github.com/pion/interceptor v0.1.37 // indirect
|
||||||
|
github.com/pion/logging v0.2.2 // indirect
|
||||||
|
github.com/pion/mdns v0.0.12 // indirect
|
||||||
|
github.com/pion/randutil v0.1.0 // indirect
|
||||||
|
github.com/pion/rtcp v1.2.14 // indirect
|
||||||
|
github.com/pion/rtp v1.8.9 // indirect
|
||||||
|
github.com/pion/sctp v1.8.34 // indirect
|
||||||
|
github.com/pion/sdp/v3 v3.0.9 // indirect
|
||||||
|
github.com/pion/srtp/v2 v2.0.20 // indirect
|
||||||
|
github.com/pion/stun v0.6.1 // indirect
|
||||||
|
github.com/pion/transport/v2 v2.2.10 // indirect
|
||||||
|
github.com/pion/turn/v2 v2.1.6 // indirect
|
||||||
|
github.com/pion/webrtc/v3 v3.3.4 // indirect
|
||||||
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||||
|
github.com/polydawn/refmt v0.89.0 // indirect
|
||||||
|
github.com/prometheus/client_golang v1.20.5 // indirect
|
||||||
|
github.com/prometheus/client_model v0.6.1 // indirect
|
||||||
|
github.com/prometheus/common v0.61.0 // indirect
|
||||||
|
github.com/prometheus/procfs v0.15.1 // indirect
|
||||||
|
github.com/quic-go/qpack v0.5.1 // indirect
|
||||||
|
github.com/quic-go/quic-go v0.48.2 // indirect
|
||||||
|
github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 // indirect
|
||||||
|
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
|
||||||
|
github.com/rogpeppe/go-internal v1.13.1 // indirect
|
||||||
|
github.com/rs/cors v1.11.1 // indirect
|
||||||
|
github.com/rs/zerolog v1.32.0 // indirect
|
||||||
|
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||||
|
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||||
|
github.com/samber/lo v1.47.0 // indirect
|
||||||
|
github.com/sasha-s/go-deadlock v0.3.1 // indirect
|
||||||
|
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||||
|
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||||
|
github.com/spf13/afero v1.11.0 // indirect
|
||||||
|
github.com/spf13/cast v1.7.1 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
|
github.com/spf13/viper v1.19.0 // indirect
|
||||||
|
github.com/stretchr/testify v1.10.0 // indirect
|
||||||
|
github.com/subosito/gotenv v1.6.0 // indirect
|
||||||
|
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
|
||||||
|
github.com/tendermint/go-amino v0.16.0 // indirect
|
||||||
|
github.com/tidwall/btree v1.7.0 // indirect
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
|
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||||
|
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
|
||||||
|
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||||
|
github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect
|
||||||
|
github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect
|
||||||
|
github.com/whyrusleeping/cbor-gen v0.1.2 // indirect
|
||||||
|
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect
|
||||||
|
github.com/wlynxg/anet v0.0.5 // indirect
|
||||||
|
github.com/x448/float16 v0.8.4 // indirect
|
||||||
|
github.com/zeebo/blake3 v0.2.4 // indirect
|
||||||
|
github.com/zondax/hid v0.9.2 // indirect
|
||||||
|
github.com/zondax/ledger-go v0.14.3 // indirect
|
||||||
|
go.etcd.io/bbolt v1.3.10 // indirect
|
||||||
|
go.opencensus.io v0.24.0 // indirect
|
||||||
|
go.opentelemetry.io/otel v1.31.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/metric v1.31.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/trace v1.31.0 // indirect
|
||||||
|
go.uber.org/dig v1.18.0 // indirect
|
||||||
|
go.uber.org/fx v1.23.0 // indirect
|
||||||
|
go.uber.org/mock v0.5.0 // indirect
|
||||||
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
|
go.uber.org/zap v1.27.0 // indirect
|
||||||
|
go4.org v0.0.0-20230225012048-214862532bf5 // indirect
|
||||||
|
golang.org/x/crypto v0.31.0 // indirect
|
||||||
|
golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d // indirect
|
||||||
|
golang.org/x/mod v0.22.0 // indirect
|
||||||
|
golang.org/x/net v0.33.0 // indirect
|
||||||
|
golang.org/x/sync v0.10.0 // indirect
|
||||||
|
golang.org/x/sys v0.28.0 // indirect
|
||||||
|
golang.org/x/term v0.27.0 // indirect
|
||||||
|
golang.org/x/text v0.21.0 // indirect
|
||||||
|
golang.org/x/time v0.8.0 // indirect
|
||||||
|
golang.org/x/tools v0.28.0 // indirect
|
||||||
|
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
|
||||||
|
gonum.org/v1/gonum v0.15.0 // indirect
|
||||||
|
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 // indirect
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect
|
||||||
|
google.golang.org/grpc v1.69.2 // indirect
|
||||||
|
google.golang.org/protobuf v1.36.1 // indirect
|
||||||
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
gotest.tools/v3 v3.5.1 // indirect
|
||||||
|
pgregory.net/rapid v1.1.0 // indirect
|
||||||
|
rsc.io/tmplfunc v0.0.3 // indirect
|
||||||
|
sigs.k8s.io/yaml v1.4.0 // indirect
|
||||||
|
)
|
16
handlers/errors.go
Normal file
16
handlers/errors.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/onsonr/sonr/gateway/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ErrorHandler(err error, c echo.Context) {
|
||||||
|
if he, ok := err.(*echo.HTTPError); ok {
|
||||||
|
if he.Code == 500 {
|
||||||
|
// Log the error if needed
|
||||||
|
c.Logger().Errorf("Error: %v", he.Message)
|
||||||
|
context.RenderError(c, he)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
handlers/index.go
Normal file
14
handlers/index.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/onsonr/sonr/gateway/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
func IndexHandler(c echo.Context) error {
|
||||||
|
id := context.GetSessionID(c)
|
||||||
|
if id == "" {
|
||||||
|
context.NewSession(c)
|
||||||
|
}
|
||||||
|
return context.RenderInitial(c)
|
||||||
|
}
|
1
handlers/login.go
Normal file
1
handlers/login.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package handlers
|
111
handlers/register.go
Normal file
111
handlers/register.go
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/onsonr/sonr/gateway/islands"
|
||||||
|
"github.com/onsonr/sonr/gateway/views"
|
||||||
|
"github.com/onsonr/sonr/gateway/context"
|
||||||
|
"github.com/onsonr/sonr/internal/common"
|
||||||
|
hwayorm "github.com/onsonr/sonr/internal/database/hwayorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RegisterHandler(g *echo.Group) {
|
||||||
|
g.GET("/start", renderProfileForm)
|
||||||
|
g.POST("/profile", validateProfileForm)
|
||||||
|
g.GET("/passkey", renderPasskeyForm)
|
||||||
|
g.POST("/passkey", validatePasskeyForm)
|
||||||
|
g.GET("/vault", renderVaultStatus)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ╭──────────────────────────────────────────────────────╮
|
||||||
|
// │ Registration Views │
|
||||||
|
// ╰──────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
func renderProfileForm(c echo.Context) error {
|
||||||
|
params := context.CreateProfileParams{
|
||||||
|
FirstNumber: 6,
|
||||||
|
LastNumber: 3,
|
||||||
|
}
|
||||||
|
return context.Render(c, views.RegisterProfileView(params.FirstNumber, params.LastNumber))
|
||||||
|
}
|
||||||
|
|
||||||
|
func renderPasskeyForm(c echo.Context) error {
|
||||||
|
cc, err := context.GetGateway(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
handle := c.FormValue("handle")
|
||||||
|
origin := c.FormValue("origin")
|
||||||
|
name := c.FormValue("name")
|
||||||
|
cc.InsertProfile(context.BG(), hwayorm.InsertProfileParams{
|
||||||
|
Handle: handle,
|
||||||
|
Origin: origin,
|
||||||
|
Name: name,
|
||||||
|
})
|
||||||
|
|
||||||
|
params, err := cc.Spawn(handle, origin)
|
||||||
|
if err != nil {
|
||||||
|
return context.RenderError(c, err)
|
||||||
|
}
|
||||||
|
return context.Render(c, views.RegisterPasskeyView(params.Address, params.Handle, params.Name, params.Challenge, params.CreationBlock))
|
||||||
|
}
|
||||||
|
|
||||||
|
func renderVaultStatus(c echo.Context) error {
|
||||||
|
return context.Render(c, views.LoadingView())
|
||||||
|
}
|
||||||
|
|
||||||
|
// ╭─────────────────────────────────────────────────────────╮
|
||||||
|
// │ Validation Components │
|
||||||
|
// ╰─────────────────────────────────────────────────────────╯
|
||||||
|
|
||||||
|
func validateProfileForm(c echo.Context) error {
|
||||||
|
cc, err := context.GetGateway(c)
|
||||||
|
if err != nil {
|
||||||
|
return context.RenderError(c, err)
|
||||||
|
}
|
||||||
|
handle := c.FormValue("handle")
|
||||||
|
if handle == "" {
|
||||||
|
return context.Render(c, islands.InputHandleError(handle, "Please enter a 4-16 character handle"))
|
||||||
|
}
|
||||||
|
notok, err := cc.CheckHandleExists(context.BG(), handle)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if notok {
|
||||||
|
return context.Render(c, islands.InputHandleError(handle, "Handle is already taken"))
|
||||||
|
}
|
||||||
|
cc.WriteCookie(common.UserHandle, handle)
|
||||||
|
return context.Render(c, islands.InputHandleSuccess(handle))
|
||||||
|
}
|
||||||
|
|
||||||
|
func validatePasskeyForm(c echo.Context) error {
|
||||||
|
cc, err := context.GetGateway(c)
|
||||||
|
if err != nil {
|
||||||
|
return context.RenderError(c, err)
|
||||||
|
}
|
||||||
|
handle := context.GetProfileHandle(c)
|
||||||
|
origin := c.Request().Host
|
||||||
|
credentialJSON := c.FormValue("credential")
|
||||||
|
cred := &context.CredentialDescriptor{}
|
||||||
|
|
||||||
|
// Unmarshal the credential JSON
|
||||||
|
err = json.Unmarshal([]byte(credentialJSON), cred)
|
||||||
|
if err != nil {
|
||||||
|
return context.RenderError(c, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
md := cred.ToModel(handle, origin)
|
||||||
|
_, err = cc.InsertCredential(context.BG(), hwayorm.InsertCredentialParams{
|
||||||
|
Handle: md.Handle,
|
||||||
|
CredentialID: md.CredentialID,
|
||||||
|
Origin: md.Origin,
|
||||||
|
Type: md.Type,
|
||||||
|
Transports: md.Transports,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return context.RenderError(c, err)
|
||||||
|
}
|
||||||
|
return context.Render(c, views.LoadingView())
|
||||||
|
}
|
151
internal/sink/highway/query.sql
Normal file
151
internal/sink/highway/query.sql
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
-- name: InsertCredential :one
|
||||||
|
INSERT INTO credentials (
|
||||||
|
id,
|
||||||
|
created_at,
|
||||||
|
updated_at,
|
||||||
|
deleted_at,
|
||||||
|
handle,
|
||||||
|
credential_id,
|
||||||
|
authenticator_attachment,
|
||||||
|
origin,
|
||||||
|
type,
|
||||||
|
transports
|
||||||
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
|
RETURNING *;
|
||||||
|
|
||||||
|
-- name: InsertProfile :one
|
||||||
|
INSERT INTO profiles (
|
||||||
|
id,
|
||||||
|
created_at,
|
||||||
|
updated_at,
|
||||||
|
deleted_at,
|
||||||
|
address,
|
||||||
|
handle,
|
||||||
|
origin,
|
||||||
|
name,
|
||||||
|
status
|
||||||
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
|
RETURNING *;
|
||||||
|
|
||||||
|
-- name: GetProfileByID :one
|
||||||
|
SELECT * FROM profiles
|
||||||
|
WHERE id = ? AND deleted_at IS NULL
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
-- name: GetProfileByAddress :one
|
||||||
|
SELECT * FROM profiles
|
||||||
|
WHERE address = ? AND deleted_at IS NULL
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
-- name: GetChallengeBySessionID :one
|
||||||
|
SELECT challenge FROM sessions
|
||||||
|
WHERE id = ? AND deleted_at IS NULL
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
-- name: GetHumanVerificationNumbers :one
|
||||||
|
SELECT is_human_first, is_human_last FROM sessions
|
||||||
|
WHERE id = ? AND deleted_at IS NULL
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
-- name: GetSessionByID :one
|
||||||
|
SELECT * FROM sessions
|
||||||
|
WHERE id = ? AND deleted_at IS NULL
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
-- name: GetSessionByClientIP :one
|
||||||
|
SELECT * FROM sessions
|
||||||
|
WHERE client_ipaddr = ? AND deleted_at IS NULL
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
-- name: UpdateSessionHumanVerification :one
|
||||||
|
UPDATE sessions
|
||||||
|
SET
|
||||||
|
is_human_first = ?,
|
||||||
|
is_human_last = ?,
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE id = ?
|
||||||
|
RETURNING *;
|
||||||
|
|
||||||
|
-- name: UpdateSessionWithProfileID :one
|
||||||
|
UPDATE sessions
|
||||||
|
SET
|
||||||
|
profile_id = ?,
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE id = ?
|
||||||
|
RETURNING *;
|
||||||
|
|
||||||
|
-- name: CheckHandleExists :one
|
||||||
|
SELECT COUNT(*) > 0 as handle_exists FROM profiles
|
||||||
|
WHERE handle = ?
|
||||||
|
AND deleted_at IS NULL;
|
||||||
|
|
||||||
|
-- name: GetCredentialsByHandle :many
|
||||||
|
SELECT * FROM credentials
|
||||||
|
WHERE handle = ?
|
||||||
|
AND deleted_at IS NULL;
|
||||||
|
|
||||||
|
-- name: GetCredentialByID :one
|
||||||
|
SELECT * FROM credentials
|
||||||
|
WHERE credential_id = ?
|
||||||
|
AND deleted_at IS NULL
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
-- name: SoftDeleteCredential :exec
|
||||||
|
UPDATE credentials
|
||||||
|
SET deleted_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE credential_id = ?;
|
||||||
|
|
||||||
|
-- name: SoftDeleteProfile :exec
|
||||||
|
UPDATE profiles
|
||||||
|
SET deleted_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE id = ?;
|
||||||
|
|
||||||
|
-- name: UpdateProfile :one
|
||||||
|
UPDATE profiles
|
||||||
|
SET
|
||||||
|
name = ?,
|
||||||
|
handle = ?,
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE id = ?
|
||||||
|
AND deleted_at IS NULL
|
||||||
|
RETURNING *;
|
||||||
|
|
||||||
|
-- name: GetProfileByHandle :one
|
||||||
|
SELECT * FROM profiles
|
||||||
|
WHERE handle = ?
|
||||||
|
AND deleted_at IS NULL
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
-- name: GetVaultConfigByCID :one
|
||||||
|
SELECT * FROM vaults
|
||||||
|
WHERE cid = ?
|
||||||
|
AND deleted_at IS NULL
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
-- name: GetVaultRedirectURIBySessionID :one
|
||||||
|
SELECT redirect_uri FROM vaults
|
||||||
|
WHERE session_id = ?
|
||||||
|
AND deleted_at IS NULL
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
-- name: CreateSession :one
|
||||||
|
INSERT INTO sessions (
|
||||||
|
id,
|
||||||
|
created_at,
|
||||||
|
updated_at,
|
||||||
|
deleted_at,
|
||||||
|
browser_name,
|
||||||
|
browser_version,
|
||||||
|
client_ipaddr,
|
||||||
|
platform,
|
||||||
|
is_desktop,
|
||||||
|
is_mobile,
|
||||||
|
is_tablet,
|
||||||
|
is_tv,
|
||||||
|
is_bot,
|
||||||
|
challenge,
|
||||||
|
is_human_first,
|
||||||
|
is_human_last,
|
||||||
|
profile_id
|
||||||
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
|
RETURNING *;
|
122
internal/sink/highway/schema.sql
Normal file
122
internal/sink/highway/schema.sql
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
-- Profiles represent user identities
|
||||||
|
CREATE TABLE profiles (
|
||||||
|
id TEXT PRIMARY KEY,
|
||||||
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
deleted_at DATETIME,
|
||||||
|
address TEXT NOT NULL,
|
||||||
|
handle TEXT NOT NULL UNIQUE,
|
||||||
|
origin TEXT NOT NULL,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
status TEXT NOT NULL,
|
||||||
|
UNIQUE(address, origin)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Accounts represent blockchain accounts
|
||||||
|
CREATE TABLE accounts (
|
||||||
|
id TEXT PRIMARY KEY,
|
||||||
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
deleted_at DATETIME,
|
||||||
|
number INTEGER NOT NULL,
|
||||||
|
sequence INTEGER NOT NULL DEFAULT 0,
|
||||||
|
address TEXT NOT NULL UNIQUE,
|
||||||
|
public_key TEXT NOT NULL,
|
||||||
|
chain_id TEXT NOT NULL,
|
||||||
|
controller TEXT NOT NULL,
|
||||||
|
is_subsidiary INTEGER NOT NULL DEFAULT 0,
|
||||||
|
is_validator INTEGER NOT NULL DEFAULT 0,
|
||||||
|
is_delegator INTEGER NOT NULL DEFAULT 0,
|
||||||
|
is_accountable INTEGER NOT NULL DEFAULT 1
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Assets represent tokens and coins
|
||||||
|
CREATE TABLE assets (
|
||||||
|
id TEXT PRIMARY KEY,
|
||||||
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
deleted_at DATETIME,
|
||||||
|
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)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Credentials store WebAuthn credentials
|
||||||
|
CREATE TABLE credentials (
|
||||||
|
id TEXT PRIMARY KEY,
|
||||||
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
deleted_at DATETIME,
|
||||||
|
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
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Sessions track user authentication state
|
||||||
|
CREATE TABLE sessions (
|
||||||
|
id TEXT PRIMARY KEY,
|
||||||
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
deleted_at DATETIME,
|
||||||
|
browser_name TEXT NOT NULL,
|
||||||
|
browser_version TEXT NOT NULL,
|
||||||
|
client_ipaddr TEXT NOT NULL,
|
||||||
|
platform TEXT NOT NULL,
|
||||||
|
is_desktop INTEGER NOT NULL DEFAULT 0,
|
||||||
|
is_mobile INTEGER NOT NULL DEFAULT 0,
|
||||||
|
is_tablet INTEGER NOT NULL DEFAULT 0,
|
||||||
|
is_tv INTEGER NOT NULL DEFAULT 0,
|
||||||
|
is_bot INTEGER NOT NULL DEFAULT 0,
|
||||||
|
challenge TEXT NOT NULL,
|
||||||
|
is_human_first INTEGER NOT NULL DEFAULT 0,
|
||||||
|
is_human_last INTEGER NOT NULL DEFAULT 0,
|
||||||
|
profile_id TEXT NOT NULL,
|
||||||
|
FOREIGN KEY (profile_id) REFERENCES profiles(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Vaults store encrypted data
|
||||||
|
CREATE TABLE vaults (
|
||||||
|
id TEXT PRIMARY KEY,
|
||||||
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
deleted_at DATETIME,
|
||||||
|
handle TEXT NOT NULL,
|
||||||
|
origin TEXT NOT NULL,
|
||||||
|
address TEXT NOT NULL,
|
||||||
|
cid TEXT NOT NULL UNIQUE,
|
||||||
|
config TEXT NOT NULL,
|
||||||
|
session_id TEXT NOT NULL,
|
||||||
|
redirect_uri TEXT NOT NULL,
|
||||||
|
FOREIGN KEY (session_id) REFERENCES sessions(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Indexes for common queries
|
||||||
|
CREATE INDEX idx_profiles_handle ON profiles(handle);
|
||||||
|
CREATE INDEX idx_profiles_address ON profiles(address);
|
||||||
|
CREATE INDEX idx_profiles_origin ON profiles(origin);
|
||||||
|
CREATE INDEX idx_profiles_status ON profiles(status);
|
||||||
|
CREATE INDEX idx_profiles_deleted_at ON profiles(deleted_at);
|
||||||
|
|
||||||
|
CREATE INDEX idx_accounts_address ON accounts(address);
|
||||||
|
CREATE INDEX idx_accounts_chain_id ON accounts(chain_id);
|
||||||
|
CREATE INDEX idx_accounts_deleted_at ON accounts(deleted_at);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
CREATE INDEX idx_sessions_profile_id ON sessions(profile_id);
|
||||||
|
CREATE INDEX idx_sessions_client_ipaddr ON sessions(client_ipaddr);
|
||||||
|
CREATE INDEX idx_sessions_deleted_at ON sessions(deleted_at);
|
8
internal/sink/sink.go
Normal file
8
internal/sink/sink.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package sink
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "embed"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed vault/schema.sql
|
||||||
|
var SchemaVaultSQL string
|
138
internal/sink/vault/query.sql
Normal file
138
internal/sink/vault/query.sql
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
-- name: InsertCredential :one
|
||||||
|
INSERT INTO credentials (
|
||||||
|
handle,
|
||||||
|
credential_id,
|
||||||
|
origin,
|
||||||
|
type,
|
||||||
|
transports
|
||||||
|
) VALUES (?, ?, ?, ?, ?)
|
||||||
|
RETURNING *;
|
||||||
|
|
||||||
|
-- name: InsertProfile :one
|
||||||
|
INSERT INTO profiles (
|
||||||
|
address,
|
||||||
|
handle,
|
||||||
|
origin,
|
||||||
|
name
|
||||||
|
) VALUES (?, ?, ?, ?)
|
||||||
|
RETURNING *;
|
||||||
|
|
||||||
|
-- name: GetProfileByID :one
|
||||||
|
SELECT * FROM profiles
|
||||||
|
WHERE id = ? AND deleted_at IS NULL
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
-- name: GetProfileByAddress :one
|
||||||
|
SELECT * FROM profiles
|
||||||
|
WHERE address = ? AND deleted_at IS NULL
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
-- name: GetChallengeBySessionID :one
|
||||||
|
SELECT challenge FROM sessions
|
||||||
|
WHERE id = ? AND deleted_at IS NULL
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
-- name: GetHumanVerificationNumbers :one
|
||||||
|
SELECT is_human_first, is_human_last FROM sessions
|
||||||
|
WHERE id = ? AND deleted_at IS NULL
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
-- name: GetSessionByID :one
|
||||||
|
SELECT * FROM sessions
|
||||||
|
WHERE id = ? AND deleted_at IS NULL
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
-- name: GetSessionByClientIP :one
|
||||||
|
SELECT * FROM sessions
|
||||||
|
WHERE client_ipaddr = ? AND deleted_at IS NULL
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
-- name: UpdateSessionHumanVerification :one
|
||||||
|
UPDATE sessions
|
||||||
|
SET
|
||||||
|
is_human_first = ?,
|
||||||
|
is_human_last = ?,
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE id = ?
|
||||||
|
RETURNING *;
|
||||||
|
|
||||||
|
-- name: UpdateSessionWithProfileID :one
|
||||||
|
UPDATE sessions
|
||||||
|
SET
|
||||||
|
profile_id = ?,
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE id = ?
|
||||||
|
RETURNING *;
|
||||||
|
|
||||||
|
-- name: CheckHandleExists :one
|
||||||
|
SELECT COUNT(*) > 0 as handle_exists FROM profiles
|
||||||
|
WHERE handle = ?
|
||||||
|
AND deleted_at IS NULL;
|
||||||
|
|
||||||
|
-- name: GetCredentialsByHandle :many
|
||||||
|
SELECT * FROM credentials
|
||||||
|
WHERE handle = ?
|
||||||
|
AND deleted_at IS NULL;
|
||||||
|
|
||||||
|
-- name: GetCredentialByID :one
|
||||||
|
SELECT * FROM credentials
|
||||||
|
WHERE credential_id = ?
|
||||||
|
AND deleted_at IS NULL
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
-- name: SoftDeleteCredential :exec
|
||||||
|
UPDATE credentials
|
||||||
|
SET deleted_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE credential_id = ?;
|
||||||
|
|
||||||
|
-- name: SoftDeleteProfile :exec
|
||||||
|
UPDATE profiles
|
||||||
|
SET deleted_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE address = ?;
|
||||||
|
|
||||||
|
-- name: UpdateProfile :one
|
||||||
|
UPDATE profiles
|
||||||
|
SET
|
||||||
|
name = ?,
|
||||||
|
handle = ?,
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE address = ?
|
||||||
|
AND deleted_at IS NULL
|
||||||
|
RETURNING *;
|
||||||
|
|
||||||
|
-- name: GetProfileByHandle :one
|
||||||
|
SELECT * FROM profiles
|
||||||
|
WHERE handle = ?
|
||||||
|
AND deleted_at IS NULL
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
-- name: GetVaultConfigByCID :one
|
||||||
|
SELECT * FROM vaults
|
||||||
|
WHERE cid = ?
|
||||||
|
AND deleted_at IS NULL
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
-- name: GetVaultRedirectURIBySessionID :one
|
||||||
|
SELECT redirect_uri FROM vaults
|
||||||
|
WHERE session_id = ?
|
||||||
|
AND deleted_at IS NULL
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
-- name: CreateSession :one
|
||||||
|
INSERT INTO sessions (
|
||||||
|
id,
|
||||||
|
browser_name,
|
||||||
|
browser_version,
|
||||||
|
client_ipaddr,
|
||||||
|
platform,
|
||||||
|
is_desktop,
|
||||||
|
is_mobile,
|
||||||
|
is_tablet,
|
||||||
|
is_tv,
|
||||||
|
is_bot,
|
||||||
|
challenge,
|
||||||
|
is_human_first,
|
||||||
|
is_human_last,
|
||||||
|
profile_id
|
||||||
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
|
||||||
|
RETURNING *;
|
121
internal/sink/vault/schema.sql
Normal file
121
internal/sink/vault/schema.sql
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
-- 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)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 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,
|
||||||
|
controller 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))
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 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)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 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
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Sessions track user authentication state
|
||||||
|
CREATE TABLE sessions (
|
||||||
|
id TEXT PRIMARY KEY,
|
||||||
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
deleted_at TIMESTAMP,
|
||||||
|
browser_name TEXT NOT NULL,
|
||||||
|
browser_version TEXT NOT NULL,
|
||||||
|
client_ipaddr TEXT NOT NULL,
|
||||||
|
platform TEXT NOT NULL,
|
||||||
|
is_desktop BOOLEAN NOT NULL DEFAULT FALSE CHECK(is_desktop IN (0,1)),
|
||||||
|
is_mobile BOOLEAN NOT NULL DEFAULT FALSE CHECK(is_mobile IN (0,1)),
|
||||||
|
is_tablet BOOLEAN NOT NULL DEFAULT FALSE CHECK(is_tablet IN (0,1)),
|
||||||
|
is_tv BOOLEAN NOT NULL DEFAULT FALSE CHECK(is_tv IN (0,1)),
|
||||||
|
is_bot BOOLEAN NOT NULL DEFAULT FALSE CHECK(is_bot IN (0,1)),
|
||||||
|
challenge TEXT NOT NULL,
|
||||||
|
is_human_first BOOLEAN NOT NULL DEFAULT FALSE CHECK(is_human_first IN (0,1)),
|
||||||
|
is_human_last BOOLEAN NOT NULL DEFAULT FALSE CHECK(is_human_last IN (0,1)),
|
||||||
|
profile_id INTEGER NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 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
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Indexes for common queries
|
||||||
|
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);
|
||||||
|
|
||||||
|
CREATE INDEX idx_accounts_address ON accounts(address);
|
||||||
|
CREATE INDEX idx_accounts_chain_id ON accounts(chain_id);
|
||||||
|
CREATE INDEX idx_accounts_deleted_at ON accounts(deleted_at);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
CREATE INDEX idx_sessions_profile_id ON sessions(profile_id);
|
||||||
|
CREATE INDEX idx_sessions_client_ipaddr ON sessions(client_ipaddr);
|
||||||
|
CREATE INDEX idx_sessions_deleted_at ON sessions(deleted_at);
|
||||||
|
|
||||||
|
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);
|
26
internal/sqlc.yaml
Normal file
26
internal/sqlc.yaml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
version: "2"
|
||||||
|
sql:
|
||||||
|
- engine: "sqlite"
|
||||||
|
queries: "./sink/vault/query.sql"
|
||||||
|
schema: "./sink/vault/schema.sql"
|
||||||
|
gen:
|
||||||
|
go:
|
||||||
|
emit_interface: true
|
||||||
|
emit_json_tags: true
|
||||||
|
package: "motrorm"
|
||||||
|
out: "motrorm"
|
||||||
|
|
||||||
|
- engine: "postgresql"
|
||||||
|
queries: "./sink/highway/query.sql"
|
||||||
|
schema: "./sink/highway/schema.sql"
|
||||||
|
gen:
|
||||||
|
go:
|
||||||
|
emit_all_enum_values: true
|
||||||
|
emit_enum_valid_method: true
|
||||||
|
emit_json_tags: true
|
||||||
|
emit_interface: true
|
||||||
|
emit_result_struct_pointers: true
|
||||||
|
omit_unused_structs: true
|
||||||
|
package: "hwayorm"
|
||||||
|
out: "hwayorm"
|
||||||
|
sql_package: "pgx/v5"
|
80
pkg/common/chain_query.go
Normal file
80
pkg/common/chain_query.go
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1"
|
||||||
|
nodev1beta1 "github.com/cosmos/cosmos-sdk/client/grpc/node"
|
||||||
|
didv1 "github.com/onsonr/sonr/api/did/v1"
|
||||||
|
dwnv1 "github.com/onsonr/sonr/api/dwn/v1"
|
||||||
|
svcv1 "github.com/onsonr/sonr/api/svc/v1"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
StatusResponse = nodev1beta1.StatusResponse // StatusResponse is the response type for the Service.Status RPC method.
|
||||||
|
StatusRequest = nodev1beta1.StatusRequest // StatusRequest is the request type for the Service.Status RPC method.
|
||||||
|
BalanceRequest = bankv1beta1.QueryBalanceRequest // BalanceRequest is the request type for the Bank.Balance RPC method.
|
||||||
|
BalanceResponse = bankv1beta1.QueryBalanceResponse // BalanceResponse is the response type for the Bank.Balance RPC method.
|
||||||
|
AllBalancesRequest = bankv1beta1.QueryAllBalancesRequest // AllBalancesRequest is the request type for the Bank.AllBalances RPC method.
|
||||||
|
AllBalancesResponse = bankv1beta1.QueryAllBalancesResponse // AllBalancesResponse is the response type for the Bank.AllBalances RPC method.
|
||||||
|
TotalSupplyRequest = bankv1beta1.QueryTotalSupplyRequest // TotalSupplyRequest is the request type for the Bank.TotalSupply RPC method.
|
||||||
|
TotalSupplyResponse = bankv1beta1.QueryTotalSupplyResponse // TotalSupplyResponse is the response type for the Bank.TotalSupply RPC method.
|
||||||
|
DenomMetadataRequest = bankv1beta1.QueryDenomMetadataRequest // DenomMetadataRequest is the request type for the Bank.DenomMetadata RPC method.
|
||||||
|
DenomMetadataResponse = bankv1beta1.QueryDenomMetadataResponse // DenomMetadataResponse is the response type for the Bank.DenomMetadata RPC method.
|
||||||
|
BankParamsRequest = bankv1beta1.QueryParamsRequest // BankParamsRequest is the request type for the Bank.Params RPC method.
|
||||||
|
BankParamsResponse = bankv1beta1.QueryParamsResponse // BankParamsResponse is the response type for the Bank.Params RPC method.
|
||||||
|
DIDParamsRequest = didv1.QueryRequest // DIDParamsRequest is the request type for the DID.Params RPC method.
|
||||||
|
DIDParamsResponse = didv1.QueryParamsResponse // DIDParamsResponse is the response type for the DID.Params RPC method.
|
||||||
|
DIDResolveResponse = didv1.QueryResolveResponse // DIDResolveResponse is the response type for the DID.Resolve RPC method.
|
||||||
|
DWNParamsRequest = dwnv1.QueryParamsRequest // DWNParamsRequest is the request type for the DWN.Params RPC method.
|
||||||
|
DWNParamsResponse = dwnv1.QueryParamsResponse // DWNParamsResponse is the response type for the DWN.Params RPC method.
|
||||||
|
SVCParamsRequest = svcv1.QueryParamsRequest // SVCParamsRequest is the request type for the SVC.Params RPC method.
|
||||||
|
SVCParamsResponse = svcv1.QueryParamsResponse // SVCParamsResponse is the response type for the SVC.Params RPC method.
|
||||||
|
)
|
||||||
|
|
||||||
|
func conn(addr string) (*grpc.ClientConn, error) {
|
||||||
|
grpcConn, err := grpc.NewClient(addr, grpc.WithInsecure())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return grpcConn, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBankClient(addr string) (bankv1beta1.QueryClient, error) {
|
||||||
|
conn, err := conn(addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return bankv1beta1.NewQueryClient(conn), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDIDClient(addr string) (didv1.QueryClient, error) {
|
||||||
|
conn, err := conn(addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return didv1.NewQueryClient(conn), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDWNClient(addr string) (dwnv1.QueryClient, error) {
|
||||||
|
conn, err := conn(addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return dwnv1.NewQueryClient(conn), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNodeClient(addr string) (nodev1beta1.ServiceClient, error) {
|
||||||
|
conn, err := conn(addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return nodev1beta1.NewServiceClient(conn), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSVCClient(addr string) (svcv1.QueryClient, error) {
|
||||||
|
conn, err := conn(addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return svcv1.NewQueryClient(conn), nil
|
||||||
|
}
|
124
pkg/common/http_cookies.go
Normal file
124
pkg/common/http_cookies.go
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CookieKey is a type alias for string.
|
||||||
|
type CookieKey string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// SessionID is the key for the session ID cookie.
|
||||||
|
SessionID CookieKey = "session.id"
|
||||||
|
|
||||||
|
// SessionChallenge is the key for the session challenge cookie.
|
||||||
|
SessionChallenge CookieKey = "session.challenge"
|
||||||
|
|
||||||
|
// SessionRole is the key for the session role cookie.
|
||||||
|
SessionRole CookieKey = "session.role"
|
||||||
|
|
||||||
|
// SonrAddress is the key for the Sonr address cookie.
|
||||||
|
SonrAddress CookieKey = "sonr.address"
|
||||||
|
|
||||||
|
// SonrDID is the key for the Sonr DID cookie.
|
||||||
|
SonrDID CookieKey = "sonr.did"
|
||||||
|
|
||||||
|
// UserAvatar is the key for the User Avatar cookie.
|
||||||
|
UserAvatar CookieKey = "user.avatar"
|
||||||
|
|
||||||
|
// UserHandle is the key for the User Handle cookie.
|
||||||
|
UserHandle CookieKey = "user.handle"
|
||||||
|
|
||||||
|
// UserName is the key for the User Name cookie.
|
||||||
|
UserName CookieKey = "user.full_name"
|
||||||
|
|
||||||
|
// VaultAddress is the key for the Vault address cookie.
|
||||||
|
VaultAddress CookieKey = "vault.address"
|
||||||
|
|
||||||
|
// VaultCID is the key for the Vault CID cookie.
|
||||||
|
VaultCID CookieKey = "vault.cid"
|
||||||
|
|
||||||
|
// VaultSchema is the key for the Vault schema cookie.
|
||||||
|
VaultSchema CookieKey = "vault.schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns the string representation of the CookieKey.
|
||||||
|
func (c CookieKey) String() string {
|
||||||
|
return string(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ╭───────────────────────────────────────────────────────────╮
|
||||||
|
// │ Utility Methods │
|
||||||
|
// ╰───────────────────────────────────────────────────────────╯
|
||||||
|
|
||||||
|
func CookieExists(c echo.Context, key CookieKey) bool {
|
||||||
|
ck, err := c.Cookie(key.String())
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return ck != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadCookie(c echo.Context, key CookieKey) (string, error) {
|
||||||
|
cookie, err := c.Cookie(key.String())
|
||||||
|
if err != nil {
|
||||||
|
// Cookie not found or other error
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if cookie == nil || cookie.Value == "" {
|
||||||
|
// Cookie is empty
|
||||||
|
return "", http.ErrNoCookie
|
||||||
|
}
|
||||||
|
return cookie.Value, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadCookieBytes(c echo.Context, key CookieKey) ([]byte, error) {
|
||||||
|
cookie, err := c.Cookie(key.String())
|
||||||
|
if err != nil {
|
||||||
|
// Cookie not found or other error
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if cookie == nil || cookie.Value == "" {
|
||||||
|
// Cookie is empty
|
||||||
|
return nil, http.ErrNoCookie
|
||||||
|
}
|
||||||
|
return base64.RawURLEncoding.DecodeString(cookie.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadCookieUnsafe(c echo.Context, key CookieKey) string {
|
||||||
|
ck, err := c.Cookie(key.String())
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return ck.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func WriteCookie(c echo.Context, key CookieKey, value string) error {
|
||||||
|
cookie := &http.Cookie{
|
||||||
|
Name: key.String(),
|
||||||
|
Value: value,
|
||||||
|
Expires: time.Now().Add(24 * time.Hour),
|
||||||
|
HttpOnly: true,
|
||||||
|
Path: "/",
|
||||||
|
// Add Secure and SameSite attributes as needed
|
||||||
|
}
|
||||||
|
c.SetCookie(cookie)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func WriteCookieBytes(c echo.Context, key CookieKey, value []byte) error {
|
||||||
|
cookie := &http.Cookie{
|
||||||
|
Name: key.String(),
|
||||||
|
Value: base64.RawURLEncoding.EncodeToString(value),
|
||||||
|
Expires: time.Now().Add(24 * time.Hour),
|
||||||
|
HttpOnly: true,
|
||||||
|
Path: "/",
|
||||||
|
// Add Secure and SameSite attributes as needed
|
||||||
|
}
|
||||||
|
c.SetCookie(cookie)
|
||||||
|
return nil
|
||||||
|
}
|
52
pkg/common/http_headers.go
Normal file
52
pkg/common/http_headers.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import "github.com/labstack/echo/v4"
|
||||||
|
|
||||||
|
type HeaderKey string
|
||||||
|
|
||||||
|
const (
|
||||||
|
Authorization HeaderKey = "Authorization"
|
||||||
|
|
||||||
|
// User Agent
|
||||||
|
Architecture HeaderKey = "Sec-CH-UA-Arch"
|
||||||
|
Bitness HeaderKey = "Sec-CH-UA-Bitness"
|
||||||
|
FullVersionList HeaderKey = "Sec-CH-UA-Full-Version-List"
|
||||||
|
Mobile HeaderKey = "Sec-CH-UA-Mobile"
|
||||||
|
Model HeaderKey = "Sec-CH-UA-Model"
|
||||||
|
Platform HeaderKey = "Sec-CH-UA-Platform"
|
||||||
|
PlatformVersion HeaderKey = "Sec-CH-UA-Platform-Version"
|
||||||
|
UserAgent HeaderKey = "Sec-CH-UA"
|
||||||
|
|
||||||
|
// Sonr Injected
|
||||||
|
SonrAPIURL HeaderKey = "X-Sonr-API"
|
||||||
|
SonrgRPCURL HeaderKey = "X-Sonr-GRPC"
|
||||||
|
SonrRPCURL HeaderKey = "X-Sonr-RPC"
|
||||||
|
SonrWSURL HeaderKey = "X-Sonr-WS"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (h HeaderKey) String() string {
|
||||||
|
return string(h)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ╭───────────────────────────────────────────────────────────╮
|
||||||
|
// │ Utility Methods │
|
||||||
|
// ╰───────────────────────────────────────────────────────────╯
|
||||||
|
|
||||||
|
func HeaderEquals(c echo.Context, key HeaderKey, value string) bool {
|
||||||
|
return c.Response().Header().Get(key.String()) == value
|
||||||
|
}
|
||||||
|
|
||||||
|
// HeaderExists returns true if the request has the header Key.
|
||||||
|
func HeaderExists(c echo.Context, key HeaderKey) bool {
|
||||||
|
return c.Response().Header().Get(key.String()) != ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// HeaderRead returns the header value for the Key.
|
||||||
|
func HeaderRead(c echo.Context, key HeaderKey) string {
|
||||||
|
return c.Response().Header().Get(key.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
// HeaderWrite sets the header value for the Key.
|
||||||
|
func HeaderWrite(c echo.Context, key HeaderKey, value string) {
|
||||||
|
c.Response().Header().Set(key.String(), value)
|
||||||
|
}
|
136
pkg/common/ipfs_api.go
Normal file
136
pkg/common/ipfs_api.go
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/ipfs/boxo/files"
|
||||||
|
"github.com/ipfs/boxo/path"
|
||||||
|
"github.com/ipfs/kubo/client/rpc"
|
||||||
|
"github.com/ipfs/kubo/core/coreiface/options"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IPFS represents a wrapper interface abstracting the localhost api
|
||||||
|
type IPFS interface {
|
||||||
|
Add(data []byte) (string, error)
|
||||||
|
AddFile(file File) (string, error)
|
||||||
|
AddFolder(folder Folder) (string, error)
|
||||||
|
Exists(cid string) (bool, error)
|
||||||
|
Get(cid string) ([]byte, error)
|
||||||
|
IsPinned(ipns string) (bool, error)
|
||||||
|
Ls(cid string) ([]string, error)
|
||||||
|
Pin(cid string, name string) error
|
||||||
|
Unpin(cid string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type File interface {
|
||||||
|
files.File
|
||||||
|
Name() string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFileMap(vs []File) map[string]files.Node {
|
||||||
|
m := make(map[string]files.Node)
|
||||||
|
for _, f := range vs {
|
||||||
|
m[f.Name()] = f
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
type client struct {
|
||||||
|
api *rpc.HttpApi
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewIPFS() (IPFS, error) {
|
||||||
|
api, err := rpc.NewLocalApi()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &client{api: api}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) Add(data []byte) (string, error) {
|
||||||
|
file := files.NewBytesFile(data)
|
||||||
|
cidFile, err := c.api.Unixfs().Add(context.Background(), file)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return cidFile.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) Get(cid string) ([]byte, error) {
|
||||||
|
p, err := path.NewPath(cid)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
node, err := c.api.Unixfs().Get(context.Background(), p)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
file, ok := node.(files.File)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("unexpected node type: %T", node)
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
if _, err := io.Copy(buf, file); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) IsPinned(ipns string) (bool, error) {
|
||||||
|
_, err := c.api.Name().Resolve(context.Background(), ipns)
|
||||||
|
if err != nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) Exists(cid string) (bool, error) {
|
||||||
|
p, err := path.NewPath(cid)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
_, err = c.api.Block().Stat(context.Background(), p)
|
||||||
|
if err != nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) Pin(cid string, name string) error {
|
||||||
|
p, err := path.NewPath(cid)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return c.api.Pin().Add(context.Background(), p, options.Pin.Name(name))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) Unpin(cid string) error {
|
||||||
|
p, err := path.NewPath(cid)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return c.api.Pin().Rm(context.Background(), p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) Ls(cid string) ([]string, error) {
|
||||||
|
p, err := path.NewPath(cid)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
node, err := c.api.Unixfs().Ls(context.Background(), p)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var files []string
|
||||||
|
for entry := range node {
|
||||||
|
files = append(files, entry.Name)
|
||||||
|
}
|
||||||
|
return files, nil
|
||||||
|
}
|
28
pkg/common/ipfs_file.go
Normal file
28
pkg/common/ipfs_file.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/ipfs/boxo/files"
|
||||||
|
)
|
||||||
|
|
||||||
|
type file struct {
|
||||||
|
files.File
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *file) Name() string {
|
||||||
|
return f.name
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFile(name string, data []byte) File {
|
||||||
|
return &file{File: files.NewBytesFile(data), name: name}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) AddFile(file File) (string, error) {
|
||||||
|
cidFile, err := c.api.Unixfs().Add(context.Background(), file)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return cidFile.String(), nil
|
||||||
|
}
|
21
pkg/common/ipfs_folder.go
Normal file
21
pkg/common/ipfs_folder.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/ipfs/boxo/files"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Folder = files.Directory
|
||||||
|
|
||||||
|
func NewFolder(fs ...File) Folder {
|
||||||
|
return files.NewMapDirectory(NewFileMap(fs))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) AddFolder(folder Folder) (string, error) {
|
||||||
|
cidFile, err := c.api.Unixfs().Add(context.Background(), folder)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return cidFile.String(), nil
|
||||||
|
}
|
142
pkg/common/ucan_store.go
Normal file
142
pkg/common/ucan_store.go
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/golang-jwt/jwt"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
"github.com/onsonr/sonr/internal/crypto/keys"
|
||||||
|
"github.com/onsonr/sonr/internal/crypto/ucan"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IPFSTokenStore interface {
|
||||||
|
ucan.TokenStore
|
||||||
|
ResolveCIDBytes(ctx context.Context, id cid.Cid) ([]byte, error)
|
||||||
|
ResolveDIDKey(ctx context.Context, did string) (keys.DID, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ipfsUCANStore is a token store that uses IPFS to store tokens. It uses the memory store as a cache
|
||||||
|
// for CID strings to be used as keys for retrieving tokens.
|
||||||
|
type ipfsUCANStore struct {
|
||||||
|
sync.Mutex
|
||||||
|
ipfs IPFS
|
||||||
|
cache map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewUCANStore creates a new IPFS-backed token store
|
||||||
|
func NewUCANStore(ipfsClient IPFS) IPFSTokenStore {
|
||||||
|
return &ipfsUCANStore{
|
||||||
|
ipfs: ipfsClient,
|
||||||
|
cache: make(map[string]string),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (st *ipfsUCANStore) PutToken(ctx context.Context, key string, raw string) error {
|
||||||
|
// Validate token format
|
||||||
|
p := &jwt.Parser{
|
||||||
|
UseJSONNumber: true,
|
||||||
|
SkipClaimsValidation: false,
|
||||||
|
}
|
||||||
|
if _, _, err := p.ParseUnverified(raw, jwt.MapClaims{}); err != nil {
|
||||||
|
return fmt.Errorf("%w: %s", ucan.ErrInvalidToken, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store token in IPFS
|
||||||
|
cid, err := st.ipfs.Add([]byte(raw))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to store token in IPFS: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update cache
|
||||||
|
st.Lock()
|
||||||
|
defer st.Unlock()
|
||||||
|
st.cache[key] = cid
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (st *ipfsUCANStore) RawToken(ctx context.Context, key string) (string, error) {
|
||||||
|
st.Lock()
|
||||||
|
cid, exists := st.cache[key]
|
||||||
|
st.Unlock()
|
||||||
|
|
||||||
|
if !exists {
|
||||||
|
return "", ucan.ErrTokenNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve token from IPFS
|
||||||
|
data, err := st.ipfs.Get(cid)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to retrieve token from IPFS: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(data), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (st *ipfsUCANStore) DeleteToken(ctx context.Context, key string) error {
|
||||||
|
st.Lock()
|
||||||
|
defer st.Unlock()
|
||||||
|
|
||||||
|
cid, exists := st.cache[key]
|
||||||
|
if !exists {
|
||||||
|
return ucan.ErrTokenNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpin from IPFS
|
||||||
|
if err := st.ipfs.Unpin(cid); err != nil {
|
||||||
|
return fmt.Errorf("failed to unpin token from IPFS: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(st.cache, key)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (st *ipfsUCANStore) ListTokens(ctx context.Context, offset, limit int) ([]ucan.RawToken, error) {
|
||||||
|
st.Lock()
|
||||||
|
defer st.Unlock()
|
||||||
|
|
||||||
|
tokens := make(ucan.RawTokens, 0, len(st.cache))
|
||||||
|
for key, cid := range st.cache {
|
||||||
|
data, err := st.ipfs.Get(cid)
|
||||||
|
if err != nil {
|
||||||
|
continue // Skip invalid tokens
|
||||||
|
}
|
||||||
|
tokens = append(tokens, ucan.RawToken{
|
||||||
|
Key: key,
|
||||||
|
Raw: string(data),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort tokens
|
||||||
|
sort.Sort(tokens)
|
||||||
|
|
||||||
|
// Apply pagination
|
||||||
|
if offset >= len(tokens) {
|
||||||
|
return []ucan.RawToken{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
end := offset + limit
|
||||||
|
if end > len(tokens) || limit <= 0 {
|
||||||
|
end = len(tokens)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tokens[offset:end], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (st *ipfsUCANStore) ResolveCIDBytes(ctx context.Context, id cid.Cid) ([]byte, error) {
|
||||||
|
data, err := st.ipfs.Get(id.String())
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to resolve CID bytes: %w", err)
|
||||||
|
}
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (st *ipfsUCANStore) ResolveDIDKey(ctx context.Context, did string) (keys.DID, error) {
|
||||||
|
id, err := keys.Parse(did)
|
||||||
|
if err != nil {
|
||||||
|
return keys.DID{}, fmt.Errorf("failed to parse DID: %w", err)
|
||||||
|
}
|
||||||
|
return id, nil
|
||||||
|
}
|
19
pkg/context/credentials.go
Normal file
19
pkg/context/credentials.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package context
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/go-webauthn/webauthn/protocol"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *GatewayContext) NewChallenge() string {
|
||||||
|
chal, _ := protocol.CreateChallenge()
|
||||||
|
chalStr := chal.String()
|
||||||
|
return chalStr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cc *GatewayContext) ListCredentials(handle string) ([]*CredentialDescriptor, error) {
|
||||||
|
creds, err := cc.GetCredentialsByHandle(bgCtx(), handle)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return CredentialArrayToDescriptors(creds), nil
|
||||||
|
}
|
64
pkg/context/middleware.go
Normal file
64
pkg/context/middleware.go
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
package context
|
||||||
|
|
||||||
|
import (
|
||||||
|
gocontext "context"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/medama-io/go-useragent"
|
||||||
|
"github.com/onsonr/sonr/internal/crypto/mpc"
|
||||||
|
"github.com/onsonr/sonr/internal/common"
|
||||||
|
"github.com/onsonr/sonr/internal/config/hway"
|
||||||
|
hwayorm "github.com/onsonr/sonr/internal/database/hwayorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GatewayContext struct {
|
||||||
|
echo.Context
|
||||||
|
hwayorm.Querier
|
||||||
|
id string
|
||||||
|
ipfsClient common.IPFS
|
||||||
|
agent useragent.UserAgent
|
||||||
|
tokenStore common.IPFSTokenStore
|
||||||
|
stagedEnclaves map[string]mpc.Enclave
|
||||||
|
grpcAddr string
|
||||||
|
turnstileSiteKey string
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetGateway(c echo.Context) (*GatewayContext, error) {
|
||||||
|
cc, ok := c.(*GatewayContext)
|
||||||
|
if !ok {
|
||||||
|
return nil, echo.NewHTTPError(http.StatusInternalServerError, "Gateway Context not found")
|
||||||
|
}
|
||||||
|
return cc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func UseGateway(env hway.Hway, ipc common.IPFS, db *hwayorm.Queries) echo.MiddlewareFunc {
|
||||||
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
|
return func(c echo.Context) error {
|
||||||
|
ua := useragent.NewParser()
|
||||||
|
ctx := &GatewayContext{
|
||||||
|
Context: c,
|
||||||
|
Querier: db,
|
||||||
|
ipfsClient: ipc,
|
||||||
|
agent: ua.Parse(c.Request().UserAgent()),
|
||||||
|
grpcAddr: env.GetSonrGrpcUrl(),
|
||||||
|
tokenStore: common.NewUCANStore(ipc),
|
||||||
|
turnstileSiteKey: env.GetTurnstileSiteKey(),
|
||||||
|
}
|
||||||
|
return next(ctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BG() gocontext.Context {
|
||||||
|
ctx := gocontext.Background()
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cc *GatewayContext) ReadCookie(k common.CookieKey) string {
|
||||||
|
return common.ReadCookieUnsafe(cc.Context, k)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cc *GatewayContext) WriteCookie(k common.CookieKey, v string) {
|
||||||
|
common.WriteCookie(cc.Context, k, v)
|
||||||
|
}
|
53
pkg/context/profiles.go
Normal file
53
pkg/context/profiles.go
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package context
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
hwayorm "github.com/onsonr/sonr/internal/database/hwayorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func UpdateProfile(c echo.Context) (*hwayorm.Profile, error) {
|
||||||
|
ctx, ok := c.(*GatewayContext)
|
||||||
|
if !ok {
|
||||||
|
return nil, echo.NewHTTPError(http.StatusInternalServerError, "Profile Context not found")
|
||||||
|
}
|
||||||
|
address := c.FormValue("address")
|
||||||
|
handle := c.FormValue("handle")
|
||||||
|
name := c.FormValue("name")
|
||||||
|
profile, err := ctx.UpdateProfile(bgCtx(), hwayorm.UpdateProfileParams{
|
||||||
|
Address: address,
|
||||||
|
Handle: handle,
|
||||||
|
Name: name,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return profile, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadProfile(c echo.Context) (*hwayorm.Profile, error) {
|
||||||
|
ctx, ok := c.(*GatewayContext)
|
||||||
|
if !ok {
|
||||||
|
return nil, echo.NewHTTPError(http.StatusInternalServerError, "Profile Context not found")
|
||||||
|
}
|
||||||
|
handle := c.Param("handle")
|
||||||
|
profile, err := ctx.GetProfileByHandle(bgCtx(), handle)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return profile, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteProfile(c echo.Context) error {
|
||||||
|
ctx, ok := c.(*GatewayContext)
|
||||||
|
if !ok {
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError, "Profile Context not found")
|
||||||
|
}
|
||||||
|
address := c.Param("address")
|
||||||
|
err := ctx.SoftDeleteProfile(bgCtx(), address)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
42
pkg/context/renderer.go
Normal file
42
pkg/context/renderer.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package context
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
|
||||||
|
"github.com/a-h/templ"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/onsonr/sonr/gateway/views"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Render(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
|
||||||
|
}
|
||||||
|
|
||||||
|
func RenderError(c echo.Context, err error) error {
|
||||||
|
return Render(c, views.ErrorView(err.Error()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func RenderInitial(c echo.Context) error {
|
||||||
|
return Render(c, views.InitialView())
|
||||||
|
}
|
||||||
|
|
||||||
|
func RenderLoading(c echo.Context) error {
|
||||||
|
return Render(c, views.LoadingView())
|
||||||
|
}
|
105
pkg/context/resolver.go
Normal file
105
pkg/context/resolver.go
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
package context
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/onsonr/sonr/internal/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ParamsBank returns the bank params
|
||||||
|
func (cc *GatewayContext) ParamsBank() (*common.BankParamsResponse, error) {
|
||||||
|
cl, err := common.NewBankClient(cc.grpcAddr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp, err := cl.Params(bgCtx(), &common.BankParamsRequest{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParamsDID returns the DID params
|
||||||
|
func (cc *GatewayContext) ParamsDID() (*common.DIDParamsResponse, error) {
|
||||||
|
cl, err := common.NewDIDClient(cc.grpcAddr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp, err := cl.Params(bgCtx(), &common.DIDParamsRequest{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParamsDWN returns the DWN params
|
||||||
|
func (cc *GatewayContext) ParamsDWN() (*common.DWNParamsResponse, error) {
|
||||||
|
cl, err := common.NewDWNClient(cc.grpcAddr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp, err := cl.Params(bgCtx(), &common.DWNParamsRequest{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParamsSVC returns the SVC params
|
||||||
|
func (cc *GatewayContext) ParamsSVC() (*common.SVCParamsResponse, error) {
|
||||||
|
cl, err := common.NewSVCClient(cc.grpcAddr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp, err := cl.Params(bgCtx(), &common.SVCParamsRequest{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// StatusBlock returns the current block
|
||||||
|
func (cc *GatewayContext) StatusBlock() string {
|
||||||
|
qc, err := common.NewNodeClient(cc.grpcAddr)
|
||||||
|
if err != nil {
|
||||||
|
return "-1"
|
||||||
|
}
|
||||||
|
resp, err := qc.Status(bgCtx(), &common.StatusRequest{})
|
||||||
|
if err != nil {
|
||||||
|
return "-1"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%d", resp.GetHeight())
|
||||||
|
}
|
||||||
|
|
||||||
|
// StatusNode returns the node status
|
||||||
|
func (cc *GatewayContext) StatusNode() (*common.StatusResponse, error) {
|
||||||
|
cl, err := common.NewNodeClient(cc.grpcAddr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp, err := cl.Status(bgCtx(), &common.StatusRequest{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TxBroadcast broadcasts a transaction to the network
|
||||||
|
func (cc *GatewayContext) TxBroadcast() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TxEncode encodes a transaction
|
||||||
|
func (cc *GatewayContext) TxEncode() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TxDecode decodes a transaction
|
||||||
|
func (cc *GatewayContext) TxDecode() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TxSimulate simulates a transaction on the network
|
||||||
|
func (cc *GatewayContext) TxSimulate() error {
|
||||||
|
return nil
|
||||||
|
}
|
148
pkg/context/sessions.go
Normal file
148
pkg/context/sessions.go
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
package context
|
||||||
|
|
||||||
|
import (
|
||||||
|
gocontext "context"
|
||||||
|
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/onsonr/sonr/internal/common"
|
||||||
|
"github.com/segmentio/ksuid"
|
||||||
|
"lukechampine.com/blake3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewSession(c echo.Context) error {
|
||||||
|
cc, ok := c.(*GatewayContext)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
baseSessionCreateParams := BaseSessionCreateParams(cc)
|
||||||
|
cc.id = baseSessionCreateParams.ID
|
||||||
|
if _, err := cc.CreateSession(bgCtx(), baseSessionCreateParams); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Set Cookie
|
||||||
|
if err := common.WriteCookie(c, common.SessionID, cc.id); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uses blake3 to hash the sessionID to generate a nonce of length 12 bytes
|
||||||
|
func GetNonce(sessionID string) ([]byte, error) {
|
||||||
|
hash := blake3.New(32, nil)
|
||||||
|
_, err := hash.Write([]byte(sessionID))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Read the hash into a byte slice
|
||||||
|
nonce := make([]byte, 12)
|
||||||
|
_, err = hash.Write(nonce)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return nonce, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ForbiddenDevice returns true if the device is unavailable
|
||||||
|
func ForbiddenDevice(c echo.Context) bool {
|
||||||
|
cc, ok := c.(*GatewayContext)
|
||||||
|
if !ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return cc.agent.IsBot() || cc.agent.IsTV()
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetOrigin(c echo.Context) string {
|
||||||
|
return c.Request().Host
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetSessionID(c echo.Context) string {
|
||||||
|
// Check from context
|
||||||
|
cc, ok := c.(*GatewayContext)
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
// check from cookie
|
||||||
|
if cc.id == "" {
|
||||||
|
if ok := common.CookieExists(c, common.SessionID); !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
cc.id = common.ReadCookieUnsafe(c, common.SessionID)
|
||||||
|
}
|
||||||
|
return cc.id
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetAuthChallenge(c echo.Context) string {
|
||||||
|
cc, ok := c.(*GatewayContext)
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
s, err := cc.GetChallengeBySessionID(bgCtx(), cc.id)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetProfileHandle(c echo.Context) string {
|
||||||
|
// First check for the cookie
|
||||||
|
handle := common.ReadCookieUnsafe(c, common.UserHandle)
|
||||||
|
if handle != "" {
|
||||||
|
return handle
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then check the session
|
||||||
|
cc, ok := c.(*GatewayContext)
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
s, err := cc.GetSessionByID(bgCtx(), cc.id)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
profile, err := cc.GetProfileByID(bgCtx(), s.ProfileID)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return profile.Handle
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// func GetHumanVerificationNumbers(c echo.Context) (int64, int64) {
|
||||||
|
// cc, ok := c.(*GatewayContext)
|
||||||
|
// if !ok {
|
||||||
|
// return 0, 0
|
||||||
|
// }
|
||||||
|
// s, err := cc.dbq.GetHumanVerificationNumbers(bgCtx(), cc.id)
|
||||||
|
// if err != nil {
|
||||||
|
// return 0, 0
|
||||||
|
// }
|
||||||
|
// return s.IsHumanFirst, s.IsHumanLast
|
||||||
|
// }
|
||||||
|
|
||||||
|
// utility function to get a context
|
||||||
|
func bgCtx() gocontext.Context {
|
||||||
|
ctx := gocontext.Background()
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
func getOrCreateSessionID(c echo.Context) string {
|
||||||
|
if ok := common.CookieExists(c, common.SessionID); !ok {
|
||||||
|
sessionID := ksuid.New().String()
|
||||||
|
common.WriteCookie(c, common.SessionID, sessionID)
|
||||||
|
return sessionID
|
||||||
|
}
|
||||||
|
|
||||||
|
sessionID, err := common.ReadCookie(c, common.SessionID)
|
||||||
|
if err != nil {
|
||||||
|
sessionID = ksuid.New().String()
|
||||||
|
common.WriteCookie(c, common.SessionID, sessionID)
|
||||||
|
}
|
||||||
|
return sessionID
|
||||||
|
}
|
||||||
|
|
||||||
|
func boolToInt64(b bool) int64 {
|
||||||
|
if b {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
102
pkg/context/types.go
Normal file
102
pkg/context/types.go
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
package context
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/go-webauthn/webauthn/protocol"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/medama-io/go-useragent"
|
||||||
|
hwayorm "github.com/onsonr/sonr/internal/database/hwayorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 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) *hwayorm.Credential {
|
||||||
|
return &hwayorm.Credential{
|
||||||
|
Handle: handle,
|
||||||
|
Origin: origin,
|
||||||
|
CredentialID: c.ID,
|
||||||
|
Type: c.Type,
|
||||||
|
Transports: c.Transports,
|
||||||
|
AuthenticatorAttachment: c.AuthenticatorAttachment,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func CredentialArrayToDescriptors(credentials []*hwayorm.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
|
||||||
|
}
|
||||||
|
|
||||||
|
func BaseSessionCreateParams(e echo.Context) hwayorm.CreateSessionParams {
|
||||||
|
// f := rand.Intn(5) + 1
|
||||||
|
// l := rand.Intn(4) + 1
|
||||||
|
challenge, _ := protocol.CreateChallenge()
|
||||||
|
id := getOrCreateSessionID(e)
|
||||||
|
ua := useragent.NewParser()
|
||||||
|
s := ua.Parse(e.Request().UserAgent())
|
||||||
|
|
||||||
|
return hwayorm.CreateSessionParams{
|
||||||
|
ID: id,
|
||||||
|
BrowserName: s.GetBrowser(),
|
||||||
|
BrowserVersion: s.GetMajorVersion(),
|
||||||
|
ClientIpaddr: e.RealIP(),
|
||||||
|
Platform: s.GetOS(),
|
||||||
|
IsMobile: s.IsMobile(),
|
||||||
|
IsTablet: s.IsTablet(),
|
||||||
|
IsDesktop: s.IsDesktop(),
|
||||||
|
IsBot: s.IsBot(),
|
||||||
|
IsTv: s.IsTV(),
|
||||||
|
// IsHumanFirst: int64(f),
|
||||||
|
// IsHumanLast: int64(l),
|
||||||
|
Challenge: challenge.String(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ╭───────────────────────────────────────────────────────────╮
|
||||||
|
// │ Create Passkey (/register/passkey) │
|
||||||
|
// ╰───────────────────────────────────────────────────────────╯
|
||||||
|
|
||||||
|
// CreatePasskeyParams represents the parameters for creating a passkey
|
||||||
|
type CreatePasskeyParams struct {
|
||||||
|
Address string
|
||||||
|
Handle string
|
||||||
|
Name string
|
||||||
|
Challenge string
|
||||||
|
CreationBlock string
|
||||||
|
}
|
||||||
|
|
||||||
|
// ╭───────────────────────────────────────────────────────────╮
|
||||||
|
// │ Create Profile (/register/profile) │
|
||||||
|
// ╰───────────────────────────────────────────────────────────╯
|
||||||
|
|
||||||
|
// CreateProfileParams represents the parameters for creating a profile
|
||||||
|
type CreateProfileParams struct {
|
||||||
|
TurnstileSiteKey string
|
||||||
|
FirstNumber int
|
||||||
|
LastNumber int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sum returns the sum of the first and last number
|
||||||
|
func (d CreateProfileParams) Sum() int {
|
||||||
|
return d.FirstNumber + d.LastNumber
|
||||||
|
}
|
45
pkg/context/vaults.go
Normal file
45
pkg/context/vaults.go
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package context
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/onsonr/sonr/internal/crypto/mpc"
|
||||||
|
"github.com/onsonr/sonr/internal/common"
|
||||||
|
"lukechampine.com/blake3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (cc *GatewayContext) Spawn(handle, origin string) (*CreatePasskeyParams, error) {
|
||||||
|
challenge := GetAuthChallenge(cc)
|
||||||
|
sid := GetSessionID(cc)
|
||||||
|
nonce, err := calcNonce(sid)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
encl, err := mpc.GenEnclave(nonce)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cc.stagedEnclaves[sid] = encl
|
||||||
|
common.WriteCookie(cc, common.SonrAddress, encl.Address())
|
||||||
|
return &CreatePasskeyParams{
|
||||||
|
Address: encl.Address(),
|
||||||
|
Handle: handle,
|
||||||
|
Name: origin,
|
||||||
|
Challenge: challenge,
|
||||||
|
CreationBlock: cc.StatusBlock(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uses blake3 to hash the sessionID to generate a nonce of length 12 bytes
|
||||||
|
func calcNonce(sessionID string) ([]byte, error) {
|
||||||
|
hash := blake3.New(32, nil)
|
||||||
|
_, err := hash.Write([]byte(sessionID))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Read the hash into a byte slice
|
||||||
|
nonce := make([]byte, 12)
|
||||||
|
_, err = hash.Write(nonce)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return nonce, nil
|
||||||
|
}
|
38
pkg/islands/card_account.templ
Normal file
38
pkg/islands/card_account.templ
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package islands
|
||||||
|
|
||||||
|
templ CardAccount(addr, name, handle, creationBlock string) {
|
||||||
|
<div class="profile-card min-w-[320px]">
|
||||||
|
<div class="text-white max-w-xs my-auto mx-auto bg-gradient-to-r from-cyan-600 to-cyan-300 p-4 py-5 px-5 rounded-xl">
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<div>
|
||||||
|
<h2>sonr-testnet-1</h2>
|
||||||
|
<p class="text-2xl font-bold">{ handle }</p>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center opacity-60">
|
||||||
|
<sl-icon style="font-size: 52px;" library="sonr" name="sonr-fill"></sl-icon>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mt-5 flex justify-between items-center w-52">
|
||||||
|
<span class="text-lg font-mono">{ shortenAddress(addr) }</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-between mt-5 w-48 ">
|
||||||
|
<div>
|
||||||
|
<h3 class="text-xs">Block Created </h3>
|
||||||
|
<p class="font-bold"><span>#</span>{ creationBlock }</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 class="text-xs">Issued to</h3>
|
||||||
|
<p class="font-bold">{ name }</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to shorten address
|
||||||
|
func shortenAddress(address string) string {
|
||||||
|
if len(address) <= 20 {
|
||||||
|
return address
|
||||||
|
}
|
||||||
|
return address[:16] + "..." + address[len(address)-4:]
|
||||||
|
}
|
100
pkg/islands/card_account_templ.go
Normal file
100
pkg/islands/card_account_templ.go
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
|
// templ: version: v0.2.793
|
||||||
|
package islands
|
||||||
|
|
||||||
|
//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 CardAccount(addr, name, handle, creationBlock 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_Var1 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var1 == nil {
|
||||||
|
templ_7745c5c3_Var1 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"profile-card min-w-[320px]\"><div class=\"text-white max-w-xs my-auto mx-auto bg-gradient-to-r from-cyan-600 to-cyan-300 p-4 py-5 px-5 rounded-xl\"><div class=\"flex justify-between\"><div><h2>sonr-testnet-1</h2><p class=\"text-2xl font-bold\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var2 string
|
||||||
|
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(handle)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/islands/card_account.templ`, Line: 9, Col: 43}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p></div><div class=\"flex items-center opacity-60\"><sl-icon style=\"font-size: 52px;\" library=\"sonr\" name=\"sonr-fill\"></sl-icon></div></div><div class=\"mt-5 flex justify-between items-center w-52\"><span class=\"text-lg font-mono\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var3 string
|
||||||
|
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(shortenAddress(addr))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/islands/card_account.templ`, Line: 16, Col: 58}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</span></div><div class=\"flex justify-between mt-5 w-48 \"><div><h3 class=\"text-xs\">Block Created </h3><p class=\"font-bold\"><span>#</span>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var4 string
|
||||||
|
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(creationBlock)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/islands/card_account.templ`, Line: 21, Col: 55}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p></div><div><h3 class=\"text-xs\">Issued to</h3><p class=\"font-bold\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var5 string
|
||||||
|
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(name)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/islands/card_account.templ`, Line: 25, Col: 32}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p></div></div></div></div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to shorten address
|
||||||
|
func shortenAddress(address string) string {
|
||||||
|
if len(address) <= 20 {
|
||||||
|
return address
|
||||||
|
}
|
||||||
|
return address[:16] + "..." + address[len(address)-4:]
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = templruntime.GeneratedTemplate
|
70
pkg/islands/coin_select.templ
Normal file
70
pkg/islands/coin_select.templ
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package islands
|
||||||
|
|
||||||
|
type Coin struct {
|
||||||
|
Ticker string
|
||||||
|
Name string
|
||||||
|
IsDefault bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultCoins = []Coin{
|
||||||
|
{Ticker: "SNR", Name: "Sonr", IsDefault: true},
|
||||||
|
{Ticker: "BTC", Name: "Bitcoin", IsDefault: true},
|
||||||
|
{Ticker: "ETH", Name: "Ethereum", IsDefault: true},
|
||||||
|
{Ticker: "SOL", Name: "Solana", IsDefault: false},
|
||||||
|
{Ticker: "LTC", Name: "Litecoin", IsDefault: false},
|
||||||
|
{Ticker: "DOGE", Name: "Dogecoin", IsDefault: false},
|
||||||
|
{Ticker: "XRP", Name: "Ripple", IsDefault: false},
|
||||||
|
{Ticker: "OSMO", Name: "Osmosis", IsDefault: false},
|
||||||
|
{Ticker: "ATOM", Name: "Cosmos", IsDefault: false},
|
||||||
|
{Ticker: "STARZ", Name: "Stargaze", IsDefault: false},
|
||||||
|
{Ticker: "AKT", Name: "Akash", IsDefault: false},
|
||||||
|
{Ticker: "EVMOS", Name: "Evmos", IsDefault: false},
|
||||||
|
{Ticker: "FIL", Name: "Filecoin", IsDefault: false},
|
||||||
|
{Ticker: "AXL", Name: "Axelar", IsDefault: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
templ CoinSelect() {
|
||||||
|
<sl-select
|
||||||
|
label="Accounts"
|
||||||
|
name="selected_assets"
|
||||||
|
value="SNR BTC ETH"
|
||||||
|
help-text="Select Blockchains to connect with your Vault"
|
||||||
|
multiple
|
||||||
|
class="custom-tag py-2"
|
||||||
|
>
|
||||||
|
for _, a := range defaultCoins {
|
||||||
|
@CoinOption(a)
|
||||||
|
}
|
||||||
|
</sl-select>
|
||||||
|
<script>
|
||||||
|
const select = document.querySelector('.custom-tag');
|
||||||
|
select.getTag = (option, index) => {
|
||||||
|
// Use the same icon used in the <sl-option>
|
||||||
|
const name = option.querySelector('sl-icon[slot="prefix"]').name;
|
||||||
|
|
||||||
|
// You can return a string, a Lit Template, or an HTMLElement here
|
||||||
|
return `
|
||||||
|
<sl-tag removable>
|
||||||
|
<sl-icon name="${name}" library="crypto" style="padding-inline-end: .5rem;"></sl-icon>
|
||||||
|
${option.getTextLabel()}
|
||||||
|
</sl-tag>
|
||||||
|
`;
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
}
|
||||||
|
|
||||||
|
templ CoinOption(a Coin) {
|
||||||
|
if a.IsDefault {
|
||||||
|
<sl-option value={ a.Ticker } selected disabled>
|
||||||
|
<sl-icon slot="prefix" name={ a.Ticker } library="crypto"></sl-icon>
|
||||||
|
{ a.Name }
|
||||||
|
</sl-option>
|
||||||
|
<sl-divider></sl-divider>
|
||||||
|
} else {
|
||||||
|
<sl-option value={ a.Ticker }>
|
||||||
|
<sl-icon slot="prefix" name={ a.Ticker } library="crypto"></sl-icon>
|
||||||
|
{ a.Name }
|
||||||
|
</sl-option>
|
||||||
|
<sl-divider></sl-divider>
|
||||||
|
}
|
||||||
|
}
|
187
pkg/islands/coin_select_templ.go
Normal file
187
pkg/islands/coin_select_templ.go
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
|
// templ: version: v0.2.793
|
||||||
|
package islands
|
||||||
|
|
||||||
|
//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"
|
||||||
|
|
||||||
|
type Coin struct {
|
||||||
|
Ticker string
|
||||||
|
Name string
|
||||||
|
IsDefault bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultCoins = []Coin{
|
||||||
|
{Ticker: "SNR", Name: "Sonr", IsDefault: true},
|
||||||
|
{Ticker: "BTC", Name: "Bitcoin", IsDefault: true},
|
||||||
|
{Ticker: "ETH", Name: "Ethereum", IsDefault: true},
|
||||||
|
{Ticker: "SOL", Name: "Solana", IsDefault: false},
|
||||||
|
{Ticker: "LTC", Name: "Litecoin", IsDefault: false},
|
||||||
|
{Ticker: "DOGE", Name: "Dogecoin", IsDefault: false},
|
||||||
|
{Ticker: "XRP", Name: "Ripple", IsDefault: false},
|
||||||
|
{Ticker: "OSMO", Name: "Osmosis", IsDefault: false},
|
||||||
|
{Ticker: "ATOM", Name: "Cosmos", IsDefault: false},
|
||||||
|
{Ticker: "STARZ", Name: "Stargaze", IsDefault: false},
|
||||||
|
{Ticker: "AKT", Name: "Akash", IsDefault: false},
|
||||||
|
{Ticker: "EVMOS", Name: "Evmos", IsDefault: false},
|
||||||
|
{Ticker: "FIL", Name: "Filecoin", IsDefault: false},
|
||||||
|
{Ticker: "AXL", Name: "Axelar", IsDefault: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
func CoinSelect() 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 = templ_7745c5c3_Buffer.WriteString("<sl-select label=\"Accounts\" name=\"selected_assets\" value=\"SNR BTC ETH\" help-text=\"Select Blockchains to connect with your Vault\" multiple class=\"custom-tag py-2\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
for _, a := range defaultCoins {
|
||||||
|
templ_7745c5c3_Err = CoinOption(a).Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</sl-select><script>\n\t const select = document.querySelector('.custom-tag');\n select.getTag = (option, index) => {\n // Use the same icon used in the <sl-option>\n const name = option.querySelector('sl-icon[slot=\"prefix\"]').name;\n\n // You can return a string, a Lit Template, or an HTMLElement here\n return `\n <sl-tag removable>\n <sl-icon name=\"${name}\" library=\"crypto\" style=\"padding-inline-end: .5rem;\"></sl-icon>\n ${option.getTextLabel()}\n </sl-tag>\n `;\n };\n\t</script>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func CoinOption(a Coin) 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)
|
||||||
|
if a.IsDefault {
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<sl-option value=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var3 string
|
||||||
|
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(a.Ticker)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/islands/coin_select.templ`, Line: 58, Col: 29}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" selected disabled><sl-icon slot=\"prefix\" name=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var4 string
|
||||||
|
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(a.Ticker)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/islands/coin_select.templ`, Line: 59, Col: 41}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" library=\"crypto\"></sl-icon> ")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var5 string
|
||||||
|
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(a.Name)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/islands/coin_select.templ`, Line: 60, Col: 11}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</sl-option> <sl-divider></sl-divider>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<sl-option value=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var6 string
|
||||||
|
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(a.Ticker)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/islands/coin_select.templ`, Line: 64, Col: 29}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><sl-icon slot=\"prefix\" name=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var7 string
|
||||||
|
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(a.Ticker)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/islands/coin_select.templ`, Line: 65, Col: 41}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" library=\"crypto\"></sl-icon> ")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var8 string
|
||||||
|
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(a.Name)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/islands/coin_select.templ`, Line: 66, Col: 11}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</sl-option> <sl-divider></sl-divider>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = templruntime.GeneratedTemplate
|
25
pkg/islands/human_slider.templ
Normal file
25
pkg/islands/human_slider.templ
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package islands
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
templ HumanSlider(firstNumber int, lastNumber int) {
|
||||||
|
<div hx-target="this" hx-swap="outerHTML">
|
||||||
|
<sl-range name="is_human" label={ humanLabel(firstNumber, lastNumber) } help-text="Prove you are a human." min="0" max="9" step="1" hx-post="/register/profile/is_human"></sl-range>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
templ HumanSliderError(firstNumber int, lastNumber int) {
|
||||||
|
<sl-range name="is_human" label={ humanLabel(firstNumber, lastNumber) } help-text="Prove you are a human." min="0" max="9" step="1"></sl-range>
|
||||||
|
<div slot="help-text">
|
||||||
|
<sl-icon name="x-lg" library="sonr"></sl-icon>
|
||||||
|
Invalid Human Sum
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
templ HumanSliderSuccess() {
|
||||||
|
<sl-range name="is_human" label="Success! Welcome Human." help-text="Prove you are a human." min="0" max="9" step="1" value="9" disabled></sl-range>
|
||||||
|
}
|
||||||
|
|
||||||
|
func humanLabel(firstNumber int, lastNumber int) string {
|
||||||
|
return fmt.Sprintf("What is %d + %d?", firstNumber, lastNumber)
|
||||||
|
}
|
130
pkg/islands/human_slider_templ.go
Normal file
130
pkg/islands/human_slider_templ.go
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
|
// templ: version: v0.2.793
|
||||||
|
package islands
|
||||||
|
|
||||||
|
//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 HumanSlider(firstNumber int, lastNumber int) 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 = templ_7745c5c3_Buffer.WriteString("<div hx-target=\"this\" hx-swap=\"outerHTML\"><sl-range name=\"is_human\" label=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var2 string
|
||||||
|
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(humanLabel(firstNumber, lastNumber))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/islands/human_slider.templ`, Line: 7, Col: 71}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" help-text=\"Prove you are a human.\" min=\"0\" max=\"9\" step=\"1\" hx-post=\"/register/profile/is_human\"></sl-range></div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func HumanSliderError(firstNumber int, lastNumber int) 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 = templ_7745c5c3_Buffer.WriteString("<sl-range name=\"is_human\" label=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var4 string
|
||||||
|
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(humanLabel(firstNumber, lastNumber))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/islands/human_slider.templ`, Line: 12, Col: 70}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" help-text=\"Prove you are a human.\" min=\"0\" max=\"9\" step=\"1\"></sl-range><div slot=\"help-text\"><sl-icon name=\"x-lg\" library=\"sonr\"></sl-icon> Invalid Human Sum</div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func HumanSliderSuccess() 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 = templ_7745c5c3_Buffer.WriteString("<sl-range name=\"is_human\" label=\"Success! Welcome Human.\" help-text=\"Prove you are a human.\" min=\"0\" max=\"9\" step=\"1\" value=\"9\" disabled></sl-range>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func humanLabel(firstNumber int, lastNumber int) string {
|
||||||
|
return fmt.Sprintf("What is %d + %d?", firstNumber, lastNumber)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = templruntime.GeneratedTemplate
|
45
pkg/islands/input_handle.templ
Normal file
45
pkg/islands/input_handle.templ
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package islands
|
||||||
|
|
||||||
|
type HandleState string
|
||||||
|
|
||||||
|
const (
|
||||||
|
HandleStateInitial HandleState = "inital"
|
||||||
|
HandleStateValid HandleState = "valid"
|
||||||
|
HandleStateInvalid HandleState = "invalid"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s HandleState) string() string {
|
||||||
|
return string(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
templ InputHandle() {
|
||||||
|
<div hx-target="this" hx-swap="outerHTML">
|
||||||
|
<sl-input name="handle" placeholder="digitalgold" type="text" label="Handle" minlength="4" maxlength="12" required hx-post="/register/profile" hx-indicator="#handle-indicator" autofocus>
|
||||||
|
<div slot="prefix">
|
||||||
|
<sl-icon name="at-sign" library="sonr"></sl-icon>
|
||||||
|
</div>
|
||||||
|
</sl-input>
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
|
}
|
||||||
|
|
||||||
|
templ InputHandleError(value string, helpText string) {
|
||||||
|
<sl-input name="handle" placeholder="digitalgold" type="text" label="Handle" minlength="4" maxlength="12" required class="border-red-500" value={ value } help-text={ helpText }>
|
||||||
|
<div slot="prefix">
|
||||||
|
<sl-icon name="at-sign" library="sonr"></sl-icon>
|
||||||
|
</div>
|
||||||
|
<div slot="suffix" style="color: #B54549;">
|
||||||
|
<sl-icon name="x"></sl-icon>
|
||||||
|
</div>
|
||||||
|
</sl-input>
|
||||||
|
<br/>
|
||||||
|
}
|
||||||
|
|
||||||
|
templ InputHandleSuccess(value string) {
|
||||||
|
<sl-input name="handle" placeholder="digitalgold" type="text" label="Handle" minlength="4" maxlength="12" required class="border-green-500" value={ value } disabled>
|
||||||
|
<div slot="prefix" style="color: #46A758;">
|
||||||
|
<sl-icon name="at-sign" library="sonr"></sl-icon>
|
||||||
|
</div>
|
||||||
|
</sl-input>
|
||||||
|
<br/>
|
||||||
|
}
|
149
pkg/islands/input_handle_templ.go
Normal file
149
pkg/islands/input_handle_templ.go
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
|
// templ: version: v0.2.793
|
||||||
|
package islands
|
||||||
|
|
||||||
|
//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"
|
||||||
|
|
||||||
|
type HandleState string
|
||||||
|
|
||||||
|
const (
|
||||||
|
HandleStateInitial HandleState = "inital"
|
||||||
|
HandleStateValid HandleState = "valid"
|
||||||
|
HandleStateInvalid HandleState = "invalid"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s HandleState) string() string {
|
||||||
|
return string(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func InputHandle() 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 = templ_7745c5c3_Buffer.WriteString("<div hx-target=\"this\" hx-swap=\"outerHTML\"><sl-input name=\"handle\" placeholder=\"digitalgold\" type=\"text\" label=\"Handle\" minlength=\"4\" maxlength=\"12\" required hx-post=\"/register/profile\" hx-indicator=\"#handle-indicator\" autofocus><div slot=\"prefix\"><sl-icon name=\"at-sign\" library=\"sonr\"></sl-icon></div></sl-input></div><br>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func InputHandleError(value string, helpText 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_Var2 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var2 == nil {
|
||||||
|
templ_7745c5c3_Var2 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<sl-input name=\"handle\" placeholder=\"digitalgold\" type=\"text\" label=\"Handle\" minlength=\"4\" maxlength=\"12\" required class=\"border-red-500\" value=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var3 string
|
||||||
|
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(value)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/islands/input_handle.templ`, Line: 27, Col: 152}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" help-text=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var4 string
|
||||||
|
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(helpText)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/islands/input_handle.templ`, Line: 27, Col: 175}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><div slot=\"prefix\"><sl-icon name=\"at-sign\" library=\"sonr\"></sl-icon></div><div slot=\"suffix\" style=\"color: #B54549;\"><sl-icon name=\"x\"></sl-icon></div></sl-input><br>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func InputHandleSuccess(value 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_Var5 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var5 == nil {
|
||||||
|
templ_7745c5c3_Var5 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<sl-input name=\"handle\" placeholder=\"digitalgold\" type=\"text\" label=\"Handle\" minlength=\"4\" maxlength=\"12\" required class=\"border-green-500\" value=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var6 string
|
||||||
|
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(value)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/islands/input_handle.templ`, Line: 39, Col: 154}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" disabled><div slot=\"prefix\" style=\"color: #46A758;\"><sl-icon name=\"at-sign\" library=\"sonr\"></sl-icon></div></sl-input><br>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = templruntime.GeneratedTemplate
|
97
pkg/islands/input_passkey.templ
Normal file
97
pkg/islands/input_passkey.templ
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
package islands
|
||||||
|
|
||||||
|
templ InputPasskey(addr string, userHandle string, challenge string) {
|
||||||
|
<sl-button style="width: 100%;" onclick={ navigatorCredentialsCreate(addr, userHandle, challenge) }>
|
||||||
|
<sl-icon slot="prefix" name="passkey" library="sonr" style="font-size: 24px;" class="text-neutral-500"></sl-icon>
|
||||||
|
Register Passkey
|
||||||
|
</sl-button>
|
||||||
|
}
|
||||||
|
|
||||||
|
script navigatorCredentialsCreate(userId string, userHandle string, challenge string) {
|
||||||
|
const publicKey = {
|
||||||
|
challenge: Uint8Array.from(challenge, (c) => c.charCodeAt(0)),
|
||||||
|
rp: {
|
||||||
|
name: "Sonr.ID",
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
// Assuming that userId is ASCII-only
|
||||||
|
id: Uint8Array.from(userId, (c) => c.charCodeAt(0)),
|
||||||
|
name: userId,
|
||||||
|
displayName: userHandle,
|
||||||
|
},
|
||||||
|
pubKeyCredParams: [
|
||||||
|
{
|
||||||
|
type: "public-key",
|
||||||
|
alg: -7, // "ES256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "public-key",
|
||||||
|
alg: -257, // "RS256"
|
||||||
|
},
|
||||||
|
],
|
||||||
|
authenticatorSelection: {
|
||||||
|
userVerification: "required",
|
||||||
|
residentKey: "required",
|
||||||
|
authenticatorAttachment: "platform",
|
||||||
|
},
|
||||||
|
timeout: 60000, // 1 minute
|
||||||
|
extensions: {
|
||||||
|
payment: {
|
||||||
|
isPayment: true,
|
||||||
|
},
|
||||||
|
largeBlob: {
|
||||||
|
supported: "preferred",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper function to convert ArrayBuffer to Base64URL string
|
||||||
|
function arrayBufferToBase64URL(buffer) {
|
||||||
|
const bytes = new Uint8Array(buffer);
|
||||||
|
let str = '';
|
||||||
|
bytes.forEach(byte => { str += String.fromCharCode(byte) });
|
||||||
|
return btoa(str)
|
||||||
|
.replace(/\+/g, '-')
|
||||||
|
.replace(/\//g, '_')
|
||||||
|
.replace(/=/g, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
navigator.credentials
|
||||||
|
.create({ publicKey })
|
||||||
|
.then((newCredentialInfo) => {
|
||||||
|
if (!(newCredentialInfo instanceof PublicKeyCredential)) {
|
||||||
|
throw new Error('Received credential is not a PublicKeyCredential');
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = newCredentialInfo.response;
|
||||||
|
if (!(response instanceof AuthenticatorAttestationResponse)) {
|
||||||
|
throw new Error('Response is not an AuthenticatorAttestationResponse');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the credential data to a cross-platform compatible format
|
||||||
|
const credentialJSON = {
|
||||||
|
id: newCredentialInfo.id,
|
||||||
|
rawId: arrayBufferToBase64URL(newCredentialInfo.rawId),
|
||||||
|
type: newCredentialInfo.type,
|
||||||
|
authenticatorAttachment: newCredentialInfo.authenticatorAttachment || null,
|
||||||
|
transports: Array.isArray(response.getTransports) ? response.getTransports() : [],
|
||||||
|
clientExtensionResults: newCredentialInfo.getClientExtensionResults(),
|
||||||
|
response: {
|
||||||
|
attestationObject: arrayBufferToBase64URL(response.attestationObject),
|
||||||
|
clientDataJSON: arrayBufferToBase64URL(response.clientDataJSON)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set the form value with the stringified credential data
|
||||||
|
const credential = document.getElementById('credential-data');
|
||||||
|
credential.value = JSON.stringify(credentialJSON);
|
||||||
|
|
||||||
|
// Submit the form
|
||||||
|
const form = document.getElementById('passkey-form');
|
||||||
|
form.submit();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error('Passkey creation failed:', err);
|
||||||
|
alert(`Failed to create passkey: ${err.message || 'Unknown error'}`);
|
||||||
|
});
|
||||||
|
}
|
148
pkg/islands/input_passkey_templ.go
Normal file
148
pkg/islands/input_passkey_templ.go
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
|
// templ: version: v0.2.793
|
||||||
|
package islands
|
||||||
|
|
||||||
|
//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 InputPasskey(addr string, userHandle string, challenge 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_Var1 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var1 == nil {
|
||||||
|
templ_7745c5c3_Var1 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
templ_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, navigatorCredentialsCreate(addr, userHandle, challenge))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<sl-button style=\"width: 100%;\" onclick=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var2 templ.ComponentScript = navigatorCredentialsCreate(addr, userHandle, challenge)
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var2.Call)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><sl-icon slot=\"prefix\" name=\"passkey\" library=\"sonr\" style=\"font-size: 24px;\" class=\"text-neutral-500\"></sl-icon> Register Passkey</sl-button>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func navigatorCredentialsCreate(userId string, userHandle string, challenge string) templ.ComponentScript {
|
||||||
|
return templ.ComponentScript{
|
||||||
|
Name: `__templ_navigatorCredentialsCreate_63c0`,
|
||||||
|
Function: `function __templ_navigatorCredentialsCreate_63c0(userId, userHandle, challenge){const publicKey = {
|
||||||
|
challenge: Uint8Array.from(challenge, (c) => c.charCodeAt(0)),
|
||||||
|
rp: {
|
||||||
|
name: "Sonr.ID",
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
// Assuming that userId is ASCII-only
|
||||||
|
id: Uint8Array.from(userId, (c) => c.charCodeAt(0)),
|
||||||
|
name: userId,
|
||||||
|
displayName: userHandle,
|
||||||
|
},
|
||||||
|
pubKeyCredParams: [
|
||||||
|
{
|
||||||
|
type: "public-key",
|
||||||
|
alg: -7, // "ES256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "public-key",
|
||||||
|
alg: -257, // "RS256"
|
||||||
|
},
|
||||||
|
],
|
||||||
|
authenticatorSelection: {
|
||||||
|
userVerification: "required",
|
||||||
|
residentKey: "required",
|
||||||
|
authenticatorAttachment: "platform",
|
||||||
|
},
|
||||||
|
timeout: 60000, // 1 minute
|
||||||
|
extensions: {
|
||||||
|
payment: {
|
||||||
|
isPayment: true,
|
||||||
|
},
|
||||||
|
largeBlob: {
|
||||||
|
supported: "preferred",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper function to convert ArrayBuffer to Base64URL string
|
||||||
|
function arrayBufferToBase64URL(buffer) {
|
||||||
|
const bytes = new Uint8Array(buffer);
|
||||||
|
let str = '';
|
||||||
|
bytes.forEach(byte => { str += String.fromCharCode(byte) });
|
||||||
|
return btoa(str)
|
||||||
|
.replace(/\+/g, '-')
|
||||||
|
.replace(/\//g, '_')
|
||||||
|
.replace(/=/g, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
navigator.credentials
|
||||||
|
.create({ publicKey })
|
||||||
|
.then((newCredentialInfo) => {
|
||||||
|
if (!(newCredentialInfo instanceof PublicKeyCredential)) {
|
||||||
|
throw new Error('Received credential is not a PublicKeyCredential');
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = newCredentialInfo.response;
|
||||||
|
if (!(response instanceof AuthenticatorAttestationResponse)) {
|
||||||
|
throw new Error('Response is not an AuthenticatorAttestationResponse');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the credential data to a cross-platform compatible format
|
||||||
|
const credentialJSON = {
|
||||||
|
id: newCredentialInfo.id,
|
||||||
|
rawId: arrayBufferToBase64URL(newCredentialInfo.rawId),
|
||||||
|
type: newCredentialInfo.type,
|
||||||
|
authenticatorAttachment: newCredentialInfo.authenticatorAttachment || null,
|
||||||
|
transports: Array.isArray(response.getTransports) ? response.getTransports() : [],
|
||||||
|
clientExtensionResults: newCredentialInfo.getClientExtensionResults(),
|
||||||
|
response: {
|
||||||
|
attestationObject: arrayBufferToBase64URL(response.attestationObject),
|
||||||
|
clientDataJSON: arrayBufferToBase64URL(response.clientDataJSON)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set the form value with the stringified credential data
|
||||||
|
const credential = document.getElementById('credential-data');
|
||||||
|
credential.value = JSON.stringify(credentialJSON);
|
||||||
|
|
||||||
|
// Submit the form
|
||||||
|
const form = document.getElementById('passkey-form');
|
||||||
|
form.submit();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error('Passkey creation failed:', err);
|
||||||
|
alert(` + "`" + `Failed to create passkey: ${err.message || 'Unknown error'}` + "`" + `);
|
||||||
|
});
|
||||||
|
}`,
|
||||||
|
Call: templ.SafeScript(`__templ_navigatorCredentialsCreate_63c0`, userId, userHandle, challenge),
|
||||||
|
CallInline: templ.SafeScriptInline(`__templ_navigatorCredentialsCreate_63c0`, userId, userHandle, challenge),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = templruntime.GeneratedTemplate
|
58
pkg/views/base_form.templ
Normal file
58
pkg/views/base_form.templ
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package views
|
||||||
|
|
||||||
|
templ Form(action, id string) {
|
||||||
|
<form method="GET" action={ templ.SafeURL(action) } id={ id } hx-post={ action } hx-target="#{ id }" hx-swap="outerHTML">
|
||||||
|
{ children... }
|
||||||
|
</form>
|
||||||
|
}
|
||||||
|
|
||||||
|
templ FormHeader() {
|
||||||
|
<div slot="header">
|
||||||
|
<div class="w-full py-2">
|
||||||
|
{ children... }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
templ FormBody() {
|
||||||
|
<sl-card class="card-form max-w-lg mx-auto">
|
||||||
|
{ children... }
|
||||||
|
<style>
|
||||||
|
.card-form {
|
||||||
|
space-y: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-form [slot='header'] {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-form [slot='footer'] {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</sl-card>
|
||||||
|
}
|
||||||
|
|
||||||
|
templ FormFooter() {
|
||||||
|
<div slot="footer">
|
||||||
|
{ children... }
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
templ FormCancel() {
|
||||||
|
<sl-button href="/" outline>
|
||||||
|
<sl-icon slot="prefix" name="x-lg"></sl-icon>
|
||||||
|
Cancel
|
||||||
|
</sl-button>
|
||||||
|
}
|
||||||
|
|
||||||
|
templ FormSubmit(text string) {
|
||||||
|
<sl-button type="submit">
|
||||||
|
{ text }
|
||||||
|
<sl-icon slot="suffix" name="arrow-right" library="sonr"></sl-icon>
|
||||||
|
</sl-button>
|
||||||
|
}
|
265
pkg/views/base_form_templ.go
Normal file
265
pkg/views/base_form_templ.go
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
|
// templ: version: v0.2.793
|
||||||
|
package views
|
||||||
|
|
||||||
|
//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 Form(action, id 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_Var1 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var1 == nil {
|
||||||
|
templ_7745c5c3_Var1 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<form method=\"GET\" action=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var2 templ.SafeURL = templ.SafeURL(action)
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var2)))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" id=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var3 string
|
||||||
|
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(id)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/views/base_form.templ`, Line: 4, Col: 60}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" hx-post=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var4 string
|
||||||
|
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(action)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/views/base_form.templ`, Line: 4, Col: 79}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" hx-target=\"#{ id }\" hx-swap=\"outerHTML\">")
|
||||||
|
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 = templ_7745c5c3_Buffer.WriteString("</form>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func FormHeader() 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 = templ_7745c5c3_Buffer.WriteString("<div slot=\"header\"><div class=\"w-full py-2\">")
|
||||||
|
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 = templ_7745c5c3_Buffer.WriteString("</div></div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func FormBody() 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 = templ_7745c5c3_Buffer.WriteString("<sl-card class=\"card-form max-w-lg mx-auto\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = templ_7745c5c3_Var6.Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<style>\n\t\t.card-form {\n\t\t\t\tspace-y: 1rem;\n\t\t}\n\n \t.card-form [slot='header'] {\n \tdisplay: flex;\n \talign-items: center;\n \t justify-content: space-between;\n\t }\n\n\t .card-form [slot='footer'] {\n \t \tdisplay: flex;\n \tjustify-content: space-between;\n \talign-items: center;\n \t}\n\t\t</style></sl-card>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func FormFooter() 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_Var7 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var7 == nil {
|
||||||
|
templ_7745c5c3_Var7 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div slot=\"footer\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = templ_7745c5c3_Var7.Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func FormCancel() 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 = templ_7745c5c3_Buffer.WriteString("<sl-button href=\"/\" outline><sl-icon slot=\"prefix\" name=\"x-lg\"></sl-icon> Cancel</sl-button>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func FormSubmit(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 = templ_7745c5c3_Buffer.WriteString("<sl-button type=\"submit\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var10 string
|
||||||
|
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(text)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/views/base_form.templ`, Line: 55, Col: 8}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" <sl-icon slot=\"suffix\" name=\"arrow-right\" library=\"sonr\"></sl-icon></sl-button>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = templruntime.GeneratedTemplate
|
135
pkg/views/base_head.templ
Normal file
135
pkg/views/base_head.templ
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
package views
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
var (
|
||||||
|
nebulaHandle = templ.NewOnceHandle()
|
||||||
|
tailwindHandle = templ.NewOnceHandle()
|
||||||
|
alpineHandle = templ.NewOnceHandle()
|
||||||
|
dexieHandle = templ.NewOnceHandle()
|
||||||
|
htmxHandle = templ.NewOnceHandle()
|
||||||
|
turnstileHandle = templ.NewOnceHandle()
|
||||||
|
)
|
||||||
|
|
||||||
|
templ Head(title string, nebulaVersion string) {
|
||||||
|
<head>
|
||||||
|
@Turnstile()
|
||||||
|
@Tailwind()
|
||||||
|
@Alpine()
|
||||||
|
@Htmx()
|
||||||
|
@Dexie()
|
||||||
|
@Nebula(nebulaVersion)
|
||||||
|
<meta charset="UTF-8"/>
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
<title>{ title }</title>
|
||||||
|
<!-- Sets the status bar style to transparent -->
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes"/>
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
|
||||||
|
<link rel="icon" type="image/png" href="https://cdn.sonr.id/favicon.png"/>
|
||||||
|
<style>
|
||||||
|
@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>
|
||||||
|
{ children... }
|
||||||
|
</head>
|
||||||
|
}
|
||||||
|
|
||||||
|
// ╭──────────────────────────────────────────────────────────╮
|
||||||
|
// │ 3rd Party Libraries │
|
||||||
|
// ╰──────────────────────────────────────────────────────────╯
|
||||||
|
|
||||||
|
// Tailwind css dependencies
|
||||||
|
templ Tailwind() {
|
||||||
|
@tailwindHandle.Once() {
|
||||||
|
<script src="https://cdn.tailwindcss.com?plugins=typography,aspect-ratio,container-queries"></script>
|
||||||
|
<script src="https://kit.fontawesome.com/9909219bb5.js" crossorigin="anonymous"></script>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turnstile is used for cloudflare challenges
|
||||||
|
templ Turnstile() {
|
||||||
|
@turnstileHandle.Once() {
|
||||||
|
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alpine is a component that renders the Alpine.js library
|
||||||
|
templ Alpine() {
|
||||||
|
@alpineHandle.Once() {
|
||||||
|
<script src={ jsDelivrURL("alpinejs", "3.14.6", "dist/cdn.min.js") }></script>
|
||||||
|
<script src={ jsDelivrURL("@alpinejs/focus", "3.14.6", "dist/cdn.min.js") }></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>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nebula is a component that renders the Nebula.js library
|
||||||
|
templ Nebula(version string) {
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
media="(prefers-color-scheme:light)"
|
||||||
|
href={ jsDelivrURL("@onsonr/nebula", version, "cdn/themes/light.css") }
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
media="(prefers-color-scheme:dark)"
|
||||||
|
href={ jsDelivrURL("@onsonr/nebula", version, "cdn/themes/dark.css") }
|
||||||
|
onload="document.documentElement.classList.add('sl-theme-dark');"
|
||||||
|
/>
|
||||||
|
@nebulaHandle.Once() {
|
||||||
|
<script type="module" src={ jsDelivrURL("@onsonr/nebula", version, "cdn/shoelace-autoloader.js") }></script>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ╭───────────────────────────────────────────────────────────╮
|
||||||
|
// │ Helper Functions │
|
||||||
|
// ╰───────────────────────────────────────────────────────────╯
|
||||||
|
|
||||||
|
func jsDelivrURL(pkg string, version string, path string) string {
|
||||||
|
return fmt.Sprintf("https://cdn.jsdelivr.net/npm/%s@%s/%s", pkg, version, path)
|
||||||
|
}
|
573
pkg/views/base_head_templ.go
Normal file
573
pkg/views/base_head_templ.go
Normal file
@ -0,0 +1,573 @@
|
|||||||
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
|
// templ: version: v0.2.793
|
||||||
|
package views
|
||||||
|
|
||||||
|
//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 (
|
||||||
|
nebulaHandle = templ.NewOnceHandle()
|
||||||
|
tailwindHandle = templ.NewOnceHandle()
|
||||||
|
alpineHandle = templ.NewOnceHandle()
|
||||||
|
dexieHandle = templ.NewOnceHandle()
|
||||||
|
htmxHandle = templ.NewOnceHandle()
|
||||||
|
turnstileHandle = templ.NewOnceHandle()
|
||||||
|
)
|
||||||
|
|
||||||
|
func Head(title string, nebulaVersion 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_Var1 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var1 == nil {
|
||||||
|
templ_7745c5c3_Var1 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<head>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = Turnstile().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 = Alpine().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 = Dexie().Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = Nebula(nebulaVersion).Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<meta charset=\"UTF-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var2 string
|
||||||
|
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(title)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/views/base_head.templ`, Line: 25, Col: 16}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</title><!-- Sets the status bar style to transparent --><meta name=\"apple-mobile-web-app-capable\" content=\"yes\"><meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\"><link rel=\"icon\" type=\"image/png\" href=\"https://cdn.sonr.id/favicon.png\"><style>\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
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</head>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ╭──────────────────────────────────────────────────────────╮
|
||||||
|
// │ 3rd Party Libraries │
|
||||||
|
// ╰──────────────────────────────────────────────────────────╯
|
||||||
|
|
||||||
|
// 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_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 = templ_7745c5c3_Buffer.WriteString("<script src=\"https://cdn.tailwindcss.com?plugins=typography,aspect-ratio,container-queries\"></script> <script src=\"https://kit.fontawesome.com/9909219bb5.js\" crossorigin=\"anonymous\"></script>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = tailwindHandle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var4), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turnstile is used for cloudflare challenges
|
||||||
|
func Turnstile() 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 = templ_7745c5c3_Buffer.WriteString("<script src=\"https://challenges.cloudflare.com/turnstile/v0/api.js\" async defer></script>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = turnstileHandle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var6), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alpine is a component that renders the Alpine.js library
|
||||||
|
func Alpine() 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_Var7 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var7 == nil {
|
||||||
|
templ_7745c5c3_Var7 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
templ_7745c5c3_Var8 := 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 = templ_7745c5c3_Buffer.WriteString("<script src=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var9 string
|
||||||
|
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(jsDelivrURL("alpinejs", "3.14.6", "dist/cdn.min.js"))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/views/base_head.templ`, Line: 86, Col: 68}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"></script> <script src=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var10 string
|
||||||
|
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(jsDelivrURL("@alpinejs/focus", "3.14.6", "dist/cdn.min.js"))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/views/base_head.templ`, Line: 87, Col: 75}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"></script>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = alpineHandle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var8), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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_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 = templ_7745c5c3_Buffer.WriteString("<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("dexie", "4.0.10", "dist/dexie.min.js"))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/views/base_head.templ`, Line: 94, Col: 67}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"></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("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: `gateway/views/base_head.templ`, Line: 95, Col: 94}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"></script>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = dexieHandle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var12), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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_Var15 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var15 == nil {
|
||||||
|
templ_7745c5c3_Var15 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
templ_7745c5c3_Var16 := 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 = templ_7745c5c3_Buffer.WriteString("<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.org", "1.9.12", "dist/htmx.min.js"))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/views/base_head.templ`, Line: 102, Col: 69}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"></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-include-vals", "2.0.0", "include-vals.min.js"))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/views/base_head.templ`, Line: 103, Col: 84}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"></script> <script src=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var19 string
|
||||||
|
templ_7745c5c3_Var19, 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: `gateway/views/base_head.templ`, Line: 104, Col: 82}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"></script> <script src=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var20 string
|
||||||
|
templ_7745c5c3_Var20, 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: `gateway/views/base_head.templ`, Line: 105, Col: 84}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"></script> <script src=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var21 string
|
||||||
|
templ_7745c5c3_Var21, 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: `gateway/views/base_head.templ`, Line: 106, Col: 66}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"></script> <script src=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var22 string
|
||||||
|
templ_7745c5c3_Var22, 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: `gateway/views/base_head.templ`, Line: 107, Col: 64}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"></script>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = htmxHandle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var16), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nebula is a component that renders the Nebula.js library
|
||||||
|
func Nebula(version 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_Var23 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var23 == nil {
|
||||||
|
templ_7745c5c3_Var23 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<link rel=\"stylesheet\" media=\"(prefers-color-scheme:light)\" href=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var24 string
|
||||||
|
templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(jsDelivrURL("@onsonr/nebula", version, "cdn/themes/light.css"))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/views/base_head.templ`, Line: 116, Col: 71}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><link rel=\"stylesheet\" media=\"(prefers-color-scheme:dark)\" href=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var25 string
|
||||||
|
templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(jsDelivrURL("@onsonr/nebula", version, "cdn/themes/dark.css"))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/views/base_head.templ`, Line: 121, Col: 70}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" onload=\"document.documentElement.classList.add('sl-theme-dark');\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Var26 := 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 = templ_7745c5c3_Buffer.WriteString("<script type=\"module\" src=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var27 string
|
||||||
|
templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(jsDelivrURL("@onsonr/nebula", version, "cdn/shoelace-autoloader.js"))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/views/base_head.templ`, Line: 125, Col: 98}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"></script>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = nebulaHandle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var26), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ╭───────────────────────────────────────────────────────────╮
|
||||||
|
// │ Helper Functions │
|
||||||
|
// ╰───────────────────────────────────────────────────────────╯
|
||||||
|
|
||||||
|
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
|
36
pkg/views/base_hero.templ
Normal file
36
pkg/views/base_hero.templ
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package views
|
||||||
|
|
||||||
|
templ HeroTitle(title string, subtitle string) {
|
||||||
|
<div class="flex flex-col items-center justify-center h-full w-full gap-2.5">
|
||||||
|
<h1 class="text-2xl md:text-3xl lg:text-4xl font-bold">
|
||||||
|
{ title }
|
||||||
|
</h1>
|
||||||
|
<p class="text-md md:text-lg lg:text-xl font-medium text-gray-500">
|
||||||
|
{ subtitle }
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
templ HeroStart() {
|
||||||
|
<div class="pt-1.5 mb-3 flex flex-col items-center justify-center h-full">
|
||||||
|
<sl-button size="large" hx-target="#container" hx-get="/register" hx-push-url="/register/start" type="button">
|
||||||
|
<sl-icon slot="prefix" library="sonr" name="sonr"></sl-icon>
|
||||||
|
Create Vault
|
||||||
|
<sl-icon slot="suffix" library="sonr" name="arrow-right"></sl-icon>
|
||||||
|
</sl-button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
templ HeroSocials() {
|
||||||
|
<div class="pt-1.5 flex flex-row items-center justify-center h-full gap-3">
|
||||||
|
<sl-button circle outline href="https://sonr.io">
|
||||||
|
<sl-icon name="home" library="sonr" label="Home"></sl-icon>
|
||||||
|
</sl-button>
|
||||||
|
<sl-button circle outline href="https://onsonr.dev">
|
||||||
|
<sl-icon name="docs" library="sonr" label="Docs"></sl-icon>
|
||||||
|
</sl-button>
|
||||||
|
<sl-button circle outline href="https://github.com/onsonr/sonr">
|
||||||
|
<sl-icon name="social-github" library="sonr" label="Open Source"></sl-icon>
|
||||||
|
</sl-button>
|
||||||
|
</div>
|
||||||
|
}
|
124
pkg/views/base_hero_templ.go
Normal file
124
pkg/views/base_hero_templ.go
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
|
// templ: version: v0.2.793
|
||||||
|
package views
|
||||||
|
|
||||||
|
//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 HeroTitle(title string, subtitle 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_Var1 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var1 == nil {
|
||||||
|
templ_7745c5c3_Var1 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"flex flex-col items-center justify-center h-full w-full gap-2.5\"><h1 class=\"text-2xl md:text-3xl lg:text-4xl font-bold\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var2 string
|
||||||
|
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(title)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/views/base_hero.templ`, Line: 6, Col: 10}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</h1><p class=\"text-md md:text-lg lg:text-xl font-medium text-gray-500\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var3 string
|
||||||
|
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(subtitle)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/views/base_hero.templ`, Line: 9, Col: 13}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p></div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func HeroStart() 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 = templ_7745c5c3_Buffer.WriteString("<div class=\"pt-1.5 mb-3 flex flex-col items-center justify-center h-full\"><sl-button size=\"large\" hx-target=\"#container\" hx-get=\"/register\" hx-push-url=\"/register/start\" type=\"button\"><sl-icon slot=\"prefix\" library=\"sonr\" name=\"sonr\"></sl-icon> Create Vault <sl-icon slot=\"suffix\" library=\"sonr\" name=\"arrow-right\"></sl-icon></sl-button></div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func HeroSocials() 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 = templ_7745c5c3_Buffer.WriteString("<div class=\"pt-1.5 flex flex-row items-center justify-center h-full gap-3\"><sl-button circle outline href=\"https://sonr.io\"><sl-icon name=\"home\" library=\"sonr\" label=\"Home\"></sl-icon></sl-button> <sl-button circle outline href=\"https://onsonr.dev\"><sl-icon name=\"docs\" library=\"sonr\" label=\"Docs\"></sl-icon></sl-button> <sl-button circle outline href=\"https://github.com/onsonr/sonr\"><sl-icon name=\"social-github\" library=\"sonr\" label=\"Open Source\"></sl-icon></sl-button></div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = templruntime.GeneratedTemplate
|
59
pkg/views/base_layout.templ
Normal file
59
pkg/views/base_layout.templ
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
package views
|
||||||
|
|
||||||
|
templ LayoutContainer() {
|
||||||
|
<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>
|
||||||
|
}
|
||||||
|
|
||||||
|
// Columns is a component that renders a responsive flex container that stacks on mobile
|
||||||
|
templ LayoutColumns() {
|
||||||
|
<div class="flex flex-col h-full w-full gap-4 md:gap-6 md:flex-row md:flex-wrap">
|
||||||
|
{ children... }
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rows is a component that renders a responsive flex container that wraps on mobile
|
||||||
|
templ LayoutRows() {
|
||||||
|
<div class="flex flex-col w-full gap-3 sm:flex-row sm:flex-wrap sm:gap-4">
|
||||||
|
{ children... }
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
templ LayoutSeparator(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>
|
||||||
|
}
|
||||||
|
|
||||||
|
// Layout is a component that renders the general layout of the application
|
||||||
|
templ LayoutView(title string) {
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
@Head(title, "0.0.11")
|
||||||
|
<body class="flex items-center justify-center h-full lg:p-24 md:16 p-4 no-scrollbar">
|
||||||
|
<main class="flex-row items-center justify-center mx-auto w-fit max-w-screen-lg gap-y-3">
|
||||||
|
{ children... }
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
}
|
||||||
|
|
||||||
|
func Clsx(attrs ...templ.Attributes) templ.Attributes {
|
||||||
|
merged := templ.Attributes{}
|
||||||
|
for _, attr := range attrs {
|
||||||
|
for k, v := range attr {
|
||||||
|
merged[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return merged
|
||||||
|
}
|
222
pkg/views/base_layout_templ.go
Normal file
222
pkg/views/base_layout_templ.go
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
|
// templ: version: v0.2.793
|
||||||
|
package views
|
||||||
|
|
||||||
|
//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 LayoutContainer() 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 = templ_7745c5c3_Buffer.WriteString("<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_Var1.Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div></div></div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Columns is a component that renders a responsive flex container that stacks on mobile
|
||||||
|
func LayoutColumns() 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 = templ_7745c5c3_Buffer.WriteString("<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_Var2.Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rows is a component that renders a responsive flex container that wraps on mobile
|
||||||
|
func LayoutRows() 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 = templ_7745c5c3_Buffer.WriteString("<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_Var3.Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func LayoutSeparator(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_Var4 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var4 == nil {
|
||||||
|
templ_7745c5c3_Var4 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<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_Var5 string
|
||||||
|
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(text)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/views/base_layout.templ`, Line: 33, Col: 45}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</span></div></div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Layout is a component that renders the general layout of the application
|
||||||
|
func LayoutView(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_Var6 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var6 == nil {
|
||||||
|
templ_7745c5c3_Var6 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<!doctype html><html lang=\"en\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = Head(title, "0.0.11").Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<body class=\"flex items-center justify-center h-full lg:p-24 md:16 p-4 no-scrollbar\"><main class=\"flex-row items-center justify-center mx-auto w-fit max-w-screen-lg gap-y-3\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = templ_7745c5c3_Var6.Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</main></body></html>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func Clsx(attrs ...templ.Attributes) templ.Attributes {
|
||||||
|
merged := templ.Attributes{}
|
||||||
|
for _, attr := range attrs {
|
||||||
|
for k, v := range attr {
|
||||||
|
merged[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return merged
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = templruntime.GeneratedTemplate
|
14
pkg/views/view_errors.templ
Normal file
14
pkg/views/view_errors.templ
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package views
|
||||||
|
|
||||||
|
templ ErrorView(err string) {
|
||||||
|
@LayoutView("Error | Sonr.ID") {
|
||||||
|
@LayoutContainer() {
|
||||||
|
@HeroTitle("Uh oh!", "Something went wrong.")
|
||||||
|
<div class="pt-3 flex flex-col items-center justify-center h-full">
|
||||||
|
<p class="text-red-500">
|
||||||
|
{ err }
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
93
pkg/views/view_errors_templ.go
Normal file
93
pkg/views/view_errors_templ.go
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
|
// templ: version: v0.2.793
|
||||||
|
package views
|
||||||
|
|
||||||
|
//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 ErrorView(err 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_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_Var3 := 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 = HeroTitle("Uh oh!", "Something went wrong.").Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" <div class=\"pt-3 flex flex-col items-center justify-center h-full\"><p class=\"text-red-500\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var4 string
|
||||||
|
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(err)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `gateway/views/view_errors.templ`, Line: 9, Col: 10}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p></div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = LayoutContainer().Render(templ.WithChildren(ctx, templ_7745c5c3_Var3), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = LayoutView("Error | Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = templruntime.GeneratedTemplate
|
26
pkg/views/view_home.templ
Normal file
26
pkg/views/view_home.templ
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package views
|
||||||
|
|
||||||
|
templ InitialView() {
|
||||||
|
@LayoutView("Sonr.ID") {
|
||||||
|
@LayoutContainer() {
|
||||||
|
@HeroTitle("Sonr.ID", "The decentralized identity layer for the web.")
|
||||||
|
@HeroStart()
|
||||||
|
@HeroSocials()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
templ ReturningView() {
|
||||||
|
@LayoutView("Login | Sonr.ID") {
|
||||||
|
@LayoutContainer() {
|
||||||
|
@HeroTitle("Welcome Back!", "Continue with your existing Sonr.ID.")
|
||||||
|
<div class="pt-3 flex flex-col items-center justify-center h-full">
|
||||||
|
<sl-button hx-target="#container" hx-get="/register" type="button">
|
||||||
|
<sl-icon slot="prefix" library="sonr" name="sonr"></sl-icon>
|
||||||
|
Log back in
|
||||||
|
<sl-icon slot="suffix" library="sonr" name="arrow-right"></sl-icon>
|
||||||
|
</sl-button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
161
pkg/views/view_home_templ.go
Normal file
161
pkg/views/view_home_templ.go
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
|
// templ: version: v0.2.793
|
||||||
|
package views
|
||||||
|
|
||||||
|
//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 InitialView() 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_Var3 := 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 = HeroTitle("Sonr.ID", "The decentralized identity layer for the web.").Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = HeroStart().Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = HeroSocials().Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = LayoutContainer().Render(templ.WithChildren(ctx, templ_7745c5c3_Var3), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = LayoutView("Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReturningView() 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_Var5 := 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_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 = HeroTitle("Welcome Back!", "Continue with your existing Sonr.ID.").Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" <div class=\"pt-3 flex flex-col items-center justify-center h-full\"><sl-button hx-target=\"#container\" hx-get=\"/register\" type=\"button\"><sl-icon slot=\"prefix\" library=\"sonr\" name=\"sonr\"></sl-icon> Log back in <sl-icon slot=\"suffix\" library=\"sonr\" name=\"arrow-right\"></sl-icon></sl-button></div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = LayoutContainer().Render(templ.WithChildren(ctx, templ_7745c5c3_Var6), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = LayoutView("Login | Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var5), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = templruntime.GeneratedTemplate
|
9
pkg/views/view_loading.templ
Normal file
9
pkg/views/view_loading.templ
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package views
|
||||||
|
|
||||||
|
templ LoadingView() {
|
||||||
|
@LayoutView("Loading... | Sonr.ID") {
|
||||||
|
@LayoutContainer() {
|
||||||
|
@HeroTitle("Loading Vault", "This will be used to login to your vault.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
76
pkg/views/view_loading_templ.go
Normal file
76
pkg/views/view_loading_templ.go
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
|
// templ: version: v0.2.793
|
||||||
|
package views
|
||||||
|
|
||||||
|
//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 LoadingView() 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_Var3 := 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 = HeroTitle("Loading Vault", "This will be used to login to your vault.").Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = LayoutContainer().Render(templ.WithChildren(ctx, templ_7745c5c3_Var3), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = LayoutView("Loading... | Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = templruntime.GeneratedTemplate
|
47
pkg/views/view_register.templ
Normal file
47
pkg/views/view_register.templ
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package views
|
||||||
|
|
||||||
|
import "github.com/onsonr/sonr/gateway/islands"
|
||||||
|
|
||||||
|
templ RegisterProfileView(firstNumber int, lastNumber int) {
|
||||||
|
@LayoutView("New Profile | Sonr.ID") {
|
||||||
|
@LayoutContainer() {
|
||||||
|
@HeroTitle("Basic Info", "Tell us a little about yourself.")
|
||||||
|
@Form("/register/passkey", "create-profile") {
|
||||||
|
@FormBody() {
|
||||||
|
@FormHeader() {
|
||||||
|
<div class="w-full py-2">
|
||||||
|
<sl-avatar shape="circle" size="large" src="https://avatars.githubusercontent.com/u/101929?v=4"></sl-avatar>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@islands.InputHandle()
|
||||||
|
@islands.HumanSlider(firstNumber, lastNumber)
|
||||||
|
@FormFooter() {
|
||||||
|
@FormCancel()
|
||||||
|
@FormSubmit("Next")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
templ RegisterPasskeyView(address string, handle string, name string, challenge string, creationBlock string) {
|
||||||
|
@LayoutView("Register | Sonr.ID") {
|
||||||
|
@LayoutContainer() {
|
||||||
|
@HeroTitle("Link a PassKey", "This will be used to login to your vault.")
|
||||||
|
@Form("/register/finish", "passkey-form") {
|
||||||
|
<input type="hidden" name="credential" id="credential-data" required/>
|
||||||
|
@FormBody() {
|
||||||
|
@FormHeader() {
|
||||||
|
@islands.CardAccount(address, name, handle, creationBlock)
|
||||||
|
}
|
||||||
|
@islands.CoinSelect()
|
||||||
|
@FormFooter() {
|
||||||
|
@islands.InputPasskey(address, handle, challenge)
|
||||||
|
@FormCancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
363
pkg/views/view_register_templ.go
Normal file
363
pkg/views/view_register_templ.go
Normal file
@ -0,0 +1,363 @@
|
|||||||
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
|
// templ: version: v0.2.793
|
||||||
|
package views
|
||||||
|
|
||||||
|
//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/onsonr/sonr/gateway/islands"
|
||||||
|
|
||||||
|
func RegisterProfileView(firstNumber int, lastNumber int) 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_Var3 := 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 = HeroTitle("Basic Info", "Tell us a little about yourself.").Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
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_Var5 := 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_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 = templ_7745c5c3_Buffer.WriteString("<div class=\"w-full py-2\"><sl-avatar shape=\"circle\" size=\"large\" src=\"https://avatars.githubusercontent.com/u/101929?v=4\"></sl-avatar></div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = FormHeader().Render(templ.WithChildren(ctx, templ_7745c5c3_Var6), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = islands.InputHandle().Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = islands.HumanSlider(firstNumber, lastNumber).Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
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 = FormCancel().Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = FormSubmit("Next").Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = FormFooter().Render(templ.WithChildren(ctx, templ_7745c5c3_Var7), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = FormBody().Render(templ.WithChildren(ctx, templ_7745c5c3_Var5), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = Form("/register/passkey", "create-profile").Render(templ.WithChildren(ctx, templ_7745c5c3_Var4), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = LayoutContainer().Render(templ.WithChildren(ctx, templ_7745c5c3_Var3), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = LayoutView("New Profile | Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func RegisterPasskeyView(address string, handle string, name string, challenge string, creationBlock 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_Var8 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var8 == nil {
|
||||||
|
templ_7745c5c3_Var8 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
templ_7745c5c3_Var9 := 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_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 = HeroTitle("Link a PassKey", "This will be used to login to your vault.").Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Var11 := 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 = templ_7745c5c3_Buffer.WriteString("<input type=\"hidden\" name=\"credential\" id=\"credential-data\" required>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
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_Var13 := 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 = islands.CardAccount(address, name, handle, creationBlock).Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = FormHeader().Render(templ.WithChildren(ctx, templ_7745c5c3_Var13), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = islands.CoinSelect().Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Var14 := 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 = islands.InputPasskey(address, handle, challenge).Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = FormCancel().Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = FormFooter().Render(templ.WithChildren(ctx, templ_7745c5c3_Var14), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = FormBody().Render(templ.WithChildren(ctx, templ_7745c5c3_Var12), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = Form("/register/finish", "passkey-form").Render(templ.WithChildren(ctx, templ_7745c5c3_Var11), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = LayoutContainer().Render(templ.WithChildren(ctx, templ_7745c5c3_Var10), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = LayoutView("Register | Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var9), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = templruntime.GeneratedTemplate
|
26
sqlc.yaml
Normal file
26
sqlc.yaml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
version: "2"
|
||||||
|
sql:
|
||||||
|
- engine: "sqlite"
|
||||||
|
queries: "./sink/vault/query.sql"
|
||||||
|
schema: "./sink/vault/schema.sql"
|
||||||
|
gen:
|
||||||
|
go:
|
||||||
|
emit_interface: true
|
||||||
|
emit_json_tags: true
|
||||||
|
package: "motrorm"
|
||||||
|
out: "motrorm"
|
||||||
|
|
||||||
|
- engine: "postgresql"
|
||||||
|
queries: "./sink/highway/query.sql"
|
||||||
|
schema: "./sink/highway/schema.sql"
|
||||||
|
gen:
|
||||||
|
go:
|
||||||
|
emit_all_enum_values: true
|
||||||
|
emit_enum_valid_method: true
|
||||||
|
emit_json_tags: true
|
||||||
|
emit_interface: true
|
||||||
|
emit_result_struct_pointers: true
|
||||||
|
omit_unused_structs: true
|
||||||
|
package: "hwayorm"
|
||||||
|
out: "hwayorm"
|
||||||
|
sql_package: "pgx/v5"
|
1
x/health/handlers/api.go
Normal file
1
x/health/handlers/api.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package handlers
|
1
x/health/handlers/data.go
Normal file
1
x/health/handlers/data.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package handlers
|
1
x/health/handlers/view.go
Normal file
1
x/health/handlers/view.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package handlers
|
1
x/health/routes.go
Normal file
1
x/health/routes.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package health
|
1
x/index/handlers/api.go
Normal file
1
x/index/handlers/api.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package handlers
|
1
x/index/handlers/data.go
Normal file
1
x/index/handlers/data.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package handlers
|
1
x/index/handlers/view.go
Normal file
1
x/index/handlers/view.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package handlers
|
1
x/index/routes.go
Normal file
1
x/index/routes.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package dash
|
1
x/spawn/handlers/api.go
Normal file
1
x/spawn/handlers/api.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package handlers
|
1
x/spawn/handlers/data.go
Normal file
1
x/spawn/handlers/data.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package handlers
|
1
x/spawn/handlers/view.go
Normal file
1
x/spawn/handlers/view.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package handlers
|
1
x/spawn/routes.go
Normal file
1
x/spawn/routes.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package dash
|
Loading…
x
Reference in New Issue
Block a user