diff --git a/context/ChainsContext/helpers.tsx b/context/ChainsContext/helpers.tsx index a679714..965bd73 100644 --- a/context/ChainsContext/helpers.tsx +++ b/context/ChainsContext/helpers.tsx @@ -19,7 +19,7 @@ export const emptyChain: ChainInfo = { export const isChainInfoFilled = (chain: Partial): chain is ChainInfo => Boolean( chain.registryName && - typeof chain.logo === "string" && + // typeof chain.logo === "string" && chain.chainId && chain.chainDisplayName && typeof chain.nodeAddress === "string" && diff --git a/context/ChainsContext/service.tsx b/context/ChainsContext/service.tsx index 0e274c9..b327c07 100644 --- a/context/ChainsContext/service.tsx +++ b/context/ChainsContext/service.tsx @@ -71,10 +71,15 @@ export const useChainsFromRegistry = () => { }; export const getNodeFromArray = async (nodeArray: readonly string[]) => { - // only return https connections - const secureNodes = nodeArray - .filter((address) => address.startsWith("https://")) - .map((address) => address); + let secureNodes: readonly string[] = []; + + if (process.env.NEXT_PUBLIC_IS_HTTP_ENABLED?.toLowerCase() === "true") { + // Allow all nodes, HTTP or HTTPS + secureNodes = nodeArray; + } else { + // Filter only HTTPS nodes + secureNodes = nodeArray.filter((address) => address.startsWith("https://")); + } if (!secureNodes.length) { throw new Error("No SSL enabled RPC nodes available for this chain"); diff --git a/stack-orchestrator/compose/docker-compose-cosmos-multisig-ui.yml b/stack-orchestrator/compose/docker-compose-cosmos-multisig-ui.yml new file mode 100644 index 0000000..885f9d2 --- /dev/null +++ b/stack-orchestrator/compose/docker-compose-cosmos-multisig-ui.yml @@ -0,0 +1,34 @@ +services: + cosmos-multisig-ui: + image: cerc/cosmos-multisig-ui:local + restart: unless-stopped + depends_on: + - alpha + network_mode: "host" # For local testing, to allow the container to directly access host machine ports from container + environment: + DGRAPH_URL: ${DGRAPH_URL:-http://localhost:8080/graphql} + NEXT_PUBLIC_MULTICHAIN: ${NEXT_PUBLIC_MULTICHAIN} + NEXT_PUBLIC_REGISTRY_NAME: ${NEXT_PUBLIC_REGISTRY_NAME} + NEXT_PUBLIC_LOGO: ${NEXT_PUBLIC_LOGO} + NEXT_PUBLIC_CHAIN_ID: ${NEXT_PUBLIC_CHAIN_ID} + NEXT_PUBLIC_CHAIN_DISPLAY_NAME: ${NEXT_PUBLIC_CHAIN_DISPLAY_NAME} + NEXT_PUBLIC_NODE_ADDRESSES: ${NEXT_PUBLIC_NODE_ADDRESSES} + NEXT_PUBLIC_DENOM: ${NEXT_PUBLIC_DENOM} + NEXT_PUBLIC_DISPLAY_DENOM: ${NEXT_PUBLIC_DISPLAY_DENOM} + NEXT_PUBLIC_DISPLAY_DENOM_EXPONENT: ${NEXT_PUBLIC_DISPLAY_DENOM_EXPONENT} + NEXT_PUBLIC_ASSETS: ${NEXT_PUBLIC_ASSETS} + NEXT_PUBLIC_GAS_PRICE: ${NEXT_PUBLIC_GAS_PRICE} + NEXT_PUBLIC_ADDRESS_PREFIX: ${NEXT_PUBLIC_ADDRESS_PREFIX} + NEXT_PUBLIC_IS_HTTP_ENABLED: ${NEXT_PUBLIC_IS_HTTP_ENABLED:-false} + command: ["bash", "/cosmos-script/run.sh"] + volumes: + - ../config/cosmos-multisig-ui/run.sh:/cosmos-script/run.sh + - ../config/cosmos-multisig-ui/db-schema.graphql:/cosmos-script/db-schema.graphql + ports: + - "3000" + healthcheck: + test: ["CMD", "nc", "-vz", "127.0.0.1", "3000"] + interval: 20s + timeout: 5s + retries: 15 + start_period: 10s diff --git a/stack-orchestrator/compose/docker-compose-dgraph.yml b/stack-orchestrator/compose/docker-compose-dgraph.yml new file mode 100644 index 0000000..2e511b2 --- /dev/null +++ b/stack-orchestrator/compose/docker-compose-dgraph.yml @@ -0,0 +1,33 @@ +services: + zero: + image: dgraph/dgraph:v21.03.2 + volumes: + - zero-data:/dgraph + ports: + - "5080" + - "6080" + restart: on-failure + command: dgraph zero --my=zero:5080 + + alpha: + image: dgraph/dgraph:v21.03.2 + depends_on: + - zero + volumes: + - alpha-data:/dgraph + ports: + - "8080" + - "9080" + restart: on-failure + command: dgraph alpha --my=alpha:7080 --zero=zero:5080 --security "whitelist=0.0.0.0/0" + + ratel: + image: dgraph/ratel:v21.03.2 + ports: + - "8000" + depends_on: + - alpha + +volumes: + zero-data: + alpha-data: diff --git a/stack-orchestrator/config/cosmos-multisig-ui/db-schema.graphql b/stack-orchestrator/config/cosmos-multisig-ui/db-schema.graphql new file mode 100644 index 0000000..2196eda --- /dev/null +++ b/stack-orchestrator/config/cosmos-multisig-ui/db-schema.graphql @@ -0,0 +1,30 @@ +type Multisig { + id: ID! + chainId: String! @search(by: [hash]) + address: String! @search(by: [hash]) + creator: String @search(by: [hash]) + pubkeyJSON: String! @search(by: [fulltext]) + transactions: [Transaction] @hasInverse(field: creator) +} + +type Transaction { + id: ID! + txHash: String + creator: Multisig + dataJSON: String! + signatures: [Signature] @hasInverse(field: transaction) +} + +type Signature { + transaction: Transaction! + bodyBytes: String! + signature: String! + address: String! +} + +type Nonce { + id: ID! + chainId: String! @search(by: [hash]) + address: String! @search(by: [hash]) + nonce: Int! +} diff --git a/stack-orchestrator/config/cosmos-multisig-ui/run.sh b/stack-orchestrator/config/cosmos-multisig-ui/run.sh new file mode 100644 index 0000000..32154c8 --- /dev/null +++ b/stack-orchestrator/config/cosmos-multisig-ui/run.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +set -e +if [ -n "$CERC_SCRIPT_DEBUG" ]; then + set -x +fi + +echo "Using the following env variables:" +echo "DGRAPH_URL: ${DGRAPH_URL}" +echo "NEXT_PUBLIC_MULTICHAIN: ${NEXT_PUBLIC_MULTICHAIN}" +echo "NEXT_PUBLIC_REGISTRY_NAME: ${NEXT_PUBLIC_REGISTRY_NAME}" +echo "NEXT_PUBLIC_LOGO: ${NEXT_PUBLIC_LOGO}" +echo "NEXT_PUBLIC_CHAIN_ID: ${NEXT_PUBLIC_CHAIN_ID}" +echo "NEXT_PUBLIC_CHAIN_DISPLAY_NAME: ${NEXT_PUBLIC_CHAIN_DISPLAY_NAME}" +echo "NEXT_PUBLIC_NODE_ADDRESSES: ${NEXT_PUBLIC_NODE_ADDRESSES}" +echo "NEXT_PUBLIC_DENOM: ${NEXT_PUBLIC_DENOM}" +echo "NEXT_PUBLIC_DISPLAY_DENOM: ${NEXT_PUBLIC_DISPLAY_DENOM}" +echo "NEXT_PUBLIC_DISPLAY_DENOM_EXPONENT: ${NEXT_PUBLIC_DISPLAY_DENOM_EXPONENT}" +echo "NEXT_PUBLIC_ASSETS: ${NEXT_PUBLIC_ASSETS}" +echo "NEXT_PUBLIC_GAS_PRICE: ${NEXT_PUBLIC_GAS_PRICE}" +echo "NEXT_PUBLIC_ADDRESS_PREFIX: ${NEXT_PUBLIC_ADDRESS_PREFIX}" +echo "NEXT_PUBLIC_IS_HTTP_ENABLED: ${NEXT_PUBLIC_IS_HTTP_ENABLED}" + +# Install dependencies +npm install + +# Build with all required env vars +DGRAPH_URL="${DGRAPH_URL}" \ +NEXT_PUBLIC_MULTICHAIN="${NEXT_PUBLIC_MULTICHAIN}" \ +NEXT_PUBLIC_REGISTRY_NAME="${NEXT_PUBLIC_REGISTRY_NAME}" \ +NEXT_PUBLIC_LOGO="${NEXT_PUBLIC_LOGO}" \ +NEXT_PUBLIC_CHAIN_ID="${NEXT_PUBLIC_CHAIN_ID}" \ +NEXT_PUBLIC_CHAIN_DISPLAY_NAME="${NEXT_PUBLIC_CHAIN_DISPLAY_NAME}" \ +NEXT_PUBLIC_NODE_ADDRESSES="${NEXT_PUBLIC_NODE_ADDRESSES}" \ +NEXT_PUBLIC_DENOM="${NEXT_PUBLIC_DENOM}" \ +NEXT_PUBLIC_DISPLAY_DENOM="${NEXT_PUBLIC_DISPLAY_DENOM}" \ +NEXT_PUBLIC_DISPLAY_DENOM_EXPONENT="${NEXT_PUBLIC_DISPLAY_DENOM_EXPONENT}" \ +NEXT_PUBLIC_ASSETS="${NEXT_PUBLIC_ASSETS}" \ +NEXT_PUBLIC_GAS_PRICE="${NEXT_PUBLIC_GAS_PRICE}" \ +NEXT_PUBLIC_ADDRESS_PREFIX="${NEXT_PUBLIC_ADDRESS_PREFIX}" \ +NEXT_PUBLIC_IS_HTTP_ENABLED="${NEXT_PUBLIC_IS_HTTP_ENABLED}" \ +npm run build + +# Load Dgraph schema +echo "Posting schema to Dgraph..." +curl -X POST localhost:8080/admin/schema -d @/cosmos-script/db-schema.graphql + +# Start Next.js production server +echo "Starting Next.js app in production mode..." +npm run start diff --git a/stack-orchestrator/container-build/cerc-cosmos-multisig-ui/Dockerfile b/stack-orchestrator/container-build/cerc-cosmos-multisig-ui/Dockerfile new file mode 100644 index 0000000..f18a262 --- /dev/null +++ b/stack-orchestrator/container-build/cerc-cosmos-multisig-ui/Dockerfile @@ -0,0 +1,41 @@ +FROM node:20.11.0-bullseye + +ARG USERNAME=node +ARG NPM_GLOBAL=/usr/local/share/npm-global + +# Add NPM global to PATH and disable update notifier +ENV PATH=${NPM_GLOBAL}/bin:${PATH} +ENV NPM_CONFIG_UPDATE_NOTIFIER=false + +# Configure global npm install location and install CLI tools +RUN \ + if ! getent group npm > /dev/null 2>&1; then groupadd -r npm; fi \ + && usermod -a -G npm ${USERNAME} \ + && umask 0002 \ + && mkdir -p ${NPM_GLOBAL} \ + && touch /usr/local/etc/npmrc \ + && chown ${USERNAME}:npm ${NPM_GLOBAL} /usr/local/etc/npmrc \ + && chmod g+s ${NPM_GLOBAL} \ + && npm config -g set prefix ${NPM_GLOBAL} \ + && su ${USERNAME} -c "npm config -g set prefix ${NPM_GLOBAL}" \ + && su ${USERNAME} -c "umask 0002 && npm install -g http-server" \ + && npm cache clean --force > /dev/null 2>&1 + +# Install system packages +RUN apt-get update && DEBIAN_FRONTEND=noninteractive \ + apt-get -y install --no-install-recommends jq bash netcat curl \ + && apt-get clean && rm -rf /var/lib/apt/lists/* + +# Create script directory +RUN mkdir -p /cosmos-script + +# Set app working directory +WORKDIR /app + +# Copy app source code +COPY . . + +# Install app dependencies +RUN npm install --legacy-peer-deps + +EXPOSE 3000 diff --git a/stack-orchestrator/container-build/cerc-cosmos-multisig-ui/build.sh b/stack-orchestrator/container-build/cerc-cosmos-multisig-ui/build.sh new file mode 100755 index 0000000..eaf475b --- /dev/null +++ b/stack-orchestrator/container-build/cerc-cosmos-multisig-ui/build.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +# Build cerc/cosmos-multisig-ui + +source ${CERC_CONTAINER_BASE_DIR}/build-base.sh + +# See: https://stackoverflow.com/a/246128/1701505 +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +echo "SCRIPT_DIR: ${SCRIPT_DIR}" + +docker build -t cerc/cosmos-multisig-ui:local ${build_command_args} -f ${SCRIPT_DIR}/Dockerfile ${CERC_REPO_BASE_DIR}/cosmos-multisig-ui diff --git a/stack-orchestrator/stacks/cosmos-multisig-ui/README.md b/stack-orchestrator/stacks/cosmos-multisig-ui/README.md new file mode 100644 index 0000000..40fe0d3 --- /dev/null +++ b/stack-orchestrator/stacks/cosmos-multisig-ui/README.md @@ -0,0 +1,133 @@ +# cosmos-multisig-ui + +Instructions for running the `cosmos-multisig-ui` using [laconic-so](https://git.vdb.to/cerc-io/stack-orchestrator) + +## Setup + +* Clone the stack repo: + + ```bash + laconic-so fetch-stack git.vdb.to/cerc-io/cosmos-multisig-ui --git-ssh --pull + ``` + +* Build the container image: + + ```bash + laconic-so --stack ~/cerc/cosmos-multisig-ui/stack-orchestrator/stacks/cosmos-multisig-ui build-containers + ``` + + This should create the `cerc/cosmos-multisig-ui` image locally + +## Create a deployment + +* Create a spec file for the deployment: + + ```bash + laconic-so --stack ~/cerc/cosmos-multisig-ui/stack-orchestrator/stacks/cosmos-multisig-ui deploy init --output cosmos-multisig-ui-spec.yml + ``` + +* Edit `network` in the spec file to map container ports to host ports as required: + + ```bash + # cosmos-multisig-ui-spec.yml + ... + network: + ports: + cosmos-multisig-ui: + - 3000:3000 + zero: + - 5080 + - 6080 + alpha: + - 8080:8080 + - 9080 + ratel: + - 8000 + ... + ``` + +* Create a deployment from the spec file: + + ```bash + laconic-so --stack ~/cerc/cosmos-multisig-ui/stack-orchestrator/stacks/cosmos-multisig-ui/ deploy create --spec-file cosmos-multisig-ui-spec.yml --deployment-dir cosmos-multisig-deployment + ``` + +* Inside the `cosmos-multisig-deployment` deployment directory, open `config.env` file and set following env variables: + + ```bash + # Allow multiple networks/chains in app + NEXT_PUBLIC_MULTICHAIN= + + # Name of the chain registry + NEXT_PUBLIC_REGISTRY_NAME= + + # Path or URL to the logo asset (can be left empty if not needed) + NEXT_PUBLIC_LOGO= + + # Chain ID + NEXT_PUBLIC_CHAIN_ID= + + # Display name for the chain + NEXT_PUBLIC_CHAIN_DISPLAY_NAME= + + # JSON array of RPC node URLs + NEXT_PUBLIC_NODE_ADDRESSES= + + # Native token base denom + NEXT_PUBLIC_DENOM= + + # Display name for the token (used in UI) + NEXT_PUBLIC_DISPLAY_DENOM= + + # Exponent used to convert from base denom + NEXT_PUBLIC_DISPLAY_DENOM_EXPONENT= + + # JSON array of asset metadata + NEXT_PUBLIC_ASSETS= + + # Minimum gas price + NEXT_PUBLIC_GAS_PRICE= + + # Bech32 address prefix for the chain + NEXT_PUBLIC_ADDRESS_PREFIX= + + # Whether to use HTTP (true/false) + NEXT_PUBLIC_IS_HTTP_ENABLED= + ``` + +## Start the deployment + +* Run: + + ```bash + laconic-so deployment --dir cosmos-multisig-deployment start + ``` + +* Check health status: + + ```bash + docker ps + ``` + +* Open the app in a browser at + +## Clean up + +* Stop the deployment: + + ```bash + laconic-so deployment --dir cosmos-multisig-deployment stop + ``` + +* Remove data: + + ```bash + # Remove deployment directory (deployment will have to be recreated for a re-run) + sudo rm -rf cosmos-multisig-deployment + ``` + +* Remove `cerc/cosmos-multisig-ui` image + + ```bash + docker rmi cerc/cosmos-multisig-ui:local + ``` diff --git a/stack-orchestrator/stacks/cosmos-multisig-ui/stack.yml b/stack-orchestrator/stacks/cosmos-multisig-ui/stack.yml new file mode 100644 index 0000000..dadfca2 --- /dev/null +++ b/stack-orchestrator/stacks/cosmos-multisig-ui/stack.yml @@ -0,0 +1,9 @@ +version: "1.0" +name: cosmos-multisig-ui +description: "cosmos multisig UI" +repos: +containers: + - cerc/cosmos-multisig-ui +pods: + - cosmos-multisig-ui + - dgraph