# 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
