diff --git a/tools/walletextension/Dockerfile b/tools/walletextension/Dockerfile
index ddc6223560..0e3dcd7a2e 100644
--- a/tools/walletextension/Dockerfile
+++ b/tools/walletextension/Dockerfile
@@ -16,6 +16,10 @@ FROM system as get-dependencies
# setup container data structure
RUN mkdir -p /home/obscuro/go-obscuro
+
+# Install Node.js and npm (needed for frontend)
+RUN apk add --update nodejs npm
+
# Ensures container layer caching when dependencies are not changed
WORKDIR /home/obscuro/go-obscuro
COPY go.mod .
@@ -27,7 +31,22 @@ FROM get-dependencies as build-wallet
# make sure the geth network code is available
COPY . /home/obscuro/go-obscuro
-# build the contract deployer exec
+# Create .env file for frontend
+WORKDIR /home/obscuro/go-obscuro/tools/walletextension/frontend
+RUN if [ "$TESTNET_TYPE" = "dev-testnet" ]; then \
+ echo "NEXT_PUBLIC_API_GATEWAY_URL=https://dev-testnet.obscu.ro" > .env; \
+ elif [ "$TESTNET_TYPE" = "uat-testnet" ]; then \
+ echo "NEXT_PUBLIC_API_GATEWAY_URL=https://uat-testnet.obscu.ro" > .env; \
+ elif [ "$TESTNET_TYPE" = "sepolia-testnet" ]; then \
+ echo "NEXT_PUBLIC_API_GATEWAY_URL=https://testnet.obscu.ro" > .env; \
+ else \
+ echo "NEXT_PUBLIC_API_GATEWAY_URL=http://127.0.0.1:3000" > .env; \
+ fi
+# Run npm build for frontend
+RUN npm install
+RUN npm run build
+
+# build the gateway executable
WORKDIR /home/obscuro/go-obscuro/tools/walletextension/main
RUN --mount=type=cache,target=/root/.cache/go-build \
go build -o ../bin/wallet_extension_linux
diff --git a/tools/walletextension/api/server.go b/tools/walletextension/api/server.go
index b725975ef4..dc6b512e25 100644
--- a/tools/walletextension/api/server.go
+++ b/tools/walletextension/api/server.go
@@ -11,13 +11,11 @@ import (
"github.com/ten-protocol/go-ten/tools/walletextension/common"
)
-//go:embed static
-//go:embed staticOG
+//go:embed all:static
var staticFiles embed.FS
const (
- staticDir = "static"
- staticDirOG = "staticOG"
+ staticDir = "static"
)
// Server is a wrapper for the http server
@@ -67,13 +65,7 @@ func createHTTPServer(address string, routes []Route) *http.Server {
if err != nil {
panic(fmt.Sprintf("could not serve static files. Cause: %s", err))
}
- serveMux.Handle(common.PathViewingKeys, http.StripPrefix(common.PathViewingKeys, http.FileServer(http.FS(noPrefixStaticFiles))))
-
- noPrefixStaticFilesOG, err := fs.Sub(staticFiles, staticDirOG)
- if err != nil {
- panic(fmt.Errorf("could not serve static files. Cause: %w", err).Error())
- }
- serveMux.Handle(common.PathObscuroGateway, http.StripPrefix(common.PathObscuroGateway, http.FileServer(http.FS(noPrefixStaticFilesOG))))
+ serveMux.Handle(common.PathObscuroGateway, http.StripPrefix(common.PathObscuroGateway, http.FileServer(http.FS(noPrefixStaticFiles))))
// Creates the actual http server with a ReadHeaderTimeout to avoid Potential Slowloris Attack
server := &http.Server{Addr: address, Handler: serveMux, ReadHeaderTimeout: common.ReaderHeadTimeout}
diff --git a/tools/walletextension/api/static/favicon.ico b/tools/walletextension/api/static/favicon.ico
new file mode 100644
index 0000000000..1bb8f324a1
Binary files /dev/null and b/tools/walletextension/api/static/favicon.ico differ
diff --git a/tools/walletextension/api/static/index.html b/tools/walletextension/api/static/index.html
deleted file mode 100644
index 8bdd8fb131..0000000000
--- a/tools/walletextension/api/static/index.html
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
- Obscuro | Generate viewing key
-
-
-
-
-
-
-
-
-◠. Hello frens. Welcome to the Obscuro wallet extension! ◠.
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/tools/walletextension/api/static/javascript.js b/tools/walletextension/api/static/javascript.js
deleted file mode 100644
index b57d372df1..0000000000
--- a/tools/walletextension/api/static/javascript.js
+++ /dev/null
@@ -1,77 +0,0 @@
-const eventClick = "click";
-const eventDomLoaded = "DOMContentLoaded";
-const idGenerateViewingKey = "generateViewingKey";
-const idStatus = "status";
-const pathGenerateViewingKey = "/generateviewingkey/";
-const pathSubmitViewingKey = "/submitviewingkey/";
-const methodPost = "post";
-const jsonHeaders = {
- "Accept": "application/json",
- "Content-Type": "application/json"
-};
-const metamaskRequestAccounts = "eth_requestAccounts";
-const metamaskPersonalSign = "personal_sign";
-const personalSignPrefix = "vk";
-
-const initialize = () => {
- const generateViewingKeyButton = document.getElementById(idGenerateViewingKey);
- const statusArea = document.getElementById(idStatus);
-
- generateViewingKeyButton.addEventListener(eventClick, async () => {
- if (typeof ethereum === "undefined") {
- statusArea.innerText = "`ethereum` object is not available. Please install and enable MetaMask."
- return
- }
-
- const accounts = await ethereum.request({method: metamaskRequestAccounts});
- if (accounts.length === 0) {
- statusArea.innerText = "No MetaMask accounts found."
- return
- }
- // Accounts is "An array of a single, hexadecimal Ethereum address string.", so we grab the single entry at index zero.
- const account = accounts[0];
-
- const addressJson = {"address": account}
- const viewingKeyResp = await fetch(
- pathGenerateViewingKey, {
- method: methodPost,
- headers: jsonHeaders,
- body: JSON.stringify(addressJson)
- }
- );
- if (!viewingKeyResp.ok) {
- statusArea.innerText = "Failed to generate viewing key."
- return
- }
-
- const viewingKey = await viewingKeyResp.text();
-
- const signature = await ethereum.request({
- method: metamaskPersonalSign,
- // Without a prefix such as 'vk', personal_sign transforms the data for security reasons.
- params: [personalSignPrefix + viewingKey, account]
- }).catch(_ => { return -1 })
- if (signature === -1) {
- statusArea.innerText = "Failed to sign viewing key."
- return
- }
-
- const signedViewingKeyJson = {"signature": signature, "address": account}
- const submitViewingKeyResp = await fetch(
- pathSubmitViewingKey, {
- method: methodPost,
- headers: jsonHeaders,
- body: JSON.stringify(signedViewingKeyJson)
- }
- );
-
- let checksummedAccount = Web3.utils.toChecksumAddress(account);
- if (submitViewingKeyResp.ok) {
- statusArea.innerText = `Account: ${checksummedAccount}\nViewing key: ${viewingKey}\nSigned bytes: ${signature}`
- } else {
- statusArea.innerText = "Failed to submit viewing key to enclave."
- }
- })
-}
-
-window.addEventListener(eventDomLoaded, initialize);
\ No newline at end of file
diff --git a/tools/walletextension/api/static/style.css b/tools/walletextension/api/static/style.css
deleted file mode 100644
index 2c9cadb9cd..0000000000
--- a/tools/walletextension/api/static/style.css
+++ /dev/null
@@ -1,34 +0,0 @@
-html {
- font-family: sans-serif;
- line-height: 1.5;
-}
-
-body {
- color: white;
- background-color: black;
- margin: 1rem;
-}
-
-a {
- color: white;
-}
-
-textarea {
- color: white;
- background-color: black;
- font-family: sans-serif;
- border: solid 1px white;
- border-radius: 3px;
-}
-
-button {
- color: white;
- background-color: black;
- border: solid 1px white;
- border-radius: 3px;
-}
-
-/*Formats the block-decoder form.*/
-form { display: table; }
-label { display: table-cell; }
-input { display: table-cell; }
\ No newline at end of file
diff --git a/tools/walletextension/frontend/next.config.js b/tools/walletextension/frontend/next.config.js
index a843cbee09..45ddca84d4 100644
--- a/tools/walletextension/frontend/next.config.js
+++ b/tools/walletextension/frontend/next.config.js
@@ -1,6 +1,8 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
+ output: 'export',
+ distDir: '../api/static'
}
module.exports = nextConfig
diff --git a/tools/walletextension/frontend/src/components/modules/common/network-status.tsx b/tools/walletextension/frontend/src/components/modules/common/network-status.tsx
index bfa457bfa2..8f999f4015 100644
--- a/tools/walletextension/frontend/src/components/modules/common/network-status.tsx
+++ b/tools/walletextension/frontend/src/components/modules/common/network-status.tsx
@@ -8,7 +8,7 @@ const MessageContent = (
);
export const NetworkStatus = ({ message = MessageContent }) => {
- const [isOnline, setIsOnline] = React.useState(navigator.onLine);
+ const [isOnline, setIsOnline] = React.useState(true);
React.useEffect(() => {
const setOnlineStatus = () => {
diff --git a/tools/walletextension/main/main.go b/tools/walletextension/main/main.go
index 119a3d707c..63c8234069 100644
--- a/tools/walletextension/main/main.go
+++ b/tools/walletextension/main/main.go
@@ -74,7 +74,7 @@ func main() {
}()
walletExtensionAddr := fmt.Sprintf("%s:%d", common.Localhost, config.WalletExtensionPortHTTP)
- fmt.Printf("💡 Wallet extension started - visit http://%s/viewingkeys/ to generate an ephemeral viewing key.\n", walletExtensionAddr)
+ fmt.Printf("💡 Wallet extension started") // Some tests rely on seeing this message. Removed in next PR.
fmt.Printf("💡 Obscuro Gateway started - visit http://%s to use it.\n", walletExtensionAddr)
select {}