feature/1111 sync chain dwn endpoint (#1143)

- **feat(did): add assertion type to DID spec**
- **refactor: update build process to include assets generation**
- **refactor: update import paths for  to**
- **feat: introduce new authentication state management**
- **feat: add current account route**
- **feat: implement global toasts with custom HTML**
- **refactor: remove unused session code**
- **feat: add config.json to embedded assets**
- **refactor: remove unused dependency on gorilla/sessions**
- **refactor: simplify session management and remove unnecessary
fields**
- **fix: remove unnecessary import for unused protobuf types**
- **feat: introduce separate HTTP contexts for Highway and DWN**
- **fix(keeper): Handle missing controller during initial sync**
- **refactor: extract DWN configuration from DWNContext**
- **feat: add  view route**
- **fix: update configuration file name in embed.go**
- **feat: improve vaultindex page loading experience**
- **feat(hway): add highway context to echo context**
- **chore(deps): bump onsonr/crypto from 1.32.0 to 1.33.0**
- **refactor: rename DWNSessionMiddleware to WebNodeSessionMiddleware**
- **feat: rename client API to web node API**
- **refactor: separate API and view routes**
- **refactor: remove unused build targets in Makefile**
- **feat: add Devbox integration to container**
- **feat: add wasm support for dwn**
- **refactor: update module proto import**
- **feat: add default first and third party caveats**
- **feat: Add target vault allocation mechanism**
- **refactor: introduce standardized session cookie handling**
- **fix: update service worker installation and ready states**
- **feat: add worker handlers**
- **feat: Enable SSH access to devcontainer**
- **refactor: rename HighwayContext to HwayContext**
- **feat: add block expiration calculation to sonr context**
- **feat: remove config from cookie and header**
- **feat(gen): Remove generated code for IPFS, Motr and Sonr**
- **refactor: remove unused createMotrConfig function**
- **feat: add project analytics with Repobeats**
- **docs: Remove component details from README**
- **refactor: rename SetConfig to injectConfig**
This commit is contained in:
Prad Nukala 2024-10-15 14:31:19 -04:00 committed by GitHub
parent 104df074e9
commit b6c49828ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
146 changed files with 18035 additions and 4202 deletions

15
.devcontainer/Dockerfile Normal file
View File

@ -0,0 +1,15 @@
FROM jetpackio/devbox:latest
# Installing your devbox project
WORKDIR /code
USER root:root
RUN mkdir -p /code && chown ${DEVBOX_USER}:${DEVBOX_USER} /code
USER ${DEVBOX_USER}:${DEVBOX_USER}
COPY --chown=${DEVBOX_USER}:${DEVBOX_USER} devbox.json devbox.json
COPY --chown=${DEVBOX_USER}:${DEVBOX_USER} devbox.lock devbox.lock
RUN devbox run -- echo "Installed Packages."
RUN devbox shellenv --init-hook >> ~/.profile

View File

@ -0,0 +1,21 @@
{
"name": "Devbox Remote Container",
"build": {
"dockerfile": "./Dockerfile",
"context": ".."
},
"features": {
"ghcr.io/devcontainers/features/sshd:1": {
"version": "latest"
}
},
"customizations": {
"vscode": {
"settings": {},
"extensions": [
"jetpack-io.devbox"
]
}
},
"remoteUser": "devbox"
}

View File

@ -296,6 +296,10 @@ sh-testnet: mod-tidy
.PHONY: templ-gen pkl-gen .PHONY: templ-gen pkl-gen
assets-gen:
@echo "(assets) Generating gateway cloudflare workers assets"
go run github.com/syumai/workers/cmd/workers-assets-gen -mode=go -o ./cmd/hway/build
templ-gen: templ-gen:
@echo "(templ) Generating templ files" @echo "(templ) Generating templ files"
templ generate templ generate
@ -306,34 +310,6 @@ pkl-gen:
go run github.com/apple/pkl-go/cmd/pkl-gen-go ./pkl/ORM.pkl go run github.com/apple/pkl-go/cmd/pkl-gen-go ./pkl/ORM.pkl
go run github.com/apple/pkl-go/cmd/pkl-gen-go ./pkl/Txns.pkl go run github.com/apple/pkl-go/cmd/pkl-gen-go ./pkl/Txns.pkl
###############################################################################
### motr, hway & nebula ###
###############################################################################
.PHONY: motr-build hway-build nebula-build
nebula-build:
@echo "(ui) Building nebula"
cd pkg/nebula && bun install && bun run build
motr-build: nebula-build templ-gen pkl-gen
@echo "(dwn) Building motr.wasm -> Service Worker IPFS Vault"
GOOS=js GOARCH=wasm go build -o ./pkg/dwn/app.wasm ./cmd/motr/main.go
hway-build: nebula-build templ-gen
@echo "(hway) Building Highway gateway"
GOOS=js GOARCH=wasm go build -o ./cmd/hway/build/app.wasm ./cmd/hway/main.go
hway-dev:
@echo "(hway) Serving Highway gateway"
bunx wrangler dev
hway-deploy:
@echo "(hway) Deploying Highway gateway"
bunx wrangler deploy
############################################################################### ###############################################################################
### help ### ### help ###
############################################################################### ###############################################################################

View File

@ -1,37 +1,23 @@
<div align="center" style="text-align: center;">
# `sonr` - Sonr Chain # `sonr` - Sonr Chain
<center>
[![Go Reference](https://pkg.go.dev/badge/github.com/onsonr/sonr.svg)](https://pkg.go.dev/github.com/onsonr/sonr) [![Go Reference](https://pkg.go.dev/badge/github.com/onsonr/sonr.svg)](https://pkg.go.dev/github.com/onsonr/sonr)
![GitHub commit activity](https://img.shields.io/github/commit-activity/w/onsonr/sonr) ![GitHub commit activity](https://img.shields.io/github/commit-activity/w/onsonr/sonr)
![GitHub Release Date - Published_At](https://img.shields.io/github/release-date/onsonr/sonr) ![GitHub Release Date - Published_At](https://img.shields.io/github/release-date/onsonr/sonr)
[![Static Badge](https://img.shields.io/badge/homepage-sonr.io-blue?style=flat-square)](https://sonr.io) [![Static Badge](https://img.shields.io/badge/homepage-sonr.io-blue?style=flat-square)](https://sonr.io)
[![Go Report Card](https://goreportcard.com/badge/github.com/onsonr/sonr)](https://goreportcard.com/report/github.com/onsonr/sonr) [![Go Report Card](https://goreportcard.com/badge/github.com/onsonr/sonr)](https://goreportcard.com/report/github.com/onsonr/sonr)
[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=sonrhq_sonr&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=sonr-io_sonr) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=sonrhq_sonr&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=sonr-io_sonr)
</div> </center>
<br />
## Overview
Sonr is a combination of decentralized primitives. Fundamentally, it is a peer-to-peer identity and asset management system that leverages DID documents, Webauthn, and IPFS—providing users with a secure, portable decentralized identity. Sonr is a combination of decentralized primitives. Fundamentally, it is a peer-to-peer identity and asset management system that leverages DID documents, Webauthn, and IPFS—providing users with a secure, portable decentralized identity.
<br /> ## Stats
## Components ![Alt](https://repobeats.axiom.co/api/embed/8d0b17e889942889c5b6e632da09bd597efd84c4.svg "Repobeats analytics image")
### `sonrd`
The main blockchain node that runs the `sonr` chain. It is responsible for maintaining the state of the chain, including IPFS based vaults, and did documents.
### `vault`
The `vault` is a wasm module that is compiled and deployed to IPFS on behalf of the user. It is responsible for storing and retrieving encrypted data.
- SQLite Database backend
- Encryption via admonition
- Authentication via webauthn
- Authorization via Macroons
- HTTP API
## Acknowledgements ## Acknowledgements

39
Taskfile.yml Normal file
View File

@ -0,0 +1,39 @@
version: "3"
vars:
ROOT_DIR:
sh: pwd
tasks:
hway:build:
dir: cmd/hway
env:
GOOS: js
GOARCH: wasm
cmds:
- go build -o build/app.wasm main.go
hway:dev:
dir: cmd/hway
cmds:
- bunx wrangler dev
hway:deploy:
dir: cmd/hway
cmds:
- bunx wrangler deploy
motr:build:
dir: internal/dwn
env:
GOOS: js
GOARCH: wasm
cmds:
- go build -o app.wasm wasm/main.go
nebula:build:
dir: pkg/nebula
cmds:
- bun install
- bun run deps.mjs
- bunx tailwindcss -i ./global/styles/globals.css -o ./assets/css/styles.css

View File

@ -104,9 +104,9 @@ func (x *fastReflection_Module) Has(fd protoreflect.FieldDescriptor) bool {
switch fd.FullName() { switch fd.FullName() {
default: default:
if fd.IsExtension() { if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.did.module.v1.Module")) panic(fmt.Errorf("proto3 declared messages do not support extensions: did.module.v1.Module"))
} }
panic(fmt.Errorf("message onsonr.sonr.did.module.v1.Module does not contain field %s", fd.FullName())) panic(fmt.Errorf("message did.module.v1.Module does not contain field %s", fd.FullName()))
} }
} }
@ -120,9 +120,9 @@ func (x *fastReflection_Module) Clear(fd protoreflect.FieldDescriptor) {
switch fd.FullName() { switch fd.FullName() {
default: default:
if fd.IsExtension() { if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.did.module.v1.Module")) panic(fmt.Errorf("proto3 declared messages do not support extensions: did.module.v1.Module"))
} }
panic(fmt.Errorf("message onsonr.sonr.did.module.v1.Module does not contain field %s", fd.FullName())) panic(fmt.Errorf("message did.module.v1.Module does not contain field %s", fd.FullName()))
} }
} }
@ -136,9 +136,9 @@ func (x *fastReflection_Module) Get(descriptor protoreflect.FieldDescriptor) pro
switch descriptor.FullName() { switch descriptor.FullName() {
default: default:
if descriptor.IsExtension() { if descriptor.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.did.module.v1.Module")) panic(fmt.Errorf("proto3 declared messages do not support extensions: did.module.v1.Module"))
} }
panic(fmt.Errorf("message onsonr.sonr.did.module.v1.Module does not contain field %s", descriptor.FullName())) panic(fmt.Errorf("message did.module.v1.Module does not contain field %s", descriptor.FullName()))
} }
} }
@ -156,9 +156,9 @@ func (x *fastReflection_Module) Set(fd protoreflect.FieldDescriptor, value proto
switch fd.FullName() { switch fd.FullName() {
default: default:
if fd.IsExtension() { if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.did.module.v1.Module")) panic(fmt.Errorf("proto3 declared messages do not support extensions: did.module.v1.Module"))
} }
panic(fmt.Errorf("message onsonr.sonr.did.module.v1.Module does not contain field %s", fd.FullName())) panic(fmt.Errorf("message did.module.v1.Module does not contain field %s", fd.FullName()))
} }
} }
@ -176,9 +176,9 @@ func (x *fastReflection_Module) Mutable(fd protoreflect.FieldDescriptor) protore
switch fd.FullName() { switch fd.FullName() {
default: default:
if fd.IsExtension() { if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.did.module.v1.Module")) panic(fmt.Errorf("proto3 declared messages do not support extensions: did.module.v1.Module"))
} }
panic(fmt.Errorf("message onsonr.sonr.did.module.v1.Module does not contain field %s", fd.FullName())) panic(fmt.Errorf("message did.module.v1.Module does not contain field %s", fd.FullName()))
} }
} }
@ -189,9 +189,9 @@ func (x *fastReflection_Module) NewField(fd protoreflect.FieldDescriptor) protor
switch fd.FullName() { switch fd.FullName() {
default: default:
if fd.IsExtension() { if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.did.module.v1.Module")) panic(fmt.Errorf("proto3 declared messages do not support extensions: did.module.v1.Module"))
} }
panic(fmt.Errorf("message onsonr.sonr.did.module.v1.Module does not contain field %s", fd.FullName())) panic(fmt.Errorf("message did.module.v1.Module does not contain field %s", fd.FullName()))
} }
} }
@ -201,7 +201,7 @@ func (x *fastReflection_Module) NewField(fd protoreflect.FieldDescriptor) protor
func (x *fastReflection_Module) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { func (x *fastReflection_Module) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
switch d.FullName() { switch d.FullName() {
default: default:
panic(fmt.Errorf("%s is not a oneof field in onsonr.sonr.did.module.v1.Module", d.FullName())) panic(fmt.Errorf("%s is not a oneof field in did.module.v1.Module", d.FullName()))
} }
panic("unreachable") panic("unreachable")
} }
@ -414,29 +414,24 @@ var File_did_module_v1_module_proto protoreflect.FileDescriptor
var file_did_module_v1_module_proto_rawDesc = []byte{ var file_did_module_v1_module_proto_rawDesc = []byte{
0x0a, 0x1a, 0x64, 0x69, 0x64, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x0a, 0x1a, 0x64, 0x69, 0x64, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f,
0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x6f, 0x6e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x64, 0x69,
0x73, 0x6f, 0x6e, 0x72, 0x2e, 0x73, 0x6f, 0x6e, 0x72, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x6d, 0x6f, 0x64, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x20, 0x63, 0x6f, 0x73,
0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x20, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
0x61, 0x70, 0x70, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x6d, 0x6f, 0x64, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x28, 0x0a,
0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x28, 0x0a, 0x06, 0x4d, 0x6f, 0x64, 0x06, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, 0x1e, 0xba, 0xc0, 0x96, 0xda, 0x01, 0x18, 0x0a,
0x75, 0x6c, 0x65, 0x3a, 0x1e, 0xba, 0xc0, 0x96, 0xda, 0x01, 0x18, 0x0a, 0x16, 0x67, 0x69, 0x74, 0x16, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f,
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x42, 0xa9, 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e,
0x6f, 0x6e, 0x72, 0x42, 0xe8, 0x01, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x6f, 0x6e, 0x73, 0x6f, 0x64, 0x69, 0x64, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x4d,
0x6e, 0x72, 0x2e, 0x73, 0x6f, 0x6e, 0x72, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69,
0x6c, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f,
0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x69, 0x64, 0x2f, 0x6d, 0x6f, 0x64,
0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x76, 0x31, 0xa2,
0x2f, 0x64, 0x69, 0x64, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6d, 0x02, 0x03, 0x44, 0x4d, 0x58, 0xaa, 0x02, 0x0d, 0x44, 0x69, 0x64, 0x2e, 0x4d, 0x6f, 0x64, 0x75,
0x6f, 0x64, 0x75, 0x6c, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x04, 0x4f, 0x53, 0x44, 0x4d, 0xaa, 0x02, 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0d, 0x44, 0x69, 0x64, 0x5c, 0x4d, 0x6f, 0x64, 0x75,
0x19, 0x4f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2e, 0x53, 0x6f, 0x6e, 0x72, 0x2e, 0x44, 0x69, 0x64, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x19, 0x44, 0x69, 0x64, 0x5c, 0x4d, 0x6f, 0x64, 0x75,
0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x19, 0x4f, 0x6e, 0x73, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
0x6f, 0x6e, 0x72, 0x5c, 0x53, 0x6f, 0x6e, 0x72, 0x5c, 0x44, 0x69, 0x64, 0x5c, 0x4d, 0x6f, 0x64, 0x61, 0xea, 0x02, 0x0f, 0x44, 0x69, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a,
0x75, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x25, 0x4f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x5c, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x53, 0x6f, 0x6e, 0x72, 0x5c, 0x44, 0x69, 0x64, 0x5c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5c,
0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02,
0x1d, 0x4f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x3a, 0x3a, 0x53, 0x6f, 0x6e, 0x72, 0x3a, 0x3a, 0x44,
0x69, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (
@ -453,7 +448,7 @@ func file_did_module_v1_module_proto_rawDescGZIP() []byte {
var file_did_module_v1_module_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_did_module_v1_module_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_did_module_v1_module_proto_goTypes = []interface{}{ var file_did_module_v1_module_proto_goTypes = []interface{}{
(*Module)(nil), // 0: onsonr.sonr.did.module.v1.Module (*Module)(nil), // 0: did.module.v1.Module
} }
var file_did_module_v1_module_proto_depIdxs = []int32{ var file_did_module_v1_module_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type 0, // [0:0] is the sub-list for method output_type

View File

@ -9,6 +9,163 @@ import (
ormerrors "cosmossdk.io/orm/types/ormerrors" ormerrors "cosmossdk.io/orm/types/ormerrors"
) )
type AssertionTable interface {
Insert(ctx context.Context, assertion *Assertion) error
Update(ctx context.Context, assertion *Assertion) error
Save(ctx context.Context, assertion *Assertion) error
Delete(ctx context.Context, assertion *Assertion) error
Has(ctx context.Context, did string) (found bool, err error)
// Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found.
Get(ctx context.Context, did string) (*Assertion, error)
HasByControllerSubject(ctx context.Context, controller string, subject string) (found bool, err error)
// GetByControllerSubject returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found.
GetByControllerSubject(ctx context.Context, controller string, subject string) (*Assertion, error)
List(ctx context.Context, prefixKey AssertionIndexKey, opts ...ormlist.Option) (AssertionIterator, error)
ListRange(ctx context.Context, from, to AssertionIndexKey, opts ...ormlist.Option) (AssertionIterator, error)
DeleteBy(ctx context.Context, prefixKey AssertionIndexKey) error
DeleteRange(ctx context.Context, from, to AssertionIndexKey) error
doNotImplement()
}
type AssertionIterator struct {
ormtable.Iterator
}
func (i AssertionIterator) Value() (*Assertion, error) {
var assertion Assertion
err := i.UnmarshalMessage(&assertion)
return &assertion, err
}
type AssertionIndexKey interface {
id() uint32
values() []interface{}
assertionIndexKey()
}
// primary key starting index..
type AssertionPrimaryKey = AssertionDidIndexKey
type AssertionDidIndexKey struct {
vs []interface{}
}
func (x AssertionDidIndexKey) id() uint32 { return 0 }
func (x AssertionDidIndexKey) values() []interface{} { return x.vs }
func (x AssertionDidIndexKey) assertionIndexKey() {}
func (this AssertionDidIndexKey) WithDid(did string) AssertionDidIndexKey {
this.vs = []interface{}{did}
return this
}
type AssertionControllerSubjectIndexKey struct {
vs []interface{}
}
func (x AssertionControllerSubjectIndexKey) id() uint32 { return 1 }
func (x AssertionControllerSubjectIndexKey) values() []interface{} { return x.vs }
func (x AssertionControllerSubjectIndexKey) assertionIndexKey() {}
func (this AssertionControllerSubjectIndexKey) WithController(controller string) AssertionControllerSubjectIndexKey {
this.vs = []interface{}{controller}
return this
}
func (this AssertionControllerSubjectIndexKey) WithControllerSubject(controller string, subject string) AssertionControllerSubjectIndexKey {
this.vs = []interface{}{controller, subject}
return this
}
type assertionTable struct {
table ormtable.Table
}
func (this assertionTable) Insert(ctx context.Context, assertion *Assertion) error {
return this.table.Insert(ctx, assertion)
}
func (this assertionTable) Update(ctx context.Context, assertion *Assertion) error {
return this.table.Update(ctx, assertion)
}
func (this assertionTable) Save(ctx context.Context, assertion *Assertion) error {
return this.table.Save(ctx, assertion)
}
func (this assertionTable) Delete(ctx context.Context, assertion *Assertion) error {
return this.table.Delete(ctx, assertion)
}
func (this assertionTable) Has(ctx context.Context, did string) (found bool, err error) {
return this.table.PrimaryKey().Has(ctx, did)
}
func (this assertionTable) Get(ctx context.Context, did string) (*Assertion, error) {
var assertion Assertion
found, err := this.table.PrimaryKey().Get(ctx, &assertion, did)
if err != nil {
return nil, err
}
if !found {
return nil, ormerrors.NotFound
}
return &assertion, nil
}
func (this assertionTable) HasByControllerSubject(ctx context.Context, controller string, subject string) (found bool, err error) {
return this.table.GetIndexByID(1).(ormtable.UniqueIndex).Has(ctx,
controller,
subject,
)
}
func (this assertionTable) GetByControllerSubject(ctx context.Context, controller string, subject string) (*Assertion, error) {
var assertion Assertion
found, err := this.table.GetIndexByID(1).(ormtable.UniqueIndex).Get(ctx, &assertion,
controller,
subject,
)
if err != nil {
return nil, err
}
if !found {
return nil, ormerrors.NotFound
}
return &assertion, nil
}
func (this assertionTable) List(ctx context.Context, prefixKey AssertionIndexKey, opts ...ormlist.Option) (AssertionIterator, error) {
it, err := this.table.GetIndexByID(prefixKey.id()).List(ctx, prefixKey.values(), opts...)
return AssertionIterator{it}, err
}
func (this assertionTable) ListRange(ctx context.Context, from, to AssertionIndexKey, opts ...ormlist.Option) (AssertionIterator, error) {
it, err := this.table.GetIndexByID(from.id()).ListRange(ctx, from.values(), to.values(), opts...)
return AssertionIterator{it}, err
}
func (this assertionTable) DeleteBy(ctx context.Context, prefixKey AssertionIndexKey) error {
return this.table.GetIndexByID(prefixKey.id()).DeleteBy(ctx, prefixKey.values()...)
}
func (this assertionTable) DeleteRange(ctx context.Context, from, to AssertionIndexKey) error {
return this.table.GetIndexByID(from.id()).DeleteRange(ctx, from.values(), to.values())
}
func (this assertionTable) doNotImplement() {}
var _ AssertionTable = assertionTable{}
func NewAssertionTable(db ormtable.Schema) (AssertionTable, error) {
table := db.GetTable(&Assertion{})
if table == nil {
return nil, ormerrors.TableNotFound.Wrap(string((&Assertion{}).ProtoReflect().Descriptor().FullName()))
}
return assertionTable{table}, nil
}
type AuthenticationTable interface { type AuthenticationTable interface {
Insert(ctx context.Context, authentication *Authentication) error Insert(ctx context.Context, authentication *Authentication) error
Update(ctx context.Context, authentication *Authentication) error Update(ctx context.Context, authentication *Authentication) error
@ -692,6 +849,7 @@ func NewVerificationTable(db ormtable.Schema) (VerificationTable, error) {
} }
type StateStore interface { type StateStore interface {
AssertionTable() AssertionTable
AuthenticationTable() AuthenticationTable AuthenticationTable() AuthenticationTable
ControllerTable() ControllerTable ControllerTable() ControllerTable
VerificationTable() VerificationTable VerificationTable() VerificationTable
@ -700,11 +858,16 @@ type StateStore interface {
} }
type stateStore struct { type stateStore struct {
assertion AssertionTable
authentication AuthenticationTable authentication AuthenticationTable
controller ControllerTable controller ControllerTable
verification VerificationTable verification VerificationTable
} }
func (x stateStore) AssertionTable() AssertionTable {
return x.assertion
}
func (x stateStore) AuthenticationTable() AuthenticationTable { func (x stateStore) AuthenticationTable() AuthenticationTable {
return x.authentication return x.authentication
} }
@ -722,6 +885,11 @@ func (stateStore) doNotImplement() {}
var _ StateStore = stateStore{} var _ StateStore = stateStore{}
func NewStateStore(db ormtable.Schema) (StateStore, error) { func NewStateStore(db ormtable.Schema) (StateStore, error) {
assertionTable, err := NewAssertionTable(db)
if err != nil {
return nil, err
}
authenticationTable, err := NewAuthenticationTable(db) authenticationTable, err := NewAuthenticationTable(db)
if err != nil { if err != nil {
return nil, err return nil, err
@ -738,6 +906,7 @@ func NewStateStore(db ormtable.Schema) (StateStore, error) {
} }
return stateStore{ return stateStore{
assertionTable,
authenticationTable, authenticationTable,
controllerTable, controllerTable,
verificationTable, verificationTable,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -20,7 +20,10 @@ const _ = grpc.SupportPackageIsVersion7
const ( const (
Msg_ExecuteTx_FullMethodName = "/did.v1.Msg/ExecuteTx" Msg_ExecuteTx_FullMethodName = "/did.v1.Msg/ExecuteTx"
Msg_RegisterController_FullMethodName = "/did.v1.Msg/RegisterController" Msg_LinkAssertion_FullMethodName = "/did.v1.Msg/LinkAssertion"
Msg_LinkAuthentication_FullMethodName = "/did.v1.Msg/LinkAuthentication"
Msg_UnlinkAssertion_FullMethodName = "/did.v1.Msg/UnlinkAssertion"
Msg_UnlinkAuthentication_FullMethodName = "/did.v1.Msg/UnlinkAuthentication"
Msg_UpdateParams_FullMethodName = "/did.v1.Msg/UpdateParams" Msg_UpdateParams_FullMethodName = "/did.v1.Msg/UpdateParams"
) )
@ -31,9 +34,14 @@ type MsgClient interface {
// ExecuteTx executes a transaction on the Sonr Blockchain. It leverages // ExecuteTx executes a transaction on the Sonr Blockchain. It leverages
// Macaroon for verification. // Macaroon for verification.
ExecuteTx(ctx context.Context, in *MsgExecuteTx, opts ...grpc.CallOption) (*MsgExecuteTxResponse, error) ExecuteTx(ctx context.Context, in *MsgExecuteTx, opts ...grpc.CallOption) (*MsgExecuteTxResponse, error)
// RegisterController initializes a controller with the given authentication // LinkAssertion links an assertion to a controller.
// set, address, cid, publicKey, and user-defined alias. LinkAssertion(ctx context.Context, in *MsgLinkAssertion, opts ...grpc.CallOption) (*MsgLinkAssertionResponse, error)
RegisterController(ctx context.Context, in *MsgRegisterController, opts ...grpc.CallOption) (*MsgRegisterControllerResponse, error) // LinkAuthentication links an authentication to a controller.
LinkAuthentication(ctx context.Context, in *MsgLinkAuthentication, opts ...grpc.CallOption) (*MsgLinkAuthenticationResponse, error)
// UnlinkAssertion unlinks an assertion from a controller.
UnlinkAssertion(ctx context.Context, in *MsgUnlinkAssertion, opts ...grpc.CallOption) (*MsgUnlinkAssertionResponse, error)
// UnlinkAuthentication unlinks an authentication from a controller.
UnlinkAuthentication(ctx context.Context, in *MsgUnlinkAuthentication, opts ...grpc.CallOption) (*MsgUnlinkAuthenticationResponse, error)
// UpdateParams defines a governance operation for updating the parameters. // UpdateParams defines a governance operation for updating the parameters.
UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error)
} }
@ -55,9 +63,36 @@ func (c *msgClient) ExecuteTx(ctx context.Context, in *MsgExecuteTx, opts ...grp
return out, nil return out, nil
} }
func (c *msgClient) RegisterController(ctx context.Context, in *MsgRegisterController, opts ...grpc.CallOption) (*MsgRegisterControllerResponse, error) { func (c *msgClient) LinkAssertion(ctx context.Context, in *MsgLinkAssertion, opts ...grpc.CallOption) (*MsgLinkAssertionResponse, error) {
out := new(MsgRegisterControllerResponse) out := new(MsgLinkAssertionResponse)
err := c.cc.Invoke(ctx, Msg_RegisterController_FullMethodName, in, out, opts...) err := c.cc.Invoke(ctx, Msg_LinkAssertion_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *msgClient) LinkAuthentication(ctx context.Context, in *MsgLinkAuthentication, opts ...grpc.CallOption) (*MsgLinkAuthenticationResponse, error) {
out := new(MsgLinkAuthenticationResponse)
err := c.cc.Invoke(ctx, Msg_LinkAuthentication_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *msgClient) UnlinkAssertion(ctx context.Context, in *MsgUnlinkAssertion, opts ...grpc.CallOption) (*MsgUnlinkAssertionResponse, error) {
out := new(MsgUnlinkAssertionResponse)
err := c.cc.Invoke(ctx, Msg_UnlinkAssertion_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *msgClient) UnlinkAuthentication(ctx context.Context, in *MsgUnlinkAuthentication, opts ...grpc.CallOption) (*MsgUnlinkAuthenticationResponse, error) {
out := new(MsgUnlinkAuthenticationResponse)
err := c.cc.Invoke(ctx, Msg_UnlinkAuthentication_FullMethodName, in, out, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -80,9 +115,14 @@ type MsgServer interface {
// ExecuteTx executes a transaction on the Sonr Blockchain. It leverages // ExecuteTx executes a transaction on the Sonr Blockchain. It leverages
// Macaroon for verification. // Macaroon for verification.
ExecuteTx(context.Context, *MsgExecuteTx) (*MsgExecuteTxResponse, error) ExecuteTx(context.Context, *MsgExecuteTx) (*MsgExecuteTxResponse, error)
// RegisterController initializes a controller with the given authentication // LinkAssertion links an assertion to a controller.
// set, address, cid, publicKey, and user-defined alias. LinkAssertion(context.Context, *MsgLinkAssertion) (*MsgLinkAssertionResponse, error)
RegisterController(context.Context, *MsgRegisterController) (*MsgRegisterControllerResponse, error) // LinkAuthentication links an authentication to a controller.
LinkAuthentication(context.Context, *MsgLinkAuthentication) (*MsgLinkAuthenticationResponse, error)
// UnlinkAssertion unlinks an assertion from a controller.
UnlinkAssertion(context.Context, *MsgUnlinkAssertion) (*MsgUnlinkAssertionResponse, error)
// UnlinkAuthentication unlinks an authentication from a controller.
UnlinkAuthentication(context.Context, *MsgUnlinkAuthentication) (*MsgUnlinkAuthenticationResponse, error)
// UpdateParams defines a governance operation for updating the parameters. // UpdateParams defines a governance operation for updating the parameters.
UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error)
mustEmbedUnimplementedMsgServer() mustEmbedUnimplementedMsgServer()
@ -95,8 +135,17 @@ type UnimplementedMsgServer struct {
func (UnimplementedMsgServer) ExecuteTx(context.Context, *MsgExecuteTx) (*MsgExecuteTxResponse, error) { func (UnimplementedMsgServer) ExecuteTx(context.Context, *MsgExecuteTx) (*MsgExecuteTxResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ExecuteTx not implemented") return nil, status.Errorf(codes.Unimplemented, "method ExecuteTx not implemented")
} }
func (UnimplementedMsgServer) RegisterController(context.Context, *MsgRegisterController) (*MsgRegisterControllerResponse, error) { func (UnimplementedMsgServer) LinkAssertion(context.Context, *MsgLinkAssertion) (*MsgLinkAssertionResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method RegisterController not implemented") return nil, status.Errorf(codes.Unimplemented, "method LinkAssertion not implemented")
}
func (UnimplementedMsgServer) LinkAuthentication(context.Context, *MsgLinkAuthentication) (*MsgLinkAuthenticationResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method LinkAuthentication not implemented")
}
func (UnimplementedMsgServer) UnlinkAssertion(context.Context, *MsgUnlinkAssertion) (*MsgUnlinkAssertionResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method UnlinkAssertion not implemented")
}
func (UnimplementedMsgServer) UnlinkAuthentication(context.Context, *MsgUnlinkAuthentication) (*MsgUnlinkAuthenticationResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method UnlinkAuthentication not implemented")
} }
func (UnimplementedMsgServer) UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) { func (UnimplementedMsgServer) UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method UpdateParams not implemented") return nil, status.Errorf(codes.Unimplemented, "method UpdateParams not implemented")
@ -132,20 +181,74 @@ func _Msg_ExecuteTx_Handler(srv interface{}, ctx context.Context, dec func(inter
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
func _Msg_RegisterController_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { func _Msg_LinkAssertion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(MsgRegisterController) in := new(MsgLinkAssertion)
if err := dec(in); err != nil { if err := dec(in); err != nil {
return nil, err return nil, err
} }
if interceptor == nil { if interceptor == nil {
return srv.(MsgServer).RegisterController(ctx, in) return srv.(MsgServer).LinkAssertion(ctx, in)
} }
info := &grpc.UnaryServerInfo{ info := &grpc.UnaryServerInfo{
Server: srv, Server: srv,
FullMethod: Msg_RegisterController_FullMethodName, FullMethod: Msg_LinkAssertion_FullMethodName,
} }
handler := func(ctx context.Context, req interface{}) (interface{}, error) { handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MsgServer).RegisterController(ctx, req.(*MsgRegisterController)) return srv.(MsgServer).LinkAssertion(ctx, req.(*MsgLinkAssertion))
}
return interceptor(ctx, in, info, handler)
}
func _Msg_LinkAuthentication_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(MsgLinkAuthentication)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MsgServer).LinkAuthentication(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Msg_LinkAuthentication_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MsgServer).LinkAuthentication(ctx, req.(*MsgLinkAuthentication))
}
return interceptor(ctx, in, info, handler)
}
func _Msg_UnlinkAssertion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(MsgUnlinkAssertion)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MsgServer).UnlinkAssertion(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Msg_UnlinkAssertion_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MsgServer).UnlinkAssertion(ctx, req.(*MsgUnlinkAssertion))
}
return interceptor(ctx, in, info, handler)
}
func _Msg_UnlinkAuthentication_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(MsgUnlinkAuthentication)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MsgServer).UnlinkAuthentication(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Msg_UnlinkAuthentication_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MsgServer).UnlinkAuthentication(ctx, req.(*MsgUnlinkAuthentication))
} }
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
@ -180,8 +283,20 @@ var Msg_ServiceDesc = grpc.ServiceDesc{
Handler: _Msg_ExecuteTx_Handler, Handler: _Msg_ExecuteTx_Handler,
}, },
{ {
MethodName: "RegisterController", MethodName: "LinkAssertion",
Handler: _Msg_RegisterController_Handler, Handler: _Msg_LinkAssertion_Handler,
},
{
MethodName: "LinkAuthentication",
Handler: _Msg_LinkAuthentication_Handler,
},
{
MethodName: "UnlinkAssertion",
Handler: _Msg_UnlinkAssertion_Handler,
},
{
MethodName: "UnlinkAuthentication",
Handler: _Msg_UnlinkAuthentication_Handler,
}, },
{ {
MethodName: "UpdateParams", MethodName: "UpdateParams",

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -21,7 +21,9 @@ const _ = grpc.SupportPackageIsVersion7
const ( const (
Query_Params_FullMethodName = "/vault.v1.Query/Params" Query_Params_FullMethodName = "/vault.v1.Query/Params"
Query_Schema_FullMethodName = "/vault.v1.Query/Schema" Query_Schema_FullMethodName = "/vault.v1.Query/Schema"
Query_Sync_FullMethodName = "/vault.v1.Query/Sync" Query_Allocate_FullMethodName = "/vault.v1.Query/Allocate"
Query_SyncInitial_FullMethodName = "/vault.v1.Query/SyncInitial"
Query_SyncCurrent_FullMethodName = "/vault.v1.Query/SyncCurrent"
) )
// QueryClient is the client API for Query service. // QueryClient is the client API for Query service.
@ -33,9 +35,15 @@ type QueryClient interface {
// Schema queries the DID document by its id. And returns the required PKL // Schema queries the DID document by its id. And returns the required PKL
// information // information
Schema(ctx context.Context, in *QuerySchemaRequest, opts ...grpc.CallOption) (*QuerySchemaResponse, error) Schema(ctx context.Context, in *QuerySchemaRequest, opts ...grpc.CallOption) (*QuerySchemaResponse, error)
// Allocate initializes a Target Vault available for claims with a compatible
// Authentication mechanism. The default authentication mechanism is WebAuthn.
Allocate(ctx context.Context, in *AllocateRequest, opts ...grpc.CallOption) (*AllocateResponse, error)
// Sync queries the DID document by its id. And returns the required PKL // Sync queries the DID document by its id. And returns the required PKL
// information // information
Sync(ctx context.Context, in *SyncRequest, opts ...grpc.CallOption) (*SyncResponse, error) SyncInitial(ctx context.Context, in *SyncInitialRequest, opts ...grpc.CallOption) (*SyncInitialResponse, error)
// SyncCurrent queries the DID document by its id. And returns the required PKL
// information
SyncCurrent(ctx context.Context, in *SyncCurrentRequest, opts ...grpc.CallOption) (*SyncCurrentResponse, error)
} }
type queryClient struct { type queryClient struct {
@ -64,9 +72,27 @@ func (c *queryClient) Schema(ctx context.Context, in *QuerySchemaRequest, opts .
return out, nil return out, nil
} }
func (c *queryClient) Sync(ctx context.Context, in *SyncRequest, opts ...grpc.CallOption) (*SyncResponse, error) { func (c *queryClient) Allocate(ctx context.Context, in *AllocateRequest, opts ...grpc.CallOption) (*AllocateResponse, error) {
out := new(SyncResponse) out := new(AllocateResponse)
err := c.cc.Invoke(ctx, Query_Sync_FullMethodName, in, out, opts...) err := c.cc.Invoke(ctx, Query_Allocate_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *queryClient) SyncInitial(ctx context.Context, in *SyncInitialRequest, opts ...grpc.CallOption) (*SyncInitialResponse, error) {
out := new(SyncInitialResponse)
err := c.cc.Invoke(ctx, Query_SyncInitial_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *queryClient) SyncCurrent(ctx context.Context, in *SyncCurrentRequest, opts ...grpc.CallOption) (*SyncCurrentResponse, error) {
out := new(SyncCurrentResponse)
err := c.cc.Invoke(ctx, Query_SyncCurrent_FullMethodName, in, out, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -82,9 +108,15 @@ type QueryServer interface {
// Schema queries the DID document by its id. And returns the required PKL // Schema queries the DID document by its id. And returns the required PKL
// information // information
Schema(context.Context, *QuerySchemaRequest) (*QuerySchemaResponse, error) Schema(context.Context, *QuerySchemaRequest) (*QuerySchemaResponse, error)
// Allocate initializes a Target Vault available for claims with a compatible
// Authentication mechanism. The default authentication mechanism is WebAuthn.
Allocate(context.Context, *AllocateRequest) (*AllocateResponse, error)
// Sync queries the DID document by its id. And returns the required PKL // Sync queries the DID document by its id. And returns the required PKL
// information // information
Sync(context.Context, *SyncRequest) (*SyncResponse, error) SyncInitial(context.Context, *SyncInitialRequest) (*SyncInitialResponse, error)
// SyncCurrent queries the DID document by its id. And returns the required PKL
// information
SyncCurrent(context.Context, *SyncCurrentRequest) (*SyncCurrentResponse, error)
mustEmbedUnimplementedQueryServer() mustEmbedUnimplementedQueryServer()
} }
@ -98,8 +130,14 @@ func (UnimplementedQueryServer) Params(context.Context, *QueryParamsRequest) (*Q
func (UnimplementedQueryServer) Schema(context.Context, *QuerySchemaRequest) (*QuerySchemaResponse, error) { func (UnimplementedQueryServer) Schema(context.Context, *QuerySchemaRequest) (*QuerySchemaResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Schema not implemented") return nil, status.Errorf(codes.Unimplemented, "method Schema not implemented")
} }
func (UnimplementedQueryServer) Sync(context.Context, *SyncRequest) (*SyncResponse, error) { func (UnimplementedQueryServer) Allocate(context.Context, *AllocateRequest) (*AllocateResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Sync not implemented") return nil, status.Errorf(codes.Unimplemented, "method Allocate not implemented")
}
func (UnimplementedQueryServer) SyncInitial(context.Context, *SyncInitialRequest) (*SyncInitialResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method SyncInitial not implemented")
}
func (UnimplementedQueryServer) SyncCurrent(context.Context, *SyncCurrentRequest) (*SyncCurrentResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method SyncCurrent not implemented")
} }
func (UnimplementedQueryServer) mustEmbedUnimplementedQueryServer() {} func (UnimplementedQueryServer) mustEmbedUnimplementedQueryServer() {}
@ -150,20 +188,56 @@ func _Query_Schema_Handler(srv interface{}, ctx context.Context, dec func(interf
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
func _Query_Sync_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { func _Query_Allocate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SyncRequest) in := new(AllocateRequest)
if err := dec(in); err != nil { if err := dec(in); err != nil {
return nil, err return nil, err
} }
if interceptor == nil { if interceptor == nil {
return srv.(QueryServer).Sync(ctx, in) return srv.(QueryServer).Allocate(ctx, in)
} }
info := &grpc.UnaryServerInfo{ info := &grpc.UnaryServerInfo{
Server: srv, Server: srv,
FullMethod: Query_Sync_FullMethodName, FullMethod: Query_Allocate_FullMethodName,
} }
handler := func(ctx context.Context, req interface{}) (interface{}, error) { handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(QueryServer).Sync(ctx, req.(*SyncRequest)) return srv.(QueryServer).Allocate(ctx, req.(*AllocateRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Query_SyncInitial_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SyncInitialRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(QueryServer).SyncInitial(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Query_SyncInitial_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(QueryServer).SyncInitial(ctx, req.(*SyncInitialRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Query_SyncCurrent_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SyncCurrentRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(QueryServer).SyncCurrent(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Query_SyncCurrent_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(QueryServer).SyncCurrent(ctx, req.(*SyncCurrentRequest))
} }
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
@ -184,8 +258,16 @@ var Query_ServiceDesc = grpc.ServiceDesc{
Handler: _Query_Schema_Handler, Handler: _Query_Schema_Handler,
}, },
{ {
MethodName: "Sync", MethodName: "Allocate",
Handler: _Query_Sync_Handler, Handler: _Query_Allocate_Handler,
},
{
MethodName: "SyncInitial",
Handler: _Query_SyncInitial_Handler,
},
{
MethodName: "SyncCurrent",
Handler: _Query_SyncCurrent_Handler,
}, },
}, },
Streams: []grpc.StreamDesc{}, Streams: []grpc.StreamDesc{},

File diff suppressed because it is too large Load Diff

View File

@ -1191,7 +1191,7 @@ func GetDefaultBypassFeeMessages() []string {
sdk.MsgTypeURL(&ibcchanneltypes.MsgChannelOpenConfirm{}), sdk.MsgTypeURL(&ibcchanneltypes.MsgChannelOpenConfirm{}),
sdk.MsgTypeURL(&ibcchanneltypes.MsgChannelOpenAck{}), sdk.MsgTypeURL(&ibcchanneltypes.MsgChannelOpenAck{}),
sdk.MsgTypeURL(&vaulttypes.MsgAllocateVault{}), sdk.MsgTypeURL(&vaulttypes.MsgAllocateVault{}),
sdk.MsgTypeURL(&didtypes.MsgRegisterController{}), sdk.MsgTypeURL(&didtypes.MsgLinkAuthentication{}),
} }
} }

4
buf.work.yaml Normal file
View File

@ -0,0 +1,4 @@
version: v1
directories:
- proto
- third_party/proto

View File

@ -11,8 +11,8 @@ import (
func main() { func main() {
s := echo.New() s := echo.New()
s.Use(ctx.SessionMiddleware) s.Use(ctx.HighwaySessionMiddleware)
routes.RegisterProxyViews(s) routes.RegisterGatewayViews(s)
routes.RegisterProxyAPI(s) routes.RegisterGatewayAPI(s)
workers.Serve(s) workers.Serve(s)
} }

View File

@ -1,8 +1,8 @@
name = "sonr-id" name = "sonr-id"
main = "./cmd/hway/build/worker.mjs" main = "./build/worker.mjs"
compatibility_date = "2024-10-07" compatibility_date = "2024-10-07"
routes = [{ pattern = "sonr.id", custom_domain = true }] routes = [{ pattern = "sonr.id", custom_domain = true }]
[build] [build]
command = "make hway-build" command = "task hway:build"

View File

@ -1,6 +1,11 @@
{ {
"$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.12.0/.schema/devbox.schema.json", "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.12.0/.schema/devbox.schema.json",
"packages": ["go@1.22", "bun@latest", "ipfs@latest", "templ@latest"], "packages": [
"go@1.22",
"bun@latest",
"ipfs@latest",
"templ@latest"
],
"env": { "env": {
"GOPATH": "$HOME/go", "GOPATH": "$HOME/go",
"PATH": "./build:$HOME/go/bin:$PATH", "PATH": "./build:$HOME/go/bin:$PATH",
@ -20,18 +25,18 @@
}, },
"shell": { "shell": {
"scripts": { "scripts": {
"build:docker": ["make local-image"], "gen:pkl": [
"build:hway": ["make hway-build"], "make gen-pkl"
"build:nebula": ["make nebula-build"], ],
"build:motr": ["make motr-build"], "gen:templ": [
"build:sonrd": ["make motr-build", "make build"], "make gen-templ"
"build": ["make motr-build", "make build", "make hway-build"], ],
"gen:proto": ["rm -rf ./pkg/nebula/node_modules", "make proto-gen"], "start": [
"gen:pkl": ["make gen-pkl"], "process-compose up -f ./deploy/process-compose.yaml"
"gen:templ": ["make gen-templ"], ],
"start": ["process-compose up -f ./deploy/process-compose.yaml"], "stop": [
"stop": ["process-compose down -f ./deploy/process-compose.yaml"], "process-compose down -f ./deploy/process-compose.yaml"
"start:testnet": ["make sh-testnet"] ]
} }
} }
} }

4
go.mod
View File

@ -66,14 +66,13 @@ require (
github.com/go-webauthn/webauthn v0.10.2 github.com/go-webauthn/webauthn v0.10.2
github.com/golang/protobuf v1.5.4 github.com/golang/protobuf v1.5.4
github.com/gorilla/mux v1.8.1 github.com/gorilla/mux v1.8.1
github.com/gorilla/sessions v1.4.0
github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0
github.com/ipfs/boxo v0.21.0 github.com/ipfs/boxo v0.21.0
github.com/ipfs/kubo v0.29.0 github.com/ipfs/kubo v0.29.0
github.com/joho/godotenv v1.5.1 github.com/joho/godotenv v1.5.1
github.com/labstack/echo/v4 v4.10.2 github.com/labstack/echo/v4 v4.10.2
github.com/nlepage/go-js-promise v1.0.0 github.com/nlepage/go-js-promise v1.0.0
github.com/onsonr/crypto v1.32.0 github.com/onsonr/crypto v1.33.0
github.com/segmentio/ksuid v1.0.4 github.com/segmentio/ksuid v1.0.4
github.com/spf13/cast v1.6.0 github.com/spf13/cast v1.6.0
github.com/spf13/cobra v1.8.0 github.com/spf13/cobra v1.8.0
@ -183,7 +182,6 @@ require (
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
github.com/googleapis/gax-go/v2 v2.12.2 // indirect github.com/googleapis/gax-go/v2 v2.12.2 // indirect
github.com/gorilla/handlers v1.5.2 // indirect github.com/gorilla/handlers v1.5.2 // indirect
github.com/gorilla/securecookie v1.1.2 // indirect
github.com/gorilla/websocket v1.5.3 // indirect github.com/gorilla/websocket v1.5.3 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect

8
go.sum
View File

@ -1375,10 +1375,6 @@ github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyE
github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
github.com/gorilla/sessions v1.4.0 h1:kpIYOp/oi6MG/p5PgxApU8srsSw9tuFbt46Lt7auzqQ=
github.com/gorilla/sessions v1.4.0/go.mod h1:FLWm50oby91+hl7p/wRxDth9bWSuk0qVL2emc7lT5ik=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
@ -1833,8 +1829,8 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk=
github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0=
github.com/onsonr/crypto v1.32.0 h1:3XxItjoYg4vLuTU7uvpbIl/MTk2tb6L43SSO9RFcEXc= github.com/onsonr/crypto v1.33.0 h1:K0KgEQXrzppw/nPXn1swY1a7oUmMdQGcLycuipoqjqM=
github.com/onsonr/crypto v1.32.0/go.mod h1:NSfeCO6XoyQeSDEp6Jy42UGG5047GvzG6lW9lRnjrR0= github.com/onsonr/crypto v1.33.0/go.mod h1:NSfeCO6XoyQeSDEp6Jy42UGG5047GvzG6lW9lRnjrR0=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI=

View File

@ -1,95 +0,0 @@
package ctx
import (
"fmt"
"net/http"
"time"
"github.com/labstack/echo/v4"
"gopkg.in/macaroon.v2"
)
const (
OriginMacroonCaveat MacroonCaveat = "origin"
ScopesMacroonCaveat MacroonCaveat = "scopes"
SubjectMacroonCaveat MacroonCaveat = "subject"
ExpMacroonCaveat MacroonCaveat = "exp"
TokenMacroonCaveat MacroonCaveat = "token"
)
var MacroonCaveats = []MacroonCaveat{OriginMacroonCaveat, ScopesMacroonCaveat, SubjectMacroonCaveat, ExpMacroonCaveat, TokenMacroonCaveat}
type MacroonCaveat string
func (c MacroonCaveat) Equal(other string) bool {
return string(c) == other
}
func (c MacroonCaveat) String() string {
return string(c)
}
func (c MacroonCaveat) Verify(value string) error {
switch c {
case OriginMacroonCaveat:
return nil
case ScopesMacroonCaveat:
return nil
case SubjectMacroonCaveat:
return nil
case ExpMacroonCaveat:
// Check if the expiration time is still valid
exp, err := time.Parse(time.RFC3339, value)
if err != nil {
return err
}
if time.Now().After(exp) {
return fmt.Errorf("expired")
}
return nil
case TokenMacroonCaveat:
return nil
default:
return fmt.Errorf("unknown caveat: %s", c)
}
}
func MacaroonMiddleware(secretKeyStr string, location string) echo.MiddlewareFunc {
secretKey := []byte(secretKeyStr)
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
// Extract the macaroon from the Authorization header
auth := c.Request().Header.Get("Authorization")
if auth == "" {
return c.JSON(http.StatusUnauthorized, map[string]string{"error": "Missing Authorization header"})
}
// Decode the macaroon
mac, err := macaroon.Base64Decode([]byte(auth))
if err != nil {
return c.JSON(http.StatusBadRequest, map[string]string{"error": "Invalid macaroon encoding"})
}
token, err := macaroon.New(secretKey, mac, location, macaroon.LatestVersion)
if err != nil {
return c.JSON(http.StatusBadRequest, map[string]string{"error": "Invalid macaroon"})
}
// Verify the macaroon
err = token.Verify(secretKey, func(caveat string) error {
for _, c := range MacroonCaveats {
if c.String() == caveat {
return nil
}
}
return nil // Return nil if the caveat is valid
}, nil)
if err != nil {
return c.JSON(http.StatusUnauthorized, map[string]string{"error": "Invalid macaroon"})
}
// Macaroon is valid, proceed to the next handler
return next(c)
}
}
}

View File

@ -1,44 +0,0 @@
//go:build js && wasm
package ctx
import (
"syscall/js"
"github.com/labstack/echo/v4"
)
type BroadcastContext struct {
echo.Context
Channel js.Value
}
func (c *BroadcastContext) BroadcastMessage(message string) {
c.Channel.Call("postMessage", message)
}
type JSHandler func(this js.Value, args []js.Value) interface{}
func UseBroadcastChannel(channelName string, handler JSHandler) echo.MiddlewareFunc {
var channel js.Value
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
if channel.IsUndefined() {
channel = js.Global().Get("BroadcastChannel").New(channelName)
channel.Call("addEventListener", "message", handler)
}
cc := &BroadcastContext{
Context: c,
Channel: channel,
}
return next(cc)
}
}
}
func PostBroadcastMessage(c echo.Context, message string) {
cc := c.(*BroadcastContext)
cc.BroadcastMessage(message)
}

30
internal/ctx/cookies.go Normal file
View File

@ -0,0 +1,30 @@
package ctx
import (
"github.com/labstack/echo/v4"
"github.com/segmentio/ksuid"
)
type CookieKey string
const (
CookieKeySessionID CookieKey = "session.id"
CookieKeySonrAddr CookieKey = "sonr.addr"
CookieKeySonrDID CookieKey = "sonr.did"
CookieKeyVaultCID CookieKey = "vault.cid"
CookieKeyVaultSchema CookieKey = "vault.schema"
)
func (c CookieKey) String() string {
return string(c)
}
func GetSessionID(c echo.Context) string {
// Attempt to read the session ID from the "session" cookie
sessionID, err := ReadCookie(c, CookieKeySessionID)
if err != nil {
// Generate a new KSUID if the session cookie is missing or invalid
WriteCookie(c, CookieKeySessionID, ksuid.New().String())
}
return sessionID
}

77
internal/ctx/ctx_dwn.go Normal file
View File

@ -0,0 +1,77 @@
package ctx
import (
"encoding/json"
"net/http"
"github.com/labstack/echo/v4"
dwngen "github.com/onsonr/sonr/internal/dwn/gen"
)
type DWNContext struct {
echo.Context
// Defaults
id string // Generated ksuid http cookie; Initialized on first request
}
func (s *DWNContext) HasAuthorization() bool {
v := ReadHeader(s.Context, HeaderAuthorization)
return v != ""
}
func (s *DWNContext) ID() string {
return s.id
}
func (s *DWNContext) Address() string {
v, err := ReadCookie(s.Context, CookieKeySonrAddr)
if err != nil {
return ""
}
return v
}
func (s *DWNContext) IPFSGatewayURL() string {
return ReadHeader(s.Context, HeaderIPFSGatewayURL)
}
func (s *DWNContext) ChainID() string {
return ReadHeader(s.Context, HeaderSonrChainID)
}
func (s *DWNContext) Schema() *dwngen.Schema {
v, err := ReadCookie(s.Context, CookieKeyVaultSchema)
if err != nil {
return nil
}
var schema dwngen.Schema
err = json.Unmarshal([]byte(v), &schema)
if err != nil {
return nil
}
return &schema
}
func GetDWNContext(c echo.Context) (*DWNContext, error) {
ctx, ok := c.(*DWNContext)
if !ok {
return nil, echo.NewHTTPError(http.StatusInternalServerError, "DWN Context not found")
}
return ctx, nil
}
// HighwaySessionMiddleware establishes a Session Cookie.
func DWNSessionMiddleware(config *dwngen.Config) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
sessionID := GetSessionID(c)
injectConfig(c, config)
cc := &DWNContext{
Context: c,
id: sessionID,
}
return next(cc)
}
}
}

38
internal/ctx/ctx_hway.go Normal file
View File

@ -0,0 +1,38 @@
package ctx
import (
"net/http"
"github.com/labstack/echo/v4"
)
type HwayContext struct {
echo.Context
// Defaults
id string // Generated ksuid http cookie; Initialized on first request
}
func (s *HwayContext) ID() string {
return s.id
}
func GetHWAYContext(c echo.Context) (*HwayContext, error) {
ctx, ok := c.(*HwayContext)
if !ok {
return nil, echo.NewHTTPError(http.StatusInternalServerError, "Highway Context not found")
}
return ctx, nil
}
// HighwaySessionMiddleware establishes a Session Cookie.
func HighwaySessionMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
sessionID := GetSessionID(c)
cc := &HwayContext{
Context: c,
id: sessionID,
}
return next(cc)
}
}

21
internal/ctx/ctx_sonr.go Normal file
View File

@ -0,0 +1,21 @@
package ctx
import (
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
)
type SonrContext struct {
sdk.Context
}
func GetSonrCTX(ctx sdk.Context) *SonrContext {
return &SonrContext{ctx}
}
func (s *SonrContext) GetBlockExpiration(duration time.Duration) int64 {
blockTime := s.BlockTime()
avgBlockTime := float64(blockTime.Sub(blockTime).Seconds())
return int64(duration.Seconds() / avgBlockTime)
}

View File

@ -1,68 +1,37 @@
package ctx package ctx
// ╭───────────────────────────────────────────────────────────╮ import (
// │ Request Headers │ "encoding/json"
// ╰───────────────────────────────────────────────────────────╯
type RequestHeaders struct { "github.com/labstack/echo/v4"
CacheControl *string `header:"Cache-Control"` dwngen "github.com/onsonr/sonr/internal/dwn/gen"
DeviceMemory *string `header:"Device-Memory"` )
From *string `header:"From"`
Host *string `header:"Host"`
Referer *string `header:"Referer"`
UserAgent *string `header:"User-Agent"`
ViewportWidth *string `header:"Viewport-Width"`
Width *string `header:"Width"`
// HTMX Specific type HeaderKey string
HXBoosted *string `header:"HX-Boosted"`
HXCurrentURL *string `header:"HX-Current-URL"` const (
HXHistoryRestoreRequest *string `header:"HX-History-Restore-Request"` HeaderAuthorization HeaderKey = "Authorization"
HXPrompt *string `header:"HX-Prompt"`
HXRequest *string `header:"HX-Request"` HeaderIPFSGatewayURL HeaderKey = "X-IPFS-Gateway"
HXTarget *string `header:"HX-Target"` HeaderSonrChainID HeaderKey = "X-Sonr-ChainID"
HXTriggerName *string `header:"HX-Trigger-Name"` HeaderSonrKeyshare HeaderKey = "X-Sonr-Keyshare"
HXTrigger *string `header:"HX-Trigger"` )
func (h HeaderKey) String() string {
return string(h)
} }
type ProtectedRequestHeaders struct { func injectConfig(c echo.Context, config *dwngen.Config) {
Authorization *string `header:"Authorization"` WriteHeader(c, HeaderIPFSGatewayURL, config.IpfsGatewayUrl)
Forwarded *string `header:"Forwarded"` WriteHeader(c, HeaderSonrChainID, config.SonrChainId)
Link *string `header:"Link"` WriteHeader(c, HeaderSonrKeyshare, config.MotrKeyshare)
PermissionsPolicy *string `header:"Permissions-Policy"` WriteCookie(c, CookieKeySonrAddr, config.MotrAddress)
ProxyAuthorization *string `header:"Proxy-Authorization"`
WWWAuthenticate *string `header:"WWW-Authenticate"` schemaBz, err := json.Marshal(config.VaultSchema)
if err != nil {
c.Logger().Error(err)
return
} }
// ╭───────────────────────────────────────────────────────────╮ WriteCookie(c, CookieKeyVaultSchema, string(schemaBz))
// │ Response Headers │
// ╰───────────────────────────────────────────────────────────╯
type ResponseHeaders struct {
// HTMX Specific
HXLocation *string `header:"HX-Location"`
HXPushURL *string `header:"HX-Push-Url"`
HXRedirect *string `header:"HX-Redirect"`
HXRefresh *string `header:"HX-Refresh"`
HXReplaceURL *string `header:"HX-Replace-Url"`
HXReswap *string `header:"HX-Reswap"`
HXRetarget *string `header:"HX-Retarget"`
HXReselect *string `header:"HX-Reselect"`
HXTrigger *string `header:"HX-Trigger"`
HXTriggerAfterSettle *string `header:"HX-Trigger-After-Settle"`
HXTriggerAfterSwap *string `header:"HX-Trigger-After-Swap"`
}
type ProtectedResponseHeaders struct {
AcceptCH *string `header:"Accept-CH"`
AccessControlAllowCredentials *string `header:"Access-Control-Allow-Credentials"`
AccessControlAllowHeaders *string `header:"Access-Control-Allow-Headers"`
AccessControlAllowMethods *string `header:"Access-Control-Allow-Methods"`
AccessControlExposeHeaders *string `header:"Access-Control-Expose-Headers"`
AccessControlRequestHeaders *string `header:"Access-Control-Request-Headers"`
ContentSecurityPolicy *string `header:"Content-Security-Policy"`
CrossOriginEmbedderPolicy *string `header:"Cross-Origin-Embedder-Policy"`
PermissionsPolicy *string `header:"Permissions-Policy"`
ProxyAuthorization *string `header:"Proxy-Authorization"`
WWWAuthenticate *string `header:"WWW-Authenticate"`
} }

View File

@ -1,25 +0,0 @@
package ctx
import (
"bytes"
"github.com/a-h/templ"
"github.com/labstack/echo/v4"
)
func RenderTempl(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())
return err
}

35
internal/ctx/request.go Normal file
View File

@ -0,0 +1,35 @@
package ctx
// ╭───────────────────────────────────────────────────────────╮
// │ Request Headers │
// ╰───────────────────────────────────────────────────────────╯
type RequestHeaders struct {
CacheControl *string `header:"Cache-Control"`
DeviceMemory *string `header:"Device-Memory"`
From *string `header:"From"`
Host *string `header:"Host"`
Referer *string `header:"Referer"`
UserAgent *string `header:"User-Agent"`
ViewportWidth *string `header:"Viewport-Width"`
Width *string `header:"Width"`
// HTMX Specific
HXBoosted *string `header:"HX-Boosted"`
HXCurrentURL *string `header:"HX-Current-URL"`
HXHistoryRestoreRequest *string `header:"HX-History-Restore-Request"`
HXPrompt *string `header:"HX-Prompt"`
HXRequest *string `header:"HX-Request"`
HXTarget *string `header:"HX-Target"`
HXTriggerName *string `header:"HX-Trigger-Name"`
HXTrigger *string `header:"HX-Trigger"`
}
type ProtectedRequestHeaders struct {
Authorization *string `header:"Authorization"`
Forwarded *string `header:"Forwarded"`
Link *string `header:"Link"`
PermissionsPolicy *string `header:"Permissions-Policy"`
ProxyAuthorization *string `header:"Proxy-Authorization"`
WWWAuthenticate *string `header:"WWW-Authenticate"`
}

38
internal/ctx/response.go Normal file
View File

@ -0,0 +1,38 @@
package ctx
import "github.com/go-webauthn/webauthn/protocol"
type WebBytes = protocol.URLEncodedBase64
// ╭───────────────────────────────────────────────────────────╮
// │ Response Headers │
// ╰───────────────────────────────────────────────────────────╯
type ResponseHeaders struct {
// HTMX Specific
HXLocation *string `header:"HX-Location"`
HXPushURL *string `header:"HX-Push-Url"`
HXRedirect *string `header:"HX-Redirect"`
HXRefresh *string `header:"HX-Refresh"`
HXReplaceURL *string `header:"HX-Replace-Url"`
HXReswap *string `header:"HX-Reswap"`
HXRetarget *string `header:"HX-Retarget"`
HXReselect *string `header:"HX-Reselect"`
HXTrigger *string `header:"HX-Trigger"`
HXTriggerAfterSettle *string `header:"HX-Trigger-After-Settle"`
HXTriggerAfterSwap *string `header:"HX-Trigger-After-Swap"`
}
type ProtectedResponseHeaders struct {
AcceptCH *string `header:"Accept-CH"`
AccessControlAllowCredentials *string `header:"Access-Control-Allow-Credentials"`
AccessControlAllowHeaders *string `header:"Access-Control-Allow-Headers"`
AccessControlAllowMethods *string `header:"Access-Control-Allow-Methods"`
AccessControlExposeHeaders *string `header:"Access-Control-Expose-Headers"`
AccessControlRequestHeaders *string `header:"Access-Control-Request-Headers"`
ContentSecurityPolicy *string `header:"Content-Security-Policy"`
CrossOriginEmbedderPolicy *string `header:"Cross-Origin-Embedder-Policy"`
PermissionsPolicy *string `header:"Permissions-Policy"`
ProxyAuthorization *string `header:"Proxy-Authorization"`
WWWAuthenticate *string `header:"WWW-Authenticate"`
}

View File

@ -1,103 +0,0 @@
package ctx
import (
"context"
"errors"
"net/http"
"net/url"
"time"
"github.com/gorilla/sessions"
"github.com/labstack/echo/v4"
"github.com/segmentio/ksuid"
)
var store sessions.Store
type ctxKeySessionID struct{}
// SessionMiddleware establishes a Session Cookie.
func SessionMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
store = sessions.NewCookieStore([]byte("SESSION_KEY"))
return func(c echo.Context) error {
ctx := c.Request().Context()
// Attempt to read the session ID from the "session" cookie
sessionID, err := readSessionIDFromCookie(c)
if err != nil {
// Generate a new KSUID if the session cookie is missing or invalid
sessionID = ksuid.New().String()
// Write the new session ID to the "session" cookie
err = writeSessionIDToCookie(c, sessionID)
if err != nil {
return c.JSON(
http.StatusInternalServerError,
map[string]string{"error": "Failed to set session cookie"},
)
}
}
// Inject the session ID into the context
ctx = context.WithValue(ctx, ctxKeySessionID{}, sessionID)
// Update the request with the new context
c.SetRequest(c.Request().WithContext(ctx))
return next(c)
}
}
func buildSession(c echo.Context, id string) *Session {
return &Session{
ID: id,
Origin: getOrigin(c.Request().Header.Get("Host")),
UserAgent: c.Request().Header.Get("Sec-Ch-Ua"),
Platform: c.Request().Header.Get("Sec-Ch-Ua-Platform"),
Address: c.Request().Header.Get("X-Sonr-Address"),
ChainID: "",
}
}
func getOrigin(o string) string {
if o == "" {
return ""
}
u, err := url.Parse(o)
if err != nil {
return ""
}
return u.Hostname()
}
func getSessionID(ctx context.Context) (string, error) {
sessionID, ok := ctx.Value(ctxKeySessionID{}).(string)
if !ok || sessionID == "" {
return "", errors.New("session ID not found in context")
}
return sessionID, nil
}
func readSessionIDFromCookie(c echo.Context) (string, error) {
cookie, err := c.Cookie("session")
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 writeSessionIDToCookie(c echo.Context, sessionID string) error {
cookie := &http.Cookie{
Name: "session",
Value: sessionID,
Expires: time.Now().Add(24 * time.Hour),
HttpOnly: true,
Path: "/",
// Add Secure and SameSite attributes as needed
}
c.SetCookie(cookie)
return nil
}

View File

@ -1,27 +0,0 @@
package ctx
import "github.com/labstack/echo/v4"
type AuthState string
const (
Visitor AuthState = "visitor"
Authenticated AuthState = "authenticated"
Expired AuthState = "expired"
PendingCredentials AuthState = "pending_credentials"
PendingAssertion AuthState = "pending_assertion"
)
func (s AuthState) String() string {
return string(s)
}
func GetAuthState(c echo.Context) AuthState {
vals := c.Request().Header.Values("Authorization")
if len(vals) == 0 {
return Visitor
}
s := AuthState(c.Request().Header.Get("Authorization"))
return s
}

View File

@ -1,70 +0,0 @@
package ctx
import (
"errors"
"fmt"
"github.com/go-webauthn/webauthn/protocol"
"github.com/labstack/echo/v4"
)
type WebBytes = protocol.URLEncodedBase64
type Session struct {
// Defaults
ID string // Generated ksuid http cookie; Initialized on first request
Origin string // Webauthn mapping to Relaying Party ID; Initialized on first request
UserAgent string
Platform string
// Initialization
Address string // Webauthn mapping to User ID; Supplied by DWN frontend
ChainID string // Macaroon mapping to location; Supplied by DWN frontend
Subject string // Webauthn mapping to User Displayable Name; Supplied by DWN frontend
// Authentication
challenge WebBytes // Webauthn mapping to Challenge; Per session based on origin
}
func (s *Session) GetChallenge(subject string) (WebBytes, error) {
// Check if challenge is already set and subject matches
if s.Subject != "" && s.Subject != subject {
return nil, errors.New("challenge already set, and subject does not match")
} else if s.Subject == "" {
s.Subject = subject
} else {
return s.challenge, nil
}
if s.challenge == nil {
chl, err := protocol.CreateChallenge()
if err != nil {
return nil, err
}
s.challenge = chl
}
return s.challenge, nil
}
func (s *Session) ValidateChallenge(challenge WebBytes, subject string) error {
if s.challenge == nil {
return nil
}
if s.challenge.String() != challenge.String() {
return fmt.Errorf("invalid challenge")
}
s.Subject = subject
return nil
}
func GetSession(c echo.Context) *Session {
id, _ := getSessionID(c.Request().Context())
return buildSession(c, id)
}
func SetAddress(c echo.Context, address string) *Session {
// Write address to X-Sonr-Address header
c.Response().Header().Set("X-Sonr-Address", address)
return buildSession(c, "")
}

73
internal/ctx/utils.go Normal file
View File

@ -0,0 +1,73 @@
package ctx
import (
"bytes"
"net/http"
"time"
"github.com/a-h/templ"
"github.com/labstack/echo/v4"
)
// ╭───────────────────────────────────────────────────────────╮
// │ Template Rendering │
// ╰───────────────────────────────────────────────────────────╯
func RenderTempl(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())
return err
}
// ╭──────────────────────────────────────────────────────────╮
// │ Cookie Management │
// ╰──────────────────────────────────────────────────────────╯
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 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
}
// ╭────────────────────────────────────────────────────────╮
// │ HTTP Headers │
// ╰────────────────────────────────────────────────────────╯
func WriteHeader(c echo.Context, key HeaderKey, value string) {
c.Response().Header().Set(key.String(), value)
}
func ReadHeader(c echo.Context, key HeaderKey) string {
return c.Response().Header().Get(key.String())
}

Binary file not shown.

View File

@ -2,10 +2,18 @@ package dwn
import ( import (
_ "embed" _ "embed"
"encoding/json"
"github.com/ipfs/boxo/files" "github.com/ipfs/boxo/files"
"github.com/onsonr/sonr/internal/dwn/gen" "github.com/onsonr/sonr/internal/dwn/gen"
"github.com/onsonr/sonr/pkg/nebula/components/index" "github.com/onsonr/sonr/pkg/nebula/components/vaultindex"
)
const (
FileNameAppWASM = "app.wasm"
FileNameConfigJSON = "dwn.json"
FileNameIndexHTML = "index.html"
FileNameWorkerJS = "sw.js"
) )
//go:embed app.wasm //go:embed app.wasm
@ -14,21 +22,21 @@ var dwnWasmData []byte
//go:embed sw.js //go:embed sw.js
var swJSData []byte var swJSData []byte
var (
dwnWasmFile = files.NewBytesFile(dwnWasmData)
swJSFile = files.NewBytesFile(swJSData)
)
// NewVaultDirectory creates a new directory with the default files // NewVaultDirectory creates a new directory with the default files
func NewVaultDirectory(cnfg *gen.Config) (files.Node, error) { func NewVaultDirectory(cnfg *gen.Config) (files.Node, error) {
idxFile, err := index.BuildFile(cnfg) idxFile, err := vaultindex.BuildFile(cnfg)
if err != nil {
return nil, err
}
cnfgBz, err := json.Marshal(cnfg)
if err != nil { if err != nil {
return nil, err return nil, err
} }
fileMap := map[string]files.Node{ fileMap := map[string]files.Node{
"sw.js": swJSFile, FileNameAppWASM: files.NewBytesFile(dwnWasmData),
"app.wasm": dwnWasmFile, FileNameConfigJSON: files.NewBytesFile(cnfgBz),
"index.html": idxFile, FileNameIndexHTML: idxFile,
FileNameWorkerJS: files.NewBytesFile(swJSData),
} }
return files.NewMapDirectory(fileMap), nil return files.NewMapDirectory(fileMap), nil
} }

View File

@ -1,7 +1,7 @@
//go:build js && wasm //go:build js && wasm
// +build js,wasm // +build js,wasm
package dwn package fetch
import ( import (
"bytes" "bytes"

View File

@ -2,13 +2,17 @@
package gen package gen
type Config struct { type Config struct {
Ipfs *IPFS `pkl:"ipfs" json:"ipfs,omitempty"` IpfsGatewayUrl string `pkl:"ipfsGatewayUrl" json:"ipfsGatewayUrl,omitempty"`
Sonr *Sonr `pkl:"sonr" json:"sonr,omitempty"` MotrKeyshare string `pkl:"motrKeyshare" json:"motrKeyshare,omitempty"`
Motr *Motr `pkl:"motr" json:"motr,omitempty"` MotrAddress string `pkl:"motrAddress" json:"motrAddress,omitempty"`
Schema *Schema `pkl:"schema" json:"schema,omitempty"` SonrApiUrl string `pkl:"sonrApiUrl" json:"sonrApiUrl,omitempty"`
ProxyUrl string `pkl:"proxyUrl" json:"proxyUrl,omitempty"` SonrRpcUrl string `pkl:"sonrRpcUrl" json:"sonrRpcUrl,omitempty"`
SonrChainId string `pkl:"sonrChainId" json:"sonrChainId,omitempty"`
VaultSchema *Schema `pkl:"vaultSchema" json:"vaultSchema,omitempty"`
} }

View File

@ -1,8 +0,0 @@
// Code generated from Pkl module `dwngen`. DO NOT EDIT.
package gen
type IPFS struct {
ApiUrl string `pkl:"apiUrl" json:"apiUrl,omitempty"`
GatewayUrl string `pkl:"gatewayUrl" json:"gatewayUrl,omitempty"`
}

View File

@ -1,10 +0,0 @@
// Code generated from Pkl module `dwngen`. DO NOT EDIT.
package gen
type Motr struct {
Keyshare string `pkl:"keyshare" json:"keyshare,omitempty"`
Address string `pkl:"address" json:"address,omitempty"`
Origin string `pkl:"origin" json:"origin,omitempty"`
}

View File

@ -1,14 +0,0 @@
// Code generated from Pkl module `dwngen`. DO NOT EDIT.
package gen
type Sonr struct {
ApiUrl string `pkl:"apiUrl" json:"apiUrl,omitempty"`
GrpcUrl string `pkl:"grpcUrl" json:"grpcUrl,omitempty"`
RpcUrl string `pkl:"rpcUrl" json:"rpcUrl,omitempty"`
WebSocketUrl string `pkl:"webSocketUrl" json:"webSocketUrl,omitempty"`
ChainId string `pkl:"chainId" json:"chainId,omitempty"`
}

View File

@ -6,8 +6,5 @@ import "github.com/apple/pkl-go/pkl"
func init() { func init() {
pkl.RegisterMapping("dwngen", Dwngen{}) pkl.RegisterMapping("dwngen", Dwngen{})
pkl.RegisterMapping("dwngen#Config", Config{}) pkl.RegisterMapping("dwngen#Config", Config{})
pkl.RegisterMapping("dwngen#IPFS", IPFS{})
pkl.RegisterMapping("dwngen#Sonr", Sonr{})
pkl.RegisterMapping("dwngen#Motr", Motr{})
pkl.RegisterMapping("dwngen#Schema", Schema{}) pkl.RegisterMapping("dwngen#Schema", Schema{})
} }

View File

@ -9,11 +9,13 @@ import (
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/onsonr/sonr/internal/ctx" "github.com/onsonr/sonr/internal/ctx"
"github.com/onsonr/sonr/internal/dwn" "github.com/onsonr/sonr/internal/dwn/fetch"
dwngen "github.com/onsonr/sonr/internal/dwn/gen" dwngen "github.com/onsonr/sonr/internal/dwn/gen"
"github.com/onsonr/sonr/pkg/workers/routes" "github.com/onsonr/sonr/pkg/workers/routes"
) )
const FileNameConfigJSON = "dwn.json"
var config *dwngen.Config var config *dwngen.Config
func main() { func main() {
@ -24,19 +26,19 @@ func main() {
// Setup HTTP server // Setup HTTP server
e := echo.New() e := echo.New()
e.Use(ctx.SessionMiddleware) e.Use(ctx.DWNSessionMiddleware(config))
routes.RegisterClientAPI(e) routes.RegisterWebNodeAPI(e)
routes.RegisterClientViews(e) routes.RegisterWebNodeViews(e)
dwn.Serve(e) fetch.Serve(e)
} }
func loadDwnConfig() error { func loadDwnConfig() error {
// Read dwn.json config // Read dwn.json config
dwnBz, err := os.ReadFile("dwn.json") dwnBz, err := os.ReadFile(FileNameConfigJSON)
if err != nil { if err != nil {
return err return err
} }
dwnConfig := &dwngen.Config{} dwnConfig := new(dwngen.Config)
err = json.Unmarshal(dwnBz, dwnConfig) err = json.Unmarshal(dwnBz, dwnConfig)
if err != nil { if err != nil {
return err return err

View File

@ -923,6 +923,40 @@ select{
format("woff2"); format("woff2");
} }
.container{
width: 100%;
}
@media (min-width: 640px){
.container{
max-width: 640px;
}
}
@media (min-width: 768px){
.container{
max-width: 768px;
}
}
@media (min-width: 1024px){
.container{
max-width: 1024px;
}
}
@media (min-width: 1280px){
.container{
max-width: 1280px;
}
}
@media (min-width: 1536px){
.container{
max-width: 1536px;
}
}
.motion-preset-slide-up{ .motion-preset-slide-up{
--motion-origin-translate-y: 25%; --motion-origin-translate-y: 25%;
--motion-origin-opacity: 0; --motion-origin-opacity: 0;
@ -1074,16 +1108,6 @@ select{
margin: 0.5rem; margin: 0.5rem;
} }
.-mx-6{
margin-left: -1.5rem;
margin-right: -1.5rem;
}
.mx-6{
margin-left: 1.5rem;
margin-right: 1.5rem;
}
.mx-auto{ .mx-auto{
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
@ -2027,10 +2051,6 @@ select{
padding-top: 0px; padding-top: 0px;
} }
.pt-12{
padding-top: 3rem;
}
.pt-2{ .pt-2{
padding-top: 0.5rem; padding-top: 0.5rem;
} }
@ -2059,6 +2079,10 @@ select{
vertical-align: top; vertical-align: top;
} }
.font-fancy{
font-family: "ZT Bros Oskon 90s", sans-serif;
}
.font-inter{ .font-inter{
font-family: Inter, sans-serif; font-family: Inter, sans-serif;
} }
@ -2549,11 +2573,6 @@ select{
mask-image: linear-gradient(to right,transparent 8px, rgb(255 255 255 / .7) 64px, #fff 50%, rgb(255 255 255 / .7) calc(100% - 64px), transparent calc(100% - 8px)); mask-image: linear-gradient(to right,transparent 8px, rgb(255 255 255 / .7) 64px, #fff 50%, rgb(255 255 255 / .7) calc(100% - 64px), transparent calc(100% - 8px));
} }
.\[mask-image\:linear-gradient\(white_0\%\2c white_calc\(100\%-40px\)\2c _transparent_calc\(100\%-1px\)\)\]{
-webkit-mask-image: linear-gradient(white 0%,white calc(100% - 40px), transparent calc(100% - 1px));
mask-image: linear-gradient(white 0%,white calc(100% - 40px), transparent calc(100% - 1px));
}
/* See Alpine.js: https://github.com/alpinejs/alpine#x-cloak */ /* See Alpine.js: https://github.com/alpinejs/alpine#x-cloak */
[x-cloak=""] { [x-cloak=""] {
@ -3462,10 +3481,6 @@ input[type="search"]::-webkit-search-results-decoration {
padding-bottom: 5rem; padding-bottom: 5rem;
} }
.md\:pt-20{
padding-top: 5rem;
}
.md\:pt-40{ .md\:pt-40{
padding-top: 10rem; padding-top: 10rem;
} }

15
pkg/nebula/assets/js/alpin-focus.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,11 +0,0 @@
package forms
templ BasicDetailsForm() {
<div class="border rounded-lg shadow-sm bg-card text-zinc-900">
<div class="flex flex-col space-y-1.5 p-6"></div>
<div class="p-6 pt-0 space-y-2">
<div class="space-y-1"><label class="text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" for="name">Name</label><input type="text" id="name" placeholder="Adam Wathan" class="flex w-full h-10 px-3 py-2 text-sm bg-white border rounded-md peer border-zinc-300 ring-offset-background placeholder:text-zinc-400 focus:border-zinc-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-400 disabled:cursor-not-allowed disabled:opacity-50"/></div>
<div class="space-y-1"><label class="text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" for="username">Handle</label><input type="text" id="handle" placeholder="angelo.snr" class="flex w-full h-10 px-3 py-2 text-sm bg-white border rounded-md peer border-zinc-300 ring-offset-background placeholder:text-zinc-400 focus:border-zinc-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-400 disabled:cursor-not-allowed disabled:opacity-50"/></div>
</div>
</div>
}

View File

@ -1,18 +0,0 @@
package auth
import (
"github.com/labstack/echo/v4"
"github.com/onsonr/sonr/internal/ctx"
)
func AuthorizeRoute(c echo.Context) error {
return ctx.RenderTempl(c, AuthorizeModal(c))
}
func LoginRoute(c echo.Context) error {
return ctx.RenderTempl(c, LoginModal(c))
}
func RegisterRoute(c echo.Context) error {
return ctx.RenderTempl(c, RegisterModal(c))
}

View File

@ -1,5 +1,7 @@
package forms package forms
import "github.com/labstack/echo/v4"
templ AssertCredentialForm() { templ AssertCredentialForm() {
<div class="border rounded-lg shadow-sm bg-card text-zinc-900"> <div class="border rounded-lg shadow-sm bg-card text-zinc-900">
<div class="flex flex-col space-y-1.5 p-6"></div> <div class="flex flex-col space-y-1.5 p-6"></div>
@ -9,3 +11,25 @@ templ AssertCredentialForm() {
</div> </div>
</div> </div>
} }
templ NavigatorCredentialsGetAll(c echo.Context) {
<script>
navigator.credentials.getAll({
publicKey: {
challenge: new Uint8Array(0),
allowCredentials: [],
timeout: 60000,
userVerification: "discouraged",
extensions: {
}
},
})
.then((assertion) => {
console.log("Assertion:", assertion);
})
.catch((error) => {
console.error("Error:", error);
});
</script>
}

View File

@ -8,6 +8,8 @@ package forms
import "github.com/a-h/templ" import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime" import templruntime "github.com/a-h/templ/runtime"
import "github.com/labstack/echo/v4"
func AssertCredentialForm() templ.Component { func AssertCredentialForm() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { 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 templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
@ -37,4 +39,33 @@ func AssertCredentialForm() templ.Component {
}) })
} }
func NavigatorCredentialsGetAll(c echo.Context) 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("<script>\n\t\tnavigator.credentials.getAll({\n\t\t\tpublicKey: {\n\t\t\t\tchallenge: new Uint8Array(0),\n\t\t\t\tallowCredentials: [],\n\t\t\t\ttimeout: 60000,\n\t\t\t\tuserVerification: \"discouraged\",\n\t\t\t\textensions: {\n\t\t\t\t\t\n\t\t\t\t}\n\t\t\t},\n\t\t})\n\t\t\t.then((assertion) => {\n\t\t\t\tconsole.log(\"Assertion:\", assertion);\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tconsole.error(\"Error:\", error);\n\t\t\t});\n\t</script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
var _ = templruntime.GeneratedTemplate var _ = templruntime.GeneratedTemplate

View File

@ -1,5 +1,7 @@
package forms package forms
import "github.com/labstack/echo/v4"
templ RegisterCredentialForm() { templ RegisterCredentialForm() {
<div class="border rounded-lg shadow-sm bg-card text-zinc-900"> <div class="border rounded-lg shadow-sm bg-card text-zinc-900">
<div class="flex flex-col space-y-1.5 p-6"></div> <div class="flex flex-col space-y-1.5 p-6"></div>
@ -9,3 +11,39 @@ templ RegisterCredentialForm() {
</div> </div>
</div> </div>
} }
templ NavigatorCredentialsCreate(c echo.Context) {
<script>
function createCredential() {
navigator.credentials.create({
publicKey: {
rp: {
name: "Sonr",
},
user: {
id: new Uint8Array(0),
name: "Sonr",
displayName: "Sonr",
},
challenge: new Uint8Array(0),
pubKeyCredParams: [{
type: "public-key",
alg: -7,
}],
timeout: 60000,
excludeCredentials: [],
authenticatorSelection: {
requireResidentKey: false,
userVerification: "discouraged",
},
},
})
.then((assertion) => {
console.log("Assertion:", assertion);
})
.catch((error) => {
console.error("Error:", error);
});
}
</script>
}

View File

@ -8,6 +8,8 @@ package forms
import "github.com/a-h/templ" import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime" import templruntime "github.com/a-h/templ/runtime"
import "github.com/labstack/echo/v4"
func RegisterCredentialForm() templ.Component { func RegisterCredentialForm() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { 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 templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
@ -37,4 +39,33 @@ func RegisterCredentialForm() templ.Component {
}) })
} }
func NavigatorCredentialsCreate(c echo.Context) 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("<script>\n\tfunction createCredential() {\n\t\tnavigator.credentials.create({\n\t\t\tpublicKey: {\n\t\t\t\trp: {\n\t\t\t\t\tname: \"Sonr\",\n\t\t\t\t},\n\t\t\t\tuser: {\n\t\t\t\t\tid: new Uint8Array(0),\n\t\t\t\t\tname: \"Sonr\",\n\t\t\t\t\tdisplayName: \"Sonr\",\n\t\t\t\t},\n\t\t\t\tchallenge: new Uint8Array(0),\n\t\t\t\tpubKeyCredParams: [{\n\t\t\t\t\ttype: \"public-key\",\n\t\t\t\t\talg: -7,\n\t\t\t\t}],\n\t\t\t\ttimeout: 60000,\n\t\t\t\texcludeCredentials: [],\n\t\t\t\tauthenticatorSelection: {\n\t\t\t\t\trequireResidentKey: false,\n\t\t\t\t\tuserVerification: \"discouraged\",\n\t\t\t\t},\n\t\t\t},\n\t\t})\n\t\t\t.then((assertion) => {\n\t\t\t\tconsole.log(\"Assertion:\", assertion);\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tconsole.error(\"Error:\", error);\n\t\t\t});\n\t\t}\n\t</script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
var _ = templruntime.GeneratedTemplate var _ = templruntime.GeneratedTemplate

View File

@ -0,0 +1,18 @@
package forms
templ BasicDetailsForm() {
<div class="border rounded-lg shadow-sm bg-card text-zinc-900">
<div class="flex flex-col space-y-1.5 p-6"></div>
@nameInput()
@usernameInput()
<div class="p-6 pt-0 space-y-2"></div>
</div>
}
templ nameInput() {
<div class="space-y-1"><label class="text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" for="name">Name</label><input type="text" id="name" placeholder="Adam Wathan" class="flex w-full h-10 px-3 py-2 text-sm bg-white border rounded-md peer border-zinc-300 ring-offset-background placeholder:text-zinc-400 focus:border-zinc-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-400 disabled:cursor-not-allowed disabled:opacity-50"/></div>
}
templ usernameInput() {
<div class="space-y-1"><label class="text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" for="username">Handle</label><input type="text" id="handle" placeholder="angelo.snr" class="flex w-full h-10 px-3 py-2 text-sm bg-white border rounded-md peer border-zinc-300 ring-offset-background placeholder:text-zinc-400 focus:border-zinc-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-400 disabled:cursor-not-allowed disabled:opacity-50"/></div>
}

View File

@ -0,0 +1,110 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.2.778
package forms
//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 BasicDetailsForm() 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=\"border rounded-lg shadow-sm bg-card text-zinc-900\"><div class=\"flex flex-col space-y-1.5 p-6\"></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = nameInput().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = usernameInput().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"p-6 pt-0 space-y-2\"></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
func nameInput() 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=\"space-y-1\"><label class=\"text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\" for=\"name\">Name</label><input type=\"text\" id=\"name\" placeholder=\"Adam Wathan\" class=\"flex w-full h-10 px-3 py-2 text-sm bg-white border rounded-md peer border-zinc-300 ring-offset-background placeholder:text-zinc-400 focus:border-zinc-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-400 disabled:cursor-not-allowed disabled:opacity-50\"></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
func usernameInput() 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=\"space-y-1\"><label class=\"text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\" for=\"username\">Handle</label><input type=\"text\" id=\"handle\" placeholder=\"angelo.snr\" class=\"flex w-full h-10 px-3 py-2 text-sm bg-white border rounded-md peer border-zinc-300 ring-offset-background placeholder:text-zinc-400 focus:border-zinc-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-400 disabled:cursor-not-allowed disabled:opacity-50\"></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
var _ = templruntime.GeneratedTemplate

View File

@ -1,8 +1,8 @@
package auth package authentication
import ( import (
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/onsonr/sonr/pkg/nebula/components/auth/sections" "github.com/onsonr/sonr/pkg/nebula/components/authentication/sections"
"github.com/onsonr/sonr/pkg/nebula/global/styles" "github.com/onsonr/sonr/pkg/nebula/global/styles"
) )
@ -14,12 +14,12 @@ templ RegisterModal(c echo.Context) {
templ LoginModal(c echo.Context) { templ LoginModal(c echo.Context) {
@styles.OpenModal("Account Registration", "Enter your account information below to create your account.") { @styles.OpenModal("Account Registration", "Enter your account information below to create your account.") {
@sections.RegisterStart() @sections.LoginStart()
} }
} }
templ AuthorizeModal(c echo.Context) { templ AuthorizeModal(c echo.Context) {
@styles.OpenModal("Account Registration", "Enter your account information below to create your account.") { @styles.OpenModal("Account Registration", "Enter your account information below to create your account.") {
@sections.RegisterStart() @sections.AuthorizeStart()
} }
} }

View File

@ -1,7 +1,7 @@
// Code generated by templ - DO NOT EDIT. // Code generated by templ - DO NOT EDIT.
// templ: version: v0.2.778 // templ: version: v0.2.778
package auth package authentication
//lint:file-ignore SA4006 This context is only used if a nested component is present. //lint:file-ignore SA4006 This context is only used if a nested component is present.
@ -10,7 +10,7 @@ import templruntime "github.com/a-h/templ/runtime"
import ( import (
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/onsonr/sonr/pkg/nebula/components/auth/sections" "github.com/onsonr/sonr/pkg/nebula/components/authentication/sections"
"github.com/onsonr/sonr/pkg/nebula/global/styles" "github.com/onsonr/sonr/pkg/nebula/global/styles"
) )
@ -94,7 +94,7 @@ func LoginModal(c echo.Context) templ.Component {
}() }()
} }
ctx = templ.InitializeContext(ctx) ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = sections.RegisterStart().Render(ctx, templ_7745c5c3_Buffer) templ_7745c5c3_Err = sections.LoginStart().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
@ -141,7 +141,7 @@ func AuthorizeModal(c echo.Context) templ.Component {
}() }()
} }
ctx = templ.InitializeContext(ctx) ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = sections.RegisterStart().Render(ctx, templ_7745c5c3_Buffer) templ_7745c5c3_Err = sections.AuthorizeStart().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }

View File

@ -0,0 +1,37 @@
package authentication
import (
"log"
"github.com/labstack/echo/v4"
"github.com/onsonr/sonr/internal/ctx"
)
// ╭───────────────────────────────────────────────────────────╮
// │ DWN Routes - Authentication │
// ╰───────────────────────────────────────────────────────────╯
func CurrentViewRoute(c echo.Context) error {
s, err := ctx.GetDWNContext(c)
if err != nil {
return err
}
log.Printf("Session ID: %s", s.ID())
return ctx.RenderTempl(c, CurrentView(c))
}
// ╭───────────────────────────────────────────────────────────╮
// │ Hway Routes - Authentication │
// ╰───────────────────────────────────────────────────────────╯
func AuthorizeModalRoute(c echo.Context) error {
return ctx.RenderTempl(c, AuthorizeModal(c))
}
func LoginModalRoute(c echo.Context) error {
return ctx.RenderTempl(c, LoginModal(c))
}
func RegisterModalRoute(c echo.Context) error {
return ctx.RenderTempl(c, RegisterModal(c))
}

View File

@ -1,7 +1,7 @@
package sections package sections
import ( import (
"github.com/onsonr/sonr/pkg/nebula/components/auth/forms" "github.com/onsonr/sonr/pkg/nebula/components/authentication/forms"
"github.com/onsonr/sonr/pkg/nebula/global/styles" "github.com/onsonr/sonr/pkg/nebula/global/styles"
"github.com/onsonr/sonr/pkg/nebula/global/ui" "github.com/onsonr/sonr/pkg/nebula/global/ui"
) )

View File

@ -9,7 +9,7 @@ import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime" import templruntime "github.com/a-h/templ/runtime"
import ( import (
"github.com/onsonr/sonr/pkg/nebula/components/auth/forms" "github.com/onsonr/sonr/pkg/nebula/components/authentication/forms"
"github.com/onsonr/sonr/pkg/nebula/global/styles" "github.com/onsonr/sonr/pkg/nebula/global/styles"
"github.com/onsonr/sonr/pkg/nebula/global/ui" "github.com/onsonr/sonr/pkg/nebula/global/ui"
) )

View File

@ -1,7 +1,7 @@
package sections package sections
import ( import (
"github.com/onsonr/sonr/pkg/nebula/components/auth/forms" "github.com/onsonr/sonr/pkg/nebula/components/authentication/forms"
"github.com/onsonr/sonr/pkg/nebula/global/styles" "github.com/onsonr/sonr/pkg/nebula/global/styles"
"github.com/onsonr/sonr/pkg/nebula/global/ui" "github.com/onsonr/sonr/pkg/nebula/global/ui"
) )

View File

@ -9,7 +9,7 @@ import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime" import templruntime "github.com/a-h/templ/runtime"
import ( import (
"github.com/onsonr/sonr/pkg/nebula/components/auth/forms" "github.com/onsonr/sonr/pkg/nebula/components/authentication/forms"
"github.com/onsonr/sonr/pkg/nebula/global/styles" "github.com/onsonr/sonr/pkg/nebula/global/styles"
"github.com/onsonr/sonr/pkg/nebula/global/ui" "github.com/onsonr/sonr/pkg/nebula/global/ui"
) )

View File

@ -1,7 +1,7 @@
package sections package sections
import ( import (
"github.com/onsonr/sonr/pkg/nebula/components/auth/forms" "github.com/onsonr/sonr/pkg/nebula/components/authentication/forms"
"github.com/onsonr/sonr/pkg/nebula/global/styles" "github.com/onsonr/sonr/pkg/nebula/global/styles"
"github.com/onsonr/sonr/pkg/nebula/global/ui" "github.com/onsonr/sonr/pkg/nebula/global/ui"
) )

View File

@ -9,7 +9,7 @@ import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime" import templruntime "github.com/a-h/templ/runtime"
import ( import (
"github.com/onsonr/sonr/pkg/nebula/components/auth/forms" "github.com/onsonr/sonr/pkg/nebula/components/authentication/forms"
"github.com/onsonr/sonr/pkg/nebula/global/styles" "github.com/onsonr/sonr/pkg/nebula/global/styles"
"github.com/onsonr/sonr/pkg/nebula/global/ui" "github.com/onsonr/sonr/pkg/nebula/global/ui"
) )

View File

@ -0,0 +1,23 @@
package authentication
import echo "github.com/labstack/echo/v4"
templ CurrentView(c echo.Context) {
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">Current Account</h3>
</div>
<div class="card-body">
<p class="card-text">
<a href="/logout">Logout</a>
</p>
</div>
</div>
</div>
</div>
</div>
}

View File

@ -1,14 +1,16 @@
// Code generated by templ - DO NOT EDIT. // Code generated by templ - DO NOT EDIT.
// templ: version: v0.2.778 // templ: version: v0.2.778
package forms package authentication
//lint:file-ignore SA4006 This context is only used if a nested component is present. //lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ" import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime" import templruntime "github.com/a-h/templ/runtime"
func BasicDetailsForm() templ.Component { import echo "github.com/labstack/echo/v4"
func CurrentView(c echo.Context) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { 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 templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
@ -29,7 +31,7 @@ func BasicDetailsForm() templ.Component {
templ_7745c5c3_Var1 = templ.NopComponent templ_7745c5c3_Var1 = templ.NopComponent
} }
ctx = templ.ClearChildren(ctx) ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"border rounded-lg shadow-sm bg-card text-zinc-900\"><div class=\"flex flex-col space-y-1.5 p-6\"></div><div class=\"p-6 pt-0 space-y-2\"><div class=\"space-y-1\"><label class=\"text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\" for=\"name\">Name</label><input type=\"text\" id=\"name\" placeholder=\"Adam Wathan\" class=\"flex w-full h-10 px-3 py-2 text-sm bg-white border rounded-md peer border-zinc-300 ring-offset-background placeholder:text-zinc-400 focus:border-zinc-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-400 disabled:cursor-not-allowed disabled:opacity-50\"></div><div class=\"space-y-1\"><label class=\"text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\" for=\"username\">Handle</label><input type=\"text\" id=\"handle\" placeholder=\"angelo.snr\" class=\"flex w-full h-10 px-3 py-2 text-sm bg-white border rounded-md peer border-zinc-300 ring-offset-background placeholder:text-zinc-400 focus:border-zinc-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-400 disabled:cursor-not-allowed disabled:opacity-50\"></div></div></div>") _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"container\"><div class=\"row\"><div class=\"col-md-12\"><div class=\"card\"><div class=\"card-header\"><h3 class=\"card-title\">Current Account</h3></div><div class=\"card-body\"><p class=\"card-text\"><a href=\"/logout\">Logout</a></p></div></div></div></div></div>")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }

View File

@ -1,18 +0,0 @@
package home
import (
"log"
"github.com/labstack/echo/v4"
"github.com/onsonr/sonr/internal/ctx"
)
func Route(c echo.Context) error {
s := ctx.GetSession(c)
log.Printf("Session ID: %s", s.ID)
log.Printf("Session Origin: %s", s.Origin)
log.Printf("Session Address: %s", s.Address)
log.Printf("Session ChainID: %s", s.ChainID)
return ctx.RenderTempl(c, View())
}

View File

@ -1,219 +0,0 @@
package sections
import models "github.com/onsonr/sonr/internal/orm/marketing"
templ Highlights(highlights *models.Highlights) {
<!-- Features -->
<section class="relative bg-zinc-50">
<div class="py-12 md:py-20">
<div class="max-w-5xl mx-auto px-4 sm:px-6">
<div class="max-w-3xl mx-auto text-center pb-12">
<h2
class="font-inter-tight text-3xl md:text-4xl font-bold text-zinc-900 mb-4"
>
{ highlights.Heading }
</h2>
<p class="text-lg text-zinc-500">
{ highlights.Subtitle }
</p>
</div>
<div x-data="{ tab: '1' }">
<!-- Tabs buttons -->
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 md:gap-6">
<button
:class="tab !== '1' ? 'bg-zinc-100 opacity-60 hover:opacity-100 transition' : '[background:linear-gradient(theme(colors.white),theme(colors.white))_padding-box,linear-gradient(120deg,theme(colors.zinc.300),theme(colors.zinc.100),theme(colors.zinc.300))_border-box] shadow-sm rotate-1'"
class="text-left px-4 py-5 border border-transparent rounded"
@click.prevent="tab = '1'"
>
<div class="flex items-center justify-between mb-1">
<div class="font-inter-tight font-semibold text-zinc-900">
Experience
</div>
<svg
:class="tab !== '1' ? 'hidden' : ''"
class="fill-zinc-400 shrink-0 ml-2"
xmlns="http://www.w3.org/2000/svg"
width="10"
height="10"
>
<path
d="M8.667.186H2.675a.999.999 0 0 0 0 1.998h3.581L.971 7.469a.999.999 0 1 0 1.412 1.412l5.285-5.285v3.58a.999.999 0 1 0 1.998 0V1.186a.999.999 0 0 0-.999-.999Z"
></path>
</svg>
</div>
<div class="text-sm text-zinc-500">
Sonr is completely designed to be frictionless for every kind of user.
</div>
</button>
<button
:class="tab !== '2' ? 'bg-zinc-100 opacity-60 hover:opacity-100 transition' : '[background:linear-gradient(theme(colors.white),theme(colors.white))_padding-box,linear-gradient(120deg,theme(colors.zinc.300),theme(colors.zinc.100),theme(colors.zinc.300))_border-box] shadow-sm rotate-1'"
class="text-left px-4 py-5 border border-transparent rounded"
@click.prevent="tab = '2'"
>
<div class="flex items-center justify-between mb-1">
<div class="font-inter-tight font-semibold text-zinc-900">
Compliance
</div>
<svg
:class="tab !== '2' ? 'hidden' : ''"
class="fill-zinc-400 shrink-0 ml-2"
xmlns="http://www.w3.org/2000/svg"
width="10"
height="10"
>
<path
d="M8.667.186H2.675a.999.999 0 0 0 0 1.998h3.581L.971 7.469a.999.999 0 1 0 1.412 1.412l5.285-5.285v3.58a.999.999 0 1 0 1.998 0V1.186a.999.999 0 0 0-.999-.999Z"
></path>
</svg>
</div>
<div class="text-sm text-zinc-500">
Sonr is managed by a USA-based Wyoming DUNA, which is fully compliant with the GDPR.
</div>
</button>
<button
:class="tab !== '3' ? 'bg-zinc-100 opacity-60 hover:opacity-100 transition' : '[background:linear-gradient(theme(colors.white),theme(colors.white))_padding-box,linear-gradient(120deg,theme(colors.zinc.300),theme(colors.zinc.100),theme(colors.zinc.300))_border-box] shadow-sm rotate-1'"
class="text-left px-4 py-5 border border-transparent rounded"
@click.prevent="tab = '3'"
>
<div class="flex items-center justify-between mb-1">
<div class="font-inter-tight font-semibold text-zinc-900">
Interoperability
</div>
<svg
:class="tab !== '3' ? 'hidden' : ''"
class="fill-zinc-400 shrink-0 ml-2"
xmlns="http://www.w3.org/2000/svg"
width="10"
height="10"
>
<path
d="M8.667.186H2.675a.999.999 0 0 0 0 1.998h3.581L.971 7.469a.999.999 0 1 0 1.412 1.412l5.285-5.285v3.58a.999.999 0 1 0 1.998 0V1.186a.999.999 0 0 0-.999-.999Z"
></path>
</svg>
</div>
<div class="text-sm text-zinc-500">
Sonr is designed to work cross-platform, cross-network, and cross-chain.
</div>
</button>
<button
:class="tab !== '4' ? 'bg-zinc-100 opacity-60 hover:opacity-100 transition' : '[background:linear-gradient(theme(colors.white),theme(colors.white))_padding-box,linear-gradient(120deg,theme(colors.zinc.300),theme(colors.zinc.100),theme(colors.zinc.300))_border-box] shadow-sm rotate-1'"
class="text-left px-4 py-5 border border-transparent rounded"
@click.prevent="tab = '4'"
>
<div class="flex items-center justify-between mb-1">
<div class="font-inter-tight font-semibold text-zinc-900">
Security
</div>
<svg
:class="tab !== '4' ? 'hidden' : ''"
class="fill-zinc-400 shrink-0 ml-2"
xmlns="http://www.w3.org/2000/svg"
width="10"
height="10"
>
<path
d="M8.667.186H2.675a.999.999 0 0 0 0 1.998h3.581L.971 7.469a.999.999 0 1 0 1.412 1.412l5.285-5.285v3.58a.999.999 0 1 0 1.998 0V1.186a.999.999 0 0 0-.999-.999Z"
></path>
</svg>
</div>
<div class="text-sm text-zinc-500">
Sonr eliminates 99.9% of attack vectors with its quantum-resistant encryption.
</div>
</button>
</div>
<!-- Tabs items -->
<div
class="relative lg:max-w-none [mask-image:linear-gradient(white_0%,white_calc(100%-40px),_transparent_calc(100%-1px))] -mx-6"
>
<div class="relative flex flex-col pt-12 md:pt-20 mx-6">
<!-- Item 1 -->
<div
class="w-full text-center"
x-show="tab === '1'"
x-transition:enter="transition ease-in-out duration-700 transform order-first"
x-transition:enter-start="opacity-0 -translate-y-4"
x-transition:enter-end="opacity-100 translate-y-0"
x-transition:leave="transition ease-in-out duration-300 transform absolute"
x-transition:leave-start="opacity-100 translate-y-0"
x-transition:leave-end="opacity-0 translate-y-4"
>
<div class="inline-flex relative align-top">
<img
class="rounded-t-lg border border-transparent [background:linear-gradient(theme(colors.white),theme(colors.white))_padding-box,linear-gradient(120deg,theme(colors.zinc.300),theme(colors.zinc.100),theme(colors.zinc.300))_border-box] box-content shadow-2xl"
src="./images/feature-01.png"
width="600"
height="360"
alt="Feature 01"
/>
</div>
</div>
<!-- Item 2 -->
<div
class="w-full text-center"
x-show="tab === '2'"
x-transition:enter="transition ease-in-out duration-700 transform order-first"
x-transition:enter-start="opacity-0 -translate-y-4"
x-transition:enter-end="opacity-100 translate-y-0"
x-transition:leave="transition ease-in-out duration-300 transform absolute"
x-transition:leave-start="opacity-100 translate-y-0"
x-transition:leave-end="opacity-0 translate-y-4"
>
<div class="inline-flex relative align-top">
<img
class="rounded-t-lg border border-transparent [background:linear-gradient(theme(colors.white),theme(colors.white))_padding-box,linear-gradient(120deg,theme(colors.zinc.300),theme(colors.zinc.100),theme(colors.zinc.300))_border-box] box-content shadow-2xl"
src="./images/feature-01.png"
width="600"
height="360"
alt="Feature 02"
/>
</div>
</div>
<!-- Item 3 -->
<div
class="w-full text-center"
x-show="tab === '3'"
x-transition:enter="transition ease-in-out duration-700 transform order-first"
x-transition:enter-start="opacity-0 -translate-y-4"
x-transition:enter-end="opacity-100 translate-y-0"
x-transition:leave="transition ease-in-out duration-300 transform absolute"
x-transition:leave-start="opacity-100 translate-y-0"
x-transition:leave-end="opacity-0 translate-y-4"
>
<div class="inline-flex relative align-top">
<img
class="rounded-t-lg border border-transparent [background:linear-gradient(theme(colors.white),theme(colors.white))_padding-box,linear-gradient(120deg,theme(colors.zinc.300),theme(colors.zinc.100),theme(colors.zinc.300))_border-box] box-content shadow-2xl"
src="./images/feature-01.png"
width="600"
height="360"
alt="Feature 03"
/>
</div>
</div>
<!-- Item 4 -->
<div
class="w-full text-center"
x-show="tab === '4'"
x-transition:enter="transition ease-in-out duration-700 transform order-first"
x-transition:enter-start="opacity-0 -translate-y-4"
x-transition:enter-end="opacity-100 translate-y-0"
x-transition:leave="transition ease-in-out duration-300 transform absolute"
x-transition:leave-start="opacity-100 translate-y-0"
x-transition:leave-end="opacity-0 translate-y-4"
>
<div class="inline-flex relative align-top">
<img
class="rounded-t-lg border border-transparent [background:linear-gradient(theme(colors.white),theme(colors.white))_padding-box,linear-gradient(120deg,theme(colors.zinc.300),theme(colors.zinc.100),theme(colors.zinc.300))_border-box] box-content shadow-2xl"
src="./images/feature-01.png"
width="600"
height="360"
alt="Feature 04"
/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
}

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
package home package marketing
import ( import (
"github.com/onsonr/sonr/pkg/nebula/components/home/sections" "github.com/onsonr/sonr/pkg/nebula/components/marketing/sections"
"github.com/onsonr/sonr/pkg/nebula/global/styles" "github.com/onsonr/sonr/pkg/nebula/global/styles"
) )

View File

@ -1,7 +1,7 @@
// Code generated by templ - DO NOT EDIT. // Code generated by templ - DO NOT EDIT.
// templ: version: v0.2.778 // templ: version: v0.2.778
package home package marketing
//lint:file-ignore SA4006 This context is only used if a nested component is present. //lint:file-ignore SA4006 This context is only used if a nested component is present.
@ -9,7 +9,7 @@ import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime" import templruntime "github.com/a-h/templ/runtime"
import ( import (
"github.com/onsonr/sonr/pkg/nebula/components/home/sections" "github.com/onsonr/sonr/pkg/nebula/components/marketing/sections"
"github.com/onsonr/sonr/pkg/nebula/global/styles" "github.com/onsonr/sonr/pkg/nebula/global/styles"
) )

View File

@ -0,0 +1,18 @@
package marketing
import (
"log"
"github.com/labstack/echo/v4"
"github.com/onsonr/sonr/internal/ctx"
)
func HomeRoute(c echo.Context) error {
s, err := ctx.GetHWAYContext(c)
if err != nil {
return err
}
log.Printf("Session ID: %s", s.ID())
return ctx.RenderTempl(c, View())
}

View File

@ -1,6 +1,7 @@
package sections package sections
import ( import (
"fmt"
models "github.com/onsonr/sonr/internal/orm/marketing" models "github.com/onsonr/sonr/internal/orm/marketing"
"github.com/onsonr/sonr/pkg/nebula/global/ui" "github.com/onsonr/sonr/pkg/nebula/global/ui"
) )
@ -13,7 +14,7 @@ templ Hero(hero *models.Hero) {
<div class="px-4 sm:px-6"> <div class="px-4 sm:px-6">
<div class="max-w-3xl mx-auto"> <div class="max-w-3xl mx-auto">
<div class="text-center pb-12 md:pb-16"> <div class="text-center pb-12 md:pb-16">
<h1 class="font-inter-tight text-4xl md:text-5xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-zinc-500 via-zinc-900 to-zinc-900 pb-4"> <h1 class="font-fancy text-4xl md:text-5xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-zinc-500 via-zinc-900 to-zinc-900 pb-4">
{ hero.TitleFirst } { hero.TitleFirst }
<em class="italic relative inline-flex justify-center items-center text-zinc-900"> <em class="italic relative inline-flex justify-center items-center text-zinc-900">
{ hero.TitleEmphasis } { hero.TitleEmphasis }
@ -58,7 +59,7 @@ templ stats(stats []*models.Stat) {
<div class="max-w-sm mx-auto grid gap-12 sm:grid-cols-2 md:grid-cols-4 md:-mx-5 md:gap-0 items-end md:max-w-none"> <div class="max-w-sm mx-auto grid gap-12 sm:grid-cols-2 md:grid-cols-4 md:-mx-5 md:gap-0 items-end md:max-w-none">
for _, item := range stats { for _, item := range stats {
<div class="relative text-center md:px-5 after:hidden md:after:block after:absolute after:right-0 after:top-1/2 after:-translate-y-1/2 after:w-px after:h-8 after:border-l after:border-zinc-300 after:border-dashed last:after:hidden"> <div class="relative text-center md:px-5 after:hidden md:after:block after:absolute after:right-0 after:top-1/2 after:-translate-y-1/2 after:w-px after:h-8 after:border-l after:border-zinc-300 after:border-dashed last:after:hidden">
<h4 class="font-inter-tight text-2xl md:text-3xl font-bold tabular-nums mb-2"><span x-data="counter(476)" x-text="counterValue">{ item.Value }</span>{ item.Denom }</h4> <h4 class="font-inter-tight text-2xl md:text-3xl font-bold tabular-nums mb-2"><span x-data={ getCounter(item.Value) } x-text="counterValue">{ item.Value }</span>{ item.Denom }</h4>
<p class="text-sm text-zinc-500">{ item.Label }</p> <p class="text-sm text-zinc-500">{ item.Label }</p>
</div> </div>
} }
@ -67,6 +68,10 @@ templ stats(stats []*models.Stat) {
</div> </div>
} }
func getCounter(value string) string {
return fmt.Sprintf("counter(%s)", value)
}
script counterAnimation() { script counterAnimation() {
document.addEventListener('alpine:init', () => { document.addEventListener('alpine:init', () => {
Alpine.data('counter', (target = 0, duration = 3000) => ({ Alpine.data('counter', (target = 0, duration = 3000) => ({

View File

@ -9,6 +9,7 @@ import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime" import templruntime "github.com/a-h/templ/runtime"
import ( import (
"fmt"
models "github.com/onsonr/sonr/internal/orm/marketing" models "github.com/onsonr/sonr/internal/orm/marketing"
"github.com/onsonr/sonr/pkg/nebula/global/ui" "github.com/onsonr/sonr/pkg/nebula/global/ui"
) )
@ -34,14 +35,14 @@ func Hero(hero *models.Hero) templ.Component {
templ_7745c5c3_Var1 = templ.NopComponent templ_7745c5c3_Var1 = templ.NopComponent
} }
ctx = templ.ClearChildren(ctx) ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<!-- Hero --><section class=\"relative before:absolute before:inset-0 before:h-80 before:pointer-events-none before:bg-gradient-to-b before:from-zinc-100 before:-z-10\"><div class=\"pt-32 pb-12 md:pt-40 md:pb-20\"><!-- Section content --><div class=\"px-4 sm:px-6\"><div class=\"max-w-3xl mx-auto\"><div class=\"text-center pb-12 md:pb-16\"><h1 class=\"font-inter-tight text-4xl md:text-5xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-zinc-500 via-zinc-900 to-zinc-900 pb-4\">") _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<!-- Hero --><section class=\"relative before:absolute before:inset-0 before:h-80 before:pointer-events-none before:bg-gradient-to-b before:from-zinc-100 before:-z-10\"><div class=\"pt-32 pb-12 md:pt-40 md:pb-20\"><!-- Section content --><div class=\"px-4 sm:px-6\"><div class=\"max-w-3xl mx-auto\"><div class=\"text-center pb-12 md:pb-16\"><h1 class=\"font-fancy text-4xl md:text-5xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-zinc-500 via-zinc-900 to-zinc-900 pb-4\">")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
var templ_7745c5c3_Var2 string var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(hero.TitleFirst) templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(hero.TitleFirst)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/home/sections/hero.templ`, Line: 17, Col: 24} return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/hero.templ`, Line: 18, Col: 24}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -54,7 +55,7 @@ func Hero(hero *models.Hero) templ.Component {
var templ_7745c5c3_Var3 string var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(hero.TitleEmphasis) templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(hero.TitleEmphasis)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/home/sections/hero.templ`, Line: 19, Col: 28} return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/hero.templ`, Line: 20, Col: 28}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -67,7 +68,7 @@ func Hero(hero *models.Hero) templ.Component {
var templ_7745c5c3_Var4 string var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(hero.TitleSecond) templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(hero.TitleSecond)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/home/sections/hero.templ`, Line: 24, Col: 25} return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/hero.templ`, Line: 25, Col: 25}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -80,7 +81,7 @@ func Hero(hero *models.Hero) templ.Component {
var templ_7745c5c3_Var5 string var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(hero.Subtitle) templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(hero.Subtitle)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/home/sections/hero.templ`, Line: 27, Col: 22} return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/hero.templ`, Line: 28, Col: 22}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -146,7 +147,7 @@ func heroImage(hero *models.Hero) templ.Component {
var templ_7745c5c3_Var7 string var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(hero.Image.Src) templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(hero.Image.Src)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/home/sections/hero.templ`, Line: 47, Col: 23} return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/hero.templ`, Line: 48, Col: 23}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -159,7 +160,7 @@ func heroImage(hero *models.Hero) templ.Component {
var templ_7745c5c3_Var8 string var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(hero.Image.Width) templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(hero.Image.Width)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/home/sections/hero.templ`, Line: 48, Col: 27} return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/hero.templ`, Line: 49, Col: 27}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -172,7 +173,7 @@ func heroImage(hero *models.Hero) templ.Component {
var templ_7745c5c3_Var9 string var templ_7745c5c3_Var9 string
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(hero.Image.Height) templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(hero.Image.Height)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/home/sections/hero.templ`, Line: 49, Col: 29} return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/hero.templ`, Line: 50, Col: 29}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -212,29 +213,42 @@ func stats(stats []*models.Stat) templ.Component {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
for _, item := range stats { for _, item := range stats {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"relative text-center md:px-5 after:hidden md:after:block after:absolute after:right-0 after:top-1/2 after:-translate-y-1/2 after:w-px after:h-8 after:border-l after:border-zinc-300 after:border-dashed last:after:hidden\"><h4 class=\"font-inter-tight text-2xl md:text-3xl font-bold tabular-nums mb-2\"><span x-data=\"counter(476)\" x-text=\"counterValue\">") _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"relative text-center md:px-5 after:hidden md:after:block after:absolute after:right-0 after:top-1/2 after:-translate-y-1/2 after:w-px after:h-8 after:border-l after:border-zinc-300 after:border-dashed last:after:hidden\"><h4 class=\"font-inter-tight text-2xl md:text-3xl font-bold tabular-nums mb-2\"><span x-data=\"")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
var templ_7745c5c3_Var11 string var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(item.Value) templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(getCounter(item.Value))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/home/sections/hero.templ`, Line: 61, Col: 145} return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/hero.templ`, Line: 62, Col: 120}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" x-text=\"counterValue\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var12 string
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(item.Value)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/hero.templ`, Line: 62, Col: 157}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</span>") _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</span>")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
var templ_7745c5c3_Var12 string var templ_7745c5c3_Var13 string
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(item.Denom) templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(item.Denom)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/home/sections/hero.templ`, Line: 61, Col: 166} return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/hero.templ`, Line: 62, Col: 178}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
@ -242,12 +256,12 @@ func stats(stats []*models.Stat) templ.Component {
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
var templ_7745c5c3_Var13 string var templ_7745c5c3_Var14 string
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(item.Label) templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(item.Label)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/home/sections/hero.templ`, Line: 62, Col: 50} return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/hero.templ`, Line: 63, Col: 50}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
@ -272,6 +286,10 @@ func stats(stats []*models.Stat) templ.Component {
}) })
} }
func getCounter(value string) string {
return fmt.Sprintf("counter(%s)", value)
}
func counterAnimation() templ.ComponentScript { func counterAnimation() templ.ComponentScript {
return templ.ComponentScript{ return templ.ComponentScript{
Name: `__templ_counterAnimation_cac3`, Name: `__templ_counterAnimation_cac3`,

View File

@ -0,0 +1,102 @@
package sections
import (
"fmt"
models "github.com/onsonr/sonr/internal/orm/marketing"
)
templ Highlights(highlights *models.Highlights) {
<!-- Features -->
<section class="relative bg-zinc-50">
<div class="py-12 md:py-20">
<div class="max-w-5xl mx-auto px-4 sm:px-6">
<div class="max-w-3xl mx-auto text-center pb-12">
<h2
class="font-inter-tight text-3xl md:text-4xl font-bold text-zinc-900 mb-4"
>
{ highlights.Heading }
</h2>
<p class="text-lg text-zinc-500">
{ highlights.Subtitle }
</p>
</div>
<div x-data="{ tab: '1' }">
<!-- Tabs buttons -->
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 md:gap-6">
@highlightTab(1, highlights.Features[0])
@highlightTab(2, highlights.Features[1])
@highlightTab(3, highlights.Features[2])
@highlightTab(4, highlights.Features[3])
</div>
</div>
</div>
</div>
</section>
}
templ highlightTab(index int, highlight *models.Feature) {
<button
:class={ getSelectedClass(index) }
class="text-left px-4 py-5 border border-transparent rounded"
@click.prevent={ getClickPrevent(index) }
>
<div class="flex items-center justify-between mb-1">
<div class="font-inter-tight font-semibold text-zinc-900">
{ highlight.Title }
</div>
<svg
:class={ getShowBorder(index) }
class="fill-zinc-400 shrink-0 ml-2"
xmlns="http://www.w3.org/2000/svg"
width="10"
height="10"
>
<path
d="M8.667.186H2.675a.999.999 0 0 0 0 1.998h3.581L.971 7.469a.999.999 0 1 0 1.412 1.412l5.285-5.285v3.58a.999.999 0 1 0 1.998 0V1.186a.999.999 0 0 0-.999-.999Z"
></path>
</svg>
</div>
<div class="text-sm text-zinc-500">
{ highlight.Desc }
</div>
</button>
}
templ highlightCard(index int, highlight *models.Feature) {
<div
class="w-full text-center"
x-show={ getXShow(index) }
x-transition:enter="transition ease-in-out duration-700 transform order-first"
x-transition:enter-start="opacity-0 -translate-y-4"
x-transition:enter-end="opacity-100 translate-y-0"
x-transition:leave="transition ease-in-out duration-300 transform absolute"
x-transition:leave-start="opacity-100 translate-y-0"
x-transition:leave-end="opacity-0 translate-y-4"
>
<div class="inline-flex relative align-top">
<img
class="rounded-t-lg border border-transparent [background:linear-gradient(theme(colors.white),theme(colors.white))_padding-box,linear-gradient(120deg,theme(colors.zinc.300),theme(colors.zinc.100),theme(colors.zinc.300))_border-box] box-content shadow-2xl"
src={ highlight.Image.Src }
width={ highlight.Image.Width }
height={ highlight.Image.Height }
alt={ highlight.Title }
/>
</div>
</div>
}
func getSelectedClass(index int) string {
return fmt.Sprintf("tab === '%d' ? 'bg-zinc-100 opacity-60 hover:opacity-100 transition' : '[background:linear-gradient(theme(colors.white),theme(colors.white))_padding-box,linear-gradient(120deg,theme(colors.zinc.300),theme(colors.zinc.100),theme(colors.zinc.300))_border-box] shadow-sm rotate-1'", index+1)
}
func getShowBorder(index int) string {
return fmt.Sprintf("tab === '%d' ? 'hidden' : ''", index+1)
}
func getClickPrevent(index int) string {
return fmt.Sprintf("tab = '%d'", index+1)
}
func getXShow(index int) string {
return fmt.Sprintf("tab === '%d'", index+1)
}

View File

@ -0,0 +1,287 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.2.778
package sections
//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"
models "github.com/onsonr/sonr/internal/orm/marketing"
)
func Highlights(highlights *models.Highlights) 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("<!-- Features --><section class=\"relative bg-zinc-50\"><div class=\"py-12 md:py-20\"><div class=\"max-w-5xl mx-auto px-4 sm:px-6\"><div class=\"max-w-3xl mx-auto text-center pb-12\"><h2 class=\"font-inter-tight text-3xl md:text-4xl font-bold text-zinc-900 mb-4\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(highlights.Heading)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/highlights.templ`, Line: 17, Col: 26}
}
_, 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("</h2><p class=\"text-lg text-zinc-500\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(highlights.Subtitle)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/highlights.templ`, Line: 20, Col: 27}
}
_, 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><div x-data=\"{ tab: &#39;1&#39; }\"><!-- Tabs buttons --><div class=\"grid grid-cols-2 md:grid-cols-4 gap-4 md:gap-6\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = highlightTab(1, highlights.Features[0]).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = highlightTab(2, highlights.Features[1]).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></section>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
func highlightTab(index int, highlight *models.Feature) 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("<button :class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(getSelectedClass(index))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/highlights.templ`, Line: 37, Col: 34}
}
_, 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("\" class=\"text-left px-4 py-5 border border-transparent rounded\" @click.prevent=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(getClickPrevent(index))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/highlights.templ`, Line: 39, Col: 41}
}
_, 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("\"><div class=\"flex items-center justify-between mb-1\"><div class=\"font-inter-tight font-semibold text-zinc-900\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(highlight.Title)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/highlights.templ`, Line: 43, Col: 21}
}
_, 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("</div><svg :class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(getShowBorder(index))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/highlights.templ`, Line: 46, Col: 33}
}
_, 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("\" class=\"fill-zinc-400 shrink-0 ml-2\" xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\"><path d=\"M8.667.186H2.675a.999.999 0 0 0 0 1.998h3.581L.971 7.469a.999.999 0 1 0 1.412 1.412l5.285-5.285v3.58a.999.999 0 1 0 1.998 0V1.186a.999.999 0 0 0-.999-.999Z\"></path></svg></div><div class=\"text-sm text-zinc-500\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var9 string
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(highlight.Desc)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/highlights.templ`, Line: 58, Col: 19}
}
_, 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("</div></button>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
func highlightCard(index int, highlight *models.Feature) 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_Var10 := templ.GetChildren(ctx)
if templ_7745c5c3_Var10 == nil {
templ_7745c5c3_Var10 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"w-full text-center\" x-show=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(getXShow(index))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/highlights.templ`, Line: 66, Col: 26}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" x-transition:enter=\"transition ease-in-out duration-700 transform order-first\" x-transition:enter-start=\"opacity-0 -translate-y-4\" x-transition:enter-end=\"opacity-100 translate-y-0\" x-transition:leave=\"transition ease-in-out duration-300 transform absolute\" x-transition:leave-start=\"opacity-100 translate-y-0\" x-transition:leave-end=\"opacity-0 translate-y-4\"><div class=\"inline-flex relative align-top\"><img class=\"rounded-t-lg border border-transparent [background:linear-gradient(theme(colors.white),theme(colors.white))_padding-box,linear-gradient(120deg,theme(colors.zinc.300),theme(colors.zinc.100),theme(colors.zinc.300))_border-box] box-content shadow-2xl\" src=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var12 string
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(highlight.Image.Src)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/highlights.templ`, Line: 77, Col: 29}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" width=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var13 string
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(highlight.Image.Width)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/highlights.templ`, Line: 78, Col: 33}
}
_, 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("\" height=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var14 string
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(highlight.Image.Height)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/highlights.templ`, Line: 79, Col: 35}
}
_, 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("\" alt=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var15 string
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(highlight.Title)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/highlights.templ`, Line: 80, Col: 25}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
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 getSelectedClass(index int) string {
return fmt.Sprintf("tab === '%d' ? 'bg-zinc-100 opacity-60 hover:opacity-100 transition' : '[background:linear-gradient(theme(colors.white),theme(colors.white))_padding-box,linear-gradient(120deg,theme(colors.zinc.300),theme(colors.zinc.100),theme(colors.zinc.300))_border-box] shadow-sm rotate-1'", index+1)
}
func getShowBorder(index int) string {
return fmt.Sprintf("tab === '%d' ? 'hidden' : ''", index+1)
}
func getClickPrevent(index int) string {
return fmt.Sprintf("tab = '%d'", index+1)
}
func getXShow(index int) string {
return fmt.Sprintf("tab === '%d'", index+1)
}
var _ = templruntime.GeneratedTemplate

View File

@ -1,4 +1,4 @@
package home package marketing
import models "github.com/onsonr/sonr/internal/orm/marketing" import models "github.com/onsonr/sonr/internal/orm/marketing"
@ -27,22 +27,22 @@ var highlights = &models.Highlights{
Subtitle: "Sonr is a comprehensive system for Identity Management which proteects users across their digital personas while providing Developers a cost-effective solution for decentralized authentication.", Subtitle: "Sonr is a comprehensive system for Identity Management which proteects users across their digital personas while providing Developers a cost-effective solution for decentralized authentication.",
Features: []*models.Feature{ Features: []*models.Feature{
{ {
Title: "Infinite-Factor Authentication", Title: "∞-Factor Auth",
Desc: "Sonr is designed to work across all platforms and devices, building a encrypted and anonymous identity layer for each user on the internet.", Desc: "Sonr is designed to work across all platforms and devices, building a encrypted and anonymous identity layer for each user on the internet.",
Icon: nil, Icon: nil,
}, },
{ {
Title: "Self-Custody BTC & ETH", Title: "Data Ownership",
Desc: "Sonr leverages advanced cryptography to permit facilitating Wallet Operations directly on-chain, without the need for a centralized server.", Desc: "Sonr leverages advanced cryptography to permit facilitating Wallet Operations directly on-chain, without the need for a centralized server.",
Icon: nil, Icon: nil,
}, },
{ {
Title: "mAiNsTrEaM Ready", Title: "Everyday Transactions",
Desc: "Sonr follows the latest specifications from W3C, DIF, and ICF to essentially have an Interchain-Connected, Smart Account System - seamlessly authenticated with PassKeys.", Desc: "Sonr follows the latest specifications from W3C, DIF, and ICF to essentially have an Interchain-Connected, Smart Account System - seamlessly authenticated with PassKeys.",
Icon: nil, Icon: nil,
}, },
{ {
Title: "DAO Governed", Title: "Limitless Possibilities",
Desc: "Sonr is a proudly American Project which operates under the new Wyoming DUNA Legal Framework, ensuring the protection of your digital rights.", Desc: "Sonr is a proudly American Project which operates under the new Wyoming DUNA Legal Framework, ensuring the protection of your digital rights.",
Icon: nil, Icon: nil,
}, },
@ -54,25 +54,18 @@ var mission = &models.Mission{
Heading: "The Protocol for Decentralized Identity & Authentication", Heading: "The Protocol for Decentralized Identity & Authentication",
Subtitle: "We're creating the Global Standard for Decentralized Identity. Authenticate users with PassKeys, Issue Crypto Wallets, Build Payment flows, Send Encrypted Messages - all on a single platform.", Subtitle: "We're creating the Global Standard for Decentralized Identity. Authenticate users with PassKeys, Issue Crypto Wallets, Build Payment flows, Send Encrypted Messages - all on a single platform.",
Experience: &models.Feature{ Experience: &models.Feature{
Title: "Experience", Title: "Less is More",
Desc: "Sonr is a comprehensive system for Identity Management which proteects users across their digital personas while providing Developers a cost-effective solution for decentralized authentication.", Desc: "Sonr is a comprehensive system for Identity Management which proteects users across their digital personas while providing Developers a cost-effective solution for decentralized authentication.",
Icon: nil, Icon: nil,
}, },
Compliance: &models.Feature{ Compliance: &models.Feature{
Title: "Compliance", Title: "Works where there's Internet",
Desc: "Sonr is designed to work across all platforms and devices, building a encrypted and anonymous identity layer for each user on the internet.", Desc: "Sonr is designed to work across all platforms and devices, building a encrypted and anonymous identity layer for each user on the internet.",
Icon: nil, Icon: nil,
}, },
Interoperability: &models.Feature{ Interoperability: &models.Feature{
Title: "Interoperability", Title: "American Made DUNA",
Desc: "Sonr follows the latest specifications from W3C, DIF, and ICF to essentially have an Interchain-Connected, Smart Account System - seamlessly authenticated with PassKeys.", Desc: "Sonr follows the latest specifications from W3C, DIF, and ICF to essentially have an Interchain-Connected, Smart Account System - seamlessly authenticated with PassKeys.",
Icon: nil, Icon: nil,
}, },
Standards: []*models.Feature{
{
Title: "Standards",
Desc: "Sonr is a proudly American Project which operates under the new Wyoming DUNA Legal Framework, ensuring the protection of your digital rights.",
Icon: nil,
},
},
} }

View File

@ -1,21 +1,16 @@
package index package vaultindex
import ( import (
"bytes" "bytes"
"context" "context"
"encoding/json"
"github.com/ipfs/boxo/files" "github.com/ipfs/boxo/files"
"github.com/onsonr/sonr/internal/dwn/gen" "github.com/onsonr/sonr/internal/dwn/gen"
) )
func BuildFile(cnfg *gen.Config) (files.Node, error) { func BuildFile(cnfg *gen.Config) (files.Node, error) {
_, err := json.Marshal(cnfg)
if err != nil {
return nil, err
}
w := bytes.NewBuffer(nil) w := bytes.NewBuffer(nil)
err = IndexFile().Render(context.Background(), w) err := IndexFile().Render(context.Background(), w)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -1,31 +1,29 @@
package index package vaultindex
import ( import (
"github.com/onsonr/sonr/internal/dwn/gen"
"github.com/onsonr/sonr/pkg/nebula/global/state" "github.com/onsonr/sonr/pkg/nebula/global/state"
"github.com/onsonr/sonr/pkg/nebula/global/styles" "github.com/onsonr/sonr/pkg/nebula/global/styles"
) )
func ConfigFile(dwnConfig *gen.Config) {
}
templ IndexFile() { templ IndexFile() {
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
@styles.Styles()
@styles.Alpine() @styles.Alpine()
@styles.Htmx() @styles.Htmx()
@styles.Styles()
<meta charset="UTF-8"/> <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/> <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Sonr DWN</title> <title>Sonr DWN</title>
@state.RegisterServiceWorker() @state.RegisterServiceWorker()
</head> </head>
<body class="flex items-center justify-center h-full bg-neutral-50 lg:p-24 md:16 p-4"> @styles.Toaster() {
<body class="flex items-center justify-center h-full bg-zinc-50 lg:p-24 md:16 p-4">
<main class="flex-row items-center justify-center mx-auto w-fit max-w-screen-sm gap-y-3"> <main class="flex-row items-center justify-center mx-auto w-fit max-w-screen-sm gap-y-3">
<div id="output">Loading...</div> <div hx-get="/#" swap="outerHTML">Loading...</div>
</main> </main>
</body> </body>
}
</html> </html>
} }

View File

@ -1,7 +1,7 @@
// Code generated by templ - DO NOT EDIT. // Code generated by templ - DO NOT EDIT.
// templ: version: v0.2.778 // templ: version: v0.2.778
package index package vaultindex
//lint:file-ignore SA4006 This context is only used if a nested component is present. //lint:file-ignore SA4006 This context is only used if a nested component is present.
@ -9,14 +9,10 @@ import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime" import templruntime "github.com/a-h/templ/runtime"
import ( import (
"github.com/onsonr/sonr/internal/dwn/gen"
"github.com/onsonr/sonr/pkg/nebula/global/state" "github.com/onsonr/sonr/pkg/nebula/global/state"
"github.com/onsonr/sonr/pkg/nebula/global/styles" "github.com/onsonr/sonr/pkg/nebula/global/styles"
) )
func ConfigFile(dwnConfig *gen.Config) {
}
func IndexFile() templ.Component { func IndexFile() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { 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 templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
@ -42,6 +38,10 @@ func IndexFile() templ.Component {
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
templ_7745c5c3_Err = styles.Styles().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = styles.Alpine().Render(ctx, templ_7745c5c3_Buffer) templ_7745c5c3_Err = styles.Alpine().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
@ -50,10 +50,6 @@ func IndexFile() templ.Component {
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
templ_7745c5c3_Err = styles.Styles().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>Sonr DWN</title>") _, 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>Sonr DWN</title>")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
@ -62,7 +58,33 @@ func IndexFile() templ.Component {
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</head><body class=\"flex items-center justify-center h-full bg-neutral-50 lg:p-24 md:16 p-4\"><main class=\"flex-row items-center justify-center mx-auto w-fit max-w-screen-sm gap-y-3\"><div id=\"output\">Loading...</div></main></body></html>") _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</head>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<body class=\"flex items-center justify-center h-full bg-zinc-50 lg:p-24 md:16 p-4\"><main class=\"flex-row items-center justify-center mx-auto w-fit max-w-screen-sm gap-y-3\"><div hx-get=\"/#\" swap=\"outerHTML\">Loading...</div></main></body>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
templ_7745c5c3_Err = styles.Toaster().Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</html>")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }

View File

@ -34,11 +34,36 @@ async function main() {
"./assets/js/alpine.min.js", "./assets/js/alpine.min.js",
); );
// Fetch alpin-focus.min.js
await fetchAndSave(
"https://cdnjs.cloudflare.com/ajax/libs/alpinejs-focus/3.14.1/cdn.min.js",
"./assets/js/alpin-focus.min.js",
);
// Fetch dexie.min.js // Fetch dexie.min.js
await fetchAndSave( await fetchAndSave(
"https://cdnjs.cloudflare.com/ajax/libs/dexie/4.0.8/dexie.min.js", "https://cdnjs.cloudflare.com/ajax/libs/dexie/4.0.8/dexie.min.js",
"./assets/js/dexie.min.js", "./assets/js/dexie.min.js",
); );
// Fetch d3.min.js
await fetchAndSave(
"https://cdnjs.cloudflare.com/ajax/libs/d3/7.9.0/d3.min.js",
"./assets/js/d3.min.js",
);
// TopoJSON
await fetchAndSave(
"https://cdnjs.cloudflare.com/ajax/libs/topojson/3.0.2/topojson.min.js",
"./assets/js/topojson.min.js",
);
// Datamaps
await fetchAndSave(
"https://cdnjs.cloudflare.com/ajax/libs/datamaps/0.5.9/datamaps.world.min.js",
"./assets/js/datamaps.world.min.js",
);
} }
main(); main();

View File

@ -1,92 +0,0 @@
package state
templ NavigatorCredentialsCreate() {
<script>
function createCredential() {
navigator.credentials.create({
publicKey: {
rp: {
name: "Sonr",
},
user: {
id: new Uint8Array(0),
name: "Sonr",
displayName: "Sonr",
},
challenge: new Uint8Array(0),
pubKeyCredParams: [{
type: "public-key",
alg: -7,
}],
timeout: 60000,
excludeCredentials: [],
authenticatorSelection: {
requireResidentKey: false,
userVerification: "discouraged",
},
},
})
.then((assertion) => {
console.log("Assertion:", assertion);
})
.catch((error) => {
console.error("Error:", error);
});
}
</script>
}
templ NavigatorCredentialsGet() {
<script>
function getCredential() {
navigator.credentials.get({
publicKey: {
challenge: new Uint8Array(0),
allowCredentials: [],
timeout: 60000,
userVerification: "discouraged",
},
})
.then((assertion) => {
console.log("Assertion:", assertion);
})
.catch((error) => {
console.error("Error:", error);
});
}
</script>
}
templ NavigatorCredentialsGetAll() {
<script>
navigator.credentials.getAll({
publicKey: {
challenge: new Uint8Array(0),
allowCredentials: [],
timeout: 60000,
userVerification: "discouraged",
extensions: {
}
},
})
.then((assertion) => {
console.log("Assertion:", assertion);
})
.catch((error) => {
console.error("Error:", error);
});
</script>
}
templ NavigatorCredentialsHasPasskey() {
<script>
navigator.credentials.has()
.then((has) => {
console.log("Has Passkey:", has);
})
.catch((error) => {
console.error("Error:", error);
});
</script>
}

View File

@ -1,127 +0,0 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.2.778
package state
//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 NavigatorCredentialsCreate() 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("<script>\n\tfunction createCredential() {\n\t\tnavigator.credentials.create({\n\t\t\tpublicKey: {\n\t\t\t\trp: {\n\t\t\t\t\tname: \"Sonr\",\n\t\t\t\t},\n\t\t\t\tuser: {\n\t\t\t\t\tid: new Uint8Array(0),\n\t\t\t\t\tname: \"Sonr\",\n\t\t\t\t\tdisplayName: \"Sonr\",\n\t\t\t\t},\n\t\t\t\tchallenge: new Uint8Array(0),\n\t\t\t\tpubKeyCredParams: [{\n\t\t\t\t\ttype: \"public-key\",\n\t\t\t\t\talg: -7,\n\t\t\t\t}],\n\t\t\t\ttimeout: 60000,\n\t\t\t\texcludeCredentials: [],\n\t\t\t\tauthenticatorSelection: {\n\t\t\t\t\trequireResidentKey: false,\n\t\t\t\t\tuserVerification: \"discouraged\",\n\t\t\t\t},\n\t\t\t},\n\t\t})\n\t\t\t.then((assertion) => {\n\t\t\t\tconsole.log(\"Assertion:\", assertion);\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tconsole.error(\"Error:\", error);\n\t\t\t});\n\t\t}\n\t</script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
func NavigatorCredentialsGet() 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("<script>\n\t\tfunction getCredential() {\n\t\tnavigator.credentials.get({\n\t\t\tpublicKey: {\n\t\t\t\tchallenge: new Uint8Array(0),\n\t\t\t\tallowCredentials: [],\n\t\t\t\ttimeout: 60000,\n\t\t\t\tuserVerification: \"discouraged\",\n\t\t\t},\n\t\t})\n\t\t\t.then((assertion) => {\n\t\t\t\tconsole.log(\"Assertion:\", assertion);\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tconsole.error(\"Error:\", error);\n\t\t\t});\n\t}\n\t</script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
func NavigatorCredentialsGetAll() 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("<script>\n\t\tnavigator.credentials.getAll({\n\t\t\tpublicKey: {\n\t\t\t\tchallenge: new Uint8Array(0),\n\t\t\t\tallowCredentials: [],\n\t\t\t\ttimeout: 60000,\n\t\t\t\tuserVerification: \"discouraged\",\n\t\t\t\textensions: {\n\t\t\t\t\t\n\t\t\t\t}\n\t\t\t},\n\t\t})\n\t\t\t.then((assertion) => {\n\t\t\t\tconsole.log(\"Assertion:\", assertion);\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tconsole.error(\"Error:\", error);\n\t\t\t});\n\t</script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
func NavigatorCredentialsHasPasskey() 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("<script>\n\t\tnavigator.credentials.has()\n\t\t\t.then((has) => {\n\t\t\t\tconsole.log(\"Has Passkey:\", has);\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tconsole.error(\"Error:\", error);\n\t\t\t});\n\t</script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
var _ = templruntime.GeneratedTemplate

View File

@ -15,3 +15,14 @@ templ InsertAccount(accountName string) {
console.log("Inserted account with ID:", accountId); console.log("Inserted account with ID:", accountId);
</script> </script>
} }
templ InsertCredential(credentialName string) {
<script>
const credentialId = await motr.insertCredential({
name: credentialName,
createdAt: new Date(),
});
console.log("Inserted credential with ID:", credentialId);
</script>
}

View File

@ -37,4 +37,33 @@ func InsertAccount(accountName string) templ.Component {
}) })
} }
func InsertCredential(credentialName 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("<script>\n\t\tconst credentialId = await motr.insertCredential({\n\t\t\tname: credentialName,\n\t\t\tcreatedAt: new Date(),\n\t\t});\n\n\t\tconsole.log(\"Inserted credential with ID:\", credentialId);\n\t</script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
var _ = templruntime.GeneratedTemplate var _ = templruntime.GeneratedTemplate

View File

@ -1 +0,0 @@
package state

View File

@ -1,13 +1,15 @@
package state package state
var ( var (
serviceWorkerHandle = templ.NewOnceHandle() serviceWorkerInstall = templ.NewOnceHandle()
serviceWorkerReady = templ.NewOnceHandle()
) )
templ RegisterServiceWorker() { templ RegisterServiceWorker() {
@serviceWorkerHandle.Once() { @serviceWorkerInstall.Once() {
<script> <script type="text/javascript">
if ("serviceWorker" in navigator) { if ("serviceWorker" in navigator) {
// Register the service worker
window.addEventListener("load", function() { window.addEventListener("load", function() {
navigator.serviceWorker navigator.serviceWorker
.register("/sw.js") .register("/sw.js")

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