From 1886a9acf03e6c6c157f9abd75c52e8e92cdb5fc Mon Sep 17 00:00:00 2001 From: ishavenikar Date: Wed, 28 May 2025 13:36:34 +0000 Subject: [PATCH] Add playbook to setup cosmos multisig app (#6) Part of https://www.notion.so/Create-stacks-for-mainnet-1f2a6b22d4728034be4be2c51decf94e Co-authored-by: IshaVenikar Reviewed-on: https://git.vdb.to/cerc-io/laconicd-stack/pulls/6 Co-authored-by: ishavenikar Co-committed-by: ishavenikar --- README.md | 1 + config/network.json | 45 ++++++++ docs/demo.md | 109 ++++++++++++++++++ playbooks/cosmos-multisig-app/README.md | 68 +++++++++++ .../cosmos-multisig-app-start.yml | 88 ++++++++++++++ .../cosmos-multisig-vars.example.yml | 13 +++ .../cosmos-multisig-app-spec-template.yml.j2 | 6 + 7 files changed, 330 insertions(+) create mode 100644 config/network.json create mode 100644 playbooks/cosmos-multisig-app/README.md create mode 100644 playbooks/cosmos-multisig-app/cosmos-multisig-app-start.yml create mode 100644 playbooks/cosmos-multisig-app/cosmos-multisig-vars.example.yml create mode 100644 playbooks/cosmos-multisig-app/templates/specs/cosmos-multisig-app-spec-template.yml.j2 diff --git a/README.md b/README.md index e81912c..7e1229f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # laconicd-stack - Follow [run-first-validator.md](docs/run-first-validator.md) to run the first validator node +- Follow [cosmos-multisig-app playbook](./playbooks/cosmos-multisig-app/README.md) to run the Cosmos Multisig app - Follow [run-validator.md](docs/run-validator.md) to run subsequent validator nodes diff --git a/config/network.json b/config/network.json new file mode 100644 index 0000000..302c664 --- /dev/null +++ b/config/network.json @@ -0,0 +1,45 @@ +{ + "chainId": "laconic-mainnet", + "chainName": "Laconic Mainnet", + "rpc": "", + "rest": "", + "bip44": { + "coinType": 118 + }, + "bech32Config": { + "bech32PrefixAccAddr": "laconic", + "bech32PrefixAccPub": "laconipub", + "bech32PrefixValAddr": "laconicvaloper", + "bech32PrefixValPub": "laconicvaloperpub", + "bech32PrefixConsAddr": "laconicvalcons", + "bech32PrefixConsPub": "laconicvalconspub" + }, + "currencies": [ + { + "coinDenom": "ALNT", + "coinMinimalDenom": "alnt", + "coinDecimals": 18 + } + ], + "feeCurrencies": [ + { + "coinDenom": "ALNT", + "coinMinimalDenom": "alnt", + "coinDecimals": 18 + } + ], + "stakeCurrency": { + "coinDenom": "ALNT", + "coinMinimalDenom": "alnt", + "coinDecimals": 18 + }, + "gasPriceStep": { + "low": 0.01, + "average": 0.01, + "high": 0.02 + }, + "features": [ + "stargate", + "ibc-transfer" + ] +} diff --git a/docs/demo.md b/docs/demo.md index d38e1d3..464199c 100644 --- a/docs/demo.md +++ b/docs/demo.md @@ -188,6 +188,8 @@ laconic-so deployment --dir $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR logs laconicd -f ``` + - The chain will start running after some time. + - Verify that validator and TMKMS pubkeys match - Get validator pubkey on chain @@ -379,6 +381,113 @@ rm $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR/data/laconicd-data/config/priv_validator_key.json ``` +- Copy the example variables file for cosmos-multisig app playbook: + + ```bash + cp ~/cerc/laconicd-stack/playbooks/cosmos-multisig-app/cosmos-multisig-vars.example.yml ~/cerc/laconicd-stack/playbooks/cosmos-multisig-app/cosmos-multisig-vars.yml + ``` + + - Update env values in `cosmos-multisig-vars.yml` withyour node RPC URL + + ```bash + next_public_node_addresses: '["http://localhost:26657"]' + node_rest_endpoint: 'http://localhost:1317' + next_public_is_http_enabled: true + ``` + +- Set envs: + + ```bash + # Set multisig app deployment directory + export MULTISIG_DEPLOYMENT_DIR=cosmos-multisig-deployment + # Set path to custom network JSON file + export NETWORK_JSON_PATH=~/cerc/laconicd-stack/config/network.json + + # Set network mode to host so that browser app and backend can use the same node localhost RPC URL + export USE_HOST_NETWORK=host + + # Set local host URL for dgraph server + export DGRAPH_URL=http://localhost:8080/graphql + ``` + +- Run playbook to setup cosmos multisig app + + ```bash + ansible-playbook -v -i localhost, -c local ~/cerc/laconicd-stack/playbooks/cosmos-multisig-app/cosmos-multisig-app-start.yml + ``` + +- Check logs to ensure that the app is running: + + ```bash + laconic-so deployment --dir $DATA_DIRECTORY/$MULTISIG_DEPLOYMENT_DIR logs -f + ``` + +- The app will be running on `http://localhost:3000/laconic` + +### Create a multisig with both the validator accounts + +- On opening the app, a prompt will be shown to add laconic network to you keplr wallet. Click on `Approve` + +- Go to home and click on `I don't have a multisig` + +- Add the addresses of your validators as member 1 and member 2 + +- Set the threshold to 2 out of 2 members (Both the validators should sign the TX to broadcast it) + +- Click on `Submit` and `Create multisig` + +- Copy your multisig address and send some funds to the address + + ``` + laconic-so deployment --dir $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR exec laconicd "laconicd tx bank send validator-2 1000000alnt --fees 2000alnt --keyring-backend test" + ``` + +### Create and sign transaction + +- Add accounts in keplr wallet for signing the transaction + + - Open keplr wallet and click on the user icon in the top right corner + + - Click on `Add wallet`, then select `Import an existing wallet` and go to `Use recovery phrase or private key` + + - Select the `Private key` tab and then paste the private key of the validator account and click on import + + - Set a name for the wallet (used when connecting wallet to app for signing transaction) and click on next + + - Search for `Laconic network` and select it, then click on `Save` + + - Follow the above steps for the second validator account + +- Go to `home`, paste your multisig address and click on `Use this multisig` + +- You will see the multisig members and holdings for the address + +- Click on `Create new transaction` and then click on `Bank Send` under `Add New Msg` + +- Enter the recipient address ( Eg: `laconic1n4wa366kh0zxndwyq3kkse9ulz9jv9xukx3hy4`), amount to be transfered and memo (optional) + +- Click on create transaction + +- Go back to the multisig info page and scroll down to the `Transactions` section + +- Click on `Verify identity` and connect the app to your validator account in the keplr wallet + +- After approving the connection, you will see the list of transactions created by your multisig + +- Click on your transaction and under `Choose wallet to sign`, click on connect keplr + +- After connecting the wallet, click on `Sign transaction` and approve the transaction + +- Go back to multisig info page, switch to the second validator account in keplr wallet and repeat the same process to sign the transaction with the second validator account + +- Once the transaction is signed by both the validators, click on `Broadcast Transaction`. + +- Confirm funds transfer by checking balance of recipient address + + ```bash + laconic-so deployment --dir $DATA_DIRECTORY/$MAINNET_DEPLOYMENT_DIR exec laconicd "laconicd query bank balances laconic1n4wa366kh0zxndwyq3kkse9ulz9jv9xukx3hy4" + ``` + ## Cleanup - Remove deployments and other config files diff --git a/playbooks/cosmos-multisig-app/README.md b/playbooks/cosmos-multisig-app/README.md new file mode 100644 index 0000000..1bbe6d7 --- /dev/null +++ b/playbooks/cosmos-multisig-app/README.md @@ -0,0 +1,68 @@ +# Cosmos Multisig App Setup + +This playbook sets up the Cosmos Multisig application for managing multisig wallets on the Laconic chain. + +## Prerequisites + +- [ansible](../README.md#ansible-installation) +- [laconic-so](https://github.com/cerc-io/stack-orchestrator/?tab=readme-ov-file#install) +- [Running Laconic validator node](../../docs/run-validator.md) +- Keplr wallet extension installed in browser + +## Configuration + +* Fetch the stack: + + ```bash + laconic-so fetch-stack git.vdb.to/cerc-io/laconicd-stack --git-ssh --pull + ``` + +* Copy the example variables file: + + ```bash + cp ~/cerc/laconicd-stack/playbooks/cosmos-multisig-app/cosmos-multisig-vars.example.yml ~/cerc/laconicd-stack/playbooks/cosmos-multisig-app/cosmos-multisig-vars.yml + ``` + +* Update `cosmos-multisig-vars.yml` with your node configuration: + ```yaml + # TODO: Update with example domains mapped to ports + next_public_node_addresses: + node_rest_endpoint: + ``` + +## Setup Steps + +* Set environment variables: + ```bash + export CWD=$(pwd) + export DATA_DIRECTORY=$CWD + export MULTISIG_DEPLOYMENT_DIR=cosmos-multisig-deployment + export NETWORK_JSON_PATH=~/cerc/laconicd-stack/config/network.json + ``` + +* Setup and start the multisig app: + ```bash + ansible-playbook -v -i localhost, -c local ~/cerc/laconicd-stack/playbooks/cosmos-multisig-app/cosmos-multisig-app-start.yml + ``` + +* Access the app at `http://localhost:3000/laconic` + +## Check Status + +* Check app logs: + ```bash + laconic-so deployment --dir $DATA_DIRECTORY/$MULTISIG_DEPLOYMENT_DIR logs -f + ``` + +## Clean up + +- To stop the deployment: + ```bash + laconic-so deployment --dir $DATA_DIRECTORY/$MULTISIG_DEPLOYMENT_DIR stop + ``` + +- To stop and delete all data: + ```bash + laconic-so deployment --dir $DATA_DIRECTORY/$MULTISIG_DEPLOYMENT_DIR stop --delete-volumes + sudo rm -rf $DATA_DIRECTORY/$MULTISIG_DEPLOYMENT_DIR + ``` diff --git a/playbooks/cosmos-multisig-app/cosmos-multisig-app-start.yml b/playbooks/cosmos-multisig-app/cosmos-multisig-app-start.yml new file mode 100644 index 0000000..22ed152 --- /dev/null +++ b/playbooks/cosmos-multisig-app/cosmos-multisig-app-start.yml @@ -0,0 +1,88 @@ +--- +- name: Setup and deploy the cosmos multisig app + hosts: localhost + vars_files: + - cosmos-multisig-vars.yml + vars: + data_directory: "{{ lookup('env', 'DATA_DIRECTORY') }}" + multisig_deployment_dir: "{{ lookup('env', 'MULTISIG_DEPLOYMENT_DIR') }}" + spec_output: "{{data_directory}}/cosmos-multisig-ui-spec.yml" + spec_template: "./templates/specs/cosmos-multisig-app-spec-template.yml.j2" + network_json: "{{ lookup('env', 'NETWORK_JSON_PATH') }}" + temp_network_json: "{{data_directory}}/temp_network.json" + tasks: + - name: Fail if DATA_DIRECTORY env var is not set + fail: + msg: "Environment variable DATA_DIRECTORY is not set. Please export it before running the playbook." + when: lookup('env', 'DATA_DIRECTORY') == '' + + - name: Clone cosmos-multisig-ui repo + shell: | + laconic-so fetch-stack git.vdb.to/cerc-io/cosmos-multisig-ui@v0.1.0 --git-ssh --pull + + - name: Build container image + shell: | + laconic-so --stack ~/cerc/cosmos-multisig-ui/stack-orchestrator/stacks/cosmos-multisig-ui build-containers + + - name: Create deployment spec file + shell: | + laconic-so --stack ~/cerc/cosmos-multisig-ui/stack-orchestrator/stacks/cosmos-multisig-ui deploy init --output {{ spec_output }} + + - name: Replace network section in spec_output + shell: > + yq eval '(.network) = load("{{ spec_template }}").network' -i {{ spec_output }} + + - name: Create deployment from spec file + shell: | + laconic-so --stack ~/cerc/cosmos-multisig-ui/stack-orchestrator/stacks/cosmos-multisig-ui/ deploy create --spec-file {{ spec_output }} --deployment-dir {{data_directory}}/{{ multisig_deployment_dir }} + + - name: Create config.env in deployment dir + copy: + dest: "{{data_directory}}/{{ multisig_deployment_dir }}/config.env" + content: | + NEXT_PUBLIC_MULTICHAIN={{ next_public_multichain }} + NEXT_PUBLIC_REGISTRY_NAME={{ next_public_registry_name }} + NEXT_PUBLIC_LOGO={{ next_public_logo }} + NEXT_PUBLIC_CHAIN_ID={{ next_public_chain_id }} + NEXT_PUBLIC_CHAIN_DISPLAY_NAME={{ next_public_chain_display_name }} + NEXT_PUBLIC_NODE_ADDRESSES={{ next_public_node_addresses }} + NODE_REST_ENDPOINT={{ node_rest_endpoint }} + NEXT_PUBLIC_DENOM={{ next_public_denom }} + NEXT_PUBLIC_DISPLAY_DENOM={{ next_public_display_denom }} + NEXT_PUBLIC_DISPLAY_DENOM_EXPONENT={{ next_public_display_denom_exponent }} + NEXT_PUBLIC_ASSETS={{ next_public_assets }} + NEXT_PUBLIC_GAS_PRICE={{ next_public_gas_price }} + NEXT_PUBLIC_ADDRESS_PREFIX={{ next_public_address_prefix }} + NEXT_PUBLIC_IS_HTTP_ENABLED={{ next_public_is_http_enabled }} + CHAIN_CONFIG_PATH="{{data_directory}}/{{ multisig_deployment_dir }}/config/cosmos-multisig-ui/network.json" + mode: '0644' + + - name: Fail if NETWORK_JSON_PATH env var is not set + fail: + msg: "Environment variable NETWORK_JSON_PATH is not set. Please export it before running the playbook." + when: lookup('env', 'NETWORK_JSON_PATH') == '' + + - name: Update network.json with environment endpoints + shell: | + RPC_VALUE=$(echo '{{ next_public_node_addresses }}' | jq -r '.[0]') + echo "Using RPC value: $RPC_VALUE" + + jq --arg rpc "$RPC_VALUE" --arg rest "{{ node_rest_endpoint }}" \ + '.rpc = $rpc | .rest = $rest' "{{ lookup('env', 'NETWORK_JSON_PATH') }}" > "{{ temp_network_json }}" + args: + executable: /bin/bash + + - name: Copy modified network JSON to deployment config directory + copy: + src: "{{ temp_network_json }}" + dest: "{{data_directory}}/{{ multisig_deployment_dir }}/config/cosmos-multisig-ui/network.json" + mode: '0644' + + - name: Clean up temporary network.json + file: + path: "{{ temp_network_json }}" + state: absent + + - name: Start the deployment + shell: | + laconic-so deployment --dir {{data_directory}}/{{ multisig_deployment_dir }} start diff --git a/playbooks/cosmos-multisig-app/cosmos-multisig-vars.example.yml b/playbooks/cosmos-multisig-app/cosmos-multisig-vars.example.yml new file mode 100644 index 0000000..ae2d3ed --- /dev/null +++ b/playbooks/cosmos-multisig-app/cosmos-multisig-vars.example.yml @@ -0,0 +1,13 @@ +next_public_multichain: false +next_public_registry_name: "Laconic Mainnet" +next_public_logo: "" +next_public_chain_id: "laconic-mainnet" +next_public_chain_display_name: "Laconic Mainnet" +next_public_node_addresses: '' +next_public_denom: "alnt" +next_public_display_denom: "ALNT" +next_public_display_denom_exponent: 18 +next_public_assets: '[{"denom_units":[{"denom":"alnt","exponent":0},{"denom":"alnt","exponent":6}],"base":"alnt","name":"Laconic Token","display":"ALNT","symbol":"alnt"}]' +next_public_gas_price: "0.01alnt" +next_public_address_prefix: "laconic" +next_public_is_http_enabled: false diff --git a/playbooks/cosmos-multisig-app/templates/specs/cosmos-multisig-app-spec-template.yml.j2 b/playbooks/cosmos-multisig-app/templates/specs/cosmos-multisig-app-spec-template.yml.j2 new file mode 100644 index 0000000..e3a4c9a --- /dev/null +++ b/playbooks/cosmos-multisig-app/templates/specs/cosmos-multisig-app-spec-template.yml.j2 @@ -0,0 +1,6 @@ +network: + ports: + cosmos-multisig-ui: + - 3000:3000 + alpha: + - 8080:8080