diff --git a/.envrc b/.envrc deleted file mode 100644 index 84fc8e536..000000000 --- a/.envrc +++ /dev/null @@ -1,7 +0,0 @@ -# Automatically sets up your devbox environment whenever you cd into this -# directory via our direnv integration: - -eval "$(devbox generate direnv --print-envrc)" - -# check out https://www.jetpack.io/devbox/docs/ide_configuration/direnv/ -# for more details diff --git a/Makefile b/Makefile index 72eb863e5..47a1702c7 100644 --- a/Makefile +++ b/Makefile @@ -299,6 +299,10 @@ sh-testnet: mod-tidy .PHONY: dwn motr templ +motr: + @echo "(motr) Building motr gateway" + go build -o ./build/motr ./cmd/motr + dwn: @echo "(dwn) Building dwn.wasm -> IPFS Vault" GOOS=js GOARCH=wasm go build -o ./x/vault/types/internal/app.wasm ./x/vault/client/dwn/dwn.go @@ -313,6 +317,14 @@ pkl: go run github.com/apple/pkl-go/cmd/pkl-gen-go ./config/pkl/dwn.pkl go run github.com/apple/pkl-go/cmd/pkl-gen-go ./config/pkl/orm.pkl +start-caddy: + @echo "(start-caddy) Starting caddy" + ./build/caddy run --config ./config/caddy/Caddyfile + +start-proxy: + @echo "(start-proxy) Starting proxy server" + ./build/motr proxy + ############################################################################### ### help ### ############################################################################### diff --git a/cmd/motr/main.go b/cmd/motr/main.go new file mode 100644 index 000000000..ed4fb66b7 --- /dev/null +++ b/cmd/motr/main.go @@ -0,0 +1,14 @@ +package main + +import "github.com/spf13/cobra" + +func main() { + rootCmd := &cobra.Command{ + Use: "motr", + Short: "Manage a local DWN instance for the Sonr blockchain", + } + rootCmd.AddCommand(NewProxyCmd()) + if err := rootCmd.Execute(); err != nil { + panic(err) + } +} diff --git a/cmd/motr/proxy.go b/cmd/motr/proxy.go new file mode 100644 index 000000000..232387771 --- /dev/null +++ b/cmd/motr/proxy.go @@ -0,0 +1,55 @@ +package main + +import ( + "context" + "net/http" + "os" + "os/signal" + "time" + + "github.com/labstack/echo/v4" + "github.com/labstack/gommon/log" + "github.com/onsonr/sonr/nebula" + "github.com/onsonr/sonr/nebula/pages" + "github.com/spf13/cobra" +) + +func NewProxyCmd() *cobra.Command { + return &cobra.Command{ + Use: "proxy", + Short: "Starts the DWN proxy server for the local IPFS node", + Run: func(cmd *cobra.Command, args []string) { + // Echo instance + e := echo.New() + e.Logger.SetLevel(log.INFO) + + // Configure the server + if err := nebula.UseAssets(e); err != nil { + e.Logger.Fatal(err) + } + + e.GET("/", pages.Home) + e.GET("/allocate", pages.Profile) + + // Start server + ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt) + defer stop() + // Start server + go func() { + if err := e.Start(":1323"); err != nil && err != http.ErrServerClosed { + e.Logger.Fatal("shutting down the server") + } + }() + + // Wait for interrupt signal to gracefully shutdown the server with a timeout of 10 seconds. + <-ctx.Done() + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + // Shutdown the server with 10 seconds timeout. + if err := e.Shutdown(ctx); err != nil { + e.Logger.Fatal(err) + } + }, + } +} diff --git a/config/caddy/Caddyfile b/config/caddy/Caddyfile index c97299e26..ae09792e7 100644 --- a/config/caddy/Caddyfile +++ b/config/caddy/Caddyfile @@ -1,33 +1,43 @@ { - email team@sonr.id + # Global options + email team@sonr.id +} + +# Services exposed via Cloudflare Tunnel +:1323 { + reverse_proxy localhost:1323 +} + +:1317 { + reverse_proxy localhost:1317 +} + +:9090 { + reverse_proxy localhost:9091 +} + +:26657 { + reverse_proxy localhost:26657 } -# Vaults at vault.sonr.id vault.sonr.id { - tls { - dns cloudflare {env.CLOUDFLARE_API_TOKEN} - resolvers 1.1.1.1 - } + # Since vault.sonr.id has specific configurations, we can specify the hostname - # Match paths that are bech32 addresses - @vault path_regexp vaultPath ^/([a-z0-9]{42})(/.*|)$ + reverse_proxy localhost:8080 - handle @vault { - # Rewrite to IPFS gateway format - uri replace /{re.vaultPath.0} /ipns/{re.vaultPath.1}{re.vaultPath.2} + @vault path_regexp vaultPath ^/([a-z0-9]{42})(/.*|)$ - # Proxy to IPFS gateway - reverse_proxy http://localhost:8080 - } + handle @vault { + uri replace /{re.vaultPath.0} /ipns/{re.vaultPath.1}{re.vaultPath.2} + reverse_proxy localhost:8080 + } - file_server + file_server - header { - Content-Type .wasm application/wasm - Service-Worker-Allowed "/" - # Add any other necessary headers - } + header { + Content-Type .wasm application/wasm + Service-Worker-Allowed "/" + } - # Optional: Enable compression - encode zstd gzip + encode zstd gzip } diff --git a/config/caddy/caddy.json b/config/caddy/caddy.json deleted file mode 100644 index e69de29bb..000000000 diff --git a/config/dwn/Config.pkl.go b/config/dwn/Config.pkl.go index 69b448bea..f0c8ef0cf 100644 --- a/config/dwn/Config.pkl.go +++ b/config/dwn/Config.pkl.go @@ -9,4 +9,6 @@ type Config struct { Motr *Motr `pkl:"motr" json:"motr,omitempty"` Schema *Schema `pkl:"schema" json:"schema,omitempty"` + + ProxyUrl string `pkl:"proxyUrl" json:"proxyUrl,omitempty"` } diff --git a/config/pkl/dwn.pkl b/config/pkl/dwn.pkl index ea4cea655..4eae02fbc 100644 --- a/config/pkl/dwn.pkl +++ b/config/pkl/dwn.pkl @@ -24,6 +24,9 @@ class Config { @JsonField schema: Schema + + @JsonField + proxyUrl: String } class IPFS { diff --git a/devbox.json b/devbox.json index dc6d221f1..217a42e76 100644 --- a/devbox.json +++ b/devbox.json @@ -1,27 +1,61 @@ { "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.12.0/.schema/devbox.schema.json", - "packages": ["go@1.22", "bun@latest"], + "packages": [ + "go@1.22", + "bun@latest", + "ipfs@latest", + "skate@latest", + "cloudflared@latest" + ], "env": { - "CLOUDFLARE_API_TOKEN": "$CLOUDFLARE_API_TOKEN", + "CLOUDFLARE_TUNNEL_TOKEN": "$(skate get CLOUDFLARE_TUNNEL_TOKEN)", "GOPATH": "$HOME/go", "PATH": "$HOME/go/bin:$PATH", "TEMPL_EXPERIMENT": "rawgo", "CHAIN_ID": "sonr-testnet-1", "DENOM": "usnr", "KEYRING": "test", - "MONIKER": "florence", - "ENV": "$ENVIRONMENT" + "MONIKER": "florence" }, "shell": { "scripts": { - "install": ["make install"], - "build": ["bun --cwd nebula run build", "make dwn", "make build"], - "docker": ["make local-image"], - "proto": ["make proto-gen"], - "pkl": ["make pkl"], - "templ": ["make templ"], - "proxy": ["./build/sonrd dwn-proxy"], - "watch:nebula": ["bun --cwd nebula run watch"] + "install": [ + "make install", + "bun --cwd nebula run fetch:deps" + ], + "build:docker": [ + "make local-image" + ], + "build:dwn": [ + "make dwn" + ], + "build:motr": [ + "make motr" + ], + "build:nebula": [ + "bun --cwd nebula run build" + ], + "build:sonrd": [ + "make build" + ], + "build:xcaddy": [ + "sh scripts/build_xcaddy.sh" + ], + "gen:proto": [ + "make proto-gen" + ], + "gen:pkl": [ + "make pkl" + ], + "gen:templ": [ + "make templ" + ], + "start:tunnel": [ + "cloudflared tunnel run --token $(skate get CLOUDFLARE_TUNNEL_TOKEN)" + ], + "watch:nebula": [ + "bun --cwd nebula run watch" + ] } } } diff --git a/devbox.lock b/devbox.lock index 2e3426763..fd921b7fd 100644 --- a/devbox.lock +++ b/devbox.lock @@ -49,6 +49,54 @@ } } }, + "cloudflared@latest": { + "last_modified": "2024-09-10T15:01:03Z", + "resolved": "github:NixOS/nixpkgs/5ed627539ac84809c78b2dd6d26a5cebeb5ae269#cloudflared", + "source": "devbox-search", + "version": "2024.8.3", + "systems": { + "aarch64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/nmmh1dx4rvqayxq31c99gxpbwvcchx9w-cloudflared-2024.8.3", + "default": true + } + ], + "store_path": "/nix/store/nmmh1dx4rvqayxq31c99gxpbwvcchx9w-cloudflared-2024.8.3" + }, + "aarch64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/kwikn13v0rddmr8kjhnj67li8aq8qwa6-cloudflared-2024.8.3", + "default": true + } + ], + "store_path": "/nix/store/kwikn13v0rddmr8kjhnj67li8aq8qwa6-cloudflared-2024.8.3" + }, + "x86_64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/9630bavr6jb44g0pcwwqn0zpgin39dc7-cloudflared-2024.8.3", + "default": true + } + ], + "store_path": "/nix/store/9630bavr6jb44g0pcwwqn0zpgin39dc7-cloudflared-2024.8.3" + }, + "x86_64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/hybva7brncispiqm6f0qrpn897r3y3ja-cloudflared-2024.8.3", + "default": true + } + ], + "store_path": "/nix/store/hybva7brncispiqm6f0qrpn897r3y3ja-cloudflared-2024.8.3" + } + } + }, "go@1.22": { "last_modified": "2024-09-12T11:58:09Z", "resolved": "github:NixOS/nixpkgs/280db3decab4cbeb22a4599bd472229ab74d25e1#go", @@ -96,6 +144,60 @@ "store_path": "/nix/store/chzgk756zb2cqlzbjr86m0lfxi63cdfy-go-1.22.7" } } + }, + "ipfs@latest": { + "last_modified": "2023-02-24T09:01:09Z", + "resolved": "github:NixOS/nixpkgs/7d0ed7f2e5aea07ab22ccb338d27fbe347ed2f11#ipfs", + "source": "devbox-search", + "version": "0.17.0" + }, + "skate@latest": { + "last_modified": "2024-09-10T15:01:03Z", + "resolved": "github:NixOS/nixpkgs/5ed627539ac84809c78b2dd6d26a5cebeb5ae269#skate", + "source": "devbox-search", + "version": "1.0.0", + "systems": { + "aarch64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/5hn4s18zy08inhimckf3794zszxjn077-skate-1.0.0", + "default": true + } + ], + "store_path": "/nix/store/5hn4s18zy08inhimckf3794zszxjn077-skate-1.0.0" + }, + "aarch64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/jxwx4fn5qbaz2nan3gmpydqx6vv8ldp1-skate-1.0.0", + "default": true + } + ], + "store_path": "/nix/store/jxwx4fn5qbaz2nan3gmpydqx6vv8ldp1-skate-1.0.0" + }, + "x86_64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/zs6ik66kpz9q8mdmzxqmgjv51y39r76h-skate-1.0.0", + "default": true + } + ], + "store_path": "/nix/store/zs6ik66kpz9q8mdmzxqmgjv51y39r76h-skate-1.0.0" + }, + "x86_64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/6zbyhj72wh0645lj6b9c392aqqg11a84-skate-1.0.0", + "default": true + } + ], + "store_path": "/nix/store/6zbyhj72wh0645lj6b9c392aqqg11a84-skate-1.0.0" + } + } } } } diff --git a/nebula/pages/login_templ.go b/nebula/pages/login_templ.go index dfb81860f..d6c91bb1b 100644 --- a/nebula/pages/login_templ.go +++ b/nebula/pages/login_templ.go @@ -50,14 +50,6 @@ func loginView(c echo.Context) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Err = blocks.Head("Sonr.ID", true).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } templ_7745c5c3_Var3 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) diff --git a/process-compose.yaml b/process-compose.yaml index dcbe76366..7c40aa43d 100644 --- a/process-compose.yaml +++ b/process-compose.yaml @@ -13,14 +13,23 @@ processes: namespace: testnet command: "make sh-testnet" restart: on_failure - max_restarts: 3 + max_restarts: 1 depends: - ipfs - proxy: + motr: namespace: testnet - command: "devbox run proxy" + command: "make start-proxy" restart: on_failure - max_restarts: 3 + max_restarts: 1 depends: - sonr + - ipfs + + tunnel: + namespace: public + command: "devbox run start:tunnel" + restart: on_failure + max_restarts: 1 + depends: + - caddy diff --git a/scripts/bootstrap_ipfs.sh b/scripts/bootstrap_ipfs.sh index 4ad5b4ed4..099a3c407 100755 --- a/scripts/bootstrap_ipfs.sh +++ b/scripts/bootstrap_ipfs.sh @@ -1,20 +1,40 @@ #!/bin/bash +# Exit immediately if a command exits with a non-zero status. +set -e + # Initialize IPFS ipfs init +# Optimize local discovery and connectivity +ipfs config --json Discovery.MDNS.Enabled true +ipfs config --json Routing.Type "dhtclient" +ipfs config --json Swarm.ConnMgr.LowWater 200 +ipfs config --json Swarm.ConnMgr.HighWater 500 + # Set up the Cloudflare IPFS gateway peers ipfs config --json Peering.Peers '[ -{"ID": "QmcFf2FH3CEgTNHeMRGhN7HNHU1EXAxoEk6EFuSyXCsvRE", "Addrs": ["/dnsaddr/node-1.ingress.cloudflare-ipfs.com"]}, -{"ID": "QmcFmLd5ySfk2WZuJ1mfSWLDjdmHZq7rSAua4GoeSQfs1z", "Addrs": ["/dnsaddr/node-2.ingress.cloudflare-ipfs.com"]}, -{"ID": "QmcfFmzSDVbwexQ9Au2pt5YEXHK5xajwgaU6PpkbLWerMa", "Addrs": ["/dnsaddr/node-3.ingress.cloudflare-ipfs.com"]}, -{"ID": "QmcfJeB3Js1FG7T8YaZATEiaHqNKVdQfybYYkbT1knUswx", "Addrs": ["/dnsaddr/node-4.ingress.cloudflare-ipfs.com"]}, -{"ID": "QmcfVvzK4tMdFmpJjEKDUoqRgP4W9FnmJoziYX5GXJJ8eZ", "Addrs": ["/dnsaddr/node-5.ingress.cloudflare-ipfs.com"]}, -{"ID": "QmcfZD3VKrUxyP9BbyUnZDpbqDnT7cQ4WjPP8TRLXaoE7G", "Addrs": ["/dnsaddr/node-6.ingress.cloudflare-ipfs.com"]}, -{"ID": "QmcfZP2LuW4jxviTeG8fi28qjnZScACb8PEgHAc17ZEri3", "Addrs": ["/dnsaddr/node-7.ingress.cloudflare-ipfs.com"]}, -{"ID": "QmcfgsJsMtx6qJb74akCw1M24X1zFwgGo11h1cuhwQjtJP", "Addrs": ["/dnsaddr/node-8.ingress.cloudflare-ipfs.com"]}, -{"ID": "Qmcfr2FC7pFzJbTSDfYaSy1J8Uuy8ccGLeLyqJCKJvTHMi", "Addrs": ["/dnsaddr/node-9.ingress.cloudflare-ipfs.com"]}, -{"ID": "QmcfR3V5YAtHBzxVACWCzXTt26SyEkxdwhGJ6875A8BuWx", "Addrs": ["/dnsaddr/node-10.ingress.cloudflare-ipfs.com"]}, -{"ID": "Qmcfuo1TM9uUiJp6dTbm915Rf1aTqm3a3dnmCdDQLHgvL5", "Addrs": ["/dnsaddr/node-11.ingress.cloudflare-ipfs.com"]}, -{"ID": "QmcfV2sg9zaq7UUHVCGuSvT2M2rnLBAPsiE79vVyK3Cuev", "Addrs": ["/dnsaddr/node-12.ingress.cloudflare-ipfs.com"]} + {"ID": "QmcFf2FH3CEgTNHeMRGhN7HNHU1EXAxoEk6EFuSyXCsvRE", "Addrs": ["/dnsaddr/node-1.ingress.cloudflare-ipfs.com"]}, + {"ID": "QmcFmLd5ySfk2WZuJ1mfSWLDjdmHZq7rSAua4GoeSQfs1z", "Addrs": ["/dnsaddr/node-2.ingress.cloudflare-ipfs.com"]}, + {"ID": "QmcfFmzSDVbwexQ9Au2pt5YEXHK5xajwgaU6PpkbLWerMa", "Addrs": ["/dnsaddr/node-3.ingress.cloudflare-ipfs.com"]}, + {"ID": "QmcfJeB3Js1FG7T8YaZATEiaHqNKVdQfybYYkbT1knUswx", "Addrs": ["/dnsaddr/node-4.ingress.cloudflare-ipfs.com"]}, + {"ID": "QmcfVvzK4tMdFmpJjEKDUoqRgP4W9FnmJoziYX5GXJJ8eZ", "Addrs": ["/dnsaddr/node-5.ingress.cloudflare-ipfs.com"]}, + {"ID": "QmcfZD3VKrUxyP9BbyUnZDpbqDnT7cQ4WjPP8TRLXaoE7G", "Addrs": ["/dnsaddr/node-6.ingress.cloudflare-ipfs.com"]}, + {"ID": "QmcfZP2LuW4jxviTeG8fi28qjnZScACb8PEgHAc17ZEri3", "Addrs": ["/dnsaddr/node-7.ingress.cloudflare-ipfs.com"]}, + {"ID": "QmcfgsJsMtx6qJb74akCw1M24X1zFwgGo11h1cuhwQjtJP", "Addrs": ["/dnsaddr/node-8.ingress.cloudflare-ipfs.com"]}, + {"ID": "Qmcfr2FC7pFzJbTSDfYaSy1J8Uuy8ccGLeLyqJCKJvTHMi", "Addrs": ["/dnsaddr/node-9.ingress.cloudflare-ipfs.com"]}, + {"ID": "QmcfR3V5YAtHBzxVACWCzXTt26SyEkxdwhGJ6875A8BuWx", "Addrs": ["/dnsaddr/node-10.ingress.cloudflare-ipfs.com"]}, + {"ID": "Qmcfuo1TM9uUiJp6dTbm915Rf1aTqm3a3dnmCdDQLHgvL5", "Addrs": ["/dnsaddr/node-11.ingress.cloudflare-ipfs.com"]}, + {"ID": "QmcfV2sg9zaq7UUHVCGuSvT2M2rnLBAPsiE79vVyK3Cuev", "Addrs": ["/dnsaddr/node-12.ingress.cloudflare-ipfs.com"]} ]' + +# Configure API and Gateway addresses to listen on localhost only +ipfs config Addresses.API /ip4/127.0.0.1/tcp/5001 +ipfs config Addresses.Gateway /ip4/127.0.0.1/tcp/8080 + +# Enable experimental features +ipfs config --json Experimental.FilestoreEnabled true +ipfs config --json Experimental.UrlstoreEnabled true + +# Start the IPFS daemon with additional options for better performance and compatibility +ipfs daemon --enable-gc --migrate --enable-pubsub-experiment --enable-namesys-pubsub diff --git a/scripts/build_xcaddy.sh b/scripts/build_xcaddy.sh new file mode 100755 index 000000000..13a882eec --- /dev/null +++ b/scripts/build_xcaddy.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +# Exit immediately if a command exits with a non-zero status. +set -e + +# Function to check if a command exists. +command_exists() { + command -v "$1" >/dev/null 2>&1 +} + +echo "Starting the build process for Caddy with Cloudflare DNS module..." + +# Check if Go is installed +if ! command_exists go; then + echo "Go is not installed. Please install Go before running this script." + exit 1 +fi + +# Set Go environment variables +export GOPATH=$(go env GOPATH) +export GOBIN=$GOPATH/bin +export PATH=$PATH:$GOBIN + +# Install xcaddy if not present +if ! command_exists xcaddy; then + echo "xcaddy not found. Installing xcaddy..." + curl -sSfL https://raw.githubusercontent.com/caddyserver/xcaddy/master/install.sh | bash -s -- -b $GOBIN +fi + +# Build Caddy with the Cloudflare DNS module +echo "Building Caddy with the Cloudflare DNS module..." +xcaddy build --with github.com/caddy-dns/cloudflare +mv caddy ../build/caddy +echo "Caddy has been built successfully with the Cloudflare DNS module." + +# Optional: Move the caddy binary to /usr/local/bin (requires sudo) +# echo "Moving caddy to /usr/local/bin (requires sudo)..." +# sudo mv caddy /usr/local/bin/ + +# echo "Caddy has been installed to /usr/local/bin." diff --git a/x/vault/types/internal/app.wasm b/x/vault/types/internal/app.wasm index f2c0f709e..ed589d153 100755 Binary files a/x/vault/types/internal/app.wasm and b/x/vault/types/internal/app.wasm differ