├── .build.sh ├── .dockerignore ├── .gitattributes ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── 01-bug-report.yml │ ├── 02-feature-request.yml │ ├── 03-docs-request.yml │ ├── 04-epic-template.md │ └── 05-issue-template.md ├── PULL_REQUEST_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE │ ├── docs.md │ ├── others.md │ └── production.md ├── codecov.yml ├── dependabot.yml ├── stale.yml └── workflows │ ├── codeql-analysis.yml │ ├── dependabot-changelog.yml │ ├── deploy-docs.yml │ ├── docker-push.yml │ ├── interchain-automerge.yml │ ├── interchain-test.yml │ ├── lint.yml │ ├── md-link-checker.yml │ ├── nightly-tests.yml │ ├── release-sims.yml │ ├── release.yml │ ├── sim-label.yml │ ├── sims.yml │ ├── stale.yml │ └── test.yml ├── .gitignore ├── .gitpod.yml ├── .golangci.yml ├── .goreleaser.yml ├── .mergify.yml ├── .mockery.yaml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── DOCKER_README.md ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── RELEASE_NOTES.md ├── RELEASE_PROCESS.md ├── SECURITY.md ├── STATE-COMPATIBILITY.md ├── UPGRADING.md ├── ante ├── ante.go ├── gov_vote_ante.go └── gov_vote_ante_test.go ├── app ├── app.go ├── app_helpers.go ├── app_test.go ├── const.go ├── export.go ├── genesis.go ├── genesis_account.go ├── genesis_account_fuzz_test.go ├── helpers │ └── test_helpers.go ├── keepers │ ├── keepers.go │ └── keys.go ├── modules.go ├── params │ ├── amino.go │ ├── doc.go │ ├── encoding.go │ ├── params.go │ ├── proto.go │ └── weights.go ├── post.go ├── sim │ ├── sim_config.go │ ├── sim_state.go │ └── sim_utils.go ├── sim_bench_test.go ├── sim_test.go └── upgrades │ ├── types.go │ └── v25 │ ├── constants.go │ └── upgrades.go ├── buf.work.yaml ├── client └── docs │ ├── config.json │ └── swagger-ui │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── index.html │ ├── oauth2-redirect.html │ ├── swagger-ui-bundle.js │ ├── swagger-ui-bundle.js.map │ ├── swagger-ui-es-bundle-core.js │ ├── swagger-ui-es-bundle-core.js.map │ ├── swagger-ui-es-bundle.js │ ├── swagger-ui-es-bundle.js.map │ ├── swagger-ui-standalone-preset.js │ ├── swagger-ui-standalone-preset.js.map │ ├── swagger-ui.css │ ├── swagger-ui.css.map │ ├── swagger-ui.js │ ├── swagger-ui.js.map │ └── swagger.yaml ├── cmd └── gaiad │ ├── cmd │ ├── README.md │ ├── bech32_convert.go │ ├── genaccounts.go │ ├── root.go │ ├── root_test.go │ ├── testnet.go │ └── testnet_set_local_validator.go │ └── main.go ├── contrib ├── Dockerfile.test ├── audits │ └── liquid-zellic-audit-25.pdf ├── cw_template.wasm ├── denom.json ├── devtools │ └── Makefile ├── get_node.sh ├── scripts │ ├── local-gaia.sh │ ├── test_localnet_liveness.sh │ └── upgrade_test_scripts │ │ ├── run_gaia.sh │ │ ├── run_upgrade_commands.sh │ │ └── test_upgrade.sh ├── single-node.sh ├── statesync.bash ├── testnets │ ├── Makefile │ ├── README.md │ ├── add-cluster.sh │ ├── add-datadog.sh │ ├── del-cluster.sh │ ├── del-datadog.sh │ ├── list.sh │ ├── new-testnet.sh │ ├── remote │ │ ├── ansible │ │ │ ├── .gitignore │ │ │ ├── add-lcd.yml │ │ │ ├── clear-config.yml │ │ │ ├── extract-config.yml │ │ │ ├── increase-openfiles.yml │ │ │ ├── install-datadog-agent.yml │ │ │ ├── inventory │ │ │ │ ├── COPYING │ │ │ │ ├── digital_ocean.ini │ │ │ │ ├── digital_ocean.py │ │ │ │ ├── ec2.ini │ │ │ │ └── ec2.py │ │ │ ├── logzio.yml │ │ │ ├── remove-datadog-agent.yml │ │ │ ├── roles │ │ │ │ ├── add-lcd │ │ │ │ │ ├── defaults │ │ │ │ │ │ └── main.yml │ │ │ │ │ ├── handlers │ │ │ │ │ │ └── main.yml │ │ │ │ │ ├── tasks │ │ │ │ │ │ └── main.yml │ │ │ │ │ └── templates │ │ │ │ │ │ └── gaiacli.service.j2 │ │ │ │ ├── clear-config │ │ │ │ │ └── tasks │ │ │ │ │ │ └── main.yml │ │ │ │ ├── extract-config │ │ │ │ │ ├── defaults │ │ │ │ │ │ └── main.yml │ │ │ │ │ └── tasks │ │ │ │ │ │ └── main.yml │ │ │ │ ├── increase-openfiles │ │ │ │ │ ├── files │ │ │ │ │ │ ├── 50-fs.conf │ │ │ │ │ │ ├── 91-nofiles.conf │ │ │ │ │ │ └── limits.conf │ │ │ │ │ ├── handlers │ │ │ │ │ │ └── main.yml │ │ │ │ │ └── tasks │ │ │ │ │ │ └── main.yml │ │ │ │ ├── install-datadog-agent │ │ │ │ │ ├── handlers │ │ │ │ │ │ └── main.yml │ │ │ │ │ └── tasks │ │ │ │ │ │ └── main.yml │ │ │ │ ├── logzio │ │ │ │ │ ├── files │ │ │ │ │ │ └── journalbeat.service │ │ │ │ │ ├── handlers │ │ │ │ │ │ └── main.yml │ │ │ │ │ ├── tasks │ │ │ │ │ │ └── main.yml │ │ │ │ │ └── templates │ │ │ │ │ │ └── journalbeat.yml.j2 │ │ │ │ ├── remove-datadog-agent │ │ │ │ │ └── tasks │ │ │ │ │ │ └── main.yml │ │ │ │ ├── set-debug │ │ │ │ │ ├── files │ │ │ │ │ │ ├── sysconfig │ │ │ │ │ │ │ ├── gaiacli │ │ │ │ │ │ │ └── gaiad │ │ │ │ │ │ └── sysctl.d │ │ │ │ │ │ │ └── 10-procdump │ │ │ │ │ ├── handlers │ │ │ │ │ │ └── main.yaml │ │ │ │ │ └── tasks │ │ │ │ │ │ └── main.yml │ │ │ │ ├── setup-fullnodes │ │ │ │ │ ├── defaults │ │ │ │ │ │ └── main.yml │ │ │ │ │ ├── files │ │ │ │ │ │ └── gaiad.service │ │ │ │ │ ├── handlers │ │ │ │ │ │ └── main.yml │ │ │ │ │ └── tasks │ │ │ │ │ │ └── main.yml │ │ │ │ ├── setup-journald │ │ │ │ │ ├── handlers │ │ │ │ │ │ └── main.yml │ │ │ │ │ └── tasks │ │ │ │ │ │ └── main.yml │ │ │ │ ├── setup-validators │ │ │ │ │ ├── defaults │ │ │ │ │ │ └── main.yml │ │ │ │ │ ├── files │ │ │ │ │ │ └── gaiad.service │ │ │ │ │ ├── handlers │ │ │ │ │ │ └── main.yml │ │ │ │ │ └── tasks │ │ │ │ │ │ └── main.yml │ │ │ │ ├── start │ │ │ │ │ └── tasks │ │ │ │ │ │ └── main.yml │ │ │ │ ├── stop │ │ │ │ │ └── tasks │ │ │ │ │ │ └── main.yml │ │ │ │ ├── update-datadog-agent │ │ │ │ │ ├── files │ │ │ │ │ │ └── conf.d │ │ │ │ │ │ │ ├── http_check.d │ │ │ │ │ │ │ └── conf.yaml │ │ │ │ │ │ │ ├── network.d │ │ │ │ │ │ │ └── conf.yaml │ │ │ │ │ │ │ ├── process.d │ │ │ │ │ │ │ └── conf.yaml │ │ │ │ │ │ │ └── prometheus.d │ │ │ │ │ │ │ └── conf.yaml │ │ │ │ │ ├── handlers │ │ │ │ │ │ └── main.yml │ │ │ │ │ ├── tasks │ │ │ │ │ │ └── main.yml │ │ │ │ │ └── templates │ │ │ │ │ │ └── datadog.yaml.j2 │ │ │ │ └── upgrade-gaiad │ │ │ │ │ ├── handlers │ │ │ │ │ └── main.yml │ │ │ │ │ └── tasks │ │ │ │ │ └── main.yml │ │ │ ├── set-debug.yml │ │ │ ├── setup-fullnodes.yml │ │ │ ├── setup-journald.yml │ │ │ ├── setup-validators.yml │ │ │ ├── start.yml │ │ │ ├── status.yml │ │ │ ├── stop.yml │ │ │ ├── update-datadog-agent.yml │ │ │ ├── upgrade-gaia.yml │ │ │ └── upgrade-gaiad.yml │ │ ├── terraform-app │ │ │ ├── .gitignore │ │ │ ├── files │ │ │ │ └── terraform.sh │ │ │ ├── infra │ │ │ │ ├── attachment.tf │ │ │ │ ├── instance.tf │ │ │ │ ├── lb.tf │ │ │ │ ├── lcd.tf │ │ │ │ ├── outputs.tf │ │ │ │ ├── variables.tf │ │ │ │ └── vpc.tf │ │ │ └── main.tf │ │ ├── terraform-aws │ │ │ ├── .gitignore │ │ │ ├── files │ │ │ │ └── terraform.sh │ │ │ ├── main.tf │ │ │ └── nodes │ │ │ │ ├── main.tf │ │ │ │ ├── outputs.tf │ │ │ │ └── variables.tf │ │ └── terraform-do │ │ │ ├── .gitignore │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── cluster │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ │ ├── files │ │ │ └── terraform.sh │ │ │ └── main.tf │ ├── test_platform │ │ ├── README.md │ │ ├── gaiad_config_manager.py │ │ └── templates │ │ │ ├── 3924406.cosmoshub-3.json.tar.gz │ │ │ ├── app.toml │ │ │ ├── config.toml │ │ │ ├── replacement_defaults.txt │ │ │ └── validator_replacement_example.json │ ├── upgrade-gaiad.sh │ └── using-cleveldb.sh └── upload-contract.sh ├── docs ├── .gitignore ├── DOCS_README.md ├── README.md ├── babel.config.js ├── build.sh ├── docs │ ├── architecture │ │ ├── PROCESS.md │ │ ├── README.md │ │ ├── _category_.json │ │ ├── adr │ │ │ ├── PROCESS.md │ │ │ ├── README.md │ │ │ ├── _category_.json │ │ │ ├── adr-001-interchain-accounts.md │ │ │ ├── adr-002-globalfee.md │ │ │ └── adr-003-ica-controller.md │ │ └── templates │ │ │ ├── _category_.json │ │ │ └── adr-template.md │ ├── client │ │ └── _category_.json │ ├── delegators │ │ ├── README.md │ │ ├── _category_.json │ │ ├── delegator-faq.md │ │ ├── delegator-guide-cli.md │ │ └── delegator-security.md │ ├── getting-started │ │ ├── README.md │ │ ├── _category_.json │ │ ├── installation.md │ │ ├── quickstart.md │ │ ├── system-requirements.md │ │ └── what-is-gaia.md │ ├── governance │ │ ├── LICENSE │ │ ├── README.md │ │ ├── _category_.json │ │ ├── best-practices.md │ │ ├── current-parameters.js │ │ ├── formatting.md │ │ ├── process.md │ │ ├── proposal-types │ │ │ ├── README.md │ │ │ ├── _category_.json │ │ │ ├── community-pool-spend.md │ │ │ ├── community-pool-spend │ │ │ │ ├── _category_.json │ │ │ │ └── proposal.json │ │ │ ├── param-change.md │ │ │ ├── software-upgrade.md │ │ │ └── text-prop.md │ │ ├── scripts │ │ │ ├── _category_.json │ │ │ └── extract_onchain_params.py │ │ └── submitting.md │ ├── hub-tutorials │ │ ├── README.md │ │ ├── _category_.json │ │ ├── gaiad.md │ │ ├── join-mainnet.md │ │ ├── join-testnet.md │ │ ├── live-upgrade-tutorial.md │ │ └── upgrade-node.md │ ├── images │ │ ├── cosmos-hub-image.jpg │ │ ├── ledger-tuto-dev-mode.png │ │ ├── ledger-tuto-lunie-address.png │ │ ├── ledger-tuto-lunie-option.png │ │ ├── ledger-tuto-manager.png │ │ ├── ledger-tuto-search.png │ │ └── verify-tx.png │ ├── index.md │ ├── interchain-security │ │ ├── README.md │ │ └── _category_.json │ ├── modules │ │ ├── README.md │ │ ├── _category_.json │ │ ├── liquid.md │ │ ├── lsm-migration.md │ │ └── metaprotocols.md │ ├── proto │ │ └── _category_.json │ ├── resources │ │ ├── README.md │ │ ├── _category_.json │ │ ├── archives.md │ │ ├── genesis.md │ │ ├── hd-wallets.md │ │ ├── ledger.md │ │ ├── reproducible-builds.md │ │ └── service-providers.md │ └── validators │ │ ├── README.md │ │ ├── _category_.json │ │ ├── kms │ │ ├── _category_.json │ │ ├── kms.md │ │ ├── kms_ledger.md │ │ ├── ledger_1.jpg │ │ └── ledger_2.jpg │ │ ├── overview.md │ │ ├── security.md │ │ ├── validator-faq.md │ │ └── validator-setup.md ├── docusaurus.config.js ├── package-lock.json ├── package.json ├── sidebars.js ├── src │ ├── css │ │ ├── base.css │ │ ├── custom.css │ │ └── fonts.css │ ├── js │ │ ├── KeyValueTable.js │ │ └── Var.js │ └── pages │ │ └── index.js ├── static │ ├── .nojekyll │ ├── fonts │ │ ├── inter │ │ │ ├── Inter-Black.woff │ │ │ ├── Inter-Black.woff2 │ │ │ ├── Inter-BlackItalic.woff │ │ │ ├── Inter-BlackItalic.woff2 │ │ │ ├── Inter-Bold.woff │ │ │ ├── Inter-Bold.woff2 │ │ │ ├── Inter-BoldItalic.woff │ │ │ ├── Inter-BoldItalic.woff2 │ │ │ ├── Inter-ExtraBold.woff │ │ │ ├── Inter-ExtraBold.woff2 │ │ │ ├── Inter-ExtraBoldItalic.woff │ │ │ ├── Inter-ExtraBoldItalic.woff2 │ │ │ ├── Inter-ExtraLight.woff │ │ │ ├── Inter-ExtraLight.woff2 │ │ │ ├── Inter-ExtraLightItalic.woff │ │ │ ├── Inter-ExtraLightItalic.woff2 │ │ │ ├── Inter-Italic.woff │ │ │ ├── Inter-Italic.woff2 │ │ │ ├── Inter-Light.woff │ │ │ ├── Inter-Light.woff2 │ │ │ ├── Inter-LightItalic.woff │ │ │ ├── Inter-LightItalic.woff2 │ │ │ ├── Inter-Medium.woff │ │ │ ├── Inter-Medium.woff2 │ │ │ ├── Inter-MediumItalic.woff │ │ │ ├── Inter-MediumItalic.woff2 │ │ │ ├── Inter-Regular.woff │ │ │ ├── Inter-Regular.woff2 │ │ │ ├── Inter-SemiBold.woff │ │ │ ├── Inter-SemiBold.woff2 │ │ │ ├── Inter-SemiBoldItalic.woff │ │ │ ├── Inter-SemiBoldItalic.woff2 │ │ │ ├── Inter-Thin.woff │ │ │ ├── Inter-Thin.woff2 │ │ │ ├── Inter-ThinItalic.woff │ │ │ ├── Inter-ThinItalic.woff2 │ │ │ ├── Inter-italic.var.woff2 │ │ │ └── Inter-roman.var.woff2 │ │ ├── intervar │ │ │ └── Inter.var.woff2 │ │ └── jetbrainsmono │ │ │ ├── JetBrainsMono-Bold.woff2 │ │ │ ├── JetBrainsMono-BoldItalic.woff2 │ │ │ ├── JetBrainsMono-ExtraBold.woff2 │ │ │ ├── JetBrainsMono-ExtraBoldItalic.woff2 │ │ │ ├── JetBrainsMono-ExtraLight.woff2 │ │ │ ├── JetBrainsMono-ExtraLightItalic.woff2 │ │ │ ├── JetBrainsMono-Italic.woff2 │ │ │ ├── JetBrainsMono-Light.woff2 │ │ │ ├── JetBrainsMono-LightItalic.woff2 │ │ │ ├── JetBrainsMono-Medium.woff2 │ │ │ ├── JetBrainsMono-MediumItalic.woff2 │ │ │ ├── JetBrainsMono-Regular.woff2 │ │ │ ├── JetBrainsMono-SemiBold.woff2 │ │ │ ├── JetBrainsMono-SemiBoldItalic.woff2 │ │ │ ├── JetBrainsMono-Thin.woff2 │ │ │ └── JetBrainsMono-ThinItalic.woff2 │ └── img │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-256x256.png │ │ ├── apple-touch-icon.png │ │ ├── banner.jpg │ │ ├── favicon copy.svg │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon-dark.svg │ │ ├── favicon.svg │ │ ├── hub.svg │ │ ├── ico-chevron.svg │ │ ├── ico-github.svg │ │ ├── logo-bw-inverse.svg │ │ ├── logo-bw.svg │ │ ├── logo-sdk.svg │ │ └── logo.svg ├── tailwind.config.js ├── versions.json └── webpack.config.js ├── go.mod ├── go.sum ├── mlc_config.json ├── pkg └── address │ ├── address.go │ └── address_test.go ├── proto ├── buf.gen.gogo.yaml ├── buf.lock ├── buf.yaml ├── gaia │ ├── liquid │ │ ├── module │ │ │ └── v1 │ │ │ │ └── module.proto │ │ └── v1beta1 │ │ │ ├── genesis.proto │ │ │ ├── liquid.proto │ │ │ ├── query.proto │ │ │ └── tx.proto │ └── metaprotocols │ │ └── extensions.proto └── scripts │ ├── protoc-swagger-gen.sh │ └── protocgen.sh ├── sims.mk ├── sonar-project.properties ├── tests ├── e2e │ ├── common │ │ ├── address.go │ │ ├── chain.go │ │ ├── command.go │ │ ├── const.go │ │ ├── hermes.go │ │ ├── http_util.go │ │ ├── io.go │ │ ├── keys.go │ │ ├── types.go │ │ ├── util.go │ │ └── validator.go │ ├── data │ │ ├── counter.wasm │ │ ├── skip_go_entry_point.wasm │ │ ├── skip_go_ibc_adapter_ibc_callbacks.wasm │ │ └── wasm_dummy_light_client.go │ ├── doc.go │ ├── docker │ │ └── hermes.Dockerfile │ ├── e2e_bank_test.go │ ├── e2e_callbacks_test.go │ ├── e2e_cw_test.go │ ├── e2e_distribution_test.go │ ├── e2e_encode_test.go │ ├── e2e_evidence_test.go │ ├── e2e_feegrant_test.go │ ├── e2e_gov_test.go │ ├── e2e_ibc_test.go │ ├── e2e_ibc_v2_test.go │ ├── e2e_ica_test.go │ ├── e2e_liquid_test.go │ ├── e2e_rate_limit_test.go │ ├── e2e_rest_regression_test.go │ ├── e2e_setup_test.go │ ├── e2e_slashing_test.go │ ├── e2e_staking_test.go │ ├── e2e_test.go │ ├── e2e_vesting_test.go │ ├── e2e_wasm_light_client_test.go │ ├── genesis.go │ ├── msg │ │ ├── memo.go │ │ └── proposals.go │ ├── query │ │ ├── auth.go │ │ ├── bank.go │ │ ├── distribution.go │ │ ├── evidence.go │ │ ├── gov.go │ │ ├── ibc.go │ │ ├── ica.go │ │ ├── ics.go │ │ ├── liquid.go │ │ ├── rate_limiting.go │ │ ├── staking.go │ │ ├── tendermint.go │ │ └── wasm.go │ ├── scripts │ │ └── hermes_bootstrap.sh │ ├── suite.go │ └── tx │ │ ├── bank.go │ │ ├── distribution.go │ │ ├── feegrant.go │ │ ├── gov.go │ │ ├── ibc.go │ │ ├── ibc_transfer_v1.go │ │ ├── ibc_transfer_v2.go │ │ ├── ica.go │ │ ├── slashing.go │ │ ├── staking.go │ │ ├── tx.go │ │ ├── vesting.go │ │ └── wasm.go ├── integration │ ├── feemarket_test.go │ ├── interchain_security_test.go │ ├── liquid_test.go │ ├── rate_limit_test.go │ ├── test_common.go │ └── test_utils.go └── interchain │ ├── README.md │ ├── chainsuite │ ├── chain.go │ ├── chain_ics.go │ ├── config.go │ ├── context.go │ ├── envconfig.go │ ├── http.go │ ├── ibc.go │ ├── relayer.go │ ├── suite.go │ └── utils.go │ ├── consumer_chain │ ├── changeover_test.go │ ├── consumer_launch_test.go │ ├── consumer_modification_test.go │ ├── mainnet_consumers_test.go │ └── unbonding_test.go │ ├── delegator │ ├── auth_test.go │ ├── authz_test.go │ ├── bank_test.go │ ├── cosmwasm_test.go │ ├── distribution_test.go │ ├── evidence_test.go │ ├── feegrant_test.go │ ├── gov_test.go │ ├── ica_test.go │ ├── liquid_test.go │ ├── multisig_test.go │ ├── pfm_test.go │ ├── staking_test.go │ ├── suite.go │ └── testdata │ │ └── contract.wasm │ ├── go.mod │ ├── go.sum │ ├── integrator │ ├── endpoints_test.go │ └── export_test.go │ ├── matrix_tool │ └── main.go │ └── validator │ ├── config_test.go │ ├── feemarket_test.go │ ├── inactive_validator_test.go │ └── unbond_test.go ├── tools └── tools.go ├── types ├── constants.go └── errors │ └── errors.go └── x ├── liquid ├── README.md ├── autocli.go ├── client │ └── cli │ │ └── tx.go ├── keeper │ ├── abci.go │ ├── distribution.go │ ├── genesis.go │ ├── grpc_query.go │ ├── grpc_query_test.go │ ├── hooks.go │ ├── keeper.go │ ├── keeper_test.go │ ├── liquid_stake.go │ ├── liquid_stake_test.go │ ├── msg_server.go │ ├── params.go │ ├── tokenize_share_record.go │ └── tokenize_share_record_test.go ├── module.go └── types │ ├── codec.go │ ├── errors.go │ ├── events.go │ ├── expected_keepers.go │ ├── genesis.go │ ├── genesis.pb.go │ ├── keys.go │ ├── liquid.pb.go │ ├── liquid_validator.go │ ├── mocks │ ├── AccountKeeper.go │ ├── BankKeeper.go │ ├── DistributionKeeper.go │ └── StakingKeeper.go │ ├── msg.go │ ├── params.go │ ├── query.pb.go │ ├── query.pb.gw.go │ ├── tokenize_share_record.go │ └── tx.pb.go └── metaprotocols ├── README.md ├── module.go └── types ├── codec.go ├── extensions.pb.go └── keys.go /.build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ue 4 | 5 | # Expect the following envvars to be set: 6 | # - APP 7 | # - VERSION 8 | # - COMMIT 9 | # - TARGET_OS 10 | # - LEDGER_ENABLED 11 | # - DEBUG 12 | 13 | # Source builder's functions library 14 | . /usr/local/share/tendermint/buildlib.sh 15 | 16 | # These variables are now available 17 | # - BASEDIR 18 | # - OUTDIR 19 | 20 | # Build for each os-architecture pair 21 | for platform in ${TARGET_PLATFORMS} ; do 22 | # This function sets GOOS, GOARCH, and OS_FILE_EXT environment variables 23 | # according to the build target platform. OS_FILE_EXT is empty in all 24 | # cases except when the target platform is 'windows'. 25 | setup_build_env_for_platform "${platform}" 26 | 27 | make clean 28 | echo Building for $(go env GOOS)/$(go env GOARCH) >&2 29 | GOROOT_FINAL="$(go env GOROOT)" \ 30 | make build \ 31 | LDFLAGS=-buildid=${VERSION} \ 32 | VERSION=${VERSION} \ 33 | COMMIT=${COMMIT} \ 34 | LEDGER_ENABLED=${LEDGER_ENABLED} 35 | mv ./build/${APP}${OS_FILE_EXT} ${OUTDIR}/${APP}-${VERSION}-$(go env GOOS)-$(go env GOARCH)${OS_FILE_EXT} 36 | 37 | # This function restore the build environment variables to their 38 | # original state. 39 | restore_build_env 40 | done 41 | 42 | # Generate and display build report. 43 | generate_build_report 44 | cat ${OUTDIR}/build_report 45 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | .github 4 | .vscode 5 | docs 6 | .changelog 7 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/.gitattributes -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # CODEOWNERS: https://help.github.com/articles/about-codeowners/ 2 | 3 | # Primary repo maintainers 4 | * @cosmos/interchain_inc_gaia_write 5 | 6 | # CODEOWNERS for interchain tests 7 | 8 | /tests/interchain @dasanchez @LexaMichaelides @fastfadingviolets @cosmos/interchain_inc_gaia_write 9 | /.github/workflows/interchain-test.yml @dasanchez @LexaMichaelides @fastfadingviolets @cosmos/interchain_inc_gaia_write 10 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/01-bug-report.yml: -------------------------------------------------------------------------------- 1 | name: 🐛 Bug report 2 | description: Create a report to help us squash bugs! 3 | title: "[Bug]: " 4 | labels: ["type: bug", "status: waiting-triage"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Thanks for taking the time to fill out this bug report! 10 | Before smashing the submit button please review the template. 11 | 12 | - type: checkboxes 13 | attributes: 14 | label: Is there an existing issue for this? 15 | description: Please search existing issues to avoid creating duplicates. 16 | options: 17 | - label: I have searched the existing issues 18 | required: true 19 | 20 | - type: markdown 21 | attributes: 22 | value: | 23 | IMPORTANT: Prior to opening a bug report, check if it affects one of the core modules 24 | and if its eligible for a bug bounty on `SECURITY.md`. Bugs that are not submitted 25 | through the appropriate channels won't receive any bounty. 26 | - type: textarea 27 | id: what-happened 28 | attributes: 29 | label: What happened? 30 | description: Also tell us, what did you expect to happen? 31 | placeholder: Tell us what you see! 32 | value: "A bug happened!" 33 | validations: 34 | required: true 35 | - type: input 36 | attributes: 37 | label: Gaia Version 38 | description: If applicable, specify the version you're using 39 | placeholder: v15.0.0, v15.1.0, main, etc. 40 | validations: 41 | required: true 42 | - type: textarea 43 | id: reproduce 44 | attributes: 45 | label: How to reproduce? 46 | description: If applicable could you describe how we could reproduce the bug 47 | placeholder: Tell us how to reproduce the bug! 48 | validations: 49 | required: false -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/03-docs-request.yml: -------------------------------------------------------------------------------- 1 | name: Documentation Request 2 | description: Create an issue for missing or incorrect documentation 3 | title: "[Docs]: " 4 | labels: ["type: docs-req", "status: waiting-triage"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | ✰ Thanks for opening an issue! ✰ 10 | Tell us what you would like to see get added to the documentation or if there is an error in the documentation? 11 | 12 | - type: textarea 13 | id: what-happened 14 | attributes: 15 | label: Summary 16 | placeholder: Description of what you would like to see 17 | validations: 18 | required: true 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/04-epic-template.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Epic Template 3 | about: Basic template for epics (used by the team) 4 | title: "[Epic]: " 5 | labels: ['admin: epic', 'status: waiting-triage'] 6 | --- 7 | 8 | ## Problem 9 | 10 | 11 | 12 | ## Closing criteria 13 | 14 | 15 | 16 | 17 | ## Problem details 18 | 19 | 20 | 21 | ## Task list 22 | 23 | ```[tasklist] 24 | ### Must have 25 | 26 | ``` 27 | 28 | ```[tasklist] 29 | ### Nice to have 30 | 31 | ``` -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/05-issue-template.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Issue Template 3 | about: Basic template for issues (used by the team) 4 | labels: 'status: waiting-triage' 5 | --- 6 | 7 | 12 | 13 | ## Problem 14 | 15 | 16 | 17 | ## Closing criteria 18 | 19 | 20 | 21 | 22 | ## Problem details 23 | 24 | 25 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Please go the `Preview` tab and select the appropriate sub-template: 2 | 3 | * [Production code](?expand=1&template=production.md) - for types `fix`, `feat`, and `refactor`. 4 | * [Docs](?expand=1&template=docs.md) - for documentation changes. 5 | * [Others](?expand=1&template=others.md) - for changes that do not affect production code. -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/docs.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 3 | Closes: #XXXX 4 | 5 | 7 | 8 | 9 | --- 10 | 11 | ### Author Checklist 12 | 13 | *All items are required. Please add a note to the item if the item is not applicable and 14 | please add links to any relevant follow up issues.* 15 | 16 | I have... 17 | 18 | - [ ] included the correct `docs:` prefix in the PR title 19 | - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/gaia/blob/main/CONTRIBUTING.md#pr-targeting)) 20 | - [ ] provided a link to the relevant issue or specification 21 | - [ ] reviewed "Files changed" and left comments if necessary 22 | - [ ] confirmed all CI checks have passed 23 | 24 | ### Reviewers Checklist 25 | 26 | *All items are required. Please add a note if the item is not applicable and please add 27 | your handle next to the items reviewed if you only reviewed selected items.* 28 | 29 | I have... 30 | 31 | - [ ] Confirmed the correct `docs:` prefix in the PR title 32 | - [ ] Confirmed all author checklist items have been addressed 33 | - [ ] Confirmed that this PR only changes documentation 34 | - [ ] Reviewed content for consistency 35 | - [ ] Reviewed content for thoroughness 36 | - [ ] Reviewed content for spelling and grammar 37 | - [ ] Tested instructions (if applicable) 38 | 39 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/others.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 3 | Closes: #XXXX 4 | 5 | 7 | 8 | --- 9 | 10 | ### Author Checklist 11 | 12 | *All items are required. Please add a note to the item if the item is not applicable and 13 | please add links to any relevant follow up issues.* 14 | 15 | I have... 16 | 17 | - [ ] Included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title 18 | - [ ] Targeted the correct branch (see [PR Targeting](https://github.com/cosmos/gaia/blob/main/CONTRIBUTING.md#pr-targeting)) 19 | - [ ] Provided a link to the relevant issue or specification 20 | - [ ] Reviewed "Files changed" and left comments if necessary 21 | - [ ] Confirmed all CI checks have passed 22 | 23 | ### Reviewers Checklist 24 | 25 | *All items are required. Please add a note if the item is not applicable and please add 26 | your handle next to the items reviewed if you only reviewed selected items.* 27 | 28 | I have... 29 | 30 | - [ ] Confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title 31 | - [ ] Confirmed all author checklist items have been addressed 32 | - [ ] Confirmed that this PR does not change production code 33 | 34 | -------------------------------------------------------------------------------- /.github/codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | precision: 2 3 | round: down 4 | range: 70...100 5 | status: 6 | project: 7 | default: 8 | threshold: 1% # allow this much decrease on project 9 | app: 10 | target: 80% 11 | paths: # this must be a list type 12 | - "app/" 13 | changes: false 14 | 15 | comment: 16 | layout: "reach, diff, files" 17 | behavior: default # update if exists else create new 18 | require_changes: true 19 | 20 | ignore: 21 | - "*.pb.go" 22 | - "*.pb.gw.go" 23 | - "*.md" 24 | - "*.rst" 25 | - "cmd" 26 | - "client" 27 | - "contrib" 28 | - "docs" 29 | - "proto" 30 | - "tests/e2e" 31 | - "app/app_helpers.go" 32 | - "app/sim" 33 | - "app/upgrades" -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: "/" 5 | schedule: 6 | interval: weekly 7 | open-pull-requests-limit: 10 8 | labels: 9 | - "A:automerge" 10 | 11 | - package-ecosystem: gomod 12 | directory: "/" 13 | schedule: 14 | interval: weekly 15 | open-pull-requests-limit: 10 16 | labels: 17 | - "A:automerge" 18 | - dependencies 19 | 20 | - package-ecosystem: gomod 21 | directory: "/" 22 | schedule: 23 | interval: daily 24 | target-branch: "release/v21.x" 25 | # Only allow automated security-related dependency updates on release branches. 26 | open-pull-requests-limit: 0 27 | labels: 28 | - dependencies 29 | 30 | - package-ecosystem: gomod 31 | directory: "/" 32 | schedule: 33 | interval: daily 34 | target-branch: "release/v20.x" 35 | # Only allow automated security-related dependency updates on release branches. 36 | open-pull-requests-limit: 0 37 | labels: 38 | - dependencies 39 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-stale - https://github.com/probot/stale 2 | 3 | # Number of days of inactivity before an Issue or Pull Request becomes stale 4 | daysUntilStale: 10 5 | 6 | # Number of days of inactivity before an Issue or Pull Request with the stale label is closed. 7 | # Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. 8 | daysUntilClose: 4 9 | 10 | # Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) 11 | onlyLabels: [] 12 | 13 | # Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable 14 | exemptLabels: 15 | - blocked 16 | - pinned 17 | - security 18 | 19 | # Set to true to ignore issues in a project (defaults to false) 20 | exemptProjects: true 21 | 22 | # Set to true to ignore issues in a milestone (defaults to false) 23 | exemptMilestones: true 24 | 25 | # Label to use when marking as stale 26 | staleLabel: stale 27 | 28 | # Comment to post when marking as stale. Set to `false` to disable 29 | markComment: > 30 | This issue has been automatically marked as stale because it has not had 31 | recent activity. It will be closed if no further activity occurs. Thank you 32 | for your contributions. 33 | # Limit the number of actions per hour, from 1-30. Default is 30 34 | limitPerRun: 30 35 | 36 | # Limit to only `issues` or `pulls` 37 | only: pulls 38 | 39 | # Optionally, specify configuration settings that are specific to just 'issues' or 'pulls': 40 | pulls: 41 | daysUntilStale: 30 42 | markComment: > 43 | This pull request has been automatically marked as stale because it has not had 44 | recent activity. It will be closed if no further activity occurs. Thank you 45 | for your contributions. 46 | -------------------------------------------------------------------------------- /.github/workflows/dependabot-changelog.yml: -------------------------------------------------------------------------------- 1 | name: Dependabot Changelog Entry 2 | 3 | on: 4 | pull_request: 5 | types: [opened, reopened] 6 | branches: [main] 7 | 8 | jobs: 9 | update-changelog: 10 | if: github.actor == 'dependabot[bot]' 11 | runs-on: ubuntu-latest 12 | permissions: 13 | contents: write # needed for pushing changes 14 | 15 | steps: 16 | - uses: actions/checkout@v4 17 | - uses: crambl/dependabot-changelog-writer@trunk # Always use the latest RELEASED version of this action 18 | with: 19 | changelog-entry-pattern: 'Bump [dep] from [old] to [new] ([pr-link])' 20 | -------------------------------------------------------------------------------- /.github/workflows/deploy-docs.yml: -------------------------------------------------------------------------------- 1 | name: Deploy docs 2 | # This job builds and deploys documenation to github pages. 3 | # It runs on every push to main with a change in the docs folder. 4 | on: 5 | workflow_dispatch: 6 | push: 7 | branches: 8 | - main 9 | # - "release/**" 10 | paths: 11 | - "docs/**" 12 | # - "x/**/*.md" 13 | - .github/workflows/deploy-docs.yml 14 | 15 | permissions: 16 | contents: read 17 | 18 | jobs: 19 | build-and-deploy: 20 | permissions: 21 | contents: write # for JamesIves/github-pages-deploy-action to push changes in repo 22 | runs-on: ubuntu-latest 23 | steps: 24 | - name: Checkout 🛎️ 25 | uses: actions/checkout@v4 26 | with: 27 | persist-credentials: false 28 | fetch-depth: 0 29 | path: "." 30 | 31 | - name: Setup Node.js 🔧 32 | uses: actions/setup-node@v4 33 | with: 34 | node-version: "18.x" 35 | 36 | # npm install npm should be removed when https://github.com/npm/cli/issues/4942 is fixed 37 | - name: Build 🔧 38 | run: | 39 | npm install -g npm@8.5.5 40 | make build-docs 41 | 42 | - name: Deploy 🚀 43 | uses: JamesIves/github-pages-deploy-action@v4.7.3 44 | with: 45 | branch: gh-pages 46 | folder: ~/output 47 | single-commit: true -------------------------------------------------------------------------------- /.github/workflows/interchain-automerge.yml: -------------------------------------------------------------------------------- 1 | name: interchaintest-automerge 2 | on: 3 | pull_request_target: 4 | types: 5 | - labeled 6 | pull_request_review: 7 | types: 8 | - submitted 9 | check_suite: 10 | types: 11 | - completed 12 | jobs: 13 | automerge: 14 | runs-on: ubuntu-latest 15 | permissions: 16 | contents: write 17 | pull-requests: write 18 | steps: 19 | - uses: dorny/paths-filter@v3 20 | id: changes 21 | with: 22 | filters: | 23 | tests: 24 | - 'tests/interchain/**' 25 | src: 26 | - '**/*' 27 | - '!tests/interchain/**' 28 | predicate-quantifier: 'every' 29 | - if: steps.changes.outputs.tests == 'true' && steps.changes.outputs.src == 'false' 30 | id: automerge 31 | name: automerge tests 32 | uses: "pascalgn/automerge-action@v0.16.4" 33 | env: 34 | GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" 35 | MERGE_FORKS: "false" 36 | MERGE_METHOD: "squash" 37 | MERGE_REQUIRED_APPROVALS: "1" 38 | MERGE_LABELS: "automerge" 39 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | on: 3 | push: 4 | branches: 5 | - main 6 | - release/** 7 | - feat/** 8 | pull_request: 9 | permissions: 10 | contents: read 11 | jobs: 12 | golangci: 13 | name: golangci-lint 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v4 17 | - uses: actions/setup-go@v5 18 | with: 19 | go-version: "1.24" 20 | check-latest: true 21 | - uses: technote-space/get-diff-action@v6.1.2 22 | id: git_diff 23 | with: 24 | PATTERNS: | 25 | **/*.go 26 | go.mod 27 | go.sum 28 | **/go.mod 29 | **/go.sum 30 | - name: run linting 31 | if: env.GIT_DIFF 32 | run: | 33 | make lint 34 | -------------------------------------------------------------------------------- /.github/workflows/md-link-checker.yml: -------------------------------------------------------------------------------- 1 | name: Check Markdown links 2 | on: 3 | workflow_dispatch: 4 | schedule: 5 | - cron: '* */24 * * *' 6 | jobs: 7 | markdown-link-check: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v4 11 | - uses: gaurav-nelson/github-action-markdown-link-check@1.0.17 12 | with: 13 | folder-path: "docs" 14 | file-extension: ".mdx" -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: "Release" 2 | 3 | on: 4 | # can be used to re-release an existing tag 5 | workflow_dispatch: 6 | 7 | push: 8 | tags: 9 | - "v[0-9]+\\.[0-9]+\\.[0-9]+" 10 | - "v[0-9]+\\.[0-9]+\\.[0-9]+-rc[0-9]+" 11 | 12 | jobs: 13 | release: 14 | runs-on: Gaia-Runner-medium 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@v4 18 | with: 19 | fetch-depth: 0 20 | - run: git fetch --force --tags 21 | 22 | - uses: actions/setup-go@v5 23 | with: 24 | go-version: "1.24" 25 | 26 | - name: Set Env 27 | run: echo "TM_VERSION=$(go list -m github.com/cometbft/cometbft | sed 's:.* ::')" >> $GITHUB_ENV 28 | 29 | - name: Release 30 | run: | 31 | make ci-release 32 | env: 33 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 34 | 35 | - name: Cleanup 36 | run: | 37 | sudo rm -rf dist 38 | -------------------------------------------------------------------------------- /.github/workflows/sim-label.yml: -------------------------------------------------------------------------------- 1 | name: SimLabeled 2 | on: 3 | pull_request: 4 | types: [ labeled ] 5 | 6 | jobs: 7 | cleanup-runs: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: rokroskar/workflow-run-cleanup-action@master 11 | env: 12 | GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" 13 | # if: "!startsWith(github.ref, 'refs/tags/') && github.ref != 'refs/heads/main'" 14 | 15 | newbuild: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/setup-go@v5 19 | with: 20 | go-version: 1.24.x 21 | - name: Install runsim 22 | run: go install github.com/cosmos/tools/cmd/runsim@v1.0.0 23 | - uses: actions/cache@v4.2.0 24 | with: 25 | path: ~/go/bin 26 | key: ${{ runner.os }}-go-runsim-binary 27 | 28 | test-sim-nondeterminism-labeled: 29 | if: ${{ github.event.label.name == 'sim' }} 30 | runs-on: ubuntu-latest 31 | needs: newbuild 32 | steps: 33 | - uses: actions/checkout@v4 34 | - uses: actions/setup-go@v5 35 | with: 36 | go-version: 1.24.x 37 | - uses: actions/cache@v4.2.0 38 | with: 39 | path: ~/go/bin 40 | key: ${{ runner.os }}-go-runsim-binary 41 | - name: test nondeterminism 42 | run: | 43 | make test-sim-nondeterminism 44 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: "Close stale pull requests" 2 | on: 3 | schedule: 4 | - cron: "0 0 * * 1-5" 5 | 6 | jobs: 7 | stale: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/stale@v9.1.0 11 | with: 12 | repo-token: ${{ secrets.GITHUB_TOKEN }} 13 | stale-pr-message: "This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions." 14 | days-before-stale: -1 15 | days-before-close: -1 16 | days-before-pr-stale: 45 17 | days-before-pr-close: 6 18 | exempt-pr-labels: "pinned, security, proposal, blocked, ADR" 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS 2 | .DS_Store 3 | *.swp 4 | *.swo 5 | *.swl 6 | *.swm 7 | *.swn 8 | .vscode 9 | .idea 10 | 11 | # Build 12 | artifacts 13 | vendor 14 | build 15 | tools/bin/* 16 | examples/build/* 17 | docs/_build 18 | docs/node_modules 19 | docs/tutorial 20 | dist 21 | tools-stamp 22 | docs/node_modules 23 | docs/versioned_docs 24 | docs/versioned_sidebars 25 | 26 | # Data - ideally these don't exist 27 | baseapp/data/* 28 | client/lcd/keys/* 29 | cmd/gaiacli/statik/statik.go 30 | mytestnet 31 | 32 | # Testing 33 | coverage.txt 34 | profile.out 35 | 36 | # Vagrant 37 | .vagrant/ 38 | *.box 39 | *.log 40 | vagrant 41 | 42 | # IDE 43 | .idea/ 44 | *.iml 45 | 46 | # Graphviz 47 | dependency-graph.png 48 | 49 | # Latex 50 | *.aux 51 | *.out 52 | *.synctex.gz 53 | contract_tests/* 54 | 55 | go.work.sum 56 | 57 | node_modules 58 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | tasks: 2 | - init: go get && go build ./... && go test ./... && make 3 | command: go run 4 | image: ghcr.io/notional-labs/cosmos 5 | -------------------------------------------------------------------------------- /.mergify.yml: -------------------------------------------------------------------------------- 1 | defaults: 2 | actions: 3 | backport: 4 | assignees: 5 | - "{{ author }}" 6 | 7 | queue_rules: 8 | - name: default 9 | conditions: 10 | - "#approved-reviews-by>1" 11 | 12 | pull_request_rules: 13 | - name: Automatic merge on approval to the main branch 14 | conditions: 15 | - "#approved-reviews-by>=1" 16 | - base=main 17 | - label=A:automerge 18 | actions: 19 | queue: 20 | name: default 21 | merge: 22 | method: squash 23 | commit_message_template: | 24 | {{ title }} (#{{ number }}) 25 | {{ body }} 26 | 27 | - name: Backport patches to the release/v23.x branch 28 | conditions: 29 | - base=main 30 | - label=A:backport/v23.x 31 | actions: 32 | backport: 33 | branches: 34 | - release/v23.x 35 | 36 | - name: Backport patches to the release/v24.x branch 37 | conditions: 38 | - base=main 39 | - label=A:backport/v24.x 40 | actions: 41 | backport: 42 | branches: 43 | - release/v24.x 44 | -------------------------------------------------------------------------------- /.mockery.yaml: -------------------------------------------------------------------------------- 1 | quiet: False 2 | disable-version-string: True 3 | with-expecter: True 4 | mockname: "{{.InterfaceName}}" 5 | filename: "{{.MockName}}.go" 6 | dir: "{{ .InterfaceDirRelative }}/mocks" 7 | outpkg: mocks 8 | packages: 9 | github.com/cosmos/gaia/v22/x/lsm/types: 10 | config: 11 | recursive: True 12 | include-regex: ".*Keeper" 13 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Info on how to use this docker image can be found in DOCKER_README.md 2 | ARG IMG_TAG=latest 3 | 4 | # Compile the gaiad binary 5 | FROM golang:1.24-alpine AS gaiad-builder 6 | WORKDIR /src/app/ 7 | ENV PACKAGES="curl build-base git bash file linux-headers eudev-dev" 8 | RUN apk add --no-cache $PACKAGES 9 | 10 | # See https://github.com/CosmWasm/wasmvm/releases 11 | ARG WASMVM_VERSION=v2.2.3 12 | ADD https://github.com/CosmWasm/wasmvm/releases/download/${WASMVM_VERSION}/libwasmvm_muslc.aarch64.a /lib/libwasmvm_muslc.aarch64.a 13 | ADD https://github.com/CosmWasm/wasmvm/releases/download/${WASMVM_VERSION}/libwasmvm_muslc.x86_64.a /lib/libwasmvm_muslc.x86_64.a 14 | RUN sha256sum /lib/libwasmvm_muslc.aarch64.a | grep 6641730781bb1adc4bdf04a1e0f822b9ad4fb8ed57dcbbf575527e63b791ae41 15 | RUN sha256sum /lib/libwasmvm_muslc.x86_64.a | grep 32503fe35a7be202c5f7c3051497d6e4b3cd83079a61f5a0bf72a2a455b6d820 16 | RUN cp "/lib/libwasmvm_muslc.$(uname -m).a" /lib/libwasmvm_muslc.a 17 | 18 | COPY go.mod go.sum* ./ 19 | RUN go mod download 20 | 21 | COPY . . 22 | RUN LEDGER_ENABLED=false LINK_STATICALLY=true BUILD_TAGS=muslc make build 23 | RUN echo "Ensuring binary is statically linked ..." \ 24 | && file /src/app/build/gaiad | grep "statically linked" 25 | 26 | FROM alpine:$IMG_TAG 27 | RUN apk add --no-cache build-base jq 28 | RUN addgroup -g 1025 nonroot 29 | RUN adduser -D nonroot -u 1025 -G nonroot 30 | ARG IMG_TAG 31 | COPY --from=gaiad-builder /src/app/build/gaiad /usr/local/bin/ 32 | EXPOSE 26656 26657 1317 9090 33 | USER nonroot 34 | 35 | ENTRYPOINT ["gaiad", "start"] 36 | -------------------------------------------------------------------------------- /RELEASE_NOTES.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | # Gaia Release Notes 10 | 11 | ## 📝 Changelog 12 | 13 | Check out the [changelog](https://github.com/cosmos/gaia/blob//CHANGELOG.md) for a list of relevant changes or [compare all changes](https://github.com/cosmos/gaia/compare/...) from last release. 14 | 15 | 16 | Refer to the [upgrading guide](https://github.com/cosmos/gaia/blob/release//UPGRADING.md) when migrating from `` to ``. 17 | 18 | ## 🚀 Highlights 19 | 20 | 21 | 22 | ## 🔨 Build from source 23 | 24 | ```bash 25 | git clone https://github.com/cosmos/gaia 26 | cd gaia && git checkout 27 | make install 28 | ``` 29 | 30 | ## ⚡️ Download binaries 31 | 32 | Binaries for linux, darwin, and windows are available below. -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | ## How to Report a Security Bug 2 | 3 | If you believe you have found a security vulnerability in Gaia, 4 | you can report it to our primary vulnerability disclosure channel, the 5 | [Cosmos HackerOne Bug Bounty program](https://hackerone.com/cosmos?type=team). 6 | 7 | If you prefer to report an issue via email, you may send a bug report to 8 | security@interchain.io with the issue details, reproduction, impact, and other 9 | information. Please submit only one unique email thread per vulnerability. 10 | Any issues reported via email are ineligible for bounty rewards. 11 | 12 | Artifacts from an email report are saved at the time the email is triaged. 13 | Please note: our team is not able to monitor dynamic content (e.g. a Google 14 | Docs link that is edited after receipt) throughout the lifecycle of a report. 15 | If you would like to share additional information or modify previous 16 | information, please include it in an additional reply as an additional attachment. 17 | 18 | ***Please DO NOT file a public issue in this repository to report a security vulnerability.*** 19 | 20 | 21 | ## Coordinated Vulnerability Disclosure Policy and Safe Harbor 22 | 23 | For the most up-to-date version of the policies that govern vulnerability 24 | disclosure, please consult the [HackerOne program page](https://hackerone.com/cosmos?type=team&view_policy=true). 25 | 26 | The policy hosted on HackerOne is the official Coordinated Vulnerability 27 | Disclosure policy and Safe Harbor for the Interchain Stack, and the teams and 28 | infrastructure it supports, and it supersedes previous security policies that 29 | have been used in the past by individual teams and projects with targets in 30 | scope of the program. 31 | -------------------------------------------------------------------------------- /app/app_helpers.go: -------------------------------------------------------------------------------- 1 | package gaia 2 | 3 | import ( 4 | ibckeeper "github.com/cosmos/ibc-go/v10/modules/core/keeper" 5 | icstest "github.com/cosmos/interchain-security/v7/testutil/integration" 6 | ibcproviderkeeper "github.com/cosmos/interchain-security/v7/x/ccv/provider/keeper" 7 | ) 8 | 9 | // ProviderApp interface implementations for icstest tests 10 | 11 | // GetProviderKeeper implements the ProviderApp interface. 12 | func (app *GaiaApp) GetProviderKeeper() ibcproviderkeeper.Keeper { //nolint:nolintlint 13 | return app.ProviderKeeper 14 | } 15 | 16 | // GetIBCKeeper implements the TestingApp interface. 17 | func (app *GaiaApp) GetIBCKeeper() *ibckeeper.Keeper { //nolint:nolintlint 18 | return app.IBCKeeper 19 | } 20 | 21 | // GetTestStakingKeeper implements the ProviderApp interface. 22 | func (app *GaiaApp) GetTestStakingKeeper() icstest.TestStakingKeeper { //nolint:nolintlint 23 | return app.StakingKeeper 24 | } 25 | 26 | // GetTestBankKeeper implements the ProviderApp interface. 27 | func (app *GaiaApp) GetTestBankKeeper() icstest.TestBankKeeper { //nolint:nolintlint 28 | return app.BankKeeper 29 | } 30 | 31 | // GetTestSlashingKeeper implements the ProviderApp interface. 32 | func (app *GaiaApp) GetTestSlashingKeeper() icstest.TestSlashingKeeper { //nolint:nolintlint 33 | return app.SlashingKeeper 34 | } 35 | 36 | // GetTestDistributionKeeper implements the ProviderApp interface. 37 | func (app *GaiaApp) GetTestDistributionKeeper() icstest.TestDistributionKeeper { //nolint:nolintlint 38 | return app.DistrKeeper 39 | } 40 | 41 | func (app *GaiaApp) GetTestAccountKeeper() icstest.TestAccountKeeper { //nolint:nolintlint 42 | return app.AccountKeeper 43 | } 44 | -------------------------------------------------------------------------------- /app/app_test.go: -------------------------------------------------------------------------------- 1 | package gaia_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | 8 | db "github.com/cosmos/cosmos-db" 9 | 10 | "cosmossdk.io/log" 11 | 12 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" 13 | govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" 14 | 15 | wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" 16 | 17 | gaia "github.com/cosmos/gaia/v25/app" 18 | gaiahelpers "github.com/cosmos/gaia/v25/app/helpers" 19 | ) 20 | 21 | type EmptyAppOptions struct{} 22 | 23 | var emptyWasmOption []wasmkeeper.Option 24 | 25 | func (ao EmptyAppOptions) Get(_ string) interface{} { 26 | return nil 27 | } 28 | 29 | func TestGaiaApp_BlockedModuleAccountAddrs(t *testing.T) { 30 | app := gaia.NewGaiaApp( 31 | log.NewNopLogger(), 32 | db.NewMemDB(), 33 | nil, 34 | true, 35 | map[int64]bool{}, 36 | gaia.DefaultNodeHome, 37 | EmptyAppOptions{}, 38 | emptyWasmOption, 39 | ) 40 | 41 | moduleAccountAddresses := app.ModuleAccountAddrs() 42 | blockedAddrs := app.BlockedModuleAccountAddrs(moduleAccountAddresses) 43 | 44 | require.NotContains(t, blockedAddrs, authtypes.NewModuleAddress(govtypes.ModuleName).String()) 45 | } 46 | 47 | func TestGaiaApp_Export(t *testing.T) { 48 | app := gaiahelpers.Setup(t) 49 | _, err := app.ExportAppStateAndValidators(true, []string{}, []string{}) 50 | require.NoError(t, err, "ExportAppStateAndValidators should not have an error") 51 | } 52 | -------------------------------------------------------------------------------- /app/const.go: -------------------------------------------------------------------------------- 1 | package gaia 2 | 3 | const ( 4 | appName = "GaiaApp" 5 | ) 6 | -------------------------------------------------------------------------------- /app/genesis.go: -------------------------------------------------------------------------------- 1 | package gaia 2 | 3 | import ( 4 | "encoding/json" 5 | ) 6 | 7 | // The genesis state of the blockchain is represented here as a map of raw json 8 | // messages key'd by a identifier string. 9 | // The identifier is used to determine which module genesis information belongs 10 | // to so it may be appropriately routed during init chain. 11 | // Within this application default genesis information is retrieved from 12 | // the ModuleBasicManager which populates json from each BasicModule 13 | // object provided to it during init. 14 | type GenesisState map[string]json.RawMessage 15 | -------------------------------------------------------------------------------- /app/genesis_account_fuzz_test.go: -------------------------------------------------------------------------------- 1 | package gaia 2 | 3 | import ( 4 | "runtime/debug" 5 | "testing" 6 | 7 | "github.com/google/gofuzz" 8 | ) 9 | 10 | func TestFuzzGenesisAccountValidate(t *testing.T) { 11 | if testing.Short() { 12 | t.Skip("running in -short mode") 13 | } 14 | 15 | t.Parallel() 16 | 17 | acct := new(SimGenesisAccount) 18 | i := 0 19 | defer func() { 20 | r := recover() 21 | if r == nil { 22 | return 23 | } 24 | 25 | // Otherwise report on the configuration and iteration. 26 | t.Fatalf("Failed SimGenesisAccount on iteration #%d: %#v\n\n%s\n\n%s", i, acct, r, debug.Stack()) 27 | }() 28 | 29 | f := fuzz.New() 30 | for i = 0; i < 1e5; i++ { 31 | acct = new(SimGenesisAccount) 32 | f.Fuzz(acct) 33 | acct.Validate() //nolint:errcheck 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/params/amino.go: -------------------------------------------------------------------------------- 1 | //go:build test_amino 2 | // +build test_amino 3 | 4 | package params 5 | 6 | import ( 7 | "github.com/cosmos/cosmos-sdk/codec" 8 | cdctypes "github.com/cosmos/cosmos-sdk/codec/types" 9 | "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" 10 | ) 11 | 12 | func MakeTestEncodingConfig() EncodingConfig { 13 | cdc := codec.NewLegacyAmino() 14 | interfaceRegistry := cdctypes.NewInterfaceRegistry() 15 | codec := codec.NewProtoCodec(interfaceRegistry) 16 | 17 | return EncodingConfig{ 18 | InterfaceRegistry: interfaceRegistry, 19 | Marshaler: codec, 20 | TxConfig: legacytx.StdTxConfig{Cdc: cdc}, 21 | Amino: cdc, 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/params/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package params defines the simulation parameters in the gaia. 3 | 4 | It contains the default weights used for each transaction used on the module's 5 | simulation. These weights define the chance for a transaction to be simulated at 6 | any given operation. 7 | 8 | You can replace the default values for the weights by providing a params.json 9 | file with the weights defined for each of the transaction operations: 10 | 11 | { 12 | "op_weight_msg_send": 60, 13 | "op_weight_msg_delegate": 100, 14 | } 15 | 16 | In the example above, the `MsgSend` has 60% chance to be simulated, while the 17 | `MsgDelegate` will always be simulated. 18 | */ 19 | package params 20 | -------------------------------------------------------------------------------- /app/params/encoding.go: -------------------------------------------------------------------------------- 1 | package params 2 | 3 | import ( 4 | "github.com/cosmos/cosmos-sdk/client" 5 | "github.com/cosmos/cosmos-sdk/codec" 6 | "github.com/cosmos/cosmos-sdk/codec/types" 7 | ) 8 | 9 | // EncodingConfig specifies the concrete encoding types to use for a given app. 10 | // This is provided for compatibility between protobuf and amino implementations. 11 | type EncodingConfig struct { 12 | InterfaceRegistry types.InterfaceRegistry 13 | Marshaler codec.Codec 14 | TxConfig client.TxConfig 15 | Amino *codec.LegacyAmino 16 | } 17 | -------------------------------------------------------------------------------- /app/params/params.go: -------------------------------------------------------------------------------- 1 | package params 2 | 3 | // Simulation parameter constants 4 | const ( 5 | StakePerAccount = "stake_per_account" 6 | InitiallyBondedValidators = "initially_bonded_validators" 7 | ) 8 | 9 | // Keeper constants 10 | const ( 11 | // MaxIBCCallbackGas should roughly be a couple orders of magnitude larger than needed. 12 | MaxIBCCallbackGas = uint64(10_000_000) 13 | ) 14 | -------------------------------------------------------------------------------- /app/params/proto.go: -------------------------------------------------------------------------------- 1 | package params 2 | 3 | import ( 4 | "github.com/cosmos/gogoproto/proto" 5 | 6 | "cosmossdk.io/x/tx/signing" 7 | 8 | "github.com/cosmos/cosmos-sdk/codec" 9 | "github.com/cosmos/cosmos-sdk/codec/address" 10 | codectypes "github.com/cosmos/cosmos-sdk/codec/types" 11 | sdk "github.com/cosmos/cosmos-sdk/types" 12 | "github.com/cosmos/cosmos-sdk/x/auth/tx" 13 | ) 14 | 15 | // MakeEncodingConfig creates an EncodingConfig for an amino based test configuration. 16 | func MakeEncodingConfig() EncodingConfig { 17 | amino := codec.NewLegacyAmino() 18 | interfaceRegistry, err := codectypes.NewInterfaceRegistryWithOptions(codectypes.InterfaceRegistryOptions{ 19 | ProtoFiles: proto.HybridResolver, 20 | SigningOptions: signing.Options{ 21 | AddressCodec: address.Bech32Codec{ 22 | Bech32Prefix: sdk.GetConfig().GetBech32AccountAddrPrefix(), 23 | }, 24 | ValidatorAddressCodec: address.Bech32Codec{ 25 | Bech32Prefix: sdk.GetConfig().GetBech32ValidatorAddrPrefix(), 26 | }, 27 | }, 28 | }) 29 | if err != nil { 30 | panic(err) 31 | } 32 | cdc := codec.NewProtoCodec(interfaceRegistry) 33 | txCfg := tx.NewTxConfig(cdc, tx.DefaultSignModes) 34 | return EncodingConfig{ 35 | InterfaceRegistry: interfaceRegistry, 36 | Marshaler: cdc, 37 | TxConfig: txCfg, 38 | Amino: amino, 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/params/weights.go: -------------------------------------------------------------------------------- 1 | package params 2 | 3 | // Default simulation operation weights for messages and gov proposals 4 | const ( 5 | DefaultWeightMsgSend int = 100 6 | DefaultWeightMsgMultiSend int = 10 7 | DefaultWeightMsgSetWithdrawAddress int = 50 8 | DefaultWeightMsgWithdrawDelegationReward int = 50 9 | DefaultWeightMsgWithdrawValidatorCommission int = 50 10 | DefaultWeightMsgFundCommunityPool int = 50 11 | DefaultWeightMsgDeposit int = 100 12 | DefaultWeightMsgVote int = 67 13 | DefaultWeightMsgUnjail int = 100 14 | DefaultWeightMsgCreateValidator int = 100 15 | DefaultWeightMsgEditValidator int = 5 16 | DefaultWeightMsgDelegate int = 100 17 | DefaultWeightMsgUndelegate int = 100 18 | DefaultWeightMsgBeginRedelegate int = 100 19 | DefaultWeightMsgCancelUnbondingDelegation int = 100 20 | 21 | DefaultWeightCommunitySpendProposal int = 5 22 | DefaultWeightTextProposal int = 5 23 | DefaultWeightParamChangeProposal int = 5 24 | ) 25 | -------------------------------------------------------------------------------- /app/post.go: -------------------------------------------------------------------------------- 1 | package gaia 2 | 3 | import ( 4 | feemarketpost "github.com/skip-mev/feemarket/x/feemarket/post" 5 | 6 | errorsmod "cosmossdk.io/errors" 7 | 8 | sdk "github.com/cosmos/cosmos-sdk/types" 9 | sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" 10 | 11 | "github.com/cosmos/gaia/v25/ante" 12 | ) 13 | 14 | // PostHandlerOptions are the options required for constructing a FeeMarket PostHandler. 15 | type PostHandlerOptions struct { 16 | AccountKeeper feemarketpost.AccountKeeper 17 | BankKeeper feemarketpost.BankKeeper 18 | FeeMarketKeeper feemarketpost.FeeMarketKeeper 19 | } 20 | 21 | // NewPostHandler returns a PostHandler chain with the fee deduct decorator. 22 | func NewPostHandler(options PostHandlerOptions) (sdk.PostHandler, error) { 23 | if !ante.UseFeeMarketDecorator { 24 | return nil, nil 25 | } 26 | 27 | if options.AccountKeeper == nil { 28 | return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "account keeper is required for post builder") 29 | } 30 | 31 | if options.BankKeeper == nil { 32 | return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "bank keeper is required for post builder") 33 | } 34 | 35 | if options.FeeMarketKeeper == nil { 36 | return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "feemarket keeper is required for post builder") 37 | } 38 | 39 | postDecorators := []sdk.PostDecorator{ 40 | feemarketpost.NewFeeMarketDeductDecorator( 41 | options.AccountKeeper, 42 | options.BankKeeper, 43 | options.FeeMarketKeeper, 44 | ), 45 | } 46 | 47 | return sdk.ChainPostDecorators(postDecorators...), nil 48 | } 49 | -------------------------------------------------------------------------------- /app/upgrades/types.go: -------------------------------------------------------------------------------- 1 | package upgrades 2 | 3 | import ( 4 | store "cosmossdk.io/store/types" 5 | upgradetypes "cosmossdk.io/x/upgrade/types" 6 | 7 | sdk "github.com/cosmos/cosmos-sdk/types" 8 | "github.com/cosmos/cosmos-sdk/types/module" 9 | 10 | "github.com/cosmos/gaia/v25/app/keepers" 11 | ) 12 | 13 | // Upgrade defines a struct containing necessary fields that a SoftwareUpgradeProposal 14 | // must have written, in order for the state migration to go smoothly. 15 | // An upgrade must implement this struct, and then set it in the app.go. 16 | // The app.go will then define the handler. 17 | type Upgrade struct { 18 | // Upgrade version name, for the upgrade handler, e.g. `v7` 19 | UpgradeName string 20 | 21 | // CreateUpgradeHandler defines the function that creates an upgrade handler 22 | CreateUpgradeHandler func(*module.Manager, module.Configurator, *keepers.AppKeepers) upgradetypes.UpgradeHandler 23 | 24 | // Store upgrades, should be used for any new modules introduced, new modules deleted, or store names renamed. 25 | StoreUpgrades store.StoreUpgrades 26 | } 27 | 28 | // Fork defines a struct containing the requisite fields for a non-software upgrade proposal 29 | // Hard Fork at a given height to implement. 30 | // There is one time code that can be added for the start of the Fork, in `BeginForkLogic`. 31 | // Any other change in the code should be height-gated, if the goal is to have old and new binaries 32 | // to be compatible prior to the upgrade height. 33 | type Fork struct { 34 | // Upgrade version name, for the upgrade handler, e.g. `v7` 35 | UpgradeName string 36 | // height the upgrade occurs at 37 | UpgradeHeight int64 38 | 39 | // Function that runs some custom state transition code at the beginning of a fork. 40 | BeginForkLogic func(ctx sdk.Context, keepers *keepers.AppKeepers) 41 | } 42 | -------------------------------------------------------------------------------- /app/upgrades/v25/constants.go: -------------------------------------------------------------------------------- 1 | package v25 2 | 3 | import ( 4 | storetypes "cosmossdk.io/store/types" 5 | 6 | crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" 7 | 8 | "github.com/cosmos/gaia/v25/app/upgrades" 9 | ) 10 | 11 | const ( 12 | // UpgradeName defines the on-chain upgrade name. 13 | UpgradeName = "v25" 14 | ) 15 | 16 | var Upgrade = upgrades.Upgrade{ 17 | UpgradeName: UpgradeName, 18 | CreateUpgradeHandler: CreateUpgradeHandler, 19 | StoreUpgrades: storetypes.StoreUpgrades{ 20 | Deleted: []string{ 21 | crisistypes.ModuleName, 22 | }, 23 | }, 24 | } 25 | -------------------------------------------------------------------------------- /app/upgrades/v25/upgrades.go: -------------------------------------------------------------------------------- 1 | package v25 2 | 3 | import ( 4 | "context" 5 | 6 | errorsmod "cosmossdk.io/errors" 7 | upgradetypes "cosmossdk.io/x/upgrade/types" 8 | 9 | sdk "github.com/cosmos/cosmos-sdk/types" 10 | "github.com/cosmos/cosmos-sdk/types/module" 11 | 12 | "github.com/cosmos/gaia/v25/app/keepers" 13 | ) 14 | 15 | // CreateUpgradeHandler returns an upgrade handler for Gaia v25. 16 | func CreateUpgradeHandler( 17 | mm *module.Manager, 18 | configurator module.Configurator, 19 | keepers *keepers.AppKeepers, 20 | ) upgradetypes.UpgradeHandler { 21 | return func(c context.Context, plan upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { 22 | ctx := sdk.UnwrapSDKContext(c) 23 | ctx.Logger().Info("Starting module migrations...") 24 | 25 | vm, err := mm.RunMigrations(ctx, configurator, vm) 26 | if err != nil { 27 | return vm, errorsmod.Wrapf(err, "running module migrations") 28 | } 29 | 30 | ctx.Logger().Info("Upgrade v25 complete") 31 | return vm, nil 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /buf.work.yaml: -------------------------------------------------------------------------------- 1 | # This workspace file points to the roots found in your 2 | # previous "buf.yaml" configuration. 3 | version: v1 4 | directories: 5 | - proto 6 | -------------------------------------------------------------------------------- /client/docs/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "swagger": "2.0", 3 | "info": { 4 | "title": "Cosmoshub - gRPC Gateway docs", 5 | "description": "A REST interface for state queries", 6 | "version": "1.0.0" 7 | }, 8 | "apis": [ 9 | 10 | ] 11 | } -------------------------------------------------------------------------------- /client/docs/swagger-ui/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/client/docs/swagger-ui/favicon-16x16.png -------------------------------------------------------------------------------- /client/docs/swagger-ui/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/client/docs/swagger-ui/favicon-32x32.png -------------------------------------------------------------------------------- /client/docs/swagger-ui/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Swagger UI 7 | 8 | 9 | 10 | 31 | 32 | 33 | 34 |
35 | 36 | 37 | 38 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /client/docs/swagger-ui/swagger.yaml: -------------------------------------------------------------------------------- 1 | swagger: '2.0' 2 | info: 3 | title: Cosmoshub - gRPC Gateway docs 4 | description: A REST interface for state queries 5 | version: 1.0.0 6 | paths: 7 | 8 | -------------------------------------------------------------------------------- /cmd/gaiad/cmd/bech32_convert.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/spf13/cobra" 7 | 8 | addressutil "github.com/cosmos/gaia/v25/pkg/address" 9 | ) 10 | 11 | var flagBech32Prefix = "prefix" 12 | 13 | // AddBech32ConvertCommand returns bech32-convert cobra Command. 14 | func AddBech32ConvertCommand() *cobra.Command { 15 | cmd := &cobra.Command{ 16 | Use: "bech32-convert [address]", 17 | Short: "Convert any bech32 string to the cosmos prefix", 18 | Long: `Convert any bech32 string to the cosmos prefix 19 | 20 | Example: 21 | gaiad debug bech32-convert akash1a6zlyvpnksx8wr6wz8wemur2xe8zyh0ytz6d88 22 | 23 | gaiad debug bech32-convert stride1673f0t8p893rqyqe420mgwwz92ac4qv6synvx2 --prefix osmo 24 | `, 25 | Args: cobra.ExactArgs(1), 26 | RunE: func(cmd *cobra.Command, args []string) error { 27 | bech32prefix, err := cmd.Flags().GetString(flagBech32Prefix) 28 | if err != nil { 29 | return err 30 | } 31 | 32 | address := args[0] 33 | convertedAddress, err := addressutil.ConvertBech32Prefix(address, bech32prefix) 34 | if err != nil { 35 | return fmt.Errorf("conversation failed: %s", err) 36 | } 37 | 38 | cmd.Println(convertedAddress) 39 | 40 | return nil 41 | }, 42 | } 43 | 44 | cmd.Flags().StringP(flagBech32Prefix, "p", "cosmos", "Bech32 Prefix to encode to") 45 | 46 | return cmd 47 | } 48 | 49 | // addDebugCommands injects custom debug commands into another command as children. 50 | func addDebugCommands(cmd *cobra.Command) *cobra.Command { 51 | cmd.AddCommand(AddBech32ConvertCommand()) 52 | return cmd 53 | } 54 | -------------------------------------------------------------------------------- /cmd/gaiad/cmd/root_test.go: -------------------------------------------------------------------------------- 1 | package cmd_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | 8 | svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" 9 | 10 | app "github.com/cosmos/gaia/v25/app" 11 | "github.com/cosmos/gaia/v25/cmd/gaiad/cmd" 12 | ) 13 | 14 | func TestRootCmdConfig(t *testing.T) { 15 | rootCmd := cmd.NewRootCmd() 16 | rootCmd.SetArgs([]string{ 17 | "config", // Test the config cmd 18 | "get app pruning", 19 | "keyring-backend", // key 20 | "test", // value 21 | }) 22 | 23 | require.NoError(t, svrcmd.Execute(rootCmd, "", app.DefaultNodeHome)) 24 | } 25 | -------------------------------------------------------------------------------- /cmd/gaiad/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | 6 | svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" 7 | 8 | app "github.com/cosmos/gaia/v25/app" 9 | "github.com/cosmos/gaia/v25/cmd/gaiad/cmd" 10 | ) 11 | 12 | func main() { 13 | rootCmd := cmd.NewRootCmd() 14 | 15 | if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil { 16 | os.Exit(1) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /contrib/Dockerfile.test: -------------------------------------------------------------------------------- 1 | # Simple usage with a mounted data directory: 2 | # > docker build -t gaia . 3 | # > docker run -it -p 46657:46657 -p 46656:46656 -v ~/.gaia:/root/.gaia gaia gaiad init 4 | # > docker run -it -p 46657:46657 -p 46656:46656 -v ~/.gaia:/root/.gaia gaia gaiad start 5 | FROM golang:1.21-alpine AS build-env 6 | 7 | # Set up dependencies 8 | ENV PACKAGES curl make git libc-dev bash gcc linux-headers eudev-dev python3 9 | 10 | # Set working directory for the build 11 | WORKDIR /go/src/github.com/cosmos/gaia 12 | 13 | # Add source files 14 | COPY . . 15 | 16 | # Install minimum necessary dependencies, build Cosmos SDK, remove packages 17 | RUN apk add --no-cache $PACKAGES && \ 18 | make install 19 | 20 | # Final image 21 | FROM alpine:edge 22 | 23 | # Install ca-certificates 24 | RUN apk add --update ca-certificates 25 | WORKDIR /root 26 | 27 | # Copy over binaries from the build-env 28 | COPY --from=build-env /go/bin/gaiad /usr/bin/gaiad 29 | 30 | COPY ./contrib/single-node.sh . 31 | 32 | EXPOSE 26657 33 | 34 | ENTRYPOINT [ "./single-node.sh" ] 35 | # NOTE: to run this image, docker run -d -p 26657:26657 ./single-node.sh {{chain_id}} {{genesis_account}} 36 | -------------------------------------------------------------------------------- /contrib/audits/liquid-zellic-audit-25.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/contrib/audits/liquid-zellic-audit-25.pdf -------------------------------------------------------------------------------- /contrib/cw_template.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/contrib/cw_template.wasm -------------------------------------------------------------------------------- /contrib/denom.json: -------------------------------------------------------------------------------- 1 | 2 | 3 | [{ 4 | "base": "uatom", 5 | "denom_units": [ 6 | { 7 | "aliases": [ 8 | "microatom" 9 | ], 10 | "denom": "uatom", 11 | "exponent": 0 12 | }, 13 | { 14 | "aliases": [ 15 | "milliatom" 16 | ], 17 | "denom": "matom", 18 | "exponent": 3 19 | }, 20 | { 21 | "aliases": [], 22 | "denom": "atom", 23 | "exponent": 6 24 | } 25 | ], 26 | "description": "The native staking token of the Cosmos Hub.", 27 | "display": "atom", 28 | "name": "asdf", 29 | "symbol": "asdf" 30 | }] -------------------------------------------------------------------------------- /contrib/get_node.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | VERSION=v11.15.0 4 | NODE_FULL=node-${VERSION}-linux-x64 5 | 6 | mkdir -p ~/.local/bin 7 | mkdir -p ~/.local/node 8 | wget http://nodejs.org/dist/${VERSION}/${NODE_FULL}.tar.gz -O ~/.local/node/${NODE_FULL}.tar.gz 9 | tar -xzf ~/.local/node/${NODE_FULL}.tar.gz -C ~/.local/node/ 10 | ln -s ~/.local/node/${NODE_FULL}/bin/node ~/.local/bin/node 11 | ln -s ~/.local/node/${NODE_FULL}/bin/npm ~/.local/bin/npm 12 | export PATH=~/.local/bin:$PATH 13 | npm i -g dredd@11.0.1 14 | ln -s ~/.local/node/${NODE_FULL}/bin/dredd ~/.local/bin/dredd 15 | -------------------------------------------------------------------------------- /contrib/scripts/test_localnet_liveness.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | CNT=0 4 | ITER=$1 5 | SLEEP=$2 6 | NUMBLOCKS=$3 7 | NODEADDR=$4 8 | 9 | if [ -z "$1" ]; then 10 | echo "Invalid argument: missing number of iterations" 11 | echo "sh test_localnet_liveness.sh " 12 | exit 1 13 | fi 14 | 15 | if [ -z "$2" ]; then 16 | echo "Invalid argument: missing sleep duration" 17 | echo "sh test_localnet_liveness.sh " 18 | exit 1 19 | fi 20 | 21 | if [ -z "$3" ]; then 22 | echo "Invalid argument: missing number of blocks" 23 | echo "sh test_localnet_liveness.sh " 24 | exit 1 25 | fi 26 | 27 | if [ -z "$4" ]; then 28 | echo "Invalid argument: missing node address" 29 | echo "sh test_localnet_liveness.sh " 30 | exit 1 31 | fi 32 | 33 | echo "running 'sh test_localnet_liveness.sh iterations=$ITER sleep=$SLEEP num-blocks=$NUMBLOCKS node-address=$NODEADDR'" 34 | 35 | while [ ${CNT} -lt $ITER ]; do 36 | curr_block=$(curl -s $NODEADDR:26657/status | jq -r '.result.sync_info.latest_block_height') 37 | 38 | tail liveness.out 39 | 40 | if [ ! -z ${curr_block} ]; then 41 | echo "Current block: ${curr_block}" 42 | fi 43 | 44 | if [ ! -z ${curr_block} ] && [ ${curr_block} -gt ${NUMBLOCKS} ]; then 45 | echo "Success: number of blocks reached" 46 | exit 0 47 | fi 48 | 49 | sleep $SLEEP 50 | done 51 | 52 | echo "Failed: timeout reached" 53 | exit 1 54 | -------------------------------------------------------------------------------- /contrib/single-node.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -o errexit -o nounset 4 | 5 | HOME_DIR="${1:-$HOME}" 6 | CHAINID="test-gaia" 7 | USER_COINS="100000000000stake" 8 | STAKE="100000000stake" 9 | MONIKER="gaia-test-node" 10 | GAIAD="gaiad" 11 | 12 | 13 | echo "Using home dir: $HOME_DIR" 14 | rm -rf $HOME_DIR/.gaia 15 | $GAIAD init --chain-id $CHAINID $MONIKER --home "$HOME_DIR/.gaia" 16 | 17 | echo "Setting up genesis file" 18 | jq ".app_state.gov.params.voting_period = \"20s\" | .app_state.gov.params.expedited_voting_period = \"10s\" | .app_state.staking.params.unbonding_time = \"86400s\"" \ 19 | "${HOME_DIR}/.gaia/config/genesis.json" > \ 20 | "${HOME_DIR}/edited_genesis.json" && mv "${HOME_DIR}/edited_genesis.json" "${HOME_DIR}/.gaia/config/genesis.json" 21 | 22 | $GAIAD keys add validator --keyring-backend="test" 23 | $GAIAD keys add user --keyring-backend="test" 24 | $GAIAD genesis add-genesis-account $("${GAIAD}" keys show validator -a --keyring-backend="test") $USER_COINS 25 | $GAIAD genesis add-genesis-account $("${GAIAD}" keys show user -a --keyring-backend="test") $USER_COINS 26 | $GAIAD genesis gentx validator $STAKE --keyring-backend="test" --chain-id $CHAINID 27 | $GAIAD genesis collect-gentxs 28 | 29 | # Set proper defaults and change ports 30 | echo "Setting up node configs" 31 | # sed -i '' 's#"tcp://127.0.0.1:26657"#"tcp://0.0.0.0:26657"#g' ~/.gaia/config/config.toml 32 | sleep 1 33 | sed -i -r 's/timeout_commit = "5s"/timeout_commit = "1s"/g' ~/.gaia/config/config.toml 34 | sed -i -r 's/timeout_propose = "3s"/timeout_propose = "1s"/g' ~/.gaia/config/config.toml 35 | sed -i -r 's/index_all_keys = false/index_all_keys = true/g' ~/.gaia/config/config.toml 36 | sed -i -r 's/minimum-gas-prices = ""/minimum-gas-prices = "0stake"/g' ~/.gaia/config/app.toml 37 | 38 | # Start the gaia 39 | $GAIAD start --api.enable=true 40 | -------------------------------------------------------------------------------- /contrib/testnets/README.md: -------------------------------------------------------------------------------- 1 | # Networks 2 | 3 | Here contains the files required for automated deployment of either local or remote testnets. 4 | 5 | Doing so is best accomplished using the `make` targets. For more information, see the 6 | [networks documentation](../docs/hub-tutorials/deploy-testnet.md) 7 | -------------------------------------------------------------------------------- /contrib/testnets/add-cluster.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # add-cluster - example make call to add a set of nodes to an existing testnet in AWS 3 | # WARNING: Run it from the current directory - it uses relative paths to ship the binary and the genesis.json,config.toml files 4 | 5 | if [ $# -ne 4 ]; then 6 | echo "Usage: ./add-cluster.sh " 7 | exit 1 8 | fi 9 | set -eux 10 | 11 | # The testnet name is the same on all nodes 12 | export TESTNET_NAME=$1 13 | export CLUSTER_NAME=$2 14 | export REGION_LIMIT=$3 15 | export SERVERS=$4 16 | 17 | # Build the AWS full nodes 18 | rm -rf remote/ansible/keys 19 | make fullnodes-start 20 | 21 | # Save the private key seed words from the nodes 22 | SEEDFOLDER="${TESTNET_NAME}-${CLUSTER_NAME}-seedwords" 23 | mkdir -p "${SEEDFOLDER}" 24 | test ! -f "${SEEDFOLDER}/node0" && mv remote/ansible/keys/* "${SEEDFOLDER}" 25 | 26 | -------------------------------------------------------------------------------- /contrib/testnets/add-datadog.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # add-datadog - add datadog agent to a set of nodes 3 | 4 | if [ $# -ne 2 ]; then 5 | echo "Usage: ./add-datadog.sh " 6 | exit 1 7 | fi 8 | set -eux 9 | 10 | export TESTNET_NAME=$1 11 | export CLUSTER_NAME=$2 12 | 13 | make install-datadog 14 | 15 | -------------------------------------------------------------------------------- /contrib/testnets/del-cluster.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # del-cluster - example make call to delete a set of nodes on an existing testnet in AWS 3 | 4 | if [ $# -ne 1 ]; then 5 | echo "Usage: ./add-cluster.sh " 6 | exit 1 7 | fi 8 | set -eux 9 | 10 | export CLUSTER_NAME=$1 11 | 12 | # Delete the AWS nodes 13 | make fullnodes-stop 14 | 15 | -------------------------------------------------------------------------------- /contrib/testnets/del-datadog.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # del-datadog - aremove datadog agent from a set of nodes 3 | 4 | if [ $# -ne 1 ]; then 5 | echo "Usage: ./del-datadog.sh " 6 | exit 1 7 | fi 8 | set -eux 9 | 10 | export CLUSTER_NAME=$1 11 | 12 | make remove-datadog 13 | 14 | -------------------------------------------------------------------------------- /contrib/testnets/list.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # list - list the IPs of a set of nodes 3 | 4 | if [ $# -ne 1 ]; then 5 | echo "Usage: ./list.sh " 6 | exit 1 7 | fi 8 | set -eux 9 | 10 | export CLUSTER_NAME=$1 11 | 12 | make list 13 | 14 | -------------------------------------------------------------------------------- /contrib/testnets/new-testnet.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # new-testnet - example make call to create a new set of validator nodes in AWS 3 | # WARNING: Run it from the current directory - it uses relative paths to ship the binary 4 | 5 | if [ $# -ne 4 ]; then 6 | echo "Usage: ./new-testnet.sh " 7 | exit 1 8 | fi 9 | set -eux 10 | 11 | if [ -z "`file ../build/gaiad | grep 'ELF 64-bit'`" ]; then 12 | # Build the linux binary we're going to ship to the nodes 13 | make -C .. build-linux 14 | fi 15 | 16 | # The testnet name is the same on all nodes 17 | export TESTNET_NAME=$1 18 | export CLUSTER_NAME=$2 19 | export REGION_LIMIT=$3 20 | export SERVERS=$4 21 | 22 | # Build the AWS validator nodes and extract the genesis.json and config.toml from one of them 23 | rm -rf remote/ansible/keys 24 | make validators-start extract-config 25 | 26 | # Save the private key seed words from the validators 27 | SEEDFOLDER="${TESTNET_NAME}-${CLUSTER_NAME}-seedwords" 28 | mkdir -p "${SEEDFOLDER}" 29 | test ! -f "${SEEDFOLDER}/node0" && mv remote/ansible/keys/* "${SEEDFOLDER}" 30 | 31 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/.gitignore: -------------------------------------------------------------------------------- 1 | *.retry 2 | files/* 3 | keys/* 4 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/add-lcd.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: all 4 | any_errors_fatal: true 5 | gather_facts: no 6 | roles: 7 | - add-lcd 8 | 9 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/clear-config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: all 4 | any_errors_fatal: true 5 | gather_facts: no 6 | roles: 7 | - clear-config 8 | 9 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/extract-config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: all 4 | any_errors_fatal: true 5 | gather_facts: no 6 | roles: 7 | - extract-config 8 | 9 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/increase-openfiles.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: all 4 | any_errors_fatal: true 5 | gather_facts: no 6 | roles: 7 | - increase-openfiles 8 | 9 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/install-datadog-agent.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | #DD_API_KEY,TESTNET_NAME,CLUSTER_NAME required 4 | 5 | - hosts: all 6 | any_errors_fatal: true 7 | gather_facts: no 8 | roles: 9 | - setup-journald 10 | - install-datadog-agent 11 | - update-datadog-agent 12 | 13 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/inventory/digital_ocean.ini: -------------------------------------------------------------------------------- 1 | # Ansible DigitalOcean external inventory script settings 2 | # 3 | 4 | [digital_ocean] 5 | 6 | # The module needs your DigitalOcean API Token. 7 | # It may also be specified on the command line via --api-token 8 | # or via the environment variables DO_API_TOKEN or DO_API_KEY 9 | # 10 | #api_token = 123456abcdefg 11 | 12 | 13 | # API calls to DigitalOcean may be slow. For this reason, we cache the results 14 | # of an API call. Set this to the path you want cache files to be written to. 15 | # One file will be written to this directory: 16 | # - ansible-digital_ocean.cache 17 | # 18 | cache_path = /tmp 19 | 20 | 21 | # The number of seconds a cache file is considered valid. After this many 22 | # seconds, a new API call will be made, and the cache file will be updated. 23 | # 24 | cache_max_age = 300 25 | 26 | # Use the private network IP address instead of the public when available. 27 | # 28 | use_private_network = False 29 | 30 | # Pass variables to every group, e.g.: 31 | # 32 | # group_variables = { 'ansible_user': 'root' } 33 | # 34 | group_variables = {} 35 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/logzio.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | #Note: You need to add LOGZIO_TOKEN variable with your API key. Like this: ansible-playbook -e LOGZIO_TOKEN=ABCXYZ123456 4 | 5 | - hosts: all 6 | any_errors_fatal: true 7 | gather_facts: no 8 | vars: 9 | - service: gaiad 10 | - JOURNALBEAT_BINARY: "{{lookup('env', 'GOPATH')}}/bin/journalbeat" 11 | roles: 12 | - logzio 13 | 14 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/remove-datadog-agent.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: all 4 | any_errors_fatal: true 5 | gather_facts: no 6 | roles: 7 | - remove-datadog-agent 8 | 9 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/add-lcd/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | GAIACLI_ADDRESS: tcp://0.0.0.0:1317 4 | 5 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/add-lcd/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: systemctl 4 | systemd: name=gaiacli enabled=yes daemon_reload=yes 5 | 6 | - name: restart gaiacli 7 | service: name=gaiacli state=restarted 8 | 9 | 10 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/add-lcd/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Copy binary 4 | copy: 5 | src: "{{GAIACLI_BINARY}}" 6 | dest: /usr/bin/gaiacli 7 | mode: 0755 8 | notify: restart gaiacli 9 | 10 | - name: Copy service 11 | template: 12 | src: gaiacli.service.j2 13 | dest: /etc/systemd/system/gaiacli.service 14 | notify: systemctl 15 | 16 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/add-lcd/templates/gaiacli.service.j2: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=gaiacli 3 | Requires=network-online.target 4 | After=network-online.target 5 | 6 | [Service] 7 | Restart=on-failure 8 | User=gaiad 9 | Group=gaiad 10 | PermissionsStartOnly=true 11 | ExecStart=/usr/bin/gaiacli rest-server --laddr {{GAIACLI_ADDRESS}} 12 | ExecReload=/bin/kill -HUP $MAINPID 13 | KillSignal=SIGTERM 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | 18 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/clear-config/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Stop service 3 | service: name=gaiad state=stopped 4 | 5 | - name: Delete files 6 | file: "path={{item}} state=absent" 7 | with_items: 8 | - /usr/bin/gaiad 9 | - /home/gaiad/.gaia 10 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/extract-config/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | TESTNET_NAME: remotenet 4 | 5 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/extract-config/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Fetch genesis.json 4 | fetch: "src=/home/gaiad/.gaia/config/genesis.json dest={{GENESISFILE}} flat=yes" 5 | run_once: yes 6 | become: yes 7 | become_user: gaiad 8 | 9 | - name: Fetch config.toml 10 | fetch: "src=/home/gaiad/.gaia/config/config.toml dest={{CONFIGFILE}} flat=yes" 11 | run_once: yes 12 | become: yes 13 | become_user: gaiad 14 | 15 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/increase-openfiles/files/50-fs.conf: -------------------------------------------------------------------------------- 1 | fs.file-max=262144 2 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/increase-openfiles/files/91-nofiles.conf: -------------------------------------------------------------------------------- 1 | * soft nofile 262144 2 | * hard nofile 262144 3 | 4 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/increase-openfiles/files/limits.conf: -------------------------------------------------------------------------------- 1 | [Service] 2 | LimitNOFILE=infinity 3 | LimitMEMLOCK=infinity 4 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/increase-openfiles/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: reload systemctl 4 | systemd: name=systemd daemon_reload=yes 5 | 6 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/increase-openfiles/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Based on: https://stackoverflow.com/questions/38155108/how-to-increase-limit-for-open-processes-and-files-using-ansible 3 | 4 | - name: Set sysctl File Limits 5 | copy: 6 | src: 50-fs.conf 7 | dest: /etc/sysctl.d 8 | 9 | - name: Set Shell File Limits 10 | copy: 11 | src: 91-nofiles.conf 12 | dest: /etc/security/limits.d 13 | 14 | - name: Set gaia filehandle Limits 15 | copy: 16 | src: limits.conf 17 | dest: "/lib/systemd/system/{{item}}.service.d" 18 | notify: reload systemctl 19 | with_items: 20 | - gaiad 21 | - gaiacli 22 | 23 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/install-datadog-agent/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: restart datadog-agent 4 | service: name=datadog-agent state=restarted 5 | 6 | - name: restart rsyslog 7 | service: name=rsyslog state=restarted 8 | 9 | - name: restart journald 10 | service: name=systemd-journald state=restarted 11 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/install-datadog-agent/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Remove old datadog.yaml, if exist 4 | file: path=/etc/datadog-agent/datadog.yaml state=absent 5 | notify: restart datadog-agent 6 | 7 | - name: Download DataDog agent script 8 | get_url: url=https://raw.githubusercontent.com/DataDog/datadog-agent/master/cmd/agent/install_script.sh dest=/tmp/datadog-agent-install.sh mode=0755 9 | 10 | - name: Install DataDog agent 11 | command: "/tmp/datadog-agent-install.sh" 12 | environment: 13 | DD_API_KEY: "{{DD_API_KEY}}" 14 | DD_HOST_TAGS: "testnet:{{TESTNET_NAME}},cluster:{{CLUSTER_NAME}}" 15 | 16 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/logzio/files/journalbeat.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=journalbeat 3 | #propagates activation, deactivation and activation fails. 4 | Requires=network-online.target 5 | After=network-online.target 6 | 7 | [Service] 8 | Restart=on-failure 9 | ExecStart=/usr/bin/journalbeat -c /etc/journalbeat/journalbeat.yml -path.home /usr/share/journalbeat -path.config /etc/journalbeat -path.data /var/lib/journalbeat -path.logs /var/log/journalbeat 10 | Restart=always 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | 15 | 16 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/logzio/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: reload daemon 4 | command: "systemctl daemon-reload" 5 | 6 | - name: restart journalbeat 7 | service: name=journalbeat state=restarted 8 | 9 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/logzio/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Copy journalbeat binary 4 | copy: src="{{JOURNALBEAT_BINARY}}" dest=/usr/bin/journalbeat mode=0755 5 | notify: restart journalbeat 6 | 7 | - name: Create folders 8 | file: "path={{item}} state=directory recurse=yes" 9 | with_items: 10 | - /etc/journalbeat 11 | - /etc/pki/tls/certs 12 | - /usr/share/journalbeat 13 | - /var/log/journalbeat 14 | 15 | - name: Copy journalbeat config 16 | template: src=journalbeat.yml.j2 dest=/etc/journalbeat/journalbeat.yml mode=0600 17 | notify: restart journalbeat 18 | 19 | - name: Get server certificate for Logz.io 20 | get_url: "url=https://raw.githubusercontent.com/logzio/public-certificates/master/COMODORSADomainValidationSecureServerCA.crt force=yes dest=/etc/pki/tls/certs/COMODORSADomainValidationSecureServerCA.crt" 21 | 22 | - name: Copy journalbeat service config 23 | copy: src=journalbeat.service dest=/etc/systemd/system/journalbeat.service 24 | notify: 25 | - reload daemon 26 | - restart journalbeat 27 | 28 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/remove-datadog-agent/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Stop datadog service 4 | failed_when: false 5 | service: name=datadog-agent state=stopped 6 | 7 | - name: Uninstall datadg-agent 8 | yum: name=datadog-agent state=absent 9 | 10 | - name: Remove datadog-agent folder 11 | file: path=/etc/datadog-agent state=absent 12 | 13 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/set-debug/files/sysconfig/gaiacli: -------------------------------------------------------------------------------- 1 | DAEMON_COREFILE_LIMIT='unlimited' 2 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/set-debug/files/sysconfig/gaiad: -------------------------------------------------------------------------------- 1 | DAEMON_COREFILE_LIMIT='unlimited' 2 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/set-debug/files/sysctl.d/10-procdump: -------------------------------------------------------------------------------- 1 | kernel.core_uses_pid = 1 2 | kernel.core_pattern = /tmp/core-%e-%s-%u-%g-%p-%t 3 | fs.suid_dumpable = 2 4 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/set-debug/handlers/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: reload sysctl 4 | command: "/sbin/sysctl -p" 5 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/set-debug/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Based on https://www.cyberciti.biz/tips/linux-core-dumps.html 3 | 4 | - name: Copy sysctl and sysconfig files to enable app and daemon core dumps 5 | file: src=. dest=/etc/ 6 | notify: reload sysctl 7 | 8 | - name: Enable debugging for all apps 9 | lineinfile: create=yes line="DAEMON_COREFILE_LIMIT='unlimited'" path=/etc/sysconfig/init regexp=^DAEMON_COREFILE_LIMIT= 10 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/setup-fullnodes/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | TESTNET_NAME: remotenet 4 | 5 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/setup-fullnodes/files/gaiad.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=gaiad 3 | Requires=network-online.target 4 | After=network-online.target 5 | 6 | [Service] 7 | Restart=on-failure 8 | User=gaiad 9 | Group=gaiad 10 | PermissionsStartOnly=true 11 | ExecStart=/usr/bin/gaiad start 12 | ExecReload=/bin/kill -HUP $MAINPID 13 | KillSignal=SIGTERM 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | 18 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/setup-fullnodes/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: reload systemd 4 | systemd: name=gaiad enabled=yes daemon_reload=yes 5 | 6 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/setup-fullnodes/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Ensure keys folder exists locally 4 | file: path=keys state=directory 5 | connection: local 6 | run_once: true 7 | become: no 8 | 9 | - name: Create gaiad user 10 | user: name=gaiad home=/home/gaiad shell=/bin/bash 11 | 12 | - name: Copy binary 13 | copy: 14 | src: "{{BINARY}}" 15 | dest: /usr/bin 16 | mode: 0755 17 | 18 | - name: Copy service file 19 | copy: src=gaiad.service dest=/etc/systemd/system/gaiad.service mode=0755 20 | notify: reload systemd 21 | 22 | - name: Get node ID 23 | command: "cat /etc/nodeid" 24 | changed_when: false 25 | register: nodeid 26 | 27 | - name: gaiad init 28 | command: "/usr/bin/gaiad init --chain-id={{TESTNET_NAME}} --name=fullnode{{nodeid.stdout_lines[0]}}" 29 | become: yes 30 | become_user: gaiad 31 | register: initresult 32 | args: 33 | creates: /home/gaiad/.gaia/config 34 | 35 | - name: Get wallet word seed from result of initial transaction locally 36 | when: initresult["changed"] 37 | shell: "echo '{{initresult.stdout}}' | python -c 'import json,sys ; print json.loads(\"\".join(sys.stdin.readlines()))[\"app_message\"][\"secret\"]'" 38 | changed_when: false 39 | register: walletkey 40 | connection: local 41 | 42 | - name: Write wallet word seed to local files 43 | when: initresult["changed"] 44 | copy: "content={{walletkey.stdout}} dest=keys/node{{nodeid.stdout_lines[0]}}" 45 | become: no 46 | connection: local 47 | 48 | - name: Copy genesis file 49 | copy: 50 | src: "{{GENESISFILE}}" 51 | dest: /home/gaiad/.gaia/config/genesis.json 52 | become: yes 53 | become_user: gaiad 54 | 55 | - name: Copy config.toml file 56 | copy: 57 | src: "{{CONFIGFILE}}" 58 | dest: /home/gaiad/.gaia/config/config.toml 59 | become: yes 60 | become_user: gaiad 61 | 62 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/setup-journald/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: restart journald 4 | service: name=systemd-journald state=restarted 5 | 6 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/setup-journald/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Disable journald rate-limiting 4 | lineinfile: "dest=/etc/systemd/journald.conf regexp={{item.regexp}} line='{{item.line}}'" 5 | with_items: 6 | - { regexp: "^#RateLimitInterval", line: "RateLimitInterval=0s" } 7 | - { regexp: "^#RateLimitBurst", line: "RateLimitBurst=0" } 8 | - { regexp: "^#SystemMaxFileSize", line: "SystemMaxFileSize=100M" } 9 | - { regexp: "^#SystemMaxUse", line: "SystemMaxUse=500M" } 10 | - { regexp: "^#SystemMaxFiles", line: "SystemMaxFiles=10" } 11 | notify: restart journald 12 | 13 | - name: Change logrotate to daily 14 | lineinfile: "dest=/etc/logrotate.conf regexp={{item.regexp}} line='{{item.line}}'" 15 | with_items: 16 | - { regexp: "^weekly", line: "daily" } 17 | - { regexp: "^#compress", line: "compress" } 18 | 19 | - name: Create journal directory for permanent logs 20 | file: path=/var/log/journal state=directory 21 | notify: restart journald 22 | 23 | - name: Set journal folder with systemd-tmpfiles 24 | command: "systemd-tmpfiles --create --prefix /var/log/journal" 25 | notify: restart journald 26 | 27 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/setup-validators/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | TESTNET_NAME: remotenet 4 | 5 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/setup-validators/files/gaiad.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=gaiad 3 | Requires=network-online.target 4 | After=network-online.target 5 | 6 | [Service] 7 | Restart=on-failure 8 | User=gaiad 9 | Group=gaiad 10 | PermissionsStartOnly=true 11 | ExecStart=/usr/bin/gaiad start 12 | ExecReload=/bin/kill -HUP $MAINPID 13 | KillSignal=SIGTERM 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | 18 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/setup-validators/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: reload systemd 4 | systemd: name=gaiad enabled=yes daemon_reload=yes 5 | 6 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/start/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: start service 4 | service: "name={{service}} state=started" 5 | 6 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/stop/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: stop service 4 | service: "name={{service}} state=stopped" 5 | 6 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/update-datadog-agent/files/conf.d/http_check.d/conf.yaml: -------------------------------------------------------------------------------- 1 | init_config: 2 | 3 | instances: 4 | - name: gaiad 5 | url: http://localhost:26657/status 6 | timeout: 1 7 | content_match: '"latest_block_height": "0",' 8 | reverse_content_match: true 9 | 10 | - name: gaiacli 11 | url: http://localhost:1317/node_version 12 | timeout: 1 13 | 14 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/update-datadog-agent/files/conf.d/network.d/conf.yaml: -------------------------------------------------------------------------------- 1 | init_config: 2 | 3 | instances: 4 | - collect_connection_state: true 5 | excluded_interfaces: 6 | - lo 7 | - lo0 8 | collect_rate_metrics: true 9 | collect_count_metrics: true 10 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/update-datadog-agent/files/conf.d/process.d/conf.yaml: -------------------------------------------------------------------------------- 1 | init_config: 2 | 3 | instances: 4 | - name: ssh 5 | search_string: ['ssh', 'sshd'] 6 | thresholds: 7 | critical: [1, 5] 8 | - name: gaiad 9 | search_string: ['gaiad'] 10 | thresholds: 11 | critical: [1, 1] 12 | - name: gaiacli 13 | search_string: ['gaiacli'] 14 | thresholds: 15 | critical: [1, 1] 16 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/update-datadog-agent/files/conf.d/prometheus.d/conf.yaml: -------------------------------------------------------------------------------- 1 | init_config: 2 | 3 | instances: 4 | - prometheus_url: http://127.0.0.1:26660 5 | metrics: 6 | - go* 7 | - mempool* 8 | - p2p* 9 | - process* 10 | - promhttp* 11 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/update-datadog-agent/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: restart datadog-agent 4 | service: name=datadog-agent state=restarted 5 | 6 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/update-datadog-agent/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Set datadog.yaml config 4 | template: src=datadog.yaml.j2 dest=/etc/datadog-agent/datadog.yaml 5 | notify: restart datadog-agent 6 | 7 | - name: Set metrics config 8 | copy: src=conf.d/ dest=/etc/datadog-agent/conf.d/ 9 | notify: restart datadog-agent 10 | 11 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/upgrade-gaiad/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: restart gaiad 4 | service: name=gaiad state=restarted 5 | 6 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/roles/upgrade-gaiad/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Copy binary 4 | copy: 5 | src: "{{BINARY}}" 6 | dest: /usr/bin/gaiad 7 | mode: 0755 8 | notify: restart gaiad 9 | 10 | - name: Copy new genesis.json file, if available 11 | when: "GENESISFILE is defined and GENESISFILE != ''" 12 | copy: 13 | src: "{{GENESISFILE}}" 14 | dest: /home/gaiad/.gaia/config/genesis.json 15 | notify: restart gaiad 16 | 17 | - name: Download genesis.json URL, if available 18 | when: "GENESISURL is defined and GENESISURL != ''" 19 | get_url: 20 | url: "{{GENESISURL}}" 21 | dest: /home/gaiad/.gaia/config/genesis.json 22 | force: yes 23 | notify: restart gaiad 24 | 25 | - name: Reset network 26 | when: UNSAFE_RESET_ALL | default(false) | bool 27 | command: "sudo -u gaiad gaiad unsafe-reset-all" 28 | notify: restart gaiad 29 | 30 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/set-debug.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: all 4 | any_errors_fatal: true 5 | gather_facts: no 6 | roles: 7 | - set-debug 8 | 9 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/setup-fullnodes.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | #GENESISFILE required 4 | #CONFIGFILE required 5 | #BINARY required 6 | 7 | - hosts: all 8 | any_errors_fatal: true 9 | gather_facts: no 10 | roles: 11 | - increase-openfiles 12 | - setup-fullnodes 13 | 14 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/setup-journald.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | #DD_API_KEY 4 | 5 | - hosts: all 6 | any_errors_fatal: true 7 | gather_facts: no 8 | roles: 9 | - setup-journald 10 | 11 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/setup-validators.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: all 4 | any_errors_fatal: true 5 | gather_facts: no 6 | roles: 7 | - increase-openfiles 8 | - setup-validators 9 | 10 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/start.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: all 4 | any_errors_fatal: true 5 | gather_facts: no 6 | vars: 7 | - service: gaiad 8 | roles: 9 | - start 10 | 11 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/status.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: all 4 | connection: local 5 | any_errors_fatal: true 6 | gather_facts: no 7 | 8 | tasks: 9 | - name: Gather status 10 | uri: 11 | body_format: json 12 | url: "http://{{ansible_host}}:26657/status" 13 | register: status 14 | 15 | - name: Print status 16 | debug: var=status.json.result 17 | 18 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/stop.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: all 4 | any_errors_fatal: true 5 | gather_facts: no 6 | vars: 7 | - service: gaiad 8 | roles: 9 | - stop 10 | 11 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/update-datadog-agent.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | #DD_API_KEY,TESTNET_NAME,CLUSTER_NAME required 4 | 5 | - hosts: all 6 | any_errors_fatal: true 7 | gather_facts: no 8 | roles: 9 | - update-datadog-agent 10 | 11 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/upgrade-gaia.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: all 4 | any_errors_fatal: true 5 | gather_facts: no 6 | roles: 7 | - upgrade-gaiad 8 | - add-lcd 9 | 10 | -------------------------------------------------------------------------------- /contrib/testnets/remote/ansible/upgrade-gaiad.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # Required: BINARY 4 | # Optional: GENESISFILE, UNSAFE_RESET_ALL 5 | 6 | - hosts: all 7 | any_errors_fatal: true 8 | gather_facts: no 9 | roles: 10 | - upgrade-gaiad 11 | 12 | -------------------------------------------------------------------------------- /contrib/testnets/remote/terraform-app/.gitignore: -------------------------------------------------------------------------------- 1 | .terraform 2 | terraform.tfstate 3 | terraform.tfstate.backup 4 | terraform.tfstate.d 5 | .terraform.tfstate.lock.info 6 | -------------------------------------------------------------------------------- /contrib/testnets/remote/terraform-app/files/terraform.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Script to initialize a testnet settings on a server 3 | 4 | #Usage: terraform.sh 5 | 6 | #Add gaiad node number for remote identification 7 | echo "$2" > /etc/nodeid 8 | 9 | -------------------------------------------------------------------------------- /contrib/testnets/remote/terraform-app/infra/attachment.tf: -------------------------------------------------------------------------------- 1 | # This is the reason why we can't separate nodes and load balancer creation into different modules. 2 | # https://github.com/hashicorp/terraform/issues/10857 3 | # In short: the list of instances coming from the nodes module is a generated variable 4 | # and it should be the input for the load-balancer generation. However when attaching the instances 5 | # to the load-balancer, aws_lb_target_group_attachment.count cannot be a generated value. 6 | 7 | #Instance Attachment (autoscaling is the future) 8 | resource "aws_lb_target_group_attachment" "lb_attach" { 9 | count = "${var.SERVERS*min(length(data.aws_availability_zones.zones.names),var.max_zones)}" 10 | target_group_arn = "${aws_lb_target_group.lb_target_group.arn}" 11 | target_id = "${element(aws_instance.node.*.id,count.index)}" 12 | port = 26657 13 | } 14 | 15 | resource "aws_lb_target_group_attachment" "lb_attach_lcd" { 16 | count = "${var.SERVERS*min(length(data.aws_availability_zones.zones.names),var.max_zones)}" 17 | target_group_arn = "${aws_lb_target_group.lb_target_group_lcd.arn}" 18 | target_id = "${element(aws_instance.node.*.id,count.index)}" 19 | port = 1317 20 | } 21 | 22 | -------------------------------------------------------------------------------- /contrib/testnets/remote/terraform-app/infra/instance.tf: -------------------------------------------------------------------------------- 1 | resource "aws_key_pair" "key" { 2 | key_name = "${var.name}" 3 | public_key = "${file(var.ssh_public_file)}" 4 | } 5 | 6 | data "aws_ami" "linux" { 7 | most_recent = true 8 | filter { 9 | name = "name" 10 | values = ["${var.image_name}"] 11 | } 12 | } 13 | 14 | resource "aws_instance" "node" { 15 | # depends_on = ["${element(aws_route_table_association.route_table_association.*,count.index)}"] 16 | count = "${var.SERVERS*min(length(data.aws_availability_zones.zones.names),var.max_zones)}" 17 | ami = "${data.aws_ami.linux.image_id}" 18 | instance_type = "${var.instance_type}" 19 | key_name = "${aws_key_pair.key.key_name}" 20 | associate_public_ip_address = true 21 | vpc_security_group_ids = [ "${aws_security_group.secgroup.id}" ] 22 | subnet_id = "${element(aws_subnet.subnet.*.id,count.index)}" 23 | availability_zone = "${element(data.aws_availability_zones.zones.names,count.index)}" 24 | 25 | tags { 26 | Environment = "${var.name}" 27 | Name = "${var.name}-${element(data.aws_availability_zones.zones.names,count.index)}" 28 | } 29 | 30 | volume_tags { 31 | Environment = "${var.name}" 32 | Name = "${var.name}-${element(data.aws_availability_zones.zones.names,count.index)}-VOLUME" 33 | } 34 | 35 | root_block_device { 36 | volume_size = 40 37 | } 38 | 39 | connection { 40 | user = "centos" 41 | private_key = "${file(var.ssh_private_file)}" 42 | timeout = "600s" 43 | } 44 | 45 | provisioner "file" { 46 | source = "files/terraform.sh" 47 | destination = "/tmp/terraform.sh" 48 | } 49 | 50 | provisioner "remote-exec" { 51 | inline = [ 52 | "chmod +x /tmp/terraform.sh", 53 | "sudo /tmp/terraform.sh ${var.name} ${count.index}", 54 | ] 55 | } 56 | 57 | } 58 | 59 | -------------------------------------------------------------------------------- /contrib/testnets/remote/terraform-app/infra/lb.tf: -------------------------------------------------------------------------------- 1 | resource "aws_lb" "lb" { 2 | name = "${var.name}" 3 | subnets = ["${aws_subnet.subnet.*.id}"] 4 | security_groups = ["${aws_security_group.secgroup.id}"] 5 | tags { 6 | Name = "${var.name}" 7 | } 8 | # access_logs { 9 | # bucket = "${var.s3_bucket}" 10 | # prefix = "lblogs" 11 | # } 12 | } 13 | 14 | resource "aws_lb_listener" "lb_listener" { 15 | load_balancer_arn = "${aws_lb.lb.arn}" 16 | port = "443" 17 | protocol = "HTTPS" 18 | ssl_policy = "ELBSecurityPolicy-TLS-1-2-Ext-2018-06" 19 | certificate_arn = "${var.certificate_arn}" 20 | 21 | default_action { 22 | target_group_arn = "${aws_lb_target_group.lb_target_group.arn}" 23 | type = "forward" 24 | } 25 | } 26 | 27 | resource "aws_lb_listener_rule" "listener_rule" { 28 | listener_arn = "${aws_lb_listener.lb_listener.arn}" 29 | priority = "100" 30 | action { 31 | type = "forward" 32 | target_group_arn = "${aws_lb_target_group.lb_target_group.id}" 33 | } 34 | condition { 35 | field = "path-pattern" 36 | values = ["/"] 37 | } 38 | } 39 | 40 | resource "aws_lb_target_group" "lb_target_group" { 41 | name = "${var.name}" 42 | port = "26657" 43 | protocol = "HTTP" 44 | vpc_id = "${aws_vpc.vpc.id}" 45 | tags { 46 | name = "${var.name}" 47 | } 48 | health_check { 49 | path = "/health" 50 | } 51 | } 52 | 53 | -------------------------------------------------------------------------------- /contrib/testnets/remote/terraform-app/infra/lcd.tf: -------------------------------------------------------------------------------- 1 | resource "aws_lb_listener" "lb_listener_lcd" { 2 | load_balancer_arn = "${aws_lb.lb.arn}" 3 | port = "1317" 4 | protocol = "HTTPS" 5 | ssl_policy = "ELBSecurityPolicy-TLS-1-2-Ext-2018-06" 6 | certificate_arn = "${var.certificate_arn}" 7 | 8 | default_action { 9 | target_group_arn = "${aws_lb_target_group.lb_target_group_lcd.arn}" 10 | type = "forward" 11 | } 12 | } 13 | 14 | resource "aws_lb_listener_rule" "listener_rule_lcd" { 15 | listener_arn = "${aws_lb_listener.lb_listener_lcd.arn}" 16 | priority = "100" 17 | action { 18 | type = "forward" 19 | target_group_arn = "${aws_lb_target_group.lb_target_group_lcd.id}" 20 | } 21 | condition { 22 | field = "path-pattern" 23 | values = ["/"] 24 | } 25 | } 26 | 27 | resource "aws_lb_target_group" "lb_target_group_lcd" { 28 | name = "${var.name}lcd" 29 | port = "1317" 30 | protocol = "HTTP" 31 | vpc_id = "${aws_vpc.vpc.id}" 32 | tags { 33 | name = "${var.name}" 34 | } 35 | health_check { 36 | path = "/node_version" 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /contrib/testnets/remote/terraform-app/infra/outputs.tf: -------------------------------------------------------------------------------- 1 | // The cluster name 2 | output "name" { 3 | value = "${var.name}" 4 | } 5 | 6 | // The list of cluster instance IDs 7 | output "instances" { 8 | value = ["${aws_instance.node.*.id}"] 9 | } 10 | 11 | #output "instances_count" { 12 | # value = "${length(aws_instance.node.*)}" 13 | #} 14 | 15 | // The list of cluster instance public IPs 16 | output "public_ips" { 17 | value = ["${aws_instance.node.*.public_ip}"] 18 | } 19 | 20 | // Name of the ALB 21 | output "lb_name" { 22 | value = "${aws_lb.lb.dns_name}" 23 | } 24 | 25 | -------------------------------------------------------------------------------- /contrib/testnets/remote/terraform-app/infra/variables.tf: -------------------------------------------------------------------------------- 1 | variable "name" { 2 | description = "The testnet name, e.g cdn" 3 | } 4 | 5 | variable "image_name" { 6 | description = "Image name" 7 | default = "CentOS Linux 7 x86_64 HVM EBS 1704_01" 8 | } 9 | 10 | variable "instance_type" { 11 | description = "The instance size to use" 12 | default = "t2.small" 13 | } 14 | 15 | variable "SERVERS" { 16 | description = "Number of servers in an availability zone" 17 | default = "1" 18 | } 19 | 20 | variable "max_zones" { 21 | description = "Maximum number of availability zones to use" 22 | default = "1" 23 | } 24 | 25 | variable "ssh_private_file" { 26 | description = "SSH private key file to be used to connect to the nodes" 27 | type = "string" 28 | } 29 | 30 | variable "ssh_public_file" { 31 | description = "SSH public key file to be used on the nodes" 32 | type = "string" 33 | } 34 | 35 | variable "certificate_arn" { 36 | description = "Load-balancer SSL certificate AWS ARN" 37 | type = "string" 38 | } 39 | 40 | -------------------------------------------------------------------------------- /contrib/testnets/remote/terraform-aws/.gitignore: -------------------------------------------------------------------------------- 1 | .terraform 2 | terraform.tfstate 3 | terraform.tfstate.backup 4 | terraform.tfstate.d 5 | .terraform.tfstate.lock.info 6 | -------------------------------------------------------------------------------- /contrib/testnets/remote/terraform-aws/files/terraform.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Script to initialize a testnet settings on a server 3 | 4 | #Usage: terraform.sh 5 | 6 | #Add gaiad node number for remote identification 7 | REGION="$(($2 + 1))" 8 | RNODE="$(($3 + 1))" 9 | ID="$((${REGION} * 100 + ${RNODE}))" 10 | echo "$ID" > /etc/nodeid 11 | 12 | -------------------------------------------------------------------------------- /contrib/testnets/remote/terraform-aws/nodes/outputs.tf: -------------------------------------------------------------------------------- 1 | // The cluster name 2 | output "name" { 3 | value = "${var.name}" 4 | } 5 | 6 | // The list of cluster instance IDs 7 | output "instances" { 8 | value = ["${aws_instance.node.*.id}"] 9 | } 10 | 11 | // The list of cluster instance public IPs 12 | output "public_ips" { 13 | value = ["${aws_instance.node.*.public_ip}"] 14 | } 15 | 16 | -------------------------------------------------------------------------------- /contrib/testnets/remote/terraform-aws/nodes/variables.tf: -------------------------------------------------------------------------------- 1 | variable "name" { 2 | description = "The testnet name, e.g cdn" 3 | } 4 | 5 | variable "image_name" { 6 | description = "Image name" 7 | default = "CentOS Linux 7 x86_64 HVM EBS 1704_01" 8 | } 9 | 10 | variable "instance_type" { 11 | description = "The instance size to use" 12 | default = "t2.small" 13 | } 14 | 15 | variable "region" { 16 | description = "AWS region to use" 17 | } 18 | 19 | variable "multiplier" { 20 | description = "Multiplier for node identification" 21 | } 22 | 23 | variable "execute" { 24 | description = "Set to false to disable the module" 25 | default = true 26 | } 27 | 28 | variable "SERVERS" { 29 | description = "Number of servers in an availability zone" 30 | default = "1" 31 | } 32 | 33 | variable "ssh_private_file" { 34 | description = "SSH private key file to be used to connect to the nodes" 35 | type = "string" 36 | } 37 | 38 | variable "ssh_public_file" { 39 | description = "SSH public key file to be used on the nodes" 40 | type = "string" 41 | } 42 | 43 | -------------------------------------------------------------------------------- /contrib/testnets/remote/terraform-do/.gitignore: -------------------------------------------------------------------------------- 1 | .terraform 2 | terraform.tfstate 3 | terraform.tfstate.backup 4 | terraform.tfstate.d 5 | .terraform.tfstate.lock.info 6 | 7 | -------------------------------------------------------------------------------- /contrib/testnets/remote/terraform-do/cluster/main.tf: -------------------------------------------------------------------------------- 1 | resource "digitalocean_tag" "cluster" { 2 | name = "${var.name}" 3 | } 4 | 5 | resource "digitalocean_ssh_key" "cluster" { 6 | name = "${var.name}" 7 | public_key = "${file(var.ssh_public_file)}" 8 | } 9 | 10 | resource "digitalocean_droplet" "cluster" { 11 | name = "${var.name}-node${count.index}" 12 | image = "centos-7-x64" 13 | size = "${var.instance_size}" 14 | region = "${element(var.regions, count.index)}" 15 | ssh_keys = ["${digitalocean_ssh_key.cluster.id}"] 16 | count = "${var.servers}" 17 | tags = ["${digitalocean_tag.cluster.id}"] 18 | 19 | lifecycle = { 20 | prevent_destroy = false 21 | } 22 | 23 | connection { 24 | private_key = "${file(var.ssh_private_file)}" 25 | } 26 | 27 | provisioner "file" { 28 | source = "files/terraform.sh" 29 | destination = "/tmp/terraform.sh" 30 | } 31 | 32 | provisioner "remote-exec" { 33 | inline = [ 34 | "chmod +x /tmp/terraform.sh", 35 | "/tmp/terraform.sh ${var.name} ${count.index}", 36 | ] 37 | } 38 | 39 | } 40 | 41 | -------------------------------------------------------------------------------- /contrib/testnets/remote/terraform-do/cluster/outputs.tf: -------------------------------------------------------------------------------- 1 | // The cluster name 2 | output "name" { 3 | value = "${var.name}" 4 | } 5 | 6 | // The list of cluster instance IDs 7 | output "instances" { 8 | value = ["${digitalocean_droplet.cluster.*.id}"] 9 | } 10 | 11 | // The list of cluster instance public IPs 12 | output "public_ips" { 13 | value = ["${digitalocean_droplet.cluster.*.ipv4_address}"] 14 | } 15 | 16 | -------------------------------------------------------------------------------- /contrib/testnets/remote/terraform-do/cluster/variables.tf: -------------------------------------------------------------------------------- 1 | variable "name" { 2 | description = "The cluster name, e.g remotenet" 3 | } 4 | 5 | variable "regions" { 6 | description = "Regions to launch in" 7 | type = "list" 8 | default = ["AMS2", "TOR1", "LON1", "NYC3", "SFO2", "SGP1", "FRA1"] 9 | } 10 | 11 | variable "ssh_private_file" { 12 | description = "SSH private key filename to use to connect to the nodes" 13 | type = "string" 14 | } 15 | 16 | variable "ssh_public_file" { 17 | description = "SSH public key filename to copy to the nodes" 18 | type = "string" 19 | } 20 | 21 | variable "instance_size" { 22 | description = "The instance size to use" 23 | default = "2gb" 24 | } 25 | 26 | variable "servers" { 27 | description = "Desired instance count" 28 | default = 4 29 | } 30 | 31 | -------------------------------------------------------------------------------- /contrib/testnets/remote/terraform-do/files/terraform.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Script to initialize a testnet settings on a server 3 | 4 | #Usage: terraform.sh 5 | 6 | #Add gaiad node number for remote identification 7 | echo "$2" > /etc/nodeid 8 | 9 | -------------------------------------------------------------------------------- /contrib/testnets/remote/terraform-do/main.tf: -------------------------------------------------------------------------------- 1 | #Terraform Configuration 2 | 3 | variable "DO_API_TOKEN" { 4 | description = "DigitalOcean Access Token" 5 | } 6 | 7 | variable "TESTNET_NAME" { 8 | description = "Name of the testnet" 9 | default = "remotenet" 10 | } 11 | 12 | variable "SSH_PRIVATE_FILE" { 13 | description = "SSH private key file to be used to connect to the nodes" 14 | type = "string" 15 | } 16 | 17 | variable "SSH_PUBLIC_FILE" { 18 | description = "SSH public key file to be used on the nodes" 19 | type = "string" 20 | } 21 | 22 | variable "SERVERS" { 23 | description = "Number of nodes in testnet" 24 | default = "4" 25 | } 26 | 27 | provider "digitalocean" { 28 | token = "${var.DO_API_TOKEN}" 29 | } 30 | 31 | module "cluster" { 32 | source = "./cluster" 33 | name = "${var.TESTNET_NAME}" 34 | ssh_private_file = "${var.SSH_PRIVATE_FILE}" 35 | ssh_public_file = "${var.SSH_PUBLIC_FILE}" 36 | servers = "${var.SERVERS}" 37 | } 38 | 39 | 40 | output "public_ips" { 41 | value = "${module.cluster.public_ips}" 42 | } 43 | 44 | -------------------------------------------------------------------------------- /contrib/testnets/test_platform/templates/3924406.cosmoshub-3.json.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/contrib/testnets/test_platform/templates/3924406.cosmoshub-3.json.tar.gz -------------------------------------------------------------------------------- /contrib/testnets/test_platform/templates/replacement_defaults.txt: -------------------------------------------------------------------------------- 1 | replacement_genesis_make_safe=True 2 | replacement_genesis=templates/3924406.cosmoshub-3.json 3 | replacement_genesis=templates/3924406.cosmoshub-3.json.tar.gz 4 | replacement_genesis= 5 | num_of_nodes_to_apply=4 6 | LOG_LEVEL=debug 7 | P2P_PEERID_IP=0.0.0.0 8 | P2P_LADDR=tcp://0.0.0.0 9 | P2P_LADDR_PORT=26656 10 | RPC_LADDR=tcp://0.0.0.0 11 | RPC_LADDR_PORT=26657 12 | PROXY_APP=tcp://127.0.0.1 13 | PROXY_APP_PORT=26658 14 | GRPC_LADDR=tcp://0.0.0.0 15 | GRPC_LADDR_PORT=26659 16 | GRPC_APP_ADDR=0.0.0.0 17 | GRPC_APP_ADDR_PORT=9090 18 | GRPC_WEB_APP_ADDR=0.0.0.0 19 | GRPC_WEB_APP_ADDR_PORT=9091 20 | PROMETHEUS_LISTEN_ADDR= 21 | PROMETHEUS_LISTEN_ADDR_PORT=26660 22 | MONIKER=node0 23 | SEEDS= 24 | PERSISTENT_PEERS= 25 | PRIVATE_PEER_IDS= 26 | ALLOW_DUPLICATE_IP=true 27 | PROMETHEUS=false 28 | API_ADDRESS=tcp://0.0.0.0 29 | API_ADDRESS_PORT=1317 30 | PPROF_LADDR=localhost 31 | PPROF_LADDR_PORT=6060 -------------------------------------------------------------------------------- /contrib/testnets/upgrade-gaiad.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # upgrade-gaiad - example make call to upgrade gaiad on a set of nodes in AWS 3 | # WARNING: Run it from the current directory - it uses relative paths to ship the binary and the genesis.json,config.toml files 4 | 5 | if [ $# -ne 1 ]; then 6 | echo "Usage: ./upgrade-gaiad.sh " 7 | exit 1 8 | fi 9 | set -eux 10 | 11 | export CLUSTER_NAME=$1 12 | 13 | make upgrade-gaiad 14 | 15 | -------------------------------------------------------------------------------- /contrib/testnets/using-cleveldb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | make install GAIA_BUILD_OPTIONS="cleveldb" 4 | 5 | gaiad init "t6" --home ./t6 --chain-id t6 6 | 7 | gaiad unsafe-reset-all --home ./t6 8 | 9 | mkdir -p ./t6/data/snapshots/metadata.db 10 | 11 | gaiad keys add validator --keyring-backend test --home ./t6 12 | 13 | gaiad genesis add-genesis-account $(gaiad keys show validator -a --keyring-backend test --home ./t6) 100000000stake --keyring-backend test --home ./t6 14 | 15 | gaiad genesis gentx validator 100000000stake --keyring-backend test --home ./t6 --chain-id t6 16 | 17 | gaiad genesis collect-gentxs --home ./t6 18 | 19 | gaiad start --db_backend cleveldb --home ./t6 20 | -------------------------------------------------------------------------------- /contrib/upload-contract.sh: -------------------------------------------------------------------------------- 1 | export GAIAD_NODE="tcp://localhost:26657" 2 | 3 | FLAGS="--gas=2500000 --from=validator --keyring-backend=test --chain-id=local-1 --output=json --yes" 4 | 5 | gaiad tx wasm store ./contrib/cw_template.wasm $FLAGS 6 | sleep 2 7 | 8 | txhash=$(gaiad tx wasm instantiate 1 '{"count":0}' --label=cw_template --no-admin $FLAGS | jq -r .txhash) && echo $txhash 9 | sleep 2 10 | 11 | addr=$(gaiad q tx $txhash --output=json | jq -r .logs[0].events[2].attributes[0].value) && echo $addr 12 | sleep 2 13 | 14 | gaiad q wasm contract $addr -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Cosmos Hub Documentation 2 | 3 | Welcome to the documentation of the **Cosmos Hub application: `gaia`**. 4 | 5 | ## What is Gaia? 6 | 7 | - [Intro to the `gaia` software](./docs/getting-started/what-is-gaia.md) 8 | - [Interacting with the `gaiad` binary](./docs/hub-tutorials/gaiad.md) 9 | 10 | ## Join the Cosmos Hub Mainnet 11 | 12 | - [Install the `gaia` application](./docs/getting-started/installation.md) 13 | - [Set up a full node and join the mainnet](./docs/hub-tutorials/join-mainnet.md) 14 | - [Upgrade to a validator node](./docs/validators/validator-setup.md) 15 | 16 | ## Join the Cosmos Hub Public Testnet 17 | 18 | - [Join the testnet](./docs/hub-tutorials/join-testnet.md) 19 | 20 | ## Setup Your Own `gaia` Testnet 21 | 22 | - [Setup your own `gaia` testnet](https://github.com/cosmos/testnets/tree/master/local/previous-local-testnets/v7-theta) 23 | 24 | ## Additional Resources 25 | 26 | - [Validator Resources](./docs/validators/README.md): Contains documentation for `gaia` validators. 27 | - [Delegator Resources](./docs/delegators/README.md): Contains documentation for delegators. 28 | - [Other Resources](./docs/resources/README.md): Contains documentation on `gaiad`, genesis file, service providers, ledger wallets, ... 29 | - [Cosmos Hub Archives](./docs/resources/archives.md): State archives of past iteration of the Cosmos Hub. 30 | 31 | # Contribute 32 | 33 | See [this file](./DOCS_README.md) for details of the build process and 34 | considerations when making changes. 35 | -------------------------------------------------------------------------------- /docs/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /docs/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This builds the docs.cosmos.network docs using docusaurus. 4 | # Old documentation, is not migrated, but is still available at the appropriate release tag. 5 | 6 | # Get the current commit hash, usually should be main. 7 | COMMIT=$(git rev-parse HEAD) 8 | mkdir -p ~/versioned_docs ~/versioned_sidebars 9 | 10 | # Build docs for each version tag in versions.json. 11 | for version in $(jq -r .[] versions.json); do 12 | echo ">> Building docusaurus $version docs" 13 | (git clean -fdx && git reset --hard && git checkout $version && npm install && npm run docusaurus docs:version $version) 14 | mv ./versioned_docs/* ~/versioned_docs/ 15 | mv ./versioned_sidebars/* ~/versioned_sidebars/ 16 | echo ">> Finished building docusaurus $version docs" 17 | done 18 | 19 | # Build docs for $COMMIT that we started on. 20 | echo ">> Building docusaurus main docs" 21 | (git clean -fdx && git reset --hard && git checkout $COMMIT) 22 | mv ~/versioned_docs ~/versioned_sidebars . 23 | npm ci && npm run build 24 | mv build ~/output 25 | 26 | echo ">> Finished building docusaurus main docs" 27 | exit 0 -------------------------------------------------------------------------------- /docs/docs/architecture/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "ADRs", 3 | "position": 10, 4 | "link": { "type": "doc", "id": "architecture/README" } 5 | } -------------------------------------------------------------------------------- /docs/docs/architecture/adr/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Current ADR's", 3 | "position": 1, 4 | "link": null 5 | } -------------------------------------------------------------------------------- /docs/docs/architecture/templates/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "ADR Templates", 3 | "position": 2, 4 | "link": null 5 | } -------------------------------------------------------------------------------- /docs/docs/client/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Client", 3 | "position": 10, 4 | "link": null 5 | } -------------------------------------------------------------------------------- /docs/docs/delegators/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Delegators 3 | order: 1 4 | --- 5 | 6 | This folder contains documentation relevant to delegators of the Cosmos Hub and other `gaia` blockchains. 7 | 8 | - [Delegator CLI Guide](./delegator-guide-cli.md) 9 | - [Delegators FAQ](./delegator-faq.md) 10 | - [Delegator Security Notice](./delegator-security.md) 11 | -------------------------------------------------------------------------------- /docs/docs/delegators/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Delegators", 3 | "position": 4, 4 | "link": { "type": "doc", "id": "delegators/README" } 5 | } -------------------------------------------------------------------------------- /docs/docs/getting-started/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Getting Started 3 | order: null 4 | --- 5 | 6 | This folder contains tutorials related to the `gaia` application. 7 | 8 | - [What is Gaia?](./what-is-gaia.md) 9 | - [Installing `gaiad`](./installation.md) 10 | - [Joining Mainnet](./quickstart.md) 11 | -------------------------------------------------------------------------------- /docs/docs/getting-started/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Getting Started", 3 | "position": 2, 4 | "link": { "type": "doc", "id": "getting-started/README" } 5 | } -------------------------------------------------------------------------------- /docs/docs/getting-started/system-requirements.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: System requirements 3 | sidebar_position: 4 4 | --- 5 | 6 | 7 | # System requirements 8 | 9 | 14 | 15 | ## Gaia Upgrades 16 | 17 | The Gaia application typically needs at least 32GB RAM, for smooth operation for upgrade, as there may be lengthy migrations to perform. 18 | 19 | If you have less than 32GB RAM, you might try creating a swapfile to swap an idle program onto the hard disk to free up memory. This can allow your machine to run the binary than it could run in RAM alone. 20 | 21 | ```shell 22 | # Linux instructions 23 | sudo fallocate -l 16G /swapfile 24 | sudo chmod 600 /swapfile 25 | sudo mkswap /swapfile 26 | sudo swapon /swapfile 27 | ``` 28 | -------------------------------------------------------------------------------- /docs/docs/getting-started/what-is-gaia.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: What is Gaia? 3 | sidebar_position: 1 4 | --- 5 | 6 | The Cosmos Hub is a public Proof-of-Stake chain that uses ATOM as its native staking token. It is the first blockchain launched in the Cosmos Network and developed using the [cosmos-sdk](https://docs.cosmos.network/) development framework and [ibc-go](https://ibc.cosmos.network/). 7 | 8 | Cosmos hub is also the first security aggregation platform that leverages the [interchain-security](https://cosmos.github.io/interchain-security/) protocol ([ICS-28](https://github.com/cosmos/ibc/tree/main/spec/app/ics-028-cross-chain-validation)) to facilitate the launch of cosmos-sdk blockchain projects. 9 | 10 | 11 | :::tip 12 | Interchain security features deployed on the Cosmos Hub blockchain allow anyone to launch a blockchain using a subset, or even the entire validator set of the Cosmos Hub blockchain. 13 | ::: 14 | 15 | 16 | :::info 17 | * `gaia` is the name of the Cosmos SDK application for the Cosmos Hub. 18 | 19 | * `gaiad` is the daemon and command-line interface (CLI) that operates the `gaia` blockchain application. 20 | ::: 21 | 22 | 23 | For a full list of modules used on the Cosmos Hub follow this [link](../modules/README.md). 24 | 25 | Next, learn how to [install Gaia](./installation.md). 26 | -------------------------------------------------------------------------------- /docs/docs/governance/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Governance Overview 3 | order: 1 4 | --- 5 | 6 | The Cosmos Hub ("Gaia") has an on-chain governance mechanism for [signaling](./proposal-types/text-prop.md), changing [consensus parameters](./proposal-types/param-change.md), and spending [funds from the community pool](./proposal-types/community-pool-spend.md). 7 | 8 | This repository provides background information on these different kinds of proposals and best-practices for drafting them and proposing them on-chain. 9 | 10 | ## Community 11 | 12 | Cosmos governance is driven by the Cosmos community, and much of the documentation in this repo was funded by the community fund itself in 13 | [Proposal 23](https://www.mintscan.io/cosmos/proposals/23) and [Proposal 63](https://www.mintscan.io/cosmos/proposals/63). 14 | Governance discussions happen in a number of places moderated by diverse community members, including: 15 | 16 | - [Forum](http://forum.cosmos.network/) 17 | - [Discord](https://discord.gg/interchain) 18 | - [Reddit](http://reddit.com/r/cosmosnetwork) 19 | - anywhere else you might interact with members of the Cosmos community! 20 | -------------------------------------------------------------------------------- /docs/docs/governance/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Governance", 3 | "position": 6, 4 | "link": { "type": "doc", "id": "governance/README" } 5 | } -------------------------------------------------------------------------------- /docs/docs/governance/proposal-types/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 1 3 | parent: 4 | order: 6 5 | --- 6 | 7 | # Proposal Types 8 | 9 | - [**Text**](../proposal-types/text-prop.md) 10 | - [**Community Pool Spend**](../proposal-types/community-pool-spend.md) 11 | - [**Parameter Change**](../proposal-types/param-change.md) 12 | - [**Software Upgrade**](../proposal-types/software-upgrade.md) 13 | - **IBC Client Update** 14 | 15 | ## Drafting a Proposal 16 | 17 | Drafting and submitting a proposal is a process that takes time, attention, and involves risk. The objective of this documentation is to make this process easier by preparing participants for what to pay attention to, the information that should be considered in a proposal, and how to reduce the risk of losing deposits. 18 | 19 | Ideally, a proposal should only fail to pass because voters are aware, engaged, and have made an informed decision to vote down the proposal. 20 | 21 | If you are considering drafting a proposal, you should first review the general background on drafting and submitting a proposal: 22 | 23 | 1. [How the voting process and governance mechanism works](../process.md) 24 | 1. [How to draft your proposal and engage with the Cosmos community about it](../best-practices.md) 25 | 1. [How to format proposals](../formatting.md) 26 | 1. [How to submit your proposal](../submitting.md) 27 | 28 | You should also review details specific to each kind of proposal, listed in this section. 29 | -------------------------------------------------------------------------------- /docs/docs/governance/proposal-types/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Common proposals", 3 | "position": 1, 4 | "link": { "type": "doc", "id": "governance/proposal-types/README" } 5 | } -------------------------------------------------------------------------------- /docs/docs/governance/proposal-types/community-pool-spend/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "> Community Pool Spend", 3 | "position": 2 4 | } -------------------------------------------------------------------------------- /docs/docs/governance/proposal-types/community-pool-spend/proposal.json: -------------------------------------------------------------------------------- 1 | { 2 | "messages":[ 3 | { 4 | "@type": "/cosmos.distribution.v1beta1.MsgCommunityPoolSpend", 5 | "authority": "cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn", 6 | "recipient": "cosmos00af8sd0a9dfansdfoiasf0a9ssd9fa09i99990", 7 | "amount": [{ 8 | "denom": "uatom", 9 | "amount": "10000000000" 10 | }] 11 | } 12 | ], 13 | "deposit": "100000uatom", 14 | "proposer": "cosmos12xpdapokdfpsodf32das75sokdaadapsokd1sa", 15 | "metadata": "Community Pool Spend Proposal Example", 16 | "title": "Grant Proposal: Community Pool Spend", 17 | "summary": "summary" 18 | } -------------------------------------------------------------------------------- /docs/docs/governance/scripts/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Scripts", 3 | "position": 3 4 | } -------------------------------------------------------------------------------- /docs/docs/hub-tutorials/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Gaia Tutorials 3 | order: 1 4 | --- 5 | 6 | This folder contains tutorials related to the `gaiad` application. 7 | 8 | - [Interacting with the `gaiad` binary](./gaiad.md) 9 | - [Running a full-node for the Cosmos Hub Mainnet](./join-mainnet.md) 10 | - [Running a full-node for a `gaia` testnet](./join-testnet.md) 11 | - [Upgrading a node from a previous version](./upgrade-node.md) 12 | - [Creating an upgrade governance proposal](./live-upgrade-tutorial.md) 13 | -------------------------------------------------------------------------------- /docs/docs/hub-tutorials/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Guides", 3 | "position": 3, 4 | "link": { "type": "doc", "id": "hub-tutorials/README" } 5 | } -------------------------------------------------------------------------------- /docs/docs/images/cosmos-hub-image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/docs/images/cosmos-hub-image.jpg -------------------------------------------------------------------------------- /docs/docs/images/ledger-tuto-dev-mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/docs/images/ledger-tuto-dev-mode.png -------------------------------------------------------------------------------- /docs/docs/images/ledger-tuto-lunie-address.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/docs/images/ledger-tuto-lunie-address.png -------------------------------------------------------------------------------- /docs/docs/images/ledger-tuto-lunie-option.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/docs/images/ledger-tuto-lunie-option.png -------------------------------------------------------------------------------- /docs/docs/images/ledger-tuto-manager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/docs/images/ledger-tuto-manager.png -------------------------------------------------------------------------------- /docs/docs/images/ledger-tuto-search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/docs/images/ledger-tuto-search.png -------------------------------------------------------------------------------- /docs/docs/images/verify-tx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/docs/images/verify-tx.png -------------------------------------------------------------------------------- /docs/docs/interchain-security/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Interchain Security", 3 | "position": 6, 4 | "link": { "type": "doc", "id": "interchain-security/README" } 5 | } -------------------------------------------------------------------------------- /docs/docs/modules/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Gaia Modules", 3 | "position": 11, 4 | "link": { 5 | "type": "doc", 6 | "id": "modules/README" 7 | } 8 | } -------------------------------------------------------------------------------- /docs/docs/modules/liquid.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: x/liquid 3 | order: 2 4 | --- 5 | 6 | The `x/liquid` module used by the Hub includes types and APIs that enable liquid staking. 7 | You can read more about it in our [module documentation](https://github.com/cosmos/gaia/tree/main/x/liquid/README.md). 8 | 9 | ## What are LSM shares 10 | 11 | LSM shares are derivatives of the delegation shares. They are tied to a delegator and a validator pair and they represent the underlying delegation shares. 12 | By issuing LSM shares, the underlying staked ATOM can become "liquid" while still being slashable. The LSM shares are tokens that can be used in various DeFi protocols and transferred between users or between chains via IBC. 13 | 14 | LSM shares are not fungible (as they are tied to a delegator/validator pair) and are issued by the Hub directly and thus don't depend on the security of any entity other than the Cosmos Hub itself. 15 | 16 | ## Benefits 17 | 18 | By tokenizing your staked ATOM into LSM shares, you maintain the benefits of staking while gaining flexibility in using these shares in DeFi protocols and platforms. 19 | 20 | The LSM shares issued by the Hub are powering liquid staking derivatives like stATOM or dATOM and they are the backbone of the Hydro platform. 21 | -------------------------------------------------------------------------------- /docs/docs/proto/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Proto Docs", 3 | "position": 12, 4 | "link": { "type": "doc", "id": "proto/proto-docs" } 5 | } -------------------------------------------------------------------------------- /docs/docs/resources/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Resources 3 | order: 1 4 | --- 5 | 6 | This folder contains resources on the `gaia` software. 7 | 8 | - [`gaia` genesis file](./genesis.md) 9 | - [HD Wallets for `gaia`](./hd-wallets.md) 10 | - [Ledger Integration for `gaia`](./ledger.md) 11 | - [Service Providers Documentation](./service-providers.md) 12 | - [Reproducible Builds](./reproducible-builds.md) 13 | -------------------------------------------------------------------------------- /docs/docs/resources/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Resources", 3 | "position": 8, 4 | "link": { "type": "doc", "id": "resources/README" } 5 | } -------------------------------------------------------------------------------- /docs/docs/resources/archives.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Cosmos Hub Archives 3 | order: 2 4 | --- 5 | 6 | With each breaking upgrade of the Cosmos Hub, the network is restarted at height 0. During this process, an export of the last state of the previous network is made to produce the genesis state of the new one. 7 | 8 | As a result, the blocks of the previous networks are not downloaded by new clients (as they sync from the new genesis state), and may be deleted by existing full-nodes. 9 | 10 | In an effort to maintain transparency, the interchain hosts archives of the previous versions of the Cosmos Hub network. These archives can be found [here](https://archive.interchain.io/). 11 | 12 | If you would like to search explorers for previous hub data, these are some links where you can find the information: 13 | 14 | ### Big Dipper 15 | 16 | - [Cosmos Hub 1](https://cosmoshub-1.bigdipper.live/) 17 | - [Cosmos Hub 2](https://cosmoshub-2.bigdipper.live/) 18 | - [Cosmos Hub 3](https://cosmoshub-3.bigdipper.live/) 19 | 20 | If you want to make archives available to the community, feel free to open a PR to this file and add them. 21 | -------------------------------------------------------------------------------- /docs/docs/validators/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Validators 3 | order: 1 4 | --- 5 | 6 | This folder contains documentation relevant to validators of the Cosmos Hub and other `gaia` blockchains. 7 | 8 | - [Validator Overview](./overview.md) 9 | - [Setting Up a Validator for Cosmos Hub Mainnet](./validator-setup.md) 10 | - [Validator FAQ](./validator-faq.md) 11 | - [Validator Security Notice](./security.md) 12 | - Key Management Systems 13 | - [Intro to KMS](./kms/kms.md) 14 | - [KMS + Ledger](./kms/kms_ledger.md) 15 | -------------------------------------------------------------------------------- /docs/docs/validators/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Validators", 3 | "position": 5, 4 | "link": { "type": "doc", "id": "validators/README" } 5 | } -------------------------------------------------------------------------------- /docs/docs/validators/kms/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Key Management Systems", 3 | "position": 5, 4 | "link": null 5 | } -------------------------------------------------------------------------------- /docs/docs/validators/kms/kms.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: KMS - Key Management System 3 | order: 5 4 | --- 5 | 6 | [Tendermint KMS](https://github.com/iqlusioninc/tmkms) is a key management service that allows separating key management from Tendermint nodes. In addition it provides other advantages such as: 7 | 8 | - Improved security and risk management policies 9 | - Unified API and support for various HSM (hardware security modules) 10 | - Double signing protection (software or hardware based) 11 | 12 | It is recommended that the KMS service runs in a separate physical hosts. 13 | 14 | ## Building 15 | 16 | Detailed build instructions can be found [here](https://github.com/iqlusioninc/tmkms#installation). 17 | 18 | :::tip 19 | When compiling the KMS, ensure you have enabled the applicable features: 20 | ::: 21 | 22 | | Backend | Recommended Command line | 23 | |-----------------------|---------------------------------------| 24 | | YubiHSM | ```cargo build --features yubihsm``` | 25 | | Ledger+Tendermint App | ```cargo build --features ledgertm``` | 26 | 27 | ## Configuration 28 | 29 | A KMS can be configured in various ways: 30 | 31 | ### Using a YubiHSM 32 | 33 | Detailed information on how to setup a KMS with YubiHSM2 can be found [here](https://github.com/iqlusioninc/tmkms/blob/master/README.yubihsm.md) 34 | 35 | ### Using a Ledger device running the Tendermint app 36 | 37 | Detailed information on how to setup a KMS with Ledger Tendermint App can be found [here](kms_ledger.md) 38 | -------------------------------------------------------------------------------- /docs/docs/validators/kms/ledger_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/docs/validators/kms/ledger_1.jpg -------------------------------------------------------------------------------- /docs/docs/validators/kms/ledger_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/docs/validators/kms/ledger_2.jpg -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cosmos-hub-docs-site", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "docusaurus": "docusaurus", 7 | "start": "docusaurus start", 8 | "build": "docusaurus build", 9 | "swizzle": "docusaurus swizzle", 10 | "deploy": "docusaurus deploy", 11 | "clear": "docusaurus clear", 12 | "serve": "docusaurus serve", 13 | "write-translations": "docusaurus write-translations", 14 | "write-heading-ids": "docusaurus write-heading-ids" 15 | }, 16 | "dependencies": { 17 | "@docusaurus/core": "^3.7.0", 18 | "@docusaurus/plugin-client-redirects": "^3.7.0", 19 | "@docusaurus/plugin-google-analytics": "^3.7.0", 20 | "@docusaurus/plugin-google-gtag": "^3.7.0", 21 | "@docusaurus/preset-classic": "^3.7.0", 22 | "@mdx-js/react": "^3.0.0", 23 | "@you54f/theme-github-codeblock": "^0.1.1", 24 | "autoprefixer": "^10.4.14", 25 | "clsx": "^1.2.1", 26 | "docusaurus-lunr-search": "^3.5.0", 27 | "postcss": "^8.4.27", 28 | "postcss-import": "^15.1.0", 29 | "prism-react-renderer": "^1.3.5", 30 | "react": "^18.0.0", 31 | "react-dom": "^18.0.0", 32 | "tailwindcss": "^3.3.3" 33 | }, 34 | "devDependencies": { 35 | "@docusaurus/module-type-aliases": "^2.4.3" 36 | }, 37 | "browserslist": { 38 | "production": [ 39 | ">0.5%", 40 | "not dead", 41 | "not op_mini all" 42 | ], 43 | "development": [ 44 | "last 1 chrome version", 45 | "last 1 firefox version", 46 | "last 1 safari version" 47 | ] 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /docs/sidebars.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Creating a sidebar enables you to: 3 | - create an ordered group of docs 4 | - render a sidebar for each doc of that group 5 | - provide next/previous navigation 6 | 7 | The sidebars can be generated from the filesystem, or explicitly defined here. 8 | 9 | Create as many sidebars as you want. 10 | */ 11 | 12 | // @ts-check 13 | 14 | /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ 15 | const sidebars = { 16 | // By default, Docusaurus generates a sidebar from the docs folder structure 17 | tutorialSidebar: [{type: 'autogenerated', dirName: '.'}], 18 | 19 | // But you can create a sidebar manually 20 | /* 21 | tutorialSidebar: [ 22 | 'intro', 23 | 'hello', 24 | { 25 | type: 'category', 26 | label: 'Tutorial', 27 | items: ['tutorial-basics/create-a-document'], 28 | }, 29 | ], 30 | */ 31 | }; 32 | 33 | module.exports = sidebars; 34 | -------------------------------------------------------------------------------- /docs/src/css/base.css: -------------------------------------------------------------------------------- 1 | /* 2 | Copied from https://github.com/ignite/cli/blob/develop/docs/src/css/base.css 3 | */ 4 | 5 | @layer base { 6 | html { 7 | @apply font-inter; 8 | font-feature-settings: 'kern', 'liga', 'calt', 'zero' 0; 9 | -webkit-font-feature-settings: 'kern', 'liga', 'calt', 'zero' 0; 10 | text-size-adjust: 100%; 11 | -moz-osx-font-smoothing: grayscale; 12 | font-smoothing: antialiased; 13 | font-variant-ligatures: contextual common-ligatures; 14 | font-kerning: normal; 15 | text-rendering: optimizeLegibility; 16 | 17 | @supports (font-variation-settings: normal) { 18 | @apply font-intervar 19 | } 20 | } 21 | 22 | *, 23 | *::before, 24 | *::after { 25 | box-sizing: border-box; 26 | margin: 0; 27 | } 28 | 29 | svg { display: inline; } 30 | 31 | ::selection{ 32 | background-color: var(--ifm-color-primary); 33 | color: white; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /docs/src/css/fonts.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | FONT FAMILY GROUPS 4 | 5 | */ 6 | 7 | /* 8 | Copied from https://github.com/ignite/cli/blob/develop/docs/src/css/fonts.css 9 | */ 10 | 11 | /* Inter */ 12 | @font-face { 13 | font-family: "Inter"; 14 | font-style: normal; 15 | font-weight: 400; 16 | font-display: swap; 17 | src: url("~/static/fonts/inter/Inter-Regular.woff2?v=3.19") format("woff2"), 18 | url("~/static/fonts/inter/Inter-Regular.woff?v=3.19") format("woff"); 19 | } 20 | 21 | @font-face { 22 | font-family: "Inter"; 23 | font-style: normal; 24 | font-weight: 500; 25 | font-display: swap; 26 | src: url("~/static/fonts/inter/Inter-Medium.woff2?v=3.19") format("woff2"), 27 | url("~/static/fonts/inter/Inter-Medium.woff?v=3.19") format("woff"); 28 | } 29 | 30 | @font-face { 31 | font-family: "Inter"; 32 | font-style: normal; 33 | font-weight: 700; 34 | font-display: swap; 35 | src: url("~/static/fonts/inter/Inter-Bold.woff2?v=3.19") format("woff2"), 36 | url("~/static/fonts/inter/Inter-Bold.woff?v=3.19") format("woff"); 37 | } 38 | 39 | @font-face { 40 | font-family: "Inter"; 41 | font-style: normal; 42 | font-weight: 900; 43 | font-display: swap; 44 | src: url("~/static/fonts/inter/Inter-Black.woff2?v=3.19") format("woff2"), 45 | url("~/static/fonts/inter/Inter-Black.woff?v=3.19") format("woff"); 46 | } 47 | 48 | /* Inter var */ 49 | @font-face { 50 | font-family: "Inter var"; 51 | font-weight: 100 900; 52 | font-display: swap; 53 | font-style: oblique 0deg 10deg; 54 | src: url("~/static/fonts/intervar/Inter.var.woff2?v=3.19") format("woff2"); 55 | } 56 | 57 | /* JetBrains Mono */ 58 | @font-face { 59 | font-family: "JetBrains Mono"; 60 | font-weight: normal; 61 | font-style: normal; 62 | src: url("~/static/fonts/jetbrainsmono/JetBrainsMono-Regular.woff2") 63 | format("woff2"); 64 | } 65 | -------------------------------------------------------------------------------- /docs/src/js/KeyValueTable.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export const KeyValueTable = ({ 4 | data = {}, 5 | renderKey = (key) => ( 6 | 7 | {key} 8 | 9 | ), 10 | renderValue = (value) => value, 11 | ...otherProps 12 | }) => { 13 | return ( 14 | 15 | 16 | 17 | 18 | 19 | 20 | {Object.entries(data).map(([key, value]) => ( 21 | 22 | 23 | 26 | 27 | ))} 28 |
KeyValue
{renderKey(key)} 24 | {JSON.stringify(renderValue(value))} 25 |
29 | ); 30 | }; 31 | -------------------------------------------------------------------------------- /docs/src/js/Var.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export const Var = ({ children }) => { 4 | return {JSON.stringify(children)}; 5 | }; 6 | 7 | export const PlainVar = ({ children }) => { 8 | return {JSON.stringify(children)}; 9 | }; 10 | 11 | export const ConsoleOutput = ({ children }) => { 12 | 13 | return ( 14 | 17 | ) 18 | }; 19 | -------------------------------------------------------------------------------- /docs/src/pages/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Redirect } from "react-router-dom"; 3 | 4 | export default function Home() { 5 | return ; 6 | } 7 | -------------------------------------------------------------------------------- /docs/static/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/.nojekyll -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-Black.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-Black.woff -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-Black.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-Black.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-BlackItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-BlackItalic.woff -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-BlackItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-BlackItalic.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-Bold.woff -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-Bold.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-BoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-BoldItalic.woff -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-BoldItalic.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-ExtraBold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-ExtraBold.woff -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-ExtraBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-ExtraBold.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-ExtraBoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-ExtraBoldItalic.woff -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-ExtraBoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-ExtraBoldItalic.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-ExtraLight.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-ExtraLight.woff -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-ExtraLight.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-ExtraLight.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-ExtraLightItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-ExtraLightItalic.woff -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-ExtraLightItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-ExtraLightItalic.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-Italic.woff -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-Italic.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-Light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-Light.woff -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-Light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-Light.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-LightItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-LightItalic.woff -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-LightItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-LightItalic.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-Medium.woff -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-Medium.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-MediumItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-MediumItalic.woff -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-MediumItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-MediumItalic.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-Regular.woff -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-Regular.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-SemiBold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-SemiBold.woff -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-SemiBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-SemiBold.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-SemiBoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-SemiBoldItalic.woff -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-SemiBoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-SemiBoldItalic.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-Thin.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-Thin.woff -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-Thin.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-Thin.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-ThinItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-ThinItalic.woff -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-ThinItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-ThinItalic.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-italic.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-italic.var.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/inter/Inter-roman.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/inter/Inter-roman.var.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/intervar/Inter.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/intervar/Inter.var.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/jetbrainsmono/JetBrainsMono-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/jetbrainsmono/JetBrainsMono-Bold.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/jetbrainsmono/JetBrainsMono-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/jetbrainsmono/JetBrainsMono-BoldItalic.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/jetbrainsmono/JetBrainsMono-ExtraBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/jetbrainsmono/JetBrainsMono-ExtraBold.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/jetbrainsmono/JetBrainsMono-ExtraBoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/jetbrainsmono/JetBrainsMono-ExtraBoldItalic.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/jetbrainsmono/JetBrainsMono-ExtraLight.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/jetbrainsmono/JetBrainsMono-ExtraLight.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/jetbrainsmono/JetBrainsMono-ExtraLightItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/jetbrainsmono/JetBrainsMono-ExtraLightItalic.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/jetbrainsmono/JetBrainsMono-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/jetbrainsmono/JetBrainsMono-Italic.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/jetbrainsmono/JetBrainsMono-Light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/jetbrainsmono/JetBrainsMono-Light.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/jetbrainsmono/JetBrainsMono-LightItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/jetbrainsmono/JetBrainsMono-LightItalic.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/jetbrainsmono/JetBrainsMono-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/jetbrainsmono/JetBrainsMono-Medium.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/jetbrainsmono/JetBrainsMono-MediumItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/jetbrainsmono/JetBrainsMono-MediumItalic.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/jetbrainsmono/JetBrainsMono-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/jetbrainsmono/JetBrainsMono-Regular.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/jetbrainsmono/JetBrainsMono-SemiBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/jetbrainsmono/JetBrainsMono-SemiBold.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/jetbrainsmono/JetBrainsMono-SemiBoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/jetbrainsmono/JetBrainsMono-SemiBoldItalic.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/jetbrainsmono/JetBrainsMono-Thin.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/jetbrainsmono/JetBrainsMono-Thin.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/jetbrainsmono/JetBrainsMono-ThinItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/fonts/jetbrainsmono/JetBrainsMono-ThinItalic.woff2 -------------------------------------------------------------------------------- /docs/static/img/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/img/android-chrome-192x192.png -------------------------------------------------------------------------------- /docs/static/img/android-chrome-256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/img/android-chrome-256x256.png -------------------------------------------------------------------------------- /docs/static/img/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/img/apple-touch-icon.png -------------------------------------------------------------------------------- /docs/static/img/banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/img/banner.jpg -------------------------------------------------------------------------------- /docs/static/img/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/img/favicon-16x16.png -------------------------------------------------------------------------------- /docs/static/img/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/docs/static/img/favicon-32x32.png -------------------------------------------------------------------------------- /docs/static/img/ico-chevron.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/static/img/ico-github.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/versions.json: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /docs/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | mode: 'development', 5 | optimization: { 6 | minimize: false, 7 | }, 8 | output: { 9 | clean: true, // Clean the output directory before emit. 10 | }, 11 | }; 12 | -------------------------------------------------------------------------------- /mlc_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "ignorePatterns": [ { "pattern": "^https://ipfs.io/ipfs/" } ], 3 | "replacementPatterns": [ ], 4 | "httpHeaders": [ ], 5 | "timeout": "20s", 6 | "retryOn429": true, 7 | "retryCount": 5, 8 | "fallbackRetryDelay": "30s", 9 | "aliveStatusCodes": [0, 200, 206, 403, 429] 10 | } 11 | -------------------------------------------------------------------------------- /pkg/address/address.go: -------------------------------------------------------------------------------- 1 | package address 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/cosmos/cosmos-sdk/types/bech32" 7 | ) 8 | 9 | // ConvertBech32Prefix convert bech32 address to specified prefix. 10 | func ConvertBech32Prefix(address, prefix string) (string, error) { 11 | _, bz, err := bech32.DecodeAndConvert(address) 12 | if err != nil { 13 | return "", fmt.Errorf("cannot decode %s address: %s", address, err) 14 | } 15 | 16 | convertedAddress, err := bech32.ConvertAndEncode(prefix, bz) 17 | if err != nil { 18 | return "", fmt.Errorf("cannot convert %s address: %s", address, err) 19 | } 20 | 21 | return convertedAddress, nil 22 | } 23 | -------------------------------------------------------------------------------- /pkg/address/address_test.go: -------------------------------------------------------------------------------- 1 | package address 2 | 3 | import ( 4 | "errors" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/require" 8 | ) 9 | 10 | func TestConvertBech32Prefix(t *testing.T) { 11 | cases := []struct { 12 | name string 13 | address string 14 | prefix string 15 | converted string 16 | err error 17 | }{ 18 | { 19 | name: "Convert valid bech 32 address", 20 | address: "akash1a6zlyvpnksx8wr6wz8wemur2xe8zyh0ytz6d88", 21 | converted: "cosmos1a6zlyvpnksx8wr6wz8wemur2xe8zyh0yxeh27a", 22 | prefix: "cosmos", 23 | }, 24 | { 25 | name: "Convert invalid address", 26 | address: "invalidaddress", 27 | prefix: "cosmos", 28 | err: errors.New("cannot decode invalidaddress address: decoding bech32 failed: invalid separator index -1"), 29 | }, 30 | } 31 | 32 | for _, tt := range cases { 33 | t.Run(tt.name, func(t *testing.T) { 34 | convertedAddress, err := ConvertBech32Prefix(tt.address, tt.prefix) 35 | if tt.err != nil { 36 | require.ErrorContains(t, err, tt.err.Error()) 37 | } else { 38 | require.NoError(t, err) 39 | } 40 | require.Equal(t, tt.converted, convertedAddress) 41 | }) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /proto/buf.gen.gogo.yaml: -------------------------------------------------------------------------------- 1 | version: v1 2 | plugins: 3 | - name: gocosmos 4 | out: .. 5 | opt: plugins=grpc,Mgoogle/protobuf/any.proto=github.com/cosmos/cosmos-sdk/codec/types 6 | - name: grpc-gateway 7 | out: .. 8 | opt: logtostderr=true,allow_colon_final_segments=true -------------------------------------------------------------------------------- /proto/buf.yaml: -------------------------------------------------------------------------------- 1 | # Generated by "buf config migrate-v1beta1". Edit as necessary, and 2 | # remove this comment when you're finished. 3 | # 4 | # This module represents the "proto" root found in 5 | # the previous configuration. 6 | version: v1 7 | name: buf.build/cosmos/gaia 8 | deps: 9 | - buf.build/cosmos/gogo-proto 10 | - buf.build/cosmos/cosmos-proto 11 | - buf.build/cosmos/cosmos-sdk:v0.47.0 12 | - buf.build/cosmos/ibc:fbb44f5ad3194450af479a615fa715d9 13 | - buf.build/googleapis/googleapis 14 | - buf.build/cosmos/ics23:b1abd8678aab07165efd453c96796a179eb3131f 15 | - buf.build/cosmos/interchain-security:064c601231b85066bfaf734efec2751a672528a7 16 | 17 | breaking: 18 | use: 19 | - FILE 20 | lint: 21 | use: 22 | - DEFAULT 23 | - COMMENTS 24 | - FILE_LOWER_SNAKE_CASE 25 | except: 26 | - UNARY_RPC 27 | - COMMENT_FIELD 28 | - SERVICE_SUFFIX 29 | - PACKAGE_VERSION_SUFFIX 30 | - RPC_REQUEST_STANDARD_NAME 31 | ignore: 32 | - tendermint 33 | -------------------------------------------------------------------------------- /proto/gaia/liquid/module/v1/module.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package gaia.liquid.module.v1; 4 | 5 | import "cosmos/app/v1alpha1/module.proto"; 6 | 7 | // Module is the config object of the liquid module. 8 | message Module { 9 | option (cosmos.app.v1alpha1.module) = { 10 | go_import : "github.com/cosmos/gaia/x/liquid" 11 | }; 12 | 13 | // authority defines the custom module authority. If not set, defaults to the 14 | // governance module. 15 | string authority = 1; 16 | 17 | // bech32_prefix_validator is the bech32 validator prefix for the app. 18 | string bech32_prefix_validator = 2; 19 | 20 | // bech32_prefix_consensus is the bech32 consensus node prefix for the app. 21 | string bech32_prefix_consensus = 3; 22 | } 23 | -------------------------------------------------------------------------------- /proto/gaia/liquid/v1beta1/genesis.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package gaia.liquid.v1beta1; 3 | 4 | option go_package = "github.com/cosmos/gaia/x/liquid/types"; 5 | 6 | import "gogoproto/gogo.proto"; 7 | import "gaia/liquid/v1beta1/liquid.proto"; 8 | import "amino/amino.proto"; 9 | import "google/protobuf/timestamp.proto"; 10 | 11 | // GenesisState defines the liquid module's genesis state. 12 | message GenesisState { 13 | // params defines all the parameters of related to deposit. 14 | Params params = 1 15 | [ (gogoproto.nullable) = false, (amino.dont_omitempty) = true ]; 16 | 17 | // store tokenize share records to provide reward to record owners 18 | repeated TokenizeShareRecord tokenize_share_records = 9 19 | [ (gogoproto.nullable) = false ]; 20 | 21 | // last tokenize share record id, used for next share record id calculation 22 | uint64 last_tokenize_share_record_id = 10; 23 | 24 | // total number of liquid staked tokens at genesis 25 | bytes total_liquid_staked_tokens = 11 [ 26 | (gogoproto.customtype) = "cosmossdk.io/math.Int", 27 | (gogoproto.moretags) = "yaml:\"total_liquid_staked_tokens\"", 28 | (gogoproto.nullable) = false 29 | ]; 30 | 31 | // tokenize shares locks at genesis 32 | repeated TokenizeShareLock tokenize_share_locks = 12 33 | [ (gogoproto.nullable) = false ]; 34 | } 35 | 36 | // TokenizeSharesLock required for specifying account locks at genesis 37 | message TokenizeShareLock { 38 | // Address of the account that is locked 39 | string address = 1; 40 | // Status of the lock (LOCKED or LOCK_EXPIRING) 41 | string status = 2; 42 | // Completion time if the lock is expiring 43 | google.protobuf.Timestamp completion_time = 3 [ 44 | (gogoproto.nullable) = false, 45 | (gogoproto.stdtime) = true, 46 | (gogoproto.moretags) = "yaml:\"completion_time\"" 47 | ]; 48 | } 49 | -------------------------------------------------------------------------------- /proto/gaia/metaprotocols/extensions.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package gaia.metaprotocols; 3 | 4 | option go_package = "github.com/cosmos/gaia/x/metaprotocols/types"; 5 | 6 | // ExtensionData is a data structure that can be used in transaction extensions. 7 | message ExtensionData { 8 | // protocol_id is the identifier of the protocol 9 | // the field is not used internally but it is validated for correctness 10 | string protocol_id = 1; 11 | 12 | // protocol_version is the identifier of the protocol version 13 | // the field is not used internally but it is validated for correctness 14 | string protocol_version = 2; 15 | 16 | // arbitrary bytes data that can be used to store any data 17 | // the field is not used internally but it is validated and must be provided 18 | bytes data = 3; 19 | } 20 | -------------------------------------------------------------------------------- /proto/scripts/protoc-swagger-gen.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eo pipefail 4 | 5 | mkdir -p ./tmp-swagger-gen 6 | cd proto 7 | proto_dirs=$(find ./ -path -prune -o -name '*.proto' -print0 | xargs -0 -n1 dirname | sort | uniq) 8 | for dir in $proto_dirs; do 9 | # generate swagger files (filter query files) 10 | query_file=$(find "${dir}" -maxdepth 1 \( -name 'query.proto' -o -name 'service.proto' \)) 11 | if [[ ! -z "$query_file" ]]; then 12 | buf generate --template buf.gen.swagger.yaml $query_file 13 | fi 14 | done 15 | 16 | cd .. 17 | 18 | # combine swagger files 19 | # uses nodejs package `swagger-combine`. 20 | # all the individual swagger files need to be configured in `config.json` for merging 21 | swagger-combine ./docs/client/config.json -o ./docs/client/swagger-ui/swagger.yaml -f yaml --continueOnConflictingPaths true --includeDefinitions true 22 | 23 | # clean swagger files 24 | rm -rf ./tmp-swagger-gen -------------------------------------------------------------------------------- /proto/scripts/protocgen.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eo pipefail 4 | echo "Generating gogo proto code" 5 | cd proto 6 | proto_dirs=$(find ./ -path -prune -o -name '*.proto' -print0 | xargs -0 -n1 dirname | sort | uniq) 7 | for dir in $proto_dirs; do 8 | for file in $(find "${dir}" -maxdepth 1 -name '*.proto'); do 9 | if grep "option go_package" $file &> /dev/null ; then 10 | buf generate --template buf.gen.gogo.yaml $file 11 | fi 12 | done 13 | done 14 | cd .. 15 | # move proto files to the right places 16 | cp -r github.com/cosmos/gaia/* ./ 17 | rm -rf github.com -------------------------------------------------------------------------------- /sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=cosmos_gaia 2 | sonar.organization=cosmos 3 | 4 | sonar.projectName=Gaia 5 | 6 | sonar.sources=. 7 | sonar.exclusions=**/*_test.go,tests/**,**/testutil/**,**/*.pb.go,**/*.pb.gw.go,test_helpers.go,docs/**,client/docs/**,contrib/**, 8 | sonar.tests=. 9 | sonar.test.inclusions=**/*_test.go,tests/**,**/testutil/** 10 | sonar.go.coverage.reportPaths=coverage.out,*profile.out 11 | 12 | sonar.python.version=3 13 | sonar.sourceEncoding=UTF-8 14 | sonar.scm.provider=git 15 | 16 | # Exclude C/C++/Objective-C files from analysis 17 | sonar.c.file.suffixes=- 18 | sonar.cpp.file.suffixes=- 19 | sonar.objc.file.suffixes=- -------------------------------------------------------------------------------- /tests/e2e/common/address.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "strconv" 7 | 8 | "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" 9 | crypto "github.com/cosmos/cosmos-sdk/crypto/types" 10 | sdk "github.com/cosmos/cosmos-sdk/types" 11 | ) 12 | 13 | // HDPath generates an HD path based on the wallet index 14 | func HDPath(index int) string { 15 | return fmt.Sprintf("m/44'/118'/0'/0/%d", index) 16 | } 17 | 18 | // PubKey returns a sample account PubKey 19 | func PubKey() crypto.PubKey { 20 | seed := []byte(strconv.Itoa(rand.Int())) 21 | return ed25519.GenPrivKeyFromSecret(seed).PubKey() 22 | } 23 | 24 | // AccAddress returns a sample account address 25 | func AccAddress() sdk.AccAddress { 26 | addr := PubKey().Address() 27 | return sdk.AccAddress(addr) 28 | } 29 | 30 | // Address returns a sample string account address 31 | func Address() string { 32 | return AccAddress().String() 33 | } 34 | -------------------------------------------------------------------------------- /tests/e2e/common/http_util.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "fmt" 7 | "io" 8 | "net/http" 9 | ) 10 | 11 | func HTTPGet(endpoint string) ([]byte, error) { 12 | resp, err := http.Get(endpoint) //nolint:gosec // this is only used during tests 13 | if err != nil { 14 | return nil, fmt.Errorf("failed to execute HTTP request: %w", err) 15 | } 16 | defer resp.Body.Close() 17 | 18 | body, err := io.ReadAll(resp.Body) 19 | if err != nil { 20 | return nil, err 21 | } 22 | 23 | return body, nil 24 | } 25 | 26 | func ReadJSON(resp *http.Response) (map[string]interface{}, error) { 27 | defer resp.Body.Close() 28 | 29 | body, readErr := io.ReadAll(resp.Body) 30 | if readErr != nil { 31 | return nil, errors.New("failed to read Body") 32 | } 33 | 34 | var data map[string]interface{} 35 | err := json.Unmarshal(body, &data) 36 | if err != nil { 37 | return nil, errors.New("failed to unmarshal response body") 38 | } 39 | 40 | return data, nil 41 | } 42 | -------------------------------------------------------------------------------- /tests/e2e/common/io.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "os" 7 | ) 8 | 9 | // CopyFile copy file from src to dst 10 | func CopyFile(src, dst string) (int64, error) { 11 | sourceFileStat, err := os.Stat(src) 12 | if err != nil { 13 | return 0, err 14 | } 15 | 16 | if !sourceFileStat.Mode().IsRegular() { 17 | return 0, fmt.Errorf("%s is not a regular file", src) 18 | } 19 | 20 | source, err := os.Open(src) 21 | if err != nil { 22 | return 0, err 23 | } 24 | defer source.Close() 25 | 26 | destination, err := os.Create(dst) 27 | if err != nil { 28 | return 0, err 29 | } 30 | defer destination.Close() 31 | 32 | nBytes, err := io.Copy(destination, source) 33 | return nBytes, err 34 | } 35 | 36 | // WriteFile write a byte slice into a file path 37 | // create the file if it doesn't exist 38 | // NOTE: this file can be write and read by everyone 39 | func WriteFile(path string, body []byte) error { 40 | return os.WriteFile(path, body, 0o666) //nolint:gosec 41 | } 42 | -------------------------------------------------------------------------------- /tests/e2e/common/keys.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "github.com/cosmos/go-bip39" 5 | ) 6 | 7 | // CreateMnemonic creates a random string mnemonic 8 | func CreateMnemonic() (string, error) { 9 | entropySeed, err := bip39.NewEntropy(256) 10 | if err != nil { 11 | return "", err 12 | } 13 | 14 | mnemonic, err := bip39.NewMnemonic(entropySeed) 15 | if err != nil { 16 | return "", err 17 | } 18 | 19 | return mnemonic, nil 20 | } 21 | -------------------------------------------------------------------------------- /tests/e2e/common/types.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "github.com/ory/dockertest/v3" 5 | "github.com/stretchr/testify/suite" 6 | ) 7 | 8 | type TestingSuite struct { 9 | suite.Suite 10 | TestCounters TestCounters 11 | Resources Resources 12 | } 13 | 14 | type TestCounters struct { 15 | ProposalCounter int 16 | ContractsCounter int 17 | ContractsCounterPerSender map[string]uint64 18 | IBCV2PacketSequence int 19 | } 20 | 21 | type Resources struct { 22 | TmpDirs []string 23 | ChainA *Chain 24 | ChainB *Chain 25 | DkrPool *dockertest.Pool 26 | DkrNet *dockertest.Network 27 | HermesResource *dockertest.Resource 28 | 29 | ValResources map[string][]*dockertest.Resource 30 | } 31 | -------------------------------------------------------------------------------- /tests/e2e/data/counter.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/tests/e2e/data/counter.wasm -------------------------------------------------------------------------------- /tests/e2e/data/skip_go_entry_point.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/tests/e2e/data/skip_go_entry_point.wasm -------------------------------------------------------------------------------- /tests/e2e/data/skip_go_ibc_adapter_ibc_callbacks.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/tests/e2e/data/skip_go_ibc_adapter_ibc_callbacks.wasm -------------------------------------------------------------------------------- /tests/e2e/doc.go: -------------------------------------------------------------------------------- 1 | // Package e2e defines an integration testing suite used for full end-to-end 2 | // testing functionality. 3 | // 4 | // The file e2e_suite_test.go defines the testing suite and contains the core 5 | // bootstrapping logic that creates a testing environment via Docker containers. 6 | // A testing network is created dynamically and contains multiple Docker 7 | // containers: 8 | // 9 | // 1. Two independent Gaia networks 10 | // 3. A hermes relayer connecting the two Gaia networks over IBC 11 | // 12 | // The file e2e_test.go contains the actual end-to-end integration tests that 13 | // utilize the testing suite. 14 | package e2e 15 | -------------------------------------------------------------------------------- /tests/e2e/docker/hermes.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM --platform=linux/amd64 informalsystems/hermes:1.10.0 AS hermes-builder 2 | 3 | FROM --platform=linux/amd64 debian:buster-slim 4 | USER root 5 | 6 | COPY --from=hermes-builder /usr/bin/hermes /usr/local/bin/ 7 | RUN chmod +x /usr/local/bin/hermes 8 | 9 | EXPOSE 3031 -------------------------------------------------------------------------------- /tests/e2e/e2e_encode_test.go: -------------------------------------------------------------------------------- 1 | package e2e 2 | 3 | import ( 4 | "encoding/base64" 5 | "path/filepath" 6 | 7 | sdk "github.com/cosmos/cosmos-sdk/types" 8 | 9 | "github.com/cosmos/gaia/v25/tests/e2e/common" 10 | ) 11 | 12 | const ( 13 | rawTxFile = "tx_raw.json" 14 | ) 15 | 16 | func (s *IntegrationTestSuite) testEncode() { 17 | chain := s.Resources.ChainA 18 | _, encoded, err := buildRawTx() 19 | s.Require().NoError(err) 20 | 21 | got := s.ExecEncode(chain, filepath.Join(common.GaiaHomePath, rawTxFile)) 22 | s.T().Logf("encoded tx: %s", got) 23 | s.Require().Equal(encoded, got) 24 | } 25 | 26 | func (s *IntegrationTestSuite) testDecode() { 27 | chain := s.Resources.ChainA 28 | rawTx, encoded, err := buildRawTx() 29 | s.Require().NoError(err) 30 | 31 | got := s.ExecDecode(chain, encoded) 32 | s.T().Logf("raw tx: %s", got) 33 | s.Require().Equal(string(rawTx), got) 34 | } 35 | 36 | // buildRawTx build a dummy tx using the TxBuilder and 37 | // return the JSON and encoded tx's 38 | func buildRawTx() ([]byte, string, error) { 39 | builder := common.TxConfig.NewTxBuilder() 40 | builder.SetGasLimit(common.Gas) 41 | builder.SetFeeAmount(sdk.NewCoins(common.StandardFees)) 42 | builder.SetMemo("foomemo") 43 | tx, err := common.TxConfig.TxJSONEncoder()(builder.GetTx()) 44 | if err != nil { 45 | return nil, "", err 46 | } 47 | txBytes, err := common.TxConfig.TxEncoder()(builder.GetTx()) 48 | if err != nil { 49 | return nil, "", err 50 | } 51 | return tx, base64.StdEncoding.EncodeToString(txBytes), err 52 | } 53 | -------------------------------------------------------------------------------- /tests/e2e/e2e_evidence_test.go: -------------------------------------------------------------------------------- 1 | package e2e 2 | 3 | import ( 4 | "encoding/hex" 5 | "fmt" 6 | "strings" 7 | 8 | "cosmossdk.io/x/evidence/exported" 9 | evidencetypes "cosmossdk.io/x/evidence/types" 10 | 11 | "github.com/cosmos/gaia/v25/tests/e2e/common" 12 | "github.com/cosmos/gaia/v25/tests/e2e/query" 13 | ) 14 | 15 | func (s *IntegrationTestSuite) testEvidence() { 16 | s.Run("test evidence queries", func() { 17 | var ( 18 | valIdx = 0 19 | chain = s.Resources.ChainA 20 | chainAPI = fmt.Sprintf("http://%s", s.Resources.ValResources[chain.ID][valIdx].GetHostPort("1317/tcp")) 21 | ) 22 | res, err := query.AllEvidence(chainAPI) 23 | s.Require().NoError(err) 24 | s.Require().Equal(common.NumberOfEvidences, len(res.Evidence)) 25 | for _, evidence := range res.Evidence { 26 | var exportedEvidence exported.Evidence 27 | err := common.Cdc.UnpackAny(evidence, &exportedEvidence) 28 | s.Require().NoError(err) 29 | eq, ok := exportedEvidence.(*evidencetypes.Equivocation) 30 | s.Require().True(ok) 31 | _, err = query.ExecQueryEvidence(chainAPI, strings.ToUpper(hex.EncodeToString(eq.Hash()))) 32 | s.Require().NoError(err) 33 | } 34 | }) 35 | } 36 | -------------------------------------------------------------------------------- /tests/e2e/e2e_slashing_test.go: -------------------------------------------------------------------------------- 1 | package e2e 2 | 3 | import ( 4 | "github.com/cosmos/gaia/v25/tests/e2e/common" 5 | "github.com/cosmos/gaia/v25/tests/e2e/query" 6 | ) 7 | 8 | const jailedValidatorKey = "jailed" 9 | 10 | func (s *IntegrationTestSuite) testSlashing(chainEndpoint string) { 11 | s.Run("test unjail validator", func() { 12 | validators, err := query.Validators(chainEndpoint) 13 | s.Require().NoError(err) 14 | 15 | for _, val := range validators.Validators { 16 | if val.Jailed { 17 | s.ExecUnjail( 18 | s.Resources.ChainA, 19 | common.WithKeyValue(common.FlagFrom, jailedValidatorKey), 20 | ) 21 | 22 | valQ, err := query.Validator(chainEndpoint, val.OperatorAddress) 23 | s.Require().NoError(err) 24 | s.Require().False(valQ.Jailed) 25 | } 26 | } 27 | }) 28 | } 29 | -------------------------------------------------------------------------------- /tests/e2e/msg/memo.go: -------------------------------------------------------------------------------- 1 | package msg 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func BuildCallbacksMemo(entrypointAddress, recipientDenom, adapterAddress, recipientAddress string) string { 9 | ibcHooksData := fmt.Sprintf(`"wasm": { 10 | "contract": "%s", 11 | "msg": { 12 | "action": { 13 | "sent_asset": { 14 | "native": { 15 | "denom":"%s", 16 | "amount":"1" 17 | } 18 | }, 19 | "exact_out": false, 20 | "timeout_timestamp": %d, 21 | "action": { 22 | "transfer":{ 23 | "to_address": "%s" 24 | } 25 | } 26 | } 27 | } 28 | }`, entrypointAddress, recipientDenom, time.Now().Add(time.Minute).UnixNano(), recipientAddress) 29 | destCallbackData := fmt.Sprintf(`"dest_callback": { 30 | "address": "%s", 31 | "gas_limit": "%d" 32 | }`, adapterAddress, 10_000_000) 33 | memo := fmt.Sprintf("{%s,%s}", destCallbackData, ibcHooksData) 34 | return memo 35 | } 36 | -------------------------------------------------------------------------------- /tests/e2e/query/bank.go: -------------------------------------------------------------------------------- 1 | package query 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/cosmos/cosmos-sdk/types" 8 | banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" 9 | 10 | "github.com/cosmos/gaia/v25/tests/e2e/common" 11 | ) 12 | 13 | // if coin is zero, return empty coin. 14 | func SpecificBalance(endpoint, addr, denom string) (amt types.Coin, err error) { 15 | balances, err := AllBalances(endpoint, addr) 16 | if err != nil { 17 | return amt, err 18 | } 19 | for _, c := range balances { 20 | if strings.Contains(c.Denom, denom) { 21 | amt = c 22 | break 23 | } 24 | } 25 | return amt, nil 26 | } 27 | 28 | func AllBalances(endpoint, addr string) (types.Coins, error) { 29 | body, err := common.HTTPGet(fmt.Sprintf("%s/cosmos/bank/v1beta1/balances/%s", endpoint, addr)) 30 | if err != nil { 31 | return nil, fmt.Errorf("failed to execute HTTP request: %w", err) 32 | } 33 | 34 | var balancesResp banktypes.QueryAllBalancesResponse 35 | if err := common.Cdc.UnmarshalJSON(body, &balancesResp); err != nil { 36 | return nil, err 37 | } 38 | 39 | return balancesResp.Balances, nil 40 | } 41 | 42 | func SupplyOf(endpoint, denom string) (types.Coin, error) { 43 | body, err := common.HTTPGet(fmt.Sprintf("%s/cosmos/bank/v1beta1/supply/by_denom?denom=%s", endpoint, denom)) 44 | if err != nil { 45 | return types.Coin{}, fmt.Errorf("failed to execute HTTP request: %w", err) 46 | } 47 | 48 | var supplyOfResp banktypes.QuerySupplyOfResponse 49 | if err := common.Cdc.UnmarshalJSON(body, &supplyOfResp); err != nil { 50 | return types.Coin{}, err 51 | } 52 | 53 | return supplyOfResp.Amount, nil 54 | } 55 | -------------------------------------------------------------------------------- /tests/e2e/query/distribution.go: -------------------------------------------------------------------------------- 1 | package query 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/cosmos/cosmos-sdk/x/distribution/types" 7 | 8 | "github.com/cosmos/gaia/v25/tests/e2e/common" 9 | ) 10 | 11 | func DelegatorWithdrawalAddress(endpoint string, delegatorAddr string) (types.QueryDelegatorWithdrawAddressResponse, error) { 12 | var res types.QueryDelegatorWithdrawAddressResponse 13 | 14 | body, err := common.HTTPGet(fmt.Sprintf("%s/cosmos/distribution/v1beta1/delegators/%s/withdraw_address", endpoint, delegatorAddr)) 15 | if err != nil { 16 | return res, err 17 | } 18 | 19 | if err = common.Cdc.UnmarshalJSON(body, &res); err != nil { 20 | return res, err 21 | } 22 | return res, nil 23 | } 24 | -------------------------------------------------------------------------------- /tests/e2e/query/gov.go: -------------------------------------------------------------------------------- 1 | package query 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/cosmos/cosmos-sdk/x/gov/types/v1" 7 | "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" 8 | 9 | "github.com/cosmos/gaia/v25/tests/e2e/common" 10 | ) 11 | 12 | func GovProposal(endpoint string, proposalID int) (v1beta1.QueryProposalResponse, error) { 13 | var govProposalResp v1beta1.QueryProposalResponse 14 | 15 | path := fmt.Sprintf("%s/cosmos/gov/v1beta1/proposals/%d", endpoint, proposalID) 16 | 17 | body, err := common.HTTPGet(path) 18 | if err != nil { 19 | return govProposalResp, fmt.Errorf("failed to execute HTTP request: %w", err) 20 | } 21 | if err := common.Cdc.UnmarshalJSON(body, &govProposalResp); err != nil { 22 | return govProposalResp, err 23 | } 24 | 25 | return govProposalResp, nil 26 | } 27 | 28 | func GovProposalV1(endpoint string, proposalID int) (v1.QueryProposalResponse, error) { 29 | var govProposalResp v1.QueryProposalResponse 30 | 31 | path := fmt.Sprintf("%s/cosmos/gov/v1/proposals/%d", endpoint, proposalID) 32 | 33 | body, err := common.HTTPGet(path) 34 | if err != nil { 35 | return govProposalResp, fmt.Errorf("failed to execute HTTP request: %w", err) 36 | } 37 | if err := common.Cdc.UnmarshalJSON(body, &govProposalResp); err != nil { 38 | return govProposalResp, err 39 | } 40 | 41 | return govProposalResp, nil 42 | } 43 | -------------------------------------------------------------------------------- /tests/e2e/query/ibc.go: -------------------------------------------------------------------------------- 1 | package query 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/v10/types" 7 | 8 | "github.com/cosmos/gaia/v25/tests/e2e/common" 9 | ) 10 | 11 | func IbcWasmChecksums(endpoint string) ([]string, error) { 12 | body, err := common.HTTPGet(fmt.Sprintf("%s/ibc/lightclients/wasm/v1/checksums", endpoint)) 13 | if err != nil { 14 | return nil, fmt.Errorf("failed to execute HTTP request: %w", err) 15 | } 16 | 17 | var response types.QueryChecksumsResponse 18 | if err = common.Cdc.UnmarshalJSON(body, &response); err != nil { 19 | return nil, err 20 | } 21 | 22 | return response.Checksums, nil 23 | } 24 | -------------------------------------------------------------------------------- /tests/e2e/query/ica.go: -------------------------------------------------------------------------------- 1 | package query 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts/controller/types" 7 | 8 | "github.com/cosmos/gaia/v25/tests/e2e/common" 9 | ) 10 | 11 | func ICAAccountAddress(endpoint, owner, connectionID string) (string, error) { 12 | body, err := common.HTTPGet(fmt.Sprintf("%s/ibc/apps/interchain_accounts/controller/v1/owners/%s/connections/%s", endpoint, owner, connectionID)) 13 | if err != nil { 14 | return "", fmt.Errorf("failed to execute HTTP request: %w", err) 15 | } 16 | 17 | var icaAccountResp types.QueryInterchainAccountResponse 18 | if err := common.Cdc.UnmarshalJSON(body, &icaAccountResp); err != nil { 19 | return "", err 20 | } 21 | 22 | return icaAccountResp.Address, nil 23 | } 24 | -------------------------------------------------------------------------------- /tests/e2e/query/ics.go: -------------------------------------------------------------------------------- 1 | package query 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/cosmos/interchain-security/v7/x/ccv/provider/types" 7 | 8 | "github.com/cosmos/gaia/v25/tests/e2e/common" 9 | ) 10 | 11 | func BlocksPerEpoch(endpoint string) (int64, error) { 12 | body, err := common.HTTPGet(fmt.Sprintf("%s/interchain_security/ccv/provider/params", endpoint)) 13 | if err != nil { 14 | return 0, fmt.Errorf("failed to execute HTTP request: %w", err) 15 | } 16 | 17 | var response types.QueryParamsResponse 18 | if err = common.Cdc.UnmarshalJSON(body, &response); err != nil { 19 | return 0, err 20 | } 21 | 22 | return response.Params.BlocksPerEpoch, nil 23 | } 24 | -------------------------------------------------------------------------------- /tests/e2e/query/rate_limiting.go: -------------------------------------------------------------------------------- 1 | package query 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/cosmos/ibc-apps/modules/rate-limiting/v10/types" 7 | 8 | "github.com/cosmos/gaia/v25/tests/e2e/common" 9 | ) 10 | 11 | func AllRateLimits(endpoint string) ([]types.RateLimit, error) { 12 | var res types.QueryAllRateLimitsResponse 13 | 14 | body, err := common.HTTPGet(fmt.Sprintf("%s/Stride-Labs/ibc-rate-limiting/ratelimit/ratelimits", endpoint)) 15 | if err != nil { 16 | return []types.RateLimit{}, fmt.Errorf("failed to execute HTTP request: %w", err) 17 | } 18 | 19 | if err := common.Cdc.UnmarshalJSON(body, &res); err != nil { 20 | return []types.RateLimit{}, err 21 | } 22 | return res.RateLimits, nil 23 | } 24 | 25 | func RateLimit(endpoint, channelID, denom string) (types.QueryRateLimitResponse, error) { 26 | var res types.QueryRateLimitResponse 27 | 28 | body, err := common.HTTPGet(fmt.Sprintf("%s/Stride-Labs/ibc-rate-limiting/ratelimit/ratelimit/%s/by_denom?denom=%s", endpoint, channelID, denom)) 29 | if err != nil { 30 | return types.QueryRateLimitResponse{}, fmt.Errorf("failed to execute HTTP request: %w", err) 31 | } 32 | 33 | if err := common.Cdc.UnmarshalJSON(body, &res); err != nil { 34 | return types.QueryRateLimitResponse{}, err 35 | } 36 | return res, nil 37 | } 38 | 39 | func RateLimitsByChainID(endpoint, channelID string) ([]types.RateLimit, error) { 40 | var res types.QueryRateLimitsByChainIdResponse 41 | 42 | body, err := common.HTTPGet(fmt.Sprintf("%s/Stride-Labs/ibc-rate-limiting/ratelimit/ratelimits/%s", endpoint, channelID)) 43 | if err != nil { 44 | return []types.RateLimit{}, fmt.Errorf("failed to execute HTTP request: %w", err) 45 | } 46 | 47 | if err := common.Cdc.UnmarshalJSON(body, &res); err != nil { 48 | return []types.RateLimit{}, err 49 | } 50 | return res.RateLimits, nil 51 | } 52 | -------------------------------------------------------------------------------- /tests/e2e/query/tendermint.go: -------------------------------------------------------------------------------- 1 | package query 2 | 3 | import ( 4 | "fmt" 5 | 6 | tendermintv1beta1 "cosmossdk.io/api/cosmos/base/tendermint/v1beta1" 7 | 8 | "github.com/cosmos/gaia/v25/tests/e2e/common" 9 | ) 10 | 11 | func GetLatestBlockHeight(endpoint string) (int, error) { 12 | body, err := common.HTTPGet(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/blocks/latest", endpoint)) 13 | if err != nil { 14 | return 0, fmt.Errorf("failed to execute HTTP request: %w", err) 15 | } 16 | 17 | var response tendermintv1beta1.GetLatestBlockResponse 18 | if err = common.Cdc.UnmarshalJSON(body, &response); err != nil { 19 | return 0, err 20 | } 21 | return int(response.GetBlock().GetLastCommit().Height), nil 22 | } 23 | -------------------------------------------------------------------------------- /tests/e2e/query/wasm.go: -------------------------------------------------------------------------------- 1 | package query 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/CosmWasm/wasmd/x/wasm/types" 7 | 8 | "github.com/cosmos/gaia/v25/tests/e2e/common" 9 | ) 10 | 11 | func WasmContractAddress(endpoint, creator string, idx uint64) (string, error) { 12 | body, err := common.HTTPGet(fmt.Sprintf("%s/cosmwasm/wasm/v1/contracts/creator/%s", endpoint, creator)) 13 | if err != nil { 14 | return "", fmt.Errorf("failed to execute HTTP request: %w", err) 15 | } 16 | 17 | var response types.QueryContractsByCreatorResponse 18 | if err = common.Cdc.UnmarshalJSON(body, &response); err != nil { 19 | return "", err 20 | } 21 | 22 | return response.ContractAddresses[idx], nil 23 | } 24 | 25 | func WasmSmartContractState(endpoint, address, msg string) ([]byte, error) { 26 | body, err := common.HTTPGet(fmt.Sprintf("%s/cosmwasm/wasm/v1/contract/%s/smart/%s", endpoint, address, msg)) 27 | if err != nil { 28 | return nil, fmt.Errorf("failed to execute HTTP request: %w", err) 29 | } 30 | 31 | var response types.QuerySmartContractStateResponse 32 | if err = common.Cdc.UnmarshalJSON(body, &response); err != nil { 33 | return nil, err 34 | } 35 | 36 | return response.Data, nil 37 | } 38 | -------------------------------------------------------------------------------- /tests/e2e/suite.go: -------------------------------------------------------------------------------- 1 | package e2e 2 | 3 | import ( 4 | "github.com/cosmos/gaia/v25/tests/e2e/tx" 5 | ) 6 | 7 | type IntegrationTestSuite struct { 8 | tx.TestingSuite 9 | } 10 | -------------------------------------------------------------------------------- /tests/e2e/tx/gov.go: -------------------------------------------------------------------------------- 1 | package tx 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "time" 7 | 8 | "github.com/cosmos/cosmos-sdk/client/flags" 9 | "github.com/cosmos/cosmos-sdk/x/gov/types" 10 | 11 | "github.com/cosmos/gaia/v25/tests/e2e/common" 12 | ) 13 | 14 | func (h *TestingSuite) RunGovExec(c *common.Chain, valIdx int, submitterAddr, govCommand string, proposalFlags []string, fees string, validationFunc func([]byte, []byte) bool) { 15 | ctx, cancel := context.WithTimeout(context.Background(), time.Minute) 16 | defer cancel() 17 | validateResponse := h.DefaultExecValidation(c, valIdx) 18 | if validationFunc != nil { 19 | validateResponse = validationFunc 20 | } 21 | 22 | gaiaCommand := []string{ 23 | common.GaiadBinary, 24 | common.TxCommand, 25 | types.ModuleName, 26 | govCommand, 27 | } 28 | 29 | generalFlags := []string{ 30 | fmt.Sprintf("--%s=%s", flags.FlagFrom, submitterAddr), 31 | fmt.Sprintf("--%s=%s", flags.FlagGas, "50000000"), // default 200000 isn't enough 32 | fmt.Sprintf("--%s=%s", flags.FlagGasPrices, fees), 33 | fmt.Sprintf("--%s=%s", flags.FlagChainID, c.ID), 34 | "--keyring-backend=test", 35 | "--output=json", 36 | "-y", 37 | } 38 | 39 | gaiaCommand = common.ConcatFlags(gaiaCommand, proposalFlags, generalFlags) 40 | h.Suite.T().Logf("Executing gaiad tx gov %s on chain %s", govCommand, c.ID) 41 | h.ExecuteGaiaTxCommand(ctx, c, gaiaCommand, valIdx, validateResponse) 42 | h.Suite.T().Logf("Successfully executed %s", govCommand) 43 | } 44 | -------------------------------------------------------------------------------- /tests/e2e/tx/ibc.go: -------------------------------------------------------------------------------- 1 | package tx 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/cosmos/cosmos-sdk/client/flags" 8 | 9 | "github.com/cosmos/gaia/v25/tests/e2e/common" 10 | ) 11 | 12 | func (h *TestingSuite) AddWasmClientCounterparty(ctx context.Context, c *common.Chain, sender string, valIdx int) { 13 | cmd := []string{ 14 | common.GaiadBinary, 15 | common.TxCommand, 16 | "ibc", 17 | "client", 18 | "add-counterparty", 19 | common.V2TransferClient, 20 | common.CounterpartyID, 21 | "aWJj", 22 | fmt.Sprintf("--from=%s", sender), 23 | fmt.Sprintf("--%s=%s", flags.FlagFees, common.StandardFees.String()), 24 | fmt.Sprintf("--%s=%s", flags.FlagChainID, c.ID), 25 | "--keyring-backend=test", 26 | "--broadcast-mode=sync", 27 | "--output=json", 28 | "-y", 29 | } 30 | 31 | h.Suite.T().Logf("Adding wasm light client counterparty on chain %s", c.ID) 32 | h.ExecuteGaiaTxCommand(ctx, h.Resources.ChainA, cmd, valIdx, h.DefaultExecValidation(c, valIdx)) 33 | h.Suite.T().Log("successfully added wasm light client counterparty") 34 | } 35 | 36 | func (h *TestingSuite) CreateClient(ctx context.Context, c *common.Chain, clientState string, consensusState string, sender string, valIdx int) { 37 | cmd := []string{ 38 | common.GaiadBinary, 39 | common.TxCommand, 40 | "ibc", 41 | "client", 42 | "create", 43 | clientState, 44 | consensusState, 45 | fmt.Sprintf("--from=%s", sender), 46 | fmt.Sprintf("--%s=%s", flags.FlagFees, common.StandardFees.String()), 47 | fmt.Sprintf("--%s=%s", flags.FlagChainID, c.ID), 48 | "--keyring-backend=test", 49 | "--broadcast-mode=sync", 50 | "--output=json", 51 | "-y", 52 | } 53 | 54 | h.Suite.T().Logf("Creating wasm light client on chain %s", c.ID) 55 | h.ExecuteGaiaTxCommand(ctx, c, cmd, valIdx, h.DefaultExecValidation(h.Resources.ChainA, valIdx)) 56 | h.Suite.T().Log("successfully created wasm light client") 57 | } 58 | -------------------------------------------------------------------------------- /tests/e2e/tx/ibc_transfer_v1.go: -------------------------------------------------------------------------------- 1 | package tx 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "time" 7 | 8 | "github.com/cosmos/cosmos-sdk/client/flags" 9 | 10 | "github.com/cosmos/gaia/v25/tests/e2e/common" 11 | ) 12 | 13 | func (h *TestingSuite) SendIBC(c *common.Chain, valIdx int, sender, recipient, token, fees, note, channel string, absoluteTimeout *int64, expErr bool) { 14 | ctx, cancel := context.WithTimeout(context.Background(), time.Minute) 15 | defer cancel() 16 | 17 | ibcCmd := []string{ 18 | common.GaiadBinary, 19 | common.TxCommand, 20 | "ibc-transfer", 21 | "transfer", 22 | "transfer", 23 | channel, 24 | recipient, 25 | token, 26 | } 27 | 28 | if absoluteTimeout != nil { 29 | ibcCmd = append(ibcCmd, "--absolute-timeouts") 30 | ibcCmd = append(ibcCmd, fmt.Sprintf("--packet-timeout-timestamp=%d", *absoluteTimeout)) 31 | } 32 | 33 | ibcCmd = append(ibcCmd, []string{ 34 | fmt.Sprintf("--from=%s", sender), 35 | fmt.Sprintf("--%s=%s", flags.FlagFees, fees), 36 | fmt.Sprintf("--%s=%s", flags.FlagChainID, c.ID), 37 | // fmt.Sprintf("--%s=%s", flags.FlagNote, note), 38 | fmt.Sprintf("--memo=%s", note), 39 | "--keyring-backend=test", 40 | "--broadcast-mode=sync", 41 | "--output=json", 42 | "-y", 43 | }...) 44 | 45 | h.Suite.T().Logf("sending %s from %s (%s) to %s (%s) with memo %s", token, h.Resources.ChainA.ID, sender, h.Resources.ChainB.ID, recipient, note) 46 | if expErr { 47 | h.ExecuteGaiaTxCommand(ctx, c, ibcCmd, valIdx, h.ExpectErrExecValidation(c, valIdx, true)) 48 | h.Suite.T().Log("unsuccessfully sent IBC tokens") 49 | } else { 50 | h.ExecuteGaiaTxCommand(ctx, c, ibcCmd, valIdx, h.DefaultExecValidation(c, valIdx)) 51 | h.Suite.T().Log("successfully sent IBC tokens") 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tests/e2e/tx/slashing.go: -------------------------------------------------------------------------------- 1 | package tx 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "time" 7 | 8 | "github.com/cosmos/cosmos-sdk/x/slashing/types" 9 | 10 | "github.com/cosmos/gaia/v25/tests/e2e/common" 11 | ) 12 | 13 | func (h *TestingSuite) ExecUnjail( 14 | c *common.Chain, 15 | opt ...common.FlagOption, 16 | ) { 17 | opts := common.ApplyOptions(c.ID, opt) 18 | ctx, cancel := context.WithTimeout(context.Background(), time.Minute) 19 | defer cancel() 20 | 21 | h.Suite.T().Logf("Executing gaiad slashing unjail %s with options: %v", c.ID, opt) 22 | gaiaCommand := []string{ 23 | common.GaiadBinary, 24 | common.TxCommand, 25 | types.ModuleName, 26 | "unjail", 27 | "-y", 28 | } 29 | 30 | for flag, value := range opts { 31 | gaiaCommand = append(gaiaCommand, fmt.Sprintf("--%s=%v", flag, value)) 32 | } 33 | 34 | h.ExecuteGaiaTxCommand(ctx, c, gaiaCommand, 0, h.DefaultExecValidation(c, 0)) 35 | h.Suite.T().Logf("successfully unjail with options %v", opt) 36 | } 37 | -------------------------------------------------------------------------------- /tests/e2e/tx/vesting.go: -------------------------------------------------------------------------------- 1 | package tx 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "time" 7 | 8 | "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" 9 | 10 | "github.com/cosmos/gaia/v25/tests/e2e/common" 11 | ) 12 | 13 | func (h *TestingSuite) execVestingTx( 14 | c *common.Chain, 15 | method string, 16 | args []string, 17 | opt ...common.FlagOption, 18 | ) { 19 | opts := common.ApplyOptions(c.ID, opt) 20 | ctx, cancel := context.WithTimeout(context.Background(), time.Minute) 21 | defer cancel() 22 | 23 | h.Suite.T().Logf("%s - Executing gaiad %s with %v", c.ID, method, args) 24 | gaiaCommand := []string{ 25 | common.GaiadBinary, 26 | common.TxCommand, 27 | types.ModuleName, 28 | method, 29 | "-y", 30 | } 31 | gaiaCommand = append(gaiaCommand, args...) 32 | 33 | for flag, value := range opts { 34 | gaiaCommand = append(gaiaCommand, fmt.Sprintf("--%s=%v", flag, value)) 35 | } 36 | 37 | h.ExecuteGaiaTxCommand(ctx, c, gaiaCommand, 0, h.DefaultExecValidation(c, 0)) 38 | h.Suite.T().Logf("successfully %s with %v", method, args) 39 | } 40 | 41 | func (h *TestingSuite) ExecCreatePeriodicVestingAccount( 42 | c *common.Chain, 43 | address, 44 | jsonPath string, 45 | opt ...common.FlagOption, 46 | ) { 47 | h.Suite.T().Logf("Executing gaiad create periodic vesting account %s", c.ID) 48 | h.execVestingTx(c, "create-periodic-vesting-account", []string{address, jsonPath}, opt...) 49 | h.Suite.T().Logf("successfully created periodic vesting account %s with %s", address, jsonPath) 50 | } 51 | -------------------------------------------------------------------------------- /tests/interchain/chainsuite/envconfig.go: -------------------------------------------------------------------------------- 1 | package chainsuite 2 | 3 | import ( 4 | "github.com/kelseyhightower/envconfig" 5 | ) 6 | 7 | const prefix = "TEST" 8 | 9 | type Environment struct { 10 | DockerRegistry string `envconfig:"DOCKER_REGISTRY"` 11 | GaiaImageName string `envconfig:"GAIA_IMAGE_NAME" default:"gaia"` 12 | OldGaiaImageVersion string `envconfig:"OLD_GAIA_IMAGE_VERSION"` 13 | NewGaiaImageVersion string `envconfig:"NEW_GAIA_IMAGE_VERSION"` 14 | UpgradeName string `envconfig:"UPGRADE_NAME"` 15 | } 16 | 17 | func GetEnvironment() Environment { 18 | var env Environment 19 | envconfig.MustProcess(prefix, &env) 20 | return env 21 | } 22 | -------------------------------------------------------------------------------- /tests/interchain/chainsuite/http.go: -------------------------------------------------------------------------------- 1 | package chainsuite 2 | 3 | import ( 4 | "context" 5 | "io" 6 | "net/http" 7 | ) 8 | 9 | func CheckEndpoint(ctx context.Context, url string, f func([]byte) error) error { 10 | resp, err := http.Get(url) //nolint:gosec 11 | if err != nil { 12 | return err 13 | } 14 | defer resp.Body.Close() 15 | bts, err := io.ReadAll(resp.Body) 16 | if err != nil { 17 | return err 18 | } 19 | return f(bts) 20 | } 21 | -------------------------------------------------------------------------------- /tests/interchain/chainsuite/utils.go: -------------------------------------------------------------------------------- 1 | package chainsuite 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | sdkmath "cosmossdk.io/math" 8 | ) 9 | 10 | func StrToSDKInt(s string) (sdkmath.Int, error) { 11 | s, _, _ = strings.Cut(s, ".") 12 | i, ok := sdkmath.NewIntFromString(s) 13 | if !ok { 14 | return sdkmath.Int{}, fmt.Errorf("s: %s", s) 15 | } 16 | return i, nil 17 | } 18 | -------------------------------------------------------------------------------- /tests/interchain/delegator/bank_test.go: -------------------------------------------------------------------------------- 1 | package delegator_test 2 | 3 | import ( 4 | "testing" 5 | 6 | sdkmath "cosmossdk.io/math" 7 | "github.com/cosmos/gaia/v25/tests/interchain/chainsuite" 8 | "github.com/cosmos/gaia/v25/tests/interchain/delegator" 9 | "github.com/stretchr/testify/suite" 10 | ) 11 | 12 | type BankSuite struct { 13 | *delegator.Suite 14 | } 15 | 16 | func (s *BankSuite) TestSend() { 17 | balanceBefore, err := s.Chain.GetBalance(s.GetContext(), s.DelegatorWallet2.FormattedAddress(), s.Chain.Config().Denom) 18 | s.Require().NoError(err) 19 | 20 | _, err = s.Chain.GetNode().ExecTx( 21 | s.GetContext(), 22 | s.DelegatorWallet.FormattedAddress(), 23 | "bank", "send", 24 | s.DelegatorWallet.FormattedAddress(), s.DelegatorWallet2.FormattedAddress(), txAmountUatom(), 25 | ) 26 | s.Require().NoError(err) 27 | 28 | balanceAfter, err := s.Chain.GetBalance(s.GetContext(), s.DelegatorWallet2.FormattedAddress(), s.Chain.Config().Denom) 29 | s.Require().NoError(err) 30 | s.Require().Equal(balanceBefore.Add(sdkmath.NewInt(txAmount)), balanceAfter) 31 | } 32 | 33 | func TestBank(t *testing.T) { 34 | s := &BankSuite{Suite: &delegator.Suite{Suite: chainsuite.NewSuite(chainsuite.SuiteConfig{ 35 | UpgradeOnSetup: true, 36 | })}} 37 | suite.Run(t, s) 38 | } 39 | -------------------------------------------------------------------------------- /tests/interchain/delegator/staking_test.go: -------------------------------------------------------------------------------- 1 | package delegator_test 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | 7 | "github.com/cosmos/gaia/v25/tests/interchain/chainsuite" 8 | "github.com/cosmos/gaia/v25/tests/interchain/delegator" 9 | "github.com/stretchr/testify/suite" 10 | ) 11 | 12 | type StakingSuite struct { 13 | *delegator.Suite 14 | } 15 | 16 | func (s *StakingSuite) TestDelegateWithdrawUnbond() { 17 | // delegate tokens 18 | _, err := s.Chain.GetNode().ExecTx( 19 | s.GetContext(), 20 | s.DelegatorWallet.FormattedAddress(), 21 | "staking", "delegate", s.Chain.ValidatorWallets[0].ValoperAddress, txAmountUatom(), 22 | ) 23 | s.Require().NoError(err) 24 | 25 | startingBalance, err := s.Chain.GetBalance(s.GetContext(), s.DelegatorWallet.FormattedAddress(), chainsuite.Uatom) 26 | s.Require().NoError(err) 27 | time.Sleep(20 * time.Second) 28 | // Withdraw rewards 29 | _, err = s.Chain.GetNode().ExecTx( 30 | s.GetContext(), 31 | s.DelegatorWallet.FormattedAddress(), 32 | "distribution", "withdraw-rewards", s.Chain.ValidatorWallets[0].ValoperAddress, 33 | ) 34 | s.Require().NoError(err) 35 | endingBalance, err := s.Chain.GetBalance(s.GetContext(), s.DelegatorWallet.FormattedAddress(), chainsuite.Uatom) 36 | s.Require().NoError(err) 37 | s.Require().Truef(endingBalance.GT(startingBalance), "endingBalance: %s, startingBalance: %s", endingBalance, startingBalance) 38 | 39 | // Unbond tokens 40 | _, err = s.Chain.GetNode().ExecTx( 41 | s.GetContext(), 42 | s.DelegatorWallet.FormattedAddress(), 43 | "staking", "unbond", s.Chain.ValidatorWallets[0].ValoperAddress, txAmountUatom(), 44 | ) 45 | s.Require().NoError(err) 46 | } 47 | 48 | func TestStaking(t *testing.T) { 49 | s := &StakingSuite{Suite: &delegator.Suite{Suite: chainsuite.NewSuite(chainsuite.SuiteConfig{ 50 | UpgradeOnSetup: true, 51 | })}} 52 | suite.Run(t, s) 53 | } 54 | -------------------------------------------------------------------------------- /tests/interchain/delegator/suite.go: -------------------------------------------------------------------------------- 1 | package delegator 2 | 3 | import ( 4 | sdkmath "cosmossdk.io/math" 5 | "github.com/cosmos/gaia/v25/tests/interchain/chainsuite" 6 | "github.com/strangelove-ventures/interchaintest/v8" 7 | "github.com/strangelove-ventures/interchaintest/v8/ibc" 8 | ) 9 | 10 | // Suite is a common base suite for all delegator tests. 11 | type Suite struct { 12 | *chainsuite.Suite 13 | DelegatorWallet ibc.Wallet 14 | DelegatorWallet2 ibc.Wallet 15 | DelegatorWallet3 ibc.Wallet 16 | } 17 | 18 | func (s *Suite) SetupSuite() { 19 | s.Suite.SetupSuite() 20 | wallet, err := s.Chain.BuildWallet(s.GetContext(), "delegator", "") 21 | s.Require().NoError(err) 22 | s.DelegatorWallet = wallet 23 | s.Require().NoError(s.Chain.SendFunds(s.GetContext(), interchaintest.FaucetAccountKeyName, ibc.WalletAmount{ 24 | Address: s.DelegatorWallet.FormattedAddress(), 25 | Amount: sdkmath.NewInt(100_000_000_000), 26 | Denom: s.Chain.Config().Denom, 27 | })) 28 | 29 | wallet, err = s.Chain.BuildWallet(s.GetContext(), "delegator2", "") 30 | s.Require().NoError(err) 31 | s.DelegatorWallet2 = wallet 32 | 33 | wallet, err = s.Chain.BuildWallet(s.GetContext(), "delegator3", "") 34 | s.Require().NoError(err) 35 | s.DelegatorWallet3 = wallet 36 | 37 | s.Require().NoError(s.Chain.SendFunds(s.GetContext(), interchaintest.FaucetAccountKeyName, ibc.WalletAmount{ 38 | Address: s.DelegatorWallet2.FormattedAddress(), 39 | Amount: sdkmath.NewInt(100_000_000_000), 40 | Denom: s.Chain.Config().Denom, 41 | })) 42 | 43 | s.Require().NoError(s.Chain.SendFunds(s.GetContext(), interchaintest.FaucetAccountKeyName, ibc.WalletAmount{ 44 | Address: s.DelegatorWallet3.FormattedAddress(), 45 | Amount: sdkmath.NewInt(100_000_000_000), 46 | Denom: s.Chain.Config().Denom, 47 | })) 48 | } 49 | -------------------------------------------------------------------------------- /tests/interchain/delegator/testdata/contract.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmos/gaia/558be6323bc9b9966242069d8b9fe02c37f32848/tests/interchain/delegator/testdata/contract.wasm -------------------------------------------------------------------------------- /tests/interchain/validator/unbond_test.go: -------------------------------------------------------------------------------- 1 | package validator_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/strangelove-ventures/interchaintest/v8" 7 | "github.com/stretchr/testify/suite" 8 | 9 | "github.com/cosmos/gaia/v25/tests/interchain/chainsuite" 10 | 11 | stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" 12 | ) 13 | 14 | type UnbondingSuite struct { 15 | *chainsuite.Suite 16 | } 17 | 18 | func (s *UnbondingSuite) TestUnbondValidator() { 19 | _, err := s.Chain.Validators[5].ExecTx( 20 | s.GetContext(), 21 | s.Chain.ValidatorWallets[5].Moniker, 22 | "staking", "unbond-validator", 23 | ) 24 | s.Require().NoError(err) 25 | validator, err := s.Chain.StakingQueryValidator(s.GetContext(), s.Chain.ValidatorWallets[5].ValoperAddress) 26 | s.Require().NoError(err) 27 | s.Require().Equal(stakingtypes.Unbonding, validator.Status) 28 | 29 | _, err = s.Chain.Validators[5].ExecTx( 30 | s.GetContext(), 31 | s.Chain.ValidatorWallets[5].Moniker, 32 | "slashing", "unjail", 33 | ) 34 | s.Require().NoError(err) 35 | 36 | validator, err = s.Chain.StakingQueryValidator(s.GetContext(), s.Chain.ValidatorWallets[5].ValoperAddress) 37 | s.Require().NoError(err) 38 | s.Require().Equal(stakingtypes.Bonded, validator.Status) 39 | } 40 | 41 | func TestUnbonding(t *testing.T) { 42 | txSuite := UnbondingSuite{chainsuite.NewSuite(chainsuite.SuiteConfig{ 43 | UpgradeOnSetup: true, 44 | ChainSpec: &interchaintest.ChainSpec{ 45 | NumValidators: &chainsuite.SixValidators, 46 | }, 47 | })} 48 | suite.Run(t, &txSuite) 49 | } 50 | -------------------------------------------------------------------------------- /tools/tools.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | // +build tools 3 | 4 | // This is the canonical way to enforce dependency inclusion in go.mod for tools that are not directly involved in the build process. 5 | // See 6 | // https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module 7 | 8 | package tools 9 | 10 | //nolint 11 | 12 | import ( 13 | _ "github.com/vektra/mockery/v2" 14 | ) 15 | -------------------------------------------------------------------------------- /types/constants.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | const UAtomDenom string = "uatom" 4 | -------------------------------------------------------------------------------- /x/liquid/keeper/abci.go: -------------------------------------------------------------------------------- 1 | package keeper 2 | 3 | import ( 4 | "context" 5 | 6 | sdk "github.com/cosmos/cosmos-sdk/types" 7 | ) 8 | 9 | // BeginBlocker removes expired tokenize share locks 10 | func (k *Keeper) BeginBlocker(ctx context.Context) error { 11 | sdkCtx := sdk.UnwrapSDKContext(ctx) 12 | _, err := k.RemoveExpiredTokenizeShareLocks(ctx, sdkCtx.BlockTime()) 13 | return err 14 | } 15 | -------------------------------------------------------------------------------- /x/liquid/keeper/grpc_query_test.go: -------------------------------------------------------------------------------- 1 | package keeper_test 2 | 3 | import ( 4 | gocontext "context" 5 | "fmt" 6 | 7 | "cosmossdk.io/math" 8 | 9 | sdk "github.com/cosmos/cosmos-sdk/types" 10 | 11 | "github.com/cosmos/gaia/v25/x/liquid/types" 12 | ) 13 | 14 | func (s *KeeperTestSuite) TestGRPCQueryLiquidValidator() { 15 | ctx, keeper, queryClient := s.ctx, s.lsmKeeper, s.queryClient 16 | require := s.Require() 17 | 18 | lVal := types.NewLiquidValidator(sdk.ValAddress(PKs[0].Address().Bytes()).String()) 19 | lVal.LiquidShares = math.LegacyNewDec(10000) 20 | require.NoError(keeper.SetLiquidValidator(ctx, lVal)) 21 | var req *types.QueryLiquidValidatorRequest 22 | testCases := []struct { 23 | msg string 24 | malleate func() 25 | expPass bool 26 | }{ 27 | { 28 | "empty request", 29 | func() { 30 | req = &types.QueryLiquidValidatorRequest{} 31 | }, 32 | false, 33 | }, 34 | { 35 | "nil request", 36 | func() { 37 | req = nil 38 | }, 39 | false, 40 | }, 41 | { 42 | "with valid and not existing address", 43 | func() { 44 | req = &types.QueryLiquidValidatorRequest{ 45 | ValidatorAddr: "cosmosvaloper15jkng8hytwt22lllv6mw4k89qkqehtahd84ptu", 46 | } 47 | }, 48 | false, 49 | }, 50 | { 51 | "valid request", 52 | func() { 53 | req = &types.QueryLiquidValidatorRequest{ValidatorAddr: lVal.OperatorAddress} 54 | }, 55 | true, 56 | }, 57 | } 58 | 59 | for _, tc := range testCases { 60 | s.Run(fmt.Sprintf("Case %s", tc.msg), func() { 61 | tc.malleate() 62 | res, err := queryClient.LiquidValidator(gocontext.Background(), req) 63 | if tc.expPass { 64 | require.NoError(err) 65 | require.Equal(lVal.OperatorAddress, res.LiquidValidator.OperatorAddress) 66 | require.Equal(lVal.LiquidShares, res.LiquidValidator.LiquidShares) 67 | } else { 68 | require.Error(err) 69 | require.Nil(res) 70 | } 71 | }) 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /x/liquid/keeper/keeper.go: -------------------------------------------------------------------------------- 1 | package keeper 2 | 3 | import ( 4 | "context" 5 | 6 | storetypes "cosmossdk.io/core/store" 7 | "cosmossdk.io/log" 8 | 9 | "github.com/cosmos/cosmos-sdk/codec" 10 | sdk "github.com/cosmos/cosmos-sdk/types" 11 | 12 | "github.com/cosmos/gaia/v25/x/liquid/types" 13 | ) 14 | 15 | // Keeper of the x/liquid store 16 | type Keeper struct { 17 | storeService storetypes.KVStoreService 18 | cdc codec.BinaryCodec 19 | authKeeper types.AccountKeeper 20 | bankKeeper types.BankKeeper 21 | stakingKeeper types.StakingKeeper 22 | distKeeper types.DistributionKeeper 23 | authority string 24 | } 25 | 26 | // NewKeeper creates a new liquid Keeper instance 27 | func NewKeeper( 28 | cdc codec.BinaryCodec, 29 | storeService storetypes.KVStoreService, 30 | ak types.AccountKeeper, 31 | bk types.BankKeeper, 32 | sk types.StakingKeeper, 33 | dk types.DistributionKeeper, 34 | authority string, 35 | ) *Keeper { 36 | // ensure that authority is a valid AccAddress 37 | if _, err := ak.AddressCodec().StringToBytes(authority); err != nil { 38 | panic("authority is not a valid acc address") 39 | } 40 | 41 | return &Keeper{ 42 | storeService: storeService, 43 | cdc: cdc, 44 | authKeeper: ak, 45 | bankKeeper: bk, 46 | stakingKeeper: sk, 47 | distKeeper: dk, 48 | authority: authority, 49 | } 50 | } 51 | 52 | // Logger returns a module-specific logger. 53 | func (k Keeper) Logger(ctx context.Context) log.Logger { 54 | sdkCtx := sdk.UnwrapSDKContext(ctx) 55 | return sdkCtx.Logger().With("module", "x/"+types.ModuleName) 56 | } 57 | 58 | // GetAuthority returns the x/liquid module's authority. 59 | func (k Keeper) GetAuthority() string { 60 | return k.authority 61 | } 62 | -------------------------------------------------------------------------------- /x/liquid/keeper/params.go: -------------------------------------------------------------------------------- 1 | package keeper 2 | 3 | import ( 4 | "context" 5 | 6 | "cosmossdk.io/math" 7 | 8 | "github.com/cosmos/gaia/v25/x/liquid/types" 9 | ) 10 | 11 | // SetParams sets the x/liquid module parameters. 12 | // CONTRACT: This method performs no validation of the parameters. 13 | func (k Keeper) SetParams(ctx context.Context, params types.Params) error { 14 | store := k.storeService.OpenKVStore(ctx) 15 | bz, err := k.cdc.Marshal(¶ms) 16 | if err != nil { 17 | return err 18 | } 19 | return store.Set(types.ParamsKey, bz) 20 | } 21 | 22 | // GetParams gets the x/liquid module parameters. 23 | func (k Keeper) GetParams(ctx context.Context) (params types.Params, err error) { 24 | store := k.storeService.OpenKVStore(ctx) 25 | bz, err := store.Get(types.ParamsKey) 26 | if err != nil { 27 | return params, err 28 | } 29 | 30 | if bz == nil { 31 | return types.DefaultParams(), nil 32 | } 33 | 34 | err = k.cdc.Unmarshal(bz, ¶ms) 35 | return params, err 36 | } 37 | 38 | // Global liquid staking cap across all liquid staking providers 39 | func (k Keeper) GlobalLiquidStakingCap(ctx context.Context) (math.LegacyDec, error) { 40 | params, err := k.GetParams(ctx) 41 | return params.GlobalLiquidStakingCap, err 42 | } 43 | 44 | // Liquid staking cap for each validator 45 | func (k Keeper) ValidatorLiquidStakingCap(ctx context.Context) (math.LegacyDec, error) { 46 | params, err := k.GetParams(ctx) 47 | return params.ValidatorLiquidStakingCap, err 48 | } 49 | -------------------------------------------------------------------------------- /x/liquid/types/events.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | // liquid module event types 4 | const ( 5 | EventTypeTokenizeShares = "tokenize_shares" 6 | EventTypeRedeemShares = "redeem_shares" 7 | EventTypeTransferTokenizeShareRecord = "transfer_tokenize_share_record" 8 | EventTypeWithdrawTokenizeShareReward = "withdraw_tokenize_share_reward" 9 | 10 | AttributeKeyValidator = "validator" 11 | AttributeKeyDelegator = "delegator" 12 | AttributeKeyShareOwner = "share_owner" 13 | AttributeKeyShareRecordID = "share_record_id" 14 | AttributeKeyAmount = "amount" 15 | AttributeKeyTokenizedShares = "tokenized_shares" 16 | AttributeKeyWithdrawAddress = "withdraw_address" 17 | ) 18 | -------------------------------------------------------------------------------- /x/liquid/types/genesis.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import "cosmossdk.io/math" 4 | 5 | func NewGenesisState( 6 | params Params, 7 | tsr []TokenizeShareRecord, 8 | recordID uint64, 9 | liquidStakeTokens math.Int, 10 | locks []TokenizeShareLock, 11 | ) *GenesisState { 12 | return &GenesisState{ 13 | Params: params, 14 | TokenizeShareRecords: tsr, 15 | LastTokenizeShareRecordId: recordID, 16 | TotalLiquidStakedTokens: liquidStakeTokens, 17 | TokenizeShareLocks: locks, 18 | } 19 | } 20 | 21 | func DefaultGenesisState() *GenesisState { 22 | return &GenesisState{ 23 | Params: DefaultParams(), 24 | } 25 | } 26 | 27 | func ValidateGenesis(gs *GenesisState) error { 28 | return gs.Params.Validate() 29 | } 30 | -------------------------------------------------------------------------------- /x/liquid/types/liquid_validator.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "cosmossdk.io/math" 5 | 6 | "github.com/cosmos/cosmos-sdk/codec" 7 | ) 8 | 9 | // NewLiquidValidator constructs a new LiquidValidator 10 | func NewLiquidValidator(operator string) LiquidValidator { 11 | return LiquidValidator{ 12 | OperatorAddress: operator, 13 | LiquidShares: math.LegacyZeroDec(), 14 | } 15 | } 16 | 17 | func MustMarshalValidator(cdc codec.BinaryCodec, validator *LiquidValidator) []byte { 18 | return cdc.MustMarshal(validator) 19 | } 20 | 21 | // unmarshal from a store value 22 | func UnmarshalValidator(cdc codec.BinaryCodec, value []byte) (v LiquidValidator, err error) { 23 | err = cdc.Unmarshal(value, &v) 24 | return v, err 25 | } 26 | -------------------------------------------------------------------------------- /x/liquid/types/msg.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | sdk "github.com/cosmos/cosmos-sdk/types" 5 | ) 6 | 7 | var ( 8 | _ sdk.Msg = (*MsgWithdrawTokenizeShareRecordReward)(nil) 9 | _ sdk.Msg = (*MsgWithdrawAllTokenizeShareRecordReward)(nil) 10 | ) 11 | 12 | func NewMsgWithdrawTokenizeShareRecordReward(ownerAddr string, recordID uint64) *MsgWithdrawTokenizeShareRecordReward { 13 | return &MsgWithdrawTokenizeShareRecordReward{ 14 | OwnerAddress: ownerAddr, 15 | RecordId: recordID, 16 | } 17 | } 18 | 19 | func NewMsgWithdrawAllTokenizeShareRecordReward(ownerAddr string) *MsgWithdrawAllTokenizeShareRecordReward { 20 | return &MsgWithdrawAllTokenizeShareRecordReward{ 21 | OwnerAddress: ownerAddr, 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /x/liquid/types/tokenize_share_record.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | "strings" 7 | 8 | sdk "github.com/cosmos/cosmos-sdk/types" 9 | "github.com/cosmos/cosmos-sdk/types/address" 10 | ) 11 | 12 | func (r TokenizeShareRecord) GetModuleAddress() sdk.AccAddress { 13 | // NOTE: The module name is intentionally hard coded so that, if this 14 | // function were to move to a different module in future SDK version, 15 | // it would not break all the address lookups 16 | moduleName := "lsm" 17 | return address.Module(moduleName, []byte(r.ModuleAccount)) 18 | } 19 | 20 | func (r TokenizeShareRecord) GetShareTokenDenom() string { 21 | return fmt.Sprintf("%s/%s", strings.ToLower(r.Validator), strconv.FormatUint(r.Id, 10)) 22 | } 23 | -------------------------------------------------------------------------------- /x/metaprotocols/types/codec.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "github.com/cosmos/cosmos-sdk/codec/types" 5 | tx "github.com/cosmos/cosmos-sdk/types/tx" 6 | "github.com/cosmos/cosmos-sdk/x/authz" 7 | ) 8 | 9 | // RegisterInterfaces adds the x/metaprotocols module's interfaces to the provided InterfaceRegistry 10 | // The ExtendedData interface is registered so that the TxExtensionOptionsI can be properly encoded and decoded 11 | func RegisterInterfaces(registry types.InterfaceRegistry) { 12 | registry.RegisterImplementations( 13 | (*tx.TxExtensionOptionI)(nil), 14 | &ExtensionData{}, 15 | // needs to be registered to allow parsing of historic data stored in TxExtensionOptions 16 | // the app does not interact with this message in any way but it performs an unmarshal which must not fail 17 | &authz.MsgRevoke{}, 18 | ) 19 | } 20 | -------------------------------------------------------------------------------- /x/metaprotocols/types/keys.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | const ( 4 | ModuleName = "metaprotocols" 5 | ) 6 | --------------------------------------------------------------------------------