testnet-laconicd-stack/testnet-onboarding-demo.md
Prathamesh Musale 7041a4ebe8 Add Nitro node config for users and payments instructions (#28)
Part of [Create a public laconicd testnet](https://www.notion.so/Create-a-public-laconicd-testnet-896a11bdd8094eff8f1b49c0be0ca3b8)

Co-authored-by: Neeraj <neeraj.rtly@gmail.com>
Reviewed-on: cerc-io/testnet-laconicd-stack#28
Co-authored-by: Prathamesh Musale <prathamesh.musale0@gmail.com>
Co-committed-by: Prathamesh Musale <prathamesh.musale0@gmail.com>
2024-09-17 13:55:55 +00:00

1362 lines
45 KiB
Markdown

# testnet-onboarding-demo
## Setup
### Stack Orchestrator
- Follow these steps to install laconic-so: <https://git.vdb.to/cerc-io/stack-orchestrator#install>
### Laconic Wallet
- The `laconic-wallet` can be installed using an APK on an Android device or run as a website using `laconic-wallet-web`
- Follow one of the following (`Setup On Android` or `Setup As Website`) sections as desired
#### Setup On Android
- Install laconic wallet using [latest APK release](https://git.vdb.to/cerc-io/laconic-wallet/releases)
- Download the APK file in latest release `laconic-wallet-debug.apk`
- Install the APK on your device
- It will need third party installation permission to install the APK
- Alternatively, build laconic wallet from source by following the steps below
- Follow the [Install](https://git.vdb.to/cerc-io/laconic-wallet#install) steps from the laconic-wallet README to setup Android Studio
- Clone the repository
```bash
git clone git@git.vdb.to:cerc-io/laconic-wallet.git
```
- Enter the project directory
```bash
cd laconic-wallet
```
- Setup .env
- Copy and update [`.env`](./.env)
```bash
cp .env.example .env
```
- In the `.env` file add your WalletConnect project id. You can generate your own ProjectId at <https://cloud.walletconnect.com> (use `gmail` address)
```bash
WALLET_CONNECT_PROJECT_ID=39bc93c...
```
- Install dependencies
```bash
yarn
```
- Exit project repo
```bash
cd ../
```
#### Setup As Website
- Use the hosted `laconic-wallet-web` at <https://wallet.laconic.com>
- Alternatively, setup the `laconic-wallet-web` stack
- Clone the stack repo:
```bash
laconic-so fetch-stack git.vdb.to/cerc-io/laconic-wallet-web
```
- Build the container image:
```bash
laconic-so --stack ~/cerc/laconic-wallet-web/stack/stack-orchestrator/stack/laconic-wallet-web build-containers
```
- Create a spec file for the deployment:
```bash
laconic-so --stack ~/cerc/laconic-wallet-web/stack/stack-orchestrator/stack/laconic-wallet-web deploy init --output laconic-wallet-web-spec.yml
```
- Edit `network` in the spec file to map container ports to host ports as required:
```bash
network:
ports:
laconic-wallet-web:
- '5000:80'
```
- Create a deployment from the spec file:
```bash
laconic-so --stack ~/cerc/laconic-wallet-web/stack/stack-orchestrator/stack/laconic-wallet-web deploy create --spec-file laconic-wallet-web-spec.yml --deployment-dir laconic-wallet-web-deployment
```
- In the `laconic-wallet-web-deployment/config.env` file, set your wallet connect ProjectId:
```bash
WALLET_CONNECT_ID=39bc93c...
```
### Testnet Onboarding App and Onboarding API Stacks
- For running the onboarding API, create sumsub application token from <https://cockpit.sumsub.com>
- Reference: <https://docs.sumsub.com/docs/app-tokens>
- Clone the stack repo:
```bash
laconic-so fetch-stack git.vdb.to/cerc-io/testnet-onboarding-app-stack
```
- Setup required repositories:
```bash
laconic-so --stack ~/cerc/testnet-onboarding-app-stack/stack-orchestrator/stacks/onboarding-app setup-repositories --pull
laconic-so --stack ~/cerc/testnet-onboarding-app-stack/stack-orchestrator/stacks/onboarding-api setup-repositories --pull
```
- Build the container image:
```bash
laconic-so --stack ~/cerc/testnet-onboarding-app-stack/stack-orchestrator/stacks/onboarding-app build-containers --force-rebuild
laconic-so --stack ~/cerc/testnet-onboarding-app-stack/stack-orchestrator/stacks/onboarding-api build-containers --force-rebuild
```
- Create spec files for deployments, which will map the stack's ports to the host:
```bash
laconic-so --stack ~/cerc/testnet-onboarding-app-stack/stack-orchestrator/stacks/onboarding-app deploy init --output onboarding-app-spec.yml
laconic-so --stack ~/cerc/testnet-onboarding-app-stack/stack-orchestrator/stacks/onboarding-api deploy init --output onboarding-api-spec.yml
```
- Configure ports:
- `onboarding-app-spec.yml`:
```bash
network:
ports:
testnet-onboarding-app:
- '3000:80'
```
- `onboarding-api-spec.yml`:
```bash
network:
ports:
testnet-onboarding-api:
- '3001:3000'
```
- Create deployments:
```bash
laconic-so --stack ~/cerc/testnet-onboarding-app-stack/stack-orchestrator/stacks/onboarding-app deploy create --spec-file onboarding-app-spec.yml --deployment-dir onboarding-app-deployment
laconic-so --stack ~/cerc/testnet-onboarding-app-stack/stack-orchestrator/stacks/onboarding-api deploy create --spec-file onboarding-api-spec.yml --deployment-dir onboarding-api-deployment
```
- Env configuration:
- In the `onboarding-app-deployment/config.env` file, set your wallet connect ProjectId:
```bash
WALLET_CONNECT_ID=39bc93c...
```
- In the `onboarding-api-deployment/config.env` file, set your sumsub application token and secret key:
```bash
SUMSUB_APP_TOKEN=sbx:Xig...
SUMSUB_SECRET_KEY=pIue...
```
### fixturenet-laconicd and laconic-faucet Stacks
- Clone the stack repos:
```bash
laconic-so fetch-stack git.vdb.to/cerc-io/fixturenet-laconicd-stack --git-ssh --pull
laconic-so fetch-stack git.vdb.to/cerc-io/testnet-laconicd-stack --git-ssh --pull
```
- Clone required repositories:
```bash
# laconicd
laconic-so --stack ~/cerc/fixturenet-laconicd-stack/stack-orchestrator/stacks/fixturenet-laconicd setup-repositories --git-ssh --pull
laconic-so --stack ~/cerc/testnet-laconicd-stack/stack-orchestrator/stacks/laconic-faucet setup-repositories --git-ssh --pull
```
- Build the container images:
```bash
# laconicd
laconic-so --stack ~/cerc/fixturenet-laconicd-stack/stack-orchestrator/stacks/fixturenet-laconicd build-containers --force-rebuild
laconic-so --stack ~/cerc/testnet-laconicd-stack/stack-orchestrator/stacks/laconic-faucet build-containers --force-rebuild
```
- Create a deployment for stage 0:
- Create spec files for the deployment:
```bash
laconic-so --stack ~/cerc/fixturenet-laconicd-stack/stack-orchestrator/stacks/fixturenet-laconicd deploy init --output stage0-spec.yml
```
- Edit `network` in the spec file to map container ports to host ports as required:
```bash
# stage0-spec.yml
...
network:
ports:
laconicd:
- '6060'
- '26657:26657'
- '26656:26656'
- '9473:9473'
- '9090:9090'
- '1317:1317'
```
- Create a deployment from the spec file:
```bash
laconic-so --stack ~/cerc/fixturenet-laconicd-stack/stack-orchestrator/stacks/fixturenet-laconicd deploy create --spec-file stage0-spec.yml --deployment-dir stage0-deployment
```
- Update `stage0-deployment` env configuration:
```bash
cat <<EOF > stage0-deployment/config.env
# Set to true to enable adding participants functionality of the onboarding module
ONBOARDING_ENABLED=true
EOF
```
- Create a deployment for stage 1:
- Copy the contents of `stage0-spec.yml` to `stage1-spec.yml`:
```bash
cp stage0-spec.yml stage1-spec.yml
```
- Create a deployment from the spec file:
```bash
laconic-so --stack ~/cerc/fixturenet-laconicd-stack/stack-orchestrator/stacks/fixturenet-laconicd deploy create --spec-file stage1-spec.yml --deployment-dir stage1-deployment
```
- Create a deployment for laconic-faucet:
- Create spec file for the deployment:
```bash
laconic-so --stack ~/cerc/testnet-laconicd-stack/stack-orchestrator/stacks/laconic-faucet deploy init --output laconic-faucet-spec.yml
```
- Edit `network` in the spec file to map container port to host port as required:
```bash
# laconic-faucet-spec.yml
...
network:
ports:
faucet:
- '4000:3000'
```
- Create a deployment from the spec file:
```bash
laconic-so --stack ~/cerc/testnet-laconicd-stack/stack-orchestrator/stacks/laconic-faucet deploy create --spec-file laconic-faucet-spec.yml --deployment-dir laconic-faucet-deployment
# Place in the same namespace as stage0
cp stage0-deployment/deployment.yml laconic-faucet-deployment/deployment.yml
```
### L1 eth and L2 Optimism Stacks
- Clone the stack repo:
```bash
laconic-so fetch-stack git.vdb.to/cerc-io/fixturenet-eth-stacks --pull
laconic-so fetch-stack git.vdb.to/cerc-io/fixturenet-optimism-stack --pull
```
- Clone required repositories:
```bash
# L1 (fixturenet-eth)
laconic-so --stack ~/cerc/fixturenet-eth-stacks/stack-orchestrator/stacks/fixturenet-eth setup-repositories --pull
# L2 (optimism)
laconic-so --stack ~/cerc/fixturenet-optimism-stack/stack/fixturenet-optimism setup-repositories --pull
# If this throws an error as a result of being already checked out to a branch/tag in a repo, remove all repositories from that stack and re-run the command
# The repositories are located in $HOME/cerc by default
```
- Build the container images:
```bash
# Remove any older foundry image with `latest` tag
docker rmi ghcr.io/foundry-rs/foundry:latest
# L1 (fixturenet-eth)
laconic-so --stack ~/cerc/fixturenet-eth-stacks/stack-orchestrator/stacks/fixturenet-eth build-containers --force-rebuild
# L2 (optimism)
laconic-so --stack ~/cerc/fixturenet-optimism-stack/stack/fixturenet-optimism build-containers --force-rebuild
# If errors are thrown during build, old images used by this stack would have to be deleted
```
- NOTE: this will take >10 mins depending on the specs of your machine, and **requires** 16GB of memory or greater.
- Remove any dangling Docker images (to clear up space):
```bash
docker image prune
```
- Create spec files for deployments, which will map the stack's ports and volumes to the host:
```bash
laconic-so --stack ~/cerc/fixturenet-eth-stacks/stack-orchestrator/stacks/fixturenet-eth deploy init --output fixturenet-eth-spec.yml
laconic-so --stack ~/cerc/fixturenet-optimism-stack/stack/fixturenet-optimism deploy init --output fixturenet-optimism-spec.yml
```
- Configure ports:
- `fixturenet-eth-spec.yml`
```yml
...
network:
ports:
fixturenet-eth-bootnode-geth:
- '9898:9898'
- '30303'
fixturenet-eth-geth-1:
- '8545:8545'
- '8546:8546'
- '40000'
- '6060'
fixturenet-eth-lighthouse-1:
- '8001'
...
```
- `fixturenet-optimism-spec.yml`
```yml
...
network:
ports:
op-geth:
- '9545:8545'
- '9546:8546'
...
```
- Create deployments:
Once you've made any needed changes to the spec files, create deployments from them:
```bash
laconic-so --stack ~/cerc/fixturenet-eth-stacks/stack-orchestrator/stacks/fixturenet-eth deploy create --spec-file fixturenet-eth-spec.yml --deployment-dir fixturenet-eth-deployment
laconic-so --stack ~/cerc/fixturenet-optimism-stack/stack/fixturenet-optimism deploy create --spec-file fixturenet-optimism-spec.yml --deployment-dir fixturenet-optimism-deployment
# Place them both in the same namespace (cluster)
cp fixturenet-eth-deployment/deployment.yml fixturenet-optimism-deployment/deployment.yml
```
- Env configuration:
```bash
cat <<EOF > fixturenet-eth-deployment/config.env
CERC_ALLOW_UNPROTECTED_TXS=true
EOF
```
### Go Nitro
- Clone the stack repo:
```bash
laconic-so fetch-stack git.vdb.to/cerc-io/nitro-stack --git-ssh --pull
```
- Clone required repositories:
```bash
laconic-so --stack ~/cerc/nitro-stack/stack-orchestrator/stacks/nitro-node setup-repositories --git-ssh --pull
```
- Build the container images:
```bash
laconic-so --stack ~/cerc/nitro-stack/stack-orchestrator/stacks/nitro-node build-containers --force-rebuild
```
- Create a deployment spec-file for Alice's L1 nitro-node:
- Create spec file for the deployment:
```bash
laconic-so --stack ~/cerc/nitro-stack/stack-orchestrator/stacks/nitro-node deploy init --output l1alice-nitro-spec.yml
```
- Edit `network` in the spec file to map container ports to host ports as required:
```bash
# l1alice-nitro-spec.yml
...
network:
ports:
nitro-node:
- 3007:3005
- 4007:4005
```
- Create a deployment spec-file for Charlie's L1 nitro-node:
- Create spec file for the deployment:
```bash
laconic-so --stack ~/cerc/nitro-stack/stack-orchestrator/stacks/nitro-node deploy init --output l1charlie-nitro-spec.yml
```
- Edit `network` in the spec file to map container ports to host ports as required:
```bash
# l1charlie-nitro-spec.yml
...
network:
ports:
nitro-node:
- 3008:3005
- 4008:4005
```
- Create a deployment spec-file for Alice's L2 nitro-node:
- Create spec file for the deployment:
```bash
laconic-so --stack ~/cerc/nitro-stack/stack-orchestrator/stacks/nitro-node deploy init --output l2alice-nitro-spec.yml
```
- Edit `network` in the spec file to map container ports to host ports as required:
```bash
# l2alice-nitro-spec.yml
...
network:
ports:
nitro-node:
- 3009:3005
- 4009:4005
```
- Create a deployment spec-file for Charlie's L2 nitro-node:
- Create spec file for the deployment:
```bash
laconic-so --stack ~/cerc/nitro-stack/stack-orchestrator/stacks/nitro-node deploy init --output l2charlie-nitro-spec.yml
```
- Edit `network` in the spec file to map container ports to host ports as required:
```bash
# l2charlie-nitro-spec.yml
...
network:
ports:
nitro-node:
- 3010:3005
- 4010:4005
```
## Run
- Start L1, L2 stacks:
(run steps in directory where the stack deployments had been created)
- Start `fixturenet-eth-deployment` deployment:
```bash
laconic-so deployment --dir fixturenet-eth-deployment start
```
- Check status of L1
- Run status check:
```bash
laconic-so deployment --dir fixturenet-eth-deployment exec fixturenet-eth-bootnode-lighthouse "/scripts/status-internal.sh"
```
- Check geth logs to ensure that new blocks are getting created
```bash
laconic-so deployment --dir fixturenet-eth-deployment logs -f fixturenet-eth-geth-1
```
- Start `fixturenet-optimism-deployment` deployment:
```bash
laconic-so deployment --dir fixturenet-optimism-deployment start
```
NOTE: The `fixturenet-optimism-contracts` service will configure and deploy the Optimism contracts to L1, exiting when complete. This may take several minutes; you can follow the progress by following the container's logs
- Follow optimism contracts deployment logs:
```bash
laconic-so deployment --dir fixturenet-optimism-deployment logs -f fixturenet-optimism-contracts
```
- Check L2 logs:
```bash
laconic-so deployment --dir fixturenet-optimism-deployment logs -f op-geth
# Ensure new blocks are getting created
```
- Send ETH from L1 to L2 (run steps in directory where the stack deployments had been created)
- Get information about funded accounts on L1
```bash
curl 127.0.0.1:9898/accounts.csv
```
- Send some ETH from the desired account to the `L1StandardBridgeProxy` contract on L1 to bridge it to L2:
- Set the following variables:
```bash
L1_RPC=http://fixturenet-eth-geth-1:8545
L2_RPC=http://op-geth:8545
DEPLOYMENT_CONTEXT=1212
ACCOUNT=0xe6CE22afe802CAf5fF7d3845cec8c736ecc8d61F
```
- Read the bridge contract address from the L1 deployment records in the `op-node` container:
```bash
BRIDGE=$(laconic-so deployment --dir fixturenet-optimism-deployment exec op-node "cat /l1-deployment/$DEPLOYMENT_CONTEXT-deploy.json" | jq -r .L1StandardBridgeProxy)
# Get the funded account's pk
ACCOUNT_PK=$(laconic-so deployment --dir fixturenet-optimism-deployment exec op-node "jq -r '.AdminKey' /l2-accounts/accounts.json")
```
- Use cast to send ETH to the bridge contract:
```bash
laconic-so deployment --dir fixturenet-eth-deployment exec foundry "cast send --from $ACCOUNT --value 1ether $BRIDGE --rpc-url $L1_RPC --private-key $ACCOUNT_PK"
```
NOTE: This is for sending funds to the contracts deployer account which is also the Bridge node account
- Allow a couple minutes for the bridge to complete
- Check balance on L2
```bash
laconic-so deployment --dir fixturenet-eth-deployment exec foundry "cast balance $ACCOUNT --rpc-url $L2_RPC"
# 100000000000000000
```
- Run the bridge:
- Create a spec-file for the deployment, map container ports to host ports and set env variables:
```bash
laconic-so --stack ~/cerc/nitro-stack/stack-orchestrator/stacks/bridge deploy init --map-ports-to-host any-same --output bridge-nitro-spec.yml --config "NITRO_L1_CHAIN_URL=ws://host.docker.internal:8546,NITRO_L2_CHAIN_URL=ws://host.docker.internal:9546,NITRO_CHAIN_PK=888814df89c4358d7ddb3fa4b0213e7331239a80e1f013eaa7b2deca2a41a218,NITRO_SC_PK=0279651921cd800ac560c21ceea27aab0107b67daf436cdd25ce84cad30159b4,GETH_URL=http://host.docker.internal:8545,OPTIMISM_URL=http://host.docker.internal:9545,GETH_DEPLOYER_PK=$ACCOUNT_PK,OPTIMISM_DEPLOYER_PK=$ACCOUNT_PK,TOKEN_NAME=LaconicNetworkToken,TOKEN_SYMBOL=LNT,INITIAL_TOKEN_SUPPLY=129600"
```
- Create a deployment from the spec file:
```bash
laconic-so --stack ~/cerc/nitro-stack/stack-orchestrator/stacks/bridge deploy create --spec-file bridge-nitro-spec.yml --deployment-dir bridge-deployment
```
- Start the nitro bridge
```bash
laconic-so deployment --dir bridge-deployment start
# Check the logs, ensure that the node is running
laconic-so deployment --dir bridge-deployment logs nitro-bridge -f
```
- Send custom tokens to Alice and Charlie on L1
- Export variables for L1 token address
```bash
export L1_ASSET_ADDRESS="$(laconic-so deployment --dir bridge-deployment exec nitro-contracts "jq -r '.\"1212\"[0].contracts.Token.address' /app/deployment/nitro-addresses.json")"
export A_CHAIN_ADDRESS="0xe22AD83A0dE117bA0d03d5E94Eb4E0d80a69C62a"
export C_CHAIN_ADDRESS="0xf1ac8Dd1f6D6F5c0dA99097c57ebF50CD99Ce293"
```
- Send tokens to Alice and Charlie
```bash
# Send tokens to Alice
laconic-so deployment --dir bridge-deployment exec nitro-contracts "cd packages/nitro-protocol && yarn hardhat transfer --contract $L1_ASSET_ADDRESS --to $A_CHAIN_ADDRESS --amount 1000 --network geth"
#Send tokens to Charlie
laconic-so deployment --dir bridge-deployment exec nitro-contracts "cd packages/nitro-protocol && yarn hardhat transfer --contract $L1_ASSET_ADDRESS --to $C_CHAIN_ADDRESS --amount 1000 --network geth"
```
- Start `onboarding-app` and `onboarding-api` deployments (run where deployments are created):
```bash
# Builds and serves the app
laconic-so deployment --dir onboarding-app-deployment start
# Serves the API to generate access tokens
laconic-so deployment --dir onboarding-api-deployment start
```
Check the health status for onboarding-app container:
```bash
docker ps | grep testnet-onboarding-app
```
Once the container is healthy, the `testnet-onboarding-app` will be accessible at <http://localhost:3000>
- Run Laconic Wallet
- Follow the steps to `Run on Android` or `Run as a website` as per the chosen setup
- Run on Android:
- Connect your phone with the PC (Make sure that USB debugging is enabled on your phone)
- Setup port forwarding for your device using the following command:
```bash
# Get device id
adb devices
# Setup port forwarding
adb -s <device-id> reverse tcp:26657 tcp:26657
```
- Open Laconic Wallet app that was installed from the APK
- Alternatively, you can:
- Set up the Android device
- For a physical device, refer to the [React Native documentation for running on a physical device](https://reactnative.dev/docs/running-on-device)
- For a virtual device, continue with the steps
- Start the application:
```bash
# In laconic-wallet
yarn start
```
- Press `a` to run the application on android and wait till the wallet app opens up on your phone
- Alternatively, run as a website:
- Open `laconic-wallet-web` at <https://wallet.laconic.com>
- Alternatively, run the `laconic-wallet-web` stack:
```bash
laconic-so deployment --dir laconic-wallet-web-deployment start
```
Open `laconic-wallet-web` at <http://localhost:5000>
## Demo
- Start the stack for stage 0 laconicd (run command in directory where stage0-deployment had been created)
```bash
laconic-so deployment --dir stage0-deployment start
# Check the logs, ensure that new blocks are getting created
laconic-so deployment --dir stage0-deployment logs laconicd -f
```
- In laconic-wallet, click on `Create wallet` and update the `laconicd` network using `Edit Network` button:
```bash
Network name - laconicd
New RPC URL - http://127.0.0.1:26657
Gas Price - 1
```
- Run laconic-faucet:
- Get private key of funded faucet account from stage 0 laconicd chain:
```bash
export FAUCET_ACCOUNT_PK=$(laconic-so deployment --dir stage0-deployment exec laconicd "echo y | laconicd keys export alice --keyring-backend test --unarmored-hex --unsafe")
```
- Set the env config for faucet deployment:
```bash
cat <<EOF > laconic-faucet-deployment/config.env
CERC_FAUCET_KEY=$FAUCET_ACCOUNT_PK
EOF
```
- Start the stack for laconic-faucet:
```bash
laconic-so deployment --dir laconic-faucet-deployment start
```
- Get the deployed nitro contract addresses (run in the directory where the deployments were created):
```bash
# Nitro contract addresses
export NA_ADDRESS=$(laconic-so deployment --dir bridge-deployment exec nitro-bridge "jq -r '.\"1212\"[0].contracts.NitroAdjudicator.address' /app/deployment/nitro-addresses.json")
export CA_ADDRESS=$(laconic-so deployment --dir bridge-deployment exec nitro-bridge "jq -r '.\"1212\"[0].contracts.ConsensusApp.address' /app/deployment/nitro-addresses.json")
export VPA_ADDRESS=$(laconic-so deployment --dir bridge-deployment exec nitro-bridge "jq -r '.\"1212\"[0].contracts.VirtualPaymentApp.address' /app/deployment/nitro-addresses.json")
# Contract address of bridge
export BRIDGE_ADDRESS=$(laconic-so deployment --dir bridge-deployment exec nitro-bridge "jq -r '.\"42069\"[0].contracts.Bridge.address' /app/deployment/nitro-addresses.json")
```
- In the wallet, add 2 accounts (Alice and Charlie) for both the networks (`Ethereum` and `laconicd`) by selecting the network and clicking on `Add account`
- Get Ethereum private keys for accounts Alice and Charlie from wallet using the `Show private key` link (to be used as statechannel PKs)
```bash
export A_PRIVATE_KEY=<Alice's Ethereum Private Key>
export C_PRIVATE_KEY=<Charlie's Ethereum Private Key>
```
- Prepare deployments for the nodes
- Create a deployment `l1alice-nitro-deployment` from the spec file
```bash
laconic-so --stack ~/cerc/nitro-stack/stack-orchestrator/stacks/nitro-node deploy create --spec-file l1alice-nitro-spec.yml --deployment-dir l1alice-nitro-deployment
```
- Set the env variables for L1 Alice's nitro-node:
```bash
cat <<EOF > l1alice-nitro-deployment/config.env
NITRO_CHAIN_URL=ws://host.docker.internal:8546
NITRO_SC_PK=$A_PRIVATE_KEY
NITRO_CHAIN_PK=570b909da9669b2f35a0b1ac70b8358516d55ae1b5b3710e95e9a94395090597
NA_ADDRESS=$NA_ADDRESS
VPA_ADDRESS=$VPA_ADDRESS
CA_ADDRESS=$CA_ADDRESS
BRIDGE_ADDRESS=$BRIDGE_ADDRESS
NITRO_BOOTPEERS=/dns4/host.docker.internal/tcp/3005/p2p/16Uiu2HAmJDxLM8rSybX78FH51iZq9PdrwCoCyyHRBCndNzcAYMes
NITRO_EXT_MULTIADDR=/dns4/host.docker.internal/tcp/3007
EOF
```
- Create a deployment `l1charlie-nitro-deployment` from the spec file
```bash
laconic-so --stack ~/cerc/nitro-stack/stack-orchestrator/stacks/nitro-node deploy create --spec-file l1charlie-nitro-spec.yml --deployment-dir l1charlie-nitro-deployment
```
- Set the env variables for L1 Charlie's nitro-node:
```bash
cat <<EOF > l1charlie-nitro-deployment/config.env
NITRO_CHAIN_URL=ws://host.docker.internal:8546
NITRO_SC_PK=$C_PRIVATE_KEY
NITRO_CHAIN_PK=111b7500bdce494d6f4bcfe8c2a0dde2ef92f751d9070fac6475dbd6d8021b3f
NA_ADDRESS=$NA_ADDRESS
VPA_ADDRESS=$VPA_ADDRESS
CA_ADDRESS=$CA_ADDRESS
BRIDGE_ADDRESS=$BRIDGE_ADDRESS
NITRO_BOOTPEERS=/dns4/host.docker.internal/tcp/3005/p2p/16Uiu2HAmJDxLM8rSybX78FH51iZq9PdrwCoCyyHRBCndNzcAYMes
NITRO_EXT_MULTIADDR=/dns4/host.docker.internal/tcp/3008
EOF
```
- Create a deployment `l2alice-nitro-deployment` from the spec file:
```bash
laconic-so --stack ~/cerc/nitro-stack/stack-orchestrator/stacks/nitro-node deploy create --spec-file l2alice-nitro-spec.yml --deployment-dir l2alice-nitro-deployment
```
- Set the env variables for L2 Alice's nitro-node:
```bash
cat <<EOF > l2alice-nitro-deployment/config.env
NITRO_CHAIN_URL=ws://host.docker.internal:9546
NITRO_SC_PK=$A_PRIVATE_KEY
NITRO_CHAIN_PK=570b909da9669b2f35a0b1ac70b8358516d55ae1b5b3710e95e9a94395090597
NA_ADDRESS=$NA_ADDRESS
VPA_ADDRESS=$VPA_ADDRESS
CA_ADDRESS=$CA_ADDRESS
BRIDGE_ADDRESS=$BRIDGE_ADDRESS
NITRO_BOOTPEERS=/dns4/host.docker.internal/tcp/3006/p2p/16Uiu2HAmJDxLM8rSybX78FH51iZq9PdrwCoCyyHRBCndNzcAYMes
NITRO_EXT_MULTIADDR=/dns4/host.docker.internal/tcp/3009
NITRO_L2=true
EOF
```
- Create deployment `l2charlie-nitro-deployment` from the spec files:
```bash
laconic-so --stack ~/cerc/nitro-stack/stack-orchestrator/stacks/nitro-node deploy create --spec-file l2charlie-nitro-spec.yml --deployment-dir l2charlie-nitro-deployment
```
- Set the env variables for L2 Charlie's nitro-node:
```bash
cat <<EOF > l2charlie-nitro-deployment/config.env
NITRO_CHAIN_URL=ws://host.docker.internal:9546
NITRO_SC_PK=$C_PRIVATE_KEY
NITRO_CHAIN_PK=111b7500bdce494d6f4bcfe8c2a0dde2ef92f751d9070fac6475dbd6d8021b3f
NA_ADDRESS=$NA_ADDRESS
VPA_ADDRESS=$VPA_ADDRESS
CA_ADDRESS=$CA_ADDRESS
BRIDGE_ADDRESS=$BRIDGE_ADDRESS
NITRO_BOOTPEERS=/dns4/host.docker.internal/tcp/3006/p2p/16Uiu2HAmJDxLM8rSybX78FH51iZq9PdrwCoCyyHRBCndNzcAYMes
NITRO_EXT_MULTIADDR=/dns4/host.docker.internal/tcp/3010
NITRO_L2=true
EOF
```
- Start nitro nodes for Alice and Charlie on L1 and L2:
- Start the deployment for Alice's L1 node
```bash
laconic-so deployment --dir l1alice-nitro-deployment start
# Check the logs, ensure that the node is running
laconic-so deployment --dir l1alice-nitro-deployment logs nitro-node -f
```
- Start the deployment for Charlie's L1 node
```bash
laconic-so deployment --dir l1charlie-nitro-deployment start
# Check the logs, ensure that the node is running
laconic-so deployment --dir l1charlie-nitro-deployment logs nitro-node -f
```
- Start the deployment for Alice's L2 node
```bash
laconic-so deployment --dir l2alice-nitro-deployment start
# Check the logs, ensure that the node is running
laconic-so deployment --dir l2alice-nitro-deployment logs nitro-node -f
```
- Start the deployment for Charlie's L2 node
```bash
laconic-so deployment --dir l2charlie-nitro-deployment start
# Check the logs, ensure that the node is running
laconic-so deployment --dir l2charlie-nitro-deployment logs nitro-node -f
```
- Create ledger channels on L1 and mirrored channels on L2
- Open new terminal, check that no channels exist on L2
```bash
laconic-so deployment --dir bridge-deployment exec nitro-rpc-client "nitro-rpc-client get-all-l2-channels -p 4005 -h nitro-bridge"
```
- Set address of bridge and address of custom token on L1 in the current terminal
```bash
export BRIDGE_NITRO_ADDRESS=0xBBB676f9cFF8D242e9eaC39D063848807d3D1D94
export L1_ASSET_ADDRESS="$(laconic-so deployment --dir bridge-deployment exec nitro-contracts "jq -r '.\"1212\"[0].contracts.Token.address' /app/deployment/nitro-addresses.json")"
```
- Create ledger channel between A and Bridge with custom token
```bash
laconic-so deployment --dir l1alice-nitro-deployment exec nitro-rpc-client "nitro-rpc-client direct-fund $BRIDGE_NITRO_ADDRESS --assetAddress $L1_ASSET_ADDRESS --alphaAmount 1000000 --betaAmount 1000000 -p 4005 -h nitro-node"
```
- Once direct-fund objective is complete, bridge will create mirrored channel on L2
- Check node A' logs to see bridged-fund objective completed
- Check the [Troubleshooting](#troubleshooting) section if command to create a ledger channel fails or gets stuck
- Check status of L1 ledger channel between A and Bridge
```bash
laconic-so deployment --dir l1alice-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-ledger-channel <ledger channel ID> -p 4005 -h nitro-node"
# Expected output:
# {
# ID: '0x161d289a50222caa781db215bb82a3ede4f557217742245525b8e8cbff04ec21',
# Status: 'Open',
# Balance: {
# AssetAddress: '<Token address on L1>',
# Me: '0xaaa6628ec44a8a742987ef3a114ddfe2d4f7adce',
# Them: '0xbbb676f9cff8d242e9eac39d063848807d3d1d94',
# MyBalance: 1000000n,
# TheirBalance: 1000000n
# },
# ChannelMode: 'Open'
# }
```
- Create ledger channel between C and Bridge with custom token
```bash
laconic-so deployment --dir l1charlie-nitro-deployment exec nitro-rpc-client "nitro-rpc-client direct-fund $BRIDGE_NITRO_ADDRESS --assetAddress $L1_ASSET_ADDRESS --alphaAmount 1000000 --betaAmount 1000000 -p 4005 -h nitro-node"
```
- Once direct fund objective is complete, bridge will create mirrored channel on L2
- Check node C' logs to see bridged-fund objective completed
- Check the [Troubleshooting](#troubleshooting) section if command to create a ledger channel fails or gets stuck
- Check status of L1 ledger channel between C and Bridge
```bash
laconic-so deployment --dir l1charlie-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-ledger-channel <ledger channel ID> -p 4005 -h nitro-node"
# Expected output:
# {
# ID: '0x69a3f09b6f4f94f033cf084e6e4a9453438c45b43606e9a95f5434f4c6527543',
# Status: 'Open',
# Balance: {
# AssetAddress: '<Token address on L1>',
# Me: '0xa8d2d06ace9c7ffc24ee785c2695678aecdfd7a0',
# Them: '0xbbb676f9cff8d242e9eac39d063848807d3d1d94',
# MyBalance: 1000000n,
# TheirBalance: 1000000n
# },
# ChannelMode: 'Open'
# }
```
- Check status of all L2 mirrored ledger channels
```bash
laconic-so deployment --dir bridge-deployment exec nitro-rpc-client "nitro-rpc-client get-all-l2-channels -p 4005 -h nitro-bridge"
# Expected output:
# {"ID":"0x15dbe6b996e4e46fdd6ea3e2074cbca58014dbb07368e3e7ba286df5c7b9da0d","Status":"Open","Balance":{"AssetAddress":"<Token_address_on_L2>","Me":"0xbbb676f9cff8d242e9eac39d063848807d3d1d94","Them":"0xa8d2d06ace9c7ffc24ee785c2695678aecdfd7a0","MyBalance":1000000,"TheirBalance":1000000},"ChannelMode":"Open"}
# {"ID":"0x6a9f5ccf1fa802525d794f4a899897f947615f6acc7141e61e056a8bfca29179","Status":"Open","Balance":{"AssetAddress":"<Token_address_on_L2>","Me":"0xbbb676f9cff8d242e9eac39d063848807d3d1d94","Them":"0xaaa6628ec44a8a742987ef3a114ddfe2d4f7adce","MyBalance":1000000,"TheirBalance":1000000},"ChannelMode":"Open"}
```
In above expected output the following are observed
- In ledger channel with ID `0x15dbe6b996e4e46fdd6ea3e2074cbca58014dbb07368e3e7ba286df5c7b9da0d`
- Alice is a participant since `Them` address is `0xa8d2d06ace9c7ffc24ee785c2695678aecdfd7a0`
- Alice amount is `1000000` since `TheirBalance` corresponds to her amount
- In ledger channel with ID `0x6a9f5ccf1fa802525d794f4a899897f947615f6acc7141e61e056a8bfca29179`
- Charlie is participant since `Them` address is `0xaaa6628ec44a8a742987ef3a114ddfe2d4f7adce`
- Charlie amount is `1000000` since `TheirBalance` corresponds to his amount
- Onboard participants
- Open the `testnet-onboarding-app` at <http://localhost:3000>
- Read and accept the `Terms and Conditions`
- Connect testnet-onboarding app to the wallet:
- Click on `CONNECT WALLET` button on the testnet-onboarding app
- Click on the WalletConnect icon on the top right corner in the wallet
- If using the wallet Android app, scan the QR code from the onboarding app
- If using the wallet website, enter WalletConnect URI for pairing
- In the onboarding app, choose Alice's nitro and laconicd account to onboard
- Use nitro accounts for which ledger channels have been created on L2
- Sign using the nitro key
- Approve sign request on Wallet
- Perform the user verification steps
- Select the desired participant role (`Validator` or `Participant`) and accept the onboarding terms and conditions
- In the next step, fund your laconic account by clicking on the `REQUEST TOKENS FROM FAUCET` button; ensure that the displayed balance is updated
- Send transaction request to the wallet
- From wallet, approve and send transaction to laconicd chain
- Repeat onboarding for other (Charlies's) account by clicking on the web app header "Testnet Onboarding"
- List the participants on stage 0 (run in the directory where laconicd deployment was created):
```bash
laconic-so deployment --dir stage0-deployment exec laconicd "laconicd query onboarding list"
# Expected output
# - cosmos_address: <Alice Laconic address>
# ethereum_address: <Alice Ethereum address>
# - cosmos_address: <Charlie Laconic address>
# ethereum_address: <Charlie Ethereum address>
```
- Halt the stage 0 laconicd deployment:
```bash
# Run where deployments are created
laconic-so deployment --dir stage0-deployment stop
```
- Use the scripts in fixturenet-laconicd stack to generate genesis file for stage 1 with token allocations:
```bash
# Set current working dir path in a variable
DEPLOYMENTS_DIR=$(pwd)
cd ~/cerc/fixturenet-laconicd-stack/stack-orchestrator/stacks/fixturenet-laconicd
# Fetch account holdings from bridge
./scripts/fetch-account-holdings.sh $DEPLOYMENTS_DIR/bridge-deployment eth-account-holdings.json
# Generate the genesis file
./scripts/generate-stage1-genesis.sh $DEPLOYMENTS_DIR/stage0-deployment eth-account-holdings.json
# Expected output:
# Genesis file for stage1 written to output/genesis.json
# Remove the temporary data directory
sudo rm -rf stage1-genesis
# Go back to the directory where deployments are created
cd -
```
- Copy over the generated genesis file (`.json`) containing the onboarding module state with funded participants to data directory in stage1 deployment (`stage1-deployment/data/genesis-config`):
```bash
# Run where deployments are created
cp ~/cerc/fixturenet-laconicd-stack/stack-orchestrator/stacks/fixturenet-laconicd/output/genesis.json stage1-deployment/data/genesis-config/genesis.json
```
- Start the deployment for stage 1
```bash
laconic-so deployment --dir stage1-deployment start
```
- The `bank` module transfers are disabled on stage 1 laconicd
- Query the list of registered participants in stage 1 laconicd:
```bash
laconic-so deployment --dir stage1-deployment exec laconicd "laconicd query onboarding list"
# Expected output: same as the result from stage0-deployment
```
- Query the balances of registered participants:
<!-- TODO: Show balances on laconic-wallet -->
```bash
export A_LACONIC_ADDRESS=<Alice Laconic address>
export C_LACONIC_ADDRESS=<Charlie Laconic address>
laconic-so deployment --dir stage1-deployment exec laconicd "laconicd query bank balances $A_LACONIC_ADDRESS"
laconic-so deployment --dir stage1-deployment exec laconicd "laconicd query bank balances $C_LACONIC_ADDRESS"
# Expected output: Account balances equal to Alice's and Charlie's holdings on the bridge
```
- The bridge holdings are therefore reflected on stage 1 laconicd chain as genesis allocations
- TODO: The registered participants with balances on stage 1 laconicd chain can join as validators
- <https://git.vdb.to/cerc-io/laconic-testnet/src/branch/main/validator.md>
### Payments Demo in L2
- Create virtual channel on L2 from A' to C' via Bridge' as intermediary
- Get Nitro (Ethereum) addresses for Alice and Charlie from the wallet:
```bash
export A_ADDRESS=<Alice Nitro address>
export C_ADDRESS=<Charlie Nitro address>
# Bridge's Nitro address
export BRIDGE_NITRO_ADDRESS=0xBBB676f9cFF8D242e9eaC39D063848807d3D1D94
```
- Create a virtual channel:
```bash
# Starts virtual fund objective on L2 to create virtual channel from A' to C'
laconic-so deployment --dir l2alice-nitro-deployment exec nitro-rpc-client "nitro-rpc-client virtual-fund $C_ADDRESS $BRIDGE_NITRO_ADDRESS --amount 1000 -p 4005 -h nitro-node"
# Set the payment channel id in a variable
PAYMENT_CHANNEL_ID=<payment channel id>
```
- Check payment channel between A' and C'
```bash
laconic-so deployment --dir l2alice-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-payment-channel $PAYMENT_CHANNEL_ID -p 4005 -h nitro-node"
# Expected output:
# {
# ID: '0xb29aeb32c9495a793ebf7bd116232075d1e7bfe89fc82281c7d498e3ffd3e3bf',
# Status: 'Open',
# Balance: {
# AssetAddress: '0x0000000000000000000000000000000000000000',
# Payee: '0xa8d2d06ace9c7ffc24ee785c2695678aecdfd7a0',
# Payer: '0xaaa6628ec44a8a742987ef3a114ddfe2d4f7adce',
# PaidSoFar: 0n,
# RemainingFunds: 1000n
# }
# }
```
- After virtual fund objective is complete, make payments
```bash
laconic-so deployment --dir l2alice-nitro-deployment exec nitro-rpc-client "nitro-rpc-client pay $PAYMENT_CHANNEL_ID 200 -p 4005 -h nitro-node"
# Expected output:
# {
# Amount: 200,
# Channel: '0xb29aeb32c9495a793ebf7bd116232075d1e7bfe89fc82281c7d498e3ffd3e3bf'
# }
```
- Check payment channel status again to view updated channel state
- Close payment channel after payments
```bash
laconic-so deployment --dir l2alice-nitro-deployment exec nitro-rpc-client "nitro-rpc-client virtual-defund $PAYMENT_CHANNEL_ID -p 4005 -h nitro-node"
```
- Check L2 mirrored channels status after virtual-defund is complete:
- Note balance change in A' node:
```bash
laconic-so deployment --dir l2alice-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-all-ledger-channels -p 4005 -h nitro-node"
# Expected output:
# {"ID":"0x6a9f5ccf1fa802525d794f4a899897f947615f6acc7141e61e056a8bfca29179","Status":"Open","Balance":{"AssetAddress":"<Token_address_on_L2>","Me":"0xaaa6628ec44a8a742987ef3a114ddfe2d4f7adce","Them":"0xbbb676f9cff8d242e9eac39d063848807d3d1d94","MyBalance":999800,"TheirBalance":1000200},"ChannelMode":"Open"}
```
- Note balance change in C' node:
```bash
laconic-so deployment --dir l2charlie-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-all-ledger-channels -p 4005 -h nitro-node"
# Expected output:
# {"ID":"0x15dbe6b996e4e46fdd6ea3e2074cbca58014dbb07368e3e7ba286df5c7b9da0d","Status":"Open","Balance":{"AssetAddress":"<Token_address_on_L2>","Me":"0xa8d2d06ace9c7ffc24ee785c2695678aecdfd7a0","Them":"0xbbb676f9cff8d242e9eac39d063848807d3d1d94","MyBalance":1000200,"TheirBalance":999800},"ChannelMode":"Open"}
```
## Demo cleanup
- Reset nitro-node deployments:
- Stop nitro-node deployments and remove volumes:
```bash
# Run where deployments are created
laconic-so deployment --dir l1alice-nitro-deployment stop --delete-volumes
laconic-so deployment --dir l1charlie-nitro-deployment stop --delete-volumes
laconic-so deployment --dir l2alice-nitro-deployment stop --delete-volumes
laconic-so deployment --dir l2charlie-nitro-deployment stop --delete-volumes
```
- Clear nitro-node deployments:
```bash
# Run where deployments are created
sudo rm -rf l1alice-nitro-deployment
sudo rm -rf l1charlie-nitro-deployment
sudo rm -rf l2alice-nitro-deployment
sudo rm -rf l2charlie-nitro-deployment
```
- Reset wallet:
- In laconic-wallet, click on the `Reset Wallet` button to disconnect all apps and clear the accounts
- Reset stage 0 and stage 1 laconicd deployments:
- Stop deployment and remove volumes:
```bash
# Run where deployments are created
laconic-so deployment --dir stage0-deployment stop --delete-volumes
laconic-so deployment --dir stage1-deployment stop --delete-volumes
```
- Remove data from stage 0 and stage 1 deployments:
```bash
# Run where deployments are created
sudo rm -rf stage0-deployment/data/laconicd-data/*
sudo rm -rf stage1-deployment/data/laconicd-data/*
sudo rm -rf stage1-deployment/data/genesis-config/*
```
- Reset faucet deployment:
- Stop deployment and remove volumes:
```bash
laconic-so deployment --dir laconic-faucet-deployment stop --delete-volumes
```
- Remove data from the deployment
```bash
# Run where deployments are created
sudo rm -rf laconic-faucet-deployment/data/faucet-data/*
```
## Re-run
- After running demo cleanup, follow the steps from [Demo](#demo) to re-run the demo
## Cleanup
- Reset nitro-node deployments:
- Stop nitro-node deployments and remove volumes:
```bash
# Run where deployments are created
laconic-so deployment --dir l1alice-nitro-deployment stop --delete-volumes
laconic-so deployment --dir l1charlie-nitro-deployment stop --delete-volumes
laconic-so deployment --dir l2alice-nitro-deployment stop --delete-volumes
laconic-so deployment --dir l2charlie-nitro-deployment stop --delete-volumes
laconic-so deployment --dir bridge-deployment stop --delete-volumes
```
- Clear nitro-node and bridge deployments:
```bash
# Run where deployments are created
sudo rm -rf l1alice-nitro-deployment
sudo rm -rf l1charlie-nitro-deployment
sudo rm -rf l2alice-nitro-deployment
sudo rm -rf l2charlie-nitro-deployment
sudo rm -rf bridge-deployment
```
- Reset wallet and stop the app:
- In laconic-wallet, click on the `Reset Wallet` button to disconnect all apps and clear the accounts
- Stop (`Ctrl+C`) the `laconic-wallet` if running locally in dev mode
- Stop and cleanup the `laconic-wallet-web` deployment:
```bash
# Run where deployments are created
laconic-so deployment --dir laconic-wallet-web-deployment stop
sudo rm -rf laconic-wallet-web-deployment
```
- Stop and cleanup the `onboarding-app` and `onboarding-api` deployments:
```bash
# Run where deployments are created
laconic-so deployment --dir onboarding-app-deployment stop
laconic-so deployment --dir onboarding-api-deployment stop
sudo rm -rf onboarding-app-deployment
sudo rm -rf onboarding-api-deployment
```
- Clean up stage 0 and stage 1 laconicd deployments:
- Stop deployment and remove volumes:
```bash
# Run where deployments are created
laconic-so deployment --dir stage0-deployment stop --delete-volumes
laconic-so deployment --dir stage1-deployment stop --delete-volumes
```
- Clear deployments:
```bash
# Run where deployments are created
sudo rm -rf stage0-deployment
sudo rm -rf stage1-deployment
```
- Clean up faucet deployment:
- Stop deployment and remove volumes:
```bash
laconic-so deployment --dir laconic-faucet-deployment stop --delete-volumes
```
- Clear deployment
```bash
# Run where deployment is created
sudo rm -rf laconic-faucet-deployment
```
- Clean up L1 and L2 deployments:
- Stop deployment and remove volumes:
```bash
# Run where deployments are created
laconic-so deployment --dir fixturenet-optimism-deployment stop --delete-volumes
laconic-so deployment --dir fixturenet-eth-deployment stop --delete-volumes
```
- Clear deployments:
```bash
# Run where deployments are created
sudo rm -rf fixturenet-optimism-deployment
sudo rm -rf fixturenet-eth-deployment
```
## Troubleshooting
- If the ledger channel creation fails, follow these steps:
- Check whether the status of `cerc/fixturenet-eth-geth` is `unhealthy`.
```bash
docker ps
```
- If the chain is not producing new blocks, restart the chain.
```bash
laconic-so deployment --dir fixturenet-eth-deployment stop
laconic-so deployment --dir fixturenet-eth-deployment start
```
- Stop the nitro-rpc-client direct-fund command if it is stuck
- Restart the failed node (for example: to restart Charlie's node)
- Stop the failed nitro node
```bash
laconic-so deployment --dir l1charlie-nitro-deployment stop
```
- Remove the node's durable store and create it again
```bash
sudo rm -rf l1charlie-nitro-deployment/data/nitro_node_data
mkdir l1charlie-nitro-deployment/data/nitro_node_data
```
- Restart the node and create ledger channel again
```bash
laconic-so deployment --dir l1charlie-nitro-deployment start
```
- Retry the ledger channel creation command