forked from cerc-io/stack-orchestrator
Compare commits
22 Commits
main
...
telackey/n
Author | SHA1 | Date | |
---|---|---|---|
500815fb1e | |||
4111e88d53 | |||
659e13e2f8 | |||
781dd263ab | |||
7cce68959f | |||
0cd90ad3dc | |||
90d92c3e15 | |||
202c68d996 | |||
236dea1b44 | |||
9aa02fc26a | |||
80e039d70e | |||
d7f06ad51e | |||
343d31c324 | |||
fd00143b76 | |||
36e89b5a78 | |||
80b299c1e5 | |||
f20dcb8457 | |||
7929a137b6 | |||
247025de28 | |||
76821f00a0 | |||
78219c0e04 | |||
9e87088328 |
141
stack_orchestrator/data/compose/docker-compose-nitro-auth.yml
Normal file
141
stack_orchestrator/data/compose/docker-compose-nitro-auth.yml
Normal file
@ -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:
|
@ -4,6 +4,11 @@ if [ -n "$CERC_SCRIPT_DEBUG" ]; then
|
|||||||
set -x
|
set -x
|
||||||
fi
|
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"
|
nitro_addresses_file="/app/deployment/nitro-addresses.json"
|
||||||
|
|
||||||
# Check if CERC_NA_ADDRESS environment variable is set
|
# Check if CERC_NA_ADDRESS environment variable is set
|
||||||
@ -29,22 +34,86 @@ fi
|
|||||||
|
|
||||||
echo "Running Nitro node"
|
echo "Running Nitro node"
|
||||||
|
|
||||||
# Assuming CERC_NITRO_CHAIN_URL is of format <ws|http>://host:port
|
if [[ "${CERC_GO_NITRO_WAIT_FOR_CHAIN:-true}" == "true" ]]; then
|
||||||
ws_host=$(echo "$CERC_NITRO_CHAIN_URL" | awk -F '://' '{print $2}' | cut -d ':' -f 1)
|
# Assuming CERC_NITRO_CHAIN_URL is of format <ws|http>://host[:port][/foo]
|
||||||
ws_port=$(echo "$CERC_NITRO_CHAIN_URL" | awk -F '://' '{print $2}' | cut -d ':' -f 2)
|
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)
|
||||||
# Wait till chain endpoint is available
|
if [[ "$ws_port" == "$ws_host" ]]; then
|
||||||
retry_interval=5
|
ws_port=""
|
||||||
while true; do
|
|
||||||
nc -z -w 1 "$ws_host" "$ws_port"
|
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
echo "Chain endpoint is available"
|
|
||||||
break
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Chain endpoint not yet available, retrying in $retry_interval seconds..."
|
# Wait till chain endpoint is available
|
||||||
sleep $retry_interval
|
retry_interval=5
|
||||||
done
|
while true; do
|
||||||
|
nc -z -w 1 "$ws_host" "${ws_port:-443}"
|
||||||
|
|
||||||
./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} -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} -tlscertfilepath "" -tlsKeyFilepath ""
|
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
|
19
stack_orchestrator/data/config/nitro-auth/alice.env
Normal file
19
stack_orchestrator/data/config/nitro-auth/alice.env
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# SET ME! Your on-chain private key.
|
||||||
|
#CERC_NITRO_CHAIN_PK=<MY_PK_GOES_HERE>
|
||||||
|
|
||||||
|
# Default is CERC_NITRO_CHAIN_PK.
|
||||||
|
#CERC_NITRO_PK=<MY_PK_GOES_HERE>
|
||||||
|
|
||||||
|
# SET ME! The WebSocket to connect to.
|
||||||
|
#CERC_NITRO_CHAIN_URL=wss://linea-sepolia.infura.io/ws/v3/<MY_API_KEY_GOES_HERE>
|
||||||
|
|
||||||
|
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
|
21
stack_orchestrator/data/config/nitro-auth/bob.env
Normal file
21
stack_orchestrator/data/config/nitro-auth/bob.env
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# SET ME! Your on-chain private key.
|
||||||
|
#CERC_NITRO_CHAIN_PK=<MY_PK_GOES_HERE>
|
||||||
|
|
||||||
|
# Default is CERC_NITRO_CHAIN_PK.
|
||||||
|
#CERC_NITRO_PK=<MY_PK_GOES_HERE>
|
||||||
|
|
||||||
|
# SET ME! The WebSocket to connect to.
|
||||||
|
#CERC_NITRO_CHAIN_URL=wss://linea-sepolia.infura.io/ws/v3/<MY_API_KEY_GOES_HERE>
|
||||||
|
|
||||||
|
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
|
17
stack_orchestrator/data/config/nitro-auth/bootnode.env
Normal file
17
stack_orchestrator/data/config/nitro-auth/bootnode.env
Normal file
@ -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/<MY_API_KEY_GOES_HERE>
|
||||||
|
|
||||||
|
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
|
48
stack_orchestrator/data/config/nitro-auth/caddy/Caddyfile
Normal file
48
stack_orchestrator/data/config/nitro-auth/caddy/Caddyfile
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
19
stack_orchestrator/data/config/nitro-auth/charlie.env
Normal file
19
stack_orchestrator/data/config/nitro-auth/charlie.env
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# SET ME! Your on-chain private key.
|
||||||
|
#CERC_NITRO_CHAIN_PK=<MY_PK_GOES_HERE>
|
||||||
|
|
||||||
|
# Default is CERC_NITRO_CHAIN_PK.
|
||||||
|
#CERC_NITRO_PK=<MY_PK_GOES_HERE>
|
||||||
|
|
||||||
|
# SET ME! The WebSocket to connect to.
|
||||||
|
#CERC_NITRO_CHAIN_URL=wss://linea-sepolia.infura.io/ws/v3/<MY_API_KEY_GOES_HERE>
|
||||||
|
|
||||||
|
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
|
99
stack_orchestrator/data/config/nitro-rpc-client/start.sh
Executable file
99
stack_orchestrator/data/config/nitro-rpc-client/start.sh
Executable file
@ -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
|
45
stack_orchestrator/data/config/ts-nitro/run.sh
Executable file
45
stack_orchestrator/data/config/ts-nitro/run.sh
Executable file
@ -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 <<EOF
|
||||||
|
REACT_APP_RPC_URL=${CERC_RUNTIME_ENV_RPC_URL:-$CERC_NITRO_CHAIN_URL}
|
||||||
|
REACT_APP_TARGET_URL=${CERC_RUNTIME_ENV_TARGET_URL:-$CERC_NITRO_TARGET_URL}
|
||||||
|
REACT_APP_NITRO_PK=${CERC_NITRO_PK:-$CERC_NITRO_CHAIN_PK}
|
||||||
|
REACT_APP_NA_ADDRESS=${NA_ADDRESS}
|
||||||
|
REACT_APP_VPA_ADDRESS=${VPA_ADDRESS}
|
||||||
|
REACT_APP_CA_ADDRESS=${CA_ADDRESS}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
yarn start
|
@ -6,7 +6,7 @@ fi
|
|||||||
|
|
||||||
ETHERBASE=`cat /opt/testnet/build/el/accounts.csv | head -1 | cut -d',' -f2`
|
ETHERBASE=`cat /opt/testnet/build/el/accounts.csv | head -1 | cut -d',' -f2`
|
||||||
NETWORK_ID=`cat /opt/testnet/el/el-config.yaml | grep 'chain_id' | awk '{ print $2 }'`
|
NETWORK_ID=`cat /opt/testnet/el/el-config.yaml | grep 'chain_id' | awk '{ print $2 }'`
|
||||||
NETRESTRICT=`ip addr | grep inet | grep -v '127.0' | awk '{print $2}'`
|
NETRESTRICT=`ip addr | grep 'inet ' | grep -v '127.0' | head -1 | awk '{print $2}'`
|
||||||
CERC_ETH_DATADIR="${CERC_ETH_DATADIR:-$HOME/ethdata}"
|
CERC_ETH_DATADIR="${CERC_ETH_DATADIR:-$HOME/ethdata}"
|
||||||
CERC_PLUGINS_DIR="${CERC_PLUGINS_DIR:-/usr/local/lib/plugeth}"
|
CERC_PLUGINS_DIR="${CERC_PLUGINS_DIR:-/usr/local/lib/plugeth}"
|
||||||
|
|
||||||
|
@ -8,9 +8,30 @@ COPY . .
|
|||||||
RUN go build -v -o nitro .
|
RUN go build -v -o nitro .
|
||||||
|
|
||||||
# Reduce image size
|
# Reduce image size
|
||||||
FROM debian:bullseye-slim
|
FROM node:18-bullseye-slim as builder-node
|
||||||
RUN apt-get update
|
RUN apt-get update
|
||||||
RUN apt-get install -y ca-certificates jq netcat
|
RUN apt-get install -y make
|
||||||
|
WORKDIR /app
|
||||||
|
COPY . .
|
||||||
|
RUN find . -name 'node_modules' | xargs -n1 rm -rf
|
||||||
|
RUN find . -name 'dist' | xargs -n1 rm -rf
|
||||||
|
RUN yarn
|
||||||
|
WORKDIR /app/packages/nitro-gui
|
||||||
|
RUN VITE_RPC_HOST=CERC_RUNTIME_ENV_RPC_HOST yarn build
|
||||||
|
RUN if [ -d /app/packages/nitro-auth-gui ]; then \
|
||||||
|
cd /app/packages/nitro-auth-gui && \
|
||||||
|
VITE_RPC_URL=CERC_RUNTIME_ENV_RPC_URL VITE_TARGET_URL=CERC_RUNTIME_ENV_TARGET_URL yarn build; \
|
||||||
|
fi
|
||||||
|
WORKDIR /app/packages/nitro-auth
|
||||||
|
RUN if [ -d /app/packages/nitro-auth ]; then cd /app/packages/nitro-auth && yarn build; fi
|
||||||
|
|
||||||
|
FROM node:18-bullseye-slim
|
||||||
|
RUN apt-get update
|
||||||
|
RUN apt-get install -y ca-certificates jq netcat make curl wget
|
||||||
RUN rm -rf /var/lib/apt/lists/*
|
RUN rm -rf /var/lib/apt/lists/*
|
||||||
|
RUN npm install -g http-server
|
||||||
|
RUN npm config set @cerc-io:registry https://git.vdb.to/api/packages/cerc-io/npm/
|
||||||
|
RUN npm install -g @cerc-io/peer
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=builder /app/nitro .
|
COPY --from=builder /app/nitro .
|
||||||
|
COPY --from=builder-node /app /app-node
|
@ -4,9 +4,10 @@ RUN apk --update --no-cache add python3 alpine-sdk bash curl jq
|
|||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY . .
|
COPY packages/nitro-rpc-client .
|
||||||
|
|
||||||
RUN echo "Installing dependencies" && \
|
RUN echo "Installing dependencies" && \
|
||||||
yarn
|
yarn
|
||||||
|
|
||||||
RUN cd packages/nitro-rpc-client
|
RUN yarn build
|
||||||
|
RUN ln -s /app/bin/nitro-rpc-client.js /bin/nitro-rpc-client
|
||||||
|
@ -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
|
9
stack_orchestrator/data/container-build/cerc-ts-nitro/build.sh
Executable file
9
stack_orchestrator/data/container-build/cerc-ts-nitro/build.sh
Executable file
@ -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
|
104
stack_orchestrator/data/stacks/nitro-auth/README.md
Normal file
104
stack_orchestrator/data/stacks/nitro-auth/README.md
Normal file
@ -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/<MY_API_KEY>`
|
||||||
|
|
||||||
|
#### 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=<PRIV_KEY_HERE>
|
||||||
|
CERC_ETH_RPC_ENDPOINT=https://rpc.sepolia.linea.build
|
||||||
|
|
||||||
|
# The WebSocket chain URL.
|
||||||
|
CERC_NITRO_CHAIN_URL=wss://linea-sepolia.infura.io/ws/v3/<MY_API_KEY_HERE>
|
||||||
|
|
||||||
|
# Private key for "Alice" account (payer)
|
||||||
|
CERC_NITRO_CHAIN_PK_ALICE=<ALICE_PRIVATE_KEY_HERE>
|
||||||
|
|
||||||
|
# Private key for "Bob" account (payee)
|
||||||
|
CERC_NITRO_CHAIN_PK_BOB=<BOB_PRIVATE_KEY_HERE>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Start the stack
|
||||||
|
```
|
||||||
|
$ laconic-so deployment --dir /srv/nitro-auth up
|
||||||
|
```
|
||||||
|
|
||||||
|
### Open the webapp
|
||||||
|
|
||||||
|
Visit http://localhost:5678
|
17
stack_orchestrator/data/stacks/nitro-auth/stack.yml
Normal file
17
stack_orchestrator/data/stacks/nitro-auth/stack.yml
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user