chore: rm tools/hubl (#23562)
This commit is contained in:
parent
97c61cfb24
commit
b87acd2cc0
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
@ -35,7 +35,6 @@
|
||||
/store/ @cosmos/sdk-core-dev
|
||||
/store/v2/ @cosmos/sdk-core-dev
|
||||
/types/mempool/ @cosmos/sdk-core-dev
|
||||
/tools/hubl @julienrbrt @JulianToledano @cosmos/sdk-core-dev
|
||||
/tools/cosmovisor @julienrbrt @cosmos/sdk-core-dev
|
||||
/tools/confix @julienrbrt @cosmos/sdk-core-dev
|
||||
/tests/integration/aminojson @cosmos/sdk-core-dev
|
||||
|
||||
9
.github/dependabot.yml
vendored
9
.github/dependabot.yml
vendored
@ -160,15 +160,6 @@ updates:
|
||||
labels:
|
||||
- "A:automerge"
|
||||
- dependencies
|
||||
- package-ecosystem: gomod
|
||||
directory: "/tools/hubl"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: thursday
|
||||
time: "02:15"
|
||||
labels:
|
||||
- "A:automerge"
|
||||
- dependencies
|
||||
- package-ecosystem: gomod
|
||||
directory: "/collections"
|
||||
schedule:
|
||||
|
||||
2
.github/pr_labeler.yml
vendored
2
.github/pr_labeler.yml
vendored
@ -5,8 +5,6 @@
|
||||
- tools/confix/**/*
|
||||
"C:Cosmovisor":
|
||||
- tools/cosmovisor/**/*
|
||||
"C:Hubl":
|
||||
- tools/hubl/**/*
|
||||
"C:Keys":
|
||||
- client/keys/**/*
|
||||
"C:Simulations":
|
||||
|
||||
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -46,5 +46,3 @@ jobs:
|
||||
run: GOARCH=${{ matrix.go-arch }} make cosmovisor
|
||||
- name: Build Confix
|
||||
run: GOARCH=${{ matrix.go-arch }} make confix
|
||||
- name: Build Hubl
|
||||
run: GOARCH=${{ matrix.go-arch }} make hubl
|
||||
|
||||
31
.github/workflows/test.yml
vendored
31
.github/workflows/test.yml
vendored
@ -630,37 +630,6 @@ jobs:
|
||||
with:
|
||||
projectBaseDir: tools/confix/
|
||||
|
||||
test-hubl:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.23"
|
||||
check-latest: true
|
||||
cache: true
|
||||
cache-dependency-path: tools/hubl/go.sum
|
||||
- uses: technote-space/get-diff-action@v6.1.2
|
||||
id: git_diff
|
||||
with:
|
||||
PATTERNS: |
|
||||
tools/hubl/**/*.go
|
||||
tools/hubl/go.mod
|
||||
tools/hubl/go.sum
|
||||
- name: tests
|
||||
if: env.GIT_DIFF
|
||||
run: |
|
||||
cd tools/hubl
|
||||
go test -mod=readonly -timeout 30m -coverprofile=coverage.out -covermode=atomic -tags='norace ledger test_ledger_mock' ./...
|
||||
- name: sonarcloud
|
||||
if: ${{ env.GIT_DIFF && !github.event.pull_request.draft && env.SONAR_TOKEN != null }}
|
||||
uses: SonarSource/sonarcloud-github-action@master
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
with:
|
||||
projectBaseDir: tools/hubl/
|
||||
|
||||
test-store:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
@ -49,6 +49,10 @@ Every module contains its own CHANGELOG.md. Please refer to the module you are i
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
### Removed
|
||||
|
||||
* (tools/hub) [#23562](https://github.com/cosmos/cosmos-sdk/pull/23562) Remove `tools/hubl`. A similar tool will be maintained in [ignite](https://www.github.com/ignite/cli).
|
||||
|
||||
### API Breaking Changes
|
||||
|
||||
* (x/params) [#22995](https://github.com/cosmos/cosmos-sdk/pull/22995) Remove `x/params`. Migrate to the new params system introduced in `v0.47` as demonstrated [here](https://github.com/cosmos/cosmos-sdk/blob/main/UPGRADING.md#xparams).
|
||||
|
||||
@ -31,7 +31,7 @@ Welcome to the Cosmos SDK's team roadmap.
|
||||
* [x] Multi-chain command **(Done)**
|
||||
* Release a cmd line tool that can be pointed a grpc endpoint which then can produce cmd lines to interact with the chain
|
||||
* [x] Auto-cli tx support
|
||||
* Tx support for auto-cli/hubl
|
||||
* Tx support for auto-cli
|
||||
* This would fully remove the need for application developers to write cli commands for their modules
|
||||
* [ ] [Consensus Key Rotation](https://github.com/cosmos/cosmos-sdk/issues/5231)
|
||||
|
||||
@ -121,9 +121,8 @@ Issue: https://github.com/cosmos/iavl/issues/548
|
||||
|
||||
### Client UX
|
||||
|
||||
* [ ] Hubl/AutoCLI
|
||||
* [ ] AutoCLI
|
||||
* Objective:
|
||||
* Allow users to sign and submit transactions using hubl
|
||||
* Add module support for autocli
|
||||
* Deprecate/remove legacy cli (optional)
|
||||
* Progress:
|
||||
|
||||
@ -1236,8 +1236,6 @@ For example, assuming you put all your proto files in subfolders inside your roo
|
||||
|
||||
If you are using a custom folder structure for your proto files, please reorganize them so that their OS path matches their proto package name.
|
||||
|
||||
This is to allow the proto FileDescriptSets to be correctly registered, and this standardized OS import paths allows [Hubl](https://github.com/cosmos/cosmos-sdk/tree/main/tools/hubl) to reflectively talk to any chain.
|
||||
|
||||
#### `{accepts,implements}_interface` proto annotations
|
||||
|
||||
The SDK is normalizing the strings inside the Protobuf `accepts_interface` and `implements_interface` annotations. We require them to be fully-scoped names. They will soon be used by code generators like Pulsar and Telescope to match which messages can or cannot be packed inside `Any`s.
|
||||
|
||||
@ -94,7 +94,7 @@ The keyring is then converted to the `client/v2/autocli/keyring` interface.
|
||||
If no keyring is provided, the `autocli` generated command will not be able to sign transactions, but will still be able to query the chain.
|
||||
|
||||
:::tip
|
||||
The Cosmos SDK keyring and Hubl keyring both implement the `client/v2/autocli/keyring` interface, thanks to the following wrapper:
|
||||
The Cosmos SDK keyring implements the `client/v2/autocli/keyring` interface, thanks to the following wrapper:
|
||||
|
||||
```go
|
||||
keyring.NewAutoCLIKeyring(kb)
|
||||
@ -283,10 +283,6 @@ According to the [Cobra documentation](https://pkg.go.dev/github.com/spf13/cobra
|
||||
|
||||
`autocli` lets you generate CLI to your Cosmos SDK-based applications without any cobra boilerplate. It allows you to easily generate CLI commands and flags from your protobuf messages, and provides many options for customising the behavior of your CLI application.
|
||||
|
||||
To further enhance your CLI experience with Cosmos SDK-based blockchains, you can use `hubl`. `hubl` is a tool that allows you to query any Cosmos SDK-based blockchain using the new AutoCLI feature of the Cosmos SDK. With `hubl`, you can easily configure a new chain and query modules with just a few simple commands.
|
||||
|
||||
For more information on `hubl`, including how to configure a new chain and query a module, see the [Hubl documentation](https://docs.cosmos.network/main/build/tooling/hubl).
|
||||
|
||||
# Off-Chain
|
||||
|
||||
Off-chain is a `client/v2` package providing functionalities for allowing to sign and verify files with two commands:
|
||||
|
||||
1
docs/.gitignore
vendored
1
docs/.gitignore
vendored
@ -4,7 +4,6 @@ docs/architecture
|
||||
docs/rfc
|
||||
docs/tooling/01-cosmovisor.md
|
||||
docs/tooling/02-confix.md
|
||||
docs/tooling/03-hubl.md
|
||||
docs/core/17-autocli.md
|
||||
docs/packages/01-depinject.md
|
||||
docs/packages/02-collections.md
|
||||
|
||||
1
docs/build/tooling/README.md
vendored
1
docs/build/tooling/README.md
vendored
@ -11,7 +11,6 @@ This includes tools for development, operating a node, and ease of use of a Cosm
|
||||
|
||||
* [Cosmovisor](./01-cosmovisor.md)
|
||||
* [Confix](./02-confix.md)
|
||||
* [Hubl](./03-hubl.md)
|
||||
* [Rosetta](https://docs.cosmos.network/main/run-node/rosetta)
|
||||
|
||||
## Other Tools
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
find build/modules ! -name '_category_.json' -type f -exec rm -rf {} +
|
||||
rm -rf build/tooling/01-cosmovisor.md
|
||||
rm -rf build/tooling/02-confix.md
|
||||
rm -rf build/tooling/03-hubl.md
|
||||
rm -rf build/packages/01-depinject.md
|
||||
rm -rf build/packages/02-collections.md
|
||||
rm -rf build/packages/03-orm.md
|
||||
|
||||
@ -28,7 +28,6 @@ cat ../x/README.md | sed 's/\.\.\/\/build\/building-modules\/README\.md/\/buildi
|
||||
## Add tooling documentation
|
||||
cp ../tools/cosmovisor/README.md ./build/tooling/01-cosmovisor.md
|
||||
cp ../tools/confix/README.md ./build/tooling/02-confix.md
|
||||
cp ../tools/hubl/README.md ./build/tooling/03-hubl.md
|
||||
|
||||
## Add package documentation
|
||||
cp ../client/v2/README.md ./learn/advanced/17-autocli.md
|
||||
|
||||
@ -25,7 +25,6 @@ use (
|
||||
./runtime/v2
|
||||
./tools/cosmovisor
|
||||
./tools/confix
|
||||
./tools/hubl
|
||||
./tools/benchmark
|
||||
./x/accounts
|
||||
./x/accounts/defaults/base
|
||||
|
||||
@ -149,10 +149,6 @@ cosmovisor:
|
||||
confix:
|
||||
$(MAKE) -C tools/confix confix
|
||||
|
||||
#? hubl: Build hubl
|
||||
hubl:
|
||||
$(MAKE) -C tools/hubl hubl
|
||||
|
||||
.PHONY: build build-linux-amd64 build-linux-arm64 cosmovisor confix
|
||||
|
||||
#? mocks: Generate mock file
|
||||
|
||||
1
tools/hubl/.gitignore
vendored
1
tools/hubl/.gitignore
vendored
@ -1 +0,0 @@
|
||||
/hubl
|
||||
@ -1,32 +0,0 @@
|
||||
<!--
|
||||
Guiding Principles:
|
||||
|
||||
Changelogs are for humans, not machines.
|
||||
There should be an entry for every single version.
|
||||
The same types of changes should be grouped.
|
||||
Versions and sections should be linkable.
|
||||
The latest version comes first.
|
||||
The release date of each version is displayed.
|
||||
Mention whether you follow Semantic Versioning.
|
||||
|
||||
Usage:
|
||||
|
||||
Change log entries are to be added to the Unreleased section under the
|
||||
appropriate stanza (see below). Each entry should ideally include a tag and
|
||||
the Github issue reference in the following format:
|
||||
|
||||
* (<tag>) [#<issue-number>] Changelog message.
|
||||
|
||||
Types of changes (Stanzas):
|
||||
|
||||
"Features" for new features.
|
||||
"Improvements" for changes in existing functionality.
|
||||
"Deprecated" for soon-to-be removed features.
|
||||
"Bug Fixes" for any bug fixes.
|
||||
"API Breaking" for breaking exported APIs used by developers building on SDK.
|
||||
Ref: https://keepachangelog.com/en/1.0.0/
|
||||
-->
|
||||
|
||||
# Changelog
|
||||
|
||||
## [Unreleased]
|
||||
@ -1,12 +0,0 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
all: hubl test
|
||||
|
||||
hubl:
|
||||
go build -mod=readonly ./cmd/hubl
|
||||
@echo "hubl binary has been successfully built in tools/hubl/hubl"
|
||||
|
||||
test:
|
||||
go test -mod=readonly -race ./...
|
||||
|
||||
.PHONY: all hubl test
|
||||
@ -1,73 +0,0 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# Hubl
|
||||
|
||||
`Hubl` is a tool that allows you to query any Cosmos SDK based blockchain.
|
||||
It takes advantage of the new [AutoCLI](https://docs.cosmos.network/main/learn/advanced/autocli) feature of the Cosmos SDK.
|
||||
|
||||
## Installation
|
||||
|
||||
Hubl can be installed using `go install`:
|
||||
|
||||
```shell
|
||||
go install cosmossdk.io/tools/hubl/cmd/hubl@latest
|
||||
```
|
||||
|
||||
Or build from source:
|
||||
|
||||
```shell
|
||||
git clone --depth=1 https://github.com/cosmos/cosmos-sdk
|
||||
make hubl
|
||||
```
|
||||
|
||||
The binary will be located in `tools/hubl`.
|
||||
|
||||
## Usage
|
||||
|
||||
```shell
|
||||
hubl --help
|
||||
```
|
||||
|
||||
### Add chain
|
||||
|
||||
To configure a new chain just run this command using the --init flag and the name of the chain as it's listed in the chain registry (<https://github.com/cosmos/chain-registry>).
|
||||
|
||||
If the chain is not listed in the chain registry, you can use any unique name.
|
||||
|
||||
```shell
|
||||
hubl init [chain-name]
|
||||
hubl init regen
|
||||
```
|
||||
|
||||
The chain configuration is stored in `~/.hubl/config.toml`.
|
||||
|
||||
:::tip
|
||||
|
||||
When using an insecure gRPC endpoint, change the `insecure` field to `true` in the config file.
|
||||
|
||||
```toml
|
||||
[chains]
|
||||
[chains.regen]
|
||||
[[chains.regen.trusted-grpc-endpoints]]
|
||||
endpoint = 'localhost:9090'
|
||||
insecure = true
|
||||
```
|
||||
|
||||
Or use the `--insecure` flag:
|
||||
|
||||
```shell
|
||||
hubl init regen --insecure
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
### Query
|
||||
|
||||
To query a chain, you can use the `query` command.
|
||||
Then specify which module you want to query and the query itself.
|
||||
|
||||
```shell
|
||||
hubl regen query auth module-accounts
|
||||
```
|
||||
@ -1,16 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"cosmossdk.io/tools/hubl/internal"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cmd, err := internal.RootCommand()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err = cmd.Execute(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@ -1,165 +0,0 @@
|
||||
module cosmossdk.io/tools/hubl
|
||||
|
||||
go 1.23.0
|
||||
|
||||
require (
|
||||
cosmossdk.io/api v0.7.6
|
||||
cosmossdk.io/client/v2 v2.0.0-beta.1.0.20240118210941-3897926e722e
|
||||
cosmossdk.io/core v0.11.1
|
||||
cosmossdk.io/errors v1.0.1
|
||||
github.com/cosmos/cosmos-sdk v0.50.11
|
||||
github.com/manifoldco/promptui v0.9.0
|
||||
github.com/pelletier/go-toml/v2 v2.2.3
|
||||
github.com/spf13/cobra v1.8.1
|
||||
google.golang.org/grpc v1.70.0
|
||||
google.golang.org/protobuf v1.36.4
|
||||
)
|
||||
|
||||
require (
|
||||
cosmossdk.io/collections v0.4.0 // indirect
|
||||
cosmossdk.io/depinject v1.1.0 // indirect
|
||||
cosmossdk.io/log v1.5.0 // indirect
|
||||
cosmossdk.io/math v1.5.0 // indirect
|
||||
cosmossdk.io/store v1.1.1 // indirect
|
||||
cosmossdk.io/x/tx v1.0.0-alpha.3 // indirect
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
|
||||
github.com/99designs/keyring v1.2.2 // indirect
|
||||
github.com/DataDog/datadog-go v3.2.0+incompatible // indirect
|
||||
github.com/DataDog/zstd v1.5.6 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bgentry/speakeasy v0.2.0 // indirect
|
||||
github.com/bytedance/sonic v1.12.8 // indirect
|
||||
github.com/bytedance/sonic/loader v0.2.3 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/chzyer/readline v1.5.1 // indirect
|
||||
github.com/cloudwego/base64x v0.1.5 // indirect
|
||||
github.com/cockroachdb/apd/v3 v3.2.1 // indirect
|
||||
github.com/cockroachdb/errors v1.11.3 // indirect
|
||||
github.com/cockroachdb/fifo v0.0.0-20240816210425-c5d0cb0b6fc0 // indirect
|
||||
github.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506 // indirect
|
||||
github.com/cockroachdb/pebble v1.1.2 // indirect
|
||||
github.com/cockroachdb/redact v1.1.5 // indirect
|
||||
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
|
||||
github.com/cometbft/cometbft v0.38.15 // indirect
|
||||
github.com/cometbft/cometbft-db v0.14.1 // indirect
|
||||
github.com/cosmos/btcutil v1.0.5 // indirect
|
||||
github.com/cosmos/cosmos-db v1.1.1 // indirect
|
||||
github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect
|
||||
github.com/cosmos/go-bip39 v1.0.0 // indirect
|
||||
github.com/cosmos/gogogateway v1.2.0 // indirect
|
||||
github.com/cosmos/gogoproto v1.7.0 // indirect
|
||||
github.com/cosmos/iavl v1.2.2 // indirect
|
||||
github.com/cosmos/ics23/go v0.11.0 // indirect
|
||||
github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect
|
||||
github.com/danieljoos/wincred v1.2.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
|
||||
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect
|
||||
github.com/dgraph-io/badger/v4 v4.2.0 // indirect
|
||||
github.com/dgraph-io/ristretto v0.1.1 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/dvsekhvalnov/jose2go v1.6.0 // indirect
|
||||
github.com/emicklei/dot v1.6.2 // indirect
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.8.0 // indirect
|
||||
github.com/getsentry/sentry-go v0.30.0 // indirect
|
||||
github.com/go-kit/kit v0.13.0 // indirect
|
||||
github.com/go-kit/log v0.2.1 // indirect
|
||||
github.com/go-logfmt/logfmt v0.6.0 // indirect
|
||||
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
|
||||
github.com/gogo/googleapis v1.4.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/glog v1.2.4 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/btree v1.1.3 // indirect
|
||||
github.com/google/flatbuffers v1.12.1 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/orderedcode v0.0.1 // indirect
|
||||
github.com/gorilla/handlers v1.5.2 // indirect
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
|
||||
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
|
||||
github.com/hashicorp/go-hclog v1.6.3 // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||
github.com/hashicorp/go-metrics v0.5.4 // indirect
|
||||
github.com/hashicorp/go-plugin v1.6.2 // indirect
|
||||
github.com/hashicorp/golang-lru v1.0.2 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/hashicorp/yamux v0.1.2 // indirect
|
||||
github.com/hdevalence/ed25519consensus v0.2.0 // indirect
|
||||
github.com/huandu/skiplist v1.2.1 // indirect
|
||||
github.com/iancoleman/strcase v0.3.0 // indirect
|
||||
github.com/improbable-eng/grpc-web v0.15.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jmhodges/levigo v1.0.0 // indirect
|
||||
github.com/klauspost/compress v1.17.11 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/lib/pq v1.10.9 // indirect
|
||||
github.com/linxGnu/grocksdb v1.9.7 // indirect
|
||||
github.com/magiconair/properties v1.8.9 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/minio/highwayhash v1.0.3 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/mtibben/percent v0.2.1 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a // indirect
|
||||
github.com/oklog/run v1.1.0 // indirect
|
||||
github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/client_golang v1.20.5 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.62.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
|
||||
github.com/rogpeppe/go-internal v1.13.1 // indirect
|
||||
github.com/rs/cors v1.11.1 // indirect
|
||||
github.com/rs/zerolog v1.33.0 // indirect
|
||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
github.com/sasha-s/go-deadlock v0.3.5 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.11.0 // indirect
|
||||
github.com/spf13/cast v1.7.1 // indirect
|
||||
github.com/spf13/pflag v1.0.6 // indirect
|
||||
github.com/spf13/viper v1.19.0 // indirect
|
||||
github.com/stretchr/testify v1.10.0 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
|
||||
github.com/tendermint/go-amino v0.16.0 // indirect
|
||||
github.com/tidwall/btree v1.7.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/zondax/hid v0.9.2 // indirect
|
||||
github.com/zondax/ledger-go v0.14.3 // indirect
|
||||
go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/arch v0.13.0 // indirect
|
||||
golang.org/x/crypto v0.32.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect
|
||||
golang.org/x/net v0.34.0 // indirect
|
||||
golang.org/x/sync v0.10.0 // indirect
|
||||
golang.org/x/sys v0.29.0 // indirect
|
||||
golang.org/x/term v0.28.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241202173237-19429a94021a // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250122153221-138b5a5a4fd4 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gotest.tools/v3 v3.5.1 // indirect
|
||||
nhooyr.io/websocket v1.8.7 // indirect
|
||||
pgregory.net/rapid v1.1.0 // indirect
|
||||
sigs.k8s.io/yaml v1.4.0 // indirect
|
||||
)
|
||||
1054
tools/hubl/go.sum
1054
tools/hubl/go.sum
File diff suppressed because it is too large
Load Diff
@ -1,298 +0,0 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/reflection/grpc_reflection_v1alpha"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
"google.golang.org/protobuf/reflect/protoregistry"
|
||||
"google.golang.org/protobuf/types/descriptorpb"
|
||||
|
||||
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
|
||||
reflectionv1beta1 "cosmossdk.io/api/cosmos/base/reflection/v1beta1"
|
||||
)
|
||||
|
||||
// loadFileDescriptorsGRPCReflection attempts to load the file descriptor set using gRPC reflection when cosmos.reflection.v1
|
||||
// is unavailable.
|
||||
func loadFileDescriptorsGRPCReflection(ctx context.Context, client *grpc.ClientConn) (*descriptorpb.FileDescriptorSet, error) {
|
||||
fmt.Printf("This chain does not support cosmos.reflection.v1 yet... attempting to use a fallback. Some features may be unsupported and it may not be possible to read all data.\n")
|
||||
|
||||
var interfaceImplNames []string
|
||||
cosmosReflectBetaClient := reflectionv1beta1.NewReflectionServiceClient(client)
|
||||
interfacesRes, err := cosmosReflectBetaClient.ListAllInterfaces(ctx, &reflectionv1beta1.ListAllInterfacesRequest{})
|
||||
if err == nil {
|
||||
for _, iface := range interfacesRes.InterfaceNames {
|
||||
implRes, err := cosmosReflectBetaClient.ListImplementations(ctx, &reflectionv1beta1.ListImplementationsRequest{
|
||||
InterfaceName: iface,
|
||||
})
|
||||
if err == nil {
|
||||
interfaceImplNames = append(interfaceImplNames, implMsgNameCleanup(implRes.ImplementationMessageNames)...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reflectClient, err := grpc_reflection_v1alpha.NewServerReflectionClient(client).ServerReflectionInfo(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fdMap := map[string]*descriptorpb.FileDescriptorProto{}
|
||||
waitListServiceRes := make(chan *grpc_reflection_v1alpha.ListServiceResponse) //nolint:staticcheck // we want to use the deprecated field
|
||||
waitc := make(chan struct{})
|
||||
go func() {
|
||||
for {
|
||||
in, err := reflectClient.Recv()
|
||||
if errors.Is(err, io.EOF) {
|
||||
// read done.
|
||||
close(waitc)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
switch res := in.MessageResponse.(type) {
|
||||
case *grpc_reflection_v1alpha.ServerReflectionResponse_ErrorResponse:
|
||||
panic(res.ErrorResponse.String()) //nolint:staticcheck // we want to use the deprecated field
|
||||
case *grpc_reflection_v1alpha.ServerReflectionResponse_ListServicesResponse:
|
||||
waitListServiceRes <- res.ListServicesResponse //nolint:staticcheck // we want to use the deprecated field
|
||||
case *grpc_reflection_v1alpha.ServerReflectionResponse_FileDescriptorResponse:
|
||||
_ = processFileDescriptorsResponse(res, fdMap)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
if err = reflectClient.Send(&grpc_reflection_v1alpha.ServerReflectionRequest{ //nolint:staticcheck // we want to use the deprecated field
|
||||
MessageRequest: &grpc_reflection_v1alpha.ServerReflectionRequest_ListServices{},
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
listServiceRes := <-waitListServiceRes
|
||||
|
||||
for _, response := range listServiceRes.Service { //nolint:staticcheck // we want to use the deprecated field
|
||||
err = reflectClient.Send(&grpc_reflection_v1alpha.ServerReflectionRequest{ //nolint:staticcheck // we want to use the deprecated field
|
||||
MessageRequest: &grpc_reflection_v1alpha.ServerReflectionRequest_FileContainingSymbol{
|
||||
FileContainingSymbol: response.Name, //nolint:staticcheck // we want to use the deprecated field
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
for _, msgName := range interfaceImplNames {
|
||||
err = reflectClient.Send(&grpc_reflection_v1alpha.ServerReflectionRequest{ //nolint:staticcheck // we want to use the deprecated field
|
||||
MessageRequest: &grpc_reflection_v1alpha.ServerReflectionRequest_FileContainingSymbol{
|
||||
FileContainingSymbol: msgName,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err = reflectClient.CloseSend(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
<-waitc
|
||||
|
||||
// we loop through all the file descriptor dependencies to capture any file descriptors we haven't loaded yet
|
||||
cantFind := map[string]bool{}
|
||||
for {
|
||||
missing := missingFileDescriptors(fdMap, cantFind)
|
||||
if len(missing) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
err = addMissingFileDescriptors(ctx, client, fdMap, missing)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// mark all deps that we aren't able to resolve as can't find, so we don't keep looping and get a 429 error
|
||||
for _, dep := range missing {
|
||||
if fdMap[dep] == nil {
|
||||
cantFind[dep] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for dep := range cantFind {
|
||||
fmt.Printf("Warning: can't find %s.\n", dep)
|
||||
}
|
||||
|
||||
fdSet := &descriptorpb.FileDescriptorSet{}
|
||||
for _, descriptorProto := range fdMap {
|
||||
fdSet.File = append(fdSet.File, descriptorProto)
|
||||
}
|
||||
|
||||
return fdSet, nil
|
||||
}
|
||||
|
||||
func processFileDescriptorsResponse(res *grpc_reflection_v1alpha.ServerReflectionResponse_FileDescriptorResponse, fdMap map[string]*descriptorpb.FileDescriptorProto) error {
|
||||
for _, bz := range res.FileDescriptorResponse.FileDescriptorProto { //nolint:staticcheck // we want to use the deprecated field
|
||||
fd := &descriptorpb.FileDescriptorProto{}
|
||||
err := proto.Unmarshal(bz, fd)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error unmarshalling file descriptor: %w", err)
|
||||
}
|
||||
|
||||
fdMap[fd.GetName()] = fd
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func missingFileDescriptors(fdMap map[string]*descriptorpb.FileDescriptorProto, cantFind map[string]bool) []string {
|
||||
var missing []string
|
||||
for _, descriptorProto := range fdMap {
|
||||
for _, dep := range descriptorProto.Dependency {
|
||||
if fdMap[dep] == nil && !cantFind[dep] /* skip deps we've marked as can't find */ {
|
||||
missing = append(missing, dep)
|
||||
}
|
||||
}
|
||||
}
|
||||
return missing
|
||||
}
|
||||
|
||||
func addMissingFileDescriptors(ctx context.Context, client *grpc.ClientConn, fdMap map[string]*descriptorpb.FileDescriptorProto, missingFiles []string) error {
|
||||
reflectClient, err := grpc_reflection_v1alpha.NewServerReflectionClient(client).ServerReflectionInfo(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
waitc := make(chan struct{})
|
||||
go func() {
|
||||
for {
|
||||
in, err := reflectClient.Recv()
|
||||
if errors.Is(err, io.EOF) {
|
||||
// read done.
|
||||
close(waitc)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if res, ok := in.MessageResponse.(*grpc_reflection_v1alpha.ServerReflectionResponse_FileDescriptorResponse); ok {
|
||||
_ = processFileDescriptorsResponse(res, fdMap)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
for _, file := range missingFiles {
|
||||
err = reflectClient.Send(&grpc_reflection_v1alpha.ServerReflectionRequest{ //nolint:staticcheck // we want to use the deprecated field
|
||||
MessageRequest: &grpc_reflection_v1alpha.ServerReflectionRequest_FileByFilename{
|
||||
FileByFilename: file,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = reflectClient.CloseSend()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
<-waitc
|
||||
return nil
|
||||
}
|
||||
|
||||
func guessAutocli(files *protoregistry.Files) *autocliv1.AppOptionsResponse {
|
||||
fmt.Printf("This chain does not support autocli directly yet. Using some default mappings in the meantime to support a subset of the available services.\n")
|
||||
res := map[string]*autocliv1.ModuleOptions{}
|
||||
files.RangeFiles(func(descriptor protoreflect.FileDescriptor) bool {
|
||||
services := descriptor.Services()
|
||||
n := services.Len()
|
||||
for i := 0; i < n; i++ {
|
||||
service := services.Get(i)
|
||||
serviceName := service.FullName()
|
||||
mapping, ok := defaultAutocliMappings[serviceName]
|
||||
if ok {
|
||||
parts := strings.Split(mapping, " ")
|
||||
numParts := len(parts)
|
||||
if numParts < 2 || numParts > 3 {
|
||||
fmt.Printf("Warning: bad mapping %q found for %q\n", mapping, serviceName)
|
||||
continue
|
||||
}
|
||||
|
||||
modOpts := res[parts[0]]
|
||||
if modOpts == nil {
|
||||
modOpts = &autocliv1.ModuleOptions{}
|
||||
res[parts[0]] = modOpts
|
||||
}
|
||||
|
||||
switch parts[1] {
|
||||
case "query":
|
||||
if modOpts.Query == nil {
|
||||
modOpts.Query = &autocliv1.ServiceCommandDescriptor{
|
||||
SubCommands: map[string]*autocliv1.ServiceCommandDescriptor{},
|
||||
}
|
||||
}
|
||||
if numParts == 3 {
|
||||
modOpts.Query.SubCommands[parts[2]] = &autocliv1.ServiceCommandDescriptor{Service: string(serviceName)}
|
||||
} else {
|
||||
modOpts.Query.Service = string(serviceName)
|
||||
}
|
||||
case "tx":
|
||||
if modOpts.Tx == nil {
|
||||
modOpts.Tx = &autocliv1.ServiceCommandDescriptor{
|
||||
SubCommands: map[string]*autocliv1.ServiceCommandDescriptor{},
|
||||
}
|
||||
}
|
||||
if numParts == 3 {
|
||||
modOpts.Tx.SubCommands[parts[2]] = &autocliv1.ServiceCommandDescriptor{Service: string(serviceName)}
|
||||
} else {
|
||||
modOpts.Tx.Service = string(serviceName)
|
||||
}
|
||||
default:
|
||||
fmt.Printf("Warning: bad mapping %q found for %q\n", mapping, serviceName)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
return &autocliv1.AppOptionsResponse{ModuleOptions: res}
|
||||
}
|
||||
|
||||
// Removes the first character "/" from the received name
|
||||
func implMsgNameCleanup(implMessages []string) (cleanImplMessages []string) {
|
||||
for _, implMessage := range implMessages {
|
||||
if len(implMessage) >= 1 && implMessage[0] == '/' {
|
||||
cleanImplMessages = append(cleanImplMessages, implMessage[1:])
|
||||
} else {
|
||||
cleanImplMessages = append(cleanImplMessages, implMessage)
|
||||
}
|
||||
}
|
||||
|
||||
return cleanImplMessages
|
||||
}
|
||||
|
||||
var defaultAutocliMappings = map[protoreflect.FullName]string{
|
||||
"cosmos.auth.v1beta1.Query": "auth query",
|
||||
"cosmos.authz.v1beta1.Query": "authz query",
|
||||
"cosmos.bank.v1beta1.Query": "bank query",
|
||||
"cosmos.distribution.v1beta1.Query": "distribution query",
|
||||
"cosmos.evidence.v1.Query": "evidence query",
|
||||
"cosmos.feegrant.v1beta1.Query": "feegrant query",
|
||||
"cosmos.gov.v1.Query": "gov query",
|
||||
"cosmos.gov.v1beta1.Query": "gov query v1beta1",
|
||||
"cosmos.group.v1.Query": "group query",
|
||||
"cosmos.mint.v1beta1.Query": "mint query",
|
||||
"cosmos.params.v1beta1.Query": "params query",
|
||||
"cosmos.slashing.v1beta1.Query": "slashing query",
|
||||
"cosmos.staking.v1beta1.Query": "staking query",
|
||||
"cosmos.upgrade.v1.Query": "upgrade query",
|
||||
}
|
||||
@ -1,108 +0,0 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/pelletier/go-toml/v2"
|
||||
|
||||
"cosmossdk.io/errors"
|
||||
"cosmossdk.io/tools/hubl/internal/flags"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultConfigDirName = ".hubl"
|
||||
GlobalKeyringDirName = "global"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Chains map[string]*ChainConfig `toml:"chains"`
|
||||
KeyringBackend string `toml:"keyring-backend"`
|
||||
}
|
||||
|
||||
type ChainConfig struct {
|
||||
GRPCEndpoints []GRPCEndpoint `toml:"trusted-grpc-endpoints"`
|
||||
AddressPrefix string `toml:"address-prefix"`
|
||||
KeyringBackend string `toml:"keyring-backend"`
|
||||
}
|
||||
|
||||
type GRPCEndpoint struct {
|
||||
Endpoint string `toml:"endpoint"`
|
||||
Insecure bool `toml:"insecure"`
|
||||
}
|
||||
|
||||
var EmptyConfig = &Config{
|
||||
Chains: map[string]*ChainConfig{},
|
||||
KeyringBackend: flags.DefaultKeyringBackend,
|
||||
}
|
||||
|
||||
func (cfg *Config) GetKeyringBackend(chainName string) (string, error) {
|
||||
if chainName == GlobalKeyringDirName {
|
||||
return cfg.KeyringBackend, nil
|
||||
} else {
|
||||
chainCfg, ok := cfg.Chains[chainName]
|
||||
if ok {
|
||||
return chainCfg.KeyringBackend, nil
|
||||
}
|
||||
}
|
||||
|
||||
return flags.DefaultKeyringBackend, nil
|
||||
}
|
||||
|
||||
func GetConfigDir() (string, error) {
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
configDir := path.Join(homeDir, DefaultConfigDirName)
|
||||
if _, err := os.Stat(configDir); os.IsNotExist(err) {
|
||||
return configDir, os.MkdirAll(configDir, 0o750)
|
||||
}
|
||||
|
||||
return configDir, nil
|
||||
}
|
||||
|
||||
func Load(configDir string) (*Config, error) {
|
||||
configPath := configFilename(configDir)
|
||||
|
||||
if _, err := os.Stat(configPath); os.IsNotExist(err) {
|
||||
return EmptyConfig, nil
|
||||
}
|
||||
|
||||
bz, err := os.ReadFile(configPath)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "can't read config file: %s", configPath)
|
||||
}
|
||||
|
||||
config := &Config{}
|
||||
if err = toml.Unmarshal(bz, config); err != nil {
|
||||
return nil, errors.Wrapf(err, "can't load config file: %s", configPath)
|
||||
}
|
||||
|
||||
return config, err
|
||||
}
|
||||
|
||||
func Save(configDir string, config *Config) error {
|
||||
buf := &bytes.Buffer{}
|
||||
enc := toml.NewEncoder(buf)
|
||||
if err := enc.Encode(config); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(configDir, 0o750); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
configPath := configFilename(configDir)
|
||||
if err := os.WriteFile(configPath, buf.Bytes(), 0o600); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func configFilename(configDir string) string {
|
||||
return path.Join(configDir, "config.toml")
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
package flags
|
||||
|
||||
const (
|
||||
FlagInsecure = "insecure"
|
||||
FlagUpdate = "update"
|
||||
FlagConfig = "config"
|
||||
FlagLong = "long"
|
||||
FlagOutput = "output"
|
||||
|
||||
FlagKeyringBackend = "keyring-backend"
|
||||
)
|
||||
|
||||
const (
|
||||
OutputFormatText = "text"
|
||||
OutputFormatJSON = "json"
|
||||
|
||||
DefaultKeyringBackend = "os"
|
||||
)
|
||||
@ -1,147 +0,0 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"fmt"
|
||||
"path"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
_ "cosmossdk.io/api/cosmos/crypto/ed25519"
|
||||
_ "cosmossdk.io/api/cosmos/crypto/secp256k1"
|
||||
_ "cosmossdk.io/api/cosmos/crypto/secp256r1"
|
||||
"cosmossdk.io/tools/hubl/internal/config"
|
||||
"cosmossdk.io/tools/hubl/internal/flags"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/keys"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
|
||||
sdkkeyring "github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
"github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
func getKeyring(chainName string) (sdkkeyring.Keyring, error) {
|
||||
if chainName == "" {
|
||||
chainName = config.GlobalKeyringDirName
|
||||
}
|
||||
|
||||
registry := codectypes.NewInterfaceRegistry()
|
||||
cryptocodec.RegisterInterfaces(registry)
|
||||
cdc := codec.NewProtoCodec(registry)
|
||||
|
||||
configDir, err := config.GetConfigDir()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cfg, err := config.Load(configDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
backend, err := cfg.GetKeyringBackend(chainName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
keyringDir := path.Join(configDir, "keyring", chainName)
|
||||
return sdkkeyring.New(chainName, backend, keyringDir, nil, cdc)
|
||||
}
|
||||
|
||||
func KeyringCmd(chainName string) *cobra.Command {
|
||||
shortDesc := fmt.Sprintf("Keyring management for %s", chainName)
|
||||
if chainName == "" {
|
||||
chainName = config.GlobalKeyringDirName
|
||||
shortDesc = "Global keyring management for Hubl"
|
||||
}
|
||||
|
||||
keyringCmd := &cobra.Command{
|
||||
Use: "keys",
|
||||
Short: shortDesc,
|
||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
registry := codectypes.NewInterfaceRegistry()
|
||||
cryptocodec.RegisterInterfaces(registry)
|
||||
cdc := codec.NewProtoCodec(registry)
|
||||
|
||||
configDir, err := config.GetConfigDir()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg, err := config.Load(configDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
backend, err := cfg.GetKeyringBackend(chainName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if changed := cmd.Flags().Changed(flags.FlagKeyringBackend); changed {
|
||||
b, err := cmd.Flags().GetString(flags.FlagKeyringBackend)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
backend = b
|
||||
}
|
||||
|
||||
keyringDir := path.Join(configDir, "keyring", chainName)
|
||||
inBuf := bufio.NewReader(cmd.InOrStdin())
|
||||
kr, err := sdkkeyring.New(chainName, backend, keyringDir, inBuf, cdc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// addressCodec, validatorAddressCodec, consensusAddressCodec, err := getAddressCodecFromConfig(cfg, chainName)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
addressPrefix, validatorAddressPrefix, consensusAddressPrefix, err := getAddressPrefixFromConfig(cfg, chainName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
types.GetConfig().SetBech32PrefixForAccount(addressPrefix, addressPrefix+types.PrefixPublic)
|
||||
types.GetConfig().SetBech32PrefixForValidator(validatorAddressPrefix, validatorAddressPrefix+types.PrefixPublic)
|
||||
types.GetConfig().SetBech32PrefixForConsensusNode(consensusAddressPrefix, consensusAddressPrefix+types.PrefixPublic)
|
||||
|
||||
clientCtx := client.Context{}.
|
||||
WithKeyring(kr).
|
||||
WithCodec(cdc).
|
||||
WithKeyringDir(keyringDir).
|
||||
WithInput(inBuf)
|
||||
// WithAddressCodec(addressCodec).
|
||||
// WithValidatorAddressCodec(validatorAddressCodec).
|
||||
// WithConsensusAddressCodec(consensusAddressCodec)
|
||||
|
||||
cmd.SetContext(context.WithValue(context.Background(), client.ClientContextKey, &clientCtx))
|
||||
if err := client.SetCmdClientContext(cmd, clientCtx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
keyringCmd.AddCommand(
|
||||
keys.AddKeyCommand(),
|
||||
keys.DeleteKeyCommand(),
|
||||
keys.ExportKeyCommand(),
|
||||
keys.ImportKeyCommand(),
|
||||
keys.ImportKeyHexCommand(),
|
||||
keys.ListKeysCmd(),
|
||||
keys.ParseKeyStringCommand(),
|
||||
keys.RenameKeyCommand(),
|
||||
keys.ShowKeysCmd(),
|
||||
)
|
||||
keyringCmd.PersistentFlags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test|memory)")
|
||||
keyringCmd.PersistentFlags().String(flags.FlagOutput, flags.OutputFormatText, "Output format (text|json)")
|
||||
|
||||
return keyringCmd
|
||||
}
|
||||
@ -1,201 +0,0 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/reflect/protodesc"
|
||||
"google.golang.org/protobuf/reflect/protoregistry"
|
||||
"google.golang.org/protobuf/types/descriptorpb"
|
||||
|
||||
authv1betav1 "cosmossdk.io/api/cosmos/auth/v1beta1"
|
||||
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
|
||||
reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1"
|
||||
"cosmossdk.io/tools/hubl/internal/config"
|
||||
)
|
||||
|
||||
type ChainInfo struct {
|
||||
client *grpc.ClientConn
|
||||
|
||||
Context context.Context
|
||||
ConfigDir string
|
||||
Chain string
|
||||
Config *config.ChainConfig
|
||||
|
||||
ProtoFiles *protoregistry.Files
|
||||
ModuleOptions map[string]*autocliv1.ModuleOptions
|
||||
}
|
||||
|
||||
func NewChainInfo(configDir, chain string, config *config.ChainConfig) *ChainInfo {
|
||||
return &ChainInfo{
|
||||
Context: context.Background(),
|
||||
Config: config,
|
||||
Chain: chain,
|
||||
ConfigDir: configDir,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ChainInfo) getCacheDir() (string, error) {
|
||||
cacheDir := path.Join(c.ConfigDir, "cache")
|
||||
return cacheDir, os.MkdirAll(cacheDir, 0o750)
|
||||
}
|
||||
|
||||
func (c *ChainInfo) fdsCacheFilename() (string, error) {
|
||||
cacheDir, err := c.getCacheDir()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return path.Join(cacheDir, fmt.Sprintf("%s.fds", c.Chain)), nil
|
||||
}
|
||||
|
||||
func (c *ChainInfo) appOptsCacheFilename() (string, error) {
|
||||
cacheDir, err := c.getCacheDir()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return path.Join(cacheDir, fmt.Sprintf("%s.autocli", c.Chain)), nil
|
||||
}
|
||||
|
||||
func (c *ChainInfo) Load(reload bool) error {
|
||||
fdSet := &descriptorpb.FileDescriptorSet{}
|
||||
fdsFilename, err := c.fdsCacheFilename()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := os.Stat(fdsFilename); os.IsNotExist(err) || reload {
|
||||
client, err := c.OpenClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
reflectionClient := reflectionv1.NewReflectionServiceClient(client)
|
||||
fdRes, err := reflectionClient.FileDescriptors(c.Context, &reflectionv1.FileDescriptorsRequest{})
|
||||
if err != nil {
|
||||
fdSet, err = loadFileDescriptorsGRPCReflection(c.Context, client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
fdSet = &descriptorpb.FileDescriptorSet{File: fdRes.Files}
|
||||
}
|
||||
|
||||
bz, err := proto.Marshal(fdSet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = os.WriteFile(fdsFilename, bz, 0o600); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
bz, err := os.ReadFile(fdsFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = proto.Unmarshal(bz, fdSet); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
c.ProtoFiles, err = protodesc.FileOptions{AllowUnresolvable: true}.NewFiles(fdSet)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error building protoregistry.Files: %w", err)
|
||||
}
|
||||
|
||||
appOptsFilename, err := c.appOptsCacheFilename()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := os.Stat(appOptsFilename); os.IsNotExist(err) || reload {
|
||||
client, err := c.OpenClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
autocliQueryClient := autocliv1.NewQueryClient(client)
|
||||
appOptsRes, err := autocliQueryClient.AppOptions(c.Context, &autocliv1.AppOptionsRequest{})
|
||||
if err != nil {
|
||||
appOptsRes = guessAutocli(c.ProtoFiles)
|
||||
}
|
||||
|
||||
bz, err := proto.Marshal(appOptsRes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.WriteFile(appOptsFilename, bz, 0o600); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.ModuleOptions = appOptsRes.ModuleOptions
|
||||
} else {
|
||||
bz, err := os.ReadFile(appOptsFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var appOptsRes autocliv1.AppOptionsResponse
|
||||
if err := proto.Unmarshal(bz, &appOptsRes); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.ModuleOptions = appOptsRes.ModuleOptions
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ChainInfo) OpenClient() (*grpc.ClientConn, error) {
|
||||
if c.client != nil {
|
||||
return c.client, nil
|
||||
}
|
||||
|
||||
var res error
|
||||
for _, endpoint := range c.Config.GRPCEndpoints {
|
||||
var creds credentials.TransportCredentials
|
||||
if endpoint.Insecure {
|
||||
creds = insecure.NewCredentials()
|
||||
} else {
|
||||
creds = credentials.NewTLS(&tls.Config{
|
||||
MinVersion: tls.VersionTLS12,
|
||||
})
|
||||
}
|
||||
|
||||
var err error
|
||||
c.client, err = grpc.NewClient(endpoint.Endpoint, grpc.WithTransportCredentials(creds))
|
||||
if err != nil {
|
||||
res = errors.Join(res, err)
|
||||
continue
|
||||
}
|
||||
|
||||
return c.client, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("error loading gRPC client: %w", res)
|
||||
}
|
||||
|
||||
// getAddressPrefix returns the address prefix of the chain.
|
||||
func getAddressPrefix(ctx context.Context, conn grpc.ClientConnInterface) (string, error) {
|
||||
authClient := authv1betav1.NewQueryClient(conn)
|
||||
resp, err := authClient.Bech32Prefix(ctx, &authv1betav1.Bech32PrefixRequest{})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if resp == nil || resp.Bech32Prefix == "" {
|
||||
return "", errors.New("bech32 account address prefix is not set")
|
||||
}
|
||||
|
||||
return resp.Bech32Prefix, nil
|
||||
}
|
||||
@ -1,104 +0,0 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/manifoldco/promptui"
|
||||
)
|
||||
|
||||
type ChainRegistryEntry struct {
|
||||
APIs struct {
|
||||
GRPC []*APIEntry `json:"grpc"`
|
||||
} `json:"apis"`
|
||||
}
|
||||
|
||||
type APIEntry struct {
|
||||
Address string
|
||||
Provider string
|
||||
}
|
||||
|
||||
func GetChainRegistryEntry(chain string) (*ChainRegistryEntry, error) {
|
||||
res, err := http.Get(fmt.Sprintf("https://raw.githubusercontent.com/cosmos/chain-registry/master/%v/chain.json", chain))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bz, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = res.Body.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data := &ChainRegistryEntry{}
|
||||
if err = json.Unmarshal(bz, data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// clean-up the URL
|
||||
cleanEntries := make([]*APIEntry, 0)
|
||||
for i, apiEntry := range data.APIs.GRPC {
|
||||
// clean-up the http(s):// prefix
|
||||
if idx := strings.Index(apiEntry.Address, "://"); idx != -1 {
|
||||
data.APIs.GRPC[i].Address = apiEntry.Address[idx+3:]
|
||||
}
|
||||
|
||||
// remove trailing slashes
|
||||
data.APIs.GRPC[i].Address = strings.TrimSuffix(data.APIs.GRPC[i].Address, "/")
|
||||
|
||||
// remove addresses without a port
|
||||
if !strings.Contains(data.APIs.GRPC[i].Address, ":") {
|
||||
continue
|
||||
}
|
||||
|
||||
cleanEntries = append(cleanEntries, data.APIs.GRPC[i])
|
||||
}
|
||||
|
||||
data.APIs.GRPC = cleanEntries
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func SelectGRPCEndpoints(chain string) (string, error) {
|
||||
entry, err := GetChainRegistryEntry(chain)
|
||||
if err != nil || len(entry.APIs.GRPC) == 0 {
|
||||
if err != nil {
|
||||
// print error here so that user can know what happened and decide what to do next
|
||||
fmt.Printf("Failed to load data for %s in the chain registry: %v\n", chain, err)
|
||||
} else {
|
||||
fmt.Printf("Found empty gRPC endpoint of %s in the chain registry.\n", chain)
|
||||
}
|
||||
fmt.Println("Specify a custom gRPC endpoint manually.")
|
||||
prompt := &promptui.Prompt{
|
||||
Label: "Enter a gRPC endpoint that you trust",
|
||||
}
|
||||
return prompt.Run()
|
||||
}
|
||||
fmt.Printf("Found data for %s in the chain registry\n", chain)
|
||||
|
||||
var items []string
|
||||
for _, apiEntry := range entry.APIs.GRPC {
|
||||
items = append(items, fmt.Sprintf("%s: %s", apiEntry.Provider, apiEntry.Address))
|
||||
}
|
||||
prompt := promptui.SelectWithAdd{
|
||||
Label: fmt.Sprintf("Select a gRPC endpoint that you trust for the %s network", chain),
|
||||
Items: items,
|
||||
AddLabel: "Custom endpoint:",
|
||||
}
|
||||
|
||||
i, ep, err := prompt.Run()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// user selected a custom endpoint
|
||||
if i == -1 {
|
||||
return ep, nil
|
||||
}
|
||||
|
||||
return entry.APIs.GRPC[i].Address, nil
|
||||
}
|
||||
@ -1,262 +0,0 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
"google.golang.org/protobuf/reflect/protoregistry"
|
||||
"google.golang.org/protobuf/types/dynamicpb"
|
||||
|
||||
"cosmossdk.io/client/v2/autocli"
|
||||
"cosmossdk.io/client/v2/autocli/flag"
|
||||
"cosmossdk.io/tools/hubl/internal/config"
|
||||
"cosmossdk.io/tools/hubl/internal/flags"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/grpc/cmtservice"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
)
|
||||
|
||||
func InitCmd(config *config.Config, configDir string) *cobra.Command {
|
||||
var insecure bool
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "init <foochain>",
|
||||
Short: "Initialize a new chain",
|
||||
Long: `To configure a new chain, run this command using the --init flag and the name of the chain as it's listed in the chain registry (https://github.com/cosmos/chain-registry).
|
||||
If the chain is not listed in the chain registry, you can use any unique name.`,
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
chainName := strings.ToLower(args[0])
|
||||
return reconfigure(cmd, config, configDir, chainName)
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().BoolVar(&insecure, flags.FlagInsecure, false, "allow setting up insecure gRPC connection")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func RemoteCommand(config *config.Config, configDir string) ([]*cobra.Command, error) {
|
||||
commands := []*cobra.Command{}
|
||||
|
||||
for chain, chainConfig := range config.Chains {
|
||||
|
||||
// load chain info
|
||||
chainInfo := NewChainInfo(configDir, chain, chainConfig)
|
||||
if err := chainInfo.Load(false); err != nil {
|
||||
commands = append(commands, RemoteErrorCommand(config, configDir, chain, chainConfig, err))
|
||||
continue
|
||||
}
|
||||
|
||||
// add comet commands
|
||||
cometCmds := cmtservice.NewCometBFTCommands()
|
||||
chainInfo.ModuleOptions[cometCmds.Name()] = cometCmds.AutoCLIOptions()
|
||||
|
||||
appOpts := autocli.AppOptions{
|
||||
ModuleOptions: chainInfo.ModuleOptions,
|
||||
}
|
||||
|
||||
addressCodec, validatorAddressCodec, consensusAddressCodec, err := getAddressCodecFromConfig(config, chain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
kr, err := getKeyring(chain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
autoCLIKeyring, err := keyring.NewAutoCLIKeyring(kr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
builder := &autocli.Builder{
|
||||
Builder: flag.Builder{
|
||||
TypeResolver: &dynamicTypeResolver{chainInfo},
|
||||
FileResolver: chainInfo.ProtoFiles,
|
||||
AddressCodec: addressCodec,
|
||||
ValidatorAddressCodec: validatorAddressCodec,
|
||||
ConsensusAddressCodec: consensusAddressCodec,
|
||||
Keyring: autoCLIKeyring,
|
||||
},
|
||||
GetClientConn: func(command *cobra.Command) (grpc.ClientConnInterface, error) {
|
||||
return chainInfo.OpenClient()
|
||||
},
|
||||
AddQueryConnFlags: func(command *cobra.Command) {},
|
||||
}
|
||||
|
||||
var (
|
||||
update bool
|
||||
reconfig bool
|
||||
insecure bool
|
||||
output string
|
||||
)
|
||||
|
||||
chainCmd := &cobra.Command{
|
||||
Use: chain,
|
||||
Short: fmt.Sprintf("Commands for the %s chain", chain),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
switch {
|
||||
case reconfig:
|
||||
return reconfigure(cmd, config, configDir, chain)
|
||||
case update:
|
||||
cmd.Printf("Updating AutoCLI data for %s\n", chain)
|
||||
return chainInfo.Load(true)
|
||||
default:
|
||||
return cmd.Help()
|
||||
}
|
||||
},
|
||||
}
|
||||
chainCmd.Flags().BoolVar(&update, flags.FlagUpdate, false, "update the CLI commands for the selected chain (should be used after every chain upgrade)")
|
||||
chainCmd.Flags().BoolVar(&reconfig, flags.FlagConfig, false, "re-configure the selected chain (allows choosing a new gRPC endpoint and refreshes data")
|
||||
chainCmd.Flags().BoolVar(&insecure, flags.FlagInsecure, false, "allow re-configuring the selected chain using an insecure gRPC connection")
|
||||
chainCmd.PersistentFlags().StringVar(&output, flags.FlagOutput, flags.OutputFormatJSON, fmt.Sprintf("output format (%s|%s)", flags.OutputFormatText, flags.OutputFormatJSON))
|
||||
|
||||
// add chain specific keyring
|
||||
chainCmd.AddCommand(KeyringCmd(chainInfo.Chain))
|
||||
|
||||
// add client context
|
||||
clientCtx := client.Context{}.WithKeyring(kr)
|
||||
chainCmd.SetContext(context.WithValue(context.Background(), client.ClientContextKey, &clientCtx))
|
||||
|
||||
if err := appOpts.EnhanceRootCommandWithBuilder(chainCmd, builder); err != nil {
|
||||
// when enriching the command with autocli fails, we add a command that
|
||||
// will print the error and allow the user to reconfigure the chain instead
|
||||
chainCmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
cmd.Printf("Error while loading AutoCLI data for %s: %+v\n", chain, err)
|
||||
cmd.Printf("Attempt to reconfigure the chain using the %s flag\n", flags.FlagConfig)
|
||||
if cmd.Flags().Changed(flags.FlagConfig) {
|
||||
return reconfigure(cmd, config, configDir, chain)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
commands = append(commands, chainCmd)
|
||||
}
|
||||
|
||||
return commands, nil
|
||||
}
|
||||
|
||||
func RemoteErrorCommand(cfg *config.Config, configDir, chain string, chainConfig *config.ChainConfig, err error) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: chain,
|
||||
Short: fmt.Sprintf("Unable to load %s data", chain),
|
||||
Long: fmt.Sprintf("Unable to load %s data, reconfiguration needed.", chain),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
cmd.Printf("Error loading chain data for %s: %+v\n", chain, err)
|
||||
return reconfigure(cmd, cfg, configDir, chain)
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().Bool(flags.FlagInsecure, chainConfig.GRPCEndpoints[0].Insecure, "allow setting up insecure gRPC connection")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func reconfigure(cmd *cobra.Command, cfg *config.Config, configDir, chain string) error {
|
||||
insecure, _ := cmd.Flags().GetBool(flags.FlagInsecure)
|
||||
|
||||
cmd.Printf("Configuring %s\n", chain)
|
||||
endpoint, err := SelectGRPCEndpoints(chain)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd.Printf("%s endpoint selected\n", endpoint)
|
||||
chainConfig := &config.ChainConfig{
|
||||
GRPCEndpoints: []config.GRPCEndpoint{
|
||||
{
|
||||
Endpoint: endpoint,
|
||||
Insecure: insecure,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
chainInfo := NewChainInfo(configDir, chain, chainConfig)
|
||||
if err = chainInfo.Load(true); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client, err := chainInfo.OpenClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
addressPrefix, err := getAddressPrefix(context.Background(), client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
chainConfig.KeyringBackend = flags.DefaultKeyringBackend
|
||||
chainConfig.AddressPrefix = addressPrefix
|
||||
cfg.Chains[chain] = chainConfig
|
||||
|
||||
if err := config.Save(configDir, cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd.Printf("Configuration saved to %s\n", configDir)
|
||||
return nil
|
||||
}
|
||||
|
||||
type dynamicTypeResolver struct {
|
||||
*ChainInfo
|
||||
}
|
||||
|
||||
var (
|
||||
_ protoregistry.MessageTypeResolver = dynamicTypeResolver{}
|
||||
_ protoregistry.ExtensionTypeResolver = dynamicTypeResolver{}
|
||||
)
|
||||
|
||||
func (d dynamicTypeResolver) FindMessageByName(message protoreflect.FullName) (protoreflect.MessageType, error) {
|
||||
desc, err := d.ProtoFiles.FindDescriptorByName(message)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return dynamicpb.NewMessageType(desc.(protoreflect.MessageDescriptor)), nil
|
||||
}
|
||||
|
||||
func (d dynamicTypeResolver) FindMessageByURL(url string) (protoreflect.MessageType, error) {
|
||||
if i := strings.LastIndexByte(url, '/'); i >= 0 {
|
||||
url = url[i+len("/"):]
|
||||
}
|
||||
|
||||
return d.FindMessageByName(protoreflect.FullName(url))
|
||||
}
|
||||
|
||||
func (d dynamicTypeResolver) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) {
|
||||
desc, err := d.ProtoFiles.FindDescriptorByName(field)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return dynamicpb.NewExtensionType(desc.(protoreflect.ExtensionTypeDescriptor)), nil
|
||||
}
|
||||
|
||||
func (d dynamicTypeResolver) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) {
|
||||
desc, err := d.ProtoFiles.FindDescriptorByName(message)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
messageDesc := desc.(protoreflect.MessageDescriptor)
|
||||
exts := messageDesc.Extensions()
|
||||
n := exts.Len()
|
||||
for i := 0; i < n; i++ {
|
||||
ext := exts.Get(i)
|
||||
if ext.Number() == field {
|
||||
return dynamicpb.NewExtensionType(ext), nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, protoregistry.NotFound
|
||||
}
|
||||
@ -1,39 +0,0 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"cosmossdk.io/tools/hubl/internal/config"
|
||||
)
|
||||
|
||||
func RootCommand() (*cobra.Command, error) {
|
||||
configDir, err := config.GetConfigDir()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cfg, err := config.Load(configDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "hubl",
|
||||
Short: "Hubl is a CLI for interacting with Cosmos SDK chains",
|
||||
}
|
||||
|
||||
// add commands
|
||||
commands, err := RemoteCommand(cfg, configDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
commands = append(
|
||||
commands,
|
||||
InitCmd(cfg, configDir),
|
||||
KeyringCmd(""),
|
||||
VersionCmd(),
|
||||
)
|
||||
|
||||
cmd.AddCommand(commands...)
|
||||
return cmd, nil
|
||||
}
|
||||
@ -1,43 +0,0 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"cosmossdk.io/core/address"
|
||||
"cosmossdk.io/tools/hubl/internal/config"
|
||||
|
||||
addresscodec "github.com/cosmos/cosmos-sdk/codec/address"
|
||||
)
|
||||
|
||||
// getAddressCodecFromConfig returns the address codecs for the given chain name
|
||||
func getAddressCodecFromConfig(cfg *config.Config, chainName string) (address.Codec, address.Codec, address.Codec, error) {
|
||||
addressPrefix := "cosmos"
|
||||
|
||||
if chainName != config.GlobalKeyringDirName {
|
||||
chainConfig, ok := cfg.Chains[chainName]
|
||||
if !ok {
|
||||
return nil, nil, nil, fmt.Errorf("chain %s not found in config", chainName)
|
||||
}
|
||||
|
||||
addressPrefix = chainConfig.AddressPrefix
|
||||
}
|
||||
|
||||
return addresscodec.NewBech32Codec(addressPrefix),
|
||||
addresscodec.NewBech32Codec(fmt.Sprintf("%svaloper", addressPrefix)),
|
||||
addresscodec.NewBech32Codec(fmt.Sprintf("%svalcons", addressPrefix)),
|
||||
nil
|
||||
}
|
||||
|
||||
// getAddressPrefixFromConfig returns the address prefixes for the given chain name
|
||||
func getAddressPrefixFromConfig(cfg *config.Config, chainName string) (string, string, string, error) {
|
||||
if chainName != config.GlobalKeyringDirName {
|
||||
chainConfig, ok := cfg.Chains[chainName]
|
||||
if !ok {
|
||||
return "", "", "", fmt.Errorf("chain %s not found in config", chainName)
|
||||
}
|
||||
|
||||
return chainConfig.AddressPrefix, fmt.Sprintf("%svaloper", chainConfig.AddressPrefix), fmt.Sprintf("%svalcons", chainConfig.AddressPrefix), nil
|
||||
}
|
||||
|
||||
return "cosmos", "cosmosvaloper", "cosmosvalcons", nil
|
||||
}
|
||||
@ -1,42 +0,0 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"cosmossdk.io/tools/hubl/internal/flags"
|
||||
)
|
||||
|
||||
func VersionCmd() *cobra.Command {
|
||||
var long bool
|
||||
|
||||
versionCmd := &cobra.Command{
|
||||
Use: "version",
|
||||
Short: "Display hubl version",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
version, ok := debug.ReadBuildInfo()
|
||||
if !ok {
|
||||
return errors.New("failed to get hubl version")
|
||||
}
|
||||
|
||||
cmd.Printf("hubl version: %s\n", strings.TrimSpace(version.Main.Version))
|
||||
|
||||
if long {
|
||||
for _, dep := range version.Deps {
|
||||
if dep.Path == "cosmossdk.io/client/v2" {
|
||||
cmd.Printf("client/v2 version: %s\n", strings.TrimSpace(dep.Version))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
versionCmd.Flags().BoolVar(&long, flags.FlagLong, false, "display long version information")
|
||||
|
||||
return versionCmd
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
sonar.projectKey=cosmos-sdk-tools-hubl
|
||||
sonar.organization=cosmos
|
||||
|
||||
sonar.projectName=Cosmos SDK - Hubl
|
||||
sonar.project.monorepo.enabled=true
|
||||
|
||||
sonar.sources=.
|
||||
sonar.exclusions=**/*_test.go,**/*.pb.go,**/*.pulsar.go,**/*.pb.gw.go
|
||||
sonar.coverage.exclusions=**/*_test.go,**/testutil/**,**/*.pb.go,**/*.pb.gw.go,**/*.pulsar.go,test_helpers.go,docs/**
|
||||
sonar.tests=.
|
||||
sonar.test.inclusions=**/*_test.go
|
||||
sonar.go.coverage.reportPaths=coverage.out
|
||||
|
||||
sonar.sourceEncoding=UTF-8
|
||||
sonar.scm.provider=git
|
||||
sonar.scm.forceReloadAll=true
|
||||
Loading…
Reference in New Issue
Block a user