# testnet-nitro-node ## Prerequisites * Local: * Clone the `cerc-io/testnet-ops` repository: ```bash git clone git@git.vdb.to:cerc-io/testnet-ops.git ``` * Ansible: see [installation](https://git.vdb.to/cerc-io/testnet-ops#installation) * On deployment machine: * User with passwordless sudo: see [setup](https://git.vdb.to/cerc-io/testnet-ops/src/branch/main/user-setup/README.md#user-setup) * laconic-so: see [installation](https://git.vdb.to/cerc-io/testnet-ops/src/branch/main/stack-orchestrator-setup/README.md#setup-stack-orchestrator) ## Setup * Move to `nitro-nodes-setup` : ```bash cd testnet-ops/nitro-nodes-setup ``` * Fetch the required Nitro node config: ```bash wget -O nitro-vars.yml https://git.vdb.to/cerc-io/testnet-laconicd-stack/raw/branch/main/ops/stage2/nitro-node-config.yml ``` * Fetch required asset addresses: ```bash wget -O assets.json https://git.vdb.to/cerc-io/testnet-laconicd-stack/raw/branch/main/ops/stage2/assets.json ``` * Ask testnet operator to send L1 tokens and ETH to your chain address * [README for transferring tokens](./ops/nitro-token-ops.md#transfer-deployed-tokens-to-given-address) * [README for transferring ETH](./ops/nitro-token-ops.md#transfer-eth) * Check balance of your tokens once they are transferred: ```bash # Note: Account address should be with "0x" export ACCOUNT_ADDRESS="" export GETH_CHAIN_ID="1212" export GETH_CHAIN_URL="https://fixturenet-eth.laconic.com" export ASSET_ADDRESS_1=$(jq -r --arg chainId "$GETH_CHAIN_ID" '.[$chainId][0].contracts.TestToken.address' assets.json) export ASSET_ADDRESS_2=$(jq -r --arg chainId "$GETH_CHAIN_ID" '.[$chainId][0].contracts.TestToken2.address' assets.json) # Check balance of eth account curl -X POST $GETH_CHAIN_URL \ -H "Content-Type: application/json" \ -d '{ "jsonrpc":"2.0", "method":"eth_getBalance", "params":["'"$ACCOUNT_ADDRESS"'", "latest"], "id":1 }' # Check balance of first asset address curl -X POST $GETH_CHAIN_URL \ -H "Content-Type: application/json" \ -d '{ "jsonrpc":"2.0", "method":"eth_call", "params":[{ "to": "'"$ASSET_ADDRESS_1"'", "data": "0x70a08231000000000000000000000000'"$ACCOUNT_ADDRESS"'" }, "latest"], "id":1 }' # Check balance of second asset address curl -X POST $GETH_CHAIN_URL \ -H "Content-Type: application/json" \ -d '{ "jsonrpc":"2.0", "method":"eth_call", "params":[{ "to": "'"$ASSET_ADDRESS_2"'", "data": "0x70a08231000000000000000000000000'"$ACCOUNT_ADDRESS"'" }, "latest"], "id":1 }' ``` * Edit `nitro-vars.yml` and add the following variables: ```bash # Private key for your Nitro account (same as the one used in stage0 onboarding) # Export the key from Laconic wallet (https://wallet.laconic.com) nitro_sc_pk: "" # Private key for a funded account on L1 # This account should have L1 tokens for funding your Nitro channels nitro_chain_pk: "" # Multiaddr with publically accessible IP address / DNS for your L1 nitro node # Use port 3007 # Example: "/ip4/192.168.x.y/tcp/3007" # Example: "/dns4/example.com/tcp/3007" nitro_l1_ext_multiaddr: "" # Multiaddr with publically accessible IP address / DNS for your L2 nitro node # Use port 3009 # Example: "/ip4/192.168.x.y/tcp/3009" # Example: "/dns4/example.com/tcp/3009" nitro_l2_ext_multiaddr: "" ``` * Edit the `setup-vars.yml` to update the target directory: ```bash # Set absolute path to desired deployments directory (under your user) # Example: /home/dev/nitro-node-deployments ... nitro_directory: ... # Will create deployments at /l1-nitro-deployment and /l2-nitro-deployment ``` ## Run Nitro Nodes **NOTE**: When following this setup, Nitro nodes from two parties won't be able to communicate with each other if they are on the same network Nitro nodes can be set up on a target machine using Ansible: * In `testnet-ops/nitro-nodes-setup`, create a new `hosts.ini` file: ```bash cp ../hosts.example.ini hosts.ini ``` * Edit the [`hosts.ini`](./hosts.ini) file to run the playbook on a remote machine: ```ini [] ansible_host= ansible_user= ansible_ssh_common_args='-o ForwardAgent=yes' ``` * Replace `` with `nitro_host` * Replace `` with the alias of your choice * Replace `` with the IP address or hostname of the target machine * Replace `` with the username of the user that you set up on target machine (e.g. dev, ubuntu) * Verify that you are able to connect to the host using the following command ```bash ansible all -m ping -i hosts.ini # If using password based authentication, enter the ssh password on prompt; otherwise, leave it blank # Expected output: # | SUCCESS => { # "ansible_facts": { # "discovered_interpreter_python": "/usr/bin/python3.10" # }, # "changed": false, # "ping": "pong" # } ``` * Execute the `run-nitro-nodes.yml` Ansible playbook to setup and run a Nitro node (L1+L2): ```bash LANG=en_US.utf8 ansible-playbook -i hosts.ini run-nitro-nodes.yml --extra-vars='{ "target_host": "nitro_host"}' --user $USER ``` ### Check Deployment Status * Run the following commands on deployment machine: ```bash cd # Check the logs, ensure that the nodes are running laconic-so deployment --dir l1-nitro-deployment logs nitro-node -f laconic-so deployment --dir l2-nitro-deployment logs nitro-node -f # Let L1 node sync up with the chain # Expected logs after sync: # nitro-node-1 | 2:04PM INF Initializing Http RPC transport... # nitro-node-1 | 2:04PM INF Completed RPC server initialization url=127.0.0.1:4005/api/v1 ``` * Get your Nitro node's info: ```bash laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-node-info -p 4005 -h nitro-node" # Expected output: # { # "SCAddress": "0xd0eA8b27591b1D070cCcD4D30b8D408fe794FDfc", # "MessageServicePeerId": "16Uiu2HAmSHRjoxveaPmJipzmdq69U8zme8BMnFjSBPferj1E5XAd" # } # SCAddress -> nitro address, MessageServicePeerId -> libp2p peer id ``` ## Create Channels Create a ledger channel with the bridge on L1 which is mirrored on L2 * Run the following commands on deployment machine * Set required variables: ```bash cd export BRIDGE_NITRO_ADDRESS=$(yq eval '.bridge_nitro_address' nitro-node-config.yml) export GETH_CHAIN_ID="1212" # Get asset addresses from assets.json file export ASSET_ADDRESS_1=$(jq -r --arg chainId "$GETH_CHAIN_ID" '.[$chainId][0].contracts.TestToken.address' assets.json) export ASSET_ADDRESS_2=$(jq -r --arg chainId "$GETH_CHAIN_ID" '.[$chainId][0].contracts.TestToken2.address' assets.json) ``` * Check that you have no existing channels on L1 or L2: ```bash laconic-so deployment --dir l1-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-all-ledger-channels -p 4005 -h nitro-node" laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-all-ledger-channels -p 4005 -h nitro-node" # Expected output: # [] ``` * Ensure that your account has enough balance of tokens from `assets.json` * Create a ledger channel between your L1 Nitro node and Bridge with custom asset: ```bash laconic-so deployment --dir l1-nitro-deployment exec nitro-rpc-client "nitro-rpc-client direct-fund $BRIDGE_NITRO_ADDRESS --asset "$ASSET_ADDRESS_1:1000,1000" --asset "$ASSET_ADDRESS_2:1000,1000" -p 4005 -h nitro-node" # Follow your L1 Nitro node logs for progress # Expected Output: # Objective started DirectFunding-0x161d289a50222caa781db215bb82a3ede4f557217742245525b8e8cbff04ec21 # Channel Open 0x161d289a50222caa781db215bb82a3ede4f557217742245525b8e8cbff04ec21 # Set the resulting ledger channel id in a variable export LEDGER_CHANNEL_ID= ``` * Check the [Troubleshooting](#troubleshooting) section if command to create a ledger channel fails or gets stuck * Once direct-fund objective is complete, the bridge will create a mirrored channel on L2 * Check L2 Nitro node's logs to see that a bridged-fund objective completed: ```bash laconic-so deployment --dir l2-nitro-deployment logs nitro-node -f --tail 30 # Expected Output: # nitro-node-1 | 5:01AM INF INFO Objective cranked address=0xaaa6628ec44a8a742987ef3a114ddfe2d4f7adce objective-id=bridgedfunding-0x6a9f5ccf1fa802525d794f4a899897f947615f6acc7141e61e056a8bfca29179 waiting-for=WaitingForNothing # nitro-node-1 | 5:01AM INF INFO Objective is complete & returned to API address=0xaaa6628ec44a8a742987ef3a114ddfe2d4f7adce objective-id=bridgedfunding-0x6a9f5ccf1fa802525d794f4a899897f947615f6acc7141e61e056a8bfca29179 ``` * Check status of L1 ledger channel with the bridge using channel id: ```bash laconic-so deployment --dir l1-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-ledger-channel $LEDGER_CHANNEL_ID -p 4005 -h nitro-node" # Example output: # { # ID: '0xbb28acc2e1543f4b41eb1ab9eb2e354b18554aefe4e7f0fa5f20046869d8553f', # Status: 'Open', # Balances: [ # { # AssetAddress: '0xa6b4b8b84576047a53255649b4994743d9c83a71', # Me: '0xdaaa6ef3bc03f9c7dabc9a02847387d2c19107f5', # Them: '0xf0e6a85c6d23aca9ff1b83477d426ed26f218185', # MyBalance: 1000n, # TheirBalance: 1000n # }, # { # AssetAddress: '0x0000000000000000000000000000000000000000', # Me: '0xdaaa6ef3bc03f9c7dabc9a02847387d2c19107f5', # Them: '0xf0e6a85c6d23aca9ff1b83477d426ed26f218185', # MyBalance: 1000n, # TheirBalance: 1000n # } # ], # ChannelMode: 'Open' # } ``` * Check status of the mirrored channel on L2: ```bash laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-all-ledger-channels -p 4005 -h nitro-node" # Example output: # [ # { # "ID": "0xb34210b763d4fdd534190ba11886ad1daa1e411c87be6fd20cff74cd25077c46", # "Status": "Open", # "Balances": [ # { # "AssetAddress": "0xa4351114dae1abeb2d552d441c9733c72682a45d", # "Me": "0x075400039e303b3fb46c0cff0404c5fa61947c05", # "Them": "0xf0e6a85c6d23aca9ff1b83477d426ed26f218185", # "MyBalance": 1000, # "TheirBalance": 1000 # }, # { # "AssetAddress": "0x314e43f9825b10961859c2a62c2de6a765c1c1f1", # "Me": "0x075400039e303b3fb46c0cff0404c5fa61947c05", # "Them": "0xf0e6a85c6d23aca9ff1b83477d426ed26f218185", # "MyBalance": 1000, # "TheirBalance": 1000 # } # ], # "ChannelMode": "Open" # } # ] ``` ## Payments On L2 Channel Perform payments using a virtual payment channel created with another Nitro node over the mirrored L2 channel with bridge as an intermediary * Prerequisite: Ledger channel is required to create a payment channel * Note: Currently payment channel is created from first asset present in ledger channel * Run the following commands on deployment machine * Switch to the `nitro-node` directory: ```bash cd ``` * Check status of the mirrored channel on L2: ```bash laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-all-ledger-channels -p 4005 -h nitro-node" # Example output: # [ # { # "ID": "0xb34210b763d4fdd534190ba11886ad1daa1e411c87be6fd20cff74cd25077c46", # "Status": "Open", # "Balances": [ # { # "AssetAddress": "0xa4351114dae1abeb2d552d441c9733c72682a45d", # "Me": "0x075400039e303b3fb46c0cff0404c5fa61947c05", # "Them": "0xf0e6a85c6d23aca9ff1b83477d426ed26f218185", # "MyBalance": 1000, # "TheirBalance": 1000 # }, # { # "AssetAddress": "0x314e43f9825b10961859c2a62c2de6a765c1c1f1", # "Me": "0x075400039e303b3fb46c0cff0404c5fa61947c05", # "Them": "0xf0e6a85c6d23aca9ff1b83477d426ed26f218185", # "MyBalance": 1000, # "TheirBalance": 1000 # } # ], # "ChannelMode": "Open" # } # ] ``` * Set required variables: ```bash export BRIDGE_NITRO_ADDRESS=$(yq eval '.bridge_nitro_address' nitro-node-config.yml) # Mirrored channel on L2 export L2_CHANNEL_ID= # Amount to create the payment channel with export PAYMENT_CHANNEL_AMOUNT=500 ``` * Set counterparty address ```bash export COUNTER_PARTY_ADDRESS= ``` * Get the nitro address of the counterparty's node with whom you want create payment channel * To get the nitro address of the your node: ```bash laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-node-info -p 4005 -h nitro-node" # `SCAddress` -> nitro address ``` * Check for existing payment channels for the L2 channel: ```bash laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-payment-channels-by-ledger $L2_CHANNEL_ID -p 4005 -h nitro-node" ``` * Create a virtual payment channel: ```bash laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client virtual-fund $COUNTER_PARTY_ADDRESS $BRIDGE_NITRO_ADDRESS --amount $PAYMENT_CHANNEL_AMOUNT -p 4005 -h nitro-node" # Follow your L2 Nitro node logs for progress # Expected Output: # Objective started VirtualFund-0x43db45a101658387263b36d613322cc952d8ce5b70de51e3a495513c256bef4d # Channel Open 0x43db45a101658387263b36d613322cc952d8ce5b70de51e3a495513c256bef4d # Set the resulting payment channel id in a variable PAYMENT_CHANNEL_ID= ``` Multiple virtual payment channels can be created at once * Check the payment channel's status: ```bash laconic-so deployment --dir l2-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: '', # Payer: '', # PaidSoFar: 0n, # RemainingFunds: n # } # } ``` * Send payments using the virtual payment channel: ```bash export PAY_AMOUNT=200 laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client pay $PAYMENT_CHANNEL_ID $PAY_AMOUNT -p 4005 -h nitro-node" # Expected output # { # Amount: , # Channel: '' # } # This can be done multiple times until the payment channel balance is exhausted ``` * Check payment channel's status again to view updated channel state * Close the payment channel to settle on the L2 mirrored channel: ```bash laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client virtual-defund $PAYMENT_CHANNEL_ID -p 4005 -h nitro-node" # Expected output: # Objective started VirtualDefund-0x43db45a101658387263b36d613322cc952d8ce5b70de51e3a495513c256bef4d # Channel complete 0x43db45a101658387263b36d613322cc952d8ce5b70de51e3a495513c256bef4d ``` * Check L2 mirrored channel's status after the virtual payment channel is closed: * This can be checked by both nodes ```bash laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-all-ledger-channels -p 4005 -h nitro-node" # Example output: # [ # { # "ID": "0xb34210b763d4fdd534190ba11886ad1daa1e411c87be6fd20cff74cd25077c46", # "Status": "Open", # "Balances": [ # { # "AssetAddress": "0xa4351114dae1abeb2d552d441c9733c72682a45d", # "Me": "0x075400039e303b3fb46c0cff0404c5fa61947c05", # "Them": "0xf0e6a85c6d23aca9ff1b83477d426ed26f218185", # "MyBalance": , # "TheirBalance": # }, # { # "AssetAddress": "0x314e43f9825b10961859c2a62c2de6a765c1c1f1", # "Me": "0x075400039e303b3fb46c0cff0404c5fa61947c05", # "Them": "0xf0e6a85c6d23aca9ff1b83477d426ed26f218185", # "MyBalance": , # "TheirBalance": # } # ], # "ChannelMode": "Open" # } # ] ``` Your balance on the L2 channel should be reduced by total payments done on the virtual payment channel ## Swaps on L2 Perform swaps using a swap channel created with another Nitro node over the mirrored L2 channel with bridge as an intermediary * Prerequisite: Ledger channel is required to create a swap channel * Run the following commands on deployment machine * Switch to the `nitro-node` directory: ```bash cd ``` * Check status of the mirrored channel on L2: ```bash laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-all-ledger-channels -p 4005 -h nitro-node" # Example output: # [ # { # "ID": "0xb34210b763d4fdd534190ba11886ad1daa1e411c87be6fd20cff74cd25077c46", # "Status": "Open", # "Balances": [ # { # "AssetAddress": "0xa4351114dae1abeb2d552d441c9733c72682a45d", # "Me": "0x075400039e303b3fb46c0cff0404c5fa61947c05", # "Them": "0xf0e6a85c6d23aca9ff1b83477d426ed26f218185", # "MyBalance": 1000, # "TheirBalance": 1000 # }, # { # "AssetAddress": "0x314e43f9825b10961859c2a62c2de6a765c1c1f1", # "Me": "0x075400039e303b3fb46c0cff0404c5fa61947c05", # "Them": "0xf0e6a85c6d23aca9ff1b83477d426ed26f218185", # "MyBalance": 1000, # "TheirBalance": 1000 # } # ], # "ChannelMode": "Open" # } # ] ``` * Set required variables: ```bash export BRIDGE_NITRO_ADDRESS=$(yq eval '.bridge_nitro_address' nitro-node-config.yml) export GETH_CHAIN_ID="1212" # Get asset addresses from assets.json file export ASSET_ADDRESS_1=$(jq -r --arg chainId "$GETH_CHAIN_ID" '.[$chainId][0].contracts.TestToken.address' assets.json) export ASSET_ADDRESS_2=$(jq -r --arg chainId "$GETH_CHAIN_ID" '.[$chainId][0].contracts.TestToken2.address' assets.json) ``` * Set counterparty address ```bash export COUNTER_PARTY_ADDRESS= ``` * Get the nitro address of the counterparty's node with whom you want create swap channel * To get the nitro address of the your node: ```bash laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-node-info -p 4005 -h nitro-node" # `SCAddress` -> nitro address ``` * Create swap channel: ```bash laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client swap-fund $COUNTER_PARTY_ADDRESS $BRIDGE_NITRO_ADDRESS --asset "$ASSET_ADDRESS_1:100,100" --asset "$ASSET_ADDRESS_2:100,100" -p 4005 -h nitro-node" # Expected output # Objective started SwapFund-0x1dbd58d314f123f4b0f4147eee7fd92fa523ba7082d8a75b846f6d1189e2f0e9 # Channel open 0x1dbd58d314f123f4b0f4147eee7fd92fa523ba7082d8a75b846f6d1189e2f0e9 ``` * Export swap channel ID: ```bash export SWAP_CHANNEL_ID= ``` * Check swap channel: ```bash laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-swap-channel $SWAP_CHANNEL_ID -p 4005 -h nitro-node" # Expected output: # { # ID: '0x1dbd58d314f123f4b0f4147eee7fd92fa523ba7082d8a75b846f6d1189e2f0e9', # Status: 'Open', # Balances: [ # { # AssetAddress: '0xa4351114dae1abeb2d552d441c9733c72682a45d', # Me: '0x075400039e303b3fb46c0cff0404c5fa61947c05', # Them: '0xd0ea8b27591b1d070cccd4d30b8d408fe794fdfc', # MyBalance: 100n, # TheirBalance: 100n # }, # { # AssetAddress: '0x314e43f9825b10961859c2a62c2de6a765c1c1f1', # Me: '0x075400039e303b3fb46c0cff0404c5fa61947c05', # Them: '0xd0ea8b27591b1d070cccd4d30b8d408fe794fdfc', # MyBalance: 100n, # TheirBalance: 100n # } # ] # } ``` ### Performing swaps * Ensure that environment variables for asset addresses are set (should be done by both parties): ```bash export GETH_CHAIN_ID="1212" # Get asset addresses from assets.json file export ASSET_ADDRESS_1=$(jq -r --arg chainId "$GETH_CHAIN_ID" '.[$chainId][0].contracts.TestToken.address' assets.json) export ASSET_ADDRESS_2=$(jq -r --arg chainId "$GETH_CHAIN_ID" '.[$chainId][0].contracts.TestToken2.address' assets.json) ``` * Get all active swap channels for a specific mirrored ledger channel (should be done by both parties) * To get mirrored ledger channels: ```bash laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-all-ledger-channels -p 4005 -h nitro-node" # Example output: # [ # { # "ID": "0xb34210b763d4fdd534190ba11886ad1daa1e411c87be6fd20cff74cd25077c46", # "Status": "Open", # "Balances": [ # { # "AssetAddress": "0xa4351114dae1abeb2d552d441c9733c72682a45d", # "Me": "0x075400039e303b3fb46c0cff0404c5fa61947c05", # "Them": "0xf0e6a85c6d23aca9ff1b83477d426ed26f218185", # "MyBalance": 1000n, # "TheirBalance": 1000n # }, # { # "AssetAddress": "0x314e43f9825b10961859c2a62c2de6a765c1c1f1", # "Me": "0x075400039e303b3fb46c0cff0404c5fa61947c05", # "Them": "0xf0e6a85c6d23aca9ff1b83477d426ed26f218185", # "MyBalance": 1000n, # "TheirBalance": 1000n # } # ], # "ChannelMode": "Open" # } # ] ``` * Export ledger channel ID: ```bash export LEDGER_CHANNEL_ID= ``` * To get swap channels for a ledger channel: ```bash laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-swap-channels-by-ledger $LEDGER_CHANNEL_ID -p 4005 -h nitro-node" # Example Output: # [ # { # ID: '0x1dbd58d314f123f4b0f4147eee7fd92fa523ba7082d8a75b846f6d1189e2f0e9', # Status: 'Open', # Balances: [ # { # AssetAddress: '0xa4351114dae1abeb2d552d441c9733c72682a45d', # Me: '0x075400039e303b3fb46c0cff0404c5fa61947c05', # Them: '0xd0ea8b27591b1d070cccd4d30b8d408fe794fdfc', # MyBalance: 100, # TheirBalance: 100n # }, # { # AssetAddress: '0x314e43f9825b10961859c2a62c2de6a765c1c1f1', # Me: '0x075400039e303b3fb46c0cff0404c5fa61947c05', # Them: '0xd0ea8b27591b1d070cccd4d30b8d408fe794fdfc', # MyBalance: 100, # TheirBalance: 100 # } # ] # } # ] ``` * Export swap channel ID: ```bash export SWAP_CHANNEL_ID= ``` * One of the participants can initiate the swap and other one will either accept it or reject it * For initiating the swap: ```bash laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client swap-initiate $SWAP_CHANNEL_ID --AssetIn "$ASSET_ADDRESS_1:20" --AssetOut "$ASSET_ADDRESS_2:10" -p 4005 -h nitro-node" # Expected output: # { # SwapAssetsData: { # TokenIn: '0xa4351114dae1abeb2d552d441c9733c72682a45d', # TokenOut: '0x314e43f9825b10961859c2a62c2de6a765c1c1f1', # AmountIn: 20, # AmountOut: 10 # }, # Channel: '0x1dbd58d314f123f4b0f4147eee7fd92fa523ba7082d8a75b846f6d1189e2f0e9' # } ``` OR * For receiving the swap * Get the pending swap: ```bash laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-pending-swap $SWAP_CHANNEL_ID -p 4005 -h nitro-node" # Expected output: # { # Id: '0x7d582020753335cfd2f2af14127c9b51c7ed7a5d547a674d9cb04fe62de6ddf3', # ChannelId: '0x1dbd58d314f123f4b0f4147eee7fd92fa523ba7082d8a75b846f6d1189e2f0e9', # Exchange: { # TokenIn: '0xa4351114dae1abeb2d552d441c9733c72682a45d', # TokenOut: '0x314e43f9825b10961859c2a62c2de6a765c1c1f1', # AmountIn: 20, # AmountOut: 10 # }, # Sigs: { # '0': '0x0a018de18a091f7bfb400d9bc64fe958d298882e569c1668c5b1c853b5493221576b2d72074ef6e1899b79e60eaa9934afac5c1e07b7000746bac5b3b1da93311b' # }, # Nonce: 2840594896360394000 # } ``` * Export swap ID: ```bash export SWAP_ID= ``` * Either accept or reject the swap * To accept: ```bash laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client swap-accept $SWAP_ID -p 4005 -h nitro-node" # Expected output: # Confirming Swap with accepted # Objective complete Swap-0x7d582020753335cfd2f2af14127c9b51c7ed7a5d547a674d9cb04fe62de6ddf3 ``` OR * To reject: ```bash laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client swap-reject $SWAP_ID -p 4005 -h nitro-node" # Expected output: # Confirming Swap with accepted # Objective complete Swap-0x7d582020753335cfd2f2af14127c9b51c7ed7a5d547a674d9cb04fe62de6ddf3 ``` * Check swap channel: ```bash laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-swap-channel $SWAP_CHANNEL_ID -p 4005 -h nitro-node" # Example output: # { # ID: '0x1dbd58d314f123f4b0f4147eee7fd92fa523ba7082d8a75b846f6d1189e2f0e9', # Status: 'Open', # Balances: [ # { # AssetAddress: '0xa4351114dae1abeb2d552d441c9733c72682a45d', # Me: '0xd0ea8b27591b1d070cccd4d30b8d408fe794fdfc', # Them: '0x075400039e303b3fb46c0cff0404c5fa61947c05', # MyBalance: 120n, # TheirBalance: 80n # }, # { # AssetAddress: '0x314e43f9825b10961859c2a62c2de6a765c1c1f1', # Me: '0xd0ea8b27591b1d070cccd4d30b8d408fe794fdfc', # Them: '0x075400039e303b3fb46c0cff0404c5fa61947c05', # MyBalance: 90n, # TheirBalance: 110n # } # ] # } ``` * Close swap channel: ```bash laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client swap-defund $SWAP_CHANNEL_ID -p 4005 -h nitro-node" # Expected output: # Objective started SwapDefund-0x1dbd58d314f123f4b0f4147eee7fd92fa523ba7082d8a75b846f6d1189e2f0e9 # Objective complete SwapDefund-0x1dbd58d314f123f4b0f4147eee7fd92fa523ba7082d8a75b846f6d1189e2f0e9 ``` * Check L2 mirrored channel status: ```bash laconic-so deployment --dir l2-nitro-deployment exec nitro-rpc-client "nitro-rpc-client get-all-ledger-channels -p 4005 -h nitro-node" # Example output: # [ # { # "ID": "0xb34210b763d4fdd534190ba11886ad1daa1e411c87be6fd20cff74cd25077c46", # "Status": "Open", # "Balances": [ # { # "AssetAddress": "0xa4351114dae1abeb2d552d441c9733c72682a45d", # "Me": "0x075400039e303b3fb46c0cff0404c5fa61947c05", # "Them": "0xf0e6a85c6d23aca9ff1b83477d426ed26f218185", # "MyBalance": , # "TheirBalance": # }, # { # "AssetAddress": "0x314e43f9825b10961859c2a62c2de6a765c1c1f1", # "Me": "0x075400039e303b3fb46c0cff0404c5fa61947c05", # "Them": "0xf0e6a85c6d23aca9ff1b83477d426ed26f218185", # "MyBalance": , # "TheirBalance": # } # ], # "ChannelMode": "Open" # } # ] ``` ## Update nitro nodes * Switch to deployments dir: ```bash cd $DEPLOYMENTS_DIR/nitro-node ``` * Rebuild containers: ```bash laconic-so --stack ~/cerc/nitro-stack/stack-orchestrator/stacks/nitro-node build-containers --force-rebuild ``` * Restart the nodes ```bash laconic-so deployment --dir l1-nitro-deployment stop laconic-so deployment --dir l1-nitro-deployment start laconic-so deployment --dir l2-nitro-deployment stop laconic-so deployment --dir l2-nitro-deployment start ``` ## Clean up * Switch to deployments dir: ```bash cd ``` * Stop all Nitro services running in the background: ```bash laconic-so deployment --dir l1-nitro-deployment stop laconic-so deployment --dir l2-nitro-deployment stop ``` * To stop all services and also delete data: ```bash laconic-so deployment --dir l1-nitro-deployment stop --delete-volumes laconic-so deployment --dir l2-nitro-deployment stop --delete-volumes # Remove deployment directories (deployments will have to be recreated for a re-run) sudo rm -r l1-nitro-deployment sudo rm -r l2-nitro-deployment ``` ## Troubleshooting * Check the logs of nitro node to see if the objective is completed ```bash # To check logs of L1 nitro-node laconic-so deployment --dir l1-nitro-deployment logs nitro-node -f --tail 30 # To check logs of L2 nitro-node laconic-so deployment --dir l2-nitro-deployment logs nitro-node -f --tail 30 ``` * If the objective is completed, you can safely stop (`Ctrl+C`) the running CLI command and continue with the further instructions * Stop (`Ctrl+C`) the direct-fund command if it is stuck * Restart the L1 Nitro node: * Stop the deployment: ```bash cd laconic-so deployment --dir l1-nitro-deployment stop ``` * Reset the node's durable store: ```bash sudo rm -rf l1-nitro-deployment/data/nitro_node_data mkdir l1-nitro-deployment/data/nitro_node_data ``` * Restart the deployment: ```bash laconic-so deployment --dir l1-nitro-deployment start ``` * Retry the ledger channel creation command