-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add a mobymask-v3 stack * Fix Nitro deployment script and add watcher container * Setup Nitro config * Run build after setting Nitro addresses * Setup consensus config * Add a container for web-app * Use node 18 for the web-app * Persist Nitro node data to a volume * Add clean up steps * Update query rates
- Loading branch information
1 parent
ed9c253
commit 3dc9cd5
Showing
21 changed files
with
929 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
version: '3.2' | ||
|
||
services: | ||
# Builds and serves the MobyMask v3 react-app | ||
mobymask-v3-app: | ||
restart: unless-stopped | ||
image: cerc/mobymask-ui:local | ||
env_file: | ||
- ../config/watcher-mobymask-v3/mobymask-params.env | ||
environment: | ||
CERC_SCRIPT_DEBUG: ${CERC_SCRIPT_DEBUG} | ||
CERC_CHAIN_ID: ${CERC_CHAIN_ID} | ||
CERC_DEPLOYED_CONTRACT: ${CERC_DEPLOYED_CONTRACT} | ||
CERC_RELAY_NODES: ${CERC_RELAY_NODES} | ||
CERC_DENY_MULTIADDRS: ${CERC_DENY_MULTIADDRS} | ||
CERC_PUBSUB: ${CERC_PUBSUB} | ||
CERC_RELEASE: "laconic-v3" | ||
CERC_NA_ADDRESS: ${CERC_NA_ADDRESS} | ||
CERC_VPA_ADDRESS: ${CERC_VPA_ADDRESS} | ||
CERC_CA_ADDRESS: ${CERC_CA_ADDRESS} | ||
CERC_APP_WATCHER_URL: ${CERC_APP_WATCHER_URL} | ||
CERC_PAYMENT_NITRO_ADDRESS: ${CERC_PAYMENT_NITRO_ADDRESS} | ||
CERC_SNAP_URL: ${CERC_SNAP_URL} | ||
working_dir: /scripts | ||
command: ["sh", "mobymask-app-start.sh"] | ||
volumes: | ||
- ../config/watcher-mobymask-v3/mobymask-app-start.sh:/scripts/mobymask-app-start.sh | ||
- ../config/watcher-mobymask-v2/mobymask-app-config.json:/app/src/mobymask-app-config.json | ||
ports: | ||
- "127.0.0.1:3004:80" | ||
healthcheck: | ||
test: ["CMD", "nc", "-vz", "localhost", "80"] | ||
interval: 20s | ||
timeout: 5s | ||
retries: 15 | ||
start_period: 10s | ||
extra_hosts: | ||
- "host.docker.internal:host-gateway" |
128 changes: 128 additions & 0 deletions
128
app/data/compose/docker-compose-watcher-mobymask-v3.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
version: '3.2' | ||
|
||
services: | ||
# Starts the PostgreSQL database for watcher | ||
mobymask-watcher-db: | ||
restart: unless-stopped | ||
image: postgres:14-alpine | ||
environment: | ||
- POSTGRES_USER=vdbm | ||
- POSTGRES_MULTIPLE_DATABASES=mobymask-watcher,mobymask-watcher-job-queue | ||
- POSTGRES_EXTENSION=mobymask-watcher-job-queue:pgcrypto | ||
- POSTGRES_PASSWORD=password | ||
volumes: | ||
- ../config/postgresql/multiple-postgressql-databases.sh:/docker-entrypoint-initdb.d/multiple-postgressql-databases.sh | ||
- mobymask_watcher_db_data:/var/lib/postgresql/data | ||
ports: | ||
- "127.0.0.1:15432:5432" | ||
healthcheck: | ||
test: ["CMD", "nc", "-v", "localhost", "5432"] | ||
interval: 20s | ||
timeout: 5s | ||
retries: 15 | ||
start_period: 10s | ||
|
||
# Deploys the MobyMask contract and generates an invite link | ||
# Deployment is skipped if CERC_DEPLOYED_CONTRACT env is set | ||
mobymask: | ||
image: cerc/mobymask:local | ||
working_dir: /app/packages/server | ||
env_file: | ||
- ../config/watcher-mobymask-v3/mobymask-params.env | ||
environment: | ||
CERC_SCRIPT_DEBUG: ${CERC_SCRIPT_DEBUG} | ||
ENV: "PROD" | ||
CERC_L2_GETH_RPC: ${CERC_L2_GETH_RPC} | ||
CERC_L1_ACCOUNTS_CSV_URL: ${CERC_L1_ACCOUNTS_CSV_URL} | ||
CERC_PRIVATE_KEY_DEPLOYER: ${CERC_PRIVATE_KEY_DEPLOYER} | ||
CERC_MOBYMASK_APP_BASE_URI: ${CERC_MOBYMASK_APP_BASE_URI} | ||
CERC_DEPLOYED_CONTRACT: ${CERC_DEPLOYED_CONTRACT} | ||
CERC_L2_GETH_HOST: ${CERC_L2_GETH_HOST} | ||
CERC_L2_GETH_PORT: ${CERC_L2_GETH_PORT} | ||
CERC_L2_NODE_HOST: ${CERC_L2_NODE_HOST} | ||
CERC_L2_NODE_PORT: ${CERC_L2_NODE_PORT} | ||
command: ["sh", "deploy-and-generate-invite.sh"] | ||
volumes: | ||
- ../config/network/wait-for-it.sh:/app/packages/server/wait-for-it.sh | ||
- ../config/watcher-mobymask-v2/secrets-template.json:/app/packages/server/secrets-template.json | ||
- ../config/watcher-mobymask-v2/deploy-and-generate-invite.sh:/app/packages/server/deploy-and-generate-invite.sh | ||
- mobymask_deployment:/app/packages/server | ||
extra_hosts: | ||
- "host.docker.internal:host-gateway" | ||
|
||
# Creates peer-id files if they don't exist | ||
peer-ids-gen: | ||
image: cerc/watcher-ts:local | ||
restart: on-failure | ||
environment: | ||
CERC_SCRIPT_DEBUG: ${CERC_SCRIPT_DEBUG} | ||
working_dir: /app/packages/peer | ||
command: ["sh", "generate-peer-ids.sh"] | ||
volumes: | ||
- ../config/watcher-mobymask-v2/generate-peer-ids.sh:/app/packages/peer/generate-peer-ids.sh | ||
- peers_ids:/peer-ids | ||
|
||
# Optionally deploys the Nitro contracts; sets them at the required path | ||
# Starts the MobyMask v3 watcher server | ||
mobymask-watcher-server: | ||
image: cerc/watcher-mobymask-v3:local | ||
restart: unless-stopped | ||
depends_on: | ||
mobymask-watcher-db: | ||
condition: service_healthy | ||
peer-ids-gen: | ||
condition: service_completed_successfully | ||
mobymask: | ||
condition: service_completed_successfully | ||
env_file: | ||
- ../config/watcher-mobymask-v3/mobymask-params.env | ||
environment: | ||
CERC_SCRIPT_DEBUG: ${CERC_SCRIPT_DEBUG} | ||
CERC_L2_GETH_RPC: ${CERC_L2_GETH_RPC} | ||
CERC_L1_ACCOUNTS_CSV_URL: ${CERC_L1_ACCOUNTS_CSV_URL} | ||
CERC_PRIVATE_KEY_DEPLOYER: ${CERC_PRIVATE_KEY_DEPLOYER} | ||
CERC_RELAY_PEERS: ${CERC_RELAY_PEERS} | ||
CERC_DENY_MULTIADDRS: ${CERC_DENY_MULTIADDRS} | ||
CERC_PUBSUB: ${CERC_PUBSUB} | ||
CERC_RELAY_ANNOUNCE_DOMAIN: ${CERC_RELAY_ANNOUNCE_DOMAIN} | ||
CERC_ENABLE_PEER_L2_TXS: ${CERC_ENABLE_PEER_L2_TXS} | ||
CERC_DEPLOYED_CONTRACT: ${CERC_DEPLOYED_CONTRACT} | ||
CERC_NA_ADDRESS: ${CERC_NA_ADDRESS} | ||
CERC_VPA_ADDRESS: ${CERC_VPA_ADDRESS} | ||
CERC_CA_ADDRESS: ${CERC_CA_ADDRESS} | ||
CERC_PRIVATE_KEY_PEER: ${CERC_PRIVATE_KEY_PEER} | ||
CERC_PRIVATE_KEY_NITRO: ${CERC_PRIVATE_KEY_NITRO} | ||
CERC_PEER_ID: ${CERC_PEER_ID} | ||
entrypoint: ["bash", "-c"] | ||
command: ["./deploy-nitro-contracts.sh && ./start-server.sh"] | ||
volumes: | ||
- ../config/watcher-mobymask-v3/deploy-nitro-contracts.sh:/app/deploy-nitro-contracts.sh | ||
- ../config/watcher-mobymask-v3/deploy-nitro-contracts.ts:/app/deploy-nitro-contracts.ts | ||
- ../config/watcher-mobymask-v3/watcher-config-template.toml:/app/environments/watcher-config-template.toml | ||
- ../config/watcher-mobymask-v3/watcher-config-rates.toml:/app/environments/rates.toml | ||
- ../config/watcher-mobymask-v3/keys:/app/keys | ||
- ../config/watcher-mobymask-v3/start-server.sh:/app/start-server.sh | ||
- nitro_data:/app/out/nitro-db | ||
- peers_ids:/app/peers | ||
- nitro_addresses:/nitro | ||
- mobymask_deployment:/server | ||
# Expose GQL, metrics and relay node ports | ||
ports: | ||
- "127.0.0.1:3001:3001" | ||
- "127.0.0.1:9001:9001" | ||
- "127.0.0.1:9090:9090" | ||
healthcheck: | ||
test: ["CMD", "busybox", "nc", "localhost", "9090"] | ||
interval: 20s | ||
timeout: 5s | ||
retries: 15 | ||
start_period: 5s | ||
extra_hosts: | ||
- "host.docker.internal:host-gateway" | ||
|
||
volumes: | ||
mobymask_watcher_db_data: | ||
peers_ids: | ||
mobymask_deployment: | ||
nitro_addresses: | ||
nitro_data: |
58 changes: 58 additions & 0 deletions
58
app/data/config/watcher-mobymask-v3/deploy-nitro-contracts.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
#!/bin/bash | ||
|
||
set -e | ||
if [ -n "$CERC_SCRIPT_DEBUG" ]; then | ||
set -x | ||
fi | ||
|
||
CERC_NA_ADDRESS="${CERC_NA_ADDRESS:-${DEFAULT_CERC_NA_ADDRESS}}" | ||
CERC_VPA_ADDRESS="${CERC_VPA_ADDRESS:-${DEFAULT_CERC_VPA_ADDRESS}}" | ||
CERC_CA_ADDRESS="${CERC_CA_ADDRESS:-${DEFAULT_CERC_CA_ADDRESS}}" | ||
|
||
NITRO_ADDRESSES_FILE_PATH="/nitro/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 "Using the above addresses and skipping Nitro contracts deployment" | ||
|
||
# Create the required JSON and write it to a file | ||
nitro_addresses_json=$(jq -n \ | ||
--arg na "$CERC_NA_ADDRESS" \ | ||
--arg vpa "$CERC_VPA_ADDRESS" \ | ||
--arg ca "$CERC_CA_ADDRESS" \ | ||
'.nitroAdjudicatorAddress = $na | .virtualPaymentAppAddress = $vpa | .consensusAppAddress = $ca') | ||
echo "$nitro_addresses_json" > "${NITRO_ADDRESSES_FILE_PATH}" | ||
|
||
exit | ||
fi | ||
|
||
# Check and exit if a deployment already exists (on restarts) | ||
if [ -f ${NITRO_ADDRESSES_FILE_PATH} ]; then | ||
echo "${NITRO_ADDRESSES_FILE_PATH} already exists, skipping Nitro contracts deployment" | ||
exit | ||
fi | ||
|
||
echo "Using L2 RPC endpoint ${CERC_L2_GETH_RPC}" | ||
|
||
if [ -n "$CERC_L1_ACCOUNTS_CSV_URL" ] && \ | ||
l1_accounts_response=$(curl -L --write-out '%{http_code}' --silent --output /dev/null "$CERC_L1_ACCOUNTS_CSV_URL") && \ | ||
[ "$l1_accounts_response" -eq 200 ]; | ||
then | ||
echo "Fetching L1 account credentials using provided URL" | ||
mkdir -p /geth-accounts | ||
wget -O /geth-accounts/accounts.csv "$CERC_L1_ACCOUNTS_CSV_URL" | ||
|
||
# Read the private key of an L1 account to deploy contract | ||
CERC_PRIVATE_KEY_DEPLOYER=$(head -n 1 /geth-accounts/accounts.csv | cut -d ',' -f 3) | ||
else | ||
echo "Couldn't fetch L1 account credentials, using CERC_PRIVATE_KEY_DEPLOYER from env" | ||
fi | ||
|
||
echo "RPC_URL=${CERC_L2_GETH_RPC}" > .env | ||
echo "NITRO_ADDRESSES_FILE_PATH=${NITRO_ADDRESSES_FILE_PATH}" >> .env | ||
echo "PRIVATE_KEY=${CERC_PRIVATE_KEY_DEPLOYER}" >> .env | ||
|
||
yarn ts-node --esm deploy-nitro-contracts.ts |
49 changes: 49 additions & 0 deletions
49
app/data/config/watcher-mobymask-v3/deploy-nitro-contracts.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import 'dotenv/config'; | ||
import fs from 'fs'; | ||
import { providers, Wallet } from 'ethers'; | ||
import { deployContracts } from '@cerc-io/nitro-util'; | ||
|
||
async function main () { | ||
const rpcURL = process.env.RPC_URL; | ||
const addressesFilePath = process.env.NITRO_ADDRESSES_FILE_PATH; | ||
const deployerKey = process.env.PRIVATE_KEY; | ||
|
||
if (!rpcURL) { | ||
console.log('RPC_URL not set, skipping deployment'); | ||
return; | ||
} | ||
|
||
if (!addressesFilePath) { | ||
console.log('NITRO_ADDRESSES_FILE_PATH not set, skipping deployment'); | ||
return; | ||
} | ||
|
||
if (!deployerKey) { | ||
console.log('PRIVATE_KEY not set, skipping deployment'); | ||
return; | ||
} | ||
|
||
const provider = new providers.JsonRpcProvider(process.env.RPC_URL); | ||
const signer = new Wallet(deployerKey, provider); | ||
|
||
const [ | ||
nitroAdjudicatorAddress, | ||
virtualPaymentAppAddress, | ||
consensusAppAddress | ||
] = await deployContracts(signer as any); | ||
|
||
const output = { | ||
nitroAdjudicatorAddress, | ||
virtualPaymentAppAddress, | ||
consensusAppAddress | ||
}; | ||
|
||
fs.writeFileSync(addressesFilePath, JSON.stringify(output, null, 2)); | ||
console.log('Nitro contracts deployed, addresses written to', addressesFilePath); | ||
console.log('Result:', JSON.stringify(output, null, 2)); | ||
} | ||
|
||
main() | ||
.catch((err) => { | ||
console.log(err); | ||
}); |
11 changes: 11 additions & 0 deletions
11
...config/watcher-mobymask-v3/keys/12D3KooWAMjBkFCT9DtCnSDcxftxJzSuTBvzVojabv64cnEvX4AZ.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"peerId": { | ||
"id": "12D3KooWAMjBkFCT9DtCnSDcxftxJzSuTBvzVojabv64cnEvX4AZ", | ||
"privKey": "CAESQAKCrnY0QKTky1I18fqn+VPydXGUv1NYiV+nVKqBFkw/CAjE9sKKIDGnYAo8mivnI6dngFenERY+0Q8AJrPTaXY=", | ||
"pubKey": "CAESIAgIxPbCiiAxp2AKPJor5yOnZ4BXpxEWPtEPACaz02l2" | ||
}, | ||
"consensus": { | ||
"publicKey": "02cd17b05ca998955be5ca7bf4fd4531243d438f1aae7ce8a0ed5159f53cee5b40", | ||
"privateKey": "67d80505614bdf61fca11cbad31d93acb2c7df1c653dc25975d77d05f05f154f" | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
...config/watcher-mobymask-v3/keys/12D3KooWBNEbY3QS4y23ngupDw9PDc4bvNvRJGVRejjV9EZLjux5.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"peerId": { | ||
"id": "12D3KooWBNEbY3QS4y23ngupDw9PDc4bvNvRJGVRejjV9EZLjux5", | ||
"privKey": "CAESQGSTw0ymvn8+wX9Dbvyr4/Gib1q2voe0CC0VyeClMQP6FwW14x0fpRbBIx0XhLdxWHkRndphVg3gVAHyC+7ZI8o=", | ||
"pubKey": "CAESIBcFteMdH6UWwSMdF4S3cVh5EZ3aYVYN4FQB8gvu2SPK" | ||
}, | ||
"consensus": { | ||
"publicKey": "029c8035b3e9401b8f178f7c37285b5cb22501e017340e2058b3b842f2a1f0ae45", | ||
"privateKey": "0261008e8e3ec808168e99333599da38ca59a056a2ae4510a6ad3d8b5cb0918c" | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
...config/watcher-mobymask-v3/keys/12D3KooWSRH6ftgkAZsKZK7UX1Zr6Hx6YAsEepHqzopFszqfTxxi.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"peerId": { | ||
"id": "12D3KooWSRH6ftgkAZsKZK7UX1Zr6Hx6YAsEepHqzopFszqfTxxi", | ||
"privKey": "CAESQHBjlHxfVhZ2gXsBItrIEEgSGKcjMkFiGs3PPz9E3ace9qyWEkvR4oit5ve9SAROVoh20hoa42IC91NIafMaqws=", | ||
"pubKey": "CAESIPaslhJL0eKIreb3vUgETlaIdtIaGuNiAvdTSGnzGqsL" | ||
}, | ||
"consensus": { | ||
"publicKey": "039160c244a7ad8be16a64bdb69e6dbacdcfe20b37076792a0d06032a8097468ca", | ||
"privateKey": "8894685fe81001d75662b079905472699373967451d1255ee5fc669d0a09a9ca" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
#!/bin/bash | ||
|
||
set -e | ||
if [ -n "$CERC_SCRIPT_DEBUG" ]; then | ||
set -x | ||
fi | ||
|
||
CERC_CHAIN_ID="${CERC_CHAIN_ID:-${DEFAULT_CERC_CHAIN_ID}}" | ||
CERC_DEPLOYED_CONTRACT="${CERC_DEPLOYED_CONTRACT:-${DEFAULT_CERC_DEPLOYED_CONTRACT}}" | ||
CERC_RELAY_NODES="${CERC_RELAY_NODES:-${DEFAULT_CERC_RELAY_NODES}}" | ||
CERC_DENY_MULTIADDRS="${CERC_DENY_MULTIADDRS:-${DEFAULT_CERC_DENY_MULTIADDRS}}" | ||
CERC_PUBSUB="${CERC_PUBSUB:-${DEFAULT_CERC_PUBSUB}}" | ||
|
||
echo "Using CERC_RELAY_NODES $CERC_RELAY_NODES" | ||
|
||
if [ -z "$CERC_DEPLOYED_CONTRACT" ]; then | ||
echo "CERC_DEPLOYED_CONTRACT not set" | ||
exit 1 | ||
else | ||
echo "Using CERC_DEPLOYED_CONTRACT ${CERC_DEPLOYED_CONTRACT} from env as the MobyMask contract address" | ||
fi | ||
|
||
# Checkout to the required release/branch | ||
cd /app | ||
git checkout $CERC_RELEASE | ||
|
||
# Check if CERC_NA_ADDRESS 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" | ||
|
||
# Create the required JSON and write it to a file | ||
nitro_addresses_json=$(jq -n \ | ||
--arg na "$CERC_NA_ADDRESS" \ | ||
--arg vpa "$CERC_VPA_ADDRESS" \ | ||
--arg ca "$CERC_CA_ADDRESS" \ | ||
'.nitroAdjudicatorAddress = $na | .virtualPaymentAppAddress = $vpa | .consensusAppAddress = $ca') | ||
echo "$nitro_addresses_json" > /app/src/utils/nitro-addresses.json | ||
else | ||
echo "Nitro addresses not provided" | ||
exit 1 | ||
fi | ||
|
||
# Export config values in a json file | ||
jq --arg address "$CERC_DEPLOYED_CONTRACT" \ | ||
--argjson chainId "$CERC_CHAIN_ID" \ | ||
--argjson relayNodes "$CERC_RELAY_NODES" \ | ||
--argjson denyMultiaddrs "$CERC_DENY_MULTIADDRS" \ | ||
--arg pubsub "$CERC_PUBSUB" \ | ||
'.address = $address | .chainId = $chainId | .relayNodes = $relayNodes | .peer.denyMultiaddrs = $denyMultiaddrs | .peer.pubsub = $pubsub' \ | ||
/app/src/mobymask-app-config.json > /app/src/utils/config.json | ||
|
||
yarn install | ||
|
||
REACT_APP_WATCHER_URI="$CERC_APP_WATCHER_URL/graphql" \ | ||
REACT_APP_PAY_TO_NITRO_ADDRESS="$CERC_PAYMENT_NITRO_ADDRESS" \ | ||
REACT_APP_SNAP_ORIGIN="local:$CERC_SNAP_URL" \ | ||
yarn build | ||
|
||
http-server -p 80 /app/build |
Oops, something went wrong.