Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kava gRPC Client #1784

Merged
merged 10 commits into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
- (community) [#1704] Add module params
- (community) [#1706] Add disable inflation upgrade
- (community) [#1745] Enable params update via governance with `MsgUpdateParams`
- (client) [#1784] Add Kava gRPC client

### Bug Fixes

Expand All @@ -62,6 +63,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
## [v0.24.1](https://github.com/Kava-Labs/kava/releases/tag/v0.24.1)

### Features

- (metrics) [#1668] Adds non-state breaking x/metrics module for custom telemetry.
- (metrics) [#1669] Add performance timing metrics to all Begin/EndBlockers
- (community) [#1751] Add `AnnualizedRewards` query endpoint
Expand Down Expand Up @@ -305,6 +307,7 @@ the [changelog](https://github.com/cosmos/cosmos-sdk/blob/v0.38.4/CHANGELOG.md).
- [#257](https://github.com/Kava-Labs/kava/pulls/257) Include scripts to run
large-scale simulations remotely using aws-batch

[#1784]: https://github.com/Kava-Labs/kava/pull/1784
[#1776]: https://github.com/Kava-Labs/kava/pull/1776
[#1770]: https://github.com/Kava-Labs/kava/pull/1770
[#1755]: https://github.com/Kava-Labs/kava/pull/1755
Expand Down
74 changes: 74 additions & 0 deletions client/grpc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Kava gRPC Client

The Kava gRPC client is a tool for making gRPC queries on a Kava chain.

## Features

- Easy-to-use gRPC client for the Kava chain.
- Access all query clients for Cosmos and Kava modules using `client.Query` (e.g., `client.Query.Bank.Balance`).
- Utilize utility functions for common queries (e.g., `client.BaseAccount(str)`).

## Usage

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DracoLi found out that trying to use this client from another package (kava's ethermint forked) failed with error during go dependency resolution,

⋊> ~/f/k/e/scratch on patch-ethermint-gas-tracking ⨯ go get github.com/kava-labs/kava/
client/grpc@260d43291e4321e1b6ddb18abc2381436c8f7bc5
go: downloading github.com/tendermint/tendermint v0.34.27
go: downloading github.com/gogo/protobuf v1.3.3
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/cosmos-sdk/client/grpc/tmservice imports
        github.com/gogo/protobuf/gogoproto: reading github.com/gogo/protobuf/go.mod at revision v1.3.3: unknown revision v1.3.3
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/cosmos-sdk/client/grpc/tmservice imports
        github.com/gogo/protobuf/grpc: reading github.com/gogo/protobuf/go.mod at revision v1.3.3: unknown revision v1.3.3
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/cosmos-sdk/client/grpc/tmservice imports
        github.com/gogo/protobuf/proto: reading github.com/gogo/protobuf/go.mod at revision v1.3.3: unknown revision v1.3.3
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/cosmos-sdk/client/grpc/tmservice imports
        github.com/gogo/protobuf/types: reading github.com/gogo/protobuf/go.mod at revision v1.3.3: unknown revision v1.3.3
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/cosmos-sdk/client/grpc/tmservice imports
        github.com/tendermint/tendermint/abci/types: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/cosmos-sdk/client/grpc/tmservice imports
        github.com/tendermint/tendermint/proto/tendermint/p2p: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/cosmos-sdk/client/grpc/tmservice imports
        github.com/tendermint/tendermint/proto/tendermint/types: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/cosmos-sdk/client/grpc/tmservice imports
        github.com/tendermint/tendermint/proto/tendermint/version: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/cosmos-sdk/client/grpc/tmservice imports
        github.com/tendermint/tendermint/rpc/core/types: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/cosmos-sdk/x/auth/types imports
        github.com/tendermint/tendermint/crypto: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/cosmos-sdk/x/evidence/types imports
        github.com/tendermint/tendermint/crypto/tmhash: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/cosmos-sdk/x/evidence/types imports
        github.com/tendermint/tendermint/libs/bytes: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/cosmos-sdk/x/staking/types imports
        github.com/gogo/protobuf/protoc-gen-gogo/descriptor: reading github.com/gogo/protobuf/go.mod at revision v1.3.3: unknown revision v1.3.3
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/cosmos-sdk/x/staking/types imports
        github.com/tendermint/tendermint/proto/tendermint/crypto: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/ibc-go/v6/modules/apps/transfer/types imports
        github.com/gogo/protobuf/jsonpb: reading github.com/gogo/protobuf/go.mod at revision v1.3.3: unknown revision v1.3.3
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/ibc-go/v6/modules/apps/transfer/types imports
        github.com/tendermint/tendermint/types: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/kava-labs/kava/x/bep3/types imports
        github.com/tendermint/tendermint/types/time: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/util imports
        github.com/kava-labs/kava/app imports
        github.com/tendermint/tendermint/libs/json: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/util imports
        github.com/kava-labs/kava/app imports
        github.com/tendermint/tendermint/libs/log: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/cosmos-sdk/client/grpc/tmservice imports
        github.com/cosmos/cosmos-sdk/client imports
        github.com/tendermint/tendermint/libs/cli: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/cosmos-sdk/client/grpc/tmservice imports
        github.com/cosmos/cosmos-sdk/client imports
        github.com/tendermint/tendermint/mempool: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/cosmos-sdk/client/grpc/tmservice imports
        github.com/cosmos/cosmos-sdk/client imports
        github.com/tendermint/tendermint/rpc/client: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/cosmos-sdk/client/grpc/tmservice imports
        github.com/cosmos/cosmos-sdk/client imports
        github.com/tendermint/tendermint/rpc/client/http: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/cosmos-sdk/client/grpc/tmservice imports
        github.com/cosmos/cosmos-sdk/client/rpc imports
        github.com/tendermint/tendermint/p2p: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/cosmos-sdk/x/auth/types imports
        github.com/cosmos/cosmos-sdk/crypto/codec imports
        github.com/tendermint/tendermint/crypto/encoding: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/cosmos-sdk/x/auth/types imports
        github.com/cosmos/cosmos-sdk/crypto/codec imports
        github.com/tendermint/tendermint/crypto/sr25519: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/cosmos-sdk/x/upgrade/types imports
        github.com/cosmos/cosmos-sdk/store/types imports
        github.com/tendermint/tendermint/crypto/merkle: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/util imports
        github.com/kava-labs/kava/app imports
        github.com/cosmos/cosmos-sdk/server/api imports
        github.com/tendermint/tendermint/rpc/jsonrpc/server: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/util imports
        github.com/kava-labs/kava/app imports
        github.com/cosmos/cosmos-sdk/x/genutil imports
        github.com/tendermint/tendermint/config: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/util imports
        github.com/kava-labs/kava/app imports
        github.com/cosmos/cosmos-sdk/x/genutil imports
        github.com/tendermint/tendermint/crypto/ed25519: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/util imports
        github.com/kava-labs/kava/app imports
        github.com/cosmos/cosmos-sdk/x/genutil imports
        github.com/tendermint/tendermint/libs/os: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/util imports
        github.com/kava-labs/kava/app imports
        github.com/cosmos/cosmos-sdk/x/genutil imports
        github.com/tendermint/tendermint/privval: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/util imports
        github.com/kava-labs/kava/app imports
        github.com/evmos/ethermint/server/config imports
        github.com/tendermint/tendermint/libs/strings: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/cosmos-sdk/client/grpc/tmservice imports
        github.com/cosmos/cosmos-sdk/baseapp imports
        github.com/cosmos/cosmos-sdk/snapshots imports
        github.com/gogo/protobuf/io: reading github.com/gogo/protobuf/go.mod at revision v1.3.3: unknown revision v1.3.3
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/query imports
        github.com/cosmos/cosmos-sdk/x/upgrade/types imports
        github.com/cosmos/cosmos-sdk/store/types imports
        github.com/cosmos/cosmos-sdk/store/internal/proofs imports
        github.com/tendermint/tendermint/libs/rand: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/util imports
        github.com/kava-labs/kava/app imports
        github.com/cosmos/ibc-go/v6/modules/core imports
        github.com/cosmos/ibc-go/v6/modules/core/02-client/keeper imports
        github.com/tendermint/tendermint/light: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/util imports
        github.com/kava-labs/kava/app imports
        github.com/cosmos/ibc-go/v6/modules/core/02-client imports
        github.com/cosmos/ibc-go/v6/modules/light-clients/07-tendermint/types imports
        github.com/tendermint/tendermint/libs/math: reading github.com/tendermint/tendermint/go.mod at revision v0.34.27: unknown revision v0.34.27
go: github.com/kava-labs/kava/client/grpc imports
        github.com/kava-labs/kava/client/grpc/util imports
        github.com/kava-labs/kava/app imports
        github.com/kava-labs/kava/x/evmutil imports
        github.com/kava-labs/kava/x/evmutil/client/cli imports
        github.com/evmos/ethermint/crypto/hd imports
        github.com/btcsuite/btcutil/hdkeychain imports
        github.com/btcsuite/btcd/btcec: cannot find module providing package github.com/btcsuite/btcd/btcec

only fix was to update the go.mod with the same replaces as we have in kava's go.mod

replace (
	// Use the cosmos keyring code
	github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0
	// Use rocksdb 7.9.2
	github.com/cometbft/cometbft-db => github.com/kava-labs/cometbft-db v0.7.0-rocksdb-v7.9.2-kava.1
	// Use cosmos-sdk fork with backported fix for unsafe-reset-all, staking transfer events, and custom tally handler support
	github.com/cosmos/cosmos-sdk => github.com/kava-labs/cosmos-sdk v0.46.11-kava.1
	// See https://github.com/cosmos/cosmos-sdk/pull/13093
	github.com/dgrijalva/jwt-go => github.com/golang-jwt/jwt/v4 v4.4.2
	// Use ethermint fork that respects min-gas-price with NoBaseFee true and london enabled, and includes eip712 support
	github.com/evmos/ethermint => github.com/kava-labs/ethermint v0.21.1-0.20231127220940-f5eaf3a08c1a
	// See https://github.com/cosmos/cosmos-sdk/pull/10401, https://github.com/cosmos/cosmos-sdk/commit/0592ba6158cd0bf49d894be1cef4faeec59e8320
	github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.7.0
	// Use the cosmos modified protobufs
	github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
	// Downgraded to avoid bugs in following commits which causes "version does not exist" errors
	github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
	// Use cometbft fork of tendermint
	github.com/tendermint/tendermint => github.com/cometbft/cometbft v0.34.27
	// Indirect dependencies still use tendermint/tm-db
	github.com/tendermint/tm-db => github.com/kava-labs/tm-db v0.6.7-kava.3
)

probably worth calling out in the readme to save someone else time in resolving it (ideally this is why I would like to see this client in a seperate package, by keeping it in the kava monorepo we aren't really dogfooding the client and feeling / fixing pain points that a third party developer would go through cc @karzak @Behdad-Kava )

Copy link
Contributor

@galxy25 galxy25 Dec 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also it not being a separate package is leading to import cycles trying to use this in ethermint as the client for talking to the cosmos sdk...ending up falling back to copy pasting all the code in this package for setting up the grpc connection, defeating the very purpose of this client in terms of being the one true / last implementation of a go client for talking to the kava grpc endpoints

this is the code I would be able to write if this was a standalone package, now it's gonna be a lot more lines / copy pasting / duplication of effort

// handle edge cases in differences between traced tx status
	// and actual tx status when it was executed as part of a block
	if jsonResult["failed"] != transaction.Failed {
		jsonResult["failed"] = transaction.Failed
		_, exists := jsonResult["error"]
		if !exists {
			// fallback to tendermint tx indexer
			query := fmt.Sprintf("%s.%s='%s'", evmtypes.TypeMsgEthereumTx, evmtypes.AttributeKeyEthereumTxHash, hash.Hex())
			resTxs, err := b.clientCtx.Client.TxSearch(b.ctx, query, false, nil, nil, "")

			if err != nil {
				panic(err)
			}

			txMe := resTxs.Txs[0]
			cosmosHash := txMe.Hash

			grpcUrl := "http://localhost:9090"
			kava, err := kavaCosmosClient.NewClient(grpcUrl)

			if err != nil {
				panic(err)
			}
			res, err := kava.Query.Tx.GetTx(context.Background(), &txtypes.GetTxRequest{Hash: cosmosHash.String()})

			if err != nil {
				panic(err)
			}

			jsonResult["error"] = res.TxResponse.RawLog
			jsonResult["gas_used"] = res.TxResponse.GasUsed
		}
	}

Copy link
Contributor Author

@DracoLi DracoLi Dec 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some thoughts:

  • Regarding the replace rules - I encountered this as well when looking to set up auction bot to use the updated kava module. I think we can definitely add some docs for adding kava module to a new project.
  • For using the kava module in the modules it depends on (ie ethermint) - I think we will still get this import cycle issue even if the client is standalone? Since ethermint will now depend on the grpc client module, which is dependent on kava module, which depends on ethermint.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my two cents 😄
attempting to use the grpc client in ethermint is not the same as including it in a service that interacts with the chain. i don't think a dependency of kava should attempt to import this grpc client. it's intended end user is a service interacting with the chain, not the chain interacting with itself

regarding the replaces, it's been my experience that you always need to replaces to match kava's. not sure if there's a more ergonomic way around it..

### Creating a new client

```go
package main

import (
kavaGrpc "github.com/kava-labs/kava/client/grpc"
)
grpcUrl := "https://grpc.kava.io:443"
client, err := kavaGrpc.NewClient(url)
DracoLi marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
panic(err)
}
```

### Making grpc queries

Query clients for both Cosmos and Kava modules are available via `client.Query`.

Example: Query Cosmos module `x/bank` for address balance

```go
import (
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
)

rsp, err := client.Query.Bank.Balance(context.Background(), &banktypes.QueryBalanceRequest{
Address: "kava19rjk5qmmwywnzfccwzyn02jywgpwjqf60afj92",
Denom: "ukava",
})
```

Example: Query Kava module `x/evmutil` for params

```go
import (
evmutiltypes "github.com/kava-labs/kava/x/evmutil/types"
)

rsp, err := client.Query.Evmutil.Params(
context.Background(), &evmutiltypes.QueryParamsRequest{},
)
```

#### Query Utilities

Utility functions for common queries are available directly on the client.

Example: Util query to get a base account

```go
kavaAcc := "kava19rjk5qmmwywnzfccwzyn02jywgpwjqf60afj92"
rsp, err := client.BaseAccount(kavaAcc)
if err != nil {
panic(err)
}
fmt.Printf("account sequence for %s: %d\n", kavaAcc, rsp.Sequence)
```

## Query Tests

To test queries, a Kava node is required. Therefore, the e2e tests for the gRPC client queries can be found in the `tests/e2e` directory. Tests for new utility queries should be added as e2e tests under the `test/e2e` directory.
50 changes: 50 additions & 0 deletions client/grpc/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package grpc

import (
"errors"

"github.com/kava-labs/kava/client/grpc/query"
"github.com/kava-labs/kava/client/grpc/util"
)

// KavaGrpcClient enables the usage of kava grpc query clients and query utils
type KavaGrpcClient struct {
config KavaGrpcClientConfig

// Query clients for cosmos and kava modules
Query *query.QueryClient

// Utils for common queries (ie fetch an unpacked BaseAccount)
*util.Util
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggest "sdk" as a more intention revealing name here as we're builidng a higher level interface for making common dApp workflows simpler without having to make n number of calls to multiple api's to stitch together the end result that a dApp developer or kava engineer writing tests would care about

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so like client.sdk.BaseAccount instead of client.BaseAccount?

}

// KavaGrpcClientConfig is a configuration struct for a KavaGrpcClient
type KavaGrpcClientConfig struct {
// note: add future config options here
}

// NewClient creates a new KavaGrpcClient via a grpc url
func NewClient(grpcUrl string) (*KavaGrpcClient, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

recommend adding url as a field to the config struct above and taking that as the only input to this function

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

majority of the time the config won't be needed and is optional, so I think some benefit in splitting it as that allows the client to be created with less code. Thoughts?

return NewClientWithConfig(grpcUrl, NewDefaultConfig())
}

// NewClientWithConfig creates a new KavaGrpcClient via a grpc url and config
func NewClientWithConfig(grpcUrl string, config KavaGrpcClientConfig) (*KavaGrpcClient, error) {
if grpcUrl == "" {
return nil, errors.New("grpc url cannot be empty")
}
query, error := query.NewQueryClient(grpcUrl)
if error != nil {
return nil, error
}
client := &KavaGrpcClient{
Query: query,
Util: util.NewUtil(query),
config: config,
}
return client, nil
}

func NewDefaultConfig() KavaGrpcClientConfig {
return KavaGrpcClientConfig{}
}
15 changes: 15 additions & 0 deletions client/grpc/client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package grpc_test

import (
"testing"

"github.com/kava-labs/kava/client/grpc"
"github.com/stretchr/testify/require"
)

func TestNewClient_InvalidEndpoint(t *testing.T) {
_, err := grpc.NewClient("invalid-url")
require.ErrorContains(t, err, "unknown grpc url scheme")
_, err = grpc.NewClient("")
require.ErrorContains(t, err, "grpc url cannot be empty")
}
38 changes: 38 additions & 0 deletions client/grpc/query/connection.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package query

import (
"context"
"crypto/tls"
"fmt"
"net/url"

"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
)

// newGrpcConnection parses a GRPC endpoint and creates a connection to it
func newGrpcConnection(ctx context.Context, endpoint string) (*grpc.ClientConn, error) {
grpcUrl, err := url.Parse(endpoint)
if err != nil {
return nil, fmt.Errorf("failed to parse grpc connection \"%s\": %v", endpoint, err)
}

var creds credentials.TransportCredentials
switch grpcUrl.Scheme {
case "http":
creds = insecure.NewCredentials()
case "https":
creds = credentials.NewTLS(&tls.Config{})
default:
return nil, fmt.Errorf("unknown grpc url scheme: %s", grpcUrl.Scheme)
}

secureOpt := grpc.WithTransportCredentials(creds)
grpcConn, err := grpc.DialContext(ctx, grpcUrl.Host, secureOpt)
if err != nil {
return nil, err
}

return grpcConn, nil
}
7 changes: 7 additions & 0 deletions client/grpc/query/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
The query package includes Cosmos and Kava gRPC query clients.

To ensure that the `QueryClient` stays updated, add new module query clients
to the `QueryClient` whenever new modules with grpc queries are added to the Kava app.
*/
package query
132 changes: 132 additions & 0 deletions client/grpc/query/query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package query

import (
"context"

"github.com/cosmos/cosmos-sdk/client/grpc/tmservice"
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
authz "github.com/cosmos/cosmos-sdk/x/authz"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
disttypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types"
govv1types "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
govv1beta1types "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
paramstypes "github.com/cosmos/cosmos-sdk/x/params/types/proposal"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"

ibctransfertypes "github.com/cosmos/ibc-go/v6/modules/apps/transfer/types"
ibcclienttypes "github.com/cosmos/ibc-go/v6/modules/core/02-client/types"
evmtypes "github.com/evmos/ethermint/x/evm/types"
feemarkettypes "github.com/evmos/ethermint/x/feemarket/types"

auctiontypes "github.com/kava-labs/kava/x/auction/types"
bep3types "github.com/kava-labs/kava/x/bep3/types"
cdptypes "github.com/kava-labs/kava/x/cdp/types"
committeetypes "github.com/kava-labs/kava/x/committee/types"
communitytypes "github.com/kava-labs/kava/x/community/types"
earntypes "github.com/kava-labs/kava/x/earn/types"
evmutiltypes "github.com/kava-labs/kava/x/evmutil/types"
hardtypes "github.com/kava-labs/kava/x/hard/types"
incentivetypes "github.com/kava-labs/kava/x/incentive/types"
issuancetypes "github.com/kava-labs/kava/x/issuance/types"
kavadisttypes "github.com/kava-labs/kava/x/kavadist/types"
liquidtypes "github.com/kava-labs/kava/x/liquid/types"
pricefeedtypes "github.com/kava-labs/kava/x/pricefeed/types"
savingstypes "github.com/kava-labs/kava/x/savings/types"
swaptypes "github.com/kava-labs/kava/x/swap/types"
)

// QueryClient is a wrapper with all Cosmos and Kava grpc query clients
type QueryClient struct {
// cosmos-sdk query clients

Tm tmservice.ServiceClient
Tx txtypes.ServiceClient
Auth authtypes.QueryClient
Authz authz.QueryClient
Bank banktypes.QueryClient
Distribution disttypes.QueryClient
Evidence evidencetypes.QueryClient
Gov govv1types.QueryClient
GovBeta govv1beta1types.QueryClient
Mint minttypes.QueryClient
Params paramstypes.QueryClient
Slashing slashingtypes.QueryClient
Staking stakingtypes.QueryClient
Upgrade upgradetypes.QueryClient

// 3rd party query clients

Evm evmtypes.QueryClient
Feemarket feemarkettypes.QueryClient
IbcClient ibcclienttypes.QueryClient
IbcTransfer ibctransfertypes.QueryClient

// kava module query clients

Auction auctiontypes.QueryClient
Bep3 bep3types.QueryClient
Cdp cdptypes.QueryClient
Committee committeetypes.QueryClient
Community communitytypes.QueryClient
Earn earntypes.QueryClient
Evmutil evmutiltypes.QueryClient
Hard hardtypes.QueryClient
Incentive incentivetypes.QueryClient
Issuance issuancetypes.QueryClient
Kavadist kavadisttypes.QueryClient
Liquid liquidtypes.QueryClient
Pricefeed pricefeedtypes.QueryClient
Savings savingstypes.QueryClient
Swap swaptypes.QueryClient
}

// NewQueryClient creates a new QueryClient and initializes all the module query clients
func NewQueryClient(grpcEndpoint string) (*QueryClient, error) {
conn, err := newGrpcConnection(context.Background(), grpcEndpoint)
if err != nil {
return &QueryClient{}, err
}
client := &QueryClient{
Tm: tmservice.NewServiceClient(conn),
Tx: txtypes.NewServiceClient(conn),
Auth: authtypes.NewQueryClient(conn),
Authz: authz.NewQueryClient(conn),
Bank: banktypes.NewQueryClient(conn),
Distribution: disttypes.NewQueryClient(conn),
Evidence: evidencetypes.NewQueryClient(conn),
Gov: govv1types.NewQueryClient(conn),
GovBeta: govv1beta1types.NewQueryClient(conn),
Mint: minttypes.NewQueryClient(conn),
Params: paramstypes.NewQueryClient(conn),
Slashing: slashingtypes.NewQueryClient(conn),
Staking: stakingtypes.NewQueryClient(conn),
Upgrade: upgradetypes.NewQueryClient(conn),

Evm: evmtypes.NewQueryClient(conn),
Feemarket: feemarkettypes.NewQueryClient(conn),
IbcClient: ibcclienttypes.NewQueryClient(conn),
IbcTransfer: ibctransfertypes.NewQueryClient(conn),

Auction: auctiontypes.NewQueryClient(conn),
Bep3: bep3types.NewQueryClient(conn),
Cdp: cdptypes.NewQueryClient(conn),
Committee: committeetypes.NewQueryClient(conn),
Community: communitytypes.NewQueryClient(conn),
Earn: earntypes.NewQueryClient(conn),
Evmutil: evmutiltypes.NewQueryClient(conn),
Hard: hardtypes.NewQueryClient(conn),
Incentive: incentivetypes.NewQueryClient(conn),
Issuance: issuancetypes.NewQueryClient(conn),
Kavadist: kavadisttypes.NewQueryClient(conn),
Liquid: liquidtypes.NewQueryClient(conn),
Pricefeed: pricefeedtypes.NewQueryClient(conn),
Savings: savingstypes.NewQueryClient(conn),
Swap: swaptypes.NewQueryClient(conn),
}
return client, nil
}
Loading
Loading