Skip to content

Commit

Permalink
Separate deployment of Gateway frontend and backend (#2032)
Browse files Browse the repository at this point in the history
  • Loading branch information
zkokelj authored Aug 22, 2024
1 parent 7863992 commit cb41817
Show file tree
Hide file tree
Showing 16 changed files with 117 additions and 166 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/manual-deploy-obscuro-gateway.yml
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,6 @@ jobs:
-e OBSCURO_GATEWAY_VERSION="${{ GITHUB.RUN_NUMBER }}-${{ GITHUB.SHA }}" \
--log-opt max-file=3 --log-opt max-size=10m \
${{ vars.DOCKER_BUILD_TAG_GATEWAY }} \
-host=0.0.0.0 -port=8080 -portWS=81 -nodeHost=${{ vars.L2_RPC_URL_VALIDATOR }} -verbose=true \
-host=0.0.0.0 -port=80 -portWS=81 -nodeHost=${{ vars.L2_RPC_URL_VALIDATOR }} -verbose=true \
-logPath=sys_out -dbType=mariaDB -dbConnectionURL="obscurouser:${{ secrets.OBSCURO_GATEWAY_MARIADB_USER_PWD }}@tcp(obscurogateway-mariadb-${{ github.event.inputs.testnet_type }}.uksouth.cloudapp.azure.com:3306)/ogdb" \
-rateLimitUserComputeTime=${{ vars.GATEWAY_RATE_LIMIT_USER_COMPUTE_TIME }} -rateLimitWindow=${{ vars.GATEWAY_RATE_LIMIT_WINDOW }} -maxConcurrentRequestsPerUser=${{ vars.GATEWAY_MAX_CONCURRENT_REQUESTS_PER_USER }} '
17 changes: 3 additions & 14 deletions .github/workflows/manual-deploy-ten-gateway-frontend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,16 @@ on:
- 'dev-testnet'
- 'uat-testnet'
- 'sepolia-testnet'

jobs:
build-and-deploy:
runs-on: ubuntu-latest
environment:
name: ${{ github.event.inputs.testnet_type }}
strategy:
fail-fast: false
matrix:
include:
- testnet_type: 'dev-testnet'
GATEWAY_API_URL: 'https://dev-testnet.ten.xyz'
- testnet_type: 'uat-testnet'
GATEWAY_API_URL: 'https://uat-testnet.ten.xyz'
- testnet_type: 'sepolia-testnet'
GATEWAY_API_URL: 'https://testnet.ten.xyz'
steps:
- name: 'Print GitHub variables'
run: |
echo "Selected Testnet Type: ${{ matrix.testnet_type }}"
echo "Gateway API URL: ${{ matrix.GATEWAY_API_URL }}"
echo "Gateway API URL: ${{ vars.GATEWAY_URL }}"
- uses: actions/checkout@v4

Expand All @@ -46,7 +35,7 @@ jobs:
echo "BRANCH_NAME=${GITHUB_REF_NAME}" >> $GITHUB_ENV
- name: 'Set up Docker'
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v3.6.1

- name: 'Login to Azure docker registry'
uses: azure/docker-login@v1
Expand All @@ -62,7 +51,7 @@ jobs:

- name: Build and Push Docker Image
run: |
DOCKER_BUILDKIT=1 docker build --build-arg GATEWAY_API_URL=${{ matrix.GATEWAY_API_URL }} -t ${{ vars.DOCKER_BUILD_TAG_GATEWAY_FE }} -f ./tools/walletextension/frontend/Dockerfile .
DOCKER_BUILDKIT=1 docker build --build-arg GATEWAY_API_URL=${{ vars.GATEWAY_URL }} -t ${{ vars.DOCKER_BUILD_TAG_GATEWAY_FE }} -f ./tools/walletextension/frontend/Dockerfile .
docker push ${{ vars.DOCKER_BUILD_TAG_GATEWAY_FE }}
- name: "Deploy Gateway FE to Azure Container Instances"
Expand Down
25 changes: 0 additions & 25 deletions tools/walletextension/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ FROM system as get-dependencies
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 .
Expand All @@ -32,21 +29,6 @@ FROM get-dependencies as build-wallet
# make sure the geth network code is available
COPY . /home/obscuro/go-obscuro

# 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.ten.xyz" > .env; \
elif [ "$TESTNET_TYPE" = "uat-testnet" ]; then \
echo "NEXT_PUBLIC_API_GATEWAY_URL=https://uat-testnet.ten.xyz" > .env; \
elif [ "$TESTNET_TYPE" = "sepolia-testnet" ]; then \
echo "NEXT_PUBLIC_API_GATEWAY_URL=https://testnet.ten.xyz" > .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 \
Expand All @@ -55,19 +37,12 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
# Lightweight final build stage. Includes bare minimum to start wallet extension
FROM alpine:3.18

# Install NGINX
RUN apk update && apk add nginx

# copy over the gateway executable
COPY --from=build-wallet /home/obscuro/go-obscuro/tools/walletextension/bin /home/obscuro/go-obscuro/tools/walletextension/bin

# copy over the .sql migration files
COPY --from=build-wallet /home/obscuro/go-obscuro/tools/walletextension/storage/database /home/obscuro/go-obscuro/tools/walletextension/storage/database

# copy over the NGINX configuration file
COPY --from=build-wallet /home/obscuro/go-obscuro/tools/walletextension/nginx.conf /etc/nginx/nginx.conf


# copy over the entrypoint script
COPY --from=build-wallet /home/obscuro/go-obscuro/tools/walletextension/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
Expand Down
101 changes: 70 additions & 31 deletions tools/walletextension/README.md
Original file line number Diff line number Diff line change
@@ -1,56 +1,95 @@
# The Ten gateway

See the documentation [here](https://docs.ten.xyz/wallet-extension/wallet-extension/).
# Ten Gateway Documentation

## Developer notes
For a comprehensive overview, refer to the [official documentation](https://docs.ten.xyz/docs/tools-infrastructure/hosted-gateway).

Running gateway frontend locally requires building static files first.
To do that, run `npm run build` in `tools/walletextension/frontend` folder.
## Running the Gateway Locally

The precompiled binaries for macOS ARM64, macOS AMD64, Windows AMD64 and Linux AMD64 can be built by running the
following commands from the `tools/walletextension/main` folder:
### Backend

```
To run the backend locally, it is recommended to use **port 1443** to avoid conflicts with the frontend service, which typically runs on port 3000. First, build the backend using the `go build` command. Navigate to the `tools/walletextension/main` folder and use the following commands to build for your respective operating system:

```bash
# macOS AMD64
env GOOS=darwin GOARCH=amd64 go build -o ../bin/wallet_extension_macos_amd64 .
env GOOS=darwin GOARCH=arm64 go build -o ../bin/wallet_extension_macos_arm64 .

# macOS ARM64
env GOOS=darwin GOARCH=arm64 go build -o ../bin/wallet_extension_macos_arm64 .

# Windows AMD64
env GOOS=windows GOARCH=amd64 go build -o ../bin/wallet_extension_win_amd64.exe .

# Linux AMD64
env GOOS=linux GOARCH=amd64 go build -o ../bin/wallet_extension_linux_amd64 .
```

The binaries will be created in the `tools/walletextension/bin` folder.
The binaries will be available in the `tools/walletextension/bin` directory.
Run the compiled binary and specify the desired port.
Example:

### Structure

This package follows the same structure of `host` and `enclave`.

It uses a container to wrap the services that are required to allow the wallet extension to fulfill the business logic.
```bash
./wallet_extension_macos_arm64 --port 1443
```

### Running Wallet Extension with Docker
### Additional Backend Configuration Options

- **`--host`**: The host where the wallet extension should open the port. Default: `127.0.0.1`.
- **`--port`**: The port on which to serve the wallet extension. Default: `3000`.
- **`--portWS`**: The port on which to serve websocket JSON RPC requests. Default: `3001`.
- **`--nodeHost`**: The host on which to connect to the Obscuro node. Default: `erpc.sepolia-testnet.ten.xyz`.
- **`--nodePortHTTP`**: The port on which to connect to the Obscuro node via RPC over HTTP. Default: `80`.
- **`--nodePortWS`**: The port on which to connect to the Obscuro node via RPC over websockets. Default: `81`.
- **`--logPath`**: The path to use for the wallet extension's log file. Default: `sys_out`.
- **`--databasePath`**: The path for the wallet extension's database file. Default: `.obscuro/gateway_database.db`.
- **`--verbose`**: Flag to enable verbose logging of wallet extension traffic. Default: `false`.
- **`--dbType`**: Define the database type (`sqlite` or `mariaDB`). Default: `sqlite`.
- **`--dbConnectionURL`**: If `dbType` is set to `mariaDB`, this must be set.
- **`--tenChainID`**: ChainID of the Ten network that the gateway is communicating with. Default: `443`.
- **`--storeIncomingTxs`**: Flag to enable storing incoming transactions in the database for debugging purposes. Default: `true`.
- **`--rateLimitUserComputeTime`**: Represents how much compute time a user is allowed to use within the `rateLimitWindow` time. Set to `0` to disable rate limiting. Default: `10s`.
- **`--rateLimitWindow`**: Time window in which a user is allowed to use the defined compute time. Default: `1m`.
- **`--maxConcurrentRequestsPerUser`**: Number of concurrent requests allowed per user. Default: `3`.


### Frontend

Once the backend is running, navigate to the `tools/walletextension/frontend` directory and execute the following commands:

```bash
npm install
npm run dev
```

To build a docker image use docker build command. Please note that you need to run it from the root of the repository.
To run the container you can use `./docker_run.sh`. You can add parameters to the script, and they are passed to the wallet extension
(example: `-host=0.0.0.0` to be able to access wallet extension endpoints via localhost).
The frontend will be accessible on `http://localhost:3000`.

## HTTP Endpoints

### HTTP Endpoints
Ten Gateway exposes several HTTP endpoints for interaction:

For interacting with Ten Gateway, there are the following HTTP endpoints available:
- **`GET /v1/join`**
Generates and returns a `userID`, which needs to be added as a query parameter `u` in your Metamask (or another provider) URL to identify you.

- `GET /v1/join`
- **`POST /v1/authenticate?token=$EncryptionToken`**
Submits a signed message in the format `Register <userID> for <account>`, proving ownership of the private keys for the account, and links that account with the `userID`.

It generates and returns userID which needs to be added as a query parameter "u" to the URL in your Metamask
(or another provider) as it identifies you.
- **`GET /v1/query/address?token=$EncryptionToken&a=$Address`**
Returns a JSON response indicating whether the address "a" is registered for the user "u".

- `POST /v1/authenticate?token=$EncryptionToken`
- **`POST /v1/revoke?token=$EncryptionToken`**
Deletes the userId along with the associated authenticated viewing keys.

With this endpoint, you submit a signed message in the format `Register <userID> for <account>`
from that account which proves that you hold private keys for it, and it links that account with your userID.
- **`GET /v1/health`**
Returns a health status of the service.

- `GET /v1/query/address?token=$EncryptionToken&a=$Address`
- **`GET /v1/network-health`**
Returns the health status of the node.

This endpoint responds with a JSON of true or false if the address "a" is already registered for user "u"
- **`GET /v1/network-config`**
Returns the network configuration details.

- **`GET /v1/version`**
Returns the current version of the gateway

- `POST "/v1/revoke?token=$EncryptionToken"`
- **`GET /v1/getmessage`**
Generates and returns a message for the user to sign based on the provided encryption token.

When this endpoint is triggered, the userId with the authenticated viewing keys should be deleted.
24 changes: 0 additions & 24 deletions tools/walletextension/api/server.go

This file was deleted.

Binary file removed tools/walletextension/api/static/favicon.ico
Binary file not shown.
1 change: 0 additions & 1 deletion tools/walletextension/common/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ const (
)

const (
PathStatic = "/static/"
PathReady = "/ready/"
PathJoin = "/join/"
PathGetMessage = "/getmessage/"
Expand Down
3 changes: 0 additions & 3 deletions tools/walletextension/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
#!/bin/sh

# Start NGINX in the background
nginx &

# Start wallet_extension_linux with parameters passed to the script
/home/obscuro/go-obscuro/tools/walletextension/bin/wallet_extension_linux "$@"

Expand Down
47 changes: 34 additions & 13 deletions tools/walletextension/frontend/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,20 +1,41 @@
# Use an official Node.js 22 as a parent image
FROM node:22-alpine
# Use an official Node.js LTS version as a base image
FROM node:20-alpine AS base

WORKDIR /usr/src/app

# ARG for build-time variable (GATEWAY_API_URL)
ARG GATEWAY_API_URL

# ENV for URL to be used in the app
ENV NEXT_PUBLIC_API_GATEWAY_URL=${GATEWAY_API_URL}
ENV PORT=80

# Copy package.json and package-lock.json (or yarn.lock) into the container
COPY package*.json ./
# Set the working directory
WORKDIR /usr/src/app

RUN npm install
COPY . .
# Copy the necessary files to the working directory
COPY tools/walletextension/frontend/ .

# Install dependencies
RUN npm ci

# Build the Next.js app
RUN npm run build

# Reduce the size of the final image by using a lighter base image
FROM node:20-alpine AS runner

# Set the working directory
WORKDIR /usr/src/app

# Copy only the necessary files from the build stage
COPY --from=base /usr/src/app/.next ./.next
COPY --from=base /usr/src/app/public ./public
COPY --from=base /usr/src/app/package*.json ./

# Install production dependencies
RUN npm ci --production


# Set the environment variables
ENV PORT=80

# Expose the port
EXPOSE 80
CMD ["npm", "start"]

# Start the application
CMD ["npm", "start"]
5 changes: 0 additions & 5 deletions tools/walletextension/frontend/next.config.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
output: "export",
// distDir should be "../api/static" in production but .next in development
distDir: process.env.NODE_ENV === "development" ? ".next" : "../api/static",
images: {
unoptimized: true,
},
// base path for static files should be "" in development but "/static" in production
basePath: process.env.NODE_ENV === "development" ? "" : "/static",
};

module.exports = nextConfig;
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ export default function Header() {
<div className="flex h-16 justify-between items-center px-4">
<Link href="/">
<Image
src="/static/assets/images/black_logotype.png"
src="/assets/images/black_logotype.png"
alt="Logo"
width={150}
height={40}
className="cursor-pointer dark:hidden"
/>
<Image
src="/static/assets/images/white_logotype.png"
src="/assets/images/white_logotype.png"
alt="Logo"
width={150}
height={40}
Expand Down
2 changes: 1 addition & 1 deletion tools/walletextension/frontend/src/lib/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const tenGatewayAddress =
process.env.NEXT_PUBLIC_API_GATEWAY_URL || "http://127.0.0.1:3000";
process.env.NEXT_PUBLIC_API_GATEWAY_URL || "http://127.0.0.1:1443";

export const tenscanLink = "https://testnet.tenscan.io";

Expand Down
Loading

0 comments on commit cb41817

Please sign in to comment.