mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-26 00:05:18 +00:00
Kava gRPC Client (#1784)
* add grpc client * add e2e tests for grpc client * add grpc client readme * doc update * fix more doc issues * remove util namespace & move grpc client to chain * rename GrpcClient to Grpc * add 3rd party query clients * fix invalid url in readme * update e2e tests to use grpc client (#1787)
This commit is contained in:
parent
c63fab1317
commit
ffd306ef52
@ -44,6 +44,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||||||
- (community) [#1704] Add module params
|
- (community) [#1704] Add module params
|
||||||
- (community) [#1706] Add disable inflation upgrade
|
- (community) [#1706] Add disable inflation upgrade
|
||||||
- (community) [#1745] Enable params update via governance with `MsgUpdateParams`
|
- (community) [#1745] Enable params update via governance with `MsgUpdateParams`
|
||||||
|
- (client) [#1784] Add Kava gRPC client
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
@ -72,6 +73,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||||||
## [v0.24.1]
|
## [v0.24.1]
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
- (metrics) [#1668] Adds non-state breaking x/metrics module for custom telemetry.
|
- (metrics) [#1668] Adds non-state breaking x/metrics module for custom telemetry.
|
||||||
- (metrics) [#1669] Add performance timing metrics to all Begin/EndBlockers
|
- (metrics) [#1669] Add performance timing metrics to all Begin/EndBlockers
|
||||||
- (community) [#1751] Add `AnnualizedRewards` query endpoint
|
- (community) [#1751] Add `AnnualizedRewards` query endpoint
|
||||||
@ -315,6 +317,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
|
- [#257](https://github.com/Kava-Labs/kava/pulls/257) Include scripts to run
|
||||||
large-scale simulations remotely using aws-batch
|
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
|
[#1776]: https://github.com/Kava-Labs/kava/pull/1776
|
||||||
[#1770]: https://github.com/Kava-Labs/kava/pull/1770
|
[#1770]: https://github.com/Kava-Labs/kava/pull/1770
|
||||||
[#1755]: https://github.com/Kava-Labs/kava/pull/1755
|
[#1755]: https://github.com/Kava-Labs/kava/pull/1755
|
||||||
|
74
client/grpc/README.md
Normal file
74
client/grpc/README.md
Normal file
@ -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
|
||||||
|
|
||||||
|
### 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(grpcUrl)
|
||||||
|
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
client/grpc/client.go
Normal file
50
client/grpc/client.go
Normal file
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
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
client/grpc/client_test.go
Normal file
15
client/grpc/client_test.go
Normal file
@ -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")
|
||||||
|
}
|
@ -1,25 +1,21 @@
|
|||||||
package util
|
package query
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
"google.golang.org/grpc/credentials/insecure"
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
"google.golang.org/grpc/metadata"
|
|
||||||
|
|
||||||
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewGrpcConnection parses a GRPC endpoint and creates a connection to it
|
// newGrpcConnection parses a GRPC endpoint and creates a connection to it
|
||||||
func NewGrpcConnection(endpoint string) (*grpc.ClientConn, error) {
|
func newGrpcConnection(ctx context.Context, endpoint string) (*grpc.ClientConn, error) {
|
||||||
grpcUrl, err := url.Parse(endpoint)
|
grpcUrl, err := url.Parse(endpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("failed to parse grpc connection \"%s\": %v", endpoint, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var creds credentials.TransportCredentials
|
var creds credentials.TransportCredentials
|
||||||
@ -33,15 +29,10 @@ func NewGrpcConnection(endpoint string) (*grpc.ClientConn, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
secureOpt := grpc.WithTransportCredentials(creds)
|
secureOpt := grpc.WithTransportCredentials(creds)
|
||||||
grpcConn, err := grpc.Dial(grpcUrl.Host, secureOpt)
|
grpcConn, err := grpc.DialContext(ctx, grpcUrl.Host, secureOpt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return grpcConn, nil
|
return grpcConn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CtxAtHeight(height int64) context.Context {
|
|
||||||
heightStr := strconv.FormatInt(height, 10)
|
|
||||||
return metadata.AppendToOutgoingContext(context.Background(), grpctypes.GRPCBlockHeightHeader, heightStr)
|
|
||||||
}
|
|
7
client/grpc/query/doc.go
Normal file
7
client/grpc/query/doc.go
Normal file
@ -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
client/grpc/query/query.go
Normal file
132
client/grpc/query/query.go
Normal file
@ -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
|
||||||
|
}
|
73
client/grpc/query/query_test.go
Normal file
73
client/grpc/query/query_test.go
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
package query_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/kava-labs/kava/client/grpc/query"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewQueryClient_InvalidGprc(t *testing.T) {
|
||||||
|
t.Run("valid connection", func(t *testing.T) {
|
||||||
|
conn, err := query.NewQueryClient("http://localhost:1234")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, conn)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("non-empty url", func(t *testing.T) {
|
||||||
|
_, err := query.NewQueryClient("")
|
||||||
|
require.ErrorContains(t, err, "unknown grpc url scheme")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("invalid url scheme", func(t *testing.T) {
|
||||||
|
_, err := query.NewQueryClient("ftp://localhost:1234")
|
||||||
|
require.ErrorContains(t, err, "unknown grpc url scheme")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewQueryClient_ValidClient(t *testing.T) {
|
||||||
|
t.Run("all clients are created", func(t *testing.T) {
|
||||||
|
client, err := query.NewQueryClient("http://localhost:1234")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, client)
|
||||||
|
|
||||||
|
// validate cosmos clients
|
||||||
|
require.NotNil(t, client.Tm)
|
||||||
|
require.NotNil(t, client.Tx)
|
||||||
|
require.NotNil(t, client.Auth)
|
||||||
|
require.NotNil(t, client.Authz)
|
||||||
|
require.NotNil(t, client.Bank)
|
||||||
|
require.NotNil(t, client.Distribution)
|
||||||
|
require.NotNil(t, client.Evidence)
|
||||||
|
require.NotNil(t, client.Gov)
|
||||||
|
require.NotNil(t, client.GovBeta)
|
||||||
|
require.NotNil(t, client.Mint)
|
||||||
|
require.NotNil(t, client.Params)
|
||||||
|
require.NotNil(t, client.Slashing)
|
||||||
|
require.NotNil(t, client.Staking)
|
||||||
|
require.NotNil(t, client.Upgrade)
|
||||||
|
|
||||||
|
// validate 3rd party clients
|
||||||
|
require.NotNil(t, client.Evm)
|
||||||
|
require.NotNil(t, client.Feemarket)
|
||||||
|
require.NotNil(t, client.IbcClient)
|
||||||
|
require.NotNil(t, client.IbcTransfer)
|
||||||
|
|
||||||
|
// validate kava clients
|
||||||
|
require.NotNil(t, client.Auction)
|
||||||
|
require.NotNil(t, client.Bep3)
|
||||||
|
require.NotNil(t, client.Cdp)
|
||||||
|
require.NotNil(t, client.Committee)
|
||||||
|
require.NotNil(t, client.Community)
|
||||||
|
require.NotNil(t, client.Earn)
|
||||||
|
require.NotNil(t, client.Evmutil)
|
||||||
|
require.NotNil(t, client.Hard)
|
||||||
|
require.NotNil(t, client.Incentive)
|
||||||
|
require.NotNil(t, client.Issuance)
|
||||||
|
require.NotNil(t, client.Kavadist)
|
||||||
|
require.NotNil(t, client.Liquid)
|
||||||
|
require.NotNil(t, client.Pricefeed)
|
||||||
|
require.NotNil(t, client.Savings)
|
||||||
|
require.NotNil(t, client.Swap)
|
||||||
|
})
|
||||||
|
}
|
41
client/grpc/util/account.go
Normal file
41
client/grpc/util/account.go
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Account fetches an account via an address and returns the unpacked account
|
||||||
|
func (u *Util) Account(addr string) (authtypes.AccountI, error) {
|
||||||
|
res, err := u.query.Auth.Account(context.Background(), &authtypes.QueryAccountRequest{
|
||||||
|
Address: addr,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to fetch account: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var acc authtypes.AccountI
|
||||||
|
err = u.encodingConfig.Marshaler.UnpackAny(res.Account, &acc)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to unpack account: %w", err)
|
||||||
|
}
|
||||||
|
return acc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// BaseAccount fetches a base account via an address or returns an error if
|
||||||
|
// the account is not a base account
|
||||||
|
func (u *Util) BaseAccount(addr string) (authtypes.BaseAccount, error) {
|
||||||
|
acc, err := u.Account(addr)
|
||||||
|
if err != nil {
|
||||||
|
return authtypes.BaseAccount{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
bAcc, ok := acc.(*authtypes.BaseAccount)
|
||||||
|
if !ok {
|
||||||
|
return authtypes.BaseAccount{}, fmt.Errorf("%s is not a base account", addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
return *bAcc, nil
|
||||||
|
}
|
8
client/grpc/util/doc.go
Normal file
8
client/grpc/util/doc.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/*
|
||||||
|
The util package contains utility functions for the Kava gRPC client.
|
||||||
|
|
||||||
|
For example, `account.go` includes account-related query helpers.
|
||||||
|
In this file, utilities such as `client.Util.BaseAccount(addr)` is exposed to
|
||||||
|
query an account and return an unpacked `BaseAccount` instance.
|
||||||
|
*/
|
||||||
|
package util
|
32
client/grpc/util/util.go
Normal file
32
client/grpc/util/util.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
|
||||||
|
"google.golang.org/grpc/metadata"
|
||||||
|
|
||||||
|
"github.com/kava-labs/kava/app"
|
||||||
|
"github.com/kava-labs/kava/app/params"
|
||||||
|
query "github.com/kava-labs/kava/client/grpc/query"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Util contains utility functions for the Kava gRPC client
|
||||||
|
type Util struct {
|
||||||
|
query *query.QueryClient
|
||||||
|
encodingConfig params.EncodingConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewUtil creates a new Util instance
|
||||||
|
func NewUtil(query *query.QueryClient) *Util {
|
||||||
|
return &Util{
|
||||||
|
query: query,
|
||||||
|
encodingConfig: app.MakeEncodingConfig(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *Util) CtxAtHeight(height int64) context.Context {
|
||||||
|
heightStr := strconv.FormatInt(height, 10)
|
||||||
|
return metadata.AppendToOutgoingContext(context.Background(), grpctypes.GRPCBlockHeightHeader, heightStr)
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package client
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
@ -18,9 +18,9 @@ import (
|
|||||||
|
|
||||||
var ethFlag = "eth"
|
var ethFlag = "eth"
|
||||||
|
|
||||||
// KeyCommands registers a sub-tree of commands to interact with
|
// keyCommands registers a sub-tree of commands to interact with
|
||||||
// local private key storage.
|
// local private key storage.
|
||||||
func KeyCommands(defaultNodeHome string) *cobra.Command {
|
func keyCommands(defaultNodeHome string) *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "keys",
|
Use: "keys",
|
||||||
Short: "Manage your application's keys",
|
Short: "Manage your application's keys",
|
@ -22,7 +22,6 @@ import (
|
|||||||
|
|
||||||
"github.com/kava-labs/kava/app"
|
"github.com/kava-labs/kava/app"
|
||||||
"github.com/kava-labs/kava/app/params"
|
"github.com/kava-labs/kava/app/params"
|
||||||
kavaclient "github.com/kava-labs/kava/client"
|
|
||||||
"github.com/kava-labs/kava/cmd/kava/opendb"
|
"github.com/kava-labs/kava/cmd/kava/opendb"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -123,6 +122,6 @@ func addSubCmds(rootCmd *cobra.Command, encodingConfig params.EncodingConfig, de
|
|||||||
rootCmd.AddCommand(
|
rootCmd.AddCommand(
|
||||||
newQueryCmd(),
|
newQueryCmd(),
|
||||||
newTxCmd(),
|
newTxCmd(),
|
||||||
kavaclient.KeyCommands(app.DefaultNodeHome),
|
keyCommands(app.DefaultNodeHome),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ func (suite *IntegrationTestSuite) TestCommunityUpdateParams_NonAuthority() {
|
|||||||
res := kavaAcc.SignAndBroadcastKavaTx(req)
|
res := kavaAcc.SignAndBroadcastKavaTx(req)
|
||||||
|
|
||||||
// ASSERT
|
// ASSERT
|
||||||
_, err := util.WaitForSdkTxCommit(suite.Kava.Tx, res.Result.TxHash, 6*time.Second)
|
_, err := util.WaitForSdkTxCommit(suite.Kava.Grpc.Query.Tx, res.Result.TxHash, 6*time.Second)
|
||||||
suite.Require().Error(err)
|
suite.Require().Error(err)
|
||||||
suite.Require().ErrorContains(
|
suite.Require().ErrorContains(
|
||||||
err,
|
err,
|
||||||
@ -52,13 +52,13 @@ func (suite *IntegrationTestSuite) TestCommunityUpdateParams_NonAuthority() {
|
|||||||
|
|
||||||
func (suite *IntegrationTestSuite) TestCommunityUpdateParams_Authority() {
|
func (suite *IntegrationTestSuite) TestCommunityUpdateParams_Authority() {
|
||||||
// ARRANGE
|
// ARRANGE
|
||||||
govParamsRes, err := suite.Kava.Gov.Params(context.Background(), &govv1.QueryParamsRequest{
|
govParamsRes, err := suite.Kava.Grpc.Query.Gov.Params(context.Background(), &govv1.QueryParamsRequest{
|
||||||
ParamsType: govv1.ParamDeposit,
|
ParamsType: govv1.ParamDeposit,
|
||||||
})
|
})
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
|
|
||||||
// Check initial params
|
// Check initial params
|
||||||
communityParamsResInitial, err := suite.Kava.Community.Params(
|
communityParamsResInitial, err := suite.Kava.Grpc.Query.Community.Params(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
&communitytypes.QueryParamsRequest{},
|
&communitytypes.QueryParamsRequest{},
|
||||||
)
|
)
|
||||||
@ -77,7 +77,7 @@ func (suite *IntegrationTestSuite) TestCommunityUpdateParams_Authority() {
|
|||||||
// genesis should be set in the past so it runs immediately.
|
// genesis should be set in the past so it runs immediately.
|
||||||
suite.Require().Eventually(
|
suite.Require().Eventually(
|
||||||
func() bool {
|
func() bool {
|
||||||
params, err := suite.Kava.Community.Params(
|
params, err := suite.Kava.Grpc.Query.Community.Params(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
&communitytypes.QueryParamsRequest{},
|
&communitytypes.QueryParamsRequest{},
|
||||||
)
|
)
|
||||||
@ -132,7 +132,7 @@ func (suite *IntegrationTestSuite) TestCommunityUpdateParams_Authority() {
|
|||||||
suite.Require().NoError(res.Err)
|
suite.Require().NoError(res.Err)
|
||||||
|
|
||||||
// Wait for proposal to be submitted
|
// Wait for proposal to be submitted
|
||||||
txRes, err := util.WaitForSdkTxCommit(suite.Kava.Tx, res.Result.TxHash, 6*time.Second)
|
txRes, err := util.WaitForSdkTxCommit(suite.Kava.Grpc.Query.Tx, res.Result.TxHash, 6*time.Second)
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
// Parse tx response to get proposal id
|
// Parse tx response to get proposal id
|
||||||
@ -157,12 +157,12 @@ func (suite *IntegrationTestSuite) TestCommunityUpdateParams_Authority() {
|
|||||||
voteRes := whale.SignAndBroadcastKavaTx(voteReq)
|
voteRes := whale.SignAndBroadcastKavaTx(voteReq)
|
||||||
suite.Require().NoError(voteRes.Err)
|
suite.Require().NoError(voteRes.Err)
|
||||||
|
|
||||||
_, err = util.WaitForSdkTxCommit(suite.Kava.Tx, voteRes.Result.TxHash, 6*time.Second)
|
_, err = util.WaitForSdkTxCommit(suite.Kava.Grpc.Query.Tx, voteRes.Result.TxHash, 6*time.Second)
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
// 3. Wait until proposal passes
|
// 3. Wait until proposal passes
|
||||||
suite.Require().Eventually(func() bool {
|
suite.Require().Eventually(func() bool {
|
||||||
proposalRes, err := suite.Kava.Gov.Proposal(context.Background(), &govv1.QueryProposalRequest{
|
proposalRes, err := suite.Kava.Grpc.Query.Gov.Proposal(context.Background(), &govv1.QueryProposalRequest{
|
||||||
ProposalId: govRes.ProposalId,
|
ProposalId: govRes.ProposalId,
|
||||||
})
|
})
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
@ -171,7 +171,7 @@ func (suite *IntegrationTestSuite) TestCommunityUpdateParams_Authority() {
|
|||||||
}, 60*time.Second, 1*time.Second)
|
}, 60*time.Second, 1*time.Second)
|
||||||
|
|
||||||
// Check parameters are updated
|
// Check parameters are updated
|
||||||
communityParamsRes, err := suite.Kava.Community.Params(
|
communityParamsRes, err := suite.Kava.Grpc.Query.Community.Params(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
&communitytypes.QueryParamsRequest{},
|
&communitytypes.QueryParamsRequest{},
|
||||||
)
|
)
|
||||||
|
@ -24,7 +24,10 @@ func setupConvertToCoinTest(
|
|||||||
) (denom string, initialFunds sdk.Coins, user *testutil.SigningAccount) {
|
) (denom string, initialFunds sdk.Coins, user *testutil.SigningAccount) {
|
||||||
// we expect a denom to be registered to the allowed denoms param
|
// we expect a denom to be registered to the allowed denoms param
|
||||||
// and for the funded account to have a balance for that denom
|
// and for the funded account to have a balance for that denom
|
||||||
params, err := suite.Kava.Evmutil.Params(context.Background(), &evmutiltypes.QueryParamsRequest{})
|
params, err := suite.Kava.Grpc.Query.Evmutil.Params(
|
||||||
|
context.Background(),
|
||||||
|
&evmutiltypes.QueryParamsRequest{},
|
||||||
|
)
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
suite.GreaterOrEqual(
|
suite.GreaterOrEqual(
|
||||||
len(params.Params.AllowedCosmosDenoms), 1,
|
len(params.Params.AllowedCosmosDenoms), 1,
|
||||||
@ -73,7 +76,7 @@ func (suite *IntegrationTestSuite) setupAccountWithCosmosCoinERC20Balance(
|
|||||||
sdkBalance = sdkBalance.Sub(convertAmount)
|
sdkBalance = sdkBalance.Sub(convertAmount)
|
||||||
|
|
||||||
// query for the deployed contract
|
// query for the deployed contract
|
||||||
deployedContracts, err := suite.Kava.Evmutil.DeployedCosmosCoinContracts(
|
deployedContracts, err := suite.Kava.Grpc.Query.Evmutil.DeployedCosmosCoinContracts(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
&evmutiltypes.QueryDeployedCosmosCoinContractsRequest{CosmosDenoms: []string{denom}},
|
&evmutiltypes.QueryDeployedCosmosCoinContractsRequest{CosmosDenoms: []string{denom}},
|
||||||
)
|
)
|
||||||
@ -109,7 +112,7 @@ func (suite *IntegrationTestSuite) TestConvertCosmosCoinsToFromERC20() {
|
|||||||
suite.NoError(res.Err)
|
suite.NoError(res.Err)
|
||||||
|
|
||||||
// query for the deployed contract
|
// query for the deployed contract
|
||||||
deployedContracts, err := suite.Kava.Evmutil.DeployedCosmosCoinContracts(
|
deployedContracts, err := suite.Kava.Grpc.Query.Evmutil.DeployedCosmosCoinContracts(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
&evmutiltypes.QueryDeployedCosmosCoinContractsRequest{CosmosDenoms: []string{denom}},
|
&evmutiltypes.QueryDeployedCosmosCoinContractsRequest{CosmosDenoms: []string{denom}},
|
||||||
)
|
)
|
||||||
@ -191,18 +194,18 @@ func (suite *IntegrationTestSuite) TestEIP712ConvertCosmosCoinsToFromERC20() {
|
|||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
|
|
||||||
// submit the eip712 message to the chain.
|
// submit the eip712 message to the chain.
|
||||||
res, err := suite.Kava.Tx.BroadcastTx(context.Background(), &txtypes.BroadcastTxRequest{
|
res, err := suite.Kava.Grpc.Query.Tx.BroadcastTx(context.Background(), &txtypes.BroadcastTxRequest{
|
||||||
TxBytes: txBytes,
|
TxBytes: txBytes,
|
||||||
Mode: txtypes.BroadcastMode_BROADCAST_MODE_SYNC,
|
Mode: txtypes.BroadcastMode_BROADCAST_MODE_SYNC,
|
||||||
})
|
})
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
suite.Equal(sdkerrors.SuccessABCICode, res.TxResponse.Code)
|
suite.Equal(sdkerrors.SuccessABCICode, res.TxResponse.Code)
|
||||||
|
|
||||||
_, err = util.WaitForSdkTxCommit(suite.Kava.Tx, res.TxResponse.TxHash, 12*time.Second)
|
_, err = util.WaitForSdkTxCommit(suite.Kava.Grpc.Query.Tx, res.TxResponse.TxHash, 12*time.Second)
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
// query for the deployed contract
|
// query for the deployed contract
|
||||||
deployedContracts, err := suite.Kava.Evmutil.DeployedCosmosCoinContracts(
|
deployedContracts, err := suite.Kava.Grpc.Query.Evmutil.DeployedCosmosCoinContracts(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
&evmutiltypes.QueryDeployedCosmosCoinContractsRequest{CosmosDenoms: []string{denom}},
|
&evmutiltypes.QueryDeployedCosmosCoinContractsRequest{CosmosDenoms: []string{denom}},
|
||||||
)
|
)
|
||||||
@ -245,14 +248,14 @@ func (suite *IntegrationTestSuite) TestEIP712ConvertCosmosCoinsToFromERC20() {
|
|||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
|
|
||||||
// submit the eip712 message to the chain
|
// submit the eip712 message to the chain
|
||||||
res, err = suite.Kava.Tx.BroadcastTx(context.Background(), &txtypes.BroadcastTxRequest{
|
res, err = suite.Kava.Grpc.Query.Tx.BroadcastTx(context.Background(), &txtypes.BroadcastTxRequest{
|
||||||
TxBytes: txBytes,
|
TxBytes: txBytes,
|
||||||
Mode: txtypes.BroadcastMode_BROADCAST_MODE_SYNC,
|
Mode: txtypes.BroadcastMode_BROADCAST_MODE_SYNC,
|
||||||
})
|
})
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
suite.Equal(sdkerrors.SuccessABCICode, res.TxResponse.Code)
|
suite.Equal(sdkerrors.SuccessABCICode, res.TxResponse.Code)
|
||||||
|
|
||||||
_, err = util.WaitForSdkTxCommit(suite.Kava.Tx, res.TxResponse.TxHash, 6*time.Second)
|
_, err = util.WaitForSdkTxCommit(suite.Kava.Grpc.Query.Tx, res.TxResponse.TxHash, 6*time.Second)
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
|
|
||||||
// check erc20 balance
|
// check erc20 balance
|
||||||
|
@ -87,18 +87,18 @@ func (suite *IntegrationTestSuite) TestEip712BasicMessageAuthorization() {
|
|||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
|
|
||||||
// broadcast tx
|
// broadcast tx
|
||||||
res, err := suite.Kava.Tx.BroadcastTx(context.Background(), &txtypes.BroadcastTxRequest{
|
res, err := suite.Kava.Grpc.Query.Tx.BroadcastTx(context.Background(), &txtypes.BroadcastTxRequest{
|
||||||
TxBytes: txBytes,
|
TxBytes: txBytes,
|
||||||
Mode: txtypes.BroadcastMode_BROADCAST_MODE_SYNC,
|
Mode: txtypes.BroadcastMode_BROADCAST_MODE_SYNC,
|
||||||
})
|
})
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
suite.Equal(sdkerrors.SuccessABCICode, res.TxResponse.Code)
|
suite.Equal(sdkerrors.SuccessABCICode, res.TxResponse.Code)
|
||||||
|
|
||||||
_, err = util.WaitForSdkTxCommit(suite.Kava.Tx, res.TxResponse.TxHash, 6*time.Second)
|
_, err = util.WaitForSdkTxCommit(suite.Kava.Grpc.Query.Tx, res.TxResponse.TxHash, 6*time.Second)
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
|
|
||||||
// check that the message was processed & the kava is transferred.
|
// check that the message was processed & the kava is transferred.
|
||||||
balRes, err := suite.Kava.Bank.Balance(context.Background(), &banktypes.QueryBalanceRequest{
|
balRes, err := suite.Kava.Grpc.Query.Bank.Balance(context.Background(), &banktypes.QueryBalanceRequest{
|
||||||
Address: receiver.String(),
|
Address: receiver.String(),
|
||||||
Denom: "ukava",
|
Denom: "ukava",
|
||||||
})
|
})
|
||||||
@ -154,14 +154,14 @@ func (suite *IntegrationTestSuite) TestEip712ConvertToCoinAndDepositToLend() {
|
|||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
|
|
||||||
// broadcast tx
|
// broadcast tx
|
||||||
res, err := suite.Kava.Tx.BroadcastTx(context.Background(), &txtypes.BroadcastTxRequest{
|
res, err := suite.Kava.Grpc.Query.Tx.BroadcastTx(context.Background(), &txtypes.BroadcastTxRequest{
|
||||||
TxBytes: txBytes,
|
TxBytes: txBytes,
|
||||||
Mode: txtypes.BroadcastMode_BROADCAST_MODE_SYNC,
|
Mode: txtypes.BroadcastMode_BROADCAST_MODE_SYNC,
|
||||||
})
|
})
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
suite.Equal(sdkerrors.SuccessABCICode, res.TxResponse.Code)
|
suite.Equal(sdkerrors.SuccessABCICode, res.TxResponse.Code)
|
||||||
|
|
||||||
_, err = util.WaitForSdkTxCommit(suite.Kava.Tx, res.TxResponse.TxHash, 6*time.Second)
|
_, err = util.WaitForSdkTxCommit(suite.Kava.Grpc.Query.Tx, res.TxResponse.TxHash, 6*time.Second)
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
// check that depositor no longer has erc20 balance
|
// check that depositor no longer has erc20 balance
|
||||||
@ -169,7 +169,7 @@ func (suite *IntegrationTestSuite) TestEip712ConvertToCoinAndDepositToLend() {
|
|||||||
suite.BigIntsEqual(big.NewInt(0), balance, "expected no erc20 balance")
|
suite.BigIntsEqual(big.NewInt(0), balance, "expected no erc20 balance")
|
||||||
|
|
||||||
// check that account has cdp
|
// check that account has cdp
|
||||||
cdpRes, err := suite.Kava.Cdp.Cdp(context.Background(), &cdptypes.QueryCdpRequest{
|
cdpRes, err := suite.Kava.Grpc.Query.Cdp.Cdp(context.Background(), &cdptypes.QueryCdpRequest{
|
||||||
CollateralType: suite.DeployedErc20.CdpCollateralType,
|
CollateralType: suite.DeployedErc20.CdpCollateralType,
|
||||||
Owner: depositor.SdkAddress.String(),
|
Owner: depositor.SdkAddress.String(),
|
||||||
})
|
})
|
||||||
|
39
tests/e2e/e2e_grpc_client_query_test.go
Normal file
39
tests/e2e/e2e_grpc_client_query_test.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package e2e_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||||
|
|
||||||
|
evmutiltypes "github.com/kava-labs/kava/x/evmutil/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (suite *IntegrationTestSuite) TestGrpcClientQueryCosmosModule_Balance() {
|
||||||
|
// ARRANGE
|
||||||
|
// setup kava account
|
||||||
|
funds := ukava(1e5) // .1 KAVA
|
||||||
|
kavaAcc := suite.Kava.NewFundedAccount("balance-test", sdk.NewCoins(funds))
|
||||||
|
|
||||||
|
// ACT
|
||||||
|
rsp, err := suite.Kava.Grpc.Query.Bank.Balance(context.Background(), &banktypes.QueryBalanceRequest{
|
||||||
|
Address: kavaAcc.SdkAddress.String(),
|
||||||
|
Denom: funds.Denom,
|
||||||
|
})
|
||||||
|
|
||||||
|
// ASSERT
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
suite.Require().Equal(funds.Amount, rsp.Balance.Amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *IntegrationTestSuite) TestGrpcClientQueryKavaModule_EvmParams() {
|
||||||
|
// ACT
|
||||||
|
rsp, err := suite.Kava.Grpc.Query.Evmutil.Params(
|
||||||
|
context.Background(), &evmutiltypes.QueryParamsRequest{},
|
||||||
|
)
|
||||||
|
|
||||||
|
// ASSERT
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
suite.Require().GreaterOrEqual(len(rsp.Params.AllowedCosmosDenoms), 1)
|
||||||
|
suite.Require().GreaterOrEqual(len(rsp.Params.EnabledConversionPairs), 1)
|
||||||
|
}
|
20
tests/e2e/e2e_grpc_client_util_test.go
Normal file
20
tests/e2e/e2e_grpc_client_util_test.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package e2e_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (suite *IntegrationTestSuite) TestGrpcClientUtil_Account() {
|
||||||
|
// ARRANGE
|
||||||
|
// setup kava account
|
||||||
|
kavaAcc := suite.Kava.NewFundedAccount("account-test", sdk.NewCoins(ukava(1e5)))
|
||||||
|
|
||||||
|
// ACT
|
||||||
|
rsp, err := suite.Kava.Grpc.BaseAccount(kavaAcc.SdkAddress.String())
|
||||||
|
|
||||||
|
// ASSERT
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
suite.Equal(kavaAcc.SdkAddress.String(), rsp.Address)
|
||||||
|
suite.Greater(rsp.AccountNumber, uint64(1))
|
||||||
|
suite.Equal(uint64(0), rsp.Sequence)
|
||||||
|
}
|
@ -50,7 +50,7 @@ func (suite *IntegrationTestSuite) TestChainID() {
|
|||||||
suite.Equal(expectedEvmNetworkId, evmNetworkId)
|
suite.Equal(expectedEvmNetworkId, evmNetworkId)
|
||||||
|
|
||||||
// SDK query
|
// SDK query
|
||||||
nodeInfo, err := suite.Kava.Tm.GetNodeInfo(context.Background(), &tmservice.GetNodeInfoRequest{})
|
nodeInfo, err := suite.Kava.Grpc.Query.Tm.GetNodeInfo(context.Background(), &tmservice.GetNodeInfoRequest{})
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
suite.Equal(suite.Kava.ChainID, nodeInfo.DefaultNodeInfo.Network)
|
suite.Equal(suite.Kava.ChainID, nodeInfo.DefaultNodeInfo.Network)
|
||||||
}
|
}
|
||||||
@ -65,7 +65,7 @@ func (suite *IntegrationTestSuite) TestFundedAccount() {
|
|||||||
suite.Equal(acc.EvmAddress.Hex(), util.SdkToEvmAddress(acc.SdkAddress).Hex())
|
suite.Equal(acc.EvmAddress.Hex(), util.SdkToEvmAddress(acc.SdkAddress).Hex())
|
||||||
|
|
||||||
// check balance via SDK query
|
// check balance via SDK query
|
||||||
res, err := suite.Kava.Bank.Balance(context.Background(), banktypes.NewQueryBalanceRequest(
|
res, err := suite.Kava.Grpc.Query.Bank.Balance(context.Background(), banktypes.NewQueryBalanceRequest(
|
||||||
acc.SdkAddress, "ukava",
|
acc.SdkAddress, "ukava",
|
||||||
))
|
))
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
|
@ -13,6 +13,6 @@ func (suite *IntegrationTestSuite) TestUpgradeHandler() {
|
|||||||
suite.True(true)
|
suite.True(true)
|
||||||
|
|
||||||
// Uncomment & use these contexts to compare chain state before & after the upgrade occurs.
|
// Uncomment & use these contexts to compare chain state before & after the upgrade occurs.
|
||||||
// beforeUpgradeCtx := util.CtxAtHeight(suite.UpgradeHeight - 1)
|
// beforeUpgradeCtx := suite.Kava.Grpc.CtxAtHeight(suite.UpgradeHeight - 1)
|
||||||
// afterUpgradeCtx := util.CtxAtHeight(suite.UpgradeHeight)
|
// afterUpgradeCtx := suite.Kava.Grpc.CtxAtHeight(suite.UpgradeHeight)
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,6 @@ import (
|
|||||||
|
|
||||||
"github.com/ethereum/go-ethereum/ethclient"
|
"github.com/ethereum/go-ethereum/ethclient"
|
||||||
rpchttpclient "github.com/tendermint/tendermint/rpc/client/http"
|
rpchttpclient "github.com/tendermint/tendermint/rpc/client/http"
|
||||||
"google.golang.org/grpc"
|
|
||||||
|
|
||||||
"github.com/kava-labs/kava/tests/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -30,11 +27,6 @@ func (c ChainDetails) EvmClient() (*ethclient.Client, error) {
|
|||||||
return ethclient.Dial(c.EvmRpcUrl)
|
return ethclient.Dial(c.EvmRpcUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GrpcConn creates a new connection to the underlying Grpc url.
|
|
||||||
func (c ChainDetails) GrpcConn() (*grpc.ClientConn, error) {
|
|
||||||
return util.NewGrpcConnection(c.GrpcUrl)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RpcConn creates a new connection to the underlying Rpc url.
|
// RpcConn creates a new connection to the underlying Rpc url.
|
||||||
func (c ChainDetails) RpcConn() (*rpchttpclient.HTTP, error) {
|
func (c ChainDetails) RpcConn() (*rpchttpclient.HTTP, error) {
|
||||||
return rpchttpclient.New(c.RpcUrl, "/websocket")
|
return rpchttpclient.New(c.RpcUrl, "/websocket")
|
||||||
|
@ -6,6 +6,8 @@ import (
|
|||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client/grpc/tmservice"
|
"github.com/cosmos/cosmos-sdk/client/grpc/tmservice"
|
||||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||||
|
|
||||||
|
"github.com/kava-labs/kava/client/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
// LiveNodeRunnerConfig implements NodeRunner.
|
// LiveNodeRunnerConfig implements NodeRunner.
|
||||||
@ -49,20 +51,19 @@ func (r LiveNodeRunner) StartChains() Chains {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// determine chain id
|
// determine chain id
|
||||||
grpc, err := kavaChain.GrpcConn()
|
client, err := grpc.NewClient(kavaChain.GrpcUrl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("failed to establish grpc conn to %s: %s", r.config.KavaGrpcUrl, err))
|
panic(fmt.Sprintf("failed to create kava grpc client: %s", err))
|
||||||
}
|
}
|
||||||
tm := tmservice.NewServiceClient(grpc)
|
|
||||||
nodeInfo, err := tm.GetNodeInfo(context.Background(), &tmservice.GetNodeInfoRequest{})
|
nodeInfo, err := client.Query.Tm.GetNodeInfo(context.Background(), &tmservice.GetNodeInfoRequest{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("failed to fetch kava node info: %s", err))
|
panic(fmt.Sprintf("failed to fetch kava node info: %s", err))
|
||||||
}
|
}
|
||||||
kavaChain.ChainId = nodeInfo.DefaultNodeInfo.Network
|
kavaChain.ChainId = nodeInfo.DefaultNodeInfo.Network
|
||||||
|
|
||||||
// determine staking denom
|
// determine staking denom
|
||||||
staking := stakingtypes.NewQueryClient(grpc)
|
stakingParams, err := client.Query.Staking.Params(context.Background(), &stakingtypes.QueryParamsRequest{})
|
||||||
stakingParams, err := staking.Params(context.Background(), &stakingtypes.QueryParamsRequest{})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("failed to fetch kava staking params: %s", err))
|
panic(fmt.Sprintf("failed to fetch kava staking params: %s", err))
|
||||||
}
|
}
|
||||||
|
@ -101,8 +101,8 @@ func (chain *Chain) AddNewSigningAccountFromPrivKey(
|
|||||||
kavaSigner := util.NewKavaSigner(
|
kavaSigner := util.NewKavaSigner(
|
||||||
chainId,
|
chainId,
|
||||||
chain.EncodingConfig,
|
chain.EncodingConfig,
|
||||||
chain.Auth,
|
chain.Grpc.Query.Auth,
|
||||||
chain.Tx,
|
chain.Grpc.Query.Tx,
|
||||||
privKey,
|
privKey,
|
||||||
100,
|
100,
|
||||||
)
|
)
|
||||||
|
@ -8,18 +8,11 @@ import (
|
|||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client/grpc/tmservice"
|
|
||||||
"github.com/cosmos/cosmos-sdk/crypto/hd"
|
"github.com/cosmos/cosmos-sdk/crypto/hd"
|
||||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
|
|
||||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||||
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
|
|
||||||
govv1types "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
|
|
||||||
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
|
|
||||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
|
||||||
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
|
|
||||||
evmhd "github.com/evmos/ethermint/crypto/hd"
|
evmhd "github.com/evmos/ethermint/crypto/hd"
|
||||||
tmclient "github.com/tendermint/tendermint/rpc/client"
|
tmclient "github.com/tendermint/tendermint/rpc/client"
|
||||||
coretypes "github.com/tendermint/tendermint/rpc/core/types"
|
coretypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||||
@ -28,18 +21,11 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/ethclient"
|
"github.com/ethereum/go-ethereum/ethclient"
|
||||||
|
|
||||||
evmtypes "github.com/evmos/ethermint/x/evm/types"
|
|
||||||
|
|
||||||
"github.com/kava-labs/kava/app"
|
"github.com/kava-labs/kava/app"
|
||||||
kavaparams "github.com/kava-labs/kava/app/params"
|
kavaparams "github.com/kava-labs/kava/app/params"
|
||||||
|
"github.com/kava-labs/kava/client/grpc"
|
||||||
"github.com/kava-labs/kava/tests/e2e/runner"
|
"github.com/kava-labs/kava/tests/e2e/runner"
|
||||||
"github.com/kava-labs/kava/tests/util"
|
"github.com/kava-labs/kava/tests/util"
|
||||||
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"
|
|
||||||
kavadisttypes "github.com/kava-labs/kava/x/kavadist/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Chain wraps query clients & accounts for a network
|
// Chain wraps query clients & accounts for a network
|
||||||
@ -57,24 +43,9 @@ type Chain struct {
|
|||||||
|
|
||||||
EncodingConfig kavaparams.EncodingConfig
|
EncodingConfig kavaparams.EncodingConfig
|
||||||
|
|
||||||
Auth authtypes.QueryClient
|
|
||||||
Bank banktypes.QueryClient
|
|
||||||
Cdp cdptypes.QueryClient
|
|
||||||
Committee committeetypes.QueryClient
|
|
||||||
Community communitytypes.QueryClient
|
|
||||||
Distribution distrtypes.QueryClient
|
|
||||||
Kavadist kavadisttypes.QueryClient
|
|
||||||
Earn earntypes.QueryClient
|
|
||||||
Evm evmtypes.QueryClient
|
|
||||||
Evmutil evmutiltypes.QueryClient
|
|
||||||
Gov govv1types.QueryClient
|
|
||||||
Mint minttypes.QueryClient
|
|
||||||
Staking stakingtypes.QueryClient
|
|
||||||
Tm tmservice.ServiceClient
|
|
||||||
Tx txtypes.ServiceClient
|
|
||||||
Upgrade upgradetypes.QueryClient
|
|
||||||
|
|
||||||
TmSignClient tmclient.SignClient
|
TmSignClient tmclient.SignClient
|
||||||
|
|
||||||
|
Grpc *grpc.KavaGrpcClient
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewChain creates the query clients & signing account management for a chain run on a set of ports.
|
// NewChain creates the query clients & signing account management for a chain run on a set of ports.
|
||||||
@ -104,10 +75,11 @@ func NewChain(t *testing.T, details *runner.ChainDetails, fundedAccountMnemonic
|
|||||||
}
|
}
|
||||||
chain.Keyring = kr
|
chain.Keyring = kr
|
||||||
|
|
||||||
grpcConn, err := details.GrpcConn()
|
client, err := grpc.NewClient(details.GrpcUrl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return chain, err
|
chain.t.Fatalf("failed to create kava grpc client: %s", err)
|
||||||
}
|
}
|
||||||
|
chain.Grpc = client
|
||||||
|
|
||||||
chain.EvmClient, err = details.EvmClient()
|
chain.EvmClient, err = details.EvmClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -119,23 +91,6 @@ func NewChain(t *testing.T, details *runner.ChainDetails, fundedAccountMnemonic
|
|||||||
return chain, err
|
return chain, err
|
||||||
}
|
}
|
||||||
|
|
||||||
chain.Auth = authtypes.NewQueryClient(grpcConn)
|
|
||||||
chain.Bank = banktypes.NewQueryClient(grpcConn)
|
|
||||||
chain.Cdp = cdptypes.NewQueryClient(grpcConn)
|
|
||||||
chain.Committee = committeetypes.NewQueryClient(grpcConn)
|
|
||||||
chain.Community = communitytypes.NewQueryClient(grpcConn)
|
|
||||||
chain.Distribution = distrtypes.NewQueryClient(grpcConn)
|
|
||||||
chain.Kavadist = kavadisttypes.NewQueryClient(grpcConn)
|
|
||||||
chain.Earn = earntypes.NewQueryClient(grpcConn)
|
|
||||||
chain.Evm = evmtypes.NewQueryClient(grpcConn)
|
|
||||||
chain.Evmutil = evmutiltypes.NewQueryClient(grpcConn)
|
|
||||||
chain.Gov = govv1types.NewQueryClient(grpcConn)
|
|
||||||
chain.Mint = minttypes.NewQueryClient(grpcConn)
|
|
||||||
chain.Staking = stakingtypes.NewQueryClient(grpcConn)
|
|
||||||
chain.Tm = tmservice.NewServiceClient(grpcConn)
|
|
||||||
chain.Tx = txtypes.NewServiceClient(grpcConn)
|
|
||||||
chain.Upgrade = upgradetypes.NewQueryClient(grpcConn)
|
|
||||||
|
|
||||||
// initialize accounts map
|
// initialize accounts map
|
||||||
chain.accounts = make(map[string]*SigningAccount)
|
chain.accounts = make(map[string]*SigningAccount)
|
||||||
// setup the signing account for the initially funded account (used to fund all other accounts)
|
// setup the signing account for the initially funded account (used to fund all other accounts)
|
||||||
@ -217,7 +172,7 @@ func (chain *Chain) RegisterErc20(address common.Address) {
|
|||||||
|
|
||||||
// QuerySdkForBalances gets the balance of a particular address on this Chain.
|
// QuerySdkForBalances gets the balance of a particular address on this Chain.
|
||||||
func (chain *Chain) QuerySdkForBalances(addr sdk.AccAddress) sdk.Coins {
|
func (chain *Chain) QuerySdkForBalances(addr sdk.AccAddress) sdk.Coins {
|
||||||
res, err := chain.Bank.AllBalances(context.Background(), &banktypes.QueryAllBalancesRequest{
|
res, err := chain.Grpc.Query.Bank.AllBalances(context.Background(), &banktypes.QueryAllBalancesRequest{
|
||||||
Address: addr.String(),
|
Address: addr.String(),
|
||||||
})
|
})
|
||||||
require.NoError(chain.t, err)
|
require.NoError(chain.t, err)
|
||||||
|
@ -23,7 +23,7 @@ func (suite *E2eTestSuite) NewEip712TxBuilder(
|
|||||||
) client.TxBuilder {
|
) client.TxBuilder {
|
||||||
// get account details
|
// get account details
|
||||||
var accDetails authtypes.AccountI
|
var accDetails authtypes.AccountI
|
||||||
a, err := chain.Auth.Account(context.Background(), &authtypes.QueryAccountRequest{
|
a, err := chain.Grpc.Query.Auth.Account(context.Background(), &authtypes.QueryAccountRequest{
|
||||||
Address: acc.SdkAddress.String(),
|
Address: acc.SdkAddress.String(),
|
||||||
})
|
})
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
@ -39,7 +39,7 @@ func (suite *E2eTestSuite) NewEip712TxBuilder(
|
|||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
ethChainId := pc.Uint64()
|
ethChainId := pc.Uint64()
|
||||||
|
|
||||||
evmParams, err := chain.Evm.Params(context.Background(), &evmtypes.QueryParamsRequest{})
|
evmParams, err := chain.Grpc.Query.Evm.Params(context.Background(), &evmtypes.QueryParamsRequest{})
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
|
|
||||||
fee := legacytx.NewStdFee(gas, gasAmount)
|
fee := legacytx.NewStdFee(gas, gasAmount)
|
||||||
|
@ -28,7 +28,7 @@ func (suite *E2eTestSuite) InitKavaEvmData() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// expect the erc20 to be enabled for conversion to sdk.Coin
|
// expect the erc20 to be enabled for conversion to sdk.Coin
|
||||||
params, err := suite.Kava.Evmutil.Params(context.Background(), &evmutiltypes.QueryParamsRequest{})
|
params, err := suite.Kava.Grpc.Query.Evmutil.Params(context.Background(), &evmutiltypes.QueryParamsRequest{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("failed to fetch evmutil params during init: %s", err))
|
panic(fmt.Sprintf("failed to fetch evmutil params during init: %s", err))
|
||||||
}
|
}
|
||||||
@ -46,7 +46,7 @@ func (suite *E2eTestSuite) InitKavaEvmData() {
|
|||||||
suite.Kava.RegisterErc20(suite.DeployedErc20.Address)
|
suite.Kava.RegisterErc20(suite.DeployedErc20.Address)
|
||||||
|
|
||||||
// expect the erc20's cosmos denom to be a supported cdp collateral type
|
// expect the erc20's cosmos denom to be a supported cdp collateral type
|
||||||
cdpParams, err := suite.Kava.Cdp.Params(context.Background(), &types.QueryParamsRequest{})
|
cdpParams, err := suite.Kava.Grpc.Query.Cdp.Params(context.Background(), &types.QueryParamsRequest{})
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
found = false
|
found = false
|
||||||
for _, cp := range cdpParams.Params.CollateralParams {
|
for _, cp := range cdpParams.Params.CollateralParams {
|
||||||
|
Loading…
Reference in New Issue
Block a user