diff --git a/Dockerfile b/Dockerfile index d23a012..859b233 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,6 @@ + + +# For goreleaser FROM scratch ENTRYPOINT ["/hway"] COPY hway / diff --git a/deploy/README.md b/deploy/README.md new file mode 100644 index 0000000..05395bf --- /dev/null +++ b/deploy/README.md @@ -0,0 +1,4 @@ +# `matrix` + +Sonr Communication infrastructure which allows for Sonr Blockchain +Identities to have a secure and private communication channel. diff --git a/deploy/gateway/Dockerfile b/deploy/gateway/Dockerfile new file mode 100644 index 0000000..859b233 --- /dev/null +++ b/deploy/gateway/Dockerfile @@ -0,0 +1,6 @@ + + +# For goreleaser +FROM scratch +ENTRYPOINT ["/hway"] +COPY hway / diff --git a/deploy/bootstrap.sh b/deploy/gateway/bootstrap.sh similarity index 100% rename from deploy/bootstrap.sh rename to deploy/gateway/bootstrap.sh diff --git a/deploy/devbox.json b/deploy/gateway/devbox.json similarity index 100% rename from deploy/devbox.json rename to deploy/gateway/devbox.json diff --git a/deploy/matrix/Dockerfile b/deploy/matrix/Dockerfile new file mode 100644 index 0000000..859b233 --- /dev/null +++ b/deploy/matrix/Dockerfile @@ -0,0 +1,6 @@ + + +# For goreleaser +FROM scratch +ENTRYPOINT ["/hway"] +COPY hway / diff --git a/deploy/matrix/bootstrap.sh b/deploy/matrix/bootstrap.sh new file mode 100755 index 0000000..1fd7bdb --- /dev/null +++ b/deploy/matrix/bootstrap.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -e + + diff --git a/deploy/matrix/devbox.json b/deploy/matrix/devbox.json new file mode 100644 index 0000000..dad6044 --- /dev/null +++ b/deploy/matrix/devbox.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.13.7/.schema/devbox.schema.json", + "packages": [ + "go@latest", + "cargo@latest", + "uv@latest", + "bun@latest" + ], + "env": { + "PATH": "$HOME/.cargo/bin:$HOME/go/bin:$HOME/.local/bin:$HOME/.bun/bin:$PATH", + "GITHUB_TOKEN": "$GITHUB_TOKEN", + "GOPATH": "$HOME/go", + "GOBIN": "$GOPATH/bin", + "GHQ_ROOT": "$CLONEDIR" + }, + "shell": { + "init_hook": [], + "scripts": { + "test": [ + "echo \"Error: no test specified\" && exit 1" + ] + } + } +} diff --git a/x/resolve/handlers/api.go b/x/register/handlers/api.go similarity index 100% rename from x/resolve/handlers/api.go rename to x/register/handlers/api.go diff --git a/x/register/islands/card_account.templ b/x/register/islands/card_account.templ new file mode 100644 index 0000000..76e7b8c --- /dev/null +++ b/x/register/islands/card_account.templ @@ -0,0 +1,38 @@ +package islands + +templ CardAccount(addr, name, handle, creationBlock string) { +
+
+
+
+

sonr-testnet-1

+

{ handle }

+
+
+ +
+
+
+ { shortenAddress(addr) } +
+
+
+

Block Created

+

#{ creationBlock }

+
+
+

Issued to

+

{ name }

+
+
+
+
+} + +// Helper function to shorten address +func shortenAddress(address string) string { + if len(address) <= 20 { + return address + } + return address[:16] + "..." + address[len(address)-4:] +} diff --git a/x/register/islands/coin_select.templ b/x/register/islands/coin_select.templ new file mode 100644 index 0000000..e16e7fb --- /dev/null +++ b/x/register/islands/coin_select.templ @@ -0,0 +1,70 @@ +package islands + +type Coin struct { + Ticker string + Name string + IsDefault bool +} + +var defaultCoins = []Coin{ + {Ticker: "SNR", Name: "Sonr", IsDefault: true}, + {Ticker: "BTC", Name: "Bitcoin", IsDefault: true}, + {Ticker: "ETH", Name: "Ethereum", IsDefault: true}, + {Ticker: "SOL", Name: "Solana", IsDefault: false}, + {Ticker: "LTC", Name: "Litecoin", IsDefault: false}, + {Ticker: "DOGE", Name: "Dogecoin", IsDefault: false}, + {Ticker: "XRP", Name: "Ripple", IsDefault: false}, + {Ticker: "OSMO", Name: "Osmosis", IsDefault: false}, + {Ticker: "ATOM", Name: "Cosmos", IsDefault: false}, + {Ticker: "STARZ", Name: "Stargaze", IsDefault: false}, + {Ticker: "AKT", Name: "Akash", IsDefault: false}, + {Ticker: "EVMOS", Name: "Evmos", IsDefault: false}, + {Ticker: "FIL", Name: "Filecoin", IsDefault: false}, + {Ticker: "AXL", Name: "Axelar", IsDefault: false}, +} + +templ CoinSelect() { + + for _, a := range defaultCoins { + @CoinOption(a) + } + + +} + +templ CoinOption(a Coin) { + if a.IsDefault { + + + { a.Name } + + + } else { + + + { a.Name } + + + } +} diff --git a/x/register/islands/human_slider.templ b/x/register/islands/human_slider.templ new file mode 100644 index 0000000..ba5677c --- /dev/null +++ b/x/register/islands/human_slider.templ @@ -0,0 +1,25 @@ +package islands + +import "fmt" + +templ HumanSlider(firstNumber int, lastNumber int) { +
+ +
+} + +templ HumanSliderError(firstNumber int, lastNumber int) { + +
+ + Invalid Human Sum +
+} + +templ HumanSliderSuccess() { + +} + +func humanLabel(firstNumber int, lastNumber int) string { + return fmt.Sprintf("What is %d + %d?", firstNumber, lastNumber) +} diff --git a/x/register/islands/input_handle.templ b/x/register/islands/input_handle.templ new file mode 100644 index 0000000..12aa645 --- /dev/null +++ b/x/register/islands/input_handle.templ @@ -0,0 +1,45 @@ +package islands + +type HandleState string + +const ( + HandleStateInitial HandleState = "inital" + HandleStateValid HandleState = "valid" + HandleStateInvalid HandleState = "invalid" +) + +func (s HandleState) string() string { + return string(s) +} + +templ InputHandle() { +
+ +
+ +
+
+
+
+} + +templ InputHandleError(value string, helpText string) { + +
+ +
+
+ +
+
+
+} + +templ InputHandleSuccess(value string) { + +
+ +
+
+
+} diff --git a/x/register/islands/input_passkey.templ b/x/register/islands/input_passkey.templ new file mode 100644 index 0000000..094a13b --- /dev/null +++ b/x/register/islands/input_passkey.templ @@ -0,0 +1,97 @@ +package islands + +templ InputPasskey(addr string, userHandle string, challenge string) { + + + Register Passkey + +} + +script navigatorCredentialsCreate(userId string, userHandle string, challenge string) { + const publicKey = { + challenge: Uint8Array.from(challenge, (c) => c.charCodeAt(0)), + rp: { + name: "Sonr.ID", + }, + user: { + // Assuming that userId is ASCII-only + id: Uint8Array.from(userId, (c) => c.charCodeAt(0)), + name: userId, + displayName: userHandle, + }, + pubKeyCredParams: [ + { + type: "public-key", + alg: -7, // "ES256" + }, + { + type: "public-key", + alg: -257, // "RS256" + }, + ], + authenticatorSelection: { + userVerification: "required", + residentKey: "required", + authenticatorAttachment: "platform", + }, + timeout: 60000, // 1 minute + extensions: { + payment: { + isPayment: true, + }, + largeBlob: { + supported: "preferred", + }, + }, + }; + + // Helper function to convert ArrayBuffer to Base64URL string + function arrayBufferToBase64URL(buffer) { + const bytes = new Uint8Array(buffer); + let str = ''; + bytes.forEach(byte => { str += String.fromCharCode(byte) }); + return btoa(str) + .replace(/\+/g, '-') + .replace(/\//g, '_') + .replace(/=/g, ''); + } + +navigator.credentials + .create({ publicKey }) + .then((newCredentialInfo) => { + if (!(newCredentialInfo instanceof PublicKeyCredential)) { + throw new Error('Received credential is not a PublicKeyCredential'); + } + + const response = newCredentialInfo.response; + if (!(response instanceof AuthenticatorAttestationResponse)) { + throw new Error('Response is not an AuthenticatorAttestationResponse'); + } + + // Convert the credential data to a cross-platform compatible format + const credentialJSON = { + id: newCredentialInfo.id, + rawId: arrayBufferToBase64URL(newCredentialInfo.rawId), + type: newCredentialInfo.type, + authenticatorAttachment: newCredentialInfo.authenticatorAttachment || null, + transports: Array.isArray(response.getTransports) ? response.getTransports() : [], + clientExtensionResults: newCredentialInfo.getClientExtensionResults(), + response: { + attestationObject: arrayBufferToBase64URL(response.attestationObject), + clientDataJSON: arrayBufferToBase64URL(response.clientDataJSON) + } + }; + + // Set the form value with the stringified credential data + const credential = document.getElementById('credential-data'); + credential.value = JSON.stringify(credentialJSON); + + // Submit the form + const form = document.getElementById('passkey-form'); + form.submit(); + }) + .catch((err) => { + console.error('Passkey creation failed:', err); + alert(`Failed to create passkey: ${err.message || 'Unknown error'}`); + }); +} diff --git a/x/resolve/routes.go b/x/register/routes.go similarity index 100% rename from x/resolve/routes.go rename to x/register/routes.go diff --git a/x/spawn/handlers/api.go b/x/search/handlers/api.go similarity index 100% rename from x/spawn/handlers/api.go rename to x/search/handlers/api.go diff --git a/x/resolve/handlers/data.go b/x/search/handlers/data.go similarity index 100% rename from x/resolve/handlers/data.go rename to x/search/handlers/data.go diff --git a/x/resolve/handlers/view.go b/x/search/handlers/view.go similarity index 100% rename from x/resolve/handlers/view.go rename to x/search/handlers/view.go diff --git a/x/spawn/routes.go b/x/search/routes.go similarity index 100% rename from x/spawn/routes.go rename to x/search/routes.go diff --git a/x/spawn/handlers/data.go b/x/spawn/handlers/data.go deleted file mode 100644 index 5ac8282..0000000 --- a/x/spawn/handlers/data.go +++ /dev/null @@ -1 +0,0 @@ -package handlers diff --git a/x/spawn/handlers/view.go b/x/spawn/handlers/view.go deleted file mode 100644 index 5ac8282..0000000 --- a/x/spawn/handlers/view.go +++ /dev/null @@ -1 +0,0 @@ -package handlers