From cdf0a77ee5ff074a4be5ddf108e4a399d15ba28b Mon Sep 17 00:00:00 2001 From: Thomas E Lackey Date: Thu, 2 May 2024 15:31:51 -0500 Subject: [PATCH] Initial commit --- README.md | 104 +++++++++++++ scripts/install-so.sh | 5 + .../compose/docker-compose-nitro-auth.yml | 141 ++++++++++++++++++ .../docker-compose-nitro-contracts.yml | 23 +++ .../config/go-nitro/run-nitro-node.sh | 119 +++++++++++++++ .../config/nitro-auth/alice.env | 19 +++ stack-orchestrator/config/nitro-auth/bob.env | 21 +++ .../config/nitro-auth/bootnode.env | 17 +++ .../config/nitro-auth/caddy/Caddyfile | 48 ++++++ .../config/nitro-auth/charlie.env | 19 +++ .../config/nitro-contracts/deploy.sh | 57 +++++++ .../config/nitro-rpc-client/start.sh | 99 ++++++++++++ stack-orchestrator/config/ts-nitro/run.sh | 45 ++++++ .../container-build/cerc-go-nitro/Dockerfile | 37 +++++ .../container-build/cerc-go-nitro/build.sh | 8 + .../cerc-nitro-contracts/Dockerfile | 12 ++ .../cerc-nitro-contracts/build.sh | 9 ++ .../cerc-nitro-rpc-client/Dockerfile | 13 ++ .../cerc-nitro-rpc-client/build.sh | 9 ++ .../container-build/cerc-ts-nitro/Dockerfile | 12 ++ .../container-build/cerc-ts-nitro/build.sh | 9 ++ .../stacks/nitro-auth/stack.yml | 17 +++ 22 files changed, 843 insertions(+) create mode 100644 README.md create mode 100755 scripts/install-so.sh create mode 100644 stack-orchestrator/compose/docker-compose-nitro-auth.yml create mode 100644 stack-orchestrator/compose/docker-compose-nitro-contracts.yml create mode 100755 stack-orchestrator/config/go-nitro/run-nitro-node.sh create mode 100644 stack-orchestrator/config/nitro-auth/alice.env create mode 100644 stack-orchestrator/config/nitro-auth/bob.env create mode 100644 stack-orchestrator/config/nitro-auth/bootnode.env create mode 100644 stack-orchestrator/config/nitro-auth/caddy/Caddyfile create mode 100644 stack-orchestrator/config/nitro-auth/charlie.env create mode 100755 stack-orchestrator/config/nitro-contracts/deploy.sh create mode 100755 stack-orchestrator/config/nitro-rpc-client/start.sh create mode 100755 stack-orchestrator/config/ts-nitro/run.sh create mode 100644 stack-orchestrator/container-build/cerc-go-nitro/Dockerfile create mode 100755 stack-orchestrator/container-build/cerc-go-nitro/build.sh create mode 100644 stack-orchestrator/container-build/cerc-nitro-contracts/Dockerfile create mode 100755 stack-orchestrator/container-build/cerc-nitro-contracts/build.sh create mode 100644 stack-orchestrator/container-build/cerc-nitro-rpc-client/Dockerfile create mode 100755 stack-orchestrator/container-build/cerc-nitro-rpc-client/build.sh create mode 100644 stack-orchestrator/container-build/cerc-ts-nitro/Dockerfile create mode 100755 stack-orchestrator/container-build/cerc-ts-nitro/build.sh create mode 100644 stack-orchestrator/stacks/nitro-auth/stack.yml diff --git a/README.md b/README.md new file mode 100644 index 0000000..edaa490 --- /dev/null +++ b/README.md @@ -0,0 +1,104 @@ +# go-nitro-auth + +Deploy a stack for demoing Nitro-based auth, using either a local fixturenet (fully self-contained) or remote testnet. + +## Local Fixturenet (Self-Contained) + +### Clone required repositories + +``` +$ laconic-so --stack fixturenet-eth setup-repositories +$ laconic-so --stack go-nitro-auth setup-repositories +``` + +### Build containers + +``` +$ laconic-so --stack fixturenet-eth build-containers +$ laconic-so --stack go-nitro-auth build-containers +``` + +### Create a deployment + +``` +$ laconic-so --stack fixturenet-eth deploy init --output nitro-net.yml +$ laconic-so --stack fixturenet-eth deploy create --spec-file nitro-net.yml --deployment-dir /srv/nitro-net + +$ laconic-so --stack go-nitro-auth deploy init --map-ports-to-host any-same --output nitro-auth.yml +$ laconic-so --stack go-nitro-auth deploy create --spec-file nitro-auth.yml --deployment-dir /srv/nitro-auth + +# Place them both in the same namespace (TODO: support setting the deployment name via --cluster). +$ cp /srv/nitro-net/deployment.yml /srv/nitro-auth/deployment.yml +``` + +### Start the containers + +``` +$ laconic-so deployment --dir /srv/nitro-net up +$ laconic-so deployment --dir /srv/nitro-auth up +``` + +### Open the webapp + +Visit http://localhost:5678 + +## Remote Testnet + +This example will use the Linea Sepolia testnet. + +### Clone required repositories + +``` +$ laconic-so --stack go-nitro-auth setup-repositories +``` + +### Build containers + +``` +$ laconic-so --stack go-nitro-auth build-containers +``` + +### Create a deployment + +``` +$ laconic-so --stack go-nitro-auth deploy init --map-ports-to-host any-same --output nitro-auth.yml +$ laconic-so --stack go-nitro-auth deploy create --spec-file nitro-auth.yml --deployment-dir /srv/nitro-auth +``` + +### Set your keys, contract addresses, etc. + +You must set the private keys for two accounts with funds on the target network, as well as the contract addresses +(if they already exist) or else an account to create them. You must also set the URL to use for WebSocket connections, +eg, `wss://linea-sepolia.infura.io/ws/v3/` + +#### Config + +``` +$ vim /srv/nitro-auth/config.env +# Addresses of existing contracts. +CERC_CA_ADDRESS="0x1Ae815c3e7556e16ceaB6B6d46306C1870EB6d24" +CERC_NA_ADDRESS="0xc453C5E3f304bb545A3Df7bBa02fe6274A056636" +CERC_VPA_ADDRESS="0xA11af80D75b1150631FA78178c94fa451c7172a8" + +# Else the private key of an account and RPC URL to use create them. +CERC_PRIVATE_KEY_DEPLOYER= +CERC_ETH_RPC_ENDPOINT=https://rpc.sepolia.linea.build + +# The WebSocket chain URL. +CERC_NITRO_CHAIN_URL=wss://linea-sepolia.infura.io/ws/v3/ + +# Private key for "Alice" account (payer) +CERC_NITRO_CHAIN_PK_ALICE= + +# Private key for "Bob" account (payee) +CERC_NITRO_CHAIN_PK_BOB= +``` + +### Start the stack +``` +$ laconic-so deployment --dir /srv/nitro-auth up +``` + +### Open the webapp + +Visit http://localhost:5678 diff --git a/scripts/install-so.sh b/scripts/install-so.sh new file mode 100755 index 0000000..87000a8 --- /dev/null +++ b/scripts/install-so.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +mkdir ~/bin +curl -L -o ~/bin/laconic-so https://git.vdb.to/cerc-io/stack-orchestrator/releases/download/latest/laconic-so +chmod +x ~/bin/laconic-so + diff --git a/stack-orchestrator/compose/docker-compose-nitro-auth.yml b/stack-orchestrator/compose/docker-compose-nitro-auth.yml new file mode 100644 index 0000000..151a833 --- /dev/null +++ b/stack-orchestrator/compose/docker-compose-nitro-auth.yml @@ -0,0 +1,141 @@ +version: '3.7' + +services: + go-nitro-alice: + image: cerc/go-nitro:local + hostname: go-nitro-alice + restart: on-failure + depends_on: + - go-nitro-bootnode + environment: + CERC_NITRO_CHAIN_PK: ${CERC_NITRO_CHAIN_PK_ALICE:-888814df89c4358d7ddb3fa4b0213e7331239a80e1f013eaa7b2deca2a41a218} + CERC_NITRO_CHAIN_URL: ${CERC_NITRO_CHAIN_URL:-ws://fixturenet-eth-geth-1:8546} + CERC_NA_ADDRESS: ${CERC_NA_ADDRESS} + CERC_VPA_ADDRESS: ${CERC_VPA_ADDRESS} + CERC_CA_ADDRESS: ${CERC_CA_ADDRESS} + env_file: + - ../config/nitro-auth/alice.env + entrypoint: ["bash", "-c", "/app/run-nitro-node.sh"] + volumes: + - nitro_deployment:/app/deployment + - go_nitro_data_alice:/app/data + - ../config/go-nitro/run-nitro-node.sh:/app/run-nitro-node.sh + healthcheck: + test: ["CMD", "nc", "-vz", "localhost", "4006"] + interval: 5s + timeout: 5s + retries: 100 + start_period: 100s + ports: + - "3006" + - "4006" + - "5006" + - "4106" + - "4206" + - "4216" + + go-nitro-bob: + image: cerc/go-nitro:local + hostname: go-nitro-bob + restart: on-failure + depends_on: + - go-nitro-bootnode + environment: + CERC_NITRO_CHAIN_PK: ${CERC_NITRO_CHAIN_PK_BOB:-570b909da9669b2f35a0b1ac70b8358516d55ae1b5b3710e95e9a94395090597} + CERC_NITRO_CHAIN_URL: ${CERC_NITRO_CHAIN_URL:-ws://fixturenet-eth-geth-1:8546} + CERC_NA_ADDRESS: ${CERC_NA_ADDRESS} + CERC_VPA_ADDRESS: ${CERC_VPA_ADDRESS} + CERC_CA_ADDRESS: ${CERC_CA_ADDRESS} + env_file: + - ../config/nitro-auth/bob.env + entrypoint: ["bash", "-c", "/app/run-nitro-node.sh"] + volumes: + - nitro_deployment:/app/deployment + - go_nitro_data_bob:/app/data + - ../config/go-nitro/run-nitro-node.sh:/app/run-nitro-node.sh + healthcheck: + test: ["CMD", "nc", "-vz", "localhost", "4007"] + interval: 5s + timeout: 5s + retries: 100 + start_period: 100s + ports: + - "3007" + - "4007" + - "5007" + - "4107" + - "4207" + - "4217" + + ts-nitro-charlie: + image: cerc/ts-nitro:local + hostname: ts-nitro-charlie + restart: on-failure + depends_on: + - go-nitro-bootnode + environment: + CERC_NITRO_CHAIN_PK: ${CERC_NITRO_CHAIN_PK_CHARLIE:-111b7500bdce494d6f4bcfe8c2a0dde2ef92f751d9070fac6475dbd6d8021b3f} + CERC_NITRO_CHAIN_URL: ${CERC_NITRO_CHAIN_URL:-ws://fixturenet-eth-geth-1:8546} + CERC_NA_ADDRESS: ${CERC_NA_ADDRESS} + CERC_VPA_ADDRESS: ${CERC_VPA_ADDRESS} + CERC_CA_ADDRESS: ${CERC_CA_ADDRESS} + CERC_NITRO_TARGET_URL: ${CERC_NITRO_TARGET_URL:-http://localhost:5678} + CERC_RUNTIME_ENV_RPC_URL: ${CERC_RUNTIME_ENV_RPC_URL:-ws://localhost:8546} + PUBLIC_URL: http://localhost:5678/ts-nitro + env_file: + - ../config/nitro-auth/charlie.env + entrypoint: ["bash", "-c", "/app/run.sh"] + volumes: + - nitro_deployment:/app/deployment + - ../config/ts-nitro/run.sh:/app/run.sh + healthcheck: + test: ["CMD", "nc", "-vz", "localhost", "3000"] + interval: 5s + timeout: 5s + retries: 100 + start_period: 100s + + go-nitro-bootnode: + image: cerc/go-nitro:local + hostname: go-nitro-bootnode + restart: on-failure + environment: + CERC_NITRO_CHAIN_URL: ${CERC_NITRO_CHAIN_URL:-ws://fixturenet-eth-geth-1:8546} + CERC_NA_ADDRESS: ${CERC_NA_ADDRESS} + CERC_VPA_ADDRESS: ${CERC_VPA_ADDRESS} + CERC_CA_ADDRESS: ${CERC_CA_ADDRESS} + CERC_NITRO_RELAY_ON: true + env_file: + - ../config/nitro-auth/bootnode.env + entrypoint: [ "bash", "-c", "/app/run-nitro-node.sh" ] + volumes: + - nitro_deployment:/app/deployment + - go_nitro_data_bootnode:/app/data + - ../config/go-nitro/run-nitro-node.sh:/app/run-nitro-node.sh + healthcheck: + test: [ "CMD", "nc", "-vz", "localhost", "4008" ] + interval: 5s + timeout: 5s + retries: 100 + start_period: 100s + ports: + - "9090" + + nitro-caddy: + image: caddy:2-alpine + restart: always + environment: + CERC_ETH_RPC_ENDPOINT: ${CERC_ETH_RPC_ENDPOINT:-http://fixturenet-eth-geth-1:8545} + volumes: + - ../config/nitro-auth/caddy/Caddyfile:/etc/caddy/Caddyfile + ports: + - "5678" + depends_on: + - go-nitro-alice + - go-nitro-bob + +volumes: + go_nitro_data_alice: + go_nitro_data_bob: + go_nitro_data_bootnode: + nitro_deployment: diff --git a/stack-orchestrator/compose/docker-compose-nitro-contracts.yml b/stack-orchestrator/compose/docker-compose-nitro-contracts.yml new file mode 100644 index 0000000..8357d25 --- /dev/null +++ b/stack-orchestrator/compose/docker-compose-nitro-contracts.yml @@ -0,0 +1,23 @@ +version: '3.7' + +services: + # Optionally deploys the Nitro contracts + nitro-contracts: + image: cerc/nitro-contracts:local + restart: on-failure + environment: + CERC_SCRIPT_DEBUG: ${CERC_SCRIPT_DEBUG} + CERC_ETH_RPC_ENDPOINT: ${CERC_ETH_RPC_ENDPOINT:-http://fixturenet-eth-geth-1:8545} + CERC_PRIVATE_KEY_DEPLOYER: ${CERC_PRIVATE_KEY_DEPLOYER:-0x888814df89c4358d7ddb3fa4b0213e7331239a80e1f013eaa7b2deca2a41a218} + CERC_NA_ADDRESS: ${CERC_NA_ADDRESS} + CERC_VPA_ADDRESS: ${CERC_VPA_ADDRESS} + CERC_CA_ADDRESS: ${CERC_CA_ADDRESS} + volumes: + - ../config/nitro-contracts/deploy.sh:/app/deploy.sh + - nitro_deployment:/app/deployment + command: ["bash", "-c", "/app/deploy.sh"] + extra_hosts: + - "host.docker.internal:host-gateway" + +volumes: + nitro_deployment: diff --git a/stack-orchestrator/config/go-nitro/run-nitro-node.sh b/stack-orchestrator/config/go-nitro/run-nitro-node.sh new file mode 100755 index 0000000..f0febfb --- /dev/null +++ b/stack-orchestrator/config/go-nitro/run-nitro-node.sh @@ -0,0 +1,119 @@ +#!/bin/bash + +if [ -n "$CERC_SCRIPT_DEBUG" ]; then + set -x +fi + +if [ -z "$CERC_NITRO_CHAIN_PK" ] || [ -z "$CERC_NITRO_CHAIN_URL" ]; then + echo "You most set both CERC_NITRO_CHAIN_PK and CERC_NITRO_CHAIN_URL." 1>&2 + exit 1 +fi + +nitro_addresses_file="/app/deployment/nitro-addresses.json" + +# Check if CERC_NA_ADDRESS environment variable is set +if [ -n "$CERC_NA_ADDRESS" ]; then + echo "CERC_NA_ADDRESS is set to '$CERC_NA_ADDRESS'" + echo "CERC_VPA_ADDRESS is set to '$CERC_VPA_ADDRESS'" + echo "CERC_CA_ADDRESS is set to '$CERC_CA_ADDRESS'" + echo "Using the above Nitro addresses" + + NA_ADDRESS=${CERC_NA_ADDRESS} + VPA_ADDRESS=${CERC_VPA_ADDRESS} + CA_ADDRESS=${CERC_CA_ADDRESS} +elif [ -f ${nitro_addresses_file} ]; then + echo "Reading Nitro addresses from ${nitro_addresses_file}" + + NA_ADDRESS=$(jq -r '.nitroAdjudicatorAddress' ${nitro_addresses_file}) + VPA_ADDRESS=$(jq -r '.virtualPaymentAppAddress' ${nitro_addresses_file}) + CA_ADDRESS=$(jq -r '.consensusAppAddress' ${nitro_addresses_file}) +else + echo "File ${nitro_addresses_file} not found" + exit 1 +fi + +echo "Running Nitro node" + +if [[ "${CERC_GO_NITRO_WAIT_FOR_CHAIN:-true}" == "true" ]]; then + # Assuming CERC_NITRO_CHAIN_URL is of format ://host[:port][/foo] + ws_host=$(echo "$CERC_NITRO_CHAIN_URL" | awk -F '://' '{print $2}' | cut -d'/' -f 1 | cut -d ':' -f 1) + ws_port=$(echo "$CERC_NITRO_CHAIN_URL" | awk -F '://' '{print $2}' | cut -d'/' -f 1 | cut -d ':' -f 2) + if [[ "$ws_port" == "$ws_host" ]]; then + ws_port="" + fi + + # Wait till chain endpoint is available + retry_interval=5 + while true; do + nc -z -w 1 "$ws_host" "${ws_port:-443}" + + if [ $? -eq 0 ]; then + echo "Chain endpoint is available" + break + fi + + echo "Chain endpoint not yet available, retrying in $retry_interval seconds..." + sleep $retry_interval + done +fi + +if [[ -n "$CERC_NITRO_UI_PORT" ]] && [[ -d "/app-node/packages/nitro-gui/dist" ]]; then + for f in `ls /app-node/packages/nitro-gui/dist/assets/*.js`; do + sed -i "s#\"CERC_RUNTIME_ENV_RPC_HOST\"#\"localhost:${CERC_NITRO_RPC_PORT}\"#g" "$f" + sed -i "s#\"CERC_RUNTIME_ENV_TARGET_URL\"#\"http://localhost:5678\"#g" "$f" + done + http-server -p $CERC_NITRO_UI_PORT /app-node/packages/nitro-gui/dist & +fi + +if [[ -n "$CERC_NITRO_AUTH_UI_PORT" ]] && [[ -d "/app-node/packages/nitro-auth-gui/dist" ]]; then + for f in `ls /app-node/packages/nitro-auth-gui/dist/assets/*.js`; do + sed -i "s#\"CERC_RUNTIME_ENV_RPC_URL\"#\"http://localhost:${CERC_NITRO_RPC_PORT}\"#g" "$f" + sed -i "s#\"CERC_RUNTIME_ENV_TARGET_URL\"#\"http://localhost:5678\"#g" "$f" + done + http-server -p $CERC_NITRO_AUTH_UI_PORT /app-node/packages/nitro-auth-gui/dist & +fi + +if [[ "$CERC_NITRO_AUTH_ON" == "true" ]] && [[ -d "/app-node/packages/nitro-auth/dist" ]]; then + bash -c "sleep 6 && cd /app-node/packages/nitro-auth && yarn start" & +fi + +if [[ "$CERC_NITRO_RELAY_ON" == "true" ]]; then + if [[ ! -f "/app/deployment/relay-node.json" ]]; then + node /usr/local/lib/node_modules/@cerc-io/peer/dist/cli/create-peer.js \ + -f /app/deployment/relay-node.json + fi + DEBUG='laconic:*' node /usr/local/lib/node_modules/@cerc-io/peer/dist/cli/relay.js \ + --host 0.0.0.0 \ + -f /app/deployment/relay-node.json & +fi + +if [[ -z "$CERC_CHAIN_START_BLOCK" ]]; then + if [[ ! -f "/app/deployment/chainstartblock.json" ]]; then + curl --location "$(echo $CERC_NITRO_CHAIN_URL | sed 's/^ws/http/' | sed 's#/ws/#/#')" \ + --header 'Content-Type: application/json' \ + --data '{ + "jsonrpc": "2.0", + "id": 124, + "method": "eth_blockNumber", + "params": [] + }' > /app/deployment/chainstartblock.json + fi + CERC_CHAIN_START_BLOCK=$(printf "%d" `cat /app/deployment/chainstartblock.json | jq -r '.result'`) +fi + +cd /app +./nitro \ + -chainurl ${CERC_NITRO_CHAIN_URL} \ + -msgport ${CERC_NITRO_MSG_PORT} \ + -rpcport ${CERC_NITRO_RPC_PORT} \ + -wsmsgport ${CERC_NITRO_WS_MSG_PORT} \ + -publicip "0.0.0.0" \ + -pk ${CERC_NITRO_PK:-$CERC_NITRO_CHAIN_PK} \ + -chainpk ${CERC_NITRO_CHAIN_PK} \ + -naaddress ${NA_ADDRESS} \ + -vpaaddress ${VPA_ADDRESS} \ + -caaddress ${CA_ADDRESS} \ + -usedurablestore=${CERC_NITRO_USE_DURABLE_STORE} \ + -durablestorefolder ${CERC_NITRO_DURABLE_STORE_FOLDER} \ + -bootpeers "${CERC_NITRO_BOOT_PEERS}" \ + -chainstartblock $CERC_CHAIN_START_BLOCK \ No newline at end of file diff --git a/stack-orchestrator/config/nitro-auth/alice.env b/stack-orchestrator/config/nitro-auth/alice.env new file mode 100644 index 0000000..2de2a01 --- /dev/null +++ b/stack-orchestrator/config/nitro-auth/alice.env @@ -0,0 +1,19 @@ +# SET ME! Your on-chain private key. +#CERC_NITRO_CHAIN_PK= + +# Default is CERC_NITRO_CHAIN_PK. +#CERC_NITRO_PK= + +# SET ME! The WebSocket to connect to. +#CERC_NITRO_CHAIN_URL=wss://linea-sepolia.infura.io/ws/v3/ + +CERC_NITRO_AUTH_ON=false +CERC_NITRO_AUTH_RPC_PORT=4006 +CERC_NITRO_AUTH_UI_PORT=4206 +CERC_NITRO_BOOT_PEERS="/dns4/go-nitro-bootnode/tcp/3008/p2p/16Uiu2HAmFYz5YPf3GtkfQsAwYJfDsKSm34U9qAiTwxW7RJUVGMRK" +CERC_NITRO_DURABLE_STORE_FOLDER=/app/data/nitro-store +CERC_NITRO_MSG_PORT=3006 +CERC_NITRO_RPC_PORT=4006 +CERC_NITRO_UI_PORT=4106 +CERC_NITRO_USE_DURABLE_STORE=true +CERC_NITRO_WS_MSG_PORT=5006 \ No newline at end of file diff --git a/stack-orchestrator/config/nitro-auth/bob.env b/stack-orchestrator/config/nitro-auth/bob.env new file mode 100644 index 0000000..056a5c1 --- /dev/null +++ b/stack-orchestrator/config/nitro-auth/bob.env @@ -0,0 +1,21 @@ +# SET ME! Your on-chain private key. +#CERC_NITRO_CHAIN_PK= + +# Default is CERC_NITRO_CHAIN_PK. +#CERC_NITRO_PK= + +# SET ME! The WebSocket to connect to. +#CERC_NITRO_CHAIN_URL=wss://linea-sepolia.infura.io/ws/v3/ + +CERC_NITRO_AUTH_ON=true +CERC_NITRO_AUTH_RPC_PORT=4007 +CERC_NITRO_AUTH_UI_PORT=4207 +CERC_NITRO_BOOT_PEERS="/dns4/go-nitro-bootnode/tcp/3008/p2p/16Uiu2HAmFYz5YPf3GtkfQsAwYJfDsKSm34U9qAiTwxW7RJUVGMRK" +CERC_NITRO_DURABLE_STORE_FOLDER=/app/data/nitro-store +CERC_NITRO_MSG_PORT=3007 +CERC_NITRO_RPC_PORT=4007 +CERC_NITRO_UI_PORT=4107 +CERC_NITRO_USE_DURABLE_STORE=true +CERC_NITRO_WS_MSG_PORT=5007 +CERC_NITRO_MSG_PUBLIC_IP=127.0.0.1 +CERC_NITRO_MSG_PUBLIC_PORT=5007 diff --git a/stack-orchestrator/config/nitro-auth/bootnode.env b/stack-orchestrator/config/nitro-auth/bootnode.env new file mode 100644 index 0000000..241fbb0 --- /dev/null +++ b/stack-orchestrator/config/nitro-auth/bootnode.env @@ -0,0 +1,17 @@ +CERC_NITRO_CHAIN_PK=596db2ac27479cfdf60f708bf64ae44a1c5090e9446cca011d72bc9a59b47d3d +CERC_NITRO_PK=f41086394674cf00a66448c6688295d7330af39f6f38fed89ea023e39382d6a0 + +# The WebSocket to connect to. +#CERC_NITRO_CHAIN_URL=wss://linea-sepolia.infura.io/ws/v3/ + +CERC_NITRO_AUTH_ON=false +CERC_NITRO_AUTH_RPC_PORT=4008 +CERC_NITRO_AUTH_UI_PORT=4208 +CERC_NITRO_DURABLE_STORE_FOLDER=/app/data/nitro-store +CERC_NITRO_MSG_PORT=3008 +CERC_NITRO_RPC_PORT=4008 +CERC_NITRO_UI_PORT=4108 +CERC_NITRO_USE_DURABLE_STORE=true +CERC_NITRO_WS_MSG_PORT=5008 + +CERC_SCRIPT_DEBUG=true \ No newline at end of file diff --git a/stack-orchestrator/config/nitro-auth/caddy/Caddyfile b/stack-orchestrator/config/nitro-auth/caddy/Caddyfile new file mode 100644 index 0000000..04c8069 --- /dev/null +++ b/stack-orchestrator/config/nitro-auth/caddy/Caddyfile @@ -0,0 +1,48 @@ +:5678 { + handle /pay* { + reverse_proxy http://go-nitro-bob:8547 + } + + @eth-key-in-header { + path_regexp /eth/?$ + header X-Api-Key * + } + + handle @eth-key-in-header { + forward_auth go-nitro-bob:8547 { + uri /auth/{header.x-api-key} + } + rewrite * / + reverse_proxy {$CERC_ETH_RPC_ENDPOINT} { + header_up Host {upstream_hostport} + header_up -X-Forwarded-* + } + } + + @eth-key-in-path { + path_regexp apikey eth/(.+)$ + } + + handle @eth-key-in-path { + forward_auth go-nitro-bob:8547 { + uri /auth/{re.apikey.1} + } + rewrite * / + reverse_proxy {$CERC_ETH_RPC_ENDPOINT} { + header_up Host {upstream_hostport} + header_up -X-Forwarded-* + } + } + + handle /eth* { + respond "401 Unauthorized" 401 + } + + handle /ts-nitro* { + reverse_proxy http://ts-nitro-charlie:3000 + } + + handle { + reverse_proxy http://go-nitro-alice:4206 + } +} diff --git a/stack-orchestrator/config/nitro-auth/charlie.env b/stack-orchestrator/config/nitro-auth/charlie.env new file mode 100644 index 0000000..b410baa --- /dev/null +++ b/stack-orchestrator/config/nitro-auth/charlie.env @@ -0,0 +1,19 @@ +# SET ME! Your on-chain private key. +#CERC_NITRO_CHAIN_PK= + +# Default is CERC_NITRO_CHAIN_PK. +#CERC_NITRO_PK= + +# SET ME! The WebSocket to connect to. +#CERC_NITRO_CHAIN_URL=wss://linea-sepolia.infura.io/ws/v3/ + +CERC_NITRO_AUTH_ON=false +CERC_NITRO_AUTH_RPC_PORT=4009 +CERC_NITRO_AUTH_UI_PORT=4209 +CERC_NITRO_BOOT_PEERS="/dns4/go-nitro-bootnode/tcp/3008/p2p/16Uiu2HAmFYz5YPf3GtkfQsAwYJfDsKSm34U9qAiTwxW7RJUVGMRK" +CERC_NITRO_DURABLE_STORE_FOLDER=/app/data/nitro-store +CERC_NITRO_MSG_PORT=3009 +CERC_NITRO_RPC_PORT=4009 +CERC_NITRO_UI_PORT=4109 +CERC_NITRO_USE_DURABLE_STORE=true +CERC_NITRO_WS_MSG_PORT=5009 diff --git a/stack-orchestrator/config/nitro-contracts/deploy.sh b/stack-orchestrator/config/nitro-contracts/deploy.sh new file mode 100755 index 0000000..758837b --- /dev/null +++ b/stack-orchestrator/config/nitro-contracts/deploy.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +set -e +if [ -n "$CERC_SCRIPT_DEBUG" ]; then + set -x +fi + +nitro_addresses_file="/app/deployment/nitro-addresses.json" + +# Check if CERC_NA_ADDRESS environment variable set to skip contract deployment +if [ -n "$CERC_NA_ADDRESS" ]; then + echo "CERC_NA_ADDRESS is set to '$CERC_NA_ADDRESS'" + echo "CERC_VPA_ADDRESS is set to '$CERC_VPA_ADDRESS'" + echo "CERC_CA_ADDRESS is set to '$CERC_CA_ADDRESS'" + echo "Skipping Nitro contracts deployment" + exit +fi + +# Check and exit if a deployment already exists (on restarts) +if [ -f ${nitro_addresses_file} ]; then + echo "${nitro_addresses_file} already exists, skipping Nitro contracts deployment" + cat ${nitro_addresses_file} + exit +fi + +echo "Using ETH RPC endpoint ${CERC_ETH_RPC_ENDPOINT}" + +# Wait till ETH RPC endpoint is available with block number > 1 +retry_interval=5 +while true; do + block_number_hex=$(curl -s -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' ${CERC_ETH_RPC_ENDPOINT} | jq -r '.result') + + # Check if the request call was successful + if [ $? -ne 0 ]; then + echo "RPC endpoint not yet available, retrying in $retry_interval seconds..." + sleep $retry_interval + continue + fi + + # Convert hex to decimal + block_number_dec=$(printf %u ${block_number_hex}) + + # Check if block number is > 1 to avoid failures in the deployment + if [ "$block_number_dec" -ge 1 ]; then + echo "RPC endpoint is up" + break + else + echo "RPC endpoint not yet available, retrying in $retry_interval seconds..." + sleep $retry_interval + continue + fi +done + +echo "Using CERC_PRIVATE_KEY_DEPLOYER from env" + +yarn test:deploy-contracts --chainUrl ${CERC_ETH_RPC_ENDPOINT} --key ${CERC_PRIVATE_KEY_DEPLOYER} --addressesFilePath ${nitro_addresses_file} +cat ${nitro_addresses_file} diff --git a/stack-orchestrator/config/nitro-rpc-client/start.sh b/stack-orchestrator/config/nitro-rpc-client/start.sh new file mode 100755 index 0000000..c61eb04 --- /dev/null +++ b/stack-orchestrator/config/nitro-rpc-client/start.sh @@ -0,0 +1,99 @@ +#!/bin/bash + +CERC_NITRO_RPC_FUND_AMOUNT=${CERC_NITRO_RPC_FUND_AMOUNT:-0} +CERC_NITRO_RPC_HOST_ALICE=${CERC_NITRO_RPC_HOST_ALICE:-go-nitro-alice} +CERC_NITRO_RPC_PORT_ALICE=${CERC_NITRO_RPC_PORT_ALICE:-4006} +CERC_NITRO_USE_TLS=${CERC_NITRO_USE_TLS:-false} +CERC_NITRO_ADDRESS_BOB=${CERC_NITRO_ADDRESS_BOB:-0xe07e314501cc73b24cf45a6577486017300e153c} + + +# Wait till chain endpoint is available +retry_interval=5 +while true; do + nc -z -w 1 "$CERC_NITRO_RPC_HOST_ALICE" "$CERC_NITRO_RPC_PORT_ALICE" + + if [ $? -eq 0 ]; then + echo "Nitro endpoint is available" + break + fi + + echo "Nitro endpoint not yet available, retrying in $retry_interval seconds..." + sleep $retry_interval +done + +if [[ "$CERC_NITRO_RPC_FUND_AMOUNT" -gt 0 ]]; then + nitro-rpc-client -h $CERC_NITRO_RPC_HOST_ALICE \ + -p $CERC_NITRO_RPC_PORT_ALICE \ + -s=$CERC_NITRO_USE_TLS \ + get-all-ledger-channels | \ + jq "[.[] | select(.Status == \"Open\") | select(.Balance.Them == \"$CERC_NITRO_ADDRESS_BOB\")] | first" > \ + /app/deployment/nitro-ledger-channel-alice-to-bob.json + + ledger_channel=$(jq -r '.ID' /app/deployment/nitro-ledger-channel-alice-to-bob.json 2>/dev/null | sed 's/^null$//') + + if [[ -z "${ledger_channel}" ]]; then + echo "Creating new ledger channel ..." + nitro-rpc-client -h $CERC_NITRO_RPC_HOST_ALICE \ + -p $CERC_NITRO_RPC_PORT_ALICE \ + -s=$CERC_NITRO_USE_TLS \ + -n \ + direct-fund --amount $CERC_NITRO_RPC_FUND_AMOUNT $CERC_NITRO_ADDRESS_BOB + + nitro-rpc-client -h $CERC_NITRO_RPC_HOST_ALICE \ + -p $CERC_NITRO_RPC_PORT_ALICE \ + -s=$CERC_NITRO_USE_TLS \ + get-all-ledger-channels | \ + jq "[.[] | select(.Status == \"Open\") | select(.Balance.Them == \"$CERC_NITRO_ADDRESS_BOB\")] | first" > \ + /app/deployment/nitro-ledger-channel-alice-to-bob.json + + ledger_channel=$(jq -r '.ID' /app/deployment/nitro-ledger-channel-alice-to-bob.json) + fi + + nitro-rpc-client -h $CERC_NITRO_RPC_HOST_ALICE \ + -p $CERC_NITRO_RPC_PORT_ALICE \ + -s=$CERC_NITRO_USE_TLS \ + get-payment-channels-by-ledger $ledger_channel > \ + /app/deployment/nitro-payment-channels-alice-to-bob.json + + first_open_channel=$(jq '[.[] | select(.Status == "Open")] | first' /app/deployment/nitro-payment-channels-alice-to-bob.json | sed 's/^null$//') + + if [[ -z "$first_open_channel" ]]; then + echo "Creating new payment channel ..." + nitro-rpc-client -h $CERC_NITRO_RPC_HOST_ALICE \ + -p $CERC_NITRO_RPC_PORT_ALICE \ + -s=$CERC_NITRO_USE_TLS \ + -n \ + virtual-fund --amount $((CERC_NITRO_RPC_FUND_AMOUNT/2)) $CERC_NITRO_ADDRESS_BOB + + nitro-rpc-client -h $CERC_NITRO_RPC_HOST_ALICE \ + -p $CERC_NITRO_RPC_PORT_ALICE \ + -s=$CERC_NITRO_USE_TLS \ + get-payment-channels-by-ledger $ledger_channel > \ + /app/deployment/nitro-payment-channels-alice-to-bob.json + + first_open_channel=$(jq '[.[] | select(.Status == "Open")] | first' /app/deployment/nitro-payment-channels-alice-to-bob.json | sed 's/^null$//') + fi + + echo "" + echo "################################################################" + echo "" + + echo "LEDGER:" + cat /app/deployment/nitro-ledger-channel-alice-to-bob.json | jq + echo "" + echo "" + + echo "PAYMENT:" + cat /app/deployment/nitro-payment-channels-alice-to-bob.json | jq + echo "" + echo "" +fi + +if [ -n "$1" ]; then + exec "$@" + exit $? +fi + +while [ 1 -eq 1 ]; do + sleep 100 +done diff --git a/stack-orchestrator/config/ts-nitro/run.sh b/stack-orchestrator/config/ts-nitro/run.sh new file mode 100755 index 0000000..6157017 --- /dev/null +++ b/stack-orchestrator/config/ts-nitro/run.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +if [ -n "$CERC_SCRIPT_DEBUG" ]; then + set -x +fi + +if [ -z "$CERC_NITRO_CHAIN_PK" ] || [ -z "$CERC_NITRO_CHAIN_URL" ]; then + echo "You most set both CERC_NITRO_CHAIN_PK and CERC_NITRO_CHAIN_URL." 1>&2 + exit 1 +fi + +nitro_addresses_file="/app/deployment/nitro-addresses.json" + +# Check if CERC_NA_ADDRESS environment variable is set +if [ -n "$CERC_NA_ADDRESS" ]; then + echo "CERC_NA_ADDRESS is set to '$CERC_NA_ADDRESS'" + echo "CERC_VPA_ADDRESS is set to '$CERC_VPA_ADDRESS'" + echo "CERC_CA_ADDRESS is set to '$CERC_CA_ADDRESS'" + echo "Using the above Nitro addresses" + + NA_ADDRESS=${CERC_NA_ADDRESS} + VPA_ADDRESS=${CERC_VPA_ADDRESS} + CA_ADDRESS=${CERC_CA_ADDRESS} +elif [ -f ${nitro_addresses_file} ]; then + echo "Reading Nitro addresses from ${nitro_addresses_file}" + + NA_ADDRESS=$(jq -r '.nitroAdjudicatorAddress' ${nitro_addresses_file}) + VPA_ADDRESS=$(jq -r '.virtualPaymentAppAddress' ${nitro_addresses_file}) + CA_ADDRESS=$(jq -r '.consensusAppAddress' ${nitro_addresses_file}) +else + echo "File ${nitro_addresses_file} not found" + exit 1 +fi + +cd /app/packages/example-web-app +cat > .env < /dev/null && pwd ) + +docker build -t cerc/go-nitro:local -f ${SCRIPT_DIR}/Dockerfile ${build_command_args} ${CERC_REPO_BASE_DIR}/go-nitro diff --git a/stack-orchestrator/container-build/cerc-nitro-contracts/Dockerfile b/stack-orchestrator/container-build/cerc-nitro-contracts/Dockerfile new file mode 100644 index 0000000..4ed5192 --- /dev/null +++ b/stack-orchestrator/container-build/cerc-nitro-contracts/Dockerfile @@ -0,0 +1,12 @@ +FROM node:18.17.1-alpine3.18 + +RUN apk --update --no-cache add python3 alpine-sdk bash curl jq + +WORKDIR /app + +COPY . . + +RUN echo "Installing dependencies" && \ + yarn && yarn build:node + +WORKDIR /app/packages/nitro-node diff --git a/stack-orchestrator/container-build/cerc-nitro-contracts/build.sh b/stack-orchestrator/container-build/cerc-nitro-contracts/build.sh new file mode 100755 index 0000000..c0aa770 --- /dev/null +++ b/stack-orchestrator/container-build/cerc-nitro-contracts/build.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +# Build cerc/nitro-contracts + +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 ) + +docker build -t cerc/nitro-contracts:local -f ${SCRIPT_DIR}/Dockerfile ${build_command_args} ${CERC_REPO_BASE_DIR}/ts-nitro diff --git a/stack-orchestrator/container-build/cerc-nitro-rpc-client/Dockerfile b/stack-orchestrator/container-build/cerc-nitro-rpc-client/Dockerfile new file mode 100644 index 0000000..2def6d7 --- /dev/null +++ b/stack-orchestrator/container-build/cerc-nitro-rpc-client/Dockerfile @@ -0,0 +1,13 @@ +FROM node:18.17.1-alpine3.18 + +RUN apk --update --no-cache add python3 alpine-sdk bash curl jq + +WORKDIR /app + +COPY packages/nitro-rpc-client . + +RUN echo "Installing dependencies" && \ + yarn + +RUN yarn build +RUN ln -s /app/bin/nitro-rpc-client.js /bin/nitro-rpc-client diff --git a/stack-orchestrator/container-build/cerc-nitro-rpc-client/build.sh b/stack-orchestrator/container-build/cerc-nitro-rpc-client/build.sh new file mode 100755 index 0000000..1a80583 --- /dev/null +++ b/stack-orchestrator/container-build/cerc-nitro-rpc-client/build.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +# Build cerc/nitro-rpc-client + +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 ) + +docker build -t cerc/nitro-rpc-client:local -f ${SCRIPT_DIR}/Dockerfile ${build_command_args} ${CERC_REPO_BASE_DIR}/go-nitro diff --git a/stack-orchestrator/container-build/cerc-ts-nitro/Dockerfile b/stack-orchestrator/container-build/cerc-ts-nitro/Dockerfile new file mode 100644 index 0000000..19977e9 --- /dev/null +++ b/stack-orchestrator/container-build/cerc-ts-nitro/Dockerfile @@ -0,0 +1,12 @@ +FROM node:18.17.1-alpine3.18 + +RUN apk --update --no-cache add python3 alpine-sdk bash curl jq + +WORKDIR /app + +COPY . . + +RUN echo "Installing dependencies" && \ + yarn && yarn build:node && yarn build:browser + +WORKDIR /app diff --git a/stack-orchestrator/container-build/cerc-ts-nitro/build.sh b/stack-orchestrator/container-build/cerc-ts-nitro/build.sh new file mode 100755 index 0000000..128e117 --- /dev/null +++ b/stack-orchestrator/container-build/cerc-ts-nitro/build.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +# Build cerc/ts-nitro + +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 ) + +docker build -t cerc/ts-nitro:local -f ${SCRIPT_DIR}/Dockerfile ${build_command_args} ${CERC_REPO_BASE_DIR}/ts-nitro diff --git a/stack-orchestrator/stacks/nitro-auth/stack.yml b/stack-orchestrator/stacks/nitro-auth/stack.yml new file mode 100644 index 0000000..57fece7 --- /dev/null +++ b/stack-orchestrator/stacks/nitro-auth/stack.yml @@ -0,0 +1,17 @@ +version: "1.0" +name: nitro-auth +description: "Stack to demonstrate payments between various services" +repos: + # for nitro-contracts and ts-nitro example app + - github.com/cerc-io/ts-nitro@telackey/demo-auth + # for go-nitro, nitro-rpc-client, and go-nitro-auth example app + - github.com/cerc-io/go-nitro@telackey/update +containers: + # nitro + - cerc/nitro-contracts + - cerc/ts-nitro + - cerc/go-nitro + - cerc/nitro-rpc-client +pods: + - nitro-contracts + - nitro-auth