From e04d071ca797669bb1bf0e52ed612ac2c41a74bf Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Mon, 25 Nov 2024 13:54:33 -0500 Subject: [PATCH] refactor: update devbox configuration and scripts --- Makefile | 5 +- deploy/local/devbox.json | 34 +++ deploy/local/devbox.lock | 251 ++++++++++++++++++ deploy/local/process-compose.yaml | 28 ++ deploy/testnet/devbox.json | 43 +++ .../testnet/process-compose.yaml | 4 +- devbox.json | 37 +-- devbox.lock | 60 +---- pkg/services/credentials/scripts_templ.go | 2 +- pkg/services/payments/scripts_templ.go | 2 +- pkg/services/storage/scripts_templ.go | 2 +- pkg/webapp/components/auth/authorize_templ.go | 2 +- .../auth/create_credential_templ.go | 2 +- .../components/auth/get_credential_templ.go | 2 +- pkg/webapp/components/auth/login_templ.go | 2 +- .../components/auth/register_start_templ.go | 2 +- pkg/webapp/components/auth/register_templ.go | 2 +- pkg/webapp/components/landing/arch_templ.go | 2 +- pkg/webapp/components/landing/cta_templ.go | 2 +- pkg/webapp/components/landing/footer_templ.go | 2 +- pkg/webapp/components/landing/header_templ.go | 2 +- pkg/webapp/components/landing/hero_templ.go | 2 +- .../components/landing/highlights_templ.go | 2 +- .../components/landing/lowlights_templ.go | 2 +- .../components/landing/mission_templ.go | 2 +- pkg/webapp/components/ui/badges_templ.go | 2 +- pkg/webapp/components/ui/buttons_templ.go | 2 +- pkg/webapp/components/ui/cards_templ.go | 2 +- pkg/webapp/components/ui/icon_templ.go | 2 +- pkg/webapp/components/ui/layout_templ.go | 2 +- pkg/webapp/components/ui/panels_templ.go | 2 +- pkg/webapp/components/ui/scripts_templ.go | 2 +- pkg/webapp/components/ui/sizes_templ.go | 2 +- pkg/webapp/components/ui/typography_templ.go | 2 +- pkg/webapp/pages/auth_templ.go | 2 +- pkg/webapp/pages/dashboard_templ.go | 2 +- pkg/webapp/pages/landing_templ.go | 2 +- pkl/README.md | 4 - scripts/init_env.sh | 28 +- scripts/setup_ipfs.sh | 27 -- slumber.yml | 45 ---- web/libs/noble-client | 1 - web/libs/osmosis-client | 1 - web/libs/sonr-client | 1 - web/workers/noble-client/.gitignore | 5 + web/workers/noble-client/README.md | 9 + web/workers/noble-client/package.json | 16 ++ web/workers/noble-client/src/index.js | 45 ++++ web/workers/noble-client/src/stub.js | 26 ++ web/workers/noble-client/wrangler.toml | 113 ++++++++ web/workers/osmosis-client/.gitignore | 5 + web/workers/osmosis-client/README.md | 10 + web/workers/osmosis-client/package.json | 16 ++ web/workers/osmosis-client/src/index.js | 45 ++++ web/workers/osmosis-client/src/stub.js | 26 ++ web/workers/osmosis-client/wrangler.toml | 113 ++++++++ web/workers/sonr-client/.gitignore | 5 + web/workers/sonr-client/README.md | 10 + web/workers/sonr-client/bun.lockb | Bin 0 -> 106594 bytes web/workers/sonr-client/package.json | 16 ++ web/workers/sonr-client/src/index.js | 45 ++++ web/workers/sonr-client/src/stub.js | 26 ++ web/workers/sonr-client/wrangler.toml | 113 ++++++++ 63 files changed, 1069 insertions(+), 202 deletions(-) create mode 100644 deploy/local/devbox.json create mode 100644 deploy/local/devbox.lock create mode 100644 deploy/local/process-compose.yaml create mode 100644 deploy/testnet/devbox.json rename process-compose.yaml => deploy/testnet/process-compose.yaml (77%) delete mode 100644 pkl/README.md mode change 100644 => 100755 scripts/init_env.sh delete mode 100755 scripts/setup_ipfs.sh delete mode 100644 slumber.yml delete mode 160000 web/libs/noble-client delete mode 160000 web/libs/osmosis-client delete mode 160000 web/libs/sonr-client create mode 100644 web/workers/noble-client/.gitignore create mode 100644 web/workers/noble-client/README.md create mode 100644 web/workers/noble-client/package.json create mode 100644 web/workers/noble-client/src/index.js create mode 100644 web/workers/noble-client/src/stub.js create mode 100644 web/workers/noble-client/wrangler.toml create mode 100644 web/workers/osmosis-client/.gitignore create mode 100644 web/workers/osmosis-client/README.md create mode 100644 web/workers/osmosis-client/package.json create mode 100644 web/workers/osmosis-client/src/index.js create mode 100644 web/workers/osmosis-client/src/stub.js create mode 100644 web/workers/osmosis-client/wrangler.toml create mode 100644 web/workers/sonr-client/.gitignore create mode 100644 web/workers/sonr-client/README.md create mode 100755 web/workers/sonr-client/bun.lockb create mode 100644 web/workers/sonr-client/package.json create mode 100644 web/workers/sonr-client/src/index.js create mode 100644 web/workers/sonr-client/src/stub.js create mode 100644 web/workers/sonr-client/wrangler.toml diff --git a/Makefile b/Makefile index 87cf4f835..fda10386a 100644 --- a/Makefile +++ b/Makefile @@ -286,7 +286,10 @@ testnet-basic: setup-testnet sh-testnet: mod-tidy CHAIN_ID="sonr-testnet-1" BLOCK_TIME="1000ms" CLEAN=true sh scripts/test_node.sh -.PHONY: setup-testnet set-testnet-configs testnet testnet-basic sh-testnet +buf-publish: + cd ./proto && bunx buf dep update && bunx buf build && bunx buf push + +.PHONY: setup-testnet set-testnet-configs testnet testnet-basic sh-testnet buf-publish ############################################################################### ### help ### diff --git a/deploy/local/devbox.json b/deploy/local/devbox.json new file mode 100644 index 000000000..7161a4296 --- /dev/null +++ b/deploy/local/devbox.json @@ -0,0 +1,34 @@ +{ + "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.12.0/.schema/devbox.schema.json", + "packages": [ + "go@1.22", + "bun@latest", + "ipfs@latest", + "skate@latest", + "air@latest", + "templ@latest" + ], + "env": { + "GOPATH": "$HOME/go", + "CHAIN_ID": "sonr-testnet-1", + "DENOM": "usnr", + "KEYRING": "test", + "MONIKER": "florence", + "BINARY": "sonrd", + "ACC0_NAME": "acc0", + "ACC1_NAME": "acc1", + "ACC0_ADDRESS": "idx1efd63aw40lxf3n4mhf7dzhjkr453axur9vjt6y", + "ACC1_ADDRESS": "idx1hj5fveer5cjtn4wd6wstzugjfdxzl0xpecp0nd", + "ACC0_MNEMONIC": "$(skate get ACC0_MNEMONIC)", + "ACC1_MNEMONIC": "$(skate get ACC1_MNEMONIC)" + }, + "shell": { + "init_hook": ["export ROOT=$(git rev-parse --show-toplevel)"], + "scripts": { + "devnet": ["cd $ROOT", "make sh-testnet"], + "ipfs": ["ipfs daemon"], + "air": ["cd $ROOT", "air"], + "gex": ["gex"] + } + } +} diff --git a/deploy/local/devbox.lock b/deploy/local/devbox.lock new file mode 100644 index 000000000..e2633ad0f --- /dev/null +++ b/deploy/local/devbox.lock @@ -0,0 +1,251 @@ +{ + "lockfile_version": "1", + "packages": { + "air@latest": { + "last_modified": "2024-11-16T04:25:12Z", + "resolved": "github:NixOS/nixpkgs/34a626458d686f1b58139620a8b2793e9e123bba#air", + "source": "devbox-search", + "version": "1.61.1", + "systems": { + "aarch64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/0s90vbnmsyyixs0991md21pbrw8babfb-air-1.61.1", + "default": true + } + ], + "store_path": "/nix/store/0s90vbnmsyyixs0991md21pbrw8babfb-air-1.61.1" + }, + "aarch64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/8mpw2asxs297v26fxqy2y1bq438f344l-air-1.61.1", + "default": true + } + ], + "store_path": "/nix/store/8mpw2asxs297v26fxqy2y1bq438f344l-air-1.61.1" + }, + "x86_64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/abminkf7ldqf9vm14xx5wvsrdx3wrvy6-air-1.61.1", + "default": true + } + ], + "store_path": "/nix/store/abminkf7ldqf9vm14xx5wvsrdx3wrvy6-air-1.61.1" + }, + "x86_64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/ajx8v5rbbvglncb97yybg3x9kn95gfrm-air-1.61.1", + "default": true + } + ], + "store_path": "/nix/store/ajx8v5rbbvglncb97yybg3x9kn95gfrm-air-1.61.1" + } + } + }, + "bun@latest": { + "last_modified": "2024-11-18T00:41:09Z", + "resolved": "github:NixOS/nixpkgs/5083ec887760adfe12af64830a66807423a859a7#bun", + "source": "devbox-search", + "version": "1.1.34", + "systems": { + "aarch64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/xnj00gq1mfffvgyisghk4m9f38gc5c5c-bun-1.1.34", + "default": true + } + ], + "store_path": "/nix/store/xnj00gq1mfffvgyisghk4m9f38gc5c5c-bun-1.1.34" + }, + "aarch64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/kccpzv8fb7swmmxbhv805qzq242rhy33-bun-1.1.34", + "default": true + } + ], + "store_path": "/nix/store/kccpzv8fb7swmmxbhv805qzq242rhy33-bun-1.1.34" + }, + "x86_64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/8h5k3l4fpgs3al2wvna7x9ybyyc8k36d-bun-1.1.34", + "default": true + } + ], + "store_path": "/nix/store/8h5k3l4fpgs3al2wvna7x9ybyyc8k36d-bun-1.1.34" + }, + "x86_64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/x089g4srqw71w5jnc87vxbh7m12498i0-bun-1.1.34", + "default": true + } + ], + "store_path": "/nix/store/x089g4srqw71w5jnc87vxbh7m12498i0-bun-1.1.34" + } + } + }, + "go@1.22": { + "last_modified": "2024-11-16T04:25:12Z", + "resolved": "github:NixOS/nixpkgs/34a626458d686f1b58139620a8b2793e9e123bba#go_1_22", + "source": "devbox-search", + "version": "1.22.9", + "systems": { + "aarch64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/4nf51i4ah186y2jy3fad2fyvpa49qx6q-go-1.22.9", + "default": true + } + ], + "store_path": "/nix/store/4nf51i4ah186y2jy3fad2fyvpa49qx6q-go-1.22.9" + }, + "aarch64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/8w8vzwgp55yl8j1ljgm4wzdgjkvkv5v3-go-1.22.9", + "default": true + } + ], + "store_path": "/nix/store/8w8vzwgp55yl8j1ljgm4wzdgjkvkv5v3-go-1.22.9" + }, + "x86_64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/vlih7j78ki05i8nvzdsxvws7a7ksq04m-go-1.22.9", + "default": true + } + ], + "store_path": "/nix/store/vlih7j78ki05i8nvzdsxvws7a7ksq04m-go-1.22.9" + }, + "x86_64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/frc5188kgv3ws0n999c7cy5vi2f8k4jp-go-1.22.9", + "default": true + } + ], + "store_path": "/nix/store/frc5188kgv3ws0n999c7cy5vi2f8k4jp-go-1.22.9" + } + } + }, + "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-11-16T04:25:12Z", + "resolved": "github:NixOS/nixpkgs/34a626458d686f1b58139620a8b2793e9e123bba#skate", + "source": "devbox-search", + "version": "1.0.0", + "systems": { + "aarch64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/q6yhpyfbqiabyic6ymx5rp2db62bnbvr-skate-1.0.0", + "default": true + } + ], + "store_path": "/nix/store/q6yhpyfbqiabyic6ymx5rp2db62bnbvr-skate-1.0.0" + }, + "aarch64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/q55dbgvc4xwvr2g02dks6j2j699qni2k-skate-1.0.0", + "default": true + } + ], + "store_path": "/nix/store/q55dbgvc4xwvr2g02dks6j2j699qni2k-skate-1.0.0" + }, + "x86_64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/s1hy525y8ciya3nrns9kryy3jlcw8igv-skate-1.0.0", + "default": true + } + ], + "store_path": "/nix/store/s1hy525y8ciya3nrns9kryy3jlcw8igv-skate-1.0.0" + }, + "x86_64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/8s03iazymz77nv6pjxpz7wair0m646wv-skate-1.0.0", + "default": true + } + ], + "store_path": "/nix/store/8s03iazymz77nv6pjxpz7wair0m646wv-skate-1.0.0" + } + } + }, + "templ@latest": { + "last_modified": "2024-11-16T04:25:12Z", + "resolved": "github:NixOS/nixpkgs/34a626458d686f1b58139620a8b2793e9e123bba#templ", + "source": "devbox-search", + "version": "0.2.793", + "systems": { + "aarch64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/ivargvf76g71k5gk3iz4al52rsy28w38-templ-0.2.793", + "default": true + } + ], + "store_path": "/nix/store/ivargvf76g71k5gk3iz4al52rsy28w38-templ-0.2.793" + }, + "aarch64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/03654iddn006yx5j1lqq496hax60v8p5-templ-0.2.793", + "default": true + } + ], + "store_path": "/nix/store/03654iddn006yx5j1lqq496hax60v8p5-templ-0.2.793" + }, + "x86_64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/blvd5wbd1ix6m745s4zx3b84kwzprshq-templ-0.2.793", + "default": true + } + ], + "store_path": "/nix/store/blvd5wbd1ix6m745s4zx3b84kwzprshq-templ-0.2.793" + }, + "x86_64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/sn5h79d36r86i6a8rm1k52c2ij1s32kx-templ-0.2.793", + "default": true + } + ], + "store_path": "/nix/store/sn5h79d36r86i6a8rm1k52c2ij1s32kx-templ-0.2.793" + } + } + } + } +} diff --git a/deploy/local/process-compose.yaml b/deploy/local/process-compose.yaml new file mode 100644 index 000000000..67e41333f --- /dev/null +++ b/deploy/local/process-compose.yaml @@ -0,0 +1,28 @@ +version: "0.6" + +processes: + ipfs: + namespace: testnet + command: "devbox run ipfs" + background: true + availability: + restart: never + max_restarts: 0 + + sonr: + namespace: testnet + background: true + command: "devbox run devnet" + restart: never + max_restarts: 1 + depends: + - ipfs + + hway-air: + namespace: testnet + background: true + command: "devbox run air" + restart: never + max_restarts: 1 + depends: + - sonr diff --git a/deploy/testnet/devbox.json b/deploy/testnet/devbox.json new file mode 100644 index 000000000..637c1b677 --- /dev/null +++ b/deploy/testnet/devbox.json @@ -0,0 +1,43 @@ +{ + "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.12.0/.schema/devbox.schema.json", + "packages": [ + "go@1.22", + "bun@latest", + "ipfs@latest", + "air@latest", + "templ@latest" + ], + "env": { + "GOPATH": "$HOME/go", + "PATH": "./build:$HOME/go/bin:$PATH", + "CHAIN_ID": "sonr-testnet-1", + "DENOM": "usnr", + "KEYRING": "test", + "MONIKER": "florence", + "BINARY": "sonrd", + "ACC0_NAME": "acc0", + "ACC1_NAME": "acc1", + "ACC0_ADDRESS": "idx1efd63aw40lxf3n4mhf7dzhjkr453axur9vjt6y", + "ACC1_ADDRESS": "idx1hj5fveer5cjtn4wd6wstzugjfdxzl0xpecp0nd", + "ACC0_MNEMONIC": "$(skate get ACC0_MNEMONIC)", + "ACC1_MNEMONIC": "$(skate get ACC1_MNEMONIC)", + "TUNNEL_TOKEN": "$(skate get CLOUDFLARE_TUNNEL_TOKEN)", + "TEMPL_EXPERIMENT": "rawgo", + "R2_CDN_BUCKET": "cdn", + "R2_PKL_BUCKET": "pkljar" + }, + "shell": { + "init_hook": ["export ROOT=$(git rev-parse --show-toplevel)"], + "scripts": { + "start:testnet": ["make sh-testnet"], + "start:ipfs": ["sh scripts/setup_ipfs.sh"], + "start:air": ["air"], + "start:gex": ["go install github.com/cosmos/gex@latest", "gex"], + "gen:pkl": ["make gen-pkl"], + "gen:templ": ["make gen-templ"], + "buf-push": [ + "cd ./proto && bunx buf dep update && bunx buf build && bunx buf push" + ] + } + } +} diff --git a/process-compose.yaml b/deploy/testnet/process-compose.yaml similarity index 77% rename from process-compose.yaml rename to deploy/testnet/process-compose.yaml index 40f822b48..bb0f06d2e 100644 --- a/process-compose.yaml +++ b/deploy/testnet/process-compose.yaml @@ -3,7 +3,7 @@ version: "0.6" processes: ipfs: namespace: testnet - command: "sh scripts/setup_ipfs.sh" + command: "devbox run start:ipfs" background: true availability: restart: never @@ -12,7 +12,7 @@ processes: sonr: namespace: testnet background: true - command: "make sh-testnet" + command: "devbox run start:testnet" restart: never max_restarts: 1 depends: diff --git a/devbox.json b/devbox.json index e767e1d03..bc31be2f9 100644 --- a/devbox.json +++ b/devbox.json @@ -1,42 +1,17 @@ { "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.12.0/.schema/devbox.schema.json", - "packages": [ - "go@1.22", - "bun@latest", - "ipfs@latest", - "air@latest", - "templ@latest" - ], + "packages": ["go@1.22", "bun@latest", "ipfs@latest", "templ@latest"], "env": { "GOPATH": "$HOME/go", "PATH": "./build:$HOME/go/bin:$PATH", - "CHAIN_ID": "sonr-testnet-1", - "DENOM": "usnr", - "KEYRING": "test", - "MONIKER": "florence", - "BINARY": "sonrd", - "ACC0_NAME": "acc0", - "ACC1_NAME": "acc1", - "ACC0_ADDRESS": "idx1efd63aw40lxf3n4mhf7dzhjkr453axur9vjt6y", - "ACC1_ADDRESS": "idx1hj5fveer5cjtn4wd6wstzugjfdxzl0xpecp0nd", - "ACC0_MNEMONIC": "$(skate get ACC0_MNEMONIC)", - "ACC1_MNEMONIC": "$(skate get ACC1_MNEMONIC)", - "TUNNEL_TOKEN": "$(skate get CLOUDFLARE_TUNNEL_TOKEN)", - "TEMPL_EXPERIMENT": "rawgo", - "R2_CDN_BUCKET": "cdn", - "R2_PKL_BUCKET": "pkljar" + "TEMPL_EXPERIMENT": "rawgo" }, "shell": { + "init_hook": ["./scripts/init_env.sh"], "scripts": { - "gen:pkl": [ - "make gen-pkl" - ], - "gen:templ": [ - "make gen-templ" - ], - "buf-push": [ - "cd ./proto && bunx buf dep update && bunx buf build && bunx buf push" - ] + "start-local": ["cd deploy/local && devbox services up"], + "start-testnet": ["cd deploy/testnet && devbox services up"], + "start-gex": ["go install github.com/cosmos/gex@latest", "gex"] } } } diff --git a/devbox.lock b/devbox.lock index c2759642a..d498be17a 100644 --- a/devbox.lock +++ b/devbox.lock @@ -1,54 +1,6 @@ { "lockfile_version": "1", "packages": { - "air@latest": { - "last_modified": "2024-11-16T04:25:12Z", - "resolved": "github:NixOS/nixpkgs/34a626458d686f1b58139620a8b2793e9e123bba#air", - "source": "devbox-search", - "version": "1.61.1", - "systems": { - "aarch64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/0s90vbnmsyyixs0991md21pbrw8babfb-air-1.61.1", - "default": true - } - ], - "store_path": "/nix/store/0s90vbnmsyyixs0991md21pbrw8babfb-air-1.61.1" - }, - "aarch64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/8mpw2asxs297v26fxqy2y1bq438f344l-air-1.61.1", - "default": true - } - ], - "store_path": "/nix/store/8mpw2asxs297v26fxqy2y1bq438f344l-air-1.61.1" - }, - "x86_64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/abminkf7ldqf9vm14xx5wvsrdx3wrvy6-air-1.61.1", - "default": true - } - ], - "store_path": "/nix/store/abminkf7ldqf9vm14xx5wvsrdx3wrvy6-air-1.61.1" - }, - "x86_64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/ajx8v5rbbvglncb97yybg3x9kn95gfrm-air-1.61.1", - "default": true - } - ], - "store_path": "/nix/store/ajx8v5rbbvglncb97yybg3x9kn95gfrm-air-1.61.1" - } - } - }, "bun@latest": { "last_modified": "2024-10-23T04:36:58Z", "resolved": "github:NixOS/nixpkgs/dfffb2e7a52d29a0ef8e21ec8a0f30487b227f1a#bun", @@ -149,17 +101,7 @@ "last_modified": "2023-02-24T09:01:09Z", "resolved": "github:NixOS/nixpkgs/7d0ed7f2e5aea07ab22ccb338d27fbe347ed2f11#ipfs", "source": "devbox-search", - "version": "0.17.0", - "systems": { - "aarch64-darwin": { - "outputs": [ - { - "path": "/nix/store/1azparhiwjzxgpkswpqnapzw0bfb7vl7-kubo-0.17.0", - "default": true - } - ] - } - } + "version": "0.17.0" }, "templ@latest": { "last_modified": "2024-10-13T23:44:06Z", diff --git a/pkg/services/credentials/scripts_templ.go b/pkg/services/credentials/scripts_templ.go index a12f1871e..a6646451f 100644 --- a/pkg/services/credentials/scripts_templ.go +++ b/pkg/services/credentials/scripts_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package credentials //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/services/payments/scripts_templ.go b/pkg/services/payments/scripts_templ.go index 63f0fa290..d75fc7134 100644 --- a/pkg/services/payments/scripts_templ.go +++ b/pkg/services/payments/scripts_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package payments diff --git a/pkg/services/storage/scripts_templ.go b/pkg/services/storage/scripts_templ.go index aeed45ca9..b413849b6 100644 --- a/pkg/services/storage/scripts_templ.go +++ b/pkg/services/storage/scripts_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package storage //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/auth/authorize_templ.go b/pkg/webapp/components/auth/authorize_templ.go index 961b0b757..ad2c23bf7 100644 --- a/pkg/webapp/components/auth/authorize_templ.go +++ b/pkg/webapp/components/auth/authorize_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package auth //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/auth/create_credential_templ.go b/pkg/webapp/components/auth/create_credential_templ.go index eea1973f6..11f0103ea 100644 --- a/pkg/webapp/components/auth/create_credential_templ.go +++ b/pkg/webapp/components/auth/create_credential_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package auth //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/auth/get_credential_templ.go b/pkg/webapp/components/auth/get_credential_templ.go index 75368de9a..bfb597672 100644 --- a/pkg/webapp/components/auth/get_credential_templ.go +++ b/pkg/webapp/components/auth/get_credential_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package auth //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/auth/login_templ.go b/pkg/webapp/components/auth/login_templ.go index 6951af203..f7251cb92 100644 --- a/pkg/webapp/components/auth/login_templ.go +++ b/pkg/webapp/components/auth/login_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package auth //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/auth/register_start_templ.go b/pkg/webapp/components/auth/register_start_templ.go index 717370e4d..35ee1d9f5 100644 --- a/pkg/webapp/components/auth/register_start_templ.go +++ b/pkg/webapp/components/auth/register_start_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package auth //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/auth/register_templ.go b/pkg/webapp/components/auth/register_templ.go index 17449b7c6..231cc7bcf 100644 --- a/pkg/webapp/components/auth/register_templ.go +++ b/pkg/webapp/components/auth/register_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package auth //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/landing/arch_templ.go b/pkg/webapp/components/landing/arch_templ.go index e5e8a1b2e..81225c9f9 100644 --- a/pkg/webapp/components/landing/arch_templ.go +++ b/pkg/webapp/components/landing/arch_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/landing/cta_templ.go b/pkg/webapp/components/landing/cta_templ.go index a3a12ab86..8414bbef0 100644 --- a/pkg/webapp/components/landing/cta_templ.go +++ b/pkg/webapp/components/landing/cta_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/landing/footer_templ.go b/pkg/webapp/components/landing/footer_templ.go index c3000b9d2..2621849e4 100644 --- a/pkg/webapp/components/landing/footer_templ.go +++ b/pkg/webapp/components/landing/footer_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package landing diff --git a/pkg/webapp/components/landing/header_templ.go b/pkg/webapp/components/landing/header_templ.go index bd4e740f3..2a948dbb9 100644 --- a/pkg/webapp/components/landing/header_templ.go +++ b/pkg/webapp/components/landing/header_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/landing/hero_templ.go b/pkg/webapp/components/landing/hero_templ.go index fb3bd7f42..d3cd16ae9 100644 --- a/pkg/webapp/components/landing/hero_templ.go +++ b/pkg/webapp/components/landing/hero_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/landing/highlights_templ.go b/pkg/webapp/components/landing/highlights_templ.go index 2d3b62e7d..753f3be5f 100644 --- a/pkg/webapp/components/landing/highlights_templ.go +++ b/pkg/webapp/components/landing/highlights_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/landing/lowlights_templ.go b/pkg/webapp/components/landing/lowlights_templ.go index ad8b1b5a7..1bd2e3dfb 100644 --- a/pkg/webapp/components/landing/lowlights_templ.go +++ b/pkg/webapp/components/landing/lowlights_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/landing/mission_templ.go b/pkg/webapp/components/landing/mission_templ.go index 33347e3c0..2fccf7548 100644 --- a/pkg/webapp/components/landing/mission_templ.go +++ b/pkg/webapp/components/landing/mission_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/badges_templ.go b/pkg/webapp/components/ui/badges_templ.go index 606c77c21..ffc481bfa 100644 --- a/pkg/webapp/components/ui/badges_templ.go +++ b/pkg/webapp/components/ui/badges_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/buttons_templ.go b/pkg/webapp/components/ui/buttons_templ.go index 899f2633b..e53fd6e65 100644 --- a/pkg/webapp/components/ui/buttons_templ.go +++ b/pkg/webapp/components/ui/buttons_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/cards_templ.go b/pkg/webapp/components/ui/cards_templ.go index fdae71090..ca641cded 100644 --- a/pkg/webapp/components/ui/cards_templ.go +++ b/pkg/webapp/components/ui/cards_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/icon_templ.go b/pkg/webapp/components/ui/icon_templ.go index c19814e20..616b2de8c 100644 --- a/pkg/webapp/components/ui/icon_templ.go +++ b/pkg/webapp/components/ui/icon_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/layout_templ.go b/pkg/webapp/components/ui/layout_templ.go index 093fe9b8b..8aa496d19 100644 --- a/pkg/webapp/components/ui/layout_templ.go +++ b/pkg/webapp/components/ui/layout_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/panels_templ.go b/pkg/webapp/components/ui/panels_templ.go index 439d6a52e..a7df7e25c 100644 --- a/pkg/webapp/components/ui/panels_templ.go +++ b/pkg/webapp/components/ui/panels_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/scripts_templ.go b/pkg/webapp/components/ui/scripts_templ.go index 71d6f3d5e..86e24b9d6 100644 --- a/pkg/webapp/components/ui/scripts_templ.go +++ b/pkg/webapp/components/ui/scripts_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/sizes_templ.go b/pkg/webapp/components/ui/sizes_templ.go index 09a5f47c3..52047ba52 100644 --- a/pkg/webapp/components/ui/sizes_templ.go +++ b/pkg/webapp/components/ui/sizes_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/typography_templ.go b/pkg/webapp/components/ui/typography_templ.go index fc49235a8..c0ac9d207 100644 --- a/pkg/webapp/components/ui/typography_templ.go +++ b/pkg/webapp/components/ui/typography_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/pages/auth_templ.go b/pkg/webapp/pages/auth_templ.go index 1e9cc4ff4..79fcf26db 100644 --- a/pkg/webapp/pages/auth_templ.go +++ b/pkg/webapp/pages/auth_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package pages //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/pages/dashboard_templ.go b/pkg/webapp/pages/dashboard_templ.go index 4708ea891..ed2ca5ca4 100644 --- a/pkg/webapp/pages/dashboard_templ.go +++ b/pkg/webapp/pages/dashboard_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package pages //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/pages/landing_templ.go b/pkg/webapp/pages/landing_templ.go index 912b46b8f..4efb12569 100644 --- a/pkg/webapp/pages/landing_templ.go +++ b/pkg/webapp/pages/landing_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package pages diff --git a/pkl/README.md b/pkl/README.md deleted file mode 100644 index e32b62034..000000000 --- a/pkl/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# pkl - -This is a project to generate a language-agnostic, type-safe, and idiomatic -Go code from a [Pkl](https://pkl-lang.org) file. diff --git a/scripts/init_env.sh b/scripts/init_env.sh old mode 100644 new mode 100755 index f1f641af1..236e666d2 --- a/scripts/init_env.sh +++ b/scripts/init_env.sh @@ -1 +1,27 @@ -#!/usr/bin/env bash +#!/bin/bash + +go install github.com/cosmos/gex@latest + +rm -rf ~/.ipfs + +# Initialize IPFS +ipfs init + +# 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"]} +]' + +# Make sure ipfs is publicly accessible +ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]' diff --git a/scripts/setup_ipfs.sh b/scripts/setup_ipfs.sh deleted file mode 100755 index b98c18d5a..000000000 --- a/scripts/setup_ipfs.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash - -rm -rf ~/.ipfs - -# Initialize IPFS -ipfs init - -# 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"]} -]' - -# Make sure ipfs is publicly accessible -ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]' - -ipfs daemon diff --git a/slumber.yml b/slumber.yml deleted file mode 100644 index 158c1a8b5..000000000 --- a/slumber.yml +++ /dev/null @@ -1,45 +0,0 @@ -# For basic usage info, see: -# https://slumber.lucaspickering.me/book/getting_started.html -# For all collection options, see: -# https://slumber.lucaspickering.me/book/api/request_collection/index.html - -# Profiles are groups of data you can easily switch between. A common usage is -# to define profiles for various environments of a REST service -# slumber.yml -profiles: - local: - data: - host: http://localhost:1317 - production: - data: - host: https://api.sonr.id - -requests: - did: !folder - name: Params - requests: - did_params: !request - method: GET - url: "{{host}}/did/v1/params" - macaroon_params: !request - method: GET - url: "{{host}}/macaroon/v1/params" - service_params: !request - method: GET - url: "{{host}}/service/v1/params" - vault_params: !request - method: GET - url: "{{host}}/vault/v1/params" - - vault: !folder - name: Vault - requests: - vault_allocate: !request - method: GET - url: "{{host}}/vault/v1/allocate" - vault_schema: !request - method: GET - url: "{{host}}/vault/v1/schema" - vault_sync: !request - method: GET - url: "{{host}}/vault/v1/sync" diff --git a/web/libs/noble-client b/web/libs/noble-client deleted file mode 160000 index 712a041f4..000000000 --- a/web/libs/noble-client +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 712a041f4fa040be8c53ca0c701f961c59a22233 diff --git a/web/libs/osmosis-client b/web/libs/osmosis-client deleted file mode 160000 index e9529062b..000000000 --- a/web/libs/osmosis-client +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e9529062bc943894e14b67a48a665b0f7e4aabb4 diff --git a/web/libs/sonr-client b/web/libs/sonr-client deleted file mode 160000 index d002aa61f..000000000 --- a/web/libs/sonr-client +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d002aa61f0fed83c3227c146d329b58927975b5d diff --git a/web/workers/noble-client/.gitignore b/web/workers/noble-client/.gitignore new file mode 100644 index 000000000..90cfa7c2d --- /dev/null +++ b/web/workers/noble-client/.gitignore @@ -0,0 +1,5 @@ +node_modules +.DS_Store +.env +dist +out diff --git a/web/workers/noble-client/README.md b/web/workers/noble-client/README.md new file mode 100644 index 000000000..e83bd8757 --- /dev/null +++ b/web/workers/noble-client/README.md @@ -0,0 +1,9 @@ +# `noble-client` + +This is a Cloudflare Workers Durable Object that can be deployed to Cloudflare's edge network. + +It uses `noble-es` to provide a simple interface to interact with the Sonr network. + +## Usage + +### Deploying to Cloudflare diff --git a/web/workers/noble-client/package.json b/web/workers/noble-client/package.json new file mode 100644 index 000000000..b8b7b285d --- /dev/null +++ b/web/workers/noble-client/package.json @@ -0,0 +1,16 @@ +{ + "name": "noble-client", + "version": "0.0.0", + "private": true, + "scripts": { + "deploy": "wrangler deploy", + "dev": "wrangler dev", + "start": "wrangler dev" + }, + "devDependencies": { + "wrangler": "^3.60.3" + }, + "dependencies": { + "sonr-es": "^0.5.3" + } +} diff --git a/web/workers/noble-client/src/index.js b/web/workers/noble-client/src/index.js new file mode 100644 index 000000000..2ae2b739e --- /dev/null +++ b/web/workers/noble-client/src/index.js @@ -0,0 +1,45 @@ +export * from "./stub.js"; + +/** + * Welcome to Cloudflare Workers! This is your first Durable Objects application. + * + * - Run `npm run dev` in your terminal to start a development server + * - Open a browser tab at http://localhost:8787/ to see your Durable Object in action + * - Run `npm run deploy` to publish your application + * + * Learn more at https://developers.cloudflare.com/durable-objects + */ + +/** + * Env provides a mechanism to reference bindings declared in wrangler.toml within JavaScript + * + * @typedef {Object} Env + * @property {DurableObjectNamespace} NOBLE_DURABLE_CLIENT - The Durable Object namespace binding + */ + + +export default { + /** + * This is the standard fetch handler for a Cloudflare Worker + * + * @param {Request} request - The request submitted to the Worker from the client + * @param {Env} env - The interface to reference bindings declared in wrangler.toml + * @param {ExecutionContext} ctx - The execution context of the Worker + * @returns {Promise} The response to be sent back to the client + */ + async fetch(request, env, ctx) { + // We will create a `DurableObjectId` using the pathname from the Worker request + // This id refers to a unique instance of our 'MyDurableObject' class above + let id = env.NOBLE_DURABLE_CLIENT.idFromName(new URL(request.url).pathname); + + // This stub creates a communication channel with the Durable Object instance + // The Durable Object constructor will be invoked upon the first call for a given id + let stub = env.NOBLE_DURABLE_CLIENT.get(id); + + // We call the `sayHello()` RPC method on the stub to invoke the method on the remote + // Durable Object instance + let greeting = await stub.sayHello("world"); + + return new Response(greeting); + }, +}; diff --git a/web/workers/noble-client/src/stub.js b/web/workers/noble-client/src/stub.js new file mode 100644 index 000000000..10d27bb12 --- /dev/null +++ b/web/workers/noble-client/src/stub.js @@ -0,0 +1,26 @@ +import { DurableObject } from "cloudflare:workers"; + +/** A Durable Object's behavior is defined in an exported Javascript class */ +export class NobleDurableClient extends DurableObject { + /** + * The constructor is invoked once upon creation of the Durable Object, i.e. the first call to + * `DurableObjectStub::get` for a given identifier (no-op constructors can be omitted) + * + * @param {DurableObjectState} ctx - The interface for interacting with Durable Object state + * @param {Env} env - The interface to reference bindings declared in wrangler.toml + */ + constructor(ctx, env) { + super(ctx, env); + } + + /** + * The Durable Object exposes an RPC method sayHello which will be invoked when when a Durable + * Object instance receives a request from a Worker via the same method invocation on the stub + * + * @param {string} name - The name provided to a Durable Object instance from a Worker + * @returns {Promise} The greeting to be sent back to the Worker + */ + async sayHello(name) { + return `Hello, ${name}!`; + } +} diff --git a/web/workers/noble-client/wrangler.toml b/web/workers/noble-client/wrangler.toml new file mode 100644 index 000000000..8f4a4020a --- /dev/null +++ b/web/workers/noble-client/wrangler.toml @@ -0,0 +1,113 @@ +#:schema node_modules/wrangler/config-schema.json +name = "noble-client" +main = "src/index.js" +compatibility_date = "2024-11-12" + +# Workers Logs +# Docs: https://developers.cloudflare.com/workers/observability/logs/workers-logs/ +# Configuration: https://developers.cloudflare.com/workers/observability/logs/workers-logs/#enable-workers-logs +[observability] +enabled = true + +# Automatically place your workloads in an optimal location to minimize latency. +# If you are running back-end logic in a Worker, running it closer to your back-end infrastructure +# rather than the end user may result in better performance. +# Docs: https://developers.cloudflare.com/workers/configuration/smart-placement/#smart-placement +# [placement] +# mode = "smart" + +# Variable bindings. These are arbitrary, plaintext strings (similar to environment variables) +# Docs: +# - https://developers.cloudflare.com/workers/wrangler/configuration/#environment-variables +# Note: Use secrets to store sensitive data. +# - https://developers.cloudflare.com/workers/configuration/secrets/ +# [vars] +# MY_VARIABLE = "production_value" + +# Bind the Workers AI model catalog. Run machine learning models, powered by serverless GPUs, on Cloudflare’s global network +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#workers-ai +# [ai] +# binding = "AI" + +# Bind an Analytics Engine dataset. Use Analytics Engine to write analytics within your Pages Function. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#analytics-engine-datasets +# [[analytics_engine_datasets]] +# binding = "MY_DATASET" + +# Bind a headless browser instance running on Cloudflare's global network. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#browser-rendering +# [browser] +# binding = "MY_BROWSER" + +# Bind a D1 database. D1 is Cloudflare’s native serverless SQL database. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#d1-databases +# [[d1_databases]] +# binding = "MY_DB" +# database_name = "my-database" +# database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + +# Bind a dispatch namespace. Use Workers for Platforms to deploy serverless functions programmatically on behalf of your customers. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#dispatch-namespace-bindings-workers-for-platforms +# [[dispatch_namespaces]] +# binding = "MY_DISPATCHER" +# namespace = "my-namespace" + +# Bind a Durable Object. Durable objects are a scale-to-zero compute primitive based on the actor model. +# Durable Objects can live for as long as needed. Use these when you need a long-running "server", such as in realtime apps. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#durable-objects +[[durable_objects.bindings]] +name = "NOBLE_DURABLE_CLIENT" +class_name = "NobleDurableClient" + +# Durable Object migrations. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#migrations +[[migrations]] +tag = "v1" +new_classes = ["NobleDurableClient"] + +# Bind a Hyperdrive configuration. Use to accelerate access to your existing databases from Cloudflare Workers. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#hyperdrive +# [[hyperdrive]] +# binding = "MY_HYPERDRIVE" +# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + +# Bind a KV Namespace. Use KV as persistent storage for small key-value pairs. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#kv-namespaces +# [[kv_namespaces]] +# binding = "MY_KV_NAMESPACE" +# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + +# Bind an mTLS certificate. Use to present a client certificate when communicating with another service. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#mtls-certificates +# [[mtls_certificates]] +# binding = "MY_CERTIFICATE" +# certificate_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + +# Bind a Queue producer. Use this binding to schedule an arbitrary task that may be processed later by a Queue consumer. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues +# [[queues.producers]] +# binding = "MY_QUEUE" +# queue = "my-queue" + +# Bind a Queue consumer. Queue Consumers can retrieve tasks scheduled by Producers to act on them. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues +# [[queues.consumers]] +# queue = "my-queue" + +# Bind an R2 Bucket. Use R2 to store arbitrarily large blobs of data, such as files. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#r2-buckets +# [[r2_buckets]] +# binding = "MY_BUCKET" +# bucket_name = "my-bucket" + +# Bind another Worker service. Use this binding to call another Worker without network overhead. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#service-bindings +# [[services]] +# binding = "MY_SERVICE" +# service = "my-service" + +# Bind a Vectorize index. Use to store and query vector embeddings for semantic search, classification and other vector search use-cases. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#vectorize-indexes +# [[vectorize]] +# binding = "MY_INDEX" +# index_name = "my-index" diff --git a/web/workers/osmosis-client/.gitignore b/web/workers/osmosis-client/.gitignore new file mode 100644 index 000000000..90cfa7c2d --- /dev/null +++ b/web/workers/osmosis-client/.gitignore @@ -0,0 +1,5 @@ +node_modules +.DS_Store +.env +dist +out diff --git a/web/workers/osmosis-client/README.md b/web/workers/osmosis-client/README.md new file mode 100644 index 000000000..c54afa25e --- /dev/null +++ b/web/workers/osmosis-client/README.md @@ -0,0 +1,10 @@ +# `osmosis-client` + +This is a Cloudflare Workers Durable Object that can be deployed to Cloudflare's edge network. + +It uses `osmosis-es` to provide a simple interface to interact with the Sonr network. + +## Usage + +### Deploying to Cloudflare + diff --git a/web/workers/osmosis-client/package.json b/web/workers/osmosis-client/package.json new file mode 100644 index 000000000..4dabb65ab --- /dev/null +++ b/web/workers/osmosis-client/package.json @@ -0,0 +1,16 @@ +{ + "name": "sonr-client", + "version": "0.0.0", + "private": true, + "scripts": { + "deploy": "wrangler deploy", + "dev": "wrangler dev", + "start": "wrangler dev" + }, + "devDependencies": { + "wrangler": "^3.60.3" + }, + "dependencies": { + "sonr-es": "^0.5.3" + } +} diff --git a/web/workers/osmosis-client/src/index.js b/web/workers/osmosis-client/src/index.js new file mode 100644 index 000000000..940c612d0 --- /dev/null +++ b/web/workers/osmosis-client/src/index.js @@ -0,0 +1,45 @@ +export * from "./stub.js"; + +/** + * Welcome to Cloudflare Workers! This is your first Durable Objects application. + * + * - Run `npm run dev` in your terminal to start a development server + * - Open a browser tab at http://localhost:8787/ to see your Durable Object in action + * - Run `npm run deploy` to publish your application + * + * Learn more at https://developers.cloudflare.com/durable-objects + */ + +/** + * Env provides a mechanism to reference bindings declared in wrangler.toml within JavaScript + * + * @typedef {Object} Env + * @property {DurableObjectNamespace} OSMOSIS_DURABLE_CLIENT - The Durable Object namespace binding + */ + + +export default { + /** + * This is the standard fetch handler for a Cloudflare Worker + * + * @param {Request} request - The request submitted to the Worker from the client + * @param {Env} env - The interface to reference bindings declared in wrangler.toml + * @param {ExecutionContext} ctx - The execution context of the Worker + * @returns {Promise} The response to be sent back to the client + */ + async fetch(request, env, ctx) { + // We will create a `DurableObjectId` using the pathname from the Worker request + // This id refers to a unique instance of our 'MyDurableObject' class above + let id = env.OSMOSIS_DURABLE_CLIENT.idFromName(new URL(request.url).pathname); + + // This stub creates a communication channel with the Durable Object instance + // The Durable Object constructor will be invoked upon the first call for a given id + let stub = env.OSMOSIS_DURABLE_CLIENT.get(id); + + // We call the `sayHello()` RPC method on the stub to invoke the method on the remote + // Durable Object instance + let greeting = await stub.sayHello("world"); + + return new Response(greeting); + }, +}; diff --git a/web/workers/osmosis-client/src/stub.js b/web/workers/osmosis-client/src/stub.js new file mode 100644 index 000000000..f2afbbace --- /dev/null +++ b/web/workers/osmosis-client/src/stub.js @@ -0,0 +1,26 @@ +import { DurableObject } from "cloudflare:workers"; + +/** A Durable Object's behavior is defined in an exported Javascript class */ +export class OsmosisDurableClient extends DurableObject { + /** + * The constructor is invoked once upon creation of the Durable Object, i.e. the first call to + * `DurableObjectStub::get` for a given identifier (no-op constructors can be omitted) + * + * @param {DurableObjectState} ctx - The interface for interacting with Durable Object state + * @param {Env} env - The interface to reference bindings declared in wrangler.toml + */ + constructor(ctx, env) { + super(ctx, env); + } + + /** + * The Durable Object exposes an RPC method sayHello which will be invoked when when a Durable + * Object instance receives a request from a Worker via the same method invocation on the stub + * + * @param {string} name - The name provided to a Durable Object instance from a Worker + * @returns {Promise} The greeting to be sent back to the Worker + */ + async sayHello(name) { + return `Hello, ${name}!`; + } +} diff --git a/web/workers/osmosis-client/wrangler.toml b/web/workers/osmosis-client/wrangler.toml new file mode 100644 index 000000000..e9a92ea58 --- /dev/null +++ b/web/workers/osmosis-client/wrangler.toml @@ -0,0 +1,113 @@ +#:schema node_modules/wrangler/config-schema.json +name = "osmosis-client" +main = "src/index.js" +compatibility_date = "2024-11-12" + +# Workers Logs +# Docs: https://developers.cloudflare.com/workers/observability/logs/workers-logs/ +# Configuration: https://developers.cloudflare.com/workers/observability/logs/workers-logs/#enable-workers-logs +[observability] +enabled = true + +# Automatically place your workloads in an optimal location to minimize latency. +# If you are running back-end logic in a Worker, running it closer to your back-end infrastructure +# rather than the end user may result in better performance. +# Docs: https://developers.cloudflare.com/workers/configuration/smart-placement/#smart-placement +# [placement] +# mode = "smart" + +# Variable bindings. These are arbitrary, plaintext strings (similar to environment variables) +# Docs: +# - https://developers.cloudflare.com/workers/wrangler/configuration/#environment-variables +# Note: Use secrets to store sensitive data. +# - https://developers.cloudflare.com/workers/configuration/secrets/ +# [vars] +# MY_VARIABLE = "production_value" + +# Bind the Workers AI model catalog. Run machine learning models, powered by serverless GPUs, on Cloudflare’s global network +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#workers-ai +# [ai] +# binding = "AI" + +# Bind an Analytics Engine dataset. Use Analytics Engine to write analytics within your Pages Function. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#analytics-engine-datasets +# [[analytics_engine_datasets]] +# binding = "MY_DATASET" + +# Bind a headless browser instance running on Cloudflare's global network. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#browser-rendering +# [browser] +# binding = "MY_BROWSER" + +# Bind a D1 database. D1 is Cloudflare’s native serverless SQL database. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#d1-databases +# [[d1_databases]] +# binding = "MY_DB" +# database_name = "my-database" +# database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + +# Bind a dispatch namespace. Use Workers for Platforms to deploy serverless functions programmatically on behalf of your customers. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#dispatch-namespace-bindings-workers-for-platforms +# [[dispatch_namespaces]] +# binding = "MY_DISPATCHER" +# namespace = "my-namespace" + +# Bind a Durable Object. Durable objects are a scale-to-zero compute primitive based on the actor model. +# Durable Objects can live for as long as needed. Use these when you need a long-running "server", such as in realtime apps. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#durable-objects +[[durable_objects.bindings]] +name = "OSMOSIS_DURABLE_CLIENT" +class_name = "OsmosisDurableClient" + +# Durable Object migrations. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#migrations +[[migrations]] +tag = "v1" +new_classes = ["OsmosisDurableClient"] + +# Bind a Hyperdrive configuration. Use to accelerate access to your existing databases from Cloudflare Workers. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#hyperdrive +# [[hyperdrive]] +# binding = "MY_HYPERDRIVE" +# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + +# Bind a KV Namespace. Use KV as persistent storage for small key-value pairs. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#kv-namespaces +# [[kv_namespaces]] +# binding = "MY_KV_NAMESPACE" +# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + +# Bind an mTLS certificate. Use to present a client certificate when communicating with another service. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#mtls-certificates +# [[mtls_certificates]] +# binding = "MY_CERTIFICATE" +# certificate_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + +# Bind a Queue producer. Use this binding to schedule an arbitrary task that may be processed later by a Queue consumer. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues +# [[queues.producers]] +# binding = "MY_QUEUE" +# queue = "my-queue" + +# Bind a Queue consumer. Queue Consumers can retrieve tasks scheduled by Producers to act on them. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues +# [[queues.consumers]] +# queue = "my-queue" + +# Bind an R2 Bucket. Use R2 to store arbitrarily large blobs of data, such as files. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#r2-buckets +# [[r2_buckets]] +# binding = "MY_BUCKET" +# bucket_name = "my-bucket" + +# Bind another Worker service. Use this binding to call another Worker without network overhead. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#service-bindings +# [[services]] +# binding = "MY_SERVICE" +# service = "my-service" + +# Bind a Vectorize index. Use to store and query vector embeddings for semantic search, classification and other vector search use-cases. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#vectorize-indexes +# [[vectorize]] +# binding = "MY_INDEX" +# index_name = "my-index" diff --git a/web/workers/sonr-client/.gitignore b/web/workers/sonr-client/.gitignore new file mode 100644 index 000000000..90cfa7c2d --- /dev/null +++ b/web/workers/sonr-client/.gitignore @@ -0,0 +1,5 @@ +node_modules +.DS_Store +.env +dist +out diff --git a/web/workers/sonr-client/README.md b/web/workers/sonr-client/README.md new file mode 100644 index 000000000..40b5fb2c4 --- /dev/null +++ b/web/workers/sonr-client/README.md @@ -0,0 +1,10 @@ +# `sonr-client` + +This is a Cloudflare Workers Durable Object that can be deployed to Cloudflare's edge network. + +It uses `sonr-es` to provide a simple interface to interact with the Sonr network. + +## Usage + +### Deploying to Cloudflare + diff --git a/web/workers/sonr-client/bun.lockb b/web/workers/sonr-client/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..eab8f6254d966e5eefcf09ad26d818e7ffc1ad4b GIT binary patch literal 106594 zcmeFa2T&Eu)&{zTt%78Ul7kWjk))tx6eTH&BqisZa}>z}f`|x`vw#Ev$%-VAU;q(O z0RI~oRp8meIdQEpv&+L89;b1%D=Hh(F*vkHp znY}x!v77xKaPZqYnAn(G*_!d2J2=}Jx$?UU?!m)gFp<=Yw}P`Z0td=Q=_U_gE@yQS z#CHyeIa-KGu~QMMKj=;00a{@&K&?x|NdL0XiCiYJesV_AU;#Mi>(-S67fOjEk!&KNxtJX3#n4 z&(78sR%6^i@}M4QZ*J`1i7_&9aE3b8R<2g?d=+R9^JXawOVAHg!C>sH?4TQrshPPO zL^pdAXD>%r2WKNwD^JkY!P3YDgpU~o7a!)q#M!~c#lrisIFD@rf-VKB z0o1JYUFJ0V&-mU@9HASyK(*y4vF|S#^HWYhV7lrj7&|foE?qq zy}-IV5-4Ifb$^i;Ksb41PF$DU;?f_4~Lcf8`mKel;QOd7uY~gP=;~Y0tEjA z3Le_XGYdedO92p`-whDv&j>Vv@uUcDv_HFJV_euB#$Z5-0>O~`V``ub^CJon=Hsmp z1_P#2pn&j(E*GeWy5XQT%#*IjM*gI6$PEy#V-}(t@#q4C;|Gb85}b$YPn_6B{+9v5 zxZpGpuy(5u6WK*zmLS#76sRP=x@D`r5q}jx7{^b5F#kp_{H{jEwr26?Hu7iZ=HhAurmKkqnD1cl zA@f5K*I!d3SFjnecR|(zWS%>lf!m3@8D>ypBfe(~TfAGTy< z_{40S`8|?dz9Q%$^~v<1!YtbQWgC(j1KanFyJ9Vd8*E2pISMb-Br=d3F1Ej9b8xBu~-Ojl8tr+L3e8yGm-Yqf9R8 zmZ#C4)|A1gT)ysWtzrUr->>Eu2d97FBzx$sy*j;azf|<-iSVq3`7Q;Uq-Ol-9BTTt z`vU_xEn3B-`=oeBDW?lonJK-^+jxYy{05I-NU(YB)AQ_F{7kJR|j+T9IQDV7{6 z0-wn%PQ)@RTDg>+9qw)Ol+2HRE!^W0RcWZwpta)a=llDtp z33((I=2RlnRTrXd%6h5XF?3?4{6@rcL1rHwnunZk_7d^4no<=L-B(dqr*AeGy}^Ch zckstG)4GiDg@}|_T3Aiurp`Wzl9G9$FLg4!Mb z#IJXaRkAU&QU}gBl&M;z`K)uV+Mf!K&z$O3BmS89gE!cWeLnZC!i~Yv6LF^XUM@$l zo}aUCu&jR-_S4Z}GW-_L=y>6o_Jo#mK<>@7>7A^GvhG?!Owqn-oxLs(*Za>MC+s4a z}2sZyDaK=q^ zPwIy^!Mn$V&yznYliUD~WE93Hi(c$wYq*3HOn7M6?;2OR|x)j9d+S{pHKk+e7kk z{+|a=sXun78Ia&T=-(}MORV`JOgy6s)~?A?j0+9NRp;v7zV{{Pkd*h>{k8fr%0;%a4!PFm?X zOLL`=&?-!(mAF4XC-t0*(ZgW163YWGqxm zynDHYcU&FIe0#As(Nz0&*9$G8GYTE!m|H(eJqrI+fhYL6F) z?6UhL`E-~mBj%0c*Wm-@LD!O>m_3M=VuoO;SEB zNlfOw3%~rHT^J?LQodc-;TWPUvvFeM&vK{(T$fvTBle>^{jocw)P~_INE+y?!g*;J-p)X0tBRlVo_>gor)j z!W-#jN4~nwZCfM+Ns;t1SZoY5a_*qsI)cIJb>q zUqu^bD!9(q{7(mD43T@nNU*ml*IStj2}KfvlE#g6qJ$CL#(TelGkGt ze#t)gg{%k2Jm)@~`;6hU+mD}3M^?Jb)J?CHnLXnbKU14+?e6Baev#>v^i{$LrT5Qo zCw0<0+0_skoMG9|-u&vS$?i|xC-)2GfX9Mu8F>BiF9Un=Kv>ub4t)4w6Nc~~gSKD` z9Eb%-0S>Si-;^PIe9#e9z=vf5aDdk%n=*v|6Y#;-Fc8TH)Yyz6{43xCn!nZl&j7wI z%Kv73!#0S2Mc@!Tvi*r4>^m_?KmJY!;d=u<%pbx-aI^f!fPWgthnidElYgprVQb~27DR7N3Q!;`E;P;CjlSwfYg@r=MDG@DE~-Yf7c15 z-2)VVv#~>Mgiit%3@P9r<{s7|d4O&H$`HOX;Dc8ifk+u%hs_w${tDpB;rb7`TjjR_ zK6q91=lX4y3*$rle+PUK93Nc|KmU~>d>+CLKJ<;${S^;6hqToLeDKH}h{TQ{((eC4 zgkKK$;8nn%{Qr~rgAX41!K;UV`TxKC{bxPm|2*I;0X{sB)ct4M|5irYrUE{kKbswQ zh!(;h1AKX$fAF4Y(=i}?POxan;P_jK0pXkD_*>z^J|O%&z=!h>&fR}<{l)L(hVaF}%RTT;^Iz9*vw1-HR{{V0Hu%Hak-$wig!OQS%^&jxz`h)ZvOovSw zlK*nRmj!%ShVy5u| z3WI^qkFek1R=jCL{C5LB%s(VT4Wu5H|H_bdyTJn|>_2P^`CE-&9LI;;f8yT;@L~U< zUl`L?{b&A1{9B!WeJKC`dEi#IX+!uD;7c>ue^}n^+=WgMzBS;>0Y1`yr2g*$LE04q zK0l5R*T2mg!k-6x*nj9Bt^u1hgwFwf1OofN+3SwzBmDC?J{;a>rK`1}QR zA%C-RApCm3N7irT8bGbTGlV|}_;CG!+mNZzTqV&jWsp0N0Prt~>u3zY*X=|A-!P z{_hZJp9%Qz`4{@%Z0?~p!XLr$;k_5yR`(AF!H+WF{6+LORQ~=i(mnw20EJ|93q=+MW0h{@?MC^9bJq@Zs~zKb=1nfWMvjI|KM| z{oCwy|Ihe2ShqL+F9QB4;2-8=D{~mh-+jP``9tO(l1Cu-mxl1ySU2(q%g7k|OCs(h z!WU)x_xcS_ZFU?Zd>6on@x%EC$L?0gZzJF<06vntt@8Jkybb<0z~4^)&vI?A|0RI0v5olgxVJZcv;qIzHvAU? zzVL2hQ7Dz{|ey4 z{%@8CeL_S0KgRK48Ogz)27mJh;WP4Wygx+Z{~OxBP9uDCz=!#VYbW%N)c>pD|M3B7 zmjn3Q$^SbPANt>H9ufak2mgKl-Yge(3E`gteCchBzcj#CM)5a$4H5qPbD_+Q^9{}gz6ydD2n03Xg@IR5|1 z_<0QYGJub)f1A}n`mbZ*KM=c z4(cF$cJT5K?*INNUmx({`UCT}6%E9H0pQC3J|W=4W3z_vKLb9TKd=m+JvMs}LHKdt z$3Mon{zKoS@Xsa;;eQ2uFa`dMA28@&48~C_(*xHd^hm&@60y%t=r^N ziefN|z(10=&GrLn=L7g>0Uw!vo6RA@?*e=|l>e>fj|4n?!tn#=9h^HzKmJY!@vjE> z@+kjX9e+iDueuFB{*iw_e{ME**f%78S-^+S-;fIrcpuq}A^b?dS3||W*%%Q1Yrsdp zzeei+E(W9>G1&ZxVP{IPBFxfL)NLtOvin!E!JgiRQ13oQlk zk^LtuBlYm}Um4Pl79?K<_=jcq{D##36&IdE+L-{p94>x%|K4i+xquI*Kp@oI2ac`o zU%mtWNx+AGvEYDx*o-0Z9|L5VKgivRA^fX=Zvyy`3+wRVhfNs5p9OsQ{v1*uce8OI zd^xaq!1y5_?tQnK|LcGcUSa&%zt95yR`d4=@L~Ruco2l~{FNc?cAwgK{@eu`Z#H*O z7vU=dK79WH`@Pw|qxlgyKGcK!o$%x)4DtUM@ZtL#NP&IWYzzn=AKbhkAC}>@-zxts z;49$z5A#O^j?Eb2KOOMl{*eZd;N07)|1rRq1$@|dxc4Lg$7T%iF9=?~K|YMV_l?Mo zt@^J4d@aC-KB4ce^0~q04L<)tK8yk8U^9lqUjX><`zPpkvttM9Bm7mshwmSuZ>WLP z!#00qNIM0vc*E-t+hW17)&7SAJ{*5AcQ6L1u^B`Bw*o%;`{&JYVH8{I|4p<1s4d*|784R;rK9bFn^nk0rCG5@DJkr!@fg}%^1Qb0)rR% z{^Os_pJBi^0sf)yf5Mjq506IM;Aa88!8Z6iz|Bu@8+?7hzqk#4E#QM!cz?eCU<5hb z>iqcy`0)C{>j|#`JT_y<^_KuIU*Y(L;|3mE_3r`r@cxPT-|G7P5b%-sVcf*<&n66s zpA;;fUk4{|AOQVybIfuA^d#62VM9VpLbL2f5(YEzp?(nyd#>M zkwDrW2YmSc5OUz!fz-qDUm4QQ5%Bo|A6~b;e?|C@a|k~b@R9W!Hi7r?%^1QTK=mKF z23z5ifz2;mzmajfSq;R$;(zdw`oD_-X%`9j$oo^c2iofRUj}@05dUW5M&d&J>tFcy z_kZx*R_`ClfDayl{>&dTz~5{fi2o757s2tNf21CM{wqV;v1 z0zUMQtY2I0e+S^}qT)yVmVp*k5{Zz;;aFfLbizfc324fMs@Yz%mCoptb-wV7(wXU{Ij%e+(kjLDnyb zkO$_*A44Oo2W#G+^I-1&v44V42fRN1WB(1|d9XM9^Su(-qyC8-tkr+~f^Ey6wE|54 zKL!!@3k;_}1`(FEzyWo%!2u18uwDloaLoaGfIs;#0SFBu%)K`(0D}ng;|B}C{u{#e z@7kZU8wlH9$Cc3t{l??!(Fm_cA~+x~8F&7#a1Usc0}iwt@|!=k|KA|I7mVWkqY=hChO37N%i}ow z2oUyv0vymF!n{m@1Gf7D4rmZzyBTo6^Yh?<1`(FO;&2HdG>C9~uEGMaze4C|?N6%> zBnO{~Kqcgp0fc@j075@h0O9I(P+F&O-Tc?^YxEh6NF<8&f$2><)n&>+IS z{Y_kbB0$(a33vX#Av~3gJC8=lOTpDcgdbCJWr%P+&BB#8gRp5fu02FJ4)Op(KLt1} z#GQu-KNjK2{|zDUF77-UVO0sP9wPKpjw_=PR^0=CAj1C+Iy5xG`2h|3fd^c_;oblm zL|Fdc{$nG5|J#4SQSsmRBXC{L0SBBfcfbK{D+q@sdfx&0unfob|Mnjn-^c!M{{ctE z|MnmM+kb4V$LM_r92c+**OCA2KVUXC_96fO*ng~(t>gA48Yc6=oV9#NfC7GnKOe_o?_FSA2zZ_B0p2xg5_ zjK^vj`Q@Gm8i=BF;eH7*?5#V^D|mjnW-brk*Zflba`Mre9IeNVJ1nVK+Jo~fo$+&E@A2Tp~9XQ;D(uLOyF>LXN^E`*2%?26h@7itf z@VYAtwOtpM()|R(Qn$PL#Z2?dk#^>Hqvy`E4)IplywE0iN4z6kfw>1W!bh&v8^0Gm z^X$NE| zo#u4@k8d!~TS|*BoXGGE6L70&D{tucK9S*Q=jkW z97?ifew+R9g}^|u_18BKu=YJ+3CfSDS(D#b+#P#QqcE?}+pMNS$Z~Pr1f>g~*$~4n z4#y51IUs*Esnc2e+vTFSa`*J^Hd(=Gu%`uS^<0_he33>lgOD%B}S1 zXLIXQjl^VO&rimBl-YLWYWiG^BuqI|H)P%d=RWr8HFAJ3WId@hL(pguZA+Xn@ zK8ezWdvL_CPcF?@-1Tm6>f&Mu{q3-`@Re7oL?3=QRrCvD)vC)MuTl3qy+|&s@tQwO zL~86)m2KyA?mVlam6eL(%)>o5@IIn+;hqgKtjM=1>+s5q`3qvBbFpC(fF=onGO(-@lvVYw(>Oq>yC|wdH2{2xXU27cn;}*`(h&*qn zKhb-lv@#LHKk_X;o6JA)_}b~!<9+S;Gpw5Nm4W5YPb7qsy%l`XWqEG6InH@JPFOzv z7D|^Ct?Sx^=RI4^{8ITATZ2Zv^M}?V@`IsfL{HcGKe@Kf*QmQDVSE zt^Y?3mpYquwk4+U;wKx5)#;kG)8-Y0E%bK3YZtooRGSP_Mqi4fbm6-h#IVAS=DQdP zPu$-7IN*QKK^35xDo znjuVIZI#ME>B4tsh+*fl;}m6{zKS-wQA}xns72U`R@>r-=}ppwwtdC}EuG=*jelF<5eAO{IpK!iWA6FgtY>$iw^mk0yrMc-e)*=(f6`i+O1>eV% zm+u=Mn98s}q2k6)Ah4IMZdI>&aA&mmlTrm*ZgjpyQ=P zf(3{rpI<4unAmaYbPjJ<3YTb#*VHh6@@FyG%qD{H=y)sEz?riV{c`e$3-G!lXvNy- zd?ocPOMmkpCjUwoZeKp*f{GVDM`vW@+{^JZHi&)%jT=P!)J zKEtd^N`1X9L!WFnkk8j|Y4|yd!69=0`E1_A47F=tO7eg1@kHsucTR|5OHzBY)jFL9 z^LWZjFK0W+vfIp*C!E$1SAN0!(%?>RrRCh2TV5Fp@ucz|EoY8=xH4HYVQiOBvlgUp zZEw61q=(Xl@2(KT#;>(o`AZvXR$n|GwddP&ad&1`pQ)oo76r8SJ%=Zs-q_bow4b{} z=XGgt3f*<#ckN0+J3TwK_-Ja}!jjnbq&-6E!guM2VOOU`Bb|3^eB-vd7}mp>=wWB< z_$(!D7_VE(=Hi�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 mBFCB}*X{UiF;a{7} The response to be sent back to the client + */ + async fetch(request, env, ctx) { + // We will create a `DurableObjectId` using the pathname from the Worker request + // This id refers to a unique instance of our 'MyDurableObject' class above + let id = env.SONR_DURABLE_CLIENT.idFromName(new URL(request.url).pathname); + + // This stub creates a communication channel with the Durable Object instance + // The Durable Object constructor will be invoked upon the first call for a given id + let stub = env.SONR_DURABLE_CLIENT.get(id); + + // We call the `sayHello()` RPC method on the stub to invoke the method on the remote + // Durable Object instance + let greeting = await stub.sayHello("world"); + + return new Response(greeting); + }, +}; diff --git a/web/workers/sonr-client/src/stub.js b/web/workers/sonr-client/src/stub.js new file mode 100644 index 000000000..c0ec6bb77 --- /dev/null +++ b/web/workers/sonr-client/src/stub.js @@ -0,0 +1,26 @@ +import { DurableObject } from "cloudflare:workers"; + +/** A Durable Object's behavior is defined in an exported Javascript class */ +export class SonrDurableClient extends DurableObject { + /** + * The constructor is invoked once upon creation of the Durable Object, i.e. the first call to + * `DurableObjectStub::get` for a given identifier (no-op constructors can be omitted) + * + * @param {DurableObjectState} ctx - The interface for interacting with Durable Object state + * @param {Env} env - The interface to reference bindings declared in wrangler.toml + */ + constructor(ctx, env) { + super(ctx, env); + } + + /** + * The Durable Object exposes an RPC method sayHello which will be invoked when when a Durable + * Object instance receives a request from a Worker via the same method invocation on the stub + * + * @param {string} name - The name provided to a Durable Object instance from a Worker + * @returns {Promise} The greeting to be sent back to the Worker + */ + async sayHello(name) { + return `Hello, ${name}!`; + } +} diff --git a/web/workers/sonr-client/wrangler.toml b/web/workers/sonr-client/wrangler.toml new file mode 100644 index 000000000..1ccb2aa5f --- /dev/null +++ b/web/workers/sonr-client/wrangler.toml @@ -0,0 +1,113 @@ +#:schema node_modules/wrangler/config-schema.json +name = "sonr-client" +main = "src/index.js" +compatibility_date = "2024-11-12" + +# Workers Logs +# Docs: https://developers.cloudflare.com/workers/observability/logs/workers-logs/ +# Configuration: https://developers.cloudflare.com/workers/observability/logs/workers-logs/#enable-workers-logs +[observability] +enabled = true + +# Automatically place your workloads in an optimal location to minimize latency. +# If you are running back-end logic in a Worker, running it closer to your back-end infrastructure +# rather than the end user may result in better performance. +# Docs: https://developers.cloudflare.com/workers/configuration/smart-placement/#smart-placement +# [placement] +# mode = "smart" + +# Variable bindings. These are arbitrary, plaintext strings (similar to environment variables) +# Docs: +# - https://developers.cloudflare.com/workers/wrangler/configuration/#environment-variables +# Note: Use secrets to store sensitive data. +# - https://developers.cloudflare.com/workers/configuration/secrets/ +# [vars] +# MY_VARIABLE = "production_value" + +# Bind the Workers AI model catalog. Run machine learning models, powered by serverless GPUs, on Cloudflare’s global network +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#workers-ai +# [ai] +# binding = "AI" + +# Bind an Analytics Engine dataset. Use Analytics Engine to write analytics within your Pages Function. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#analytics-engine-datasets +# [[analytics_engine_datasets]] +# binding = "MY_DATASET" + +# Bind a headless browser instance running on Cloudflare's global network. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#browser-rendering +# [browser] +# binding = "MY_BROWSER" + +# Bind a D1 database. D1 is Cloudflare’s native serverless SQL database. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#d1-databases +# [[d1_databases]] +# binding = "MY_DB" +# database_name = "my-database" +# database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + +# Bind a dispatch namespace. Use Workers for Platforms to deploy serverless functions programmatically on behalf of your customers. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#dispatch-namespace-bindings-workers-for-platforms +# [[dispatch_namespaces]] +# binding = "MY_DISPATCHER" +# namespace = "my-namespace" + +# Bind a Durable Object. Durable objects are a scale-to-zero compute primitive based on the actor model. +# Durable Objects can live for as long as needed. Use these when you need a long-running "server", such as in realtime apps. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#durable-objects +[[durable_objects.bindings]] +name = "SONR_DURABLE_CLIENT" +class_name = "SonrDurableClient" + +# Durable Object migrations. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#migrations +[[migrations]] +tag = "v2" +renamed_classes = [{ from = "MyDurableObject", to = "SonrDurableClient" }] + +# Bind a Hyperdrive configuration. Use to accelerate access to your existing databases from Cloudflare Workers. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#hyperdrive +# [[hyperdrive]] +# binding = "MY_HYPERDRIVE" +# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + +# Bind a KV Namespace. Use KV as persistent storage for small key-value pairs. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#kv-namespaces +# [[kv_namespaces]] +# binding = "MY_KV_NAMESPACE" +# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + +# Bind an mTLS certificate. Use to present a client certificate when communicating with another service. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#mtls-certificates +# [[mtls_certificates]] +# binding = "MY_CERTIFICATE" +# certificate_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + +# Bind a Queue producer. Use this binding to schedule an arbitrary task that may be processed later by a Queue consumer. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues +# [[queues.producers]] +# binding = "MY_QUEUE" +# queue = "my-queue" + +# Bind a Queue consumer. Queue Consumers can retrieve tasks scheduled by Producers to act on them. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues +# [[queues.consumers]] +# queue = "my-queue" + +# Bind an R2 Bucket. Use R2 to store arbitrarily large blobs of data, such as files. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#r2-buckets +# [[r2_buckets]] +# binding = "MY_BUCKET" +# bucket_name = "my-bucket" + +# Bind another Worker service. Use this binding to call another Worker without network overhead. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#service-bindings +# [[services]] +# binding = "MY_SERVICE" +# service = "my-service" + +# Bind a Vectorize index. Use to store and query vector embeddings for semantic search, classification and other vector search use-cases. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#vectorize-indexes +# [[vectorize]] +# binding = "MY_INDEX" +# index_name = "my-index"