diff --git a/README.md b/README.md index bb069fe..10d00b6 100644 --- a/README.md +++ b/README.md @@ -4,3 +4,7 @@ Stacks to run a node for laconic testnet - [testnet-laconicd stack documentation](stack-orchestrator/stacks/testnet-laconicd/README.md) - [laconic-console stack documentation](stack-orchestrator/stacks/laconic-console/README.md) (to run laconic registry CLI and console standalone) + +## Testnet onboarding demo + +Follow steps in [testnet-onboarding-demo.md](./testnet-onboarding-demo.md) to run demo for onboarding testnet participants in laconicd chain diff --git a/testnet-onboarding-demo.md b/testnet-onboarding-demo.md new file mode 100644 index 0000000..e471ead --- /dev/null +++ b/testnet-onboarding-demo.md @@ -0,0 +1,1078 @@ +# testnet-onboarding-demo + +## Setup + +### Laconic Wallet + +1. Follow the [Install](https://git.vdb.to/cerc-io/laconic-wallet#install) steps from the laconic-wallet README to setup Android Studio + +2. Clone the repository + + ``` + git clone git@git.vdb.to:cerc-io/laconic-wallet.git + ``` + +3. Enter the project directory + + ``` + cd laconic-wallet + ``` + +4. Setup .env + - Copy and update [`.env`](./.env) + + ``` + cp .env.example .env + ``` + + - In the `.env` file add your WalletConnect project id. You can generate your own ProjectId at (use `gmail` address) + + ``` + WALLET_CONNECT_PROJECT_ID=39bc93c... + ``` + +5. Install dependencies + + ``` + yarn + ``` + +6. Exit project repo + + ``` + cd ../ + ``` + +### Testnet Onboarding App + +1. Clone the repository + + ``` + git clone git@git.vdb.to:cerc-io/testnet-onboarding-app.git + ``` + +2. Enter the project directory + + ``` + cd testnet-onboarding-app + ``` + +3. Setup .env + - Copy and update `.env` + + ``` + cp .env.example .env + ``` + + - In the `.env` file, add the WalletConnect project ID used in your [laconic-wallet](https://git.vdb.to/cerc-io/laconic-wallet) setup. + + ``` + WALLET_CONNECT_PROJECT_ID=39bc93c... + ``` + +4. Install dependencies + + ``` + yarn + ``` + +5. Exit project repo + + ``` + cd ../ + ``` + +### Stack Orchestrator + +- Follow these steps to install laconic-so: + +### Fixturenet laconicd Stack + +1. Clone the stack repos: + + ```bash + laconic-so fetch-stack git.vdb.to/cerc-io/fixturenet-laconicd-stack --git-ssh --pull + ``` + +2. Clone required repositories: + + ```bash + # laconicd + laconic-so --stack ~/cerc/fixturenet-laconicd-stack/stack-orchestrator/stacks/fixturenet-laconicd setup-repositories --git-ssh --pull + ``` + +3. Build the container images: + + ```bash + # laconicd + laconic-so --stack ~/cerc/fixturenet-laconicd-stack/stack-orchestrator/stacks/fixturenet-laconicd build-containers --force-rebuild + ``` + +4. 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 + ``` + + - In `stage0-deployment/config.env` file, set the following env variable: + + ```bash + # Set to true to enable adding participants functionality of the onboarding module + ONBOARDING_ENABLED=true + ``` + +5. Create a deployment for stage 1: + - Create spec file for the deployment: + + ```bash + laconic-so --stack ~/cerc/fixturenet-laconicd-stack/stack-orchestrator/stacks/fixturenet-laconicd deploy init --output stage1-spec.yml + ``` + + - Edit `network` in the spec file to map container ports to host ports as required: + + ```bash + # stage1-spec.yml + ... + network: + ports: + laconicd: + - '6060' + - '26657:26657' + - '26656:26656' + - '9473:9473' + - '9090:9090' + - '1317:1317' + ``` + + - Create deployment from the spec files: + + ```bash + laconic-so --stack ~/cerc/fixturenet-laconicd-stack/stack-orchestrator/stacks/fixturenet-laconicd deploy create --spec-file stage1-spec.yml --deployment-dir stage1-deployment + ``` + +### L1 eth and L2 optimism stacks + +1. 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 + ``` + +2. 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 + ``` + +3. 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 + ``` + +4. 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 + ``` + +5. 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' + ... + ``` + +6. 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 + ``` + +7. Env configuration: + In `fixturenet-eth-deployment/config.env` file add the following env variables: + + ```bash + # Allow unprotected txs for Optimism contracts deployment + CERC_ALLOW_UNPROTECTED_TXS=true + ``` + +### Go Nitro + +1. Clone go-nitro repository + + ```bash + git clone git@github.com:cerc-io/go-nitro.git + cd go-nitro + + # Install Node.js dependencies and build the repo + yarn && yarn build + + # Install go dependencies + go mod tidy + ``` + +2. Build go-nitro and bridge binaries + + ```bash + go build + go build -o nitro-bridge cmd/start-bridge/main.go + ``` + +3. Generate TLS certificate (prerequisite: [mkcert](https://github.com/cerc-io/go-nitro/tree/main/tls#tls)) + + ```bash + cd tls + make create-cert + ``` + +4. Install `nitro-rpc-client` package globally (run outside of go-nitro): + + ```bash + cd ~ + # 'yarn global' commands only work with Yarn versions below 2.x. + + npm install -g /packages/nitro-rpc-client + ``` + + - Replace `` with absolute path to the cloned go-nitro repo + +## 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 command in intervals of 3 seconds to check new blocks are created + + ```bash + laconic-so deployment --dir fixturenet-eth-deployment exec foundry "cast block-number" + ``` + + - 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 + + - 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" | 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 + ``` + +- Deploy go-nitro contracts on L1 and L2 (run steps in go-nitro repo) + - Go to `packages/nitro-protocol` + + ```bash + # In go-nitro + cd packages/nitro-protocol + ``` + + - Export variables for geth and optimism urls and the deployer private key (Private key used by bridge nodes as well) + + ```bash + export GETH_URL="http://127.0.0.1:8545" + export GETH_CHAIN_ID=1212 + export OPTIMISM_URL="http://127.0.0.1:9545" + + export GETH_DEPLOYER_PK=888814df89c4358d7ddb3fa4b0213e7331239a80e1f013eaa7b2deca2a41a218 + + # Use same account on both Geth and Optimism + export OPTIMISM_DEPLOYER_PK=$GETH_DEPLOYER_PK + ``` + + - Export variables for token name, token symbol and initial supply + ```bash + export TOKEN_NAME="LaconicNetworkToken" + export TOKEN_SYMBOL="LNT" + + # Note: Token supply denotes actual number of tokens and not the supply in Wei + export INITIAL_TOKEN_SUPPLY="10000000" + ``` + + - Disable deterministic deployment to make sure bridge node and address associated to it is the owner of contracts + + ```bash + export DISABLE_DETERMINISTIC_DEPLOYMENT=true + ``` + + - Reference: + - Deploy contracts on L1 and L2 + + ```bash + # Deploy contracts on geth + yarn contracts:deploy-geth + + # Deploy contracts on Optimism + yarn contracts:deploy-optimism + ``` + + - Deploy custom token on L1 + + ```bash + # Deploy token on geth + yarn contracts:deploy-token-geth + ``` + + - Note address of the deployed token on L1 and update `~/go-nitro/cmd/test-configs/bridge-assets-map.toml` config file + + ```bash + [[assets]] + l1AssetAddress = "" + ... + ``` + + - Deploy custom token on L2 + ```bash + # Deploy token on Optimism + yarn contracts:deploy-token-optimism + ``` + + - Note address of the deployed token on L2 and update `~/go-nitro/cmd/test-configs/bridge-assets-map.toml` config file + + ```bash + [[assets]] + l1AssetAddress = "" + l2AssetAddress = "" + ``` + +- Send custom tokens to Alice and Charlie on L1 + + - Export variables for L1 token address + + + ```bash + export L1_ASSET_ADDRESS="" + export A_CHAIN_ADDRESS="0xe22AD83A0dE117bA0d03d5E94Eb4E0d80a69C62a" + export C_CHAIN_ADDRESS="0xf1ac8Dd1f6D6F5c0dA99097c57ebF50CD99Ce293" + ``` + + - Send tokens to Alice and Charlie + + ```bash + # Send tokens to Alice + yarn hardhat transfer --contract $L1_ASSET_ADDRESS --to $A_CHAIN_ADDRESS --amount 1000 --network geth + + #Send tokens to Charlie + yarn hardhat transfer --contract $L1_ASSET_ADDRESS --to $C_CHAIN_ADDRESS --amount 1000 --network geth + ``` + +- Go to go-nitro repo root + + ```bash + cd ../../ + ``` + +- Update `cmd/test-configs/bridge.toml` config file + + ```bash + chainpk = "888814df89c4358d7ddb3fa4b0213e7331239a80e1f013eaa7b2deca2a41a218" + statechannelpk = "0279651921cd800ac560c21ceea27aab0107b67daf436cdd25ce84cad30159b4" + l1chainurl = "ws://127.0.0.1:8546" + l2chainurl = "ws://127.0.0.1:9546" + nodel1msgport = 3005 + nodel2msgport = 3006 + rpcport = 4006 + assetmapfilepath = "bridge-assets-map.toml" + ``` + +- Start testnet-onboarding-app (run command in testnet-onboarding-app repo) + + ```bash + # In testnet-onboarding-app + yarn start + ``` + + NOTE: Ignore source map warnings in the terminal + +- Start `laconic-wallet` android app (run steps in laconic-wallet repo) + + - 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 + + - Setup port forwarding for your device using the following command: + + ``` + # Get device id + adb devices + + # Setup port forwarding + adb -s reverse tcp:26657 tcp:26657 + ``` + + - Start the application: + + ``` + # In laconic-wallet + yarn start + + ``` + + - Press `a` to run the application on android and wait till the wallet app opens up on your phone + +- In laconic-wallet app, click on `Create wallet` and add laconicd chain using `Add network` button: + + ```bash + Network type - `COSMOS` + chain ID - `laconic_9000-1` + Network name - `laconicd` + New RPC URL - `http://127.0.0.1:26657` + Coin Type - `118` + Native Denom - `photon` + Address Prefix - `laconic` + Gas Price - `200000` + ``` + +## 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 the wallet, add 2 accounts (Alice and Charlie) for both the networks (ethereum and laconicd) by selecting the network and clicking on `Add account` + +- Fund accounts on laconicd: + - Export laconic addresses of Alice and Charlie (take the addresses from laconic wallet): + + ```bash + export A_LACONIC_ADDRESS= + export C_LACONIC_ADDRESS= + ``` + + - Send photons from funded account to Alice and Charlie: + + ```bash + # Send funds from funded account to Alice + laconic-so deployment --dir stage0-deployment exec laconicd "laconicd tx bank send alice $A_LACONIC_ADDRESS 100000000000photon --fees 100photon --keyring-backend test" + + # Send funds from funded account to Charlie + laconic-so deployment --dir stage0-deployment exec laconicd "laconicd tx bank send alice $C_LACONIC_ADDRESS 100000000000photon --fees 100photon --keyring-backend test" + ``` + + TODO: Use a faucet for funding accounts + +- Go to go-nitro repo root and start the nitro bridge using CLI: + + ```bash + # Export contract addresses stored in output files + source ./packages/nitro-protocol/hardhat-deployments/geth/.contracts.env + source ./packages/nitro-protocol/hardhat-deployments/optimism/.contracts.env + + # Start bridge CLI + ./nitro-bridge -config cmd/test-configs/bridge.toml + ``` + +- Get Ethereum private keys for accounts Alice and Charlie from `laconic-wallet` (to be used as statechannel PKs) + +- Start nitro nodes for Alice and Charlie on L1 and L2: + - Prepare config files in go-nitro repo `cmd/test-configs` + - **Note**: Enter PKs without the leading `0x` + - `cmd/test-configs/l1alice.toml` + + ```bash + usedurablestore = true + msgport = 3007 + rpcport = 4007 + pk = "" + chainpk = "570b909da9669b2f35a0b1ac70b8358516d55ae1b5b3710e95e9a94395090597" + chainurl = "ws://127.0.0.1:8546" + bootpeers = "/ip4/127.0.0.1/tcp/3005/p2p/16Uiu2HAmJDxLM8rSybX78FH51iZq9PdrwCoCyyHRBCndNzcAYMes" + ``` + + - `cmd/test-configs/l2alice.toml` + + ```bash + usedurablestore = true + msgport = 3008 + rpcport = 4008 + pk = "" + chainpk = "570b909da9669b2f35a0b1ac70b8358516d55ae1b5b3710e95e9a94395090597" + chainurl = "ws://127.0.0.1:9546" + bootpeers = "/ip4/127.0.0.1/tcp/3006/p2p/16Uiu2HAmJDxLM8rSybX78FH51iZq9PdrwCoCyyHRBCndNzcAYMes" + durablestorefolder = "./data/l2-nitro-store" + l2 = true + ``` + + - `cmd/test-configs/l1charlie.toml` + + ```bash + usedurablestore = true + msgport = 3009 + rpcport = 4009 + pk = "" + chainpk = "111b7500bdce494d6f4bcfe8c2a0dde2ef92f751d9070fac6475dbd6d8021b3f" + chainurl = "ws://127.0.0.1:8546" + bootpeers = "/ip4/127.0.0.1/tcp/3005/p2p/16Uiu2HAmJDxLM8rSybX78FH51iZq9PdrwCoCyyHRBCndNzcAYMes" + ``` + + - `cmd/test-configs/l2charlie.toml` + + ```bash + usedurablestore = true + msgport = 3010 + rpcport = 4010 + pk = "" + chainpk = "111b7500bdce494d6f4bcfe8c2a0dde2ef92f751d9070fac6475dbd6d8021b3f" + chainurl = "ws://127.0.0.1:9546" + bootpeers = "/ip4/127.0.0.1/tcp/3006/p2p/16Uiu2HAmJDxLM8rSybX78FH51iZq9PdrwCoCyyHRBCndNzcAYMes" + durablestorefolder = "./data/l2-nitro-store" + l2 = true + ``` + + - In a new terminal, go to go-nitro repo root and initialize node A on L1 + + ```bash + # Export L1 contract addresses + source ./packages/nitro-protocol/hardhat-deployments/geth/.contracts.env + + ./go-nitro -config cmd/test-configs/l1alice.toml -naaddress $NA_ADDRESS -vpaaddress $VPA_ADDRESS -caaddress $CA_ADDRESS + ``` + + - In another terminal, initialize node A' on L2 + + ```bash + # Export contract addresses stored in output files + source ./packages/nitro-protocol/hardhat-deployments/geth/.contracts.env + source ./packages/nitro-protocol/hardhat-deployments/optimism/.contracts.env + + ./go-nitro -config cmd/test-configs/l2alice.toml -bridgeaddress $BRIDGE_ADDRESS -vpaaddress $VPA_ADDRESS -caaddress $CA_ADDRESS + ``` + + - In another terminal, initialize node C on L1: + + ```bash + # Export L1 contract addresses + source ./packages/nitro-protocol/hardhat-deployments/geth/.contracts.env + + ./go-nitro -config cmd/test-configs/l1charlie.toml -naaddress $NA_ADDRESS -vpaaddress $VPA_ADDRESS -caaddress $CA_ADDRESS + ``` + + - In another terminal, initialize node C' on L2 + + ```bash + # Export contract addresses stored in output files + source ./packages/nitro-protocol/hardhat-deployments/geth/.contracts.env + source ./packages/nitro-protocol/hardhat-deployments/optimism/.contracts.env + + ./go-nitro -config cmd/test-configs/l2charlie.toml -bridgeaddress $BRIDGE_ADDRESS -vpaaddress $VPA_ADDRESS -caaddress $CA_ADDRESS + ``` + +- Create ledger channels on L1 and mirrored channel on L2s + - Open new terminal + + - Set the `NODE_EXTRA_CA_CERTS` environment variable to the path of mkcert's root CA certificate. This allows Node.js to trust locally-trusted development certificates created by mkcert + + ```bash + export NODE_EXTRA_CA_CERTS="$(mkcert -CAROOT)/rootCA.pem" + ``` + + - Check that no channels exist on L2 + + ```bash + nitro-rpc-client get-all-l2-channels -p 4006 + ``` + + - Set address of bridge and address of custom token on L1 in the current terminal + + + ```bash + export BRIDGE_ADDRESS=0xBBB676f9cFF8D242e9eaC39D063848807d3D1D94 + export L1_ASSET_ADDRESS="" + ``` + + NOTE: Replace `` with LNT token address deployed previously on L1 in [Run](#run) section + + - Create ledger channel between A and Bridge with custom token + + ```bash + nitro-rpc-client direct-fund $BRIDGE_ADDRESS --assetAddress $L1_ASSET_ADDRESS -p 4007 + ``` + + - Once direct-fund objective is complete, bridge will create mirrored channel on L2 + - Check node A' logs to see bridged-fund objective completed + - Check status of L1 ledger channel between A and Bridge + + ```bash + nitro-rpc-client get-ledger-channel -p 4007 + + # Expected output: + # { + # ID: '0x161d289a50222caa781db215bb82a3ede4f557217742245525b8e8cbff04ec21', + # Status: 'Open', + # Balance: { + # AssetAddress: '', + # Me: '0xaaa6628ec44a8a742987ef3a114ddfe2d4f7adce', + # Them: '0xbbb676f9cff8d242e9eac39d063848807d3d1d94', + # MyBalance: 1000000n, + # TheirBalance: 1000000n + # }, + # ChannelMode: 'Open' + # } + ``` + + - Create ledger channel between C and Bridge with custom token + + ```bash + nitro-rpc-client direct-fund $BRIDGE_ADDRESS --assetAddress $L1_ASSET_ADDRESS -p 4009 + ``` + + - Once direct fund objective is complete, bridge will create mirrored channel on L2 + - Check node C' logs to see bridged-fund objective completed + - Check status of L1 ledger channel between C and Bridge + + ```bash + nitro-rpc-client get-ledger-channel -p 4009 + + # Expected output: + # { + # ID: '0x69a3f09b6f4f94f033cf084e6e4a9453438c45b43606e9a95f5434f4c6527543', + # Status: 'Open', + # Balance: { + # AssetAddress: '', + # Me: '0xa8d2d06ace9c7ffc24ee785c2695678aecdfd7a0', + # Them: '0xbbb676f9cff8d242e9eac39d063848807d3d1d94', + # MyBalance: 1000000n, + # TheirBalance: 1000000n + # }, + # ChannelMode: 'Open' + # } + ``` + + - Check status of all L2 mirrored ledger channels + + ```bash + nitro-rpc-client get-all-l2-channels -p 4006 + + # Expected output: + # {"ID":"0x15dbe6b996e4e46fdd6ea3e2074cbca58014dbb07368e3e7ba286df5c7b9da0d","Status":"Open","Balance":{"AssetAddress":"","Me":"0xbbb676f9cff8d242e9eac39d063848807d3d1d94","Them":"0xa8d2d06ace9c7ffc24ee785c2695678aecdfd7a0","MyBalance":1000000,"TheirBalance":1000000},"ChannelMode":"Open"} + # {"ID":"0x6a9f5ccf1fa802525d794f4a899897f947615f6acc7141e61e056a8bfca29179","Status":"Open","Balance":{"AssetAddress":"","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 + - Connect to the testnet-onboarding app by clicking on the WalletConnect icon on the top right corner in the wallet and scanning QR code of the app + - Choose Alice's ethereum and laconicd account to onboard + - Use ethereum accounts for which ledger channels have been created on L2 + - Sign using the ethereum key + - Approve sign request on Wallet + - Send transaction request to the Wallet + - Approve and send transaction to laconicd chain + - Repeat onboarding for other (Charlies's) account + - List the participants on stage 1 (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: + # ethereum_address: + # - cosmos_address: + # 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 + cd ~/cerc/fixturenet-laconicd-stack/stack-orchestrator/stacks/fixturenet-laconicd + + ./scripts/generate-stage1-genesis.sh + + # Expected output: + # Genesis file for stage1 written to output/genesis.json + + # Remove the temporary data directory + sudo rm -rf stage1-genesis + ``` + + - Change directory to stage1 deployment directory + + ```bash + 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: + + + ```bash + export A_LACONIC_ADDRESS= + export C_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 + - + +### Payments Demo in L2 + +- Ensure the NODE_EXTRA_CA_CERTS environment variable in the current terminal is set to the path of mkcert's root CA certificate. + + ```bash + echo $NODE_EXTRA_CA_CERTS + # ~/.local/share/mkcert/rootCA.pem + + # If not present, set the environment variable + export NODE_EXTRA_CA_CERTS="$(mkcert -CAROOT)/rootCA.pem" + ``` + +- Create virtual channel on L2 from A' to C' via Bridge' as intermediary + + ```bash + export BRIDGE_ADDRESS=0xBBB676f9cFF8D242e9eaC39D063848807d3D1D94 + export A_ADDRESS= + export C_ADDRESS= + + # Starts virtual fund objective on L2 to create virtual channel from A' to C' + nitro-rpc-client virtual-fund $C_ADDRESS $BRIDGE_ADDRESS -p 4008 + ``` + +- Check payment channel between A' and C' + + ```bash + nitro-rpc-client get-payment-channel -p 4008 + + # Expected output: + # { + # ID: '0xb29aeb32c9495a793ebf7bd116232075d1e7bfe89fc82281c7d498e3ffd3e3bf', + # Status: 'Open', + # Balance: { + # AssetAddress: '', + # Payee: '0xa8d2d06ace9c7ffc24ee785c2695678aecdfd7a0', + # Payer: '0xaaa6628ec44a8a742987ef3a114ddfe2d4f7adce', + # PaidSoFar: 0n, + # RemainingFunds: 1000n + # } + # } + ``` + +- After virtual fund objective is complete, make payments + + ```bash + nitro-rpc-client pay -p 4008 + + # Expected output: + # { + # Amount: 200, + # Channel: '0xb29aeb32c9495a793ebf7bd116232075d1e7bfe89fc82281c7d498e3ffd3e3bf' + # } + ``` + +- Check payment channel status again to view updated channel state + +- Close payment channel after payments + + ```bash + nitro-rpc-client virtual-defund -p 4008 + ``` + +- Check L2 mirrored channels status after virtual-defund is complete: + + - Note balance change in A' node: + + ```bash + nitro-rpc-client get-all-ledger-channels -p 4008 + + # Expected output: + # {"ID":"0x6a9f5ccf1fa802525d794f4a899897f947615f6acc7141e61e056a8bfca29179","Status":"Open","Balance":{"AssetAddress":"","Me":"0xaaa6628ec44a8a742987ef3a114ddfe2d4f7adce","Them":"0xbbb676f9cff8d242e9eac39d063848807d3d1d94","MyBalance":999800,"TheirBalance":1000200},"ChannelMode":"Open"} + ``` + + - Note balance change in C' node: + + ```bash + nitro-rpc-client get-all-ledger-channels -p 4010 + + # Expected output: + # {"ID":"0x15dbe6b996e4e46fdd6ea3e2074cbca58014dbb07368e3e7ba286df5c7b9da0d","Status":"Open","Balance":{"AssetAddress":"","Me":"0xa8d2d06ace9c7ffc24ee785c2695678aecdfd7a0","Them":"0xbbb676f9cff8d242e9eac39d063848807d3d1d94","MyBalance":1000200,"TheirBalance":999800},"ChannelMode":"Open"} + ``` + +## Demo cleanup + +- Stop the bridge, A, A', C and C' terminals + - Change directory to go-nitro repo root + - Clear the durable store + + ```bash + rm -rf ./data/ + ``` + +- 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 stage0-deployment/data/genesis-config/* + + sudo rm -rf stage1-deployment/data/laconicd-data/* + sudo rm -rf stage1-deployment/data/genesis-config/* + ``` + +## Re-run + +- After running demo cleanup, follow the steps from [Demo](#demo) to re-run the demo + +## Cleanup + +- Stop Nitro nodes: + - Stop (`Ctrl+C`) the bridge, A, A', C and C' nitro nodes + + - Clear out nitro nodes data and configurations: + - Change directory to go-nitro repo root + + - Cleanup: + + ```bash + # In go-nitro + git clean -xdf + ``` + +- 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`) both `laconic-wallet` and `testnet-onboarding-app` + +- 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 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 + ``` + +## Future enhancements + +- Implement faucet in stage 0 laconicd chain for participants to send onboarding tx +- Use latest optimism releases (e.g. v1.7.7) in fixturenet-optimism +- Implement external stack for go-nitro + - Add stack for bridge + - Add stack for nitro node +- LATER: Implement flow for registered participants with balance to join as validators in stage 1 laconicd chain