Add Earn grpc query service and cli query commands (#1279)

* Add query methods

* Add TotalDeposited rpc query

* All accounts and all denoms query wip

* Add query deposits

* Remove IsDenomSupported strategy method

This is not necessary and is already set in params allowed vaults

* Add Vaults, TotalDeposited queries

* Deposits query tests and fixes

* proto lints

* Add earn swagger docs

* Add cli query cmds

* Update init-new-chain.sh with usdx strategy and funds

* Add denom url query path for vaults

* Return a list of coins for each depositor instead of multiple deposit entries
This commit is contained in:
Derrick Lee 2022-07-28 09:50:59 -07:00 committed by GitHub
parent 88d4868316
commit 82e2f26e14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 4024 additions and 190 deletions

View File

@ -10,9 +10,7 @@
"url": "https://github.com/Kava-Labs/kava" "url": "https://github.com/Kava-Labs/kava"
}, },
"host": "api.data.kava.io", "host": "api.data.kava.io",
"schemes": [ "schemes": ["https"],
"https"
],
"apis": [ "apis": [
{ {
"url": "./tmp-swagger-gen/kava/auction/v1beta1/query.swagger.json", "url": "./tmp-swagger-gen/kava/auction/v1beta1/query.swagger.json",
@ -82,6 +80,23 @@
] ]
} }
}, },
{
"url": "./tmp-swagger-gen/kava/earn/v1beta1/query.swagger.json",
"tags": {
"rename": {
"Query": "Earn"
}
},
"operationIds": {
"rename": [
{
"type": "regex",
"from": "(.*)",
"to": "Earn$1"
}
]
}
},
{ {
"url": "./tmp-swagger-gen/kava/hard/v1beta1/query.swagger.json", "url": "./tmp-swagger-gen/kava/hard/v1beta1/query.swagger.json",
"tags": { "tags": {
@ -196,10 +211,7 @@
} }
}, },
"paths": { "paths": {
"exclude": [ "exclude": ["^/cosmos/authz/.*", "^/cosmos/feegrant/.*"]
"^/cosmos/authz/.*",
"^/cosmos/feegrant/.*"
]
} }
}, },
{ {
@ -229,4 +241,4 @@
} }
} }
] ]
} }

View File

@ -6960,6 +6960,357 @@ paths:
type: string type: string
tags: tags:
- Committee - Committee
/kava/earn/v1beta1/deposits:
get:
summary: Deposits queries deposit details based on owner address and vault
operationId: EarnDeposits
responses:
'200':
description: A successful response.
schema:
type: object
properties:
deposits:
type: array
items:
type: object
properties:
depositor:
type: string
description: depositor represents the owner of the deposit.
denom:
type: string
description: denom represents the vault denom the deposit is for.
account_supplied:
type: string
description: >-
AccountSupplied represents the amount of denom supplied
to the vault.
account_value:
type: string
description: >-
AccountValue represents the coin value of the
depositor's share of the vault.
description: >-
DepositResponse defines a single deposit query response
type.
title: >-
deposits returns the deposits matching the requested
parameters
pagination:
description: pagination defines the pagination in the response.
type: object
properties:
next_key:
type: string
format: byte
title: |-
next_key is the key to be passed to PageRequest.key to
query the next page most efficiently
total:
type: string
format: uint64
title: >-
total is total number of results available if
PageRequest.count_total
was set, its value is undefined otherwise
description: >-
QueryDepositsResponse is the response type for the Query/Deposits
RPC method.
default:
description: An unexpected error response
schema:
type: object
properties:
error:
type: string
code:
type: integer
format: int32
message:
type: string
details:
type: array
items:
type: object
properties:
type_url:
type: string
value:
type: string
format: byte
parameters:
- name: owner
description: owner optionally filters deposits by owner.
in: query
required: false
type: string
- name: denom
description: denom optionally filters deposits by vault denom.
in: query
required: false
type: string
- name: pagination.key
description: |-
key is a value returned in PageResponse.next_key to begin
querying the next page most efficiently. Only one of offset or key
should be set.
in: query
required: false
type: string
format: byte
- name: pagination.offset
description: >-
offset is a numeric offset that can be used when key is unavailable.
It is less efficient than using key. Only one of offset or key
should
be set.
in: query
required: false
type: string
format: uint64
- name: pagination.limit
description: >-
limit is the total number of results to be returned in the result
page.
If left empty it will default to a value to be set by each app.
in: query
required: false
type: string
format: uint64
- name: pagination.count_total
description: >-
count_total is set to true to indicate that the result set should
include
a count of the total number of items available for pagination in
UIs.
count_total is only respected when offset is used. It is ignored
when key
is set.
in: query
required: false
type: boolean
format: boolean
- name: pagination.reverse
description: >-
reverse is set to true if results are to be returned in the
descending order.
Since: cosmos-sdk 0.43
in: query
required: false
type: boolean
format: boolean
tags:
- Earn
/kava/earn/v1beta1/params:
get:
summary: Params queries all parameters of the earn module.
operationId: EarnParams
responses:
'200':
description: A successful response.
schema:
type: object
properties:
params:
title: params represents the earn module parameters
type: object
properties:
allowed_vaults:
type: array
items:
type: object
properties:
denom:
type: string
description: >-
Denom is the only supported denomination of the
vault for deposits and withdrawals.
vault_strategy:
description: VaultStrategy is the strategy used for this vault.
type: string
enum:
- STRATEGY_TYPE_UNSPECIFIED
- STRATEGY_TYPE_HARD
- STRATEGY_TYPE_SAVINGS
default: STRATEGY_TYPE_UNSPECIFIED
description: >-
AllowedVault is a vault that is allowed to be created.
These can be
modified via parameter governance.
description: Params defines the parameters of the earn module.
description: >-
QueryParamsResponse defines the response type for querying x/earn
parameters.
default:
description: An unexpected error response
schema:
type: object
properties:
error:
type: string
code:
type: integer
format: int32
message:
type: string
details:
type: array
items:
type: object
properties:
type_url:
type: string
value:
type: string
format: byte
tags:
- Earn
/kava/earn/v1beta1/total-deposited/{denom}:
get:
summary: TotalDeposited queries total deposited amount for each vault.
operationId: EarnTotalDeposited
responses:
'200':
description: A successful response.
schema:
type: object
properties:
supplied_coins:
type: array
items:
type: object
properties:
denom:
type: string
amount:
type: string
description: >-
Coin defines a token with a denomination and an amount.
NOTE: The amount field is an Int which implements the custom
method
signatures required by gogoproto.
description: >-
QueryTotalDepositedResponse is the response type for the
Query/TotalDeposited RPC method.
default:
description: An unexpected error response
schema:
type: object
properties:
error:
type: string
code:
type: integer
format: int32
message:
type: string
details:
type: array
items:
type: object
properties:
type_url:
type: string
value:
type: string
format: byte
parameters:
- name: denom
description: >-
denom represents the vault denom to query total deposited amount
for.
in: path
required: true
type: string
tags:
- Earn
/kava/earn/v1beta1/vaults:
get:
summary: Vaults queries vaults based on vault denom
operationId: EarnVaults
responses:
'200':
description: A successful response.
schema:
type: object
properties:
vaults:
type: array
items:
type: object
properties:
denom:
type: string
title: denom represents the denom of the vault
vault_strategy:
description: VaultStrategy is the strategy used for this vault.
type: string
enum:
- STRATEGY_TYPE_UNSPECIFIED
- STRATEGY_TYPE_HARD
- STRATEGY_TYPE_SAVINGS
default: STRATEGY_TYPE_UNSPECIFIED
total_supplied:
type: string
description: >-
TotalSupplied is the total amount of denom coins
supplied to the vault.
total_value:
type: string
description: >-
TotalValue is the total value of denom coins supplied to
the vault if the
vault were to be liquidated.
description: VaultResponse is the response type for a vault.
title: vaults represents the earn module vaults
description: >-
QueryVaultsResponse is the response type for the Query/Vaults RPC
method.
default:
description: An unexpected error response
schema:
type: object
properties:
error:
type: string
code:
type: integer
format: int32
message:
type: string
details:
type: array
items:
type: object
properties:
type_url:
type: string
value:
type: string
format: byte
parameters:
- name: denom
description: vault filters vault by denom.
in: query
required: false
type: string
tags:
- Earn
/kava/hard/v1beta1/accounts: /kava/hard/v1beta1/accounts:
get: get:
summary: Accounts queries module accounts. summary: Accounts queries module accounts.
@ -53848,6 +54199,245 @@ definitions:
- VOTE_TYPE_YES: VOTE_TYPE_YES defines a yes vote option. - VOTE_TYPE_YES: VOTE_TYPE_YES defines a yes vote option.
- VOTE_TYPE_NO: VOTE_TYPE_NO defines a no vote option. - VOTE_TYPE_NO: VOTE_TYPE_NO defines a no vote option.
- VOTE_TYPE_ABSTAIN: VOTE_TYPE_ABSTAIN defines an abstain vote option. - VOTE_TYPE_ABSTAIN: VOTE_TYPE_ABSTAIN defines an abstain vote option.
kava.earn.v1beta1.AllowedVault:
type: object
properties:
denom:
type: string
description: >-
Denom is the only supported denomination of the vault for deposits and
withdrawals.
vault_strategy:
description: VaultStrategy is the strategy used for this vault.
type: string
enum:
- STRATEGY_TYPE_UNSPECIFIED
- STRATEGY_TYPE_HARD
- STRATEGY_TYPE_SAVINGS
default: STRATEGY_TYPE_UNSPECIFIED
description: |-
AllowedVault is a vault that is allowed to be created. These can be
modified via parameter governance.
kava.earn.v1beta1.DepositResponse:
type: object
properties:
depositor:
type: string
description: depositor represents the owner of the deposit.
denom:
type: string
description: denom represents the vault denom the deposit is for.
account_supplied:
type: string
description: AccountSupplied represents the amount of denom supplied to the vault.
account_value:
type: string
description: >-
AccountValue represents the coin value of the depositor's share of the
vault.
description: DepositResponse defines a single deposit query response type.
kava.earn.v1beta1.Params:
type: object
properties:
allowed_vaults:
type: array
items:
type: object
properties:
denom:
type: string
description: >-
Denom is the only supported denomination of the vault for
deposits and withdrawals.
vault_strategy:
description: VaultStrategy is the strategy used for this vault.
type: string
enum:
- STRATEGY_TYPE_UNSPECIFIED
- STRATEGY_TYPE_HARD
- STRATEGY_TYPE_SAVINGS
default: STRATEGY_TYPE_UNSPECIFIED
description: |-
AllowedVault is a vault that is allowed to be created. These can be
modified via parameter governance.
description: Params defines the parameters of the earn module.
kava.earn.v1beta1.QueryDepositsResponse:
type: object
properties:
deposits:
type: array
items:
type: object
properties:
depositor:
type: string
description: depositor represents the owner of the deposit.
denom:
type: string
description: denom represents the vault denom the deposit is for.
account_supplied:
type: string
description: >-
AccountSupplied represents the amount of denom supplied to the
vault.
account_value:
type: string
description: >-
AccountValue represents the coin value of the depositor's share
of the vault.
description: DepositResponse defines a single deposit query response type.
title: deposits returns the deposits matching the requested parameters
pagination:
description: pagination defines the pagination in the response.
type: object
properties:
next_key:
type: string
format: byte
title: |-
next_key is the key to be passed to PageRequest.key to
query the next page most efficiently
total:
type: string
format: uint64
title: >-
total is total number of results available if
PageRequest.count_total
was set, its value is undefined otherwise
description: >-
QueryDepositsResponse is the response type for the Query/Deposits RPC
method.
kava.earn.v1beta1.QueryParamsResponse:
type: object
properties:
params:
title: params represents the earn module parameters
type: object
properties:
allowed_vaults:
type: array
items:
type: object
properties:
denom:
type: string
description: >-
Denom is the only supported denomination of the vault for
deposits and withdrawals.
vault_strategy:
description: VaultStrategy is the strategy used for this vault.
type: string
enum:
- STRATEGY_TYPE_UNSPECIFIED
- STRATEGY_TYPE_HARD
- STRATEGY_TYPE_SAVINGS
default: STRATEGY_TYPE_UNSPECIFIED
description: >-
AllowedVault is a vault that is allowed to be created. These can
be
modified via parameter governance.
description: Params defines the parameters of the earn module.
description: >-
QueryParamsResponse defines the response type for querying x/earn
parameters.
kava.earn.v1beta1.QueryTotalDepositedResponse:
type: object
properties:
supplied_coins:
type: array
items:
type: object
properties:
denom:
type: string
amount:
type: string
description: |-
Coin defines a token with a denomination and an amount.
NOTE: The amount field is an Int which implements the custom method
signatures required by gogoproto.
description: >-
QueryTotalDepositedResponse is the response type for the
Query/TotalDeposited RPC method.
kava.earn.v1beta1.QueryVaultsResponse:
type: object
properties:
vaults:
type: array
items:
type: object
properties:
denom:
type: string
title: denom represents the denom of the vault
vault_strategy:
description: VaultStrategy is the strategy used for this vault.
type: string
enum:
- STRATEGY_TYPE_UNSPECIFIED
- STRATEGY_TYPE_HARD
- STRATEGY_TYPE_SAVINGS
default: STRATEGY_TYPE_UNSPECIFIED
total_supplied:
type: string
description: >-
TotalSupplied is the total amount of denom coins supplied to the
vault.
total_value:
type: string
description: >-
TotalValue is the total value of denom coins supplied to the
vault if the
vault were to be liquidated.
description: VaultResponse is the response type for a vault.
title: vaults represents the earn module vaults
description: QueryVaultsResponse is the response type for the Query/Vaults RPC method.
kava.earn.v1beta1.StrategyType:
type: string
enum:
- STRATEGY_TYPE_UNSPECIFIED
- STRATEGY_TYPE_HARD
- STRATEGY_TYPE_SAVINGS
default: STRATEGY_TYPE_UNSPECIFIED
description: |-
StrategyType is the type of strategy that a vault uses to optimize yields.
- STRATEGY_TYPE_UNSPECIFIED: STRATEGY_TYPE_UNSPECIFIED represents an unspecified or invalid strategy type.
- STRATEGY_TYPE_HARD: STRATEGY_TYPE_HARD represents the strategy that deposits assets in the Hard
module.
- STRATEGY_TYPE_SAVINGS: STRATEGY_TYPE_SAVINGS represents the strategy that deposits assets in the
Savings module.
kava.earn.v1beta1.VaultResponse:
type: object
properties:
denom:
type: string
title: denom represents the denom of the vault
vault_strategy:
description: VaultStrategy is the strategy used for this vault.
type: string
enum:
- STRATEGY_TYPE_UNSPECIFIED
- STRATEGY_TYPE_HARD
- STRATEGY_TYPE_SAVINGS
default: STRATEGY_TYPE_UNSPECIFIED
total_supplied:
type: string
description: >-
TotalSupplied is the total amount of denom coins supplied to the
vault.
total_value:
type: string
description: >-
TotalValue is the total value of denom coins supplied to the vault if
the
vault were to be liquidated.
description: VaultResponse is the response type for a vault.
kava.hard.v1beta1.BorrowInterestFactorResponse: kava.hard.v1beta1.BorrowInterestFactorResponse:
type: object type: object
properties: properties:

View File

@ -57,7 +57,7 @@ $BINARY add-genesis-account $evmFaucetKeyName 1000000000ukava
userKeyName="user" userKeyName="user"
printf "$userMnemonic\n" | $BINARY keys add $userKeyName --eth --recover printf "$userMnemonic\n" | $BINARY keys add $userKeyName --eth --recover
$BINARY add-genesis-account $userKeyName 1000000000ukava $BINARY add-genesis-account $userKeyName 1000000000ukava,1000000000usdx
relayerKeyName="relayer" relayerKeyName="relayer"
printf "$relayerMnemonic\n" | $BINARY keys add $relayerKeyName --eth --recover printf "$relayerMnemonic\n" | $BINARY keys add $relayerKeyName --eth --recover
@ -118,6 +118,6 @@ jq '.app_state.bridge.params.enabled_conversion_pairs = [
# Add earn vault # Add earn vault
jq '.app_state.earn.params.allowed_vaults = [ jq '.app_state.earn.params.allowed_vaults = [
{ {
denom: "ukava", denom: "usdx",
vault_strategy: 2, vault_strategy: 1,
}]' $DATA/config/genesis.json | sponge $DATA/config/genesis.json }]' $DATA/config/genesis.json | sponge $DATA/config/genesis.json

View File

@ -193,8 +193,16 @@
- [GenesisState](#kava.earn.v1beta1.GenesisState) - [GenesisState](#kava.earn.v1beta1.GenesisState)
- [kava/earn/v1beta1/query.proto](#kava/earn/v1beta1/query.proto) - [kava/earn/v1beta1/query.proto](#kava/earn/v1beta1/query.proto)
- [DepositResponse](#kava.earn.v1beta1.DepositResponse)
- [QueryDepositsRequest](#kava.earn.v1beta1.QueryDepositsRequest)
- [QueryDepositsResponse](#kava.earn.v1beta1.QueryDepositsResponse)
- [QueryParamsRequest](#kava.earn.v1beta1.QueryParamsRequest) - [QueryParamsRequest](#kava.earn.v1beta1.QueryParamsRequest)
- [QueryParamsResponse](#kava.earn.v1beta1.QueryParamsResponse) - [QueryParamsResponse](#kava.earn.v1beta1.QueryParamsResponse)
- [QueryTotalDepositedRequest](#kava.earn.v1beta1.QueryTotalDepositedRequest)
- [QueryTotalDepositedResponse](#kava.earn.v1beta1.QueryTotalDepositedResponse)
- [QueryVaultsRequest](#kava.earn.v1beta1.QueryVaultsRequest)
- [QueryVaultsResponse](#kava.earn.v1beta1.QueryVaultsResponse)
- [VaultResponse](#kava.earn.v1beta1.VaultResponse)
- [Query](#kava.earn.v1beta1.Query) - [Query](#kava.earn.v1beta1.Query)
@ -2747,13 +2755,13 @@ Msg defines the committee Msg service
<a name="kava.earn.v1beta1.StrategyType"></a> <a name="kava.earn.v1beta1.StrategyType"></a>
### StrategyType ### StrategyType
StrategyType is the type of strategy that a vault uses to optimize yields.
| Name | Number | Description | | Name | Number | Description |
| ---- | ------ | ----------- | | ---- | ------ | ----------- |
| STRATEGY_TYPE_UNKNOWN | 0 | | | STRATEGY_TYPE_UNSPECIFIED | 0 | STRATEGY_TYPE_UNSPECIFIED represents an unspecified or invalid strategy type. |
| STRATEGY_TYPE_HARD | 1 | | | STRATEGY_TYPE_HARD | 1 | STRATEGY_TYPE_HARD represents the strategy that deposits assets in the Hard module. |
| STRATEGY_TYPE_SAVINGS | 2 | | | STRATEGY_TYPE_SAVINGS | 2 | STRATEGY_TYPE_SAVINGS represents the strategy that deposits assets in the Savings module. |
<!-- end enums --> <!-- end enums -->
@ -2781,7 +2789,7 @@ modified via parameter governance.
| Field | Type | Label | Description | | Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- | | ----- | ---- | ----- | ----------- |
| `denom` | [string](#string) | | Denom is the only supported denomination of the vault for deposits and withdrawals. | | `denom` | [string](#string) | | Denom is the only supported denomination of the vault for deposits and withdrawals. |
| `vault_strategy` | [StrategyType](#kava.earn.v1beta1.StrategyType) | | VaultStrategy is the strategies to use for this vault. | | `vault_strategy` | [StrategyType](#kava.earn.v1beta1.StrategyType) | | VaultStrategy is the strategy used for this vault. |
@ -2840,7 +2848,7 @@ VaultShareRecord defines the vault shares owned by a depositor.
<a name="kava.earn.v1beta1.Params"></a> <a name="kava.earn.v1beta1.Params"></a>
### Params ### Params
Params defines the parameters of the earn module.
| Field | Type | Label | Description | | Field | Type | Label | Description |
@ -2901,6 +2909,56 @@ GenesisState defines the earn module's genesis state.
<a name="kava.earn.v1beta1.DepositResponse"></a>
### DepositResponse
DepositResponse defines a deposit query response type.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `depositor` | [string](#string) | | depositor represents the owner of the deposit. |
| `amount_supplied` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | Amount represents the amount supplied to vaults. |
| `value` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | Value represents the total accumulated value of denom coins supplied to vaults. This may be greater than or equal to amount_supplied depending on the strategy. |
<a name="kava.earn.v1beta1.QueryDepositsRequest"></a>
### QueryDepositsRequest
QueryDepositsRequest is the request type for the Query/Deposits RPC method.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `owner` | [string](#string) | | owner optionally filters deposits by owner |
| `denom` | [string](#string) | | denom optionally filters deposits by vault denom |
| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an optional pagination for the request. |
<a name="kava.earn.v1beta1.QueryDepositsResponse"></a>
### QueryDepositsResponse
QueryDepositsResponse is the response type for the Query/Deposits RPC method.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `deposits` | [DepositResponse](#kava.earn.v1beta1.DepositResponse) | repeated | deposits returns the deposits matching the requested parameters |
| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination defines the pagination in the response. |
<a name="kava.earn.v1beta1.QueryParamsRequest"></a> <a name="kava.earn.v1beta1.QueryParamsRequest"></a>
### QueryParamsRequest ### QueryParamsRequest
@ -2925,6 +2983,84 @@ QueryParamsResponse defines the response type for querying x/earn parameters.
<a name="kava.earn.v1beta1.QueryTotalDepositedRequest"></a>
### QueryTotalDepositedRequest
QueryTotalDepositedRequest is the request type for the Query/TotalDeposited RPC method.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `denom` | [string](#string) | | denom represents the vault denom to query total deposited amount for. |
<a name="kava.earn.v1beta1.QueryTotalDepositedResponse"></a>
### QueryTotalDepositedResponse
QueryTotalDepositedResponse is the response type for the Query/TotalDeposited RPC method.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `supplied_coins` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | |
<a name="kava.earn.v1beta1.QueryVaultsRequest"></a>
### QueryVaultsRequest
QueryVaultsRequest is the request type for the Query/Vault RPC method.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `denom` | [string](#string) | | vault filters vault by denom |
<a name="kava.earn.v1beta1.QueryVaultsResponse"></a>
### QueryVaultsResponse
QueryVaultsResponse is the response type for the Query/Vaults RPC method.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `vaults` | [VaultResponse](#kava.earn.v1beta1.VaultResponse) | repeated | vaults represents the earn module vaults |
<a name="kava.earn.v1beta1.VaultResponse"></a>
### VaultResponse
VaultResponse is the response type for a vault.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `denom` | [string](#string) | | denom represents the denom of the vault |
| `vault_strategy` | [StrategyType](#kava.earn.v1beta1.StrategyType) | | VaultStrategy is the strategy used for this vault. |
| `total_supplied` | [string](#string) | | TotalSupplied is the total amount of denom coins supplied to the vault. |
| `total_value` | [string](#string) | | TotalValue is the total value of denom coins supplied to the vault if the vault were to be liquidated. |
<!-- end messages --> <!-- end messages -->
<!-- end enums --> <!-- end enums -->
@ -2940,6 +3076,9 @@ Query defines the gRPC querier service for earn module
| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | | Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint |
| ----------- | ------------ | ------------- | ------------| ------- | -------- | | ----------- | ------------ | ------------- | ------------| ------- | -------- |
| `Params` | [QueryParamsRequest](#kava.earn.v1beta1.QueryParamsRequest) | [QueryParamsResponse](#kava.earn.v1beta1.QueryParamsResponse) | Params queries all parameters of the earn module. | GET|/kava/earn/v1beta1/params| | `Params` | [QueryParamsRequest](#kava.earn.v1beta1.QueryParamsRequest) | [QueryParamsResponse](#kava.earn.v1beta1.QueryParamsResponse) | Params queries all parameters of the earn module. | GET|/kava/earn/v1beta1/params|
| `Vaults` | [QueryVaultsRequest](#kava.earn.v1beta1.QueryVaultsRequest) | [QueryVaultsResponse](#kava.earn.v1beta1.QueryVaultsResponse) | Vaults queries vaults based on vault denom | GET|/kava/earn/v1beta1/vaults/{denom}|
| `Deposits` | [QueryDepositsRequest](#kava.earn.v1beta1.QueryDepositsRequest) | [QueryDepositsResponse](#kava.earn.v1beta1.QueryDepositsResponse) | Deposits queries deposit details based on owner address and vault | GET|/kava/earn/v1beta1/deposits|
| `TotalDeposited` | [QueryTotalDepositedRequest](#kava.earn.v1beta1.QueryTotalDepositedRequest) | [QueryTotalDepositedResponse](#kava.earn.v1beta1.QueryTotalDepositedResponse) | TotalDeposited queries total deposited amount for each vault. | GET|/kava/earn/v1beta1/total-deposited/{denom}|
<!-- end services --> <!-- end services -->

View File

@ -3,9 +3,9 @@ package kava.earn.v1beta1;
option go_package = "github.com/kava-labs/kava/x/earn/types"; option go_package = "github.com/kava-labs/kava/x/earn/types";
import "kava/earn/v1beta1/vault.proto";
import "kava/earn/v1beta1/params.proto";
import "gogoproto/gogo.proto"; import "gogoproto/gogo.proto";
import "kava/earn/v1beta1/params.proto";
import "kava/earn/v1beta1/vault.proto";
// GenesisState defines the earn module's genesis state. // GenesisState defines the earn module's genesis state.
message GenesisState { message GenesisState {

View File

@ -6,6 +6,7 @@ option go_package = "github.com/kava-labs/kava/x/earn/types";
import "gogoproto/gogo.proto"; import "gogoproto/gogo.proto";
import "kava/earn/v1beta1/vault.proto"; import "kava/earn/v1beta1/vault.proto";
// Params defines the parameters of the earn module.
message Params { message Params {
repeated AllowedVault allowed_vaults = 1 [(gogoproto.castrepeated) = "AllowedVaults", (gogoproto.nullable) = false]; repeated AllowedVault allowed_vaults = 1 [(gogoproto.castrepeated) = "AllowedVaults", (gogoproto.nullable) = false];
} }

View File

@ -1,12 +1,16 @@
syntax = "proto3"; syntax = "proto3";
package kava.earn.v1beta1; package kava.earn.v1beta1;
option go_package = "github.com/kava-labs/kava/x/earn/types"; option go_package = "github.com/kava-labs/kava/x/earn/types";
option (gogoproto.goproto_getters_all) = false;
import "cosmos_proto/cosmos.proto";
import "cosmos/base/query/v1beta1/pagination.proto";
import "cosmos/base/v1beta1/coin.proto";
import "gogoproto/gogo.proto"; import "gogoproto/gogo.proto";
import "google/api/annotations.proto"; import "google/api/annotations.proto";
import "cosmos_proto/cosmos.proto";
import "kava/earn/v1beta1/params.proto"; import "kava/earn/v1beta1/params.proto";
import "kava/earn/v1beta1/strategy.proto";
// Query defines the gRPC querier service for earn module // Query defines the gRPC querier service for earn module
service Query { service Query {
@ -14,17 +18,114 @@ service Query {
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/kava/earn/v1beta1/params"; option (google.api.http).get = "/kava/earn/v1beta1/params";
} }
// Vaults queries vaults based on vault denom
rpc Vaults(QueryVaultsRequest) returns (QueryVaultsResponse) {
option (google.api.http).get = "/kava/earn/v1beta1/vaults/{denom}";
}
// Deposits queries deposit details based on owner address and vault
rpc Deposits(QueryDepositsRequest) returns (QueryDepositsResponse) {
option (google.api.http).get = "/kava/earn/v1beta1/deposits";
}
// TotalDeposited queries total deposited amount for each vault.
rpc TotalDeposited(QueryTotalDepositedRequest) returns (QueryTotalDepositedResponse) {
option (google.api.http).get = "/kava/earn/v1beta1/total-deposited/{denom}";
}
} }
// QueryParamsRequest defines the request type for querying x/earn parameters. // QueryParamsRequest defines the request type for querying x/earn parameters.
message QueryParamsRequest { message QueryParamsRequest {}
option (gogoproto.goproto_getters) = false;
}
// QueryParamsResponse defines the response type for querying x/earn parameters. // QueryParamsResponse defines the response type for querying x/earn parameters.
message QueryParamsResponse { message QueryParamsResponse {
option (gogoproto.goproto_getters) = false;
// params represents the earn module parameters // params represents the earn module parameters
Params params = 1 [(gogoproto.nullable) = false]; Params params = 1 [(gogoproto.nullable) = false];
} }
// QueryVaultsRequest is the request type for the Query/Vault RPC method.
message QueryVaultsRequest {
// vault filters vault by denom
string denom = 1;
}
// QueryVaultsResponse is the response type for the Query/Vaults RPC method.
message QueryVaultsResponse {
// vaults represents the earn module vaults
repeated VaultResponse vaults = 1 [(gogoproto.nullable) = false];
}
// VaultResponse is the response type for a vault.
message VaultResponse {
// denom represents the denom of the vault
string denom = 1;
// VaultStrategy is the strategy used for this vault.
StrategyType vault_strategy = 2;
// TotalSupplied is the total amount of denom coins supplied to the vault.
string total_supplied = 3 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
// TotalValue is the total value of denom coins supplied to the vault if the
// vault were to be liquidated.
string total_value = 4 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
}
// QueryDepositsRequest is the request type for the Query/Deposits RPC method.
message QueryDepositsRequest {
// owner optionally filters deposits by owner
string owner = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// denom optionally filters deposits by vault denom
string denom = 2;
// pagination defines an optional pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 3;
}
// QueryDepositsResponse is the response type for the Query/Deposits RPC method.
message QueryDepositsResponse {
// deposits returns the deposits matching the requested parameters
repeated DepositResponse deposits = 1 [(gogoproto.nullable) = false];
// pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
// DepositResponse defines a deposit query response type.
message DepositResponse {
// depositor represents the owner of the deposit.
string depositor = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// Amount represents the amount supplied to vaults.
repeated cosmos.base.v1beta1.Coin amount_supplied = 2
[(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (gogoproto.nullable) = false];
// Value represents the total accumulated value of denom coins supplied to
// vaults. This may be greater than or equal to amount_supplied depending on
// the strategy.
repeated cosmos.base.v1beta1.Coin value = 3
[(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (gogoproto.nullable) = false];
}
// QueryTotalDepositedRequest is the request type for the Query/TotalDeposited RPC method.
message QueryTotalDepositedRequest {
// denom represents the vault denom to query total deposited amount for.
string denom = 1;
}
// QueryTotalDepositedResponse is the response type for the Query/TotalDeposited RPC method.
message QueryTotalDepositedResponse {
repeated cosmos.base.v1beta1.Coin supplied_coins = 1
[(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (gogoproto.nullable) = false];
}

View File

@ -4,13 +4,17 @@ package kava.earn.v1beta1;
option go_package = "github.com/kava-labs/kava/x/earn/types"; option go_package = "github.com/kava-labs/kava/x/earn/types";
import "gogoproto/gogo.proto"; import "gogoproto/gogo.proto";
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
// StrategyType is the type of strategy that a vault uses to optimize yields.
enum StrategyType { enum StrategyType {
option (gogoproto.goproto_enum_prefix) = false; option (gogoproto.goproto_enum_prefix) = false;
STRATEGY_TYPE_UNKNOWN = 0; // STRATEGY_TYPE_UNSPECIFIED represents an unspecified or invalid strategy type.
STRATEGY_TYPE_HARD = 1; STRATEGY_TYPE_UNSPECIFIED = 0;
// STRATEGY_TYPE_HARD represents the strategy that deposits assets in the Hard
// module.
STRATEGY_TYPE_HARD = 1;
// STRATEGY_TYPE_SAVINGS represents the strategy that deposits assets in the
// Savings module.
STRATEGY_TYPE_SAVINGS = 2; STRATEGY_TYPE_SAVINGS = 2;
} }

View File

@ -1,9 +1,9 @@
syntax = "proto3"; syntax = "proto3";
package kava.earn.v1beta1; package kava.earn.v1beta1;
import "gogoproto/gogo.proto";
import "cosmos_proto/cosmos.proto"; import "cosmos_proto/cosmos.proto";
import "cosmos/base/v1beta1/coin.proto"; import "cosmos/base/v1beta1/coin.proto";
import "gogoproto/gogo.proto";
option go_package = "github.com/kava-labs/kava/x/earn/types"; option go_package = "github.com/kava-labs/kava/x/earn/types";

View File

@ -3,9 +3,9 @@ package kava.earn.v1beta1;
option go_package = "github.com/kava-labs/kava/x/earn/types"; option go_package = "github.com/kava-labs/kava/x/earn/types";
import "gogoproto/gogo.proto";
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto"; import "cosmos_proto/cosmos.proto";
import "cosmos/base/v1beta1/coin.proto";
import "gogoproto/gogo.proto";
import "kava/earn/v1beta1/strategy.proto"; import "kava/earn/v1beta1/strategy.proto";
// AllowedVault is a vault that is allowed to be created. These can be // AllowedVault is a vault that is allowed to be created. These can be
@ -14,7 +14,7 @@ message AllowedVault {
// Denom is the only supported denomination of the vault for deposits and withdrawals. // Denom is the only supported denomination of the vault for deposits and withdrawals.
string denom = 1; string denom = 1;
// VaultStrategy is the strategies to use for this vault. // VaultStrategy is the strategy used for this vault.
StrategyType vault_strategy = 2; StrategyType vault_strategy = 2;
} }

View File

@ -2,15 +2,23 @@ package cli
import ( import (
"context" "context"
"fmt"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/version"
"github.com/kava-labs/kava/x/earn/types" "github.com/kava-labs/kava/x/earn/types"
) )
// flags for cli queries
const (
flagDenom = "denom"
flagOwner = "owner"
)
// GetQueryCmd returns the cli query commands for the earn module // GetQueryCmd returns the cli query commands for the earn module
func GetQueryCmd() *cobra.Command { func GetQueryCmd() *cobra.Command {
earnQueryCommand := &cobra.Command{ earnQueryCommand := &cobra.Command{
@ -23,6 +31,9 @@ func GetQueryCmd() *cobra.Command {
cmds := []*cobra.Command{ cmds := []*cobra.Command{
queryParamsCmd(), queryParamsCmd(),
queryVaultsCmd(),
queryDepositsCmd(),
queryTotalDepositedCmd(),
} }
for _, cmd := range cmds { for _, cmd := range cmds {
@ -58,3 +69,121 @@ func queryParamsCmd() *cobra.Command {
}, },
} }
} }
func queryVaultsCmd() *cobra.Command {
return &cobra.Command{
Use: "vaults",
Short: "get the earn vaults",
Long: "Get the earn module vaults.",
Args: cobra.MaximumNArgs(1),
Example: fmt.Sprintf(`%[1]s q %[2]s vaults
%[1]s q %[2]s vaults
%[1]s q %[2]s vaults usdx`, version.AppName, types.ModuleName),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
queryClient := types.NewQueryClient(clientCtx)
vaultDenom := ""
if len(args) > 1 {
vaultDenom = args[0]
}
req := types.NewQueryVaultsRequest(vaultDenom)
res, err := queryClient.Vaults(context.Background(), req)
if err != nil {
return err
}
return clientCtx.PrintProto(res)
},
}
}
func queryDepositsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "deposits",
Short: "get earn vault deposits",
Long: "Get earn vault deposits for all or specific accounts and vaults.",
Args: cobra.NoArgs,
Example: fmt.Sprintf(`%[1]s q %[2]s deposits
%[1]s q %[2]s deposits --owner kava1l0xsq2z7gqd7yly0g40y5836g0appumark77ny --denom usdx
%[1]s q %[2]s deposits --denom usdx`, version.AppName, types.ModuleName),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
ownerBech, err := cmd.Flags().GetString(flagOwner)
if err != nil {
return err
}
denom, err := cmd.Flags().GetString(flagDenom)
if err != nil {
return err
}
pageReq, err := client.ReadPageRequest(cmd.Flags())
if err != nil {
return err
}
queryClient := types.NewQueryClient(clientCtx)
req := types.NewQueryDepositsRequest(
ownerBech,
denom,
pageReq,
)
res, err := queryClient.Deposits(context.Background(), req)
if err != nil {
return err
}
return clientCtx.PrintProto(res)
},
}
flags.AddPaginationFlagsToCmd(cmd, "deposits")
cmd.Flags().String(flagOwner, "", "(optional) filter for deposits by owner address")
cmd.Flags().String(flagDenom, "", "(optional) filter for deposits by vault denom")
return cmd
}
func queryTotalDepositedCmd() *cobra.Command {
return &cobra.Command{
Use: "total-deposited",
Short: "get the current total deposited amount",
Long: "Get the current total deposited amount in the earn module vaults.",
Args: cobra.MaximumNArgs(1),
Example: fmt.Sprintf(`%[1]s q %[2]s total-deposited
%[1]s q %[2]s total-deposited usdx`, version.AppName, types.ModuleName),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
queryClient := types.NewQueryClient(clientCtx)
vaultDenom := ""
if len(args) > 1 {
vaultDenom = args[0]
}
req := types.NewQueryTotalDepositedRequest(vaultDenom)
res, err := queryClient.TotalDeposited(context.Background(), req)
if err != nil {
return err
}
return clientCtx.PrintProto(res)
},
}
}

View File

@ -2,7 +2,6 @@ package keeper
import ( import (
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/kava-labs/kava/x/earn/types" "github.com/kava-labs/kava/x/earn/types"
) )
@ -32,16 +31,6 @@ func (k *Keeper) Deposit(ctx sdk.Context, depositor sdk.AccAddress, amount sdk.C
return err return err
} }
// Check if this denom is allowed for the strategy
if !strategy.IsDenomSupported(amount.Denom) {
return sdkerrors.Wrapf(
types.ErrStrategyDenomNotSupported,
"denom %s is not supported by the strategy %s",
amount.Denom,
strategy.GetStrategyType(),
)
}
// Transfer amount to module account // Transfer amount to module account
if err := k.bankKeeper.SendCoinsFromAccountToModule( if err := k.bankKeeper.SendCoinsFromAccountToModule(
ctx, ctx,

View File

@ -2,11 +2,14 @@ package keeper
import ( import (
"context" "context"
"fmt"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/query"
"github.com/kava-labs/kava/x/earn/types" "github.com/kava-labs/kava/x/earn/types"
) )
@ -23,7 +26,10 @@ func NewQueryServerImpl(k Keeper) types.QueryServer {
var _ types.QueryServer = queryServer{} var _ types.QueryServer = queryServer{}
// Params implements the gRPC service handler for querying x/earn parameters. // Params implements the gRPC service handler for querying x/earn parameters.
func (s queryServer) Params(ctx context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { func (s queryServer) Params(
ctx context.Context,
req *types.QueryParamsRequest,
) (*types.QueryParamsResponse, error) {
if req == nil { if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request") return nil, status.Errorf(codes.InvalidArgument, "empty request")
} }
@ -33,3 +39,281 @@ func (s queryServer) Params(ctx context.Context, req *types.QueryParamsRequest)
return &types.QueryParamsResponse{Params: params}, nil return &types.QueryParamsResponse{Params: params}, nil
} }
// Vaults implements the gRPC service handler for querying x/earn vaults.
func (s queryServer) Vaults(
ctx context.Context,
req *types.QueryVaultsRequest,
) (*types.QueryVaultsResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}
sdkCtx := sdk.UnwrapSDKContext(ctx)
var queriedAllowedVaults types.AllowedVaults
if req.Denom != "" {
// Only 1 vault
allowedVault, found := s.keeper.GetAllowedVault(sdkCtx, req.Denom)
if !found {
return nil, status.Errorf(codes.NotFound, "vault not found with specified denom")
}
queriedAllowedVaults = types.AllowedVaults{allowedVault}
} else {
// All vaults
queriedAllowedVaults = s.keeper.GetAllowedVaults(sdkCtx)
}
vaults := []types.VaultResponse{}
for _, allowedVault := range queriedAllowedVaults {
totalSupplied, err := s.keeper.GetVaultTotalSupplied(sdkCtx, allowedVault.Denom)
if err != nil {
// No supply yet, no error just zero
totalSupplied = sdk.NewCoin(allowedVault.Denom, sdk.ZeroInt())
}
totalValue, err := s.keeper.GetVaultTotalValue(sdkCtx, allowedVault.Denom)
if err != nil {
return nil, err
}
vaults = append(vaults, types.VaultResponse{
Denom: allowedVault.Denom,
VaultStrategy: allowedVault.VaultStrategy,
TotalSupplied: totalSupplied.Amount,
TotalValue: totalValue.Amount,
})
}
return &types.QueryVaultsResponse{
Vaults: vaults,
}, nil
}
// Deposits implements the gRPC service handler for querying x/earn deposits.
func (s queryServer) Deposits(
ctx context.Context,
req *types.QueryDepositsRequest,
) (*types.QueryDepositsResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}
sdkCtx := sdk.UnwrapSDKContext(ctx)
// 1. Specific account and specific vault
if req.Owner != "" && req.Denom != "" {
owner, err := sdk.AccAddressFromBech32(req.Owner)
if err != nil {
return nil, status.Error(codes.InvalidArgument, "Invalid address")
}
shareRecord, found := s.keeper.GetVaultShareRecord(sdkCtx, owner)
if !found {
return nil, status.Error(codes.NotFound, "No deposit found for owner")
}
if shareRecord.AmountSupplied.AmountOf(req.Denom).IsZero() {
return nil, status.Error(codes.NotFound, fmt.Sprintf("No deposit for denom %s found for owner", req.Denom))
}
value, err := getAccountValue(sdkCtx, s.keeper, owner, shareRecord.AmountSupplied)
if err != nil {
return nil, status.Error(codes.InvalidArgument, err.Error())
}
return &types.QueryDepositsResponse{
Deposits: []types.DepositResponse{
{
Depositor: owner.String(),
AmountSupplied: shareRecord.AmountSupplied,
Value: value,
},
},
Pagination: nil,
}, nil
}
// 2. All accounts, specific vault
if req.Owner == "" && req.Denom != "" {
_, found := s.keeper.GetVaultRecord(sdkCtx, req.Denom)
if !found {
return nil, status.Error(codes.NotFound, "Vault record for denom not found")
}
deposits := []types.DepositResponse{}
store := prefix.NewStore(sdkCtx.KVStore(s.keeper.key), types.VaultShareRecordKeyPrefix)
pageRes, err := query.FilteredPaginate(
store,
req.Pagination,
func(key []byte, value []byte, accumulate bool) (bool, error) {
var record types.VaultShareRecord
err := s.keeper.cdc.Unmarshal(value, &record)
if err != nil {
return false, err
}
// Only those that have amount of requested denom
if record.AmountSupplied.AmountOf(req.Denom).IsZero() {
// inform paginate that there was no match on this key
return false, nil
}
if accumulate {
accValue, err := getAccountValue(sdkCtx, s.keeper, record.Depositor, record.AmountSupplied)
if err != nil {
return false, err
}
// only add to results if paginate tells us to
deposits = append(deposits, types.DepositResponse{
Depositor: record.Depositor.String(),
AmountSupplied: record.AmountSupplied,
Value: accValue,
})
}
// inform paginate that were was a match on this key
return true, nil
},
)
if err != nil {
return nil, err
}
return &types.QueryDepositsResponse{
Deposits: deposits,
Pagination: pageRes,
}, nil
}
// 3. Specific account, all vaults
if req.Owner != "" && req.Denom == "" {
owner, err := sdk.AccAddressFromBech32(req.Owner)
if err != nil {
return nil, status.Error(codes.InvalidArgument, "Invalid address")
}
deposits := []types.DepositResponse{}
accountShare, found := s.keeper.GetVaultShareRecord(sdkCtx, owner)
if !found {
return nil, status.Error(codes.NotFound, "No deposit found for owner")
}
value, err := getAccountValue(sdkCtx, s.keeper, owner, accountShare.AmountSupplied)
if err != nil {
return nil, status.Error(codes.InvalidArgument, err.Error())
}
deposits = append(deposits, types.DepositResponse{
Depositor: owner.String(),
AmountSupplied: accountShare.AmountSupplied,
Value: value,
})
return &types.QueryDepositsResponse{
Deposits: deposits,
Pagination: nil,
}, nil
}
// 4. All accounts, all vaults
deposits := []types.DepositResponse{}
store := prefix.NewStore(sdkCtx.KVStore(s.keeper.key), types.VaultShareRecordKeyPrefix)
pageRes, err := query.Paginate(
store,
req.Pagination,
func(key []byte, value []byte) error {
var record types.VaultShareRecord
err := s.keeper.cdc.Unmarshal(value, &record)
if err != nil {
return err
}
accValue, err := getAccountValue(sdkCtx, s.keeper, record.Depositor, record.AmountSupplied)
if err != nil {
return err
}
// only add to results if paginate tells us to
deposits = append(deposits, types.DepositResponse{
Depositor: record.Depositor.String(),
AmountSupplied: record.AmountSupplied,
Value: accValue,
})
return nil
},
)
if err != nil {
return nil, err
}
return &types.QueryDepositsResponse{
Deposits: deposits,
Pagination: pageRes,
}, nil
}
// Deposits implements the gRPC service handler for querying x/earn deposits.
func (s queryServer) TotalDeposited(
ctx context.Context,
req *types.QueryTotalDepositedRequest,
) (*types.QueryTotalDepositedResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}
sdkCtx := sdk.UnwrapSDKContext(ctx)
// Single vault
if req.Denom != "" {
totalSupplied, err := s.keeper.GetVaultTotalSupplied(sdkCtx, req.Denom)
if err != nil {
return nil, err
}
return &types.QueryTotalDepositedResponse{
SuppliedCoins: sdk.NewCoins(totalSupplied),
}, nil
}
coins := sdk.NewCoins()
vaults := s.keeper.GetAllVaultRecords(sdkCtx)
for _, vault := range vaults {
coins = coins.Add(vault.TotalSupply)
}
return &types.QueryTotalDepositedResponse{
SuppliedCoins: coins,
}, nil
}
func getAccountValue(
ctx sdk.Context,
keeper Keeper,
account sdk.AccAddress,
supplied sdk.Coins,
) (sdk.Coins, error) {
value := sdk.NewCoins()
for _, coin := range supplied {
accValue, err := keeper.GetVaultAccountValue(ctx, coin.Denom, account)
if err != nil {
return nil, err
}
value = value.Add(sdk.NewCoin(coin.Denom, accValue.Amount))
}
return value, nil
}

View File

@ -5,6 +5,9 @@ import (
"testing" "testing"
"github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/baseapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"github.com/kava-labs/kava/x/earn/keeper" "github.com/kava-labs/kava/x/earn/keeper"
"github.com/kava-labs/kava/x/earn/testutil" "github.com/kava-labs/kava/x/earn/testutil"
@ -53,3 +56,341 @@ func (suite *grpcQueryTestSuite) TestQueryParams() {
res.Params.AllowedVaults, res.Params.AllowedVaults,
) )
} }
func (suite *grpcQueryTestSuite) TestVaults_ZeroSupply() {
// Add vaults
suite.CreateVault("usdx", types.STRATEGY_TYPE_HARD)
suite.CreateVault("busd", types.STRATEGY_TYPE_HARD)
suite.Run("single", func() {
res, err := suite.queryClient.Vaults(context.Background(), types.NewQueryVaultsRequest("usdx"))
suite.Require().NoError(err)
suite.Require().Len(res.Vaults, 1)
suite.Require().Equal(
types.VaultResponse{
Denom: "usdx",
VaultStrategy: types.STRATEGY_TYPE_HARD,
TotalSupplied: sdk.NewInt(0),
TotalValue: sdk.NewInt(0),
},
res.Vaults[0],
)
})
suite.Run("all", func() {
res, err := suite.queryClient.Vaults(context.Background(), types.NewQueryVaultsRequest(""))
suite.Require().NoError(err)
suite.Require().Len(res.Vaults, 2)
suite.Require().ElementsMatch(
[]types.VaultResponse{
{
Denom: "usdx",
VaultStrategy: types.STRATEGY_TYPE_HARD,
TotalSupplied: sdk.NewInt(0),
TotalValue: sdk.NewInt(0),
},
{
Denom: "busd",
VaultStrategy: types.STRATEGY_TYPE_HARD,
TotalSupplied: sdk.NewInt(0),
TotalValue: sdk.NewInt(0),
},
},
res.Vaults,
)
})
}
func (suite *grpcQueryTestSuite) TestVaults_WithSupply() {
vaultDenom := "usdx"
startBalance := sdk.NewInt64Coin(vaultDenom, 1000)
depositAmount := sdk.NewInt64Coin(vaultDenom, 100)
suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD)
acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount)
suite.Require().NoError(err)
res, err := suite.queryClient.Vaults(context.Background(), types.NewQueryVaultsRequest("usdx"))
suite.Require().NoError(err)
suite.Require().Len(res.Vaults, 1)
suite.Require().Equal(
types.VaultResponse{
Denom: "usdx",
VaultStrategy: types.STRATEGY_TYPE_HARD,
TotalSupplied: depositAmount.Amount,
TotalValue: depositAmount.Amount,
},
res.Vaults[0],
)
}
func (suite *grpcQueryTestSuite) TestVaults_NotFound() {
_, err := suite.queryClient.Vaults(context.Background(), types.NewQueryVaultsRequest("usdx"))
suite.Require().Error(err)
suite.Require().ErrorIs(err, status.Errorf(codes.NotFound, "vault not found with specified denom"))
}
func (suite *grpcQueryTestSuite) TestDeposits() {
vault1Denom := "usdx"
vault2Denom := "busd"
vault3Denom := "kava"
// Add vaults
suite.CreateVault(vault1Denom, types.STRATEGY_TYPE_HARD)
suite.CreateVault(vault2Denom, types.STRATEGY_TYPE_HARD)
suite.CreateVault(vault3Denom, types.STRATEGY_TYPE_HARD)
startBalance := sdk.NewCoins(
sdk.NewInt64Coin(vault1Denom, 1000),
sdk.NewInt64Coin(vault2Denom, 1000),
sdk.NewInt64Coin(vault3Denom, 1000),
)
deposit1Amount := sdk.NewInt64Coin(vault1Denom, 100)
deposit2Amount := sdk.NewInt64Coin(vault2Denom, 200)
deposit3Amount := sdk.NewInt64Coin(vault3Denom, 200)
// Accounts
acc1 := suite.CreateAccount(startBalance, 0).GetAddress()
acc2 := suite.CreateAccount(startBalance, 1).GetAddress()
// Deposit into each vault from each account - 4 total deposits
// Acc 1: usdx + busd
// Acc 2: usdx + usdc
err := suite.Keeper.Deposit(suite.Ctx, acc1, deposit1Amount)
suite.Require().NoError(err)
err = suite.Keeper.Deposit(suite.Ctx, acc1, deposit2Amount)
suite.Require().NoError(err)
err = suite.Keeper.Deposit(suite.Ctx, acc2, deposit1Amount)
suite.Require().NoError(err)
err = suite.Keeper.Deposit(suite.Ctx, acc2, deposit3Amount)
suite.Require().NoError(err)
suite.Run("1) 1 vault for 1 account", func() {
// Query all deposits for account 1
res, err := suite.queryClient.Deposits(
context.Background(),
types.NewQueryDepositsRequest(acc1.String(), vault1Denom, nil),
)
suite.Require().NoError(err)
suite.Require().Len(res.Deposits, 1)
suite.Require().ElementsMatchf(
[]types.DepositResponse{
{
Depositor: acc1.String(),
// Still includes all deposits
AmountSupplied: sdk.NewCoins(deposit1Amount, deposit2Amount),
Value: sdk.NewCoins(deposit1Amount, deposit2Amount),
},
},
res.Deposits,
"deposits should match, got %v",
res.Deposits,
)
})
suite.Run("1) invalid vault for 1 account", func() {
_, err := suite.queryClient.Deposits(
context.Background(),
types.NewQueryDepositsRequest(acc1.String(), "notavaliddenom", nil),
)
suite.Require().Error(err)
suite.Require().ErrorIs(err, status.Errorf(codes.NotFound, "No deposit for denom notavaliddenom found for owner"))
})
suite.Run("3) all vaults for 1 account", func() {
// Query all deposits for account 1
res, err := suite.queryClient.Deposits(
context.Background(),
types.NewQueryDepositsRequest(acc1.String(), "", nil),
)
suite.Require().NoError(err)
suite.Require().Len(res.Deposits, 1)
suite.Require().ElementsMatch(
[]types.DepositResponse{
{
Depositor: acc1.String(),
AmountSupplied: sdk.NewCoins(deposit1Amount, deposit2Amount),
Value: sdk.NewCoins(deposit1Amount, deposit2Amount),
},
},
res.Deposits,
)
})
suite.Run("2) all accounts, specific vault", func() {
// Query all deposits for vault 3
res, err := suite.queryClient.Deposits(
context.Background(),
types.NewQueryDepositsRequest("", vault3Denom, nil),
)
suite.Require().NoError(err)
suite.Require().Len(res.Deposits, 1)
suite.Require().ElementsMatch(
[]types.DepositResponse{
{
Depositor: acc2.String(),
AmountSupplied: sdk.NewCoins(deposit1Amount, deposit3Amount),
Value: sdk.NewCoins(deposit1Amount, deposit3Amount),
},
},
res.Deposits,
)
})
suite.Run("4) all vaults and all accounts", func() {
// Query all deposits for all vaults
res, err := suite.queryClient.Deposits(
context.Background(),
types.NewQueryDepositsRequest("", "", nil),
)
suite.Require().NoError(err)
suite.Require().Len(res.Deposits, 2)
suite.Require().ElementsMatchf(
[]types.DepositResponse{
{
Depositor: acc1.String(),
AmountSupplied: sdk.NewCoins(deposit1Amount, deposit2Amount),
Value: sdk.NewCoins(deposit1Amount, deposit2Amount),
},
{
Depositor: acc2.String(),
AmountSupplied: sdk.NewCoins(deposit1Amount, deposit3Amount),
Value: sdk.NewCoins(deposit1Amount, deposit3Amount),
},
},
res.Deposits,
"deposits should match, got %v",
res.Deposits,
)
})
}
func (suite *grpcQueryTestSuite) TestDeposits_NotFound() {
_, err := suite.queryClient.Deposits(
context.Background(),
types.NewQueryDepositsRequest("", "usdx", nil),
)
suite.Require().Error(err)
suite.Require().ErrorIs(err, status.Error(codes.NotFound, "Vault record for denom not found"))
}
func (suite *grpcQueryTestSuite) TestDeposits_InvalidAddress() {
_, err := suite.queryClient.Deposits(
context.Background(),
types.NewQueryDepositsRequest("asdf", "usdx", nil),
)
suite.Require().Error(err)
suite.Require().ErrorIs(err, status.Error(codes.InvalidArgument, "Invalid address"))
_, err = suite.queryClient.Deposits(
context.Background(),
types.NewQueryDepositsRequest("asdf", "", nil),
)
suite.Require().Error(err)
suite.Require().ErrorIs(err, status.Error(codes.InvalidArgument, "Invalid address"))
}
func (suite *grpcQueryTestSuite) TestTotalDeposited_NoSupply() {
// Add vaults
suite.CreateVault("usdx", types.STRATEGY_TYPE_HARD)
suite.CreateVault("cats", types.STRATEGY_TYPE_HARD)
res, err := suite.queryClient.TotalDeposited(context.Background(), types.NewQueryTotalDepositedRequest(""))
suite.Require().NoError(err)
suite.Require().True(res.SuppliedCoins.Empty(), "supplied coins should be empty")
}
func (suite *grpcQueryTestSuite) TestTotalDeposited_All() {
vault1Denom := "usdx"
vault2Denom := "busd"
// Add vaults
suite.CreateVault(vault1Denom, types.STRATEGY_TYPE_HARD)
suite.CreateVault(vault2Denom, types.STRATEGY_TYPE_HARD)
startBalance := sdk.NewCoins(
sdk.NewInt64Coin(vault1Denom, 1000),
sdk.NewInt64Coin(vault2Denom, 1000),
)
deposit1Amount := sdk.NewInt64Coin(vault1Denom, 100)
deposit2Amount := sdk.NewInt64Coin(vault2Denom, 100)
acc := suite.CreateAccount(startBalance, 0).GetAddress()
err := suite.Keeper.Deposit(suite.Ctx, acc, deposit1Amount)
suite.Require().NoError(err)
res, err := suite.queryClient.TotalDeposited(
context.Background(),
types.NewQueryTotalDepositedRequest(""), // query all
)
suite.Require().NoError(err)
suite.Require().Equal(
sdk.NewCoins(deposit1Amount),
res.SuppliedCoins,
"supplied coins should be sum of all supplied coins",
)
err = suite.Keeper.Deposit(suite.Ctx, acc, deposit2Amount)
suite.Require().NoError(err)
res, err = suite.queryClient.TotalDeposited(
context.Background(),
types.NewQueryTotalDepositedRequest(""), // query all
)
suite.Require().NoError(err)
suite.Require().Equal(
sdk.NewCoins(deposit1Amount, deposit2Amount),
res.SuppliedCoins,
"supplied coins should be sum of all supplied coins for multiple coins",
)
}
func (suite *grpcQueryTestSuite) TestTotalDeposited_Single() {
vault1Denom := "usdx"
vault2Denom := "busd"
// Add vaults
suite.CreateVault(vault1Denom, types.STRATEGY_TYPE_HARD)
suite.CreateVault(vault2Denom, types.STRATEGY_TYPE_HARD)
startBalance := sdk.NewCoins(
sdk.NewInt64Coin(vault1Denom, 1000),
sdk.NewInt64Coin(vault2Denom, 1000),
)
deposit1Amount := sdk.NewInt64Coin(vault1Denom, 100)
deposit2Amount := sdk.NewInt64Coin(vault2Denom, 100)
acc := suite.CreateAccount(startBalance, 0).GetAddress()
err := suite.Keeper.Deposit(suite.Ctx, acc, deposit1Amount)
suite.Require().NoError(err)
err = suite.Keeper.Deposit(suite.Ctx, acc, deposit2Amount)
suite.Require().NoError(err)
res, err := suite.queryClient.TotalDeposited(
context.Background(),
types.NewQueryTotalDepositedRequest(vault1Denom),
)
suite.Require().NoError(err)
suite.Require().Equal(
sdk.NewCoins(deposit1Amount),
res.SuppliedCoins,
"should only contain queried denom",
)
res, err = suite.queryClient.TotalDeposited(
context.Background(),
types.NewQueryTotalDepositedRequest(vault2Denom),
)
suite.Require().NoError(err)
suite.Require().Equal(
sdk.NewCoins(deposit2Amount),
res.SuppliedCoins,
"should only contain queried denom",
)
}

View File

@ -12,10 +12,6 @@ type Strategy interface {
// GetStrategyType returns the strategy type // GetStrategyType returns the strategy type
GetStrategyType() types.StrategyType GetStrategyType() types.StrategyType
// IsDenomSupported returns true if the denom is supported for this
// strategy. For example, the hard strategy supports "usdx".
IsDenomSupported(string) bool
// GetEstimatedTotalAssets returns the estimated total assets denominated in // GetEstimatedTotalAssets returns the estimated total assets denominated in
// GetDenom() of this strategy. This is the value if the strategy were to // GetDenom() of this strategy. This is the value if the strategy were to
// liquidate all assets. // liquidate all assets.

View File

@ -24,13 +24,6 @@ func TestStrategyLendTestSuite(t *testing.T) {
suite.Run(t, new(strategyHardTestSuite)) suite.Run(t, new(strategyHardTestSuite))
} }
func (suite *strategyHardTestSuite) TestGetSupportedDenoms() {
strategy, err := suite.Keeper.GetStrategy(types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
suite.True(strategy.IsDenomSupported("usdx"))
}
func (suite *strategyHardTestSuite) TestGetStrategyType() { func (suite *strategyHardTestSuite) TestGetStrategyType() {
strategy, err := suite.Keeper.GetStrategy(types.STRATEGY_TYPE_HARD) strategy, err := suite.Keeper.GetStrategy(types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err) suite.Require().NoError(err)
@ -38,25 +31,6 @@ func (suite *strategyHardTestSuite) TestGetStrategyType() {
suite.Equal(types.STRATEGY_TYPE_HARD, strategy.GetStrategyType()) suite.Equal(types.STRATEGY_TYPE_HARD, strategy.GetStrategyType())
} }
func (suite *strategyHardTestSuite) TestDeposit_InvalidDenom() {
// Not supported by hard strategy
vaultDenom := "busd"
startBalance := sdk.NewInt64Coin(vaultDenom, 1000)
depositAmount := sdk.NewInt64Coin(vaultDenom, 100)
suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD)
acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount)
suite.Require().Error(err)
suite.Require().ErrorIs(
err,
types.ErrStrategyDenomNotSupported,
"strategy should only allow usdx deposits",
)
}
func (suite *strategyHardTestSuite) TestDeposit_SingleAcc() { func (suite *strategyHardTestSuite) TestDeposit_SingleAcc() {
vaultDenom := "usdx" vaultDenom := "usdx"
startBalance := sdk.NewInt64Coin(vaultDenom, 1000) startBalance := sdk.NewInt64Coin(vaultDenom, 1000)

View File

@ -136,6 +136,37 @@ func (k *Keeper) SetVaultRecord(ctx sdk.Context, record types.VaultRecord) {
store.Set(types.VaultKey(record.Denom), bz) store.Set(types.VaultKey(record.Denom), bz)
} }
// IterateVaultRecords iterates over all vault objects in the store and performs
// a callback function.
func (k Keeper) IterateVaultRecords(
ctx sdk.Context,
cb func(record types.VaultRecord) (stop bool),
) {
store := prefix.NewStore(ctx.KVStore(k.key), types.VaultRecordKeyPrefix)
iterator := sdk.KVStorePrefixIterator(store, []byte{})
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var record types.VaultRecord
k.cdc.MustUnmarshal(iterator.Value(), &record)
if cb(record) {
break
}
}
}
// GetAllVaultRecords returns all vault records from the store.
func (k Keeper) GetAllVaultRecords(ctx sdk.Context) types.VaultRecords {
var records types.VaultRecords
k.IterateVaultRecords(ctx, func(record types.VaultRecord) bool {
records = append(records, record)
return false
})
return records
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// VaultShare -- user shares per vault // VaultShare -- user shares per vault

View File

@ -94,6 +94,42 @@ func (suite *Suite) SetupTest() {
sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("0.05"),
sdk.ZeroDec(), sdk.ZeroDec(),
), ),
hardtypes.NewMoneyMarket(
"busd",
hardtypes.NewBorrowLimit(
true,
sdk.MustNewDecFromStr("20000000"),
sdk.MustNewDecFromStr("1"),
),
"busd:usd",
sdk.NewInt(1000000),
hardtypes.NewInterestRateModel(
sdk.MustNewDecFromStr("0.05"),
sdk.MustNewDecFromStr("2"),
sdk.MustNewDecFromStr("0.8"),
sdk.MustNewDecFromStr("10"),
),
sdk.MustNewDecFromStr("0.05"),
sdk.ZeroDec(),
),
hardtypes.NewMoneyMarket(
"kava",
hardtypes.NewBorrowLimit(
true,
sdk.MustNewDecFromStr("20000000"),
sdk.MustNewDecFromStr("1"),
),
"kava:usd",
sdk.NewInt(1000000),
hardtypes.NewInterestRateModel(
sdk.MustNewDecFromStr("0.05"),
sdk.MustNewDecFromStr("2"),
sdk.MustNewDecFromStr("0.8"),
sdk.MustNewDecFromStr("10"),
),
sdk.MustNewDecFromStr("0.05"),
sdk.ZeroDec(),
),
}, },
sdk.NewDec(10), sdk.NewDec(10),
), ),
@ -185,9 +221,12 @@ func (suite *Suite) CreateVault(vaultDenom string, vaultStrategy types.StrategyT
allowedVaults := suite.Keeper.GetAllowedVaults(suite.Ctx) allowedVaults := suite.Keeper.GetAllowedVaults(suite.Ctx)
allowedVaults = append(allowedVaults, vault) allowedVaults = append(allowedVaults, vault)
params := types.NewParams(allowedVaults)
suite.Require().NoError(params.Validate())
suite.Keeper.SetParams( suite.Keeper.SetParams(
suite.Ctx, suite.Ctx,
types.NewParams(allowedVaults), params,
) )
} }

View File

@ -6,11 +6,10 @@ import (
// earn module errors // earn module errors
var ( var (
ErrInvalidVaultDenom = sdkerrors.Register(ModuleName, 2, "invalid vault denom") ErrInvalidVaultDenom = sdkerrors.Register(ModuleName, 2, "invalid vault denom")
ErrInvalidVaultStrategy = sdkerrors.Register(ModuleName, 3, "invalid vault strategy") ErrInvalidVaultStrategy = sdkerrors.Register(ModuleName, 3, "invalid vault strategy")
ErrInsufficientAmount = sdkerrors.Register(ModuleName, 4, "insufficient amount") ErrInsufficientAmount = sdkerrors.Register(ModuleName, 4, "insufficient amount")
ErrInsufficientValue = sdkerrors.Register(ModuleName, 5, "insufficient vault account value") ErrInsufficientValue = sdkerrors.Register(ModuleName, 5, "insufficient vault account value")
ErrVaultRecordNotFound = sdkerrors.Register(ModuleName, 6, "vault record not found") ErrVaultRecordNotFound = sdkerrors.Register(ModuleName, 6, "vault record not found")
ErrVaultShareRecordNotFound = sdkerrors.Register(ModuleName, 7, "vault share record not found") ErrVaultShareRecordNotFound = sdkerrors.Register(ModuleName, 7, "vault share record not found")
ErrStrategyDenomNotSupported = sdkerrors.Register(ModuleName, 8, "denom not supported for strategy")
) )

View File

@ -94,26 +94,26 @@ func init() {
func init() { proto.RegisterFile("kava/earn/v1beta1/genesis.proto", fileDescriptor_514fe130cb964f8c) } func init() { proto.RegisterFile("kava/earn/v1beta1/genesis.proto", fileDescriptor_514fe130cb964f8c) }
var fileDescriptor_514fe130cb964f8c = []byte{ var fileDescriptor_514fe130cb964f8c = []byte{
// 293 bytes of a gzipped FileDescriptorProto // 294 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xcf, 0x4e, 0x2c, 0x4b, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xcf, 0x4e, 0x2c, 0x4b,
0xd4, 0x4f, 0x4d, 0x2c, 0xca, 0xd3, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, 0x49, 0x34, 0xd4, 0x4f, 0x4f, 0xd4, 0x4f, 0x4d, 0x2c, 0xca, 0xd3, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, 0x49, 0x34, 0xd4, 0x4f, 0x4f,
0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x04, 0x29, 0xd0, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x04, 0x29, 0xd0,
0x03, 0x29, 0xd0, 0x83, 0x2a, 0x90, 0x92, 0xc5, 0xd4, 0x53, 0x96, 0x58, 0x9a, 0x53, 0x02, 0xd1, 0x03, 0x29, 0xd0, 0x83, 0x2a, 0x90, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0xcb, 0xea, 0x83, 0x58,
0x21, 0x25, 0x87, 0x29, 0x5d, 0x90, 0x58, 0x94, 0x98, 0x0b, 0x35, 0x51, 0x4a, 0x24, 0x3d, 0x3f, 0x10, 0x85, 0x52, 0x72, 0x98, 0x26, 0x15, 0x24, 0x16, 0x25, 0xe6, 0x42, 0x0d, 0x92, 0x92, 0xc5,
0x3d, 0x1f, 0xcc, 0xd4, 0x07, 0xb1, 0x20, 0xa2, 0x4a, 0x93, 0x98, 0xb8, 0x78, 0xdc, 0x21, 0x36, 0x94, 0x2f, 0x4b, 0x2c, 0xcd, 0x29, 0x81, 0x48, 0x2b, 0x4d, 0x62, 0xe2, 0xe2, 0x71, 0x87, 0xd8,
0x07, 0x97, 0x24, 0x96, 0xa4, 0x0a, 0x99, 0x73, 0xb1, 0x41, 0xb4, 0x49, 0x30, 0x2a, 0x30, 0x6a, 0x1c, 0x5c, 0x92, 0x58, 0x92, 0x2a, 0x64, 0xce, 0xc5, 0x06, 0xd1, 0x2f, 0xc1, 0xa8, 0xc0, 0xa8,
0x70, 0x1b, 0x49, 0xea, 0x61, 0xb8, 0x44, 0x2f, 0x00, 0xac, 0xc0, 0x89, 0xe5, 0xc4, 0x3d, 0x79, 0xc1, 0x6d, 0x24, 0xa9, 0x87, 0xe1, 0x12, 0xbd, 0x00, 0xb0, 0x02, 0x27, 0x96, 0x13, 0xf7, 0xe4,
0x86, 0x20, 0xa8, 0x72, 0xa1, 0x48, 0x2e, 0x5e, 0xb0, 0x73, 0xe2, 0x8b, 0x52, 0x93, 0xf3, 0x8b, 0x19, 0x82, 0xa0, 0xca, 0x85, 0x22, 0xb9, 0x78, 0xc1, 0x06, 0xc7, 0x17, 0xa5, 0x26, 0xe7, 0x17,
0x52, 0x8a, 0x25, 0x98, 0x14, 0x98, 0x35, 0xb8, 0x8d, 0xe4, 0xb0, 0xe8, 0x0f, 0x03, 0xa9, 0x0b, 0xa5, 0x14, 0x4b, 0x30, 0x29, 0x30, 0x6b, 0x70, 0x1b, 0xc9, 0x61, 0xd1, 0x1f, 0x06, 0x52, 0x17,
0x02, 0x2b, 0x73, 0x12, 0x01, 0x19, 0xb2, 0xea, 0xbe, 0x3c, 0x0f, 0x92, 0x60, 0x71, 0x10, 0x4f, 0x04, 0x56, 0xe6, 0x24, 0x02, 0x32, 0x64, 0xd5, 0x7d, 0x79, 0x1e, 0x24, 0xc1, 0xe2, 0x20, 0x9e,
0x19, 0x12, 0x4f, 0x28, 0x8f, 0x4b, 0x18, 0x62, 0x74, 0x71, 0x46, 0x62, 0x51, 0x2a, 0xdc, 0x02, 0x32, 0x24, 0x9e, 0x50, 0x1e, 0x97, 0x30, 0xc4, 0xe8, 0xe2, 0x8c, 0xc4, 0xa2, 0x54, 0xb8, 0x05,
0x66, 0xb0, 0x05, 0xca, 0xb8, 0x2c, 0x08, 0x06, 0x29, 0x86, 0xda, 0x22, 0x09, 0xb5, 0x45, 0x10, 0xcc, 0x60, 0x0b, 0x94, 0x71, 0x59, 0x10, 0x0c, 0x52, 0x0c, 0xb5, 0x45, 0x12, 0x6a, 0x8b, 0x20,
0x5d, 0xa6, 0x38, 0x48, 0xb0, 0x0c, 0x5d, 0xc8, 0xc9, 0xe1, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xba, 0x4c, 0x71, 0x90, 0x60, 0x19, 0xba, 0x90, 0x93, 0xc3, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e,
0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe1, 0xb1, 0x1c, 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37,
0x8f, 0xe5, 0x18, 0xa2, 0xd4, 0xd2, 0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0x1e, 0xcb, 0x31, 0x44, 0xa9, 0xa5, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea,
0x41, 0xd6, 0xea, 0xe6, 0x24, 0x26, 0x15, 0x83, 0x59, 0xfa, 0x15, 0x90, 0xb0, 0x2f, 0xa9, 0x2c, 0x83, 0xac, 0xd5, 0xcd, 0x49, 0x4c, 0x2a, 0x06, 0xb3, 0xf4, 0x2b, 0x20, 0x81, 0x5c, 0x52, 0x59,
0x48, 0x2d, 0x4e, 0x62, 0x03, 0x87, 0xae, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x97, 0x15, 0xe4, 0x90, 0x5a, 0x9c, 0xc4, 0x06, 0x0e, 0x5d, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8d, 0x54,
0xfa, 0xe8, 0x01, 0x00, 0x00, 0x3b, 0x56, 0xe8, 0x01, 0x00, 0x00,
} }
func (m *GenesisState) Marshal() (dAtA []byte, err error) { func (m *GenesisState) Marshal() (dAtA []byte, err error) {

View File

@ -23,6 +23,7 @@ var _ = math.Inf
// proto package needs to be updated. // proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// Params defines the parameters of the earn module.
type Params struct { type Params struct {
AllowedVaults AllowedVaults `protobuf:"bytes,1,rep,name=allowed_vaults,json=allowedVaults,proto3,castrepeated=AllowedVaults" json:"allowed_vaults"` AllowedVaults AllowedVaults `protobuf:"bytes,1,rep,name=allowed_vaults,json=allowedVaults,proto3,castrepeated=AllowedVaults" json:"allowed_vaults"`
} }

View File

@ -1,5 +1,35 @@
package types package types
import "github.com/cosmos/cosmos-sdk/types/query"
// NewQueryParamsRequest returns a new QueryParamsRequest
func NewQueryParamsRequest() *QueryParamsRequest { func NewQueryParamsRequest() *QueryParamsRequest {
return &QueryParamsRequest{} return &QueryParamsRequest{}
} }
// NewQueryVaultsRequest returns a new QueryVaultsRequest
func NewQueryVaultsRequest(denom string) *QueryVaultsRequest {
return &QueryVaultsRequest{
Denom: denom,
}
}
// NewQueryDepositsRequest returns a new QueryDepositsRequest
func NewQueryDepositsRequest(
owner string,
denom string,
pagination *query.PageRequest,
) *QueryDepositsRequest {
return &QueryDepositsRequest{
Owner: owner,
Denom: denom,
Pagination: pagination,
}
}
// NewQueryTotalDepositedRequest returns a new QueryTotalDepositedRequest
func NewQueryTotalDepositedRequest(denom string) *QueryTotalDepositedRequest {
return &QueryTotalDepositedRequest{
Denom: denom,
}
}

File diff suppressed because it is too large Load Diff

View File

@ -49,6 +49,150 @@ func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshal
} }
func request_Query_Vaults_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryVaultsRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["denom"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "denom")
}
protoReq.Denom, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "denom", err)
}
msg, err := client.Vaults(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Query_Vaults_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryVaultsRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["denom"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "denom")
}
protoReq.Denom, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "denom", err)
}
msg, err := server.Vaults(ctx, &protoReq)
return msg, metadata, err
}
var (
filter_Query_Deposits_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
)
func request_Query_Deposits_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryDepositsRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Deposits_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.Deposits(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Query_Deposits_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryDepositsRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Deposits_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.Deposits(ctx, &protoReq)
return msg, metadata, err
}
func request_Query_TotalDeposited_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryTotalDepositedRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["denom"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "denom")
}
protoReq.Denom, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "denom", err)
}
msg, err := client.TotalDeposited(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Query_TotalDeposited_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryTotalDepositedRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["denom"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "denom")
}
protoReq.Denom, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "denom", err)
}
msg, err := server.TotalDeposited(ctx, &protoReq)
return msg, metadata, err
}
// RegisterQueryHandlerServer registers the http handlers for service Query to "mux". // RegisterQueryHandlerServer registers the http handlers for service Query to "mux".
// UnaryRPC :call QueryServer directly. // UnaryRPC :call QueryServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
@ -75,6 +219,66 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
}) })
mux.Handle("GET", pattern_Query_Vaults_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Query_Vaults_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_Vaults_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_Query_Deposits_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Query_Deposits_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_Deposits_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_Query_TotalDeposited_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Query_TotalDeposited_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_TotalDeposited_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil return nil
} }
@ -136,13 +340,85 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
}) })
mux.Handle("GET", pattern_Query_Vaults_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Query_Vaults_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_Vaults_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_Query_Deposits_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Query_Deposits_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_Deposits_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_Query_TotalDeposited_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Query_TotalDeposited_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_TotalDeposited_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil return nil
} }
var ( var (
pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"kava", "earn", "v1beta1", "params"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"kava", "earn", "v1beta1", "params"}, "", runtime.AssumeColonVerbOpt(false)))
pattern_Query_Vaults_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"kava", "earn", "v1beta1", "vaults", "denom"}, "", runtime.AssumeColonVerbOpt(false)))
pattern_Query_Deposits_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"kava", "earn", "v1beta1", "deposits"}, "", runtime.AssumeColonVerbOpt(false)))
pattern_Query_TotalDeposited_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"kava", "earn", "v1beta1", "total-deposited", "denom"}, "", runtime.AssumeColonVerbOpt(false)))
) )
var ( var (
forward_Query_Params_0 = runtime.ForwardResponseMessage forward_Query_Params_0 = runtime.ForwardResponseMessage
forward_Query_Vaults_0 = runtime.ForwardResponseMessage
forward_Query_Deposits_0 = runtime.ForwardResponseMessage
forward_Query_TotalDeposited_0 = runtime.ForwardResponseMessage
) )

View File

@ -5,8 +5,6 @@ package types
import ( import (
fmt "fmt" fmt "fmt"
_ "github.com/cosmos/cosmos-proto"
_ "github.com/cosmos/cosmos-sdk/types"
_ "github.com/gogo/protobuf/gogoproto" _ "github.com/gogo/protobuf/gogoproto"
proto "github.com/gogo/protobuf/proto" proto "github.com/gogo/protobuf/proto"
math "math" math "math"
@ -23,24 +21,30 @@ var _ = math.Inf
// proto package needs to be updated. // proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// StrategyType is the type of strategy that a vault uses to optimize yields.
type StrategyType int32 type StrategyType int32
const ( const (
STRATEGY_TYPE_UNKNOWN StrategyType = 0 // STRATEGY_TYPE_UNSPECIFIED represents an unspecified or invalid strategy type.
STRATEGY_TYPE_HARD StrategyType = 1 STRATEGY_TYPE_UNSPECIFIED StrategyType = 0
// STRATEGY_TYPE_HARD represents the strategy that deposits assets in the Hard
// module.
STRATEGY_TYPE_HARD StrategyType = 1
// STRATEGY_TYPE_SAVINGS represents the strategy that deposits assets in the
// Savings module.
STRATEGY_TYPE_SAVINGS StrategyType = 2 STRATEGY_TYPE_SAVINGS StrategyType = 2
) )
var StrategyType_name = map[int32]string{ var StrategyType_name = map[int32]string{
0: "STRATEGY_TYPE_UNKNOWN", 0: "STRATEGY_TYPE_UNSPECIFIED",
1: "STRATEGY_TYPE_HARD", 1: "STRATEGY_TYPE_HARD",
2: "STRATEGY_TYPE_SAVINGS", 2: "STRATEGY_TYPE_SAVINGS",
} }
var StrategyType_value = map[string]int32{ var StrategyType_value = map[string]int32{
"STRATEGY_TYPE_UNKNOWN": 0, "STRATEGY_TYPE_UNSPECIFIED": 0,
"STRATEGY_TYPE_HARD": 1, "STRATEGY_TYPE_HARD": 1,
"STRATEGY_TYPE_SAVINGS": 2, "STRATEGY_TYPE_SAVINGS": 2,
} }
func (x StrategyType) String() string { func (x StrategyType) String() string {
@ -58,21 +62,19 @@ func init() {
func init() { proto.RegisterFile("kava/earn/v1beta1/strategy.proto", fileDescriptor_257c4968dd48fa09) } func init() { proto.RegisterFile("kava/earn/v1beta1/strategy.proto", fileDescriptor_257c4968dd48fa09) }
var fileDescriptor_257c4968dd48fa09 = []byte{ var fileDescriptor_257c4968dd48fa09 = []byte{
// 243 bytes of a gzipped FileDescriptorProto // 220 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0xc8, 0x4e, 0x2c, 0x4b, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0xc8, 0x4e, 0x2c, 0x4b,
0xd4, 0x4f, 0x4d, 0x2c, 0xca, 0xd3, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, 0x49, 0x34, 0xd4, 0x2f, 0x2e, 0xd4, 0x4f, 0x4d, 0x2c, 0xca, 0xd3, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, 0x49, 0x34, 0xd4, 0x2f, 0x2e,
0x29, 0x4a, 0x2c, 0x49, 0x4d, 0xaf, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x04, 0xa9, 0x29, 0x4a, 0x2c, 0x49, 0x4d, 0xaf, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x04, 0xa9,
0xd0, 0x03, 0xa9, 0xd0, 0x83, 0xaa, 0x90, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0xcb, 0xea, 0x83, 0xd0, 0x03, 0xa9, 0xd0, 0x83, 0xaa, 0x90, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0xcb, 0xea, 0x83,
0x58, 0x10, 0x85, 0x52, 0x72, 0xc9, 0xf9, 0xc5, 0xb9, 0xf9, 0xc5, 0xfa, 0x49, 0x89, 0xc5, 0xa9, 0x58, 0x10, 0x85, 0x5a, 0x69, 0x5c, 0x3c, 0xc1, 0x50, 0xad, 0x21, 0x95, 0x05, 0xa9, 0x42, 0xb2,
0x70, 0xc3, 0x92, 0xf3, 0x33, 0xf3, 0xa0, 0xf2, 0x92, 0x10, 0xf9, 0x78, 0x88, 0x46, 0x08, 0x07, 0x5c, 0x92, 0xc1, 0x21, 0x41, 0x8e, 0x21, 0xae, 0xee, 0x91, 0xf1, 0x21, 0x91, 0x01, 0xae, 0xf1,
0x22, 0xa5, 0x95, 0xc4, 0xc5, 0x13, 0x0c, 0xb5, 0x35, 0xa4, 0xb2, 0x20, 0x55, 0x48, 0x92, 0x4b, 0xa1, 0x7e, 0xc1, 0x01, 0xae, 0xce, 0x9e, 0x6e, 0x9e, 0xae, 0x2e, 0x02, 0x0c, 0x42, 0x62, 0x5c,
0x34, 0x38, 0x24, 0xc8, 0x31, 0xc4, 0xd5, 0x3d, 0x32, 0x3e, 0x24, 0x32, 0xc0, 0x35, 0x3e, 0xd4, 0x42, 0xa8, 0xd2, 0x1e, 0x8e, 0x41, 0x2e, 0x02, 0x8c, 0x42, 0x92, 0x5c, 0xa2, 0xa8, 0xe2, 0xc1,
0xcf, 0xdb, 0xcf, 0x3f, 0xdc, 0x4f, 0x80, 0x41, 0x48, 0x8c, 0x4b, 0x08, 0x55, 0xca, 0xc3, 0x31, 0x8e, 0x61, 0x9e, 0x7e, 0xee, 0xc1, 0x02, 0x4c, 0x52, 0x2c, 0x1d, 0x8b, 0xe5, 0x18, 0x9c, 0x1c,
0xc8, 0x45, 0x80, 0x11, 0x53, 0x4b, 0xb0, 0x63, 0x98, 0xa7, 0x9f, 0x7b, 0xb0, 0x00, 0x93, 0x14, 0x4e, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5,
0x4b, 0xc7, 0x62, 0x39, 0x06, 0x27, 0x87, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0x18, 0x2e, 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0x4a, 0x2d, 0x3d, 0xb3, 0x24, 0xa3,
0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x34, 0x49, 0x2f, 0x39, 0x3f, 0x57, 0x1f, 0xe4, 0x6a, 0xdd, 0x9c, 0xc4, 0xa4, 0x62, 0x30, 0x4b,
0x88, 0x52, 0x4b, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x07, 0x79, 0x56, 0xbf, 0x02, 0xe2, 0xc7, 0x92, 0xca, 0x82, 0xd4, 0xe2, 0x24, 0x36, 0xb0, 0x83, 0x8d, 0x01, 0x01,
0x37, 0x27, 0x31, 0xa9, 0x18, 0xcc, 0xd2, 0xaf, 0x80, 0x04, 0x4d, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x00, 0x00, 0xff, 0xff, 0x81, 0x9e, 0x23, 0x1c, 0xfd, 0x00, 0x00, 0x00,
0x12, 0x1b, 0xd8, 0xb1, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x62, 0x68, 0x2c, 0xbc, 0x34,
0x01, 0x00, 0x00,
} }

View File

@ -202,26 +202,26 @@ var fileDescriptor_2e9dcf48a3fa0009 = []byte{
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xca, 0x4e, 0x2c, 0x4b, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xca, 0x4e, 0x2c, 0x4b,
0xd4, 0x4f, 0x4d, 0x2c, 0xca, 0xd3, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, 0x49, 0x34, 0xd4, 0x2f, 0xa9, 0xd4, 0x4f, 0x4d, 0x2c, 0xca, 0xd3, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, 0x49, 0x34, 0xd4, 0x2f, 0xa9,
0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x04, 0xc9, 0xe9, 0x81, 0xe4, 0xf4, 0xa0, 0x72, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x04, 0xc9, 0xe9, 0x81, 0xe4, 0xf4, 0xa0, 0x72,
0x52, 0x22, 0xe9, 0xf9, 0xe9, 0xf9, 0x60, 0x59, 0x7d, 0x10, 0x0b, 0xa2, 0x50, 0x4a, 0x32, 0x39, 0x52, 0x92, 0xc9, 0xf9, 0xc5, 0xb9, 0xf9, 0xc5, 0xf1, 0x60, 0x05, 0xfa, 0x10, 0x0e, 0x44, 0xb5,
0xbf, 0x38, 0x37, 0xbf, 0x38, 0x1e, 0x22, 0x01, 0xe1, 0x40, 0xa5, 0xe4, 0x20, 0x3c, 0xfd, 0xa4, 0x94, 0x1c, 0x84, 0xa7, 0x9f, 0x94, 0x58, 0x9c, 0x0a, 0x37, 0x2b, 0x39, 0x3f, 0x33, 0x0f, 0x2a,
0xc4, 0xe2, 0x54, 0xb8, 0x0d, 0xc9, 0xf9, 0x99, 0x79, 0x10, 0x79, 0xa5, 0x66, 0x46, 0x2e, 0x2e, 0x2f, 0x92, 0x9e, 0x9f, 0x9e, 0x0f, 0xd1, 0x07, 0x62, 0x41, 0x44, 0x95, 0x9a, 0x19, 0xb9, 0xb8,
0xdf, 0xe2, 0x74, 0x97, 0xd4, 0x82, 0xfc, 0xe2, 0xcc, 0x12, 0x21, 0x33, 0x2e, 0xce, 0x14, 0x08, 0x7c, 0x8b, 0xd3, 0x5d, 0x52, 0x0b, 0xf2, 0x8b, 0x33, 0x4b, 0x84, 0xcc, 0xb8, 0x38, 0x53, 0x20,
0x33, 0xbf, 0x48, 0x82, 0x51, 0x81, 0x51, 0x83, 0xd3, 0x49, 0xe2, 0xd2, 0x16, 0x5d, 0x11, 0xa8, 0xcc, 0xfc, 0x22, 0x09, 0x46, 0x05, 0x46, 0x0d, 0x4e, 0x27, 0x89, 0x4b, 0x5b, 0x74, 0x45, 0xa0,
0x99, 0x8e, 0x29, 0x29, 0x45, 0xa9, 0xc5, 0xc5, 0xc1, 0x25, 0x45, 0x99, 0x79, 0xe9, 0x41, 0x08, 0x36, 0x39, 0xa6, 0xa4, 0x14, 0xa5, 0x16, 0x17, 0x07, 0x97, 0x14, 0x65, 0xe6, 0xa5, 0x07, 0x21,
0xa5, 0x42, 0xe6, 0x5c, 0x6c, 0x89, 0xb9, 0xf9, 0xa5, 0x79, 0x25, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0x94, 0x0a, 0x99, 0x73, 0xb1, 0x25, 0xe6, 0xe6, 0x97, 0xe6, 0x95, 0x48, 0x30, 0x29, 0x30, 0x6a,
0xdc, 0x46, 0x92, 0x7a, 0x50, 0x1d, 0x20, 0x7b, 0x61, 0xae, 0xd7, 0x73, 0xce, 0xcf, 0xcc, 0x73, 0x70, 0x1b, 0x49, 0xea, 0x41, 0x75, 0x80, 0x5c, 0x03, 0x73, 0xbd, 0x9e, 0x73, 0x7e, 0x66, 0x9e,
0x62, 0x39, 0x71, 0x4f, 0x9e, 0x21, 0x08, 0xaa, 0xdc, 0x8a, 0xa5, 0x63, 0x81, 0x3c, 0x83, 0x92, 0x13, 0xcb, 0x89, 0x7b, 0xf2, 0x0c, 0x41, 0x50, 0xe5, 0x56, 0x2c, 0x1d, 0x0b, 0xe4, 0x19, 0x94,
0x08, 0x97, 0x10, 0xc2, 0x11, 0x41, 0xa9, 0xc5, 0x05, 0xf9, 0x79, 0xc5, 0xa9, 0x4a, 0x55, 0x5c, 0x44, 0xb8, 0x84, 0x10, 0x8e, 0x08, 0x4a, 0x2d, 0x2e, 0xc8, 0xcf, 0x2b, 0x4e, 0x55, 0xaa, 0xe2,
0xdc, 0xbe, 0xc5, 0xe9, 0xe1, 0x99, 0x25, 0x19, 0x29, 0x45, 0x89, 0xe5, 0x42, 0x3a, 0x5c, 0x2c, 0xe2, 0xf6, 0x2d, 0x4e, 0x0f, 0xcf, 0x2c, 0xc9, 0x48, 0x29, 0x4a, 0x2c, 0x17, 0xd2, 0xe1, 0x62,
0x69, 0x45, 0xf9, 0xb9, 0x04, 0x9d, 0x05, 0x56, 0x45, 0xa9, 0x8b, 0x44, 0xb9, 0x84, 0x91, 0xec, 0x49, 0x2b, 0xca, 0xcf, 0x25, 0xe8, 0x2c, 0xb0, 0x2a, 0x4a, 0x5d, 0x24, 0xca, 0x25, 0x8c, 0x64,
0x86, 0x39, 0xc9, 0x68, 0x15, 0x23, 0x17, 0xb3, 0x6f, 0x71, 0xba, 0x90, 0x3f, 0x17, 0x3b, 0x2c, 0x37, 0xcc, 0x49, 0x46, 0xab, 0x18, 0xb9, 0x98, 0x7d, 0x8b, 0xd3, 0x85, 0xfc, 0xb9, 0xd8, 0x61,
0xc8, 0x64, 0xf5, 0x30, 0xa2, 0x49, 0x0f, 0xe1, 0x19, 0x29, 0x55, 0xbc, 0xd2, 0x30, 0x83, 0x85, 0x41, 0x26, 0xab, 0x87, 0x11, 0x4d, 0x7a, 0x08, 0xcf, 0x48, 0xa9, 0xe2, 0x95, 0x86, 0x19, 0x2c,
0x82, 0xb8, 0x38, 0xe0, 0x1e, 0x95, 0xc3, 0xae, 0x05, 0x26, 0x2f, 0xa5, 0x86, 0x5f, 0x1e, 0x66, 0x14, 0xc4, 0xc5, 0x01, 0xf7, 0xa8, 0x1c, 0x76, 0x2d, 0x30, 0x79, 0x29, 0x35, 0xfc, 0xf2, 0x30,
0xa6, 0x93, 0xc3, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0x33, 0x9d, 0x1c, 0x4e, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6,
0xe1, 0xb1, 0x1c, 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, 0xa9, 0xa5, 0x67, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0x4a, 0x2d, 0x3d,
0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0x83, 0xcc, 0xd2, 0xcd, 0x49, 0x4c, 0x2a, 0xb3, 0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, 0x3f, 0x57, 0x1f, 0x64, 0x96, 0x6e, 0x4e, 0x62, 0x52,
0x06, 0xb3, 0xf4, 0x2b, 0x20, 0x89, 0xb1, 0xa4, 0xb2, 0x20, 0xb5, 0x38, 0x89, 0x0d, 0x9c, 0x48, 0x31, 0x98, 0xa5, 0x5f, 0x01, 0x49, 0x8c, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x49, 0x6c, 0xe0, 0x44,
0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x0d, 0x62, 0xb1, 0xf7, 0xa6, 0x02, 0x00, 0x00, 0x62, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0xc0, 0x48, 0xd0, 0x39, 0xa6, 0x02, 0x00, 0x00,
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.

View File

@ -59,7 +59,7 @@ func (a *AllowedVault) Validate() error {
return ErrInvalidVaultDenom return ErrInvalidVaultDenom
} }
if a.VaultStrategy == STRATEGY_TYPE_UNKNOWN { if a.VaultStrategy == STRATEGY_TYPE_UNSPECIFIED {
return ErrInvalidVaultStrategy return ErrInvalidVaultStrategy
} }

View File

@ -31,7 +31,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
type AllowedVault struct { type AllowedVault struct {
// Denom is the only supported denomination of the vault for deposits and withdrawals. // Denom is the only supported denomination of the vault for deposits and withdrawals.
Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"` Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"`
// VaultStrategy is the strategies to use for this vault. // VaultStrategy is the strategy used for this vault.
VaultStrategy StrategyType `protobuf:"varint,2,opt,name=vault_strategy,json=vaultStrategy,proto3,enum=kava.earn.v1beta1.StrategyType" json:"vault_strategy,omitempty"` VaultStrategy StrategyType `protobuf:"varint,2,opt,name=vault_strategy,json=vaultStrategy,proto3,enum=kava.earn.v1beta1.StrategyType" json:"vault_strategy,omitempty"`
} }
@ -79,7 +79,7 @@ func (m *AllowedVault) GetVaultStrategy() StrategyType {
if m != nil { if m != nil {
return m.VaultStrategy return m.VaultStrategy
} }
return STRATEGY_TYPE_UNKNOWN return STRATEGY_TYPE_UNSPECIFIED
} }
// VaultRecord is the state of a vault and is used to store the state of a // VaultRecord is the state of a vault and is used to store the state of a
@ -206,32 +206,32 @@ func init() { proto.RegisterFile("kava/earn/v1beta1/vault.proto", fileDescriptor
var fileDescriptor_884eb89509fbdc04 = []byte{ var fileDescriptor_884eb89509fbdc04 = []byte{
// 417 bytes of a gzipped FileDescriptorProto // 417 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xbf, 0xae, 0xd3, 0x30, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xbd, 0x8e, 0xd3, 0x40,
0x14, 0xc6, 0x93, 0xcb, 0x1f, 0xe9, 0xba, 0xa5, 0x40, 0xb8, 0x43, 0xef, 0x95, 0x48, 0xa2, 0x0e, 0x10, 0xc7, 0xed, 0xe3, 0x43, 0xba, 0x4d, 0x08, 0x60, 0xae, 0xc8, 0x9d, 0x84, 0x6d, 0xa5, 0x40,
0xa8, 0x4b, 0x1c, 0xee, 0xe5, 0x05, 0x68, 0x90, 0x10, 0x73, 0x82, 0x18, 0x58, 0x2a, 0x27, 0x36, 0x69, 0xbc, 0xe6, 0x8e, 0x17, 0x20, 0x46, 0x42, 0xd4, 0x36, 0xa2, 0xa0, 0x89, 0xd6, 0xde, 0xc5,
0x69, 0xd4, 0x24, 0x27, 0x8a, 0x9d, 0x42, 0xde, 0x82, 0xe7, 0x60, 0xe6, 0x21, 0x3a, 0x56, 0x4c, 0xb1, 0x62, 0x7b, 0x2c, 0xef, 0x3a, 0xe0, 0xb7, 0xe0, 0x39, 0xa8, 0x79, 0x88, 0x94, 0x11, 0x15,
0x4c, 0x05, 0xb5, 0x2f, 0xc0, 0xcc, 0x84, 0xfc, 0xa7, 0x05, 0xa9, 0x02, 0x31, 0xc5, 0xf6, 0x77, 0x55, 0x40, 0xc9, 0x0b, 0x50, 0x53, 0xa1, 0xfd, 0x48, 0x40, 0x8a, 0x40, 0x54, 0xde, 0x9d, 0x99,
0xbe, 0xf3, 0x3b, 0x9f, 0x63, 0xf4, 0x78, 0x49, 0x56, 0x24, 0x64, 0xa4, 0xad, 0xc3, 0xd5, 0x75, 0xff, 0xfc, 0xfe, 0x33, 0x5e, 0xf4, 0x78, 0x49, 0x56, 0x24, 0x64, 0xa4, 0xad, 0xc3, 0xd5, 0x75,
0xca, 0x04, 0xb9, 0x0e, 0x57, 0xa4, 0x2b, 0x05, 0x6e, 0x5a, 0x10, 0xe0, 0x3c, 0x94, 0x32, 0x96, 0xca, 0x04, 0xb9, 0x0e, 0x57, 0xa4, 0x2b, 0x05, 0x6e, 0x5a, 0x10, 0xe0, 0x3c, 0x94, 0x69, 0x2c,
0x32, 0x36, 0xf2, 0xd5, 0x45, 0x0e, 0x39, 0x28, 0x35, 0x94, 0x2b, 0x5d, 0x78, 0xe5, 0x66, 0xc0, 0xd3, 0xd8, 0xa4, 0xaf, 0x2e, 0x33, 0xe0, 0x15, 0xf0, 0xb9, 0x2a, 0x08, 0xf5, 0x45, 0x57, 0x5f,
0x2b, 0xe0, 0x61, 0x4a, 0x38, 0x3b, 0x76, 0xca, 0xa0, 0xa8, 0x8d, 0x7e, 0xa9, 0xf5, 0xb9, 0x36, 0xb9, 0xfa, 0x16, 0xa6, 0x84, 0xb3, 0x63, 0xbb, 0x0c, 0x8a, 0xda, 0xe4, 0x2f, 0x72, 0xc8, 0x41,
0xea, 0x8d, 0x91, 0xfc, 0xd3, 0x11, 0xb8, 0x68, 0x89, 0x60, 0x79, 0xaf, 0x2b, 0x26, 0x25, 0x1a, 0xeb, 0xe4, 0xc9, 0x44, 0xfd, 0x53, 0x0b, 0x5c, 0xb4, 0x44, 0xb0, 0xbc, 0xd7, 0x15, 0x93, 0x12,
0xce, 0xca, 0x12, 0xde, 0x33, 0xfa, 0x46, 0xce, 0xe6, 0x5c, 0xa0, 0x3b, 0x94, 0xd5, 0x50, 0x8d, 0x0d, 0x67, 0x65, 0x09, 0xef, 0x19, 0x7d, 0x23, 0xbd, 0x39, 0x17, 0xe8, 0x0e, 0x65, 0x35, 0x54,
0x6d, 0xdf, 0x9e, 0x9e, 0xc7, 0x7a, 0xe3, 0xbc, 0x44, 0x23, 0x35, 0xfa, 0xfc, 0xe0, 0x1e, 0x9f, 0x63, 0xdb, 0xb7, 0xa7, 0xe7, 0xb1, 0xbe, 0x38, 0x2f, 0xd1, 0x48, 0x59, 0x9f, 0x1f, 0xd4, 0xe3,
0xf9, 0xf6, 0x74, 0x74, 0xe3, 0xe1, 0x93, 0x10, 0x38, 0x31, 0x25, 0xaf, 0xfb, 0x86, 0xc5, 0xf7, 0x33, 0xdf, 0x9e, 0x8e, 0x6e, 0x3c, 0x7c, 0x32, 0x04, 0x4e, 0x4c, 0xc9, 0xeb, 0xbe, 0x61, 0xf1,
0x94, 0xed, 0x70, 0x34, 0xc9, 0xd1, 0x40, 0x61, 0x62, 0x96, 0x41, 0x4b, 0xff, 0x02, 0x8b, 0xd0, 0x3d, 0x25, 0x3b, 0x84, 0x26, 0x39, 0x1a, 0x28, 0x4c, 0xcc, 0x32, 0x68, 0xe9, 0x5f, 0x60, 0x11,
0x50, 0x80, 0x20, 0xe5, 0x9c, 0x77, 0x4d, 0x53, 0x6a, 0xd4, 0xe0, 0xe6, 0x12, 0x9b, 0x64, 0xf2, 0x1a, 0x0a, 0x10, 0xa4, 0x9c, 0xf3, 0xae, 0x69, 0x4a, 0x8d, 0x1a, 0xdc, 0x5c, 0x62, 0xb3, 0x0f,
0x1a, 0x8e, 0xb0, 0x17, 0x50, 0xd4, 0xd1, 0xed, 0xf5, 0xd6, 0xb3, 0xe2, 0x81, 0x32, 0x25, 0xca, 0xb9, 0x81, 0x23, 0xec, 0x05, 0x14, 0x75, 0x74, 0x7b, 0xbd, 0xf5, 0xac, 0x78, 0xa0, 0x44, 0x89,
0x33, 0xf9, 0x61, 0xa3, 0x07, 0x8a, 0x94, 0x2c, 0x48, 0xcb, 0x0c, 0xee, 0x1d, 0x3a, 0xa7, 0xac, 0xd2, 0x4c, 0x7e, 0xd8, 0xe8, 0x81, 0x22, 0x25, 0x0b, 0xd2, 0x32, 0x83, 0x7b, 0x87, 0xce, 0x29,
0x01, 0x5e, 0x08, 0x68, 0x15, 0x72, 0x18, 0xbd, 0xfa, 0xb9, 0xf5, 0x82, 0xbc, 0x10, 0x8b, 0x2e, 0x6b, 0x80, 0x17, 0x02, 0x5a, 0x85, 0x1c, 0x46, 0xaf, 0x7e, 0x6e, 0xbd, 0x20, 0x2f, 0xc4, 0xa2,
0xc5, 0x19, 0x54, 0xe6, 0xf6, 0xcc, 0x27, 0xe0, 0x74, 0x19, 0x8a, 0xbe, 0x61, 0x1c, 0xcf, 0xb2, 0x4b, 0x71, 0x06, 0x95, 0xd9, 0xb9, 0xf9, 0x04, 0x9c, 0x2e, 0x43, 0xd1, 0x37, 0x8c, 0xe3, 0x59,
0x6c, 0x46, 0x69, 0xcb, 0x38, 0xff, 0xf2, 0x39, 0x78, 0x64, 0x26, 0x31, 0x27, 0x51, 0x2f, 0x18, 0x96, 0xcd, 0x28, 0x6d, 0x19, 0xe7, 0x5f, 0x3e, 0x07, 0x8f, 0x8c, 0x13, 0x13, 0x89, 0x7a, 0xc1,
0x8f, 0x7f, 0xb7, 0x76, 0x04, 0xba, 0x4f, 0x2a, 0xe8, 0x6a, 0xa1, 0x13, 0x14, 0x8c, 0x8e, 0xcf, 0x78, 0xfc, 0xbb, 0xb5, 0x23, 0xd0, 0x7d, 0x52, 0x41, 0x57, 0x0b, 0x3d, 0x41, 0xc1, 0xe8, 0xf8,
0xfc, 0x5b, 0xff, 0xce, 0xf0, 0x54, 0x66, 0xf8, 0xf4, 0xcd, 0x9b, 0xfe, 0xc7, 0x30, 0xd2, 0xc0, 0xcc, 0xbf, 0xf5, 0xef, 0x19, 0x9e, 0xca, 0x19, 0x3e, 0x7d, 0xf3, 0xa6, 0xff, 0x61, 0x46, 0x0a,
0xe3, 0x91, 0x66, 0x24, 0x06, 0x11, 0x3d, 0x5f, 0xef, 0x5c, 0x7b, 0xb3, 0x73, 0xed, 0xef, 0x3b, 0x78, 0x3c, 0xd2, 0x8c, 0xc4, 0x20, 0xa2, 0xe7, 0xeb, 0x9d, 0x6b, 0x6f, 0x76, 0xae, 0xfd, 0x7d,
0xd7, 0xfe, 0xb8, 0x77, 0xad, 0xcd, 0xde, 0xb5, 0xbe, 0xee, 0x5d, 0xeb, 0xed, 0x93, 0x3f, 0x7a, 0xe7, 0xda, 0x1f, 0xf7, 0xae, 0xb5, 0xd9, 0xbb, 0xd6, 0xd7, 0xbd, 0x6b, 0xbd, 0x7d, 0xf2, 0x47,
0xca, 0xff, 0x15, 0x94, 0x24, 0xe5, 0x6a, 0x15, 0x7e, 0xd0, 0x8f, 0x43, 0xf5, 0x4d, 0xef, 0xaa, 0x4f, 0xf9, 0xbf, 0x82, 0x92, 0xa4, 0x5c, 0x9d, 0xc2, 0x0f, 0xfa, 0x71, 0xa8, 0xbe, 0xe9, 0x5d,
0x27, 0xf1, 0xec, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0x82, 0x2c, 0xf8, 0xd8, 0xb9, 0x02, 0x00, 0xf5, 0x24, 0x9e, 0xfd, 0x0a, 0x00, 0x00, 0xff, 0xff, 0x6e, 0x80, 0xa4, 0xff, 0xb9, 0x02, 0x00,
0x00, 0x00,
} }